diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 0000000..4aa03bd
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,21 @@
+name: Java CI
+
+on:
+ push:
+ branches:
+ - main
+ - develop
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Set up JDK 17
+ uses: actions/setup-java@v1
+ with:
+ java-version: 17
+ - name: Build with Gradle
+ run: ./gradlew build
diff --git a/.gitignore b/.gitignore
index fd45b12..46712b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,11 @@
*.iml
.gradle
/local.properties
-/.idea/caches/build_file_checksums.ser
-/.idea/libraries
-/.idea/modules.xml
-/.idea/workspace.xml
+/.idea
.DS_Store
/build
/captures
.externalNativeBuild
+sign.jks
+signing.properties
+lint-baseline.xml
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 5495239..7f5bbc0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,37 +1,35 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
-
-apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'//kapt 插件
+apply from: "${rootDir}/common.gradle"
android {
+ namespace "com.wrbug.developerhelper"
lintOptions {
checkReleaseBuilds false
abortOnError false
}
- signingConfigs {
- releaseConfig
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ if (isSignFileValid()) {
+ signingConfigs {
+ releaseConfig
+ }
}
- compileSdkVersion 28
+ compileSdk 34
defaultConfig {
applicationId "com.wrbug.developerhelper"
- minSdkVersion 21
- targetSdkVersion 28
+ minSdkVersion 23
+ targetSdkVersion 34
versionCode 100040
versionName "1.0.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
- abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
+ abiFilters "arm64-v8a","x86_64"
}
}
buildTypes {
debug {
versionNameSuffix "-debug"
- if (signingConfigs.releaseConfig != null) {
+ if (isSignFileValid()) {
signingConfig signingConfigs.releaseConfig
}
}
@@ -40,47 +38,40 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
- dataBinding {
- enabled = true
- }
-
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'net.dongliu:apk-parser:2.6.10'
testImplementation 'junit:junit:4.12'
+ implementation "androidx.work:work-runtime-ktx:2.9.1"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
- implementation 'com.google.code.gson:gson:2.8.5'
+ implementation 'com.google.code.gson:gson:2.10'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
- implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
- implementation 'com.google.android.material:material:1.1.0-alpha02'
- implementation 'com.github.yhaolpz:FloatWindow:1.0.9'
- implementation project(':basecommon')
kapt "com.android.databinding:compiler:3.1.4"
implementation 'com.elvishew:xlog:1.6.1'
implementation 'org.jetbrains.anko:anko-commons:0.10.8'
- //dagger2
- implementation 'com.google.dagger:dagger:2.16'
+ implementation 'com.airbnb.android:lottie:6.5.2'
// https://mvnrepository.com/artifact/dom4j/dom4j
implementation 'dom4j:dom4j:1.6.1'
+ implementation 'com.drakeet.multitype:multitype:4.3.0'
implementation 'com.evrencoskun.library:tableview:0.8.8'
+ implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
implementation 'gdut.bsx:share2:0.9.3'
- kapt 'com.google.dagger:dagger-compiler:2.16'
+ implementation 'de.blox:graphview:0.5.0'
+ implementation 'com.github.bumptech.glide:glide:4.16.0'
+ implementation "com.google.android.material:material:1.12.0"
+ implementation 'com.github.vipulasri:timelineview:1.1.5'
+ implementation project(':ipc')
implementation project(':commonutil')
implementation project(':mmkv')
- implementation project(':xposedmodule')
- implementation project(':commonwidget')
- implementation 'de.blox:graphview:0.5.0'
}
kapt {
generateStubs = true
}
-
Properties props = new Properties()
def propFile = file('../signing.properties')
if (propFile.canRead()) {
@@ -100,3 +91,7 @@ if (propFile.canRead()) {
println 'release build not found signing file'
android.buildTypes.release.signingConfig = null
}
+
+def isSignFileValid() {
+ return file('../signing.properties').canRead()
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 25f34e2..a03a058 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,14 +1,24 @@
+ xmlns:tools="http://schemas.android.com/tools">
-
-
+
+
+
+
+
+
+
+
+
@@ -32,6 +48,7 @@
@@ -45,19 +62,29 @@
-
-
-
+ android:name=".ui.activity.sharedpreferencesedit.SharedPreferenceEditActivity"
+ android:exported="false" />
+
+
+
+
-
-
-
\ No newline at end of file
diff --git a/app/src/main/assets/zip.dex b/app/src/main/assets/zip.dex
deleted file mode 100644
index 8cb90dd..0000000
Binary files a/app/src/main/assets/zip.dex and /dev/null differ
diff --git a/app/src/main/java/com/wrbug/developerhelper/BaseModule.kt b/app/src/main/java/com/wrbug/developerhelper/BaseModule.kt
new file mode 100644
index 0000000..7f045cc
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/BaseModule.kt
@@ -0,0 +1,12 @@
+package com.wrbug.developerhelper
+
+import android.app.Application
+import com.wrbug.developerhelper.commonutil.CommonUtils
+import com.wrbug.developerhelper.mmkv.manager.MMKVManager
+
+object BaseModule {
+ fun init(application: Application) {
+ MMKVManager.register(application)
+ CommonUtils.register(application)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/DeveloperApplication.kt b/app/src/main/java/com/wrbug/developerhelper/DeveloperApplication.kt
index b76ab66..76b99d7 100644
--- a/app/src/main/java/com/wrbug/developerhelper/DeveloperApplication.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/DeveloperApplication.kt
@@ -1,79 +1,87 @@
package com.wrbug.developerhelper
-import android.os.Handler
-import android.os.Looper
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.os.Process
import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
import com.elvishew.xlog.internal.DefaultsFactory
-import com.wrbug.developerhelper.basecommon.BaseApp
-import com.wrbug.developerhelper.commonutil.CommonUtils
-import com.wrbug.developerhelper.mmkv.manager.MMKVManager
-import java.io.File
-import java.io.FileOutputStream
-import kotlin.concurrent.thread
-import com.wrbug.developerhelper.commonwidget.flexibletoast.FlexibleToast
-
+import com.wrbug.developerhelper.base.BaseApp
+import com.wrbug.developerhelper.commonutil.ProcessUtil
+import com.wrbug.developerhelper.commonutil.print
+import com.wrbug.developerhelper.ipcserver.IpcManager
+import com.wrbug.developerhelper.ui.activity.main.MainActivity
+import com.wrbug.developerhelper.util.AppStatusRegister
class DeveloperApplication : BaseApp() {
- // 全局的 handler 对象
- private val appHandler = Handler()
- // 全局的 Toast 对象
- private val flexibleToast: FlexibleToast by lazy {
- FlexibleToast(this)
- }
- private val builder: FlexibleToast.Builder by lazy {
- FlexibleToast.Builder(this).setGravity(FlexibleToast.GRAVITY_BOTTOM)
- }
-
companion object {
+
private lateinit var instance: DeveloperApplication
fun getInstance(): DeveloperApplication {
return instance
}
}
+ override fun attachBaseContext(base: Context?) {
+ super.attachBaseContext(base)
+ instance = this
+ }
+
override fun onCreate() {
super.onCreate()
- registerModule()
- instance = this
XLog.init(
- LogConfiguration.Builder().logLevel(LogLevel.ALL).tag("developerHelper.print-->").build(),
+ LogConfiguration.Builder().logLevel(LogLevel.ALL).tag("developerHelper.print-->")
+ .build(),
DefaultsFactory.createPrinter()
)
- releaseAssetsFile()
+ registerIpcServer()
+ BaseModule.init(this)
+ registerLifecycle()
+ AppStatusRegister.init(this)
}
- private fun registerModule() {
- MMKVManager.register(this)
- CommonUtils.register(this)
+ private fun registerIpcServer() {
+ val name = ProcessUtil.readProcName(Process.myPid())
+ if (name != "$packageName:floatWindow") {
+ "ignore registerIpcServer : $name".print()
+ return
+ }
+ IpcManager.init()
+ "registerIpcServer: ${Process.myPid()}".print()
}
- private fun releaseAssetsFile() {
- thread {
- val inputStream = BaseApp.instance.assets.open("zip.dex")
- val file = File(BaseApp.instance.cacheDir, "zip.dex")
- if (file.exists().not()) {
- file.createNewFile()
+ private fun registerLifecycle() {
+ registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
+ private var count = 0
+ override fun onActivityPaused(activity: Activity) {
+
}
- val fileOutputStream = FileOutputStream(file)
- fileOutputStream.write(inputStream.readBytes())
- fileOutputStream.flush()
- fileOutputStream.close()
- }
- }
+ override fun onActivityResumed(activity: Activity) {
+ }
- fun showToast(builder: FlexibleToast.Builder) {
- if (Looper.myLooper() !== Looper.getMainLooper()) {
- appHandler.post { flexibleToast.toastShow(builder) }
- } else {
- flexibleToast.toastShow(builder)
- }
- }
+ override fun onActivityStarted(activity: Activity) {
+ count++
+ }
+
+ override fun onActivityDestroyed(activity: Activity) {
+ }
+
+ override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
+ }
+
+ override fun onActivityStopped(activity: Activity) {
+ count--
+ if (count == 0 && activity is MainActivity) {
+ activity.finish()
+ }
+ }
+
+ override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
+ }
- override fun showToast(msg: String) {
- builder.setSecondText(msg)
- showToast(builder)
+ })
}
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/AndroidExt.kt b/app/src/main/java/com/wrbug/developerhelper/base/AndroidExt.kt
new file mode 100644
index 0000000..8b0d58b
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/AndroidExt.kt
@@ -0,0 +1,21 @@
+package com.wrbug.developerhelper.base
+
+import android.app.ActivityManager
+import android.content.Context
+import android.content.pm.PackageInfo
+import android.os.Build
+
+inline val PackageInfo.versionCodeLong: Long
+ get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ longVersionCode
+ } else {
+ versionCode.toLong()
+ }
+
+
+@Suppress("DEPRECATION")
+fun isServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
+ val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ return manager.getRunningServices(Integer.MAX_VALUE)
+ .any { it.service.className == serviceClass.name }
+}
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/AppCompatActivityExt.kt b/app/src/main/java/com/wrbug/developerhelper/base/AppCompatActivityExt.kt
new file mode 100644
index 0000000..989ec51
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/AppCompatActivityExt.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.wrbug.developerhelper.base
+
+import android.Manifest
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.Settings
+import androidx.annotation.IdRes
+import androidx.appcompat.app.ActionBar
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentTransaction
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.activityresultcallback.ActResultRequest
+import com.wrbug.developerhelper.base.activityresultcallback.ActivityResultCallback
+import com.wrbug.developerhelper.constant.ReceiverConstant
+
+/**
+ * Various extension functions for AppCompatActivity.
+ */
+
+
+fun AppCompatActivity.setupActionBar(@IdRes toolbarId: Int, action: ActionBar.() -> Unit = {}) {
+ setupActionBar(findViewById(toolbarId), action)
+}
+
+fun AppCompatActivity.setupActionBar(toolbar: Toolbar, action: ActionBar.() -> Unit = {}) {
+ setSupportActionBar(toolbar)
+ supportActionBar?.run {
+ setDisplayHomeAsUpEnabled(false)
+ action()
+ }
+}
+
+/**
+ * Runs a FragmentTransaction, then calls commit().
+ */
+private inline fun FragmentManager.transact(action: FragmentTransaction.() -> Unit) {
+ beginTransaction().apply {
+ action()
+ }.commit()
+}
+
+fun AppCompatActivity.startActivityForResult(intent: Intent, callback: ActivityResultCallback) {
+ ActResultRequest(this).startForResult(intent, callback)
+}
+
+fun AppCompatActivity.startActivityForResultOk(
+ intent: Intent, action: Intent?.() -> Unit
+) {
+ ActResultRequest(this).startForResult(intent, object : ActivityResultCallback() {
+ override fun onActivityResultOk(data: Intent?) {
+ action(data)
+ }
+ })
+}
+
+fun Context.requestStoragePermission(callback: () -> Unit) {
+ if (this !is BaseActivity) {
+ return
+ }
+ when {
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
+ if (!Environment.isExternalStorageManager()) {
+ AlertDialog.Builder(this).setTitle(R.string.notice)
+ .setMessage(getString(R.string.request_write_sdcard_notice))
+ .setNegativeButton(R.string.cancel, null).setPositiveButton(
+ R.string.ok
+ ) { _, _ ->
+ try {
+ val intent =
+ Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
+ intent.addCategory("android.intent.category.DEFAULT")
+ intent.data = Uri.parse(String.format("package:%s", packageName))
+ startActivity(intent)
+ } catch (e: Exception) {
+ val intent = Intent()
+ intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
+ startActivity(intent)
+ }
+ }.create().show()
+ } else {
+ callback()
+ }
+ }
+
+ else -> {
+ requestPermission(
+ arrayOf(
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ ), object : BaseActivity.PermissionCallback() {
+ override fun granted() {
+ callback()
+ }
+ })
+ }
+ }
+}
+
+fun Context.registerReceiverComp(
+ broadcastReceiver: BroadcastReceiver,
+ intentFilter: IntentFilter,
+ flags: Int = AppCompatActivity.RECEIVER_NOT_EXPORTED
+) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ registerReceiver(broadcastReceiver, intentFilter, flags)
+ } else {
+ registerReceiver(broadcastReceiver, intentFilter)
+ }
+}
+
+fun Context.sendBroadcastComp(action: String, intentCallback: (Intent) -> Unit = {}) {
+ val intent = Intent(action)
+ intentCallback(intent)
+ intent.setPackage(packageName)
+ sendBroadcast(intent)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/BaseActivity.kt b/app/src/main/java/com/wrbug/developerhelper/base/BaseActivity.kt
new file mode 100644
index 0000000..2894673
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/BaseActivity.kt
@@ -0,0 +1,220 @@
+package com.wrbug.developerhelper.base
+
+import android.content.DialogInterface
+import android.content.pm.PackageManager
+import android.os.Bundle
+import android.view.View
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import androidx.viewbinding.ViewBinding
+import com.google.android.material.snackbar.Snackbar
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import java.util.ArrayList
+
+abstract class BaseActivity : AppCompatActivity() {
+
+ private lateinit var toastRootView: View
+ protected lateinit var context: BaseActivity
+ private var mPermissionCallback: PermissionCallback? = null
+ protected lateinit var disposable: CompositeDisposable
+ protected val createTime by lazy {
+ System.currentTimeMillis()
+ }
+
+ companion object {
+ private const val PERMISSION_REQUEST_CODE = 0xAADF1
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ context = this
+ super.onCreate(savedInstanceState)
+ disposable = CompositeDisposable()
+ }
+
+ override fun setContentView(layoutResID: Int) {
+ setContentView(layoutInflater.inflate(layoutResID, null))
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ disposable.dispose()
+ }
+
+ override fun setContentView(view: View?) {
+ view?.let {
+ toastRootView = view
+ }
+ super.setContentView(view)
+ }
+
+ fun showSnack(msg: String) {
+ Snackbar.make(toastRootView, msg, Snackbar.LENGTH_SHORT).show()
+ }
+
+ fun showSnack(id: Int) {
+ Snackbar.make(toastRootView, id, Snackbar.LENGTH_SHORT).show()
+ }
+
+ fun requestPermission(permissions: Array, callback: PermissionCallback) {
+ val list = ArrayList()
+ for (permission in permissions) {
+ val hasPermission = checkSelfPermission(permission)
+ if (hasPermission != PackageManager.PERMISSION_GRANTED) {
+ list.add(permission)
+ }
+ }
+ if (list.isEmpty()) {
+ callback.granted()
+ return
+ }
+ mPermissionCallback = callback
+ requestPermissions(list.toTypedArray(), PERMISSION_REQUEST_CODE)
+ }
+
+ fun showDialog(
+ @StringRes title: Int,
+ @StringRes msg: Int,
+ @StringRes positiveText: Int,
+ positiveListener: DialogInterface.OnClickListener
+ ) {
+ showDialog(title, msg, positiveText, 0, positiveListener, null)
+ }
+
+ fun showDialog(
+ title: String,
+ msg: String,
+ positiveText: String,
+ positiveListener: DialogInterface.OnClickListener
+ ) {
+ showDialog(title, msg, positiveText, null, positiveListener, null)
+ }
+
+ fun showDialog(
+ @StringRes title: Int,
+ @StringRes msg: Int,
+ @StringRes positiveText: Int,
+ @StringRes negativeText: Int,
+ onPositiveClick: DialogInterface.(Int) -> Unit,
+ onNegativeClick: DialogInterface.(Int) -> Unit? = {
+
+ }
+ ) {
+ showDialog(
+ title,
+ msg,
+ positiveText,
+ negativeText,
+ { dialog, which -> dialog.onPositiveClick(which) },
+ { dialog, which -> dialog.onNegativeClick(which) })
+ }
+
+ fun showDialog(
+ @StringRes title: Int,
+ msg: String,
+ @StringRes positiveText: Int,
+ @StringRes negativeText: Int,
+ onPositiveClick: DialogInterface.(Int) -> Unit,
+ onNegativeClick: DialogInterface.(Int) -> Unit? = {
+
+ }
+ ) {
+ showDialog(
+ title,
+ msg,
+ positiveText,
+ negativeText,
+ { dialog, which -> dialog.onPositiveClick(which) },
+ { dialog, which -> dialog.onNegativeClick(which) })
+ }
+
+ private fun showDialog(
+ @StringRes title: Int,
+ @StringRes msg: Int,
+ @StringRes positiveText: Int,
+ @StringRes negativeText: Int,
+ positiveListener: DialogInterface.OnClickListener,
+ negativeListener: DialogInterface.OnClickListener?
+ ) {
+ showDialog(
+ getString(title),
+ getString(msg),
+ getString(positiveText),
+ if (negativeText == 0) null else getString(negativeText),
+ positiveListener,
+ negativeListener
+ )
+ }
+
+ private fun showDialog(
+ @StringRes title: Int,
+ msg: String,
+ @StringRes positiveText: Int,
+ @StringRes negativeText: Int,
+ positiveListener: DialogInterface.OnClickListener,
+ negativeListener: DialogInterface.OnClickListener?
+ ) {
+ showDialog(
+ getString(title),
+ msg,
+ getString(positiveText),
+ if (negativeText == 0) null else getString(negativeText),
+ positiveListener,
+ negativeListener
+ )
+ }
+
+ fun showDialog(
+ title: String,
+ msg: String,
+ positiveText: String,
+ negativeText: String?,
+ positiveListener: DialogInterface.OnClickListener,
+ negativeListener: DialogInterface.OnClickListener?
+ ) {
+ val builder = AlertDialog.Builder(this).setMessage(msg).setTitle(title)
+ .setPositiveButton(positiveText, positiveListener)
+ if (negativeText.isNullOrEmpty().not()) {
+ builder.setNegativeButton(negativeText, negativeListener)
+ }
+ builder.show()
+ }
+
+ fun hasPermission(permissions: String): Boolean {
+ return checkSelfPermission(permissions) == PackageManager.PERMISSION_GRANTED
+ }
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int, permissions: Array, grantResults: IntArray
+ ) {
+ if (requestCode == PERMISSION_REQUEST_CODE) {
+ val list = ArrayList()
+ for (i in grantResults.indices) {
+ if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
+ list.add(permissions[i])
+ }
+ }
+ if (list.isEmpty()) {
+ mPermissionCallback?.granted()
+ return
+ }
+ mPermissionCallback?.denied(list)
+ return
+ }
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ }
+
+ abstract class PermissionCallback {
+
+ abstract fun granted()
+
+ open fun denied(permissions: List) {
+
+ }
+ }
+
+ protected fun T.inject(): T {
+ setContentView(this.root)
+ return this
+ }
+}
\ No newline at end of file
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseApp.kt b/app/src/main/java/com/wrbug/developerhelper/base/BaseApp.kt
similarity index 59%
rename from basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseApp.kt
rename to app/src/main/java/com/wrbug/developerhelper/base/BaseApp.kt
index 3239594..86221e7 100644
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseApp.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/base/BaseApp.kt
@@ -1,4 +1,4 @@
-package com.wrbug.developerhelper.basecommon
+package com.wrbug.developerhelper.base
import android.app.Application
@@ -12,11 +12,4 @@ abstract class BaseApp : Application() {
instance = this
}
-
- abstract fun showToast(msg: String)
-
- fun showToast(id: Int){
- showToast(getString(id))
- }
-
}
\ No newline at end of file
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseFragment.kt b/app/src/main/java/com/wrbug/developerhelper/base/BaseFragment.kt
similarity index 64%
rename from basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseFragment.kt
rename to app/src/main/java/com/wrbug/developerhelper/base/BaseFragment.kt
index 894989c..e7d2360 100644
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseFragment.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/base/BaseFragment.kt
@@ -1,4 +1,4 @@
-package com.wrbug.developerhelper.basecommon
+package com.wrbug.developerhelper.base
import androidx.fragment.app.Fragment
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseVMActivity.kt b/app/src/main/java/com/wrbug/developerhelper/base/BaseVMActivity.kt
similarity index 92%
rename from basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseVMActivity.kt
rename to app/src/main/java/com/wrbug/developerhelper/base/BaseVMActivity.kt
index fb50ab6..51bff35 100644
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseVMActivity.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/base/BaseVMActivity.kt
@@ -1,4 +1,4 @@
-package com.wrbug.developerhelper.basecommon
+package com.wrbug.developerhelper.base
import android.os.Bundle
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseViewModel.kt b/app/src/main/java/com/wrbug/developerhelper/base/BaseViewModel.kt
similarity index 90%
rename from basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseViewModel.kt
rename to app/src/main/java/com/wrbug/developerhelper/base/BaseViewModel.kt
index 3928d9a..a0e716a 100644
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseViewModel.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/base/BaseViewModel.kt
@@ -1,4 +1,4 @@
-package com.wrbug.developerhelper.basecommon
+package com.wrbug.developerhelper.base
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.MutableLiveData
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/ExtraKey.kt b/app/src/main/java/com/wrbug/developerhelper/base/ExtraKey.kt
new file mode 100644
index 0000000..bec3ba2
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/ExtraKey.kt
@@ -0,0 +1,13 @@
+package com.wrbug.developerhelper.base
+
+object ExtraKey {
+
+ const val PACKAGE_NAME = "packageName"
+ const val DATA = "data"
+ const val SELECTED = "selected"
+ const val KEY_1 = "key1"
+ const val KEY_2 = "key2"
+ const val KEY_3 = "key3"
+ const val KEY_4 = "key4"
+ const val KEY_5 = "key5"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/ActResultRequest.kt b/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/ActResultRequest.kt
new file mode 100644
index 0000000..8301892
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/ActResultRequest.kt
@@ -0,0 +1,55 @@
+package com.wrbug.developerhelper.base.activityresultcallback
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+
+class ActResultRequest {
+ private val mFragment: OnActResultEventDispatcherFragment
+
+ constructor(activity: AppCompatActivity) {
+ mFragment = getEventDispatchFragment(activity)
+ }
+
+ constructor(fragment: Fragment) {
+ mFragment = getEventDispatchFragment(fragment)
+ }
+
+
+ private fun getEventDispatchFragment(activity: AppCompatActivity): OnActResultEventDispatcherFragment {
+ val fragmentManager = activity.supportFragmentManager
+ return this.addFragment(fragmentManager)
+ }
+
+ private fun getEventDispatchFragment(fragment: Fragment): OnActResultEventDispatcherFragment {
+ val fragmentManager = fragment.childFragmentManager
+ return this.addFragment(fragmentManager)
+ }
+
+ private fun addFragment(fragmentManager: FragmentManager): OnActResultEventDispatcherFragment {
+ var fragment: OnActResultEventDispatcherFragment? =
+ this.findEventDispatchFragment(fragmentManager)
+ if (fragment == null) {
+ fragment = OnActResultEventDispatcherFragment()
+ fragmentManager.beginTransaction().add(fragment, "on_act_result_event_dispatcher")
+ .commitAllowingStateLoss()
+ fragmentManager.executePendingTransactions()
+ }
+
+ return fragment
+ }
+
+ private fun findEventDispatchFragment(manager: FragmentManager): OnActResultEventDispatcherFragment? {
+ return manager.findFragmentByTag("on_act_result_event_dispatcher") as OnActResultEventDispatcherFragment?
+ }
+
+ fun startForResult(intent: Intent, callback: ActivityResultCallback) {
+ this.mFragment.startForResult(intent, null, callback)
+ }
+
+ fun startForResult(intent: Intent, options: Bundle, callback: ActivityResultCallback) {
+ this.mFragment.startForResult(intent, options, callback)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/ActivityResultCallback.kt b/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/ActivityResultCallback.kt
new file mode 100644
index 0000000..42ef08b
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/ActivityResultCallback.kt
@@ -0,0 +1,22 @@
+package com.wrbug.developerhelper.base.activityresultcallback
+
+import android.app.Activity
+import android.content.Intent
+
+abstract class ActivityResultCallback {
+
+ fun dispatchActivityResult(resultCode: Int, data: Intent?) {
+ onActivityResult(resultCode, data)
+ if (resultCode == Activity.RESULT_OK) {
+ onActivityResultOk(data)
+ }
+ }
+
+ protected open fun onActivityResult(resultCode: Int, data: Intent?) {
+
+ }
+
+ protected open fun onActivityResultOk(data: Intent?) {
+
+ }
+}
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/OnActResultEventDispatcherFragment.kt b/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/OnActResultEventDispatcherFragment.kt
new file mode 100644
index 0000000..b44f5ba
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/activityresultcallback/OnActResultEventDispatcherFragment.kt
@@ -0,0 +1,24 @@
+package com.wrbug.developerhelper.base.activityresultcallback
+
+import android.content.Intent
+import android.os.Bundle
+import android.util.SparseArray
+import androidx.fragment.app.Fragment
+
+class OnActResultEventDispatcherFragment : Fragment() {
+ val TAG = "on_act_result_event_dispatcher"
+ private val mCallbacks = SparseArray()
+
+ fun startForResult(intent: Intent, options: Bundle?, callback: ActivityResultCallback) {
+ val requestCode = callback.hashCode() and 0xffff
+ this.mCallbacks.put(requestCode, callback)
+ this.startActivityForResult(intent, requestCode, options)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ val callback = this.mCallbacks.get(requestCode) as ActivityResultCallback
+ this.mCallbacks.remove(requestCode)
+ callback.dispatchActivityResult(resultCode, data)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/base/entry/HierarchyNode.kt b/app/src/main/java/com/wrbug/developerhelper/base/entry/HierarchyNode.kt
new file mode 100644
index 0000000..0356af7
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/base/entry/HierarchyNode.kt
@@ -0,0 +1,33 @@
+package com.wrbug.developerhelper.base.entry
+
+import android.graphics.Rect
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+import java.io.Serializable
+
+@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
+@Parcelize
+data class HierarchyNode(
+ var id: Long = -1L,
+ var screenBounds: Rect? = null,
+ var parentBounds: Rect? = null,
+ var checkable: Boolean = false,
+ var checked: Boolean = false,
+ var widget: String = "",
+ var clickable: Boolean = false,
+ var contentDesc: String = "",
+ var enabled: Boolean = false,
+ var focusable: Boolean = false,
+ var focused: Boolean = false,
+ var index: String = "",
+ var longClickable: Boolean = false,
+ var packageName: String = "",
+ var password: Boolean = false,
+ var scrollable: Boolean = false,
+ var selected: Boolean = false,
+ var text: String = "",
+ var resourceId: String = "",
+ var idHex: String? = null,
+ var parentId: Long = -1L,
+ var childId: ArrayList = arrayListOf()
+): Parcelable, Serializable
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/constant/ReceiverConstant.kt b/app/src/main/java/com/wrbug/developerhelper/constant/ReceiverConstant.kt
index 77f8af7..70b5b3d 100644
--- a/app/src/main/java/com/wrbug/developerhelper/constant/ReceiverConstant.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/constant/ReceiverConstant.kt
@@ -5,5 +5,7 @@ object ReceiverConstant {
const val ACTION_SET_FLOAT_BUTTON_VISIBLE = "ACTION_SET_FLOAT_BUTTON_VISIBLE"
const val ACTION_ADB_WIFI_CLICKED = "ACTION_ADB_WIFI_CLICKED"
const val ACTION_FINISH_HIERACHY_Activity = "ACTION_FINISH_HIERACHY_Activity"
- const val ACTION_ACCESSIBILITY_SERVICE_STATUS_CHANGED = "ACTION_ACCESSIBILITY_SERVICE_STATUS_CHANGED"
+ const val ACTION_ACCESSIBILITY_SERVICE_STATUS_CHANGED =
+ "ACTION_ACCESSIBILITY_SERVICE_STATUS_CHANGED"
+ const val ACTION_DELAY_START_APP = "ACTION_DELAY_START_APP"
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ipcserver/FileProcessDataImpl.kt b/app/src/main/java/com/wrbug/developerhelper/ipcserver/FileProcessDataImpl.kt
new file mode 100644
index 0000000..8371bf1
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ipcserver/FileProcessDataImpl.kt
@@ -0,0 +1,31 @@
+package com.wrbug.developerhelper.ipcserver
+
+import com.wrbug.developerhelper.base.BaseApp
+import com.wrbug.developerhelper.commonutil.Base64
+import com.wrbug.developerhelper.ipc.processshare.TcpUrl
+import com.wrbug.developerhelper.ipcserver.annotation.Controller
+
+
+/**
+ *
+ * class: FileProcessDataImpl.kt
+ * author: wrbug
+ * date: 2020-05-19
+ * description:
+ *
+ */
+class FileProcessDataImpl {
+ @Controller(TcpUrl.FileProcessDataUrl.GET_DATA_FINDER_ZIP_FILE)
+ fun getDataFinderZipFile(): String {
+ val data = BaseApp.instance.assets.open("datafinder-web/web-static.zip").readBytes()
+ val base64 = Base64.encodeAsString(data)
+ return base64
+ }
+
+ @Controller(TcpUrl.FileProcessDataUrl.GET_DUMP_SO_ZIP_FILE)
+ fun getDumpSoZipFile(): String {
+ val data = BaseApp.instance.assets.open("nativeDump.zip").readBytes()
+ val base64 = Base64.encodeAsString(data)
+ return base64
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ipcserver/IpcManager.kt b/app/src/main/java/com/wrbug/developerhelper/ipcserver/IpcManager.kt
new file mode 100644
index 0000000..75a3920
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ipcserver/IpcManager.kt
@@ -0,0 +1,41 @@
+package com.wrbug.developerhelper.ipcserver
+
+import com.wrbug.developerhelper.ipc.processshare.tcp.MessageHandler
+import com.wrbug.developerhelper.ipc.processshare.tcp.TcpManager
+import com.wrbug.developerhelper.ipcserver.annotation.Controller
+
+object IpcManager {
+ private val map = HashMap()
+
+ fun init() {
+ registerController(FileProcessDataImpl())
+ TcpManager.messageHandler = object : MessageHandler {
+ override fun handle(action: String, message: String): String {
+ if (!map.containsKey(action)) {
+ return ""
+ }
+ val info = map[action] ?: return ""
+ info.method.run {
+ return try {
+ if (parameterTypes.isEmpty()) {
+ invoke(info.obj)?.toString() ?: ""
+ } else {
+ invoke(info.obj, message)?.toString() ?: ""
+ }
+ } catch (t: Throwable) {
+ ""
+ }
+ }
+ }
+
+ }
+ TcpManager.startServer()
+ }
+
+ private fun registerController(obj: Any) {
+ obj.javaClass.declaredMethods.forEach {
+ val router = it.getAnnotation(Controller::class.java)?.value ?: return@forEach
+ map[router] = MethodInfo(obj, it)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ipcserver/MethodInfo.kt b/app/src/main/java/com/wrbug/developerhelper/ipcserver/MethodInfo.kt
new file mode 100644
index 0000000..f37777c
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ipcserver/MethodInfo.kt
@@ -0,0 +1,5 @@
+package com.wrbug.developerhelper.ipcserver
+
+import java.lang.reflect.Method
+
+internal class MethodInfo(val obj: Any, val method: Method)
diff --git a/app/src/main/java/com/wrbug/developerhelper/ipcserver/annotation/Controller.kt b/app/src/main/java/com/wrbug/developerhelper/ipcserver/annotation/Controller.kt
new file mode 100644
index 0000000..a231ded
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ipcserver/annotation/Controller.kt
@@ -0,0 +1,14 @@
+package com.wrbug.developerhelper.ipcserver.annotation
+
+
+/**
+ *
+ * class: Controller.kt
+ * author: wrbug
+ * date: 2020-05-15
+ * description:
+ *
+ */
+@Target(AnnotationTarget.FUNCTION)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class Controller(val value: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppData.kt b/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppData.kt
new file mode 100644
index 0000000..3c1ac5b
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppData.kt
@@ -0,0 +1,13 @@
+package com.wrbug.developerhelper.model.entity
+
+import kotlinx.parcelize.Parcelize
+import java.io.File
+import java.io.Serializable
+
+data class BackupAppData(
+ val appName: String,
+ val packageName: String,
+ val rootDir: File,
+ val backupMap: HashMap,
+ val iconPath: File?
+) : Serializable
diff --git a/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppInfo.kt b/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppInfo.kt
new file mode 100644
index 0000000..91db0d0
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppInfo.kt
@@ -0,0 +1,12 @@
+package com.wrbug.developerhelper.model.entity
+
+import com.google.gson.annotations.SerializedName
+
+data class BackupAppInfo(
+ @SerializedName("appName")
+ var appName: String = "",
+ @SerializedName("packageName")
+ var packageName: String = "",
+ @SerializedName("backupMap")
+ val backupMap: HashMap = hashMapOf()
+)
diff --git a/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppItemInfo.kt b/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppItemInfo.kt
new file mode 100644
index 0000000..1c4fff7
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/model/entity/BackupAppItemInfo.kt
@@ -0,0 +1,34 @@
+package com.wrbug.developerhelper.model.entity
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.parcelize.Parcelize
+import java.io.Serializable
+
+@Parcelize
+data class BackupAppItemInfo(
+ @SerializedName("backupFile")
+ var backupFile: String = "",
+ @SerializedName("backupApk")
+ var backupApk: Boolean = false,
+ @SerializedName("backupData")
+ var backupData: Boolean = false,
+ @SerializedName("backupAndroidData")
+ var backupAndroidData: Boolean = false,
+ @SerializedName("apkFile")
+ var apkFile: String = "",
+ @SerializedName("versionName")
+ var versionName: String = "",
+ @SerializedName("versionCode")
+ var versionCode: Long = 0,
+ @SerializedName("packageName")
+ var packageName: String = "",
+ @SerializedName("time")
+ var time: Long = 0,
+ @SerializedName("dataFile")
+ var dataFile: String = "",
+ @SerializedName("androidDataFile")
+ var androidDataFile: String = "",
+ @SerializedName("memo")
+ var memo: String = ""
+) : Parcelable, Serializable
diff --git a/app/src/main/java/com/wrbug/developerhelper/model/entity/HierarchyNode.kt b/app/src/main/java/com/wrbug/developerhelper/model/entity/HierarchyNode.kt
deleted file mode 100644
index 8f11257..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/model/entity/HierarchyNode.kt
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.wrbug.developerhelper.model.entity
-
-import android.graphics.Rect
-import android.os.Parcel
-import android.os.Parcelable
-import com.google.gson.reflect.TypeToken
-import com.wrbug.developerhelper.commonutil.JsonHelper
-import java.io.Serializable
-
-@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
-class HierarchyNode() : Parcelable, Serializable {
- var id: Long = -1L
- var screenBounds: Rect? = null
- var parentBounds: Rect? = null
- var checkable: Boolean = false
- var checked: Boolean = false
- var widget: String = ""
- var clickable: Boolean = false
- var contentDesc: String = ""
- var enabled: Boolean = false
- var focusable: Boolean = false
- var focused: Boolean = false
- var index: String = ""
- var longClickable: Boolean = false
- var packageName: String = ""
- var password: Boolean = false
- var scrollable: Boolean = false
- var selected: Boolean = false
- var text: String = ""
- var resourceId: String = ""
- var idHex: String? = null
- var parentId: Long = -1L
- var childId: ArrayList = arrayListOf()
-
- constructor(parcel: Parcel) : this() {
- id = parcel.readLong()
- screenBounds = parcel.readParcelable(Rect::class.java.classLoader)
- parentBounds = parcel.readParcelable(Rect::class.java.classLoader)
- checkable = parcel.readByte() != 0.toByte()
- checked = parcel.readByte() != 0.toByte()
- widget = parcel.readString()
- clickable = parcel.readByte() != 0.toByte()
- contentDesc = parcel.readString()
- enabled = parcel.readByte() != 0.toByte()
- focusable = parcel.readByte() != 0.toByte()
- focused = parcel.readByte() != 0.toByte()
- index = parcel.readString()
- longClickable = parcel.readByte() != 0.toByte()
- packageName = parcel.readString()
- password = parcel.readByte() != 0.toByte()
- scrollable = parcel.readByte() != 0.toByte()
- selected = parcel.readByte() != 0.toByte()
- text = parcel.readString()
- resourceId = parcel.readString()
- idHex = parcel.readString()
- parentId = parcel.readLong()
- childId = JsonHelper.fromJson(parcel.readString(), object : TypeToken>() {}.type) ?:
- arrayListOf()
- }
-
- override fun writeToParcel(parcel: Parcel, flags: Int) {
- parcel.writeLong(id)
- parcel.writeParcelable(screenBounds, flags)
- parcel.writeParcelable(parentBounds, flags)
- parcel.writeByte(if (checkable) 1 else 0)
- parcel.writeByte(if (checked) 1 else 0)
- parcel.writeString(widget)
- parcel.writeByte(if (clickable) 1 else 0)
- parcel.writeString(contentDesc)
- parcel.writeByte(if (enabled) 1 else 0)
- parcel.writeByte(if (focusable) 1 else 0)
- parcel.writeByte(if (focused) 1 else 0)
- parcel.writeString(index)
- parcel.writeByte(if (longClickable) 1 else 0)
- parcel.writeString(packageName)
- parcel.writeByte(if (password) 1 else 0)
- parcel.writeByte(if (scrollable) 1 else 0)
- parcel.writeByte(if (selected) 1 else 0)
- parcel.writeString(text)
- parcel.writeString(resourceId)
- parcel.writeString(idHex)
- parcel.writeLong(parentId)
- parcel.writeString(JsonHelper.toJson(childId))
- }
-
- override fun describeContents(): Int {
- return 0
- }
-
- companion object CREATOR : Parcelable.Creator {
- override fun createFromParcel(parcel: Parcel): HierarchyNode {
- return HierarchyNode(parcel)
- }
-
- override fun newArray(size: Int): Array {
- return arrayOfNulls(size)
- }
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/model/entity/SharedPreferenceItemInfo.kt b/app/src/main/java/com/wrbug/developerhelper/model/entity/SharedPreferenceItemInfo.kt
index 6bf2927..49859ce 100644
--- a/app/src/main/java/com/wrbug/developerhelper/model/entity/SharedPreferenceItemInfo.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/model/entity/SharedPreferenceItemInfo.kt
@@ -10,7 +10,7 @@ class SharedPreferenceItemInfo {
fun isValueValid(): Boolean {
- when (type.toLowerCase()) {
+ when (type.lowercase()) {
"string" -> {
return JsonHelper.fromJson(value) == null || JsonHelper.fromJson(newValue) != null
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/service/AccessibilityManager.kt b/app/src/main/java/com/wrbug/developerhelper/service/AccessibilityManager.kt
index 418707e..3fd6bf5 100644
--- a/app/src/main/java/com/wrbug/developerhelper/service/AccessibilityManager.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/service/AccessibilityManager.kt
@@ -4,32 +4,23 @@ import android.content.Context
import android.content.Intent
import android.provider.Settings
import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.showToast
-import com.wrbug.developerhelper.commonutil.shell.Callback
import com.wrbug.developerhelper.commonutil.shell.ShellManager
+import com.wrbug.developerhelper.util.getString
+import io.reactivex.rxjava3.core.Single
+import org.jetbrains.anko.toast
object AccessibilityManager {
- fun startService(context: Context?, callback: Callback? = null) {
- context?.run {
- ShellManager.openAccessibilityService(object : Callback {
- override fun onSuccess(data: Boolean) {
- if (!data) {
- showToast(getString(R.string.please_open_accessbility_service))
- startAccessibilitySetting(context)
- }
- callback?.onSuccess(data)
- }
-
- override fun onFailed(msg: String) {
- callback?.onFailed(msg)
- startAccessibilitySetting(context)
- }
-
- })
+ fun startService(context: Context?): Single {
+ return ShellManager.openAccessibilityService().doOnSuccess {
+ if (!it) {
+ context?.toast(getString(R.string.please_open_accessbility_service))
+ }
}
}
- fun startAccessibilitySetting(context: Context) {
+
+ fun startAccessibilitySetting(context: Context?) {
+ context ?: return
val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
diff --git a/app/src/main/java/com/wrbug/developerhelper/service/DeveloperHelperAccessibilityService.kt b/app/src/main/java/com/wrbug/developerhelper/service/DeveloperHelperAccessibilityService.kt
index e9cdee1..7c8e99f 100644
--- a/app/src/main/java/com/wrbug/developerhelper/service/DeveloperHelperAccessibilityService.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/service/DeveloperHelperAccessibilityService.kt
@@ -1,27 +1,27 @@
package com.wrbug.developerhelper.service
import android.accessibilityservice.AccessibilityService
+import android.annotation.SuppressLint
import android.content.BroadcastReceiver
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Rect
+import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseApp
-import com.wrbug.developerhelper.basecommon.showToast
+import com.wrbug.developerhelper.base.BaseApp
+import com.wrbug.developerhelper.base.entry.HierarchyNode
+import com.wrbug.developerhelper.base.registerReceiverComp
import com.wrbug.developerhelper.commonutil.AppInfoManager
+import com.wrbug.developerhelper.commonutil.UiUtils
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
import com.wrbug.developerhelper.commonutil.entity.TopActivityInfo
import com.wrbug.developerhelper.constant.ReceiverConstant
-import com.wrbug.developerhelper.model.entity.HierarchyNode
-import com.wrbug.developerhelper.commonutil.shell.Callback
-import com.wrbug.developerhelper.commonutil.shell.ShellManager
import com.wrbug.developerhelper.ui.activity.hierachy.HierarchyActivity
-import com.wrbug.developerhelper.commonutil.UiUtils
class DeveloperHelperAccessibilityService : AccessibilityService() {
@@ -29,18 +29,20 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
private var nodeId = 0L
private var currentAppInfo: ApkInfo? = null
private var topActivity: TopActivityInfo? = null
+ private val activityMap = hashMapOf()
companion object {
internal var serviceRunning = false
fun isAccessibilitySettingsOn(): Boolean {
var accessibilityEnabled = 0
- val service = "com.wrbug.developerhelper/" + DeveloperHelperAccessibilityService::class.java.canonicalName
+ val service =
+ "com.wrbug.developerhelper/" + DeveloperHelperAccessibilityService::class.java.canonicalName
try {
accessibilityEnabled = Settings.Secure.getInt(
BaseApp.instance.applicationContext.contentResolver,
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED
)
- } catch (e: Settings.SettingNotFoundException) {
+ } catch (_: Settings.SettingNotFoundException) {
}
val mStringColonSplitter = TextUtils.SimpleStringSplitter(':')
@@ -63,7 +65,6 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
return false
}
- //todo java.lang.RuntimeException:android.os.TransactionTooLargeException
val nodeMap: HashMap = hashMapOf()
}
@@ -71,7 +72,22 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
}
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
-
+ if (event?.eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+ || event.className.isNullOrEmpty()
+ || event.className?.startsWith("android.") == true
+ || event.packageName.isNullOrEmpty()
+ ) {
+ return
+ }
+ runCatching {
+ val info = packageManager.getActivityInfo(
+ ComponentName(
+ event.packageName.toString(),
+ event.className.toString()
+ ), 0
+ )
+ activityMap[info.packageName] = info.name
+ }
}
fun readNode(): ArrayList {
@@ -87,6 +103,7 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
return hierarchyNodes
}
+
private fun getDecorViewNode(node: AccessibilityNodeInfo): AccessibilityNodeInfo? {
for (index in 0 until node.childCount) {
val child = node.getChild(index)
@@ -101,16 +118,18 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
return null
}
+ @SuppressLint("UnspecifiedRegisterReceiverFlag")
override fun onCreate() {
super.onCreate()
val filter = IntentFilter()
filter.addAction(ReceiverConstant.ACTION_HIERARCHY_VIEW)
- registerReceiver(receiver, filter)
+ registerReceiverComp(receiver, filter)
sendStatusBroadcast(true)
serviceRunning = true
nodeMap.clear()
}
+
override fun onDestroy() {
super.onDestroy()
nodeMap.clear()
@@ -140,7 +159,7 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
}
for (index in 0 until accessibilityNodeInfo.childCount) {
val child = accessibilityNodeInfo.getChild(index)
- if (child.isVisibleToUser.not()) {
+ if (child?.isVisibleToUser != true) {
continue
}
val screenRect = Rect()
@@ -202,17 +221,11 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
inner class DeveloperHelperAccessibilityReceiver : BroadcastReceiver() {
- override fun onReceive(context: Context?, data: Intent?) {
- showToast(getString(R.string.getting_app_info))
- ShellManager.getTopActivity(object : Callback {
-
- override fun onSuccess(data: TopActivityInfo?) {
- topActivity = data
- val nodesInfo = readNode()
- HierarchyActivity.start(context, currentAppInfo, nodesInfo, topActivity)
- }
- })
-
+ override fun onReceive(context: Context, data: Intent?) {
+ val nodesInfo = readNode()
+ currentAppInfo?.topActivity =
+ activityMap[currentAppInfo?.packageInfo?.packageName].orEmpty()
+ HierarchyActivity.start(context, currentAppInfo, nodesInfo)
}
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/service/FloatWindowService.kt b/app/src/main/java/com/wrbug/developerhelper/service/FloatWindowService.kt
deleted file mode 100644
index ba11265..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/service/FloatWindowService.kt
+++ /dev/null
@@ -1,189 +0,0 @@
-package com.wrbug.developerhelper.service
-
-import android.app.*
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.os.Build
-import android.os.IBinder
-import android.view.LayoutInflater
-import android.widget.RemoteViews
-import androidx.core.app.NotificationCompat
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.showToast
-import com.wrbug.developerhelper.constant.ReceiverConstant
-import com.wrbug.developerhelper.commonutil.shell.Callback
-import com.wrbug.developerhelper.commonutil.shell.ShellManager
-import com.wrbug.developerhelper.ui.activity.main.MainActivity
-import com.yhao.floatwindow.FloatWindow
-import com.yhao.floatwindow.Screen
-
-
-class FloatWindowService : Service() {
-
- companion object {
- const val FLOAT_BUTTON = "floatButton"
- private const val CHANNEL_ID = "DEMON"
- fun start(context: Context) {
- context.startService(Intent(context, FloatWindowService::class.java))
- }
-
- fun stop(context: Context) {
- context.stopService(Intent(context, FloatWindowService::class.java))
- }
-
- fun setFloatButtonVisible(context: Context, visible: Boolean) {
- val intent = Intent(ReceiverConstant.ACTION_SET_FLOAT_BUTTON_VISIBLE)
- intent.putExtra("visible", visible)
- context.sendBroadcast(intent)
- }
- }
-
- private val floatCustomView: RemoteViews by lazy {
- RemoteViews(packageName, R.layout.view_float_custom).apply {
- setOnClickPendingIntent(
- R.id.adbWifiContainer, PendingIntent.getBroadcast(
- applicationContext, 0,
- Intent(ReceiverConstant.ACTION_ADB_WIFI_CLICKED), PendingIntent.FLAG_UPDATE_CURRENT
- )
- )
- }
- }
- private lateinit var notification: Notification
- private val receiver = Receiver()
- override fun onCreate() {
- super.onCreate()
- initReceiver()
- LayoutInflater.from(this).inflate(R.layout.layout_float_window_button, null)?.let { it ->
- it.setOnClickListener {
- if (!DeveloperHelperAccessibilityService.isAccessibilitySettingsOn()) {
- AccessibilityManager.startService(this, object : Callback {
- override fun onSuccess(data: Boolean) {
- if (data) {
- it.postDelayed({
- sendBroadcast(Intent(ReceiverConstant.ACTION_HIERARCHY_VIEW))
- }, 500)
- }
- }
-
- })
- return@setOnClickListener
- }
- sendBroadcast(Intent(ReceiverConstant.ACTION_HIERARCHY_VIEW))
- }
- FloatWindow
- .with(applicationContext)
- .setView(it)
- .setWidth(Screen.width, 0.1f) //设置控件宽高
- .setHeight(Screen.width, 0.1f)
- .setY(Screen.height, 0.3f)
- .setTag(FLOAT_BUTTON)
- .setDesktopShow(true) //桌面显示
- .build()
-
-
- }
- }
-
- private fun initNotification() {
- val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val channel =
- NotificationChannel(CHANNEL_ID, getString(R.string.demon_process), NotificationManager.IMPORTANCE_LOW)
- channel.enableLights(true)
- channel.setShowBadge(true)
- notificationManager.createNotificationChannel(channel)
- }
- val intent = Intent(this, MainActivity::class.java)
- intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
- val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
- val builder = NotificationCompat.Builder(this, CHANNEL_ID)
- .setAutoCancel(false)
- .setContentIntent(pendingIntent)
- .setContentTitle(getString(R.string.app_name))
- .setContentText(getString(R.string.demon_process_content))
- .setSmallIcon(R.drawable.ic_launcher_notify)
- .setVibrate(null)
- notification = builder.build()
- notification.flags = Notification.FLAG_ONGOING_EVENT or Notification.FLAG_NO_CLEAR or
- Notification.FLAG_FOREGROUND_SERVICE
- updateNotification()
- }
-
- private fun updateNotification() {
- startForeground(0x10000, notification)
- }
-
- private fun updateNotificationContent(text: String) {
- floatCustomView.setTextViewText(R.id.contentTv, text)
- updateNotification()
- }
-
- private fun updateNotificationWifi(id: Int) {
- floatCustomView.setImageViewResource(R.id.adbWifiIv, id)
- updateNotification()
- }
-
- private fun showFloatButton() {
- FloatWindow.get(FLOAT_BUTTON).show()
- }
-
- private fun hideFloatButton() {
- FloatWindow.get(FLOAT_BUTTON).hide()
- }
-
- private fun initReceiver() {
- val filter = IntentFilter(ReceiverConstant.ACTION_SET_FLOAT_BUTTON_VISIBLE)
- filter.addAction(ReceiverConstant.ACTION_ADB_WIFI_CLICKED)
- registerReceiver(receiver, filter)
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- initNotification()
- showFloatButton()
- return super.onStartCommand(intent, flags, startId)
- }
-
- override fun onDestroy() {
- try {
- FloatWindow.destroy(FLOAT_BUTTON)
- unregisterReceiver(receiver)
- stopForeground(true)
- } catch (th: Throwable) {
-
- }
-
- super.onDestroy()
- }
-
- override fun onBind(intent: Intent): IBinder = null!!
-
-
- private inner class Receiver : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
- when (intent?.action) {
- ReceiverConstant.ACTION_SET_FLOAT_BUTTON_VISIBLE -> {
- val visible = intent.getBooleanExtra("visible", false)
- if (visible) {
- showFloatButton()
- } else {
- hideFloatButton()
- }
- }
- ReceiverConstant.ACTION_ADB_WIFI_CLICKED -> {
- updateNotificationContent("正在开启adb wifi")
- val success = ShellManager.openAdbWifi()
- if (success) {
- updateNotificationContent("adb wifi 已开启")
- updateNotificationWifi(R.drawable.ic_wifi_primary)
- } else {
- updateNotificationContent("adb wifi 开启失败")
- updateNotificationWifi(R.drawable.ic_wifi_gray)
- }
- }
- }
- }
-
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/service/FloatingWindowService.kt b/app/src/main/java/com/wrbug/developerhelper/service/FloatingWindowService.kt
new file mode 100644
index 0000000..8fa524e
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/service/FloatingWindowService.kt
@@ -0,0 +1,381 @@
+package com.wrbug.developerhelper.service
+
+import android.annotation.SuppressLint
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.ServiceInfo
+import android.graphics.PixelFormat
+import android.graphics.Point
+import android.os.Build
+import android.os.Handler
+import android.os.IBinder
+import android.os.Looper
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewConfiguration
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.RemoteViews
+import androidx.core.app.NotificationCompat
+import androidx.core.app.ServiceCompat
+import androidx.core.view.isVisible
+import androidx.core.view.setPadding
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.ExtraKey
+import com.wrbug.developerhelper.base.isServiceRunning
+import com.wrbug.developerhelper.base.registerReceiverComp
+import com.wrbug.developerhelper.commonutil.AppManagerUtils
+import com.wrbug.developerhelper.commonutil.UiUtils
+import com.wrbug.developerhelper.commonutil.addTo
+import com.wrbug.developerhelper.commonutil.dpInt
+import com.wrbug.developerhelper.commonutil.shell.ShellManager
+import com.wrbug.developerhelper.constant.ReceiverConstant
+import com.wrbug.developerhelper.ui.activity.main.MainActivity
+import com.wrbug.developerhelper.util.isPortrait
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import kotlin.math.abs
+
+class FloatingWindowService : Service() {
+ companion object {
+ private const val CHANNEL_ID = "FLOAT_WINDOW_DEMON"
+ fun start(context: Context) {
+ if (isServiceRunning(context, FloatingWindowService::class.java)) {
+ return
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(Intent(context, FloatingWindowService::class.java))
+ } else {
+ context.startService(Intent(context, FloatingWindowService::class.java))
+ }
+ }
+
+ fun stop(context: Context) {
+ context.stopService(Intent(context, FloatingWindowService::class.java))
+ }
+
+ fun setFloatButtonVisible(context: Context, visible: Boolean) {
+ val intent = Intent(ReceiverConstant.ACTION_SET_FLOAT_BUTTON_VISIBLE)
+ intent.setPackage(context.packageName)
+ intent.putExtra("visible", visible)
+ context.sendBroadcast(intent)
+ }
+ }
+
+ private lateinit var windowManager: WindowManager
+ private lateinit var floatingButton: View
+ private lateinit var notification: Notification
+ private lateinit var params: WindowManager.LayoutParams
+ private var initialX = 0
+ private var initialY = 0
+ private var initialTouchX = 0f
+ private var initialTouchY = 0f
+ private var isDragging = false
+ private var screenWidth = 0
+ private var screenHeight = 0
+ private lateinit var disposable: CompositeDisposable
+ private lateinit var receiver: Receiver
+
+ private val floatCustomView: RemoteViews by lazy {
+ RemoteViews(packageName, R.layout.view_float_custom).apply {
+ setOnClickPendingIntent(
+ R.id.adbWifiContainer, PendingIntent.getBroadcast(
+ applicationContext,
+ 0,
+ Intent(ReceiverConstant.ACTION_ADB_WIFI_CLICKED),
+ PendingIntent.FLAG_UPDATE_CURRENT
+ )
+ )
+ }
+ }
+
+ override fun onBind(intent: Intent?): IBinder? = null
+
+ override fun onCreate() {
+ super.onCreate()
+ disposable = CompositeDisposable()
+ initReceiver()
+ initScreenDimensions()
+ createFloatingButton()
+ initNotification()
+ }
+
+ private fun initReceiver() {
+ receiver = Receiver()
+ val filter = IntentFilter(ReceiverConstant.ACTION_SET_FLOAT_BUTTON_VISIBLE)
+ filter.addAction(ReceiverConstant.ACTION_ADB_WIFI_CLICKED)
+ filter.addAction(ReceiverConstant.ACTION_DELAY_START_APP)
+ registerReceiverComp(receiver, filter)
+ }
+
+
+ private fun initScreenDimensions() {
+ val display = (getSystemService(WINDOW_SERVICE) as WindowManager).defaultDisplay
+ val size = Point()
+ display.getSize(size)
+ screenWidth = size.x
+ screenHeight = size.y
+ }
+
+ private fun createFloatingButton() {
+ windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
+ val screen = if (isPortrait()) {
+ UiUtils.getDeviceWidth() * 0.1
+ } else {
+ UiUtils.getDeviceHeight() * 0.1
+ }.toInt() + 20.dpInt()
+ floatingButton =
+ LayoutInflater.from(this).inflate(R.layout.layout_float_window_button, null).apply {
+ // 设置按钮大小
+ layoutParams = ViewGroup.LayoutParams(screen, screen)
+ setPadding(10.dpInt())
+ }
+ params = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ WindowManager.LayoutParams(
+ screen,
+ screen,
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.TRANSLUCENT
+ )
+ } else {
+ WindowManager.LayoutParams(
+ screen,
+ screen,
+ WindowManager.LayoutParams.TYPE_PHONE,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.TRANSLUCENT
+ )
+ }
+
+ // 初始位置 - 右上角
+ params.gravity = Gravity.TOP or Gravity.START
+ params.x = 0
+ params.y = screenHeight / 2
+
+ windowManager.addView(floatingButton, params)
+ setupTouchEvents()
+ setupClickEvent()
+ }
+
+ private fun setupTouchEvents() {
+ floatingButton.setOnTouchListener { v, event ->
+ when (event.action) {
+ MotionEvent.ACTION_DOWN -> {
+ initialX = params.x
+ initialY = params.y
+ initialTouchX = event.rawX
+ initialTouchY = event.rawY
+ isDragging = false
+ true
+ }
+
+ MotionEvent.ACTION_MOVE -> {
+ params.x = initialX + (event.rawX - initialTouchX).toInt()
+ params.y = initialY + (event.rawY - initialTouchY).toInt()
+
+ // 限制按钮不超出屏幕
+ params.x = params.x.coerceIn(0, screenWidth - floatingButton.width)
+ params.y = params.y.coerceIn(0, screenHeight - floatingButton.height)
+
+ windowManager.updateViewLayout(floatingButton, params)
+ val moveThreshold = ViewConfiguration.get(this).scaledTouchSlop
+ if (abs(event.rawX - initialTouchX) > moveThreshold || abs(event.rawY - initialTouchY) > moveThreshold) {
+ isDragging = true
+ }
+
+ if (isDragging) {
+ params.x = initialX + (event.rawX - initialTouchX).toInt()
+ params.y = initialY + (event.rawY - initialTouchY).toInt()
+ windowManager.updateViewLayout(floatingButton, params)
+ true
+ } else {
+ false
+ }
+ }
+
+ MotionEvent.ACTION_UP -> {
+ if (!isDragging) {
+ v.performClick()
+ true // 让点击事件处理
+ } else {
+ snapToNearestEdge()
+ true
+ }
+ }
+
+ else -> false
+ }
+ }
+ }
+
+ private fun snapToNearestEdge() {
+ val buttonCenterX = params.x + floatingButton.width / 2
+ val buttonCenterY = params.y + floatingButton.height / 2
+
+ // 计算到各边的距离
+ val distanceToLeft = buttonCenterX
+ val distanceToRight = screenWidth - buttonCenterX
+ val distanceToTop = buttonCenterY
+ val distanceToBottom = screenHeight - buttonCenterY
+
+ // 找到最小距离
+ val minHorizontal = minOf(distanceToLeft, distanceToRight)
+ val minVertical = minOf(distanceToTop, distanceToBottom)
+
+ // 决定吸附到哪边
+ if (minHorizontal < minVertical) {
+ // 水平方向吸附
+ params.x =
+ if (distanceToLeft < distanceToRight) 0 else screenWidth - floatingButton.width
+ } else {
+ // 垂直方向吸附
+ params.y =
+ if (distanceToTop < distanceToBottom) 0 else screenHeight - floatingButton.height
+ }
+
+ windowManager.updateViewLayout(floatingButton, params)
+ }
+
+ private fun setupClickEvent() {
+ floatingButton.setOnDoubleCheckClickListener {
+ if (!DeveloperHelperAccessibilityService.isAccessibilitySettingsOn()) {
+ AccessibilityManager.startService(this).subscribe({ data ->
+ if (data) {
+ it.postDelayed({
+ sendBroadcast(
+ Intent(ReceiverConstant.ACTION_HIERARCHY_VIEW).setPackage(
+ packageName
+ )
+ )
+ }, 500)
+ }
+ }, {
+
+ }).addTo(disposable)
+ return@setOnDoubleCheckClickListener
+ }
+ sendBroadcast(Intent(ReceiverConstant.ACTION_HIERARCHY_VIEW).setPackage(packageName))
+ }
+ }
+
+ @SuppressLint("UnspecifiedImmutableFlag")
+ private fun initNotification() {
+ val notificationManager =
+ getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(
+ CHANNEL_ID, getString(R.string.demon_process), NotificationManager.IMPORTANCE_LOW
+ )
+ channel.enableLights(true)
+ channel.setShowBadge(true)
+ notificationManager.createNotificationChannel(channel)
+ }
+ val intent = Intent(this, MainActivity::class.java)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ PendingIntent.getActivity(
+ this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ } else {
+ PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
+ }
+ val builder = NotificationCompat.Builder(this, CHANNEL_ID).setAutoCancel(false)
+ .setContentIntent(pendingIntent).setContentTitle(getString(R.string.app_name))
+ .setContentText(getString(R.string.demon_process_content))
+ .setSmallIcon(R.drawable.ic_launcher_notify).setVibrate(null)
+ notification = builder.build()
+ notification.flags =
+ Notification.FLAG_ONGOING_EVENT or Notification.FLAG_NO_CLEAR or Notification.FLAG_FOREGROUND_SERVICE
+ updateNotification()
+ }
+
+
+ private fun updateNotification() {
+ val type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+ } else {
+ 0
+ }
+ runCatching {
+ ServiceCompat.startForeground(this, 0x10000, notification, type)
+ }.getOrElse {
+ it.printStackTrace()
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ disposable.dispose()
+ if (::receiver.isInitialized) {
+ unregisterReceiver(receiver)
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ stopForeground(STOP_FOREGROUND_REMOVE)
+ } else {
+ stopForeground(true)
+ }
+ if (::floatingButton.isInitialized) {
+ windowManager.removeView(floatingButton)
+ }
+ }
+
+ private fun setFloatButtonVisible(isVisible: Boolean) {
+ floatingButton.isVisible = isVisible
+ }
+
+ private fun updateNotificationContent(text: String) {
+ floatCustomView.setTextViewText(R.id.contentTv, text)
+ updateNotification()
+ }
+
+ private fun updateNotificationWifi(id: Int) {
+ floatCustomView.setImageViewResource(R.id.adbWifiIv, id)
+ updateNotification()
+ }
+
+ private inner class Receiver : BroadcastReceiver() {
+
+ override fun onReceive(context: Context?, intent: Intent?) {
+ when (intent?.action) {
+ ReceiverConstant.ACTION_SET_FLOAT_BUTTON_VISIBLE -> {
+ val visible = intent.getBooleanExtra("visible", false)
+ setFloatButtonVisible(visible)
+ }
+
+ ReceiverConstant.ACTION_ADB_WIFI_CLICKED -> {
+ updateNotificationContent("正在开启adb wifi")
+ val success = ShellManager.openAdbWifi()
+ if (success) {
+ updateNotificationContent("adb wifi 已开启")
+ updateNotificationWifi(R.drawable.ic_wifi_primary)
+ } else {
+ updateNotificationContent("adb wifi 开启失败")
+ updateNotificationWifi(R.drawable.ic_wifi_gray)
+ }
+ }
+
+ ReceiverConstant.ACTION_DELAY_START_APP -> {
+ val pkg = intent.getStringExtra(ExtraKey.PACKAGE_NAME) ?: return
+ context?.let {
+ Handler(Looper.getMainLooper()).post {
+ AppManagerUtils.startApp(it, pkg)
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/AppBackupDetailActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/AppBackupDetailActivity.kt
new file mode 100644
index 0000000..b890f87
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/AppBackupDetailActivity.kt
@@ -0,0 +1,161 @@
+package com.wrbug.developerhelper.ui.activity.appbackup
+
+import android.app.ActionBar.LayoutParams
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.BaseActivity
+import com.wrbug.developerhelper.base.ExtraKey
+import com.wrbug.developerhelper.commonutil.AppInfoManager
+import com.wrbug.developerhelper.commonutil.GlobalEvent
+import com.wrbug.developerhelper.commonutil.addTo
+import com.wrbug.developerhelper.commonutil.dpInt
+import com.wrbug.developerhelper.databinding.ActivityAppBackupDetailBinding
+import com.wrbug.developerhelper.model.entity.BackupAppItemInfo
+import com.wrbug.developerhelper.ui.adapter.ExMultiTypeAdapter
+import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
+import com.wrbug.developerhelper.util.BackupUtils
+import com.yanzhenjie.recyclerview.SwipeMenuItem
+
+class AppBackupDetailActivity : BaseActivity() {
+
+ companion object {
+ private const val REQUEST_CODE = 100
+ fun start(context: Context, appName: String, packageName: String, fromAppSetting: Boolean) {
+ context.startActivity(Intent(context, AppBackupDetailActivity::class.java).apply {
+ putExtra(ExtraKey.PACKAGE_NAME, packageName)
+ putExtra(ExtraKey.KEY_1, appName)
+ putExtra(ExtraKey.KEY_2, fromAppSetting)
+ })
+ }
+ }
+
+
+ private val adapter by ExMultiTypeAdapter.get()
+
+ private val pkgName by lazy {
+ intent?.getStringExtra(ExtraKey.PACKAGE_NAME).orEmpty()
+ }
+ private val appName by lazy {
+ intent?.getStringExtra(ExtraKey.KEY_1).orEmpty()
+ }
+ private val fromAppSetting by lazy {
+ intent?.getBooleanExtra(ExtraKey.KEY_2, false) ?: false
+ }
+ private val binding by lazy {
+ ActivityAppBackupDetailBinding.inflate(layoutInflater)
+ }
+ private var listCache = arrayListOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(binding.root)
+ initView()
+ loadData()
+ }
+
+ private fun loadData() {
+ adapter.showLoading()
+ BackupUtils.getBackupAppInfo(pkgName).subscribe({
+ val list = it.backupMap.values.sortedByDescending { it.time }
+ listCache.clear()
+ listCache.addAll(list)
+ setupList()
+ }, {
+ adapter.showEmpty()
+ }).addTo(disposable)
+
+ }
+
+ private fun setupList() {
+ if (listCache.isEmpty()) {
+ adapter.showEmpty()
+ } else {
+ adapter.loadData(listCache)
+ }
+ }
+
+ private fun initView() {
+ binding.appBar.setSubTitle(appName)
+ binding.rvAppBackupList.layoutManager = LinearLayoutManager(this)
+ binding.rvAppBackupList.addItemDecoration(SpaceItemDecoration.standard)
+ adapter.register(BackupDetailDelegate(appName))
+ binding.rvAppBackupList.setSwipeMenuCreator { _, rightMenu, _ ->
+ rightMenu.addMenuItem(SwipeMenuItem(this).apply {
+ text = getString(R.string.item_swipe_menu_restore)
+ width = 56.dpInt()
+ height = LayoutParams.MATCH_PARENT
+ setTextColorResource(R.color.material_text_color_white_text)
+ setBackgroundColorResource(R.color.colorAccent)
+ })
+ rightMenu.addMenuItem(SwipeMenuItem(this).apply {
+ text = getString(R.string.item_swipe_menu_delete)
+ width = 56.dpInt()
+ height = LayoutParams.MATCH_PARENT
+ setTextColorResource(R.color.material_text_color_white_text)
+ setBackgroundColorResource(R.color.material_color_red_600)
+ })
+ }
+ binding.rvAppBackupList.setOnItemMenuClickListener { menuBridge, adapterPosition ->
+ menuBridge.closeMenu()
+ when (menuBridge.position) {
+ 0 -> {
+ recover(adapter.items[adapterPosition] as? BackupAppItemInfo)
+ }
+
+ 1 -> {
+ showDialog(
+ R.string.notice,
+ R.string.delete_backup_notice,
+ R.string.ok,
+ R.string.cancel,
+ {
+ deleteBackup(adapter.items[adapterPosition] as? BackupAppItemInfo)
+ dismiss()
+ },
+ {
+ dismiss()
+ })
+ }
+
+ else -> {}
+ }
+ }
+ binding.rvAppBackupList.adapter = adapter
+ }
+
+ private fun recover(backupAppItemInfo: BackupAppItemInfo?) {
+ backupAppItemInfo ?: return
+ if (!AppInfoManager.isInstalled(backupAppItemInfo.packageName) && !backupAppItemInfo.backupApk) {
+ showSnack(getString(R.string.not_installed_and_backup_apk_notice))
+ return
+ }
+ if (fromAppSetting) {
+ AppRecoverActivity.startForResult(this, REQUEST_CODE, appName, backupAppItemInfo)
+ } else {
+ AppRecoverActivity.start(this, appName, backupAppItemInfo)
+ }
+ }
+
+ private fun deleteBackup(backupAppItemInfo: BackupAppItemInfo?) {
+ backupAppItemInfo ?: return
+ BackupUtils.deleteBackupItem(backupAppItemInfo.packageName, backupAppItemInfo.backupFile)
+ .subscribe({
+ loadData()
+ }, {
+ showSnack(getString(R.string.delete_backup_failed_retry))
+ })
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == REQUEST_CODE) {
+ if (resultCode == RESULT_OK) {
+ GlobalEvent.postEvent(GlobalEvent.Action.CloseAll)
+ finish()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/AppRecoverActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/AppRecoverActivity.kt
new file mode 100644
index 0000000..b54f715
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/AppRecoverActivity.kt
@@ -0,0 +1,257 @@
+package com.wrbug.developerhelper.ui.activity.appbackup
+
+import android.app.Activity
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Bundle
+import android.os.Parcelable
+import androidx.core.view.isVisible
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.work.Constraints
+import androidx.work.Data
+import androidx.work.ExistingWorkPolicy
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.OutOfQuotaPolicy
+import androidx.work.WorkManager
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.BaseActivity
+import com.wrbug.developerhelper.base.ExtraKey
+import com.wrbug.developerhelper.base.registerReceiverComp
+import com.wrbug.developerhelper.base.sendBroadcastComp
+import com.wrbug.developerhelper.base.versionCodeLong
+import com.wrbug.developerhelper.commonutil.AppInfoManager
+import com.wrbug.developerhelper.commonutil.getParcelableCompat
+import com.wrbug.developerhelper.commonutil.getSerializableCompat
+import com.wrbug.developerhelper.commonutil.toJson
+import com.wrbug.developerhelper.constant.ReceiverConstant
+import com.wrbug.developerhelper.databinding.ActivityAppRecoverBinding
+import com.wrbug.developerhelper.model.entity.BackupAppItemInfo
+import com.wrbug.developerhelper.ui.activity.appbackup.entity.RecoverTimeLineItem
+import com.wrbug.developerhelper.ui.activity.appbackup.worker.AppRecoverWorker
+import com.wrbug.developerhelper.ui.activity.appbackup.worker.AppRecoverWorkerData
+import com.wrbug.developerhelper.ui.adapter.ExMultiTypeAdapter
+import com.wrbug.developerhelper.util.getString
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+import org.jetbrains.anko.toast
+
+class AppRecoverActivity : BaseActivity() {
+
+ companion object {
+ fun start(context: Context, appName: String, backupAppItemInfo: BackupAppItemInfo) {
+ context.startActivity(Intent(context, AppRecoverActivity::class.java).apply {
+ putExtra(ExtraKey.KEY_1, backupAppItemInfo as Parcelable)
+ putExtra(ExtraKey.KEY_2, appName)
+ })
+ }
+
+ fun startForResult(
+ activity: Activity,
+ requestCode: Int,
+ appName: String,
+ backupAppItemInfo: BackupAppItemInfo
+ ) {
+ activity.startActivityForResult(Intent(activity, AppRecoverActivity::class.java).apply {
+ putExtra(ExtraKey.KEY_1, backupAppItemInfo as Parcelable)
+ putExtra(ExtraKey.KEY_2, appName)
+ }, requestCode)
+ }
+ }
+
+ private val backupAppItemInfo: BackupAppItemInfo? by lazy {
+ intent?.getParcelableCompat(ExtraKey.KEY_1)
+ }
+ private val appName: String by lazy {
+ intent?.getStringExtra(ExtraKey.KEY_2).orEmpty()
+ }
+ private val apkInfo by lazy {
+ AppInfoManager.getAppByPackageName(backupAppItemInfo?.packageName.orEmpty())
+ }
+ private val adapter by ExMultiTypeAdapter.get()
+
+ private val binding by lazy {
+ ActivityAppRecoverBinding.inflate(layoutInflater)
+ }
+ private val receiver by lazy {
+ Receiver()
+ }
+ private val timeLineList: ArrayList = arrayListOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(binding.root)
+ initView()
+ initListener()
+ loadData()
+ }
+
+ private fun loadData() {
+ if (apkInfo == null && backupAppItemInfo?.backupApk == true) {
+ binding.cbApk.isChecked = true
+ binding.cbApk.isEnabled = false
+ }
+ }
+
+ private fun initListener() {
+ binding.viewCbMask.setOnDoubleCheckClickListener { }
+ binding.cbApk.setOnCheckedChangeListener { _, _ ->
+ updateItemList()
+ }
+ binding.cbData.setOnCheckedChangeListener { _, _ ->
+ updateItemList()
+ }
+ binding.cbAndroidData.setOnCheckedChangeListener { _, _ ->
+ updateItemList()
+ }
+ binding.btnRecover.setOnDoubleCheckClickListener {
+ if (it.tag == true) {
+ toast(getString(R.string.recover_success_launch_app, appName))
+ setResult(RESULT_OK)
+ finish()
+ sendBroadcastComp(ReceiverConstant.ACTION_DELAY_START_APP) {
+ it.putExtra(ExtraKey.PACKAGE_NAME, backupAppItemInfo?.packageName)
+ }
+ return@setOnDoubleCheckClickListener
+ }
+ updateItemList()
+ apkVersionCheck()
+ }
+ val intentFilter = IntentFilter(AppRecoverWorker.ACTION_STEP_STATUS)
+ intentFilter.addAction(AppRecoverWorker.ACTION_SUCCESS)
+ registerReceiverComp(receiver, intentFilter)
+ }
+
+ private fun apkVersionCheck() {
+ val backupVersionCode = backupAppItemInfo?.versionCode ?: return
+ val backupVersionName = backupAppItemInfo?.versionName ?: return
+ val appVersionCode = apkInfo?.packageInfo?.versionCodeLong ?: return
+ val appVersionName = apkInfo?.packageInfo?.versionName ?: return
+ if (!binding.cbApk.isChecked && apkInfo != null && backupVersionCode != appVersionCode) {
+ showDialog(
+ R.string.notice,
+ R.string.apk_version_backup_version_not_same_notice.getString(
+ "$appVersionName($appVersionCode)", "$backupVersionName($backupVersionCode)",
+ ),
+ R.string.ok,
+ R.string.cancel,
+ {
+ systemAppCheck()
+ dismiss()
+ },
+ {
+ dismiss()
+ })
+ return
+ }
+ systemAppCheck()
+ }
+
+ private fun systemAppCheck() {
+ startRecover()
+ }
+
+ private fun startRecover() {
+ val constraints = Constraints.Builder().build()
+ val data = Data.Builder().putString(
+ AppRecoverWorker.DATA, AppRecoverWorkerData(
+ appItemInfo = backupAppItemInfo,
+ appName = appName,
+ recoverApk = binding.cbApk.isChecked,
+ recoverData = binding.cbData.isChecked,
+ recoverAndroidData = binding.cbAndroidData.isChecked
+ ).toJson()
+ ).build()
+ WorkManager.getInstance(this).beginUniqueWork(
+ AppRecoverWorker.TAG,
+ ExistingWorkPolicy.REPLACE,
+ OneTimeWorkRequestBuilder().addTag(AppRecoverWorker.TAG)
+ .setInputData(data).setConstraints(constraints)
+ .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST).build()
+ ).enqueue()
+ binding.viewCbMask.isVisible = true
+ binding.btnRecover.isEnabled = false
+ binding.btnRecover.text = "正在恢复数据..."
+ }
+
+ private fun updateItemList() {
+ timeLineList.clear()
+ if (!binding.cbApk.isChecked && !binding.cbData.isChecked && !binding.cbAndroidData.isChecked) {
+ binding.btnRecover.isEnabled = false
+ adapter.loadData(timeLineList)
+ return
+ }
+ binding.btnRecover.isEnabled = true
+ timeLineList.add(RecoverTimeLineItem("初始化准备", 1))
+ if (binding.cbApk.isChecked) {
+ timeLineList.add(
+ RecoverTimeLineItem(
+ R.string.time_line_recover_title.getString(R.string.item_backup_apk.getString()),
+ 0
+ )
+ )
+ }
+ if (binding.cbData.isChecked) {
+ timeLineList.add(
+ RecoverTimeLineItem(
+ R.string.time_line_recover_title.getString(R.string.item_backup_data.getString()),
+ 0
+ )
+ )
+ }
+ if (binding.cbAndroidData.isChecked) {
+ timeLineList.add(
+ RecoverTimeLineItem(
+ R.string.time_line_recover_title.getString(R.string.item_backup_android_data.getString()),
+ 0
+ )
+ )
+ }
+ timeLineList.last().lineType = 2
+ adapter.loadData(timeLineList)
+ }
+
+ private fun initView() {
+ binding.cbApk.isEnabled = backupAppItemInfo?.backupApk == true
+ binding.cbData.isEnabled = backupAppItemInfo?.backupData == true
+ binding.cbAndroidData.isEnabled = backupAppItemInfo?.backupAndroidData == true
+ binding.rvTimeLine.layoutManager = LinearLayoutManager(this)
+ binding.rvTimeLine.adapter = adapter
+ adapter.register(RecoverTimeLineDelegate())
+ adapter.loadData(timeLineList)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ unregisterReceiver(receiver)
+ }
+
+ private inner class Receiver : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent?) {
+ when (intent?.action) {
+ AppRecoverWorker.ACTION_STEP_STATUS -> {
+ val (step, status) = intent.getSerializableCompat>(ExtraKey.KEY_1)
+ ?: return
+ timeLineList[step].status = RecoverTimeLineItem.Status.get(status)
+ adapter.notifyItemChanged(step)
+ }
+
+ AppRecoverWorker.ACTION_SUCCESS -> {
+ binding.btnRecover.isEnabled = true
+ binding.btnRecover.tag = true
+ binding.btnRecover.text = "打开 $appName"
+ }
+
+ AppRecoverWorker.ACTION_FAILED -> {
+ binding.btnRecover.isEnabled = true
+ binding.viewCbMask.isVisible = false
+ }
+
+ else -> {
+
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupAppActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupAppActivity.kt
new file mode 100644
index 0000000..8b42d40
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupAppActivity.kt
@@ -0,0 +1,55 @@
+package com.wrbug.developerhelper.ui.activity.appbackup
+
+import android.os.Bundle
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.drakeet.multitype.MultiTypeAdapter
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.BaseActivity
+import com.wrbug.developerhelper.base.setupActionBar
+import com.wrbug.developerhelper.commonutil.addTo
+import com.wrbug.developerhelper.commonutil.dpInt
+import com.wrbug.developerhelper.commonutil.runOnIO
+import com.wrbug.developerhelper.databinding.ActivityBackupAppBinding
+import com.wrbug.developerhelper.ui.adapter.ExMultiTypeAdapter
+import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
+import com.wrbug.developerhelper.util.BackupUtils
+
+class BackupAppActivity : BaseActivity() {
+ private val binding by lazy {
+ ActivityBackupAppBinding.inflate(layoutInflater)
+ }
+ private val adapter by ExMultiTypeAdapter.get()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(binding.root)
+ initView()
+ }
+
+ private fun initView() {
+ binding.rvAppList.layoutManager = LinearLayoutManager(this)
+ binding.rvAppList.adapter = adapter
+ binding.rvAppList.addItemDecoration(SpaceItemDecoration.standard)
+ adapter.register(BackupInfoItemDelegate {
+ AppBackupDetailActivity.start(this, it.appName, it.packageName, false)
+ })
+ }
+
+ override fun onStart() {
+ super.onStart()
+ loadData()
+ }
+
+ private fun loadData() {
+ adapter.showLoading()
+ BackupUtils.getAllBackupInfo().runOnIO().subscribe({
+ if (it.isEmpty()) {
+ adapter.showEmpty()
+ return@subscribe
+ }
+ adapter.loadData(it)
+ }, {
+ adapter.showEmpty()
+ }).addTo(disposable)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupDetailDelegate.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupDetailDelegate.kt
new file mode 100644
index 0000000..fec537d
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupDetailDelegate.kt
@@ -0,0 +1,53 @@
+package com.wrbug.developerhelper.ui.activity.appbackup
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.TextView
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.commonutil.byteToShowSize
+import com.wrbug.developerhelper.databinding.ItemBackupDetailInfoBinding
+import com.wrbug.developerhelper.model.entity.BackupAppItemInfo
+import com.wrbug.developerhelper.ui.adapter.delegate.BaseItemViewBindingDelegate
+import com.wrbug.developerhelper.util.BackupUtils
+import com.wrbug.developerhelper.util.format
+import com.wrbug.developerhelper.util.getColor
+import com.wrbug.developerhelper.util.getString
+import java.io.File
+
+class BackupDetailDelegate(private val appName: String) :
+ BaseItemViewBindingDelegate() {
+ override fun onBindViewHolder(binding: ItemBackupDetailInfoBinding, item: BackupAppItemInfo) {
+ binding.tvTime.text = item.time.format()
+ binding.tvTitle.text = item.memo.ifEmpty {
+ binding.root.context.getString(
+ R.string.backup_default_meme,
+ appName
+ )
+ }
+ binding.tvVersion.text = "${getFileSize(item)} | ${item.versionName}(${item.versionCode})"
+ binding.tvBackupApk.setStatusColor(item.backupApk)
+ binding.tvBackupAndroidData.setStatusColor(item.backupAndroidData)
+ binding.tvBackupData.setStatusColor(item.backupData)
+ }
+
+ private fun getFileSize(item: BackupAppItemInfo): String {
+ return File(BackupUtils.getAppBackupDir(item.packageName), item.backupFile).length()
+ .byteToShowSize()
+ }
+
+ private fun TextView.setStatusColor(enable: Boolean) {
+ val color = if (enable) {
+ R.color.material_color_green_500.getColor()
+ } else {
+ R.color.material_color_red_500.getColor()
+ }
+ setTextColor(color)
+ }
+
+ override fun onCreateViewBinding(
+ inflater: LayoutInflater,
+ parent: ViewGroup
+ ): ItemBackupDetailInfoBinding {
+ return ItemBackupDetailInfoBinding.inflate(inflater, parent, false)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupInfoItemDelegate.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupInfoItemDelegate.kt
new file mode 100644
index 0000000..7e7492d
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/BackupInfoItemDelegate.kt
@@ -0,0 +1,63 @@
+package com.wrbug.developerhelper.ui.activity.appbackup
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.commonutil.AppInfoManager
+import com.wrbug.developerhelper.commonutil.SpannableBuilder
+import com.wrbug.developerhelper.commonutil.byteToShowSize
+import com.wrbug.developerhelper.databinding.ItemBackupAppInfoBinding
+import com.wrbug.developerhelper.model.entity.BackupAppData
+import com.wrbug.developerhelper.ui.adapter.delegate.BaseItemViewBindingDelegate
+import com.wrbug.developerhelper.util.BackupUtils
+import com.wrbug.developerhelper.util.format
+import com.wrbug.developerhelper.util.getColor
+import com.wrbug.developerhelper.util.getString
+import com.wrbug.developerhelper.util.loadImage
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+import java.io.File
+
+class BackupInfoItemDelegate(private val listener: (BackupAppData) -> Unit) :
+ BaseItemViewBindingDelegate() {
+ override fun onBindViewHolder(binding: ItemBackupAppInfoBinding, item: BackupAppData) {
+ val appInfo = AppInfoManager.getAppByPackageName(item.packageName)
+ val title = if (appInfo == null) {
+ val tag = R.string.backup_uninstalled_app_tag.getString()
+ SpannableBuilder.with(binding.root.context, tag + " " + item.appName)
+ .addSpanWithColor(tag, R.color.material_color_red_600.getColor()).build()
+ } else if (appInfo.isSystemApp()) {
+ val tag = R.string.backup_system_app_tag.getString()
+ SpannableBuilder.with(binding.root.context, tag + " " + item.appName)
+ .addSpanWithColor(tag, R.color.colorAccent.getColor()).build()
+ } else {
+ item.appName
+ }
+
+ binding.tvAppName.text = title
+ binding.tvAppPackageName.text = item.packageName
+ val size = item.backupMap.size
+ val fileSize = item.backupMap.values.sumOf {
+ File(
+ BackupUtils.getAppBackupDir(it.packageName),
+ it.backupFile
+ ).length()
+ }.byteToShowSize()
+ binding.tvBackupCount.text = SpannableBuilder.with(
+ binding.root.context,
+ R.string.app_info_backup_count.getString(size, fileSize)
+ ).addSpanWithBold(size.toString()).addSpanWithBold(fileSize).build()
+ val time = item.backupMap.values.maxByOrNull { it.time }?.time ?: 0
+ binding.tvLastBackupTime.text = R.string.last_backup_time.getString(time.format())
+ binding.ivIcon.loadImage(item.iconPath, R.drawable.ic_default_app_ico_place_holder)
+ binding.root.setOnDoubleCheckClickListener {
+ listener(item)
+ }
+ }
+
+ override fun onCreateViewBinding(
+ inflater: LayoutInflater,
+ parent: ViewGroup
+ ): ItemBackupAppInfoBinding {
+ return ItemBackupAppInfoBinding.inflate(inflater, parent, false)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/RecoverTimeLineDelegate.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/RecoverTimeLineDelegate.kt
new file mode 100644
index 0000000..956eb05
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/RecoverTimeLineDelegate.kt
@@ -0,0 +1,73 @@
+package com.wrbug.developerhelper.ui.activity.appbackup
+
+import android.graphics.PorterDuff
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
+import com.github.vipulasri.timelineview.TimelineView
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.databinding.ItemRecoverAppTimeLineBinding
+import com.wrbug.developerhelper.ui.activity.appbackup.entity.RecoverTimeLineItem
+import com.wrbug.developerhelper.ui.adapter.delegate.BaseItemViewBindingDelegate
+import com.wrbug.developerhelper.util.getColor
+
+class RecoverTimeLineDelegate :
+ BaseItemViewBindingDelegate() {
+ override fun onBindViewHolder(
+ binding: ItemRecoverAppTimeLineBinding,
+ item: RecoverTimeLineItem
+ ) {
+ binding.textTimelineTitle.text = item.title
+ binding.timeMarker.initLine(item.lineType)
+ when (item.status) {
+ RecoverTimeLineItem.Status.Pending -> {
+ binding.textTimelineContent.text = "等待中"
+ binding.timeMarker.setMarker(
+ R.drawable.ic_marker_inactive,
+ R.color.material_color_grey_500
+ )
+ }
+
+ RecoverTimeLineItem.Status.Running -> {
+ binding.textTimelineContent.text = "运行中"
+ binding.timeMarker.setMarker(
+ R.drawable.ic_marker_active,
+ R.color.colorPrimary
+ )
+ }
+
+ RecoverTimeLineItem.Status.Done -> {
+ binding.textTimelineContent.text = "已完成"
+ binding.timeMarker.setMarker(
+ R.drawable.ic_marker_active,
+ R.color.colorAccent
+ )
+ }
+
+ RecoverTimeLineItem.Status.Failed -> {
+ binding.textTimelineContent.text = "恢复失败"
+ binding.timeMarker.setMarker(
+ R.drawable.ic_marker_active,
+ R.color.material_color_red_300
+ )
+ }
+ }
+ }
+
+ override fun onCreateViewBinding(
+ inflater: LayoutInflater,
+ parent: ViewGroup
+ ): ItemRecoverAppTimeLineBinding {
+ return ItemRecoverAppTimeLineBinding.inflate(inflater, parent, false)
+ }
+
+ private fun TimelineView.setMarker(drawableResId: Int, colorFilter: Int) {
+ marker = VectorDrawableCompat.create(
+ context.resources,
+ drawableResId,
+ context.theme
+ )?.apply {
+ setTint(colorFilter.getColor())
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/entity/RecoverTimeLineItem.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/entity/RecoverTimeLineItem.kt
new file mode 100644
index 0000000..624041a
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/entity/RecoverTimeLineItem.kt
@@ -0,0 +1,17 @@
+package com.wrbug.developerhelper.ui.activity.appbackup.entity
+
+data class RecoverTimeLineItem(
+ val title: String,
+ var lineType: Int,
+ var status: Status = Status.Pending
+) {
+ enum class Status(val status: Int) {
+ Pending(-1), Running(1), Done(0), Failed(2);
+
+ companion object {
+ fun get(status: Int): Status {
+ return entries.find { it.status == status } ?: Pending
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/worker/AppRecoverWorker.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/worker/AppRecoverWorker.kt
new file mode 100644
index 0000000..ce86f28
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/worker/AppRecoverWorker.kt
@@ -0,0 +1,166 @@
+package com.wrbug.developerhelper.ui.activity.appbackup.worker
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+import androidx.work.CoroutineWorker
+import androidx.work.ForegroundInfo
+import androidx.work.WorkerParameters
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.ExtraKey
+import com.wrbug.developerhelper.base.sendBroadcastComp
+import com.wrbug.developerhelper.commonutil.AppInfoManager
+import com.wrbug.developerhelper.commonutil.AppManagerUtils
+import com.wrbug.developerhelper.commonutil.Constant
+import com.wrbug.developerhelper.commonutil.createNotification
+import com.wrbug.developerhelper.commonutil.fromJson
+import com.wrbug.developerhelper.commonutil.shell.ShellManager
+import com.wrbug.developerhelper.ui.activity.appbackup.entity.RecoverTimeLineItem
+import com.wrbug.developerhelper.util.BackupUtils
+import com.wrbug.developerhelper.util.getString
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import java.io.File
+
+class AppRecoverWorker(appContext: Context, params: WorkerParameters) :
+ CoroutineWorker(appContext, params) {
+
+ private val data: AppRecoverWorkerData? by lazy {
+ params.inputData.getString(DATA)?.fromJson()
+ }
+
+ private val workDir by lazy {
+ BackupUtils.getAppBackupDir(data?.appItemInfo?.packageName.orEmpty()).absolutePath
+ }
+ private val tmpDir by lazy {
+ File(workDir, "tmp").absolutePath
+ }
+
+ private var step = 0
+
+ companion object {
+ const val ACTION_STEP_STATUS = "ACTION_STEP_STATUS"
+ const val ACTION_SUCCESS = "ACTION_SUCCESS"
+ const val ACTION_FAILED = "ACTION_FAILED"
+ const val DATA = "data"
+ private const val CHANNEL_ID = "APP_RECOVER_DEMON"
+ const val TAG = "AppRecoverWorker"
+ private const val NOTIFICATION_ID = 1234
+ }
+
+ private val foregroundInfo = ForegroundInfo(
+ NOTIFICATION_ID, createNotification(applicationContext, CHANNEL_ID, "recover") {
+ setContentTitle(R.string.app_name.getString())
+ setSmallIcon(R.drawable.ic_launcher_notify)
+ setContentText(R.string.recovering_app_data.getString(data?.appName.orEmpty()))
+ }, FOREGROUND_SERVICE_TYPE_DATA_SYNC
+ )
+
+ override suspend fun doWork(): Result {
+ setForeground(foregroundInfo)
+ return withContext(Dispatchers.IO) {
+ step = 0
+ if (!prepareExecute()) {
+ sendStatus(RecoverTimeLineItem.Status.Failed)
+ sendComplete(false)
+ return@withContext Result.success()
+ }
+ sendStatus(RecoverTimeLineItem.Status.Done)
+ if (!recoverApk()) {
+ sendStatus(RecoverTimeLineItem.Status.Failed)
+ sendComplete(false)
+ return@withContext Result.success()
+ }
+ sendStatus(RecoverTimeLineItem.Status.Done)
+ if (!recoverData()) {
+ sendStatus(RecoverTimeLineItem.Status.Failed)
+ sendComplete(false)
+ return@withContext Result.success()
+ }
+ sendStatus(RecoverTimeLineItem.Status.Done)
+ if (!recoverAndroidData()) {
+ sendStatus(RecoverTimeLineItem.Status.Failed)
+ sendComplete(false)
+ return@withContext Result.success()
+ }
+ sendStatus(RecoverTimeLineItem.Status.Done)
+ sendComplete(true)
+ Result.success()
+ }
+ }
+
+ private fun recoverAndroidData(): Boolean {
+ if (data?.recoverAndroidData != true) {
+ return true
+ }
+ step++
+ sendStatus(RecoverTimeLineItem.Status.Running)
+ val androidDataDir = "/sdcard/Android/data/" + data?.appItemInfo?.packageName
+ if (ShellManager.mkDir(androidDataDir)) {
+ return false
+ }
+ return ShellManager.tarXF(tmpDir + "/" + data?.appItemInfo?.androidDataFile, androidDataDir)
+ }
+
+ private fun recoverData(): Boolean {
+ if (data?.recoverData != true) {
+ return true
+ }
+ step++
+ sendStatus(RecoverTimeLineItem.Status.Running)
+ val dataDir = Constant.getDataDir(data?.appItemInfo?.packageName.orEmpty())
+ val map = ShellManager.getDataDirUserAndGroup(dataDir)
+ if (!ShellManager.tarXF(tmpDir + "/" + data?.appItemInfo?.dataFile, "$dataDir/")) {
+ return false
+ }
+ return ShellManager.chownDataDir(dataDir, map)
+ }
+
+ private fun recoverApk(): Boolean {
+ if (data?.recoverApk != true) {
+ return true
+ }
+ step++
+ sendStatus(RecoverTimeLineItem.Status.Running)
+ if (AppInfoManager.isInstalled(data?.appItemInfo?.packageName.orEmpty())) {
+ val result = ShellManager.uninstallApk(data?.appItemInfo?.packageName.orEmpty())
+ if (!result) {
+ return false
+ }
+ }
+ val tmpApk = "/data/local/tmp/" + data?.appItemInfo?.packageName + ".apk"
+ if (!ShellManager.cpFile(tmpDir + "/" + data?.appItemInfo?.apkFile, tmpApk)) {
+ return false
+ }
+ return ShellManager.installApk(tmpApk)
+ }
+
+ private fun prepareExecute(): Boolean {
+ sendStatus(RecoverTimeLineItem.Status.Running)
+ AppManagerUtils.forceStopApp(data?.appItemInfo?.packageName.orEmpty())
+ if (!ShellManager.rmFile(tmpDir)) {
+ return false
+ }
+ if (!ShellManager.mkDir(tmpDir)) {
+ return false
+ }
+ return ShellManager.tarXF(
+ File(workDir, data?.appItemInfo?.backupFile.orEmpty()).absolutePath, tmpDir
+ )
+ }
+
+
+ override suspend fun getForegroundInfo(): ForegroundInfo {
+ return foregroundInfo
+ }
+
+ private fun sendStatus(status: RecoverTimeLineItem.Status) {
+ applicationContext.sendBroadcastComp(ACTION_STEP_STATUS) {
+ it.putExtra(ExtraKey.KEY_1, step to status.status)
+ }
+ }
+
+ private fun sendComplete(success: Boolean) {
+ applicationContext.sendBroadcastComp(if (success) ACTION_SUCCESS else ACTION_FAILED)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/worker/AppRecoverWorkerData.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/worker/AppRecoverWorkerData.kt
new file mode 100644
index 0000000..befe60f
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/appbackup/worker/AppRecoverWorkerData.kt
@@ -0,0 +1,14 @@
+package com.wrbug.developerhelper.ui.activity.appbackup.worker
+
+import android.os.Parcelable
+import com.wrbug.developerhelper.model.entity.BackupAppItemInfo
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+class AppRecoverWorkerData(
+ val appItemInfo: BackupAppItemInfo?,
+ val appName: String,
+ val recoverApk: Boolean,
+ val recoverData: Boolean,
+ val recoverAndroidData: Boolean
+) : Parcelable
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseEditActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseEditActivity.kt
index cdfe075..0aafbf5 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseEditActivity.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseEditActivity.kt
@@ -10,23 +10,24 @@ import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.evrencoskun.tableview.listener.ITableViewListener
import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseActivity
-import com.wrbug.developerhelper.basecommon.setupActionBar
-import com.wrbug.developerhelper.basecommon.showToast
+import com.wrbug.developerhelper.base.*
import com.wrbug.developerhelper.model.entity.DatabaseTableInfo
import com.wrbug.developerhelper.commonutil.shell.ShellManager
import com.wrbug.developerhelper.util.DatabaseUtils
import com.wrbug.developerhelper.commonutil.dp2px
-import kotlinx.android.synthetic.main.activity_database_edit.*
+import com.wrbug.developerhelper.databinding.ActivityDatabaseEditBinding
import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.toast
import org.jetbrains.anko.uiThread
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
-class DatabaseEditActivity : BaseActivity() {
+class DatabaseEditActivity: BaseActivity() {
+
private var filePath: String? = ""
private lateinit var dbPath: File
+ private lateinit var dataBinding: ActivityDatabaseEditBinding
private val tableNames = ArrayList()
private var dbMap: Map = TreeMap()
private val adapter = DatabaseTableAdapter(this)
@@ -40,6 +41,7 @@ class DatabaseEditActivity : BaseActivity() {
}
companion object {
+
fun start(context: Context, filePath: String) {
val intent = Intent(context, DatabaseEditActivity::class.java)
intent.putExtra("filePath", filePath)
@@ -49,12 +51,13 @@ class DatabaseEditActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_database_edit)
+ dataBinding = ActivityDatabaseEditBinding.inflate(layoutInflater)
+ setContentView(dataBinding.root)
intent?.run {
filePath = getStringExtra("filePath")
}
if (filePath.isNullOrEmpty()) {
- showToast(getString(R.string.get_database_failed))
+ toast(getString(R.string.get_database_failed))
finish()
return
}
@@ -67,8 +70,8 @@ class DatabaseEditActivity : BaseActivity() {
}
private fun initTableView() {
- tableView.adapter = adapter
- tableView.tableViewListener = object : ITableViewListener {
+ dataBinding.tableView.adapter = adapter
+ dataBinding.tableView.tableViewListener = object: ITableViewListener {
override fun onCellLongPressed(p0: RecyclerView.ViewHolder, p1: Int, p2: Int) {
}
@@ -96,10 +99,11 @@ class DatabaseEditActivity : BaseActivity() {
if (dstDir.exists().not()) {
dstDir.mkdir()
}
- val success = ShellManager.cpFile(dbPath.absolutePath, "${dstDir.absolutePath}/${dbPath.name}")
+ val success =
+ ShellManager.cpFile(dbPath.absolutePath, "${dstDir.absolutePath}/${dbPath.name}")
if (!success) {
uiThread {
- showToast(getString(R.string.get_database_failed))
+ toast(getString(R.string.get_database_failed))
finish()
}
return@doAsync
@@ -115,11 +119,13 @@ class DatabaseEditActivity : BaseActivity() {
}
}
-
private fun setTableContainer() {
- tableNameContainer.removeAllViews()
+ dataBinding.tableNameContainer.removeAllViews()
val layoutParams =
- LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
val dp10 = dp2px(10F)
val dp20 = dp2px(20F)
tableNames.forEachIndexed { index, name ->
@@ -135,7 +141,7 @@ class DatabaseEditActivity : BaseActivity() {
tv.setOnClickListener {
selectTable(it.tag as Int)
}
- tableNameContainer.addView(tv, layoutParams)
+ dataBinding.tableNameContainer.addView(tv, layoutParams)
}
}
@@ -161,9 +167,9 @@ class DatabaseEditActivity : BaseActivity() {
uiThread {
setHasData(!cell.isEmpty())
adapter.setAllItems(keyList, rowHeaders, cell)
- var tv = tableNameContainer.getChildAt(selectedIndex) as TextView
+ var tv = dataBinding.tableNameContainer.getChildAt(selectedIndex) as TextView
tv.setTextColor(resources.getColor(R.color.text_color_666666))
- tv = tableNameContainer.getChildAt(position) as TextView
+ tv = dataBinding.tableNameContainer.getChildAt(position) as TextView
tv.setTextColor(resources.getColor(R.color.colorPrimary))
selectedIndex = position
}
@@ -172,7 +178,7 @@ class DatabaseEditActivity : BaseActivity() {
}
private fun setHasData(hasData: Boolean) {
- noDataTv.visibility = if (hasData) View.GONE else View.VISIBLE
- tableView.visibility = if (hasData) View.VISIBLE else View.GONE
+ dataBinding.noDataTv.visibility = if (hasData) View.GONE else View.VISIBLE
+ dataBinding.tableView.visibility = if (hasData) View.VISIBLE else View.GONE
}
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseTableAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseTableAdapter.kt
index 9ee8514..680b799 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseTableAdapter.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/databaseedit/DatabaseTableAdapter.kt
@@ -1,5 +1,6 @@
package com.wrbug.developerhelper.ui.activity.databaseedit
+import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
@@ -55,6 +56,7 @@ class DatabaseTableAdapter(val context: Context) : AbstractTableAdapter? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_guide)
- mSectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager)
- viewPager.adapter = mSectionsPagerAdapter
- viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageSelected(position: Int) {
- currentPosition = position
- updateIndicators(position)
- viewPager.setBackgroundColor(bgColors[position])
- buttonPre.visibility = if (position == 0) View.GONE else View.VISIBLE
- buttonNext.visibility = if (position == 2) View.GONE else View.VISIBLE
- buttonFinish.visibility = if (position == 2) View.VISIBLE else View.GONE
- }
-
- override fun onPageScrollStateChanged(position: Int) {
-
- }
-
- override fun onPageScrolled(p0: Int, p1: Float, p2: Int) {
- val colorUpdate = ArgbEvaluator().evaluate(
- p1,
- bgColors[p0],
- bgColors[if (p0 == 2) p0 else p0 + 1]
- ) as Int
- viewPager.setBackgroundColor(colorUpdate)
- }
-
- })
- indicators = arrayOf(imageViewIndicator0 as View, imageViewIndicator1 as View, imageViewIndicator2 as View)
- }
-
- private fun updateIndicators(position: Int) {
- for (i in 0 until indicators?.size!!) {
- indicators?.get(i)?.setBackgroundResource(
- if (i == position) R.drawable.onboarding_indicator_selected else R.drawable.onboarding_indicator_unselected
- )
- }
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepAccessibilityFragment.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepAccessibilityFragment.kt
deleted file mode 100644
index 1466d40..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepAccessibilityFragment.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.guide
-
-import android.content.Intent
-import android.os.Bundle
-import android.provider.Settings
-import android.view.View
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.service.AccessibilityManager
-import com.wrbug.developerhelper.service.DeveloperHelperAccessibilityService
-import kotlinx.android.synthetic.main.fragment_guide.*
-
-class GuideStepAccessibilityFragment : GuideStepFragment() {
- override fun getLabelText(): String {
- return "无障碍功能"
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- checkIsOpen()
- icoIv.setImageResource(R.drawable.ic_accessibility_black)
- contentTv.setOnClickListener {
- if (DeveloperHelperAccessibilityService.serviceRunning) {
- return@setOnClickListener
- }
- AccessibilityManager.startService(activity)
-
- }
- }
-
- private fun checkIsOpen() {
- contentTv.text =
- if (DeveloperHelperAccessibilityService.serviceRunning) "无障碍辅助已开启" else "无障碍辅助已关闭,将无法分析布局和页面信息,点击开启"
- }
-
- override fun onResume() {
- super.onResume()
- checkIsOpen()
- }
-
- companion object {
- fun instance(): GuideStepAccessibilityFragment {
- val fragment = GuideStepAccessibilityFragment()
- return fragment
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepFloatWindowFragment.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepFloatWindowFragment.kt
deleted file mode 100644
index 3e5fd57..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepFloatWindowFragment.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.guide
-
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.provider.Settings
-import android.view.View
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.service.FloatWindowService
-import com.wrbug.developerhelper.util.DeviceUtils
-import kotlinx.android.synthetic.main.fragment_guide.*
-
-class GuideStepFloatWindowFragment : GuideStepFragment() {
- override fun getLabelText(): String {
- return getString(R.string.float_window_permission)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- icoIv.setImageResource(R.drawable.ic_float_air_bubble)
- contentTv.setOnClickListener {
- if (DeviceUtils.isFloatWindowOpened(activity!!)) {
- return@setOnClickListener
- }
- startActivityForResult(
- Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:${activity?.packageName}")),
- 0
- )
- }
- }
-
- override fun onResume() {
- super.onResume()
- checkFloatWindow()
- }
-
- private fun checkFloatWindow() {
- if (activity != null && DeviceUtils.isFloatWindowOpened(activity!!)) {
- contentTv.text = getString(R.string.float_window_opened)
- FloatWindowService.start(activity!!)
- } else {
- contentTv.text = getString(R.string.float_window_closed)
- }
- }
-
- companion object {
- fun instance(): GuideStepFloatWindowFragment {
- val fragment = GuideStepFloatWindowFragment()
- return fragment
- }
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- if (requestCode == 0) {
- checkFloatWindow()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepFragment.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepFragment.kt
deleted file mode 100644
index 772c1d3..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/GuideStepFragment.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.guide
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseFragment
-import kotlinx.android.synthetic.main.fragment_guide.view.*
-
-
- abstract class GuideStepFragment : BaseFragment() {
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val rootView = inflater.inflate(R.layout.fragment_guide, container, false)
- rootView.labelTv.text = getLabelText()
- return rootView
- }
- abstract fun getLabelText(): String
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/SectionsPagerAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/SectionsPagerAdapter.kt
deleted file mode 100644
index 9515409..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/guide/SectionsPagerAdapter.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.guide
-
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentPagerAdapter
-
-class SectionsPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
- private val fragments = arrayOf(
- GuideStepFloatWindowFragment.instance(),
- GuideStepAccessibilityFragment.instance()
- )
-
- override fun getItem(position: Int): Fragment {
- return fragments[position]
- }
-
- override fun getCount(): Int {
- return fragments.size
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoDialog.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoDialog.kt
index 4d4e06e..0e85d4c 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoDialog.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoDialog.kt
@@ -9,64 +9,74 @@ import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import com.wrbug.developerhelper.R
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
-import com.wrbug.developerhelper.commonutil.entity.TopActivityInfo
import com.wrbug.developerhelper.commonutil.UiUtils
import com.wrbug.developerhelper.commonutil.dp2px
-import kotlinx.android.synthetic.main.dialog_apk_info.*
+import com.wrbug.developerhelper.databinding.DialogApkInfoBinding
+import com.wrbug.developerhelper.util.isPortrait
+import io.reactivex.rxjava3.disposables.CompositeDisposable
class AppInfoDialog : DialogFragment() {
- private var apkInfo: ApkInfo? = null
- private var topActivity: TopActivityInfo? = null
+
+ private val apkInfo: ApkInfo? by lazy {
+ arguments?.getParcelable("apkInfo")
+ }
private var listener: AppInfoDialogEventListener? = null
+ private lateinit var binding: DialogApkInfoBinding
+ private lateinit var disposable: CompositeDisposable
+ private val pagerAdapter by lazy {
+ AppInfoPagerAdapter(this, disposable)
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setStyle(DialogFragment.STYLE_NORMAL, R.style.FullScreenDialog)
- arguments?.let {
- apkInfo = it.getParcelable("apkInfo")
- topActivity = it.getParcelable("topActivity")
- }
+ setStyle(STYLE_NORMAL, R.style.FullScreenDialog)
}
- override fun onAttach(activity: Activity?) {
+ override fun onAttach(activity: Activity) {
super.onAttach(activity)
if (activity is AppInfoDialogEventListener) {
listener = activity
}
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- val view = inflater.inflate(R.layout.dialog_apk_info, container, false)
- dialog.window.takeUnless {
- it == null
- }?.run {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View {
+ disposable = CompositeDisposable()
+ binding = DialogApkInfoBinding.inflate(inflater, container, false)
+ dialog?.window?.run {
val layoutParams = attributes
- layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
- layoutParams.height = UiUtils.getDeviceHeight() / 2 + dp2px(40F)
+ if (isPortrait()) {
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
+ layoutParams.height = UiUtils.getDeviceHeight() / 2 + dp2px(40F)
+ setGravity(Gravity.TOP)
+ } else {
+ layoutParams.width = UiUtils.getDeviceWidth() / 2
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
+ setGravity(Gravity.END)
+ }
attributes = layoutParams
- setGravity(Gravity.TOP)
}
- return view
+ return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- titleContainer.setPadding(0, UiUtils.getStatusHeight(), 0, 0)
- activity?.let {
- val pagerAdapter = AppInfoPagerAdapter(this, apkInfo, topActivity)
- pagerAdapter.listener = listener
- viewPager.adapter = pagerAdapter
- tabLayout.setupWithViewPager(viewPager)
- }
- apkInfo?.let { it ->
- logoIv.setImageDrawable(it.getIco())
- titleTv.text = it.getAppName()
- subTitleTv.text = it.applicationInfo.packageName
+ binding.titleContainer.setPadding(0, UiUtils.getStatusHeight(), 0, 0)
+ pagerAdapter.listener = listener
+ binding.viewPager.adapter = pagerAdapter
+ binding.tabLayout.setupWithViewPager(binding.viewPager)
+ apkInfo?.let {
+ binding.logoIv.setImageDrawable(it.getIco())
+ binding.titleTv.text = it.getAppName()
+ binding.subTitleTv.text = it.applicationInfo.packageName
}
+ pagerAdapter.loadData(apkInfo)
}
-
override fun onDestroyView() {
- super.onDestroyView()
listener?.close()
+ disposable.dispose()
+ super.onDestroyView()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoPagerAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoPagerAdapter.kt
index a118cb8..44079d1 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoPagerAdapter.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoPagerAdapter.kt
@@ -3,61 +3,71 @@ package com.wrbug.developerhelper.ui.activity.hierachy
import android.content.Context
import android.view.View
import android.view.ViewGroup
+import androidx.annotation.Keep
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.PagerAdapter
import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.versionCodeLong
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
-import com.wrbug.developerhelper.commonutil.entity.TopActivityInfo
import com.wrbug.developerhelper.commonutil.shell.ShellManager
import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
import com.wrbug.developerhelper.ui.widget.appdatainfoview.AppDataInfoView
import com.wrbug.developerhelper.ui.widget.appsettingview.AppSettingView
import com.wrbug.developerhelper.ui.widget.layoutinfoview.infopage.InfoAdapter
import com.wrbug.developerhelper.ui.widget.layoutinfoview.infopage.ItemInfo
-import com.wrbug.developerhelper.util.EnforceUtils
import com.wrbug.developerhelper.commonutil.UiUtils
import com.wrbug.developerhelper.util.format
import com.wrbug.developerhelper.util.getString
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import io.reactivex.rxjava3.disposables.CompositeDisposable
import java.util.ArrayList
+@Keep
class AppInfoPagerAdapter(
- private val dialog: AppInfoDialog,
- private val apkInfo: ApkInfo?,
- private val topActivity: TopActivityInfo?
-) :
- PagerAdapter() {
- private val context: Context = dialog.activity!!
+ private val dialog: AppInfoDialog, private val disposable: CompositeDisposable
+) : PagerAdapter() {
+
+ private val context: Context = dialog.requireContext()
private val tabList = arrayListOf()
private val viewList = arrayListOf()
- private val adapter = InfoAdapter(context)
- private val enforceItem = ItemInfo(context.getString(R.string.enforce_type), context.getString(R.string.analyzing))
+ private val adapter by lazy {
+ InfoAdapter(context, analyzeItem)
+ }
var listener: AppInfoDialogEventListener? = null
- private val itemInfos = ArrayList()
+ private val itemInfos = ArrayList()
+ private val analyzeItem by lazy {
+ ItemInfo(getString(R.string.page_analyze), getString(R.string.click_to_analyze)).apply {
+ showCopy = false
+ textColor = context.resources.getColor(R.color.colorPrimaryDark)
+ setOnClickListener(View.OnClickListener {
+ listener?.showHierachyView()
+ dialog.dismissAllowingStateLoss()
+ })
+ }
+ }
- init {
- initAppInfoTab()
- initAppDataInfoTab()
- initAppSettingTab()
+ fun loadData(apkInfo: ApkInfo?) {
+ initAppInfoTab(apkInfo)
+ initAppDataInfoTab(apkInfo)
+ initAppSettingTab(apkInfo)
+ notifyDataSetChanged()
}
- private fun initAppSettingTab() {
+ private fun initAppSettingTab(apkInfo: ApkInfo?) {
tabList.add(context.getString(R.string.app_setting))
val view = AppSettingView(context)
- view.apkInfo = apkInfo
+ view.setApkInfo(apkInfo)
viewList.add(view)
}
- private fun initAppDataInfoTab() {
+ private fun initAppDataInfoTab(apkInfo: ApkInfo?) {
tabList.add(context.getString(R.string.data_info))
val appDataInfoView = AppDataInfoView(context)
viewList.add(appDataInfoView)
appDataInfoView.apkInfo = apkInfo
}
- private fun initAppInfoTab() {
+ private fun initAppInfoTab(apkInfo: ApkInfo?) {
tabList.add(context.getString(R.string.base_info))
val rv = RecyclerView(context)
viewList.add(rv)
@@ -68,64 +78,31 @@ class AppInfoPagerAdapter(
itemDecoration.setFirstTopPadding(UiUtils.dp2px(context, 10F))
rv.addItemDecoration(itemDecoration)
apkInfo?.let { it ->
- val item = ItemInfo(getString(R.string.page_analyze), getString(R.string.click_to_analyze))
- item.setOnClickListener(View.OnClickListener {
- listener?.showHierachyView()
- dialog.dismissAllowingStateLoss()
- })
- itemInfos.add(item)
- itemInfos.add(ItemInfo("VersionCode", it.packageInfo.versionCode))
- itemInfos.add(ItemInfo("VersionName", it.packageInfo.versionName))
- topActivity?.let {
- itemInfos.add(ItemInfo("Activity", it.activity))
- it.fragments.takeUnless { fragments ->
- fragments.isNullOrEmpty()
- }?.forEach {
- if (it.hidden.not()) {
- itemInfos.add(ItemInfo("Fragment", it.name))
- }
- }
- }
+ itemInfos.add(ItemInfo("PackageName", it.packageInfo.packageName))
it.applicationInfo.className?.let { name ->
itemInfos.add(ItemInfo("Application", name))
}
- itemInfos.add(enforceItem)
+ it.topActivity.takeIf { it.isNotEmpty() }?.let {
+ itemInfos.add(ItemInfo("Activity", it))
+ }
+ itemInfos.add(ItemInfo("VersionName", it.packageInfo.versionName))
+ itemInfos.add(ItemInfo("VersionCode", it.packageInfo.versionCodeLong))
itemInfos.add(ItemInfo("uid", it.applicationInfo.uid))
- ShellManager.getPid(it.packageInfo.packageName).takeUnless {
- it.isEmpty()
- }?.let {
+ ShellManager.getPid(it.packageInfo.packageName).takeUnless { it.isEmpty() }?.let {
itemInfos.add(ItemInfo("Pid", it))
}
itemInfos.add(
ItemInfo(
- getString(R.string.first_install_time),
- it.packageInfo.firstInstallTime.format()
+ getString(R.string.first_install_time), it.packageInfo.firstInstallTime.format()
)
)
itemInfos.add(
ItemInfo(
- getString(R.string.last_update_time),
- it.packageInfo.lastUpdateTime.format()
+ getString(R.string.last_update_time), it.packageInfo.lastUpdateTime.format()
)
)
itemInfos.add(ItemInfo("DataDir", it.applicationInfo.dataDir))
adapter.setItems(itemInfos)
- getEnforce(it.packageInfo.packageName)
- }
- }
-
- private fun setEnforceType(type: EnforceUtils.EnforceType) {
- enforceItem.content = type.type
- }
-
- private fun getEnforce(packageName: String) {
- doAsync {
- val type = EnforceUtils.getEnforceType(packageName)
- uiThread {
- setEnforceType(type)
- adapter.notifyItemChanged(enforceItem)
- }
-
}
}
@@ -137,7 +114,6 @@ class AppInfoPagerAdapter(
return tabList.size
}
-
override fun instantiateItem(container: ViewGroup, position: Int): Any {
container.addView(viewList[position])
return viewList[position]
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/HierarchyActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/HierarchyActivity.kt
index eed2cf4..5aaea85 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/HierarchyActivity.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/HierarchyActivity.kt
@@ -7,44 +7,39 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.View
-import com.google.gson.reflect.TypeToken
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseActivity
-import com.wrbug.developerhelper.constant.ReceiverConstant
+import com.wrbug.developerhelper.base.BaseActivity
+import com.wrbug.developerhelper.base.entry.HierarchyNode
+import com.wrbug.developerhelper.base.registerReceiverComp
+import com.wrbug.developerhelper.commonutil.GlobalEvent
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
-import com.wrbug.developerhelper.model.entity.HierarchyNode
-import com.wrbug.developerhelper.commonutil.entity.TopActivityInfo
-import com.wrbug.developerhelper.ui.widget.hierarchyView.HierarchyView
-import com.wrbug.developerhelper.commonutil.JsonHelper
import com.wrbug.developerhelper.constant.ReceiverConstant.ACTION_FINISH_HIERACHY_Activity
-import com.wrbug.developerhelper.service.FloatWindowService
-import com.wrbug.developerhelper.ui.widget.layoutinfoview.LayoutInfoView
-import com.wrbug.developerhelper.ui.widget.layoutinfoview.OnNodeChangedListener
-import kotlinx.android.synthetic.main.activity_hierarchy.*
+import com.wrbug.developerhelper.databinding.ActivityHierarchyBinding
+import com.wrbug.developerhelper.service.FloatingWindowService
+import com.wrbug.developerhelper.ui.widget.hierarchyView.HierarchyView
+import com.wrbug.developerhelper.ui.widget.layoutinfoview.LayoutInfoDialog
import java.lang.ref.WeakReference
-class HierarchyActivity : BaseActivity(), AppInfoDialogEventListener, OnNodeChangedListener {
-
+class HierarchyActivity : BaseActivity(), AppInfoDialogEventListener {
- private var apkInfo: ApkInfo? = null
- private var nodeList: List? = null
- private var nodeMap: HashMap? = null
+ private val apkInfo: ApkInfo? by lazy {
+ intent?.getParcelableExtra("apkInfo")
+ }
+ private val nodeList: ArrayList? by lazy {
+ intent?.getParcelableArrayListExtra("node")
+ }
private var showHierachyView = false
- private var topActivity: TopActivityInfo? = null
+ private lateinit var binding: ActivityHierarchyBinding
companion object {
+
fun start(
- context: Context?,
- apkInfo: ApkInfo?,
- node: ArrayList?,
- topActivity: TopActivityInfo?
+ context: Context?, apkInfo: ApkInfo?, node: ArrayList
) {
val intent = Intent(context, HierarchyActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val bundle = Bundle()
bundle.putParcelable("apkInfo", apkInfo)
bundle.putParcelableArrayList("node", node)
- bundle.putParcelable("topActivity", topActivity)
intent.putExtras(bundle)
context?.startActivity(intent)
}
@@ -57,7 +52,7 @@ class HierarchyActivity : BaseActivity(), AppInfoDialogEventListener, OnNodeChan
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
- ReceiverConstant.ACTION_FINISH_HIERACHY_Activity -> {
+ ACTION_FINISH_HIERACHY_Activity -> {
reference?.get()?.finish()
}
@@ -69,56 +64,70 @@ class HierarchyActivity : BaseActivity(), AppInfoDialogEventListener, OnNodeChan
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_hierarchy)
- intent?.run {
- apkInfo = getParcelableExtra("apkInfo")
- nodeList = getParcelableArrayListExtra("node")
- topActivity = getParcelableExtra("topActivity")
- val json = getStringExtra("nodeMap")
- nodeMap = JsonHelper.fromJson(json, object : TypeToken>() {}.type)
- }
+ binding = ActivityHierarchyBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ checkNodeList()
val filter = IntentFilter(ACTION_FINISH_HIERACHY_Activity)
receiver.setActivity(this)
- registerReceiver(receiver, filter)
+ GlobalEvent.register(GlobalEvent.Action.CloseAll, createTime) {
+ finish()
+ }
+ registerReceiverComp(receiver, filter)
showAppInfoDialog()
- FloatWindowService.setFloatButtonVisible(this, false)
+ FloatingWindowService.setFloatButtonVisible(this, false)
+ }
+
+ private fun checkNodeList() {
+ nodeList ?: return
+ if ((nodeList?.size ?: 0) <= 1) {
+ return
+ }
+ var hierarchyNode: HierarchyNode? = null
+ nodeList?.forEach {
+ if (hierarchyNode == null) {
+ hierarchyNode = it
+ } else if (hierarchyNode?.screenBounds?.let { it1 -> it.screenBounds?.contains(it1) } == true) {
+ hierarchyNode = it
+ }
+ }
+ nodeList?.clear()
+ hierarchyNode?.let {
+ nodeList?.add(it)
+ }
}
private fun showAppInfoDialog() {
val dialog = AppInfoDialog()
val bundle = Bundle()
bundle.putParcelable("apkInfo", apkInfo)
- bundle.putParcelable("topActivity", topActivity)
dialog.arguments = bundle
dialog.show(supportFragmentManager, "")
}
override fun showHierachyView() {
showHierachyView = true
- hierarchyView.setHierarchyNodes(nodeList)
- hierarchyView.setOnHierarchyNodeClickListener(object : HierarchyView.OnHierarchyNodeClickListener {
+ binding.hierarchyView.setHierarchyNodes(nodeList)
+ binding.hierarchyView.setOnHierarchyNodeClickListener(object :
+ HierarchyView.OnHierarchyNodeClickListener {
override fun onClick(node: HierarchyNode, parentNode: HierarchyNode?) {
- hierarchyDetailView.visibility = View.VISIBLE
- hierarchyDetailView.setNode(node, parentNode)
- val layoutInfoView = LayoutInfoView(context, nodeList, node)
- layoutInfoView.setOnNodeChangedListener(this@HierarchyActivity)
- layoutInfoView.show()
+ binding.hierarchyDetailView.visibility = View.VISIBLE
+ binding.hierarchyDetailView.setNode(node, parentNode)
+ LayoutInfoDialog.show(supportFragmentManager, nodeList, node) { node, parentNode ->
+ binding.hierarchyDetailView.setNode(node, parentNode)
+ }
}
override fun onSelectedNodeChanged(node: HierarchyNode, parentNode: HierarchyNode?) {
- hierarchyDetailView.visibility = View.VISIBLE
- hierarchyDetailView.setNode(node, parentNode)
+ binding.hierarchyDetailView.visibility = View.VISIBLE
+ binding.hierarchyDetailView.setNode(node, parentNode)
}
})
}
- override fun onChanged(node: HierarchyNode, parentNode: HierarchyNode?) {
- hierarchyDetailView.setNode(node, parentNode)
- }
-
override fun onDestroy() {
- FloatWindowService.setFloatButtonVisible(this, true)
+ FloatingWindowService.setFloatButtonVisible(this, true)
unregisterReceiver(receiver)
+ GlobalEvent.unRegister(GlobalEvent.Action.CloseAll, createTime)
super.onDestroy()
}
@@ -129,12 +138,17 @@ class HierarchyActivity : BaseActivity(), AppInfoDialogEventListener, OnNodeChan
}
override fun onBackPressed() {
- if (hierarchyDetailView.visibility == View.VISIBLE) {
- hierarchyDetailView.visibility = View.GONE
+ if (binding.hierarchyDetailView.visibility == View.VISIBLE) {
+ binding.hierarchyDetailView.visibility = View.GONE
+ return
+ }
+ if (showHierachyView) {
+ showHierachyView = false
+ binding.hierarchyView.visibility = View.GONE
+ showAppInfoDialog()
return
}
super.onBackPressed()
}
-
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/MainActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/MainActivity.kt
index 41f1901..598ceb2 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/MainActivity.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/MainActivity.kt
@@ -1,200 +1,220 @@
package com.wrbug.developerhelper.ui.activity.main
-import android.content.*
+import android.Manifest
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
import android.net.Uri
+import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.Menu
import android.view.MenuItem
-import android.widget.CompoundButton
import androidx.appcompat.app.AlertDialog
-import androidx.databinding.DataBindingUtil
-import com.wrbug.developerhelper.BuildConfig
+import androidx.core.view.isVisible
import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseVMActivity
-import com.wrbug.developerhelper.basecommon.obtainViewModel
-import com.wrbug.developerhelper.basecommon.setupActionBar
-import com.wrbug.developerhelper.basecommon.showToast
+import com.wrbug.developerhelper.base.BaseActivity
+import com.wrbug.developerhelper.base.registerReceiverComp
+import com.wrbug.developerhelper.base.requestStoragePermission
+import com.wrbug.developerhelper.base.setupActionBar
import com.wrbug.developerhelper.commonutil.ClipboardUtils
-import com.wrbug.developerhelper.commonutil.shell.Callback
+import com.wrbug.developerhelper.commonutil.shell.ShellManager
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
import com.wrbug.developerhelper.constant.ReceiverConstant
import com.wrbug.developerhelper.databinding.ActivityMainBinding
+import com.wrbug.developerhelper.mmkv.ConfigKv
+import com.wrbug.developerhelper.mmkv.manager.MMKVManager
+import com.wrbug.developerhelper.model.entity.VersionInfo
import com.wrbug.developerhelper.service.AccessibilityManager
-import com.wrbug.developerhelper.service.FloatWindowService
-import com.wrbug.developerhelper.commonutil.shell.ShellManager
-import com.wrbug.developerhelper.ui.activity.main.viewmodel.MainViewModel
-import com.wrbug.developerhelper.ui.widget.settingitemview.SettingItemView
+import com.wrbug.developerhelper.service.DeveloperHelperAccessibilityService
+import com.wrbug.developerhelper.service.FloatingWindowService
+import com.wrbug.developerhelper.ui.activity.appbackup.BackupAppActivity
import com.wrbug.developerhelper.util.DeviceUtils
-import com.wrbug.developerhelper.commonutil.toInt
-import com.wrbug.developerhelper.model.entity.VersionInfo
-import com.wrbug.developerhelper.ui.activity.xposed.xposedsetting.XposedSettingActivity
-import com.wrbug.developerhelper.util.UpdateUtils
-import kotlinx.android.synthetic.main.activity_main.*
-
-
-class MainActivity : BaseVMActivity() {
+class MainActivity : BaseActivity() {
+ private val configKv: ConfigKv = MMKVManager.get(ConfigKv::class.java)
+ private val binding: ActivityMainBinding by lazy {
+ ActivityMainBinding.inflate(layoutInflater)
+ }
- lateinit var binding: ActivityMainBinding
- lateinit var xposedSettingView: SettingItemView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (DeviceUtils.isFloatWindowOpened()) {
- FloatWindowService.start(this)
- "".toInt()
+ FloatingWindowService.start(this)
}
- binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
- binding.presenter = Presenter()
- xposedSettingView = binding.xposedSettingView
- binding.mainVm = vm
- setupActionBar(R.id.toolbar) {
-
- }
-
+ setContentView(binding.root)
+ setupActionBar(R.id.toolbar)
ShellManager.openAccessibilityService()
+ initView()
initListener()
val filter = IntentFilter(ReceiverConstant.ACTION_ACCESSIBILITY_SERVICE_STATUS_CHANGED)
- registerReceiver(receiver, filter)
+ registerReceiverComp(receiver, filter)
+ }
+
+ private fun initView() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ binding.notificationSettingView.checkable = false
+ binding.notificationSettingView.isVisible = true
+ binding.notificationSettingView.checked =
+ hasPermission(Manifest.permission.POST_NOTIFICATIONS)
+ } else {
+ binding.notificationSettingView.isVisible = false
+ }
}
private fun initListener() {
- floatWindowSettingView.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { _, isChecked ->
+ binding.floatWindowSettingView.setOnCheckedChangeListener { _, isChecked ->
if (isChecked && DeviceUtils.isFloatWindowOpened()) {
- FloatWindowService.start(this)
+ FloatingWindowService.start(this)
} else {
- FloatWindowService.stop(this)
+ FloatingWindowService.stop(this)
}
- })
- rootSettingView.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { _, _ ->
-
- })
- xposedSettingView.setOnClickListener {
- if (xposedSettingView.isChecked().not()) {
- showSnack(getString(R.string.open_xposed_first))
- return@setOnClickListener
+ }
+ binding.backupAppSettingView.setOnDoubleCheckClickListener {
+ requestStoragePermission {
+ startActivity(Intent(this, BackupAppActivity::class.java))
}
- startActivity(Intent(this, XposedSettingActivity::class.java))
}
- }
-
- override fun getViewModel(): MainViewModel {
- return obtainViewModel(MainViewModel::class.java)
- }
-
- override fun onDestroy() {
- super.onDestroy()
- unregisterReceiver(receiver)
- }
-
- inner class Presenter {
- fun onAccessibilityClick() {
- if (!accessibilitySettingView.checked) {
+ binding.accessibilitySettingView.setOnDoubleCheckClickListener {
+ if (!binding.accessibilitySettingView.checked) {
AccessibilityManager.startAccessibilitySetting(context)
} else {
showSnack(getString(R.string.accessibility_service_opened))
}
}
-
- fun onFloatWindowClick() {
- if (!floatWindowSettingView.checked) {
+ binding.floatWindowSettingView.setOnDoubleCheckClickListener {
+ if (!binding.floatWindowSettingView.checked) {
startActivityForResult(
- Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")),
- 0
+ Intent(
+ Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")
+ ), 0
)
} else {
showSnack(getString(R.string.float_window_opened))
}
}
+ binding.rootSettingView.setOnDoubleCheckClickListener {
+ if (!DeviceUtils.isRoot()) {
+ showSnack(R.string.devices_is_not_root)
+ return@setOnDoubleCheckClickListener
+ }
+ val isRootEnable = binding.rootSettingView.isChecked()
+ binding.rootSettingView.checked = !isRootEnable
+ configKv.setOpenRoot(!isRootEnable)
+ }
+ binding.notificationSettingView.setOnSwitcherClickListener {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ requestPermission(arrayOf(Manifest.permission.POST_NOTIFICATIONS),
+ object : PermissionCallback() {
+ override fun granted() {
+ binding.notificationSettingView.checked = true
+ }
+ })
+ }
+ }
+ }
+
- fun onRootClick() {
- vm.toggleRootPermission()
+ override fun onResume() {
+ super.onResume()
+ checkStatus()
+ }
+
+
+ private fun checkStatus() {
+ binding.accessibilitySettingView.checked =
+ DeveloperHelperAccessibilityService.serviceRunning
+ binding.floatWindowSettingView.checked = DeviceUtils.isFloatWindowOpened()
+ if (configKv.isOpenRoot()) {
+ if (DeviceUtils.isRoot()) {
+ binding.rootSettingView.checked = true
+ } else {
+ binding.rootSettingView.checked = false
+ configKv.setOpenRoot(false)
+ }
+ }
+ if (DeviceUtils.isFloatWindowOpened()) {
+ FloatingWindowService.start(application)
}
}
+ override fun onDestroy() {
+ super.onDestroy()
+ unregisterReceiver(receiver)
+ }
+
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return super.onCreateOptionsMenu(menu)
}
- override fun onOptionsItemSelected(item: MenuItem?): Boolean {
- item?.let {
- when (it.itemId) {
- R.id.about_menu -> {
- showAboutDialog()
- }
- R.id.exit_menu -> {
- showExitMenuDialog()
- }
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.about_menu -> {
+ showAboutDialog()
}
- }
+ R.id.exit_menu -> {
+ showExitMenuDialog()
+ }
+ }
return super.onOptionsItemSelected(item)
}
- private fun showExitMenuDialog() = AlertDialog.Builder(this)
- .setTitle(R.string.notice)
+ private fun showExitMenuDialog() = AlertDialog.Builder(this).setTitle(R.string.notice)
.setMessage(getString(R.string.exit_content))
.setPositiveButton(getString(R.string.ok)) { _, _ ->
- FloatWindowService.stop(this)
+ FloatingWindowService.stop(this)
finish()
- }
- .setNegativeButton(getString(R.string.cancel), null)
- .create()
- .show()
+ }.setNegativeButton(getString(R.string.cancel), null).create().show()
- private fun showAboutDialog() = AlertDialog.Builder(this)
- .setTitle(R.string.about)
+ private fun showAboutDialog() = AlertDialog.Builder(this).setTitle(R.string.about)
.setMessage(getString(R.string.about_content))
.setPositiveButton(getString(R.string.copy_group_number)) { _, _ ->
ClipboardUtils.saveClipboardText(this, "627962572")
showSnack(R.string.copy_success)
- }
- .setNeutralButton("检查更新") { _, _ ->
+ }.setNeutralButton(getString(R.string.check_update)) { _, _ ->
checkUpdate(true)
- }
- .create().show()
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-
- }
+ }.create().show()
private fun checkUpdate(showSnack: Boolean = false) {
- if (showSnack) {
- showSnack("正在检查新版本...")
- }
- UpdateUtils.checkUpdate(object : Callback {
- override fun onSuccess(data: VersionInfo) {
- if (BuildConfig.VERSION_NAME == data.versionName) {
- showSnack("暂无新版本")
- return
- }
- showUpdateDialog(data)
- }
-
- override fun onFailed(msg: String) {
- if (showSnack) {
- showSnack("检查失败...")
- }
- }
- })
+// if (showSnack) {
+// showSnack(getString(R.string.checking_update))
+// }
+// UpdateUtils.checkUpdate(object : Callback {
+// override fun onSuccess(data: VersionInfo) {
+// if (BuildConfig.VERSION_NAME == data.versionName) {
+// showSnack(getString(R.string.no_new_version))
+// return
+// }
+// showUpdateDialog(data)
+// }
+//
+// override fun onFailed(msg: String) {
+// if (showSnack) {
+// showSnack(getString(R.string.check_update_failed))
+// }
+// }
+// })
}
- private fun showUpdateDialog(data: VersionInfo) = AlertDialog.Builder(this)
- .setTitle("发现新版本")
- .setMessage("版本号:${data.versionName}\n更新时间:${data.updateDate}\n大小:${data.size}\n版本说明:\n${data.feature}")
- .setPositiveButton("下载") { _, _ ->
- val intent = Intent(Intent.ACTION_VIEW)
- val uri = Uri.parse(data.downloadUrl)
- intent.data = uri
- startActivity(intent)
- }
- .create().show()
+ private fun showUpdateDialog(data: VersionInfo) =
+ AlertDialog.Builder(this).setTitle(getString(R.string.find_new_version))
+ .setMessage("版本号:${data.versionName}\n更新时间:${data.updateDate}\n大小:${data.size}\n版本说明:\n${data.feature}")
+ .setPositiveButton(getString(R.string.download)) { _, _ ->
+ val intent = Intent(Intent.ACTION_VIEW)
+ val uri = Uri.parse(data.downloadUrl)
+ intent.data = uri
+ startActivity(intent)
+ }.create().show()
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
intent?.run {
if (action == ReceiverConstant.ACTION_ACCESSIBILITY_SERVICE_STATUS_CHANGED) {
- accessibilitySettingView.checked = intent.getBooleanExtra("status", false)
+ binding.accessibilitySettingView.checked =
+ intent.getBooleanExtra("status", false)
}
}
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/daggerinject/MainActivityComponent.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/daggerinject/MainActivityComponent.kt
deleted file mode 100644
index a7a23fc..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/daggerinject/MainActivityComponent.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.main.daggerinject
-
-import com.wrbug.developerhelper.ui.activity.main.MainActivity
-import dagger.Component
-
-@Component
-interface MainActivityComponent {
- fun inject(activity: MainActivity)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/viewmodel/MainViewModel.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/viewmodel/MainViewModel.kt
deleted file mode 100644
index c6959ae..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/main/viewmodel/MainViewModel.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.main.viewmodel
-
-import androidx.databinding.ObservableBoolean
-import androidx.databinding.ObservableField
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.OnLifecycleEvent
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseViewModel
-import com.wrbug.developerhelper.mmkv.ConfigKv
-import com.wrbug.developerhelper.mmkv.manager.MMKVManager
-import com.wrbug.developerhelper.service.DeveloperHelperAccessibilityService
-import com.wrbug.developerhelper.service.FloatWindowService
-import com.wrbug.developerhelper.util.DeviceUtils
-import javax.inject.Inject
-
-class MainViewModel @Inject constructor() : BaseViewModel() {
- val openAccessibility = ObservableBoolean()
- val openFloatWindow = ObservableBoolean()
- val openRoot = ObservableBoolean()
- private val configKv: ConfigKv = MMKVManager.get(ConfigKv::class.java)
- private fun checkStatus() {
- openAccessibility.set(DeveloperHelperAccessibilityService.serviceRunning)
- openFloatWindow.set(DeviceUtils.isFloatWindowOpened())
- if (configKv.isOpenRoot()) {
- if (DeviceUtils.isRoot()) {
- openRoot.set(true)
- } else {
- openRoot.set(false)
- configKv.setOpenRoot(false)
- }
- }
- if (DeviceUtils.isFloatWindowOpened()) {
- FloatWindowService.start(application)
- }
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- fun onResume() {
- checkStatus()
- }
-
- fun toggleRootPermission() {
- if (!DeviceUtils.isRoot()) {
- showSnack(R.string.devices_is_not_root)
- return
- }
- openRoot.set(!openRoot.get())
- configKv.setOpenRoot(openRoot.get())
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceEditActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceEditActivity.kt
index 1516235..04089b9 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceEditActivity.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceEditActivity.kt
@@ -6,31 +6,48 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AlertDialog
+import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseActivity
-import com.wrbug.developerhelper.basecommon.setupActionBar
-import com.wrbug.developerhelper.commonutil.shell.ShellManager
+import com.wrbug.developerhelper.base.BaseActivity
+import com.wrbug.developerhelper.base.setupActionBar
+import com.wrbug.developerhelper.commonutil.AppManagerUtils
+import com.wrbug.developerhelper.commonutil.addTo
+import com.wrbug.developerhelper.commonutil.dpInt
+import com.wrbug.developerhelper.commonutil.runOnIO
+import com.wrbug.developerhelper.util.startPageLoading
+import com.wrbug.developerhelper.util.stopPageLoading
+import com.wrbug.developerhelper.databinding.ActivitySharedPreferenceEditBinding
import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
-import com.wrbug.developerhelper.util.OutSharedPreferenceManager
-import com.wrbug.developerhelper.util.XmlUtil
-import com.wrbug.developerhelper.commonutil.dp2px
-import kotlinx.android.synthetic.main.activity_shared_preference_edit.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import com.wrbug.developerhelper.util.OutSharedPreference
import java.io.File
-class SharedPreferenceEditActivity : BaseActivity(), SharedPreferenceListAdapter.OnValueChangedListener {
+class SharedPreferenceEditActivity : BaseActivity() {
-
- private var filePath: String = ""
+ private val filePath by lazy {
+ intent?.getStringExtra(KEY_FILE_PATH).orEmpty()
+ }
+ private val filePackageName by lazy {
+ intent?.getStringExtra(KEY_PACKAGE_NAME).orEmpty()
+ }
+ private val appName by lazy {
+ intent?.getStringExtra(KEY_APP_NAME).orEmpty()
+ }
private lateinit var adapter: SharedPreferenceListAdapter
private var saveMenuItem: MenuItem? = null
+ private lateinit var binding: ActivitySharedPreferenceEditBinding
+ private lateinit var outSharedPreference: OutSharedPreference
companion object {
- fun start(context: Context, filePath: String) {
+
+ private const val KEY_FILE_PATH = "filePath"
+ private const val KEY_PACKAGE_NAME = "packageName"
+ private const val KEY_APP_NAME = "appName"
+ fun start(context: Context, filePath: String, packageName: String, appName: String) {
val intent = Intent(context, SharedPreferenceEditActivity::class.java)
- intent.putExtra("filePath", filePath)
+ intent.putExtra(KEY_FILE_PATH, filePath)
+ intent.putExtra(KEY_PACKAGE_NAME, packageName)
+ intent.putExtra(KEY_APP_NAME, appName)
context.startActivity(intent)
}
@@ -38,39 +55,42 @@ class SharedPreferenceEditActivity : BaseActivity(), SharedPreferenceListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_shared_preference_edit)
- intent?.let {
- filePath = it.getStringExtra("filePath")
- }
+ binding = ActivitySharedPreferenceEditBinding.inflate(layoutInflater).inject()
setupActionBar(R.id.toolbar) {
if (filePath.isNotEmpty()) {
title = File(filePath).name
}
}
-
- sprefRv.layoutManager = LinearLayoutManager(this)
+ outSharedPreference = OutSharedPreference(this, filePath)
+ binding.sprefRv.layoutManager = LinearLayoutManager(this)
adapter = SharedPreferenceListAdapter(this)
- sprefRv.adapter = adapter
- adapter.setOnValueChangedListener(this)
- val spaceItemDecoration = SpaceItemDecoration(dp2px(10F))
- sprefRv.addItemDecoration(spaceItemDecoration)
+ binding.sprefRv.adapter = adapter
+ adapter.setOnValueChangedListener {
+ saveMenuItem?.isVisible = it
+ }
+ val spaceItemDecoration = SpaceItemDecoration(
+ 24.dpInt(context),
+ 16.dpInt(context),
+ 24.dpInt(context),
+ 0,
+ 16.dpInt(context),
+ 40.dpInt(context)
+ )
+ binding.sprefRv.addItemDecoration(spaceItemDecoration)
parseXml()
-
- }
-
- override fun onChanged(changed: Boolean) {
- saveMenuItem?.isVisible = changed
}
private fun parseXml() {
- doAsync {
- val xml = ShellManager.catFile(filePath)
- val list = XmlUtil.parseSharedPreference(xml)
- uiThread {
- saveMenuItem?.isVisible = false
- adapter.setData(list)
- }
- }
+ binding.flLoading.startPageLoading()
+ outSharedPreference.parse().runOnIO().subscribe({
+ binding.emptyView.isVisible = it.isEmpty()
+ binding.sprefRv.isVisible = it.isNotEmpty()
+ saveMenuItem?.isVisible = false
+ adapter.setData(it)
+ binding.flLoading.stopPageLoading()
+ }, {
+ binding.flLoading.stopPageLoading()
+ }).addTo(disposable)
}
override fun onBackPressed() {
@@ -85,44 +105,50 @@ class SharedPreferenceEditActivity : BaseActivity(), SharedPreferenceListAdapter
private fun showSaveDialog() {
AlertDialog.Builder(this).setMessage(getString(R.string.confirm_shared_preference_save))
- .setTitle(R.string.notice)
- .setPositiveButton(R.string.save_and_exit) { _, _ ->
- if (doSave()) {
- showSnack(getString(R.string.save_shared_preference_success))
- finish()
- } else {
- showSnack(getString(R.string.save_shared_preference_failed))
- }
- }
- .setNegativeButton(getString(R.string.do_not_save)) { _, _ ->
+ .setTitle(R.string.notice).setPositiveButton(R.string.save_and_exit) { _, _ ->
+ doSave()
+ }.setNegativeButton(getString(R.string.do_not_save)) { _, _ ->
finish()
}.show()
}
- private fun doSave(): Boolean {
+ private fun doSave() {
val data = adapter.getData()
- val file = OutSharedPreferenceManager.saveToFile(this, data)
- val success = ShellManager.catFile(file.absolutePath, filePath, "666")
- file.delete()
- return success
+ outSharedPreference.saveToFile(this, data).runOnIO().subscribe({
+ if (it) {
+ parseXml()
+ showDialog(R.string.notice,
+ getString(R.string.save_shared_preference_success, appName),
+ R.string.ok,
+ R.string.cancel,
+ {
+ AppManagerUtils.restartApp(
+ this@SharedPreferenceEditActivity, filePackageName
+ )
+ finish()
+ })
+ } else {
+ showSnack(getString(R.string.save_shared_preference_failed))
+ }
+ }, {
+
+ }).addTo(disposable)
}
- override fun onOptionsItemSelected(item: MenuItem?): Boolean {
- item?.run {
- when (itemId) {
- R.id.save_menu -> {
- if (!doSave()) {
- showSnack(getString(R.string.save_shared_preference_failed))
- return@run
- }
- showSnack(getString(R.string.save_shared_preference_success))
- parseXml()
- }
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.save_menu -> {
+ doSave()
}
}
return super.onOptionsItemSelected(item)
}
+ override fun onDestroy() {
+ super.onDestroy()
+ outSharedPreference.deleteTmpFile()
+ }
+
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_shared_preference_edit, menu)
saveMenuItem = menu?.findItem(R.id.save_menu)
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceListAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceListAdapter.kt
index a952e6e..0e68495 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceListAdapter.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceListAdapter.kt
@@ -4,33 +4,34 @@ import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
-import android.widget.EditText
-import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.util.inVisible
+import com.wrbug.developerhelper.databinding.ItemSharedPreferenceInfoBinding
import com.wrbug.developerhelper.model.entity.SharedPreferenceItemInfo
class SharedPreferenceListAdapter(val context: Context) :
RecyclerView.Adapter() {
private val data: ArrayList = arrayListOf()
- private var onValueChangedListener: OnValueChangedListener? = null
+ private var onValueChangedListener: ((Boolean) -> Unit)? = null
private var changedFlag: Long = 0
- fun setOnValueChangedListener(listener: OnValueChangedListener) {
+ fun setOnValueChangedListener(listener: (Boolean) -> Unit) {
onValueChangedListener = listener
}
fun setData(array: Array) {
data.clear()
changedFlag = 0
- data.addAll(array.sortedBy { it.key })
+ data.addAll(array.sortedBy { it.key.lowercase() })
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_shared_preference_info, parent, false))
+ return ViewHolder(
+ ItemSharedPreferenceInfoBinding.inflate(LayoutInflater.from(context), parent, false)
+ )
}
override fun getItemCount(): Int {
@@ -39,18 +40,15 @@ class SharedPreferenceListAdapter(val context: Context) :
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val sharedPreferenceItemInfo = data[position]
- holder.titleTv?.text = sharedPreferenceItemInfo.key
- holder.contentTv?.setText(sharedPreferenceItemInfo.value)
- holder.restoreTv?.visibility =
- if (sharedPreferenceItemInfo.value == sharedPreferenceItemInfo.newValue) {
- View.INVISIBLE
- } else {
- View.VISIBLE
- }
+ holder.removeTextChangedListener()
+ holder.binding.titleTv.text = sharedPreferenceItemInfo.key
+ holder.binding.contentEt.setText(sharedPreferenceItemInfo.newValue)
+ holder.binding.restoreTv.inVisible =
+ sharedPreferenceItemInfo.value == sharedPreferenceItemInfo.newValue
if (sharedPreferenceItemInfo.isValueValid()) {
- holder.contentTv?.error = null
+ holder.binding.contentEt.error = null
} else {
- holder.contentTv?.error = context.getString(R.string.input_error)
+ holder.binding.contentEt.error = context.getString(R.string.input_error)
}
holder.tag = sharedPreferenceItemInfo
holder.addTextChangedListener()
@@ -61,21 +59,26 @@ class SharedPreferenceListAdapter(val context: Context) :
}
- inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- val titleTv: TextView? = itemView.findViewById(R.id.titleTv)
- val contentTv: EditText? = itemView.findViewById(R.id.contentEt)
- var restoreTv: TextView? = itemView.findViewById(R.id.restoreTv)
+ inner class ViewHolder(val binding: ItemSharedPreferenceInfoBinding) :
+ RecyclerView.ViewHolder(binding.root) {
var tag: SharedPreferenceItemInfo? = null
var textWatcher: TextWatcher? = null
init {
- restoreTv?.setOnClickListener {
+ binding.restoreTv.setOnClickListener {
tag?.run {
- contentTv?.setText(value)
+ binding.contentEt.setText(value)
}
}
}
+ fun removeTextChangedListener() {
+ if (textWatcher != null) {
+ binding.contentEt.removeTextChangedListener(textWatcher)
+ textWatcher = null
+ }
+ }
+
fun addTextChangedListener() {
if (textWatcher != null) {
return
@@ -90,9 +93,9 @@ class SharedPreferenceListAdapter(val context: Context) :
tag?.let {
it.newValue = toString()
if (it.isValueValid()) {
- contentTv?.error = null
+ binding.contentEt.error = null
} else {
- contentTv?.error = context.getString(R.string.input_error)
+ binding.contentEt.error = context.getString(R.string.input_error)
}
}
changedFlag = if (toString() == tag?.value) {
@@ -100,30 +103,22 @@ class SharedPreferenceListAdapter(val context: Context) :
} else {
changedFlag or 1L shl index
}
- onValueChangedListener?.onChanged(changedFlag != 0L)
+ onValueChangedListener?.invoke(changedFlag != 0L)
}
- restoreTv?.visibility =
- if (tag?.value == tag?.newValue) {
- View.INVISIBLE
- } else {
- View.VISIBLE
- }
+ binding.restoreTv.inVisible = tag?.value == tag?.newValue
}
- override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ override fun beforeTextChanged(
+ s: CharSequence?, start: Int, count: Int, after: Int
+ ) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
- contentTv?.addTextChangedListener(textWatcher)
+ binding.contentEt.addTextChangedListener(textWatcher)
}
}
-
-
- interface OnValueChangedListener {
- fun onChanged(changed: Boolean)
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/shellmanager/ShellAppListAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/shellmanager/ShellAppListAdapter.kt
deleted file mode 100644
index 8c7580e..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/shellmanager/ShellAppListAdapter.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.xposed.shellmanager
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.commonutil.entity.ApkInfo
-import com.wrbug.developerhelper.ui.widget.bottommenu.BottomMenu
-import com.wrbug.developerhelper.ui.widget.bottommenu.OnItemClickListener
-import com.wrbug.developerhelper.xposed.processshare.DumpDexListProcessData
-import com.wrbug.developerhelper.xposed.processshare.ProcessDataManager
-
-class ShellAppListAdapter(val context: Context) : RecyclerView.Adapter() {
- private val list = ArrayList()
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
- ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_shell_app_info, parent, false))
-
- fun setData(data: List) {
- list.clear()
- list.addAll(data)
- notifyDataSetChanged()
- }
-
- override fun getItemCount(): Int = list.size
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val apkInfo = list[position]
- holder.icoIv.setImageDrawable(apkInfo.getIco())
- holder.appNameTv.text = apkInfo.getAppName()
- holder.packageNameTv.text = apkInfo.packageInfo.packageName
- holder.apkInfo = apkInfo
- }
-
-
- inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var icoIv: ImageView = itemView.findViewById(R.id.icoIv)
- var appNameTv: TextView = itemView.findViewById(R.id.appNameTv)
- var packageNameTv: TextView = itemView.findViewById(R.id.packageNameTv)
- var apkInfo: ApkInfo? = null
-
- init {
- itemView.setOnClickListener {
- apkInfo?.apply {
- showDialog(this)
- }
- }
- }
-
- private fun showDialog(apkInfo: ApkInfo) {
- val bottomMenu = BottomMenu.Builder(context)
- .menuItems(arrayOf(context.getString(R.string.remove_item)))
- .onItemClickListener(object : OnItemClickListener {
- override fun onClick(position: Int) {
- when (position) {
- 0 -> {
- removeItem(apkInfo)
- }
- }
- }
- })
- .build()
- bottomMenu.show()
- }
- }
-
- private fun removeItem(apkInfo: ApkInfo) {
- val dexListProcessData = ProcessDataManager.get(DumpDexListProcessData::class.java)
- val packageNames = dexListProcessData.getData()
- packageNames?.apply {
- remove(apkInfo.packageInfo.packageName)
- dexListProcessData.setData(this)
- }
- val index = list.indexOf(apkInfo)
- list.remove(apkInfo)
- notifyItemRemoved(index)
- }
-
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/shellmanager/ShellAppManagerActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/shellmanager/ShellAppManagerActivity.kt
deleted file mode 100644
index 06c5b8b..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/shellmanager/ShellAppManagerActivity.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.xposed.shellmanager
-
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.view.View
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseActivity
-import com.wrbug.developerhelper.basecommon.setupActionBar
-import com.wrbug.developerhelper.commonutil.AppInfoManager
-import com.wrbug.developerhelper.commonutil.entity.ApkInfo
-import com.wrbug.developerhelper.xposed.processshare.DumpDexListProcessData
-import com.wrbug.developerhelper.xposed.processshare.ProcessDataManager
-import kotlinx.android.synthetic.main.activity_shell_app_manager.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
-
-class ShellAppManagerActivity : BaseActivity() {
- private var tmpList = ArrayList()
- private val adapter: ShellAppListAdapter by lazy {
- ShellAppListAdapter(this)
- }
-
- companion object {
- fun start(context: Context) {
- context.startActivity(Intent(context, ShellAppManagerActivity::class.java))
- }
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_shell_app_manager)
- setupActionBar(R.id.toolbar) {
- title = getString(R.string.shell_app_manager)
- }
- swipeLayout.setOnRefreshListener {
- getShellApp()
- }
- initRv()
- getShellApp()
- }
-
- private fun initRv() {
- shellAppRv.layoutManager = LinearLayoutManager(this)
- shellAppRv.adapter = adapter
- }
-
- private fun getShellApp() {
- swipeLayout.isRefreshing = true
- doAsync {
- val dexListProcessData = ProcessDataManager.get(DumpDexListProcessData::class.java)
- val packageNames = dexListProcessData.getData()
- if (packageNames == null || packageNames.isEmpty()) {
- uiThread {
- swipeLayout.isRefreshing = false
- emptyView.visibility = View.VISIBLE
- shellAppRv.visibility = View.INVISIBLE
- }
- tmpList.clear()
- return@doAsync
- }
- if (tmpList.size != packageNames.size || !tmpList.containsAll(packageNames)) {
- val data = ArrayList()
- packageNames.forEach { it ->
- AppInfoManager.getAppByPackageName(it)?.let {
- data.add(it)
- }
- }
- tmpList = packageNames
- uiThread {
- setData(data)
- }
- } else {
- uiThread {
- swipeLayout.isRefreshing = false
- }
- }
- }
- }
-
- private fun setData(list: List) {
- swipeLayout.isRefreshing = false
- emptyView.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE
- shellAppRv.visibility = if (list.isEmpty()) View.INVISIBLE else View.VISIBLE
- if (list.isEmpty().not()) {
- adapter.setData(list)
- }
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/xposedsetting/XposedSettingActivity.kt b/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/xposedsetting/XposedSettingActivity.kt
deleted file mode 100644
index 4a491ad..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/activity/xposed/xposedsetting/XposedSettingActivity.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.wrbug.developerhelper.ui.activity.xposed.xposedsetting
-
-import android.os.Bundle
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.BaseActivity
-import com.wrbug.developerhelper.basecommon.setupActionBar
-import com.wrbug.developerhelper.ui.activity.xposed.shellmanager.ShellAppManagerActivity
-import kotlinx.android.synthetic.main.activity_xposed_setting.*
-
-class XposedSettingActivity : BaseActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_xposed_setting)
- setupActionBar(R.id.toolbar) {
- title = getString(R.string.xposed_setting)
- }
- shellSettingItemView.setOnClickListener {
- ShellAppManagerActivity.start(this)
- }
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/adapter/ExMultiTypeAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/ExMultiTypeAdapter.kt
new file mode 100644
index 0000000..fc192c7
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/ExMultiTypeAdapter.kt
@@ -0,0 +1,36 @@
+package com.wrbug.developerhelper.ui.adapter
+
+import com.drakeet.multitype.MultiTypeAdapter
+import com.wrbug.developerhelper.ui.adapter.bean.EmptyViewItemData
+import com.wrbug.developerhelper.ui.adapter.bean.LoadingViewItemData
+import com.wrbug.developerhelper.ui.adapter.delegate.EmptyViewItemDelegate
+import com.wrbug.developerhelper.ui.adapter.delegate.LoadingItemDelegate
+
+class ExMultiTypeAdapter : MultiTypeAdapter() {
+
+ companion object {
+ fun get() = lazy {
+ ExMultiTypeAdapter()
+ }
+ }
+
+ init {
+ register(EmptyViewItemDelegate())
+ register(LoadingItemDelegate())
+ }
+
+ fun showEmpty(title: String = "") {
+ items = listOf(EmptyViewItemData(title))
+ notifyDataSetChanged()
+ }
+
+ fun showLoading() {
+ items = listOf(LoadingViewItemData)
+ notifyDataSetChanged()
+ }
+
+ fun loadData(list: List) {
+ items = list.toList()
+ notifyDataSetChanged()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/adapter/bean/EmptyViewItemData.kt b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/bean/EmptyViewItemData.kt
new file mode 100644
index 0000000..190efdb
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/bean/EmptyViewItemData.kt
@@ -0,0 +1,5 @@
+package com.wrbug.developerhelper.ui.adapter.bean
+
+class EmptyViewItemData(val title: String = "")
+
+object LoadingViewItemData
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/BaseItemViewBindingDelegate.kt b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/BaseItemViewBindingDelegate.kt
new file mode 100644
index 0000000..ad8b57c
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/BaseItemViewBindingDelegate.kt
@@ -0,0 +1,27 @@
+package com.wrbug.developerhelper.ui.adapter.delegate
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.viewbinding.ViewBinding
+import com.drakeet.multitype.ItemViewDelegate
+
+abstract class BaseItemViewBindingDelegate :
+ ItemViewDelegate>() {
+
+ final override fun onBindViewHolder(holder: ViewBindingHolder, item: T) {
+ onBindViewHolder(holder.binding, item)
+ }
+
+ final override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup
+ ): ViewBindingHolder {
+ return ViewBindingHolder(onCreateViewBinding(LayoutInflater.from(context), parent))
+ }
+
+ abstract fun onCreateViewBinding(inflater: LayoutInflater, parent: ViewGroup): B
+
+ abstract fun onBindViewHolder(binding: B, item: T)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/EmptyViewItemDelegate.kt b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/EmptyViewItemDelegate.kt
new file mode 100644
index 0000000..e191a21
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/EmptyViewItemDelegate.kt
@@ -0,0 +1,27 @@
+package com.wrbug.developerhelper.ui.adapter.delegate
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.databinding.ItemEmptyDataBinding
+import com.wrbug.developerhelper.ui.adapter.bean.EmptyViewItemData
+import com.wrbug.developerhelper.util.getString
+
+class EmptyViewItemDelegate :
+ BaseItemViewBindingDelegate() {
+ override fun onBindViewHolder(binding: ItemEmptyDataBinding, item: EmptyViewItemData) {
+ if (item.title.isNotEmpty()) {
+ binding.emptyView.setTitle(item.title)
+ } else {
+ binding.emptyView.setTitle(R.string.no_data.getString())
+ }
+ }
+
+ override fun onCreateViewBinding(
+ inflater: LayoutInflater,
+ parent: ViewGroup
+ ): ItemEmptyDataBinding {
+ return ItemEmptyDataBinding.inflate(inflater, parent, false)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/LoadingItemDelegate.kt b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/LoadingItemDelegate.kt
new file mode 100644
index 0000000..d778443
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/LoadingItemDelegate.kt
@@ -0,0 +1,20 @@
+package com.wrbug.developerhelper.ui.adapter.delegate
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.wrbug.developerhelper.databinding.ItemLoadingDataBinding
+import com.wrbug.developerhelper.ui.adapter.bean.LoadingViewItemData
+
+class LoadingItemDelegate :
+ BaseItemViewBindingDelegate() {
+ override fun onBindViewHolder(binding: ItemLoadingDataBinding, item: LoadingViewItemData) {
+
+ }
+
+ override fun onCreateViewBinding(
+ inflater: LayoutInflater,
+ parent: ViewGroup
+ ): ItemLoadingDataBinding {
+ return ItemLoadingDataBinding.inflate(inflater, parent, false)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/ViewBindingHolder.kt b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/ViewBindingHolder.kt
new file mode 100644
index 0000000..4eb89fe
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/adapter/delegate/ViewBindingHolder.kt
@@ -0,0 +1,7 @@
+package com.wrbug.developerhelper.ui.adapter.delegate
+
+import androidx.recyclerview.widget.RecyclerView
+import androidx.viewbinding.ViewBinding
+
+class ViewBindingHolder(val binding: T) :
+ RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/decoration/SpaceItemDecoration.kt b/app/src/main/java/com/wrbug/developerhelper/ui/decoration/SpaceItemDecoration.kt
index d31ab71..5fb18cf 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/decoration/SpaceItemDecoration.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/decoration/SpaceItemDecoration.kt
@@ -3,6 +3,7 @@ package com.wrbug.developerhelper.ui.decoration
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
+import com.wrbug.developerhelper.commonutil.dpInt
/**
* SpaceItemDecoration
@@ -10,15 +11,37 @@ import androidx.recyclerview.widget.RecyclerView
* @author wrbug
* @since 2017/9/29
*/
-class SpaceItemDecoration : RecyclerView.ItemDecoration {
- private var leftSpace: Int = 0
- private var topSpace: Int = 0
- private var rightSpace: Int = 0
- private var bottomSpace: Int = 0
- private var firstTopSpace = 0
- private var lastBottomSpace: Int = 0
-
- override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
+class SpaceItemDecoration(
+ private val leftSpace: Int = 0,
+ private val topSpace: Int = 0,
+ private val rightSpace: Int = 0,
+ private val bottomSpace: Int = 0,
+ private var firstTopSpace: Int = 0,
+ private var lastBottomSpace: Int = 0,
+) : RecyclerView.ItemDecoration() {
+ companion object {
+ val standard = SpaceItemDecoration(
+ 24.dpInt(),
+ 12.dpInt(),
+ 24.dpInt(),
+ 12.dpInt(),
+ 24.dpInt(),
+ 40.dpInt()
+ )
+ }
+
+ constructor(space: Int) : this(
+ bottomSpace = space,
+ topSpace = space,
+ rightSpace = space,
+ leftSpace = space,
+ lastBottomSpace = space,
+ firstTopSpace = space
+ )
+
+ override fun getItemOffsets(
+ outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State
+ ) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = leftSpace
outRect.right = rightSpace
@@ -35,14 +58,6 @@ class SpaceItemDecoration : RecyclerView.ItemDecoration {
}
- constructor(space: Int) {
- bottomSpace = space
- topSpace = space
- rightSpace = space
- leftSpace = space
- lastBottomSpace = space
- firstTopSpace = space
- }
fun setLastBottomPadding(space: Int) {
lastBottomSpace = space
@@ -51,13 +66,4 @@ class SpaceItemDecoration : RecyclerView.ItemDecoration {
fun setFirstTopPadding(space: Int) {
firstTopSpace = space
}
-
- constructor(leftSpace: Int, topSpace: Int, rightSpace: Int, bottomSpace: Int) {
- this.leftSpace = leftSpace
- this.topSpace = topSpace
- this.rightSpace = rightSpace
- this.bottomSpace = bottomSpace
- lastBottomSpace = bottomSpace
- firstTopSpace = topSpace
- }
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/appbar/AppBar.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appbar/AppBar.kt
new file mode 100644
index 0000000..c208920
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appbar/AppBar.kt
@@ -0,0 +1,88 @@
+package com.wrbug.developerhelper.ui.widget.appbar
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.isGone
+import androidx.core.view.isInvisible
+import androidx.core.view.isVisible
+import androidx.fragment.app.FragmentActivity
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.databinding.ViewAppBarBinding
+import com.wrbug.developerhelper.util.getColor
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+
+class AppBar @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null
+) : FrameLayout(context, attrs) {
+
+ private val binding = ViewAppBarBinding.inflate(LayoutInflater.from(context), this, false)
+
+ init {
+ setBackgroundColor(R.color.colorPrimaryDark.getColor(context))
+ addView(binding.root)
+ binding.ivBack.setOnDoubleCheckClickListener {
+ if (context is FragmentActivity) {
+ context.onBackPressedDispatcher.onBackPressed()
+ }
+ }
+ attrs?.let {
+ initAttr(it)
+ }
+ }
+
+ private fun initAttr(attrs: AttributeSet) {
+ with(context.obtainStyledAttributes(attrs, R.styleable.AppBar)) {
+ val title = getString(R.styleable.AppBar_title)
+ setTitle(title)
+ val subTitle = getString(R.styleable.AppBar_subTitle)
+ setSubTitle(subTitle)
+ val showBack = getBoolean(R.styleable.AppBar_showBack, false)
+ showBack(showBack)
+ recycle()
+ }
+ }
+
+ fun setSubTitle(subTitle: CharSequence?) {
+ binding.tvSubTitle.text = subTitle
+ binding.tvSubTitle.isGone = subTitle.isNullOrEmpty()
+ }
+
+ fun showBack(showBack: Boolean) {
+ binding.ivBack.isInvisible = !showBack
+ }
+
+ fun setTitle(title: CharSequence?) {
+ binding.tvTitle.text = title
+ }
+
+ override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
+ if (child == binding.root) {
+ super.addView(child, index, params)
+ return
+ }
+ binding.flRight.addView(child, index, params)
+ }
+
+ override fun addViewInLayout(
+ child: View?,
+ index: Int,
+ params: ViewGroup.LayoutParams?,
+ preventRequestLayout: Boolean
+ ): Boolean {
+ return super.addViewInLayout(child, index, params, preventRequestLayout)
+ }
+
+
+// fun setMenu(title: String?, listener: (View) -> Unit) {
+// binding.tvRightBtn.text = title
+// binding.tvRightBtn.isGone = title.isNullOrEmpty()
+// binding.tvRightBtn.setOnDoubleCheckClickListener {
+// listener(it)
+// }
+// }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/appdatainfoview/AppDataInfoView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appdatainfoview/AppDataInfoView.kt
index 1d844e6..292ab52 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/appdatainfoview/AppDataInfoView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appdatainfoview/AppDataInfoView.kt
@@ -14,37 +14,39 @@ import com.wrbug.developerhelper.commonutil.shell.ShellManager
import com.wrbug.developerhelper.ui.activity.databaseedit.DatabaseEditActivity
import com.wrbug.developerhelper.ui.activity.sharedpreferencesedit.SharedPreferenceEditActivity
import com.wrbug.developerhelper.commonutil.UiUtils
-import kotlinx.android.synthetic.main.view_app_data_info.view.*
+import com.wrbug.developerhelper.databinding.ViewAppDataInfoBinding
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import java.io.File
-class AppDataInfoView : FrameLayout {
+class AppDataInfoView: FrameLayout {
+
+ private lateinit var binding: ViewAppDataInfoBinding
var apkInfo: ApkInfo? = null
set(value) {
field = value
loadData()
}
- constructor(context: Context) : super(context) {
+ constructor(context: Context): super(context) {
initView()
}
- constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
+ constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet) {
initView()
}
private fun initView() {
- LayoutInflater.from(context).inflate(R.layout.view_app_data_info, this)
+ binding = ViewAppDataInfoBinding.inflate(LayoutInflater.from(context), this, true)
}
private fun loadData() {
apkInfo?.run {
- apkPathTv.text = applicationInfo.publicSourceDir
+ binding.apkPathTv.text = applicationInfo.publicSourceDir
val apkSignInfo = ApkUtils.getApkSignInfo(context, applicationInfo.packageName)
- apkSha1Tv.text = apkSignInfo.sha1
- apkMd5Tv.text = apkSignInfo.md5
+ binding.apkSha1Tv.text = apkSignInfo.sha1
+ binding.apkMd5Tv.text = apkSignInfo.md5
getSharedPreferencesFiles(applicationInfo.packageName)
getDatabaseFiles(applicationInfo.packageName)
}
@@ -55,11 +57,12 @@ class AppDataInfoView : FrameLayout {
val sqliteFiles = ShellManager.getSqliteFiles(packageName)
uiThread {
if (sqliteFiles.isEmpty()) {
- defaultDbTv.setText(R.string.none)
+ binding.defaultDbTv.setText(R.string.none)
return@uiThread
}
- databaseContainer.removeAllViews()
- val params = LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
+ binding.databaseContainer.removeAllViews()
+ val params =
+ LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
for (sqliteFile in sqliteFiles) {
val textView = AppCompatTextView(context)
textView.text = sqliteFile.name
@@ -67,7 +70,7 @@ class AppDataInfoView : FrameLayout {
textView.setTextColor(resources.getColor(R.color.item_content_text))
textView.setPadding(0, UiUtils.dp2px(context, 8F), 0, 0)
textView.tag = sqliteFile
- databaseContainer.addView(textView, params)
+ binding.databaseContainer.addView(textView, params)
textView.setOnClickListener {
DatabaseEditActivity.start(context, (it.tag as File).absolutePath)
}
@@ -82,11 +85,12 @@ class AppDataInfoView : FrameLayout {
val files = AppInfoManager.getSharedPreferencesFiles(packageName)
uiThread {
if (files.isEmpty()) {
- defaultSpTv.setText(R.string.none)
+ binding.defaultSpTv.setText(R.string.none)
return@uiThread
}
- sharedPreferenceContainer.removeAllViews()
- val params = LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
+ binding.sharedPreferenceContainer.removeAllViews()
+ val params =
+ LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
files.forEach {
val textView = AppCompatTextView(context)
textView.text = it.name
@@ -94,9 +98,14 @@ class AppDataInfoView : FrameLayout {
textView.setTextColor(resources.getColor(R.color.item_content_text))
textView.setPadding(0, UiUtils.dp2px(context, 8F), 0, 0)
textView.tag = it
- sharedPreferenceContainer.addView(textView, params)
+ binding.sharedPreferenceContainer.addView(textView, params)
textView.setOnClickListener {
- SharedPreferenceEditActivity.start(context, (it.tag as File).absolutePath)
+ SharedPreferenceEditActivity.start(
+ context,
+ (it.tag as File).absolutePath,
+ packageName,
+ apkInfo?.getAppName() ?: ""
+ )
}
}
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/AppSettingView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/AppSettingView.kt
index 26db862..777f8e6 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/AppSettingView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/AppSettingView.kt
@@ -1,39 +1,34 @@
package com.wrbug.developerhelper.ui.widget.appsettingview
-import android.Manifest
import android.app.Activity
-import android.app.AlertDialog
import android.content.Context
-import android.content.DialogInterface
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ScrollView
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.FragmentActivity
+import com.wrbug.developerhelper.BuildConfig
import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.basecommon.showToast
+import com.wrbug.developerhelper.base.requestStoragePermission
import com.wrbug.developerhelper.commonutil.AppManagerUtils
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
+import com.wrbug.developerhelper.util.setOnRootCheckClickListener
+import com.wrbug.developerhelper.util.visible
+import com.wrbug.developerhelper.databinding.DialogBackupAppSelectBinding
+import com.wrbug.developerhelper.databinding.ViewAppSettingBinding
import com.wrbug.developerhelper.mmkv.ConfigKv
import com.wrbug.developerhelper.mmkv.manager.MMKVManager
-import kotlinx.android.synthetic.main.view_app_setting.view.*
-import android.content.Intent
-import android.net.Uri
-import androidx.appcompat.widget.AppCompatButton
-import com.wrbug.developerhelper.basecommon.BaseActivity
-import com.wrbug.developerhelper.commonutil.shell.ShellManager
-import com.wrbug.developerhelper.commonutil.zip
-import com.wrbug.developerhelper.util.BackupUtils
-import com.wrbug.developerhelper.util.toUri
-import gdut.bsx.share2.Share2
-import gdut.bsx.share2.ShareContentType
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
-import java.io.File
-
+import com.wrbug.developerhelper.ui.activity.appbackup.AppBackupDetailActivity
+import com.wrbug.developerhelper.util.getString
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import org.jetbrains.anko.toast
class AppSettingView : ScrollView {
- var apkInfo: ApkInfo? = null
+
+ private var apkInfo: ApkInfo? = null
private val configKv = MMKVManager.get(ConfigKv::class.java)
- private var exportDexBtn: AppCompatButton? = null
+ private lateinit var binding: ViewAppSettingBinding
+ private lateinit var disposable: CompositeDisposable
constructor(context: Context) : super(context) {
initView()
@@ -43,89 +38,88 @@ class AppSettingView : ScrollView {
initView()
}
- private fun initView() {
- LayoutInflater.from(context).inflate(R.layout.view_app_setting, this)
- exportDexBtn = findViewById(R.id.exportDexBtn)
- if (configKv.isOpenRoot().not()) {
- backupApkBtn.isEnabled = false
- backupApkDataDirBtn.isEnabled = false
- restartAppBtn.isEnabled = false
- stopAppBtn.isEnabled = false
- deleteAppDataBtn.isEnabled = false
- exportDexBtn?.isEnabled = false
+ fun setApkInfo(apkInfo: ApkInfo?) {
+ this.apkInfo = apkInfo
+ if (apkInfo?.applicationInfo?.packageName == BuildConfig.APPLICATION_ID) {
+ binding.uninstallAppBtn.visible = false
}
+ }
+
+ private fun initView() {
+ binding = ViewAppSettingBinding.inflate(LayoutInflater.from(context), this, true)
initListener()
}
private fun initListener() {
- backupApkBtn.setOnClickListener {
- doBackupApk()
- }
- backupApkDataDirBtn.setOnClickListener {
- doBackupDataDir()
+ binding.backupAppBtn.setOnRootCheckClickListener {
+ showBackupSelect()
+ }
+ binding.restoreAppBtn.setOnRootCheckClickListener {
+ AppBackupDetailActivity.start(
+ context,
+ apkInfo?.getAppName().orEmpty(),
+ apkInfo?.packageInfo?.packageName.orEmpty(), true
+ )
}
- restartAppBtn.setOnClickListener {
+ binding.restartAppBtn.setOnRootCheckClickListener {
doRestartApp()
}
- stopAppBtn.setOnClickListener {
+ binding.stopAppBtn.setOnRootCheckClickListener {
doStopApp()
}
- deleteAppDataBtn.setOnClickListener {
+ binding.deleteAppDataBtn.setOnRootCheckClickListener {
doDeleteAppData()
}
- uninstallAppBtn.setOnClickListener {
+ binding.uninstallAppBtn.setOnRootCheckClickListener {
doUninstallApp()
}
-
- exportDexBtn?.setOnClickListener {
- doBackupDexData()
- }
}
- private fun doBackupDexData() {
- apkInfo?.apply {
- showToast(context.getString(R.string.packing_files))
- doAsync {
- val dir = File(context.externalCacheDir, "dex/${applicationInfo.packageName}")
- if (dir.exists()) {
- ShellManager.rmFile(dir.absolutePath)
- }
- dir.mkdirs()
- val dexDir = "/data/data/${applicationInfo.packageName}/dump"
- val lsDir = ShellManager.lsDir(dexDir)
- if (lsDir.isEmpty()) {
- uiThread {
- showToast(context.getString(R.string.no_dex_files))
- }
- return@doAsync
- }
- if (ShellManager.cpFile(dexDir, dir.absolutePath)) {
- val zipFile = File(context.externalCacheDir, "${apkInfo?.getAppName() ?: ""}-dex.zip")
- dir.zip(zipFile)
- val uri = zipFile.toUri()
- if (uri == null) {
- showToast(R.string.export_failed)
- return@doAsync
- }
- uiThread {
- showShareDexNotice(uri)
- }
- } else {
- uiThread {
- showToast(context.getString(R.string.export_failed))
- }
- }
+ private fun showBackupSelect() {
+ context.requestStoragePermission {
+ val selected = booleanArrayOf(false, false, false)
+ val binding = DialogBackupAppSelectBinding.inflate(LayoutInflater.from(context))
+ binding.cbApk.setOnCheckedChangeListener { _, isChecked ->
+ selected[0] = isChecked
}
+ binding.cbData.setOnCheckedChangeListener { _, isChecked ->
+ selected[1] = isChecked
+ }
+ binding.cbAndroidData.setOnCheckedChangeListener { _, isChecked ->
+ selected[2] = isChecked
+ }
+ binding.tvMemo.setText(
+ R.string.backup_default_meme.getString(
+ apkInfo?.getAppName().orEmpty()
+ )
+ )
+ AlertDialog.Builder(context).setTitle(R.string.backup_app_file).setView(binding.root)
+ .setNegativeButton(R.string.cancel, null).setPositiveButton(
+ R.string.ok
+ ) { _, _ ->
+ doBackup(selected, binding.tvMemo.text.toString())
+ }.create().show()
}
}
- private fun showShareDexNotice(uri: Uri) {
- Share2.Builder(context as Activity)
- .setContentType(ShareContentType.FILE)
- .setShareFileUri(uri)
- .setOnActivityResult(10)
- .build()
- .shareBySystem()
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ disposable = CompositeDisposable()
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ disposable.dispose()
+ }
+
+ private fun doBackup(selected: BooleanArray, memo: String) {
+ val activity = context as? FragmentActivity ?: return
+ if (selected.find { it } == null) {
+ return
+ }
+ BackupAppDialog.show(
+ activity.supportFragmentManager, apkInfo, memo, selected[0], selected[1], selected[2]
+ )
}
private fun doUninstallApp() {
@@ -140,13 +134,13 @@ class AppSettingView : ScrollView {
}
apkInfo?.apply {
showNotice(
- context.getString(R.string.confirm_delete_app_data),
- DialogInterface.OnClickListener { _, _ ->
- if (AppManagerUtils.clearAppData(applicationInfo.packageName)) {
- activityFinish()
- showToast(context.getString(R.string.clear_complete))
- }
- })
+ context.getString(R.string.confirm_delete_app_data)
+ ) {
+ if (AppManagerUtils.clearAppData(applicationInfo.packageName)) {
+ activityFinish()
+ context.toast(context.getString(R.string.clear_complete))
+ }
+ }
}
}
@@ -156,11 +150,11 @@ class AppSettingView : ScrollView {
return
}
apkInfo?.apply {
- showNotice(context.getString(R.string.confirm_stop_app), DialogInterface.OnClickListener { _, _ ->
+ showNotice(context.getString(R.string.confirm_stop_app)) {
if (AppManagerUtils.forceStopApp(applicationInfo.packageName)) {
activityFinish()
}
- })
+ }
}
}
@@ -169,132 +163,34 @@ class AppSettingView : ScrollView {
return
}
apkInfo?.apply {
- showNotice(context.getString(R.string.confirm_restart_app), DialogInterface.OnClickListener { _, _ ->
- if (!AppManagerUtils.forceStopApp(applicationInfo.packageName)) {
- showToast(context.getString(R.string.restart_failed))
- return@OnClickListener
- }
+ showNotice(
+ context.getString(R.string.confirm_restart_app)
+ ) {
+ AppManagerUtils.restartApp(context, applicationInfo.packageName)
activityFinish()
- val intent = context.packageManager.getLaunchIntentForPackage(applicationInfo.packageName)
- intent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- context.startActivity(intent)
- })
- }
- }
-
- private fun doBackupDataDir() {
- if (checkRoot().not()) {
- return
- }
- apkInfo?.apply {
- val backupAppData = BackupUtils.backupAppData(applicationInfo.packageName, applicationInfo.dataDir)
- if (backupAppData == null) {
- showToast(context.getString(R.string.backup_failed))
- return
}
- if (context !is BaseActivity) {
- showToast(context.getString(R.string.backup_success_msg))
- return
- }
- showShareDataNotice(backupAppData)
}
}
- private fun showShareDataNotice(backupAppData: File) {
- showNotice(
- context.getString(R.string.backup_success_and_share_msg),
- DialogInterface.OnClickListener { _, _ ->
- (context as BaseActivity).requestPermission(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
- object : BaseActivity.PermissionCallback() {
- override fun granted() {
- val zipFile = File(context.externalCacheDir, "${apkInfo?.getAppName() ?: ""}-data.zip")
- backupAppData.zip(zipFile)
- val uri = zipFile.toUri()
- if (uri == null) {
- showToast(context.getString(R.string.share_failed))
- return
- }
- activityFinish()
- Share2.Builder(context as Activity)
- .setContentType(ShareContentType.FILE)
- .setShareFileUri(uri)
- .setOnActivityResult(10)
- .build()
- .shareBySystem()
- }
-
- })
-
- })
- }
-
- private fun doBackupApk() {
- if (checkRoot().not()) {
- return
- }
- apkInfo?.apply {
- val uri = BackupUtils.backupApk(
- applicationInfo.packageName,
- applicationInfo.publicSourceDir,
- "${getAppName()}_${packageInfo.versionName}.apk"
- )
- if (uri == null) {
- showToast(context.getString(R.string.backup_failed))
- return
- }
- if (context !is BaseActivity) {
- showToast(context.getString(R.string.backup_success_msg))
- return
- }
- showShareApkDialog(uri)
-
- }
- }
-
- private fun showShareApkDialog(uri: Uri) {
- showNotice(
- context.getString(R.string.backup_success_and_share_msg),
- DialogInterface.OnClickListener { _, _ ->
- (context as BaseActivity).requestPermission(arrayOf(
- Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.WRITE_EXTERNAL_STORAGE
- ),
- object : BaseActivity.PermissionCallback() {
- override fun granted() {
- activityFinish()
- Share2.Builder(context as Activity)
- .setContentType(ShareContentType.FILE)
- .setShareFileUri(uri)
- .setOnActivityResult(10)
- .build()
- .shareBySystem()
- }
-
- })
-
- })
- }
-
private fun checkRoot(): Boolean {
if (configKv.isOpenRoot().not()) {
- showToast(context.getString(R.string.please_open_root))
+ context.toast(context.getString(R.string.please_open_root))
return false
}
return true
}
- fun activityFinish() {
+ private fun activityFinish() {
if (context is Activity) {
(context as Activity).finish()
}
}
- private fun showNotice(msg: String, listener: DialogInterface.OnClickListener) {
- AlertDialog.Builder(context)
- .setTitle(R.string.notice)
- .setMessage(msg)
- .setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.ok, listener)
- .create().show()
+ private fun showNotice(msg: String, listener: () -> Unit) {
+ AlertDialog.Builder(context).setTitle(R.string.notice).setMessage(msg)
+ .setNegativeButton(R.string.cancel, null).setPositiveButton(
+ R.string.ok
+ ) { _, _ -> listener() }.create().show()
}
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/BackupAppDialog.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/BackupAppDialog.kt
new file mode 100644
index 0000000..294b259
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/BackupAppDialog.kt
@@ -0,0 +1,276 @@
+package com.wrbug.developerhelper.ui.widget.appsettingview
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.core.view.isVisible
+import androidx.fragment.app.FragmentManager
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.ExtraKey
+import com.wrbug.developerhelper.base.versionCodeLong
+import com.wrbug.developerhelper.commonutil.addTo
+import com.wrbug.developerhelper.commonutil.entity.ApkInfo
+import com.wrbug.developerhelper.commonutil.observeOnMain
+import com.wrbug.developerhelper.commonutil.shell.ShellManager
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+import com.wrbug.developerhelper.databinding.DialogBackupAppBinding
+import com.wrbug.developerhelper.model.entity.BackupAppItemInfo
+import com.wrbug.developerhelper.ui.widget.backupprogress.BackupProgressView
+import com.wrbug.developerhelper.util.BackupUtils
+import com.wrbug.developerhelper.util.format
+import io.reactivex.rxjava3.core.Single
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.schedulers.Schedulers
+
+
+class BackupAppDialog : BottomSheetDialogFragment() {
+ companion object {
+ fun show(
+ fragmentManager: FragmentManager,
+ apkInfo: ApkInfo?,
+ memo: String,
+ backupApk: Boolean,
+ backupData: Boolean,
+ backupAndroidData: Boolean
+ ) {
+ BackupAppDialog().apply {
+ arguments = Bundle().apply {
+ putParcelable(ExtraKey.DATA, apkInfo)
+ putBoolean(ExtraKey.KEY_1, backupApk)
+ putBoolean(ExtraKey.KEY_2, backupData)
+ putBoolean(ExtraKey.KEY_3, backupAndroidData)
+ putString(ExtraKey.KEY_4, memo)
+ }
+ }.show(fragmentManager, "BackupAppDialog")
+ }
+ }
+
+ private lateinit var binding: DialogBackupAppBinding
+ private lateinit var disposable: CompositeDisposable
+ private lateinit var dateDir: String
+ private var backupTimeStamp: Long = 0
+
+ private val apkInfo: ApkInfo? by lazy {
+ arguments?.getParcelable(ExtraKey.DATA)
+ }
+
+ private val backupApk by lazy {
+ arguments?.getBoolean(ExtraKey.KEY_1) ?: false
+ }
+
+ private val memo by lazy {
+ arguments?.getString(ExtraKey.KEY_4).orEmpty()
+ }
+
+ private val backupData by lazy {
+ arguments?.getBoolean(ExtraKey.KEY_2) ?: false
+ }
+
+
+ private val backupAndroidData by lazy {
+ arguments?.getBoolean(ExtraKey.KEY_3) ?: false
+ }
+
+ private var successCount = 0
+ set(value) {
+ field = value
+ checkIsAllSuccess()
+ }
+ private var hasError = false
+ set(value) {
+ field = value
+ checkIsAllSuccess()
+ }
+
+ private fun checkIsAllSuccess() {
+ if (hasError) {
+ binding.tvNotice.isVisible = false
+ binding.btnExit.isVisible = true
+ binding.zipFileProgress.setStatus(BackupProgressView.Status.Canceled)
+ return
+ }
+ if (successCount < 3) {
+ return
+ }
+ createInfoFile()
+ }
+
+ private fun createInfoFile() {
+ binding.zipFileProgress.setStatus(BackupProgressView.Status.Processing)
+ runOnIo().map { apkInfo ->
+ BackupUtils.zipBackupFile(apkInfo.packageInfo.packageName.orEmpty(), dateDir)
+ ?.let { apkInfo to it }
+ ?: throw Exception()
+ }.map {
+ val info = BackupAppItemInfo(
+ it.second.name,
+ backupApk,
+ backupData,
+ backupAndroidData,
+ it.first.generateBackupApkFileName(),
+ it.first.packageInfo.versionName.orEmpty(),
+ it.first.packageInfo.versionCodeLong,
+ it.first.packageInfo.packageName.orEmpty(),
+ backupTimeStamp,
+ memo = memo
+ )
+ val success =
+ BackupUtils.saveBackupInfo(it.first, info, it.second.name)
+ if (success) {
+ return@map it.second.absolutePath
+ }
+ throw Exception()
+ }.observeOnMain().subscribe({
+ binding.zipFileProgress.setStatus(BackupProgressView.Status.Success, it)
+ showSuccess()
+ }, {
+ hasError = true
+ binding.zipFileProgress.setStatus(BackupProgressView.Status.Failed)
+ }).addTo(disposable)
+ }
+
+ private fun showSuccess() {
+ binding.btnExit.isVisible = true
+ binding.tvNotice.text = getString(
+ R.string.backup_success_notice,
+ BackupUtils.getAppBackupDir(
+ apkInfo?.packageInfo?.packageName.orEmpty()
+ ).absolutePath
+ )
+ binding.tvNotice.setTextColor(
+ ContextCompat.getColor(
+ requireContext(),
+ R.color.material_color_green_600
+ )
+ )
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ successCount = 0
+ backupTimeStamp = System.currentTimeMillis()
+ dateDir = backupTimeStamp.format("yyyy-MM-dd-HH_mm_ss")
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ disposable = CompositeDisposable()
+ binding = DialogBackupAppBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return super.onCreateDialog(savedInstanceState).apply {
+ setCancelable(false)
+ setCanceledOnTouchOutside(false)
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ binding.apkProgress.setTitle(R.string.item_backup_apk)
+ binding.androidDataProgress.setTitle(R.string.item_backup_android_data)
+ binding.dataProgress.setTitle(R.string.item_backup_data)
+ binding.zipFileProgress.setTitle(R.string.item_zip_backup_file)
+ binding.zipFileProgress.setStatus(BackupProgressView.Status.Waiting)
+ binding.btnExit.setOnDoubleCheckClickListener {
+ dismissAllowingStateLoss()
+ }
+ backupApk()
+ backupData()
+ backupAndroidData()
+ }
+
+ private fun backupApk() {
+ if (!backupApk) {
+ successCount++
+ binding.apkProgress.setStatus(BackupProgressView.Status.Ignore)
+ return
+ }
+ binding.apkProgress.setStatus(BackupProgressView.Status.Processing)
+ runOnIo().map {
+ BackupUtils.backupApk(
+ it.applicationInfo.packageName,
+ dateDir,
+ it.applicationInfo.publicSourceDir,
+ it.generateBackupApkFileName()
+ ) ?: throw Exception()
+ }.observeOnMain().subscribe({
+ successCount++
+ binding.apkProgress.setStatus(BackupProgressView.Status.Success, it)
+ }, {
+ hasError = true
+ binding.apkProgress.setStatus(BackupProgressView.Status.Failed)
+ }).addTo(disposable)
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ disposable.dispose()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ if (hasError) {
+ ShellManager.rmFile(
+ BackupUtils.getCurrentAppBackupDir(
+ apkInfo?.packageInfo?.packageName.orEmpty(),
+ dateDir
+ ).absolutePath
+ )
+ }
+ }
+
+ private fun backupAndroidData() {
+ if (!backupAndroidData) {
+ successCount++
+ binding.androidDataProgress.setStatus(BackupProgressView.Status.Ignore)
+ return
+ }
+ binding.androidDataProgress.setStatus(BackupProgressView.Status.Processing)
+ runOnIo().map {
+ BackupUtils.backupAppAndroidData(dateDir, it.applicationInfo.packageName)
+ ?: throw Exception()
+ }.observeOnMain().subscribe({
+ successCount++
+ binding.androidDataProgress.setStatus(
+ BackupProgressView.Status.Success,
+ it.ifEmpty { getString(R.string.no_need_to_backup) }
+ )
+ }, {
+ hasError = true
+ binding.androidDataProgress.setStatus(BackupProgressView.Status.Failed)
+ }).addTo(disposable)
+ }
+
+ private fun backupData() {
+ if (!backupData) {
+ successCount++
+ binding.dataProgress.setStatus(BackupProgressView.Status.Ignore)
+ return
+ }
+ binding.dataProgress.setStatus(BackupProgressView.Status.Processing)
+ runOnIo().map {
+ BackupUtils.backupAppData(dateDir, it.applicationInfo.packageName) ?: throw Exception()
+ }.observeOnMain().subscribe({
+ successCount++
+ binding.dataProgress.setStatus(BackupProgressView.Status.Success, it.absolutePath)
+ }, {
+ hasError = true
+ binding.dataProgress.setStatus(BackupProgressView.Status.Failed)
+ }).addTo(disposable)
+ }
+
+
+ private fun runOnIo() = if (apkInfo == null) {
+ Single.error(Exception())
+ } else {
+ Single.just(apkInfo!!).subscribeOn(Schedulers.newThread())
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/backupprogress/BackupProgressView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/backupprogress/BackupProgressView.kt
new file mode 100644
index 0000000..698bf87
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/backupprogress/BackupProgressView.kt
@@ -0,0 +1,98 @@
+package com.wrbug.developerhelper.ui.widget.backupprogress
+
+import android.content.Context
+import android.content.res.ColorStateList
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.ContextCompat
+import androidx.core.view.isVisible
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.databinding.ViewBackupProgressBinding
+import com.wrbug.developerhelper.util.getString
+
+class BackupProgressView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null
+) : ConstraintLayout(context, attrs) {
+ private val binding = ViewBackupProgressBinding.inflate(LayoutInflater.from(context), this)
+
+
+ fun setTitle(title: Int) {
+ binding.tvTitle.text = getString(title)
+ }
+
+ fun setStatus(status: Status, successPath: String = "") {
+ when (status) {
+ Status.Processing -> {
+ binding.progress.isVisible = true
+ binding.ivStatus.isVisible = false
+ binding.tvStatus.text = context.getString(R.string.backuping_data)
+ }
+
+ Status.Success -> {
+ binding.progress.isVisible = false
+ binding.ivStatus.isVisible = true
+ binding.ivStatus.setImageResource(R.drawable.ic_success)
+ binding.ivStatus.imageTintList = ColorStateList.valueOf(
+ ContextCompat.getColor(
+ context,
+ R.color.material_color_green_400
+ )
+ )
+ binding.tvStatus.text = successPath
+ }
+
+ Status.Failed -> {
+ binding.progress.isVisible = false
+ binding.ivStatus.isVisible = true
+ binding.tvStatus.text = context.getString(R.string.backup_fail)
+ binding.ivStatus.setImageResource(R.drawable.ic_fail)
+ binding.ivStatus.imageTintList = ColorStateList.valueOf(
+ ContextCompat.getColor(
+ context,
+ R.color.material_color_red_400
+ )
+ )
+
+ }
+
+ Status.Ignore -> {
+ binding.progress.isVisible = false
+ binding.ivStatus.isVisible = true
+ binding.tvStatus.text = context.getString(R.string.ignore_backup)
+ binding.ivStatus.setImageResource(R.drawable.ic_ignore)
+ binding.ivStatus.imageTintList = ColorStateList.valueOf(
+ ContextCompat.getColor(
+ context,
+ R.color.material_color_grey_400
+ )
+ )
+ }
+
+ Status.Waiting -> {
+ binding.progress.isVisible = true
+ binding.ivStatus.isVisible = true
+ binding.tvStatus.text = context.getString(R.string.backup_waiting)
+ binding.ivStatus.setImageResource(R.drawable.ic_waiting)
+ binding.ivStatus.imageTintList = ColorStateList.valueOf(
+ ContextCompat.getColor(context, R.color.material_color_grey_400)
+ )
+ }
+
+ Status.Canceled -> {
+ binding.progress.isVisible = false
+ binding.ivStatus.isVisible = true
+ binding.ivStatus.setImageResource(R.drawable.ic_canceled)
+ binding.tvStatus.text = context.getString(R.string.canceled)
+ binding.ivStatus.imageTintList = ColorStateList.valueOf(
+ ContextCompat.getColor(context, R.color.material_color_grey_400)
+ )
+ }
+ }
+ }
+
+
+ enum class Status {
+ Processing, Success, Failed, Ignore, Waiting, Canceled
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/BottomMenu.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/BottomMenu.kt
deleted file mode 100644
index fcbc77c..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/BottomMenu.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.wrbug.developerhelper.ui.widget.bottommenu
-
-import android.content.Context
-import android.graphics.drawable.ColorDrawable
-import android.os.Bundle
-import android.view.View
-import androidx.recyclerview.widget.DividerItemDecoration
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.google.android.material.bottomsheet.BottomSheetDialog
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.commonutil.UiUtils
-import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
-import kotlinx.android.synthetic.main.dialog_bottom_menu.*
-
-class BottomMenu(context: Context) : BottomSheetDialog(context), OnItemClickListener {
-
- private var title = ""
- val adapter: BottomMenuItemAdapter by lazy {
- BottomMenuItemAdapter(context)
- }
-
- private var items: Array = arrayOf()
- private var listener: OnItemClickListener? = null
-
- init {
- setContentView(R.layout.dialog_bottom_menu)
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- initRv()
- initView()
- }
-
- private fun initView() {
- titleTv.text = title
- titleTv.visibility = if (title.isEmpty()) View.GONE else View.VISIBLE
- }
-
- private fun initRv() {
- menuListRv.layoutManager = LinearLayoutManager(context)
- val decoration = SpaceItemDecoration(UiUtils.dp2px(context, 0F))
- decoration.setLastBottomPadding(UiUtils.dp2px(context, 10F))
- decoration.setFirstTopPadding(UiUtils.dp2px(context, 10F))
- menuListRv.addItemDecoration(decoration)
- val dividerItemDecoration = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
- dividerItemDecoration.setDrawable(ColorDrawable(context.resources.getColor(R.color.divider_color)))
- menuListRv.addItemDecoration(dividerItemDecoration)
- adapter.setOnItemClickListener(this)
- menuListRv.adapter = adapter
- adapter.list = items
- }
-
- override fun onClick(position: Int) {
- listener?.onClick(position)
- dismiss()
- }
-
- class Builder(val context: Context) {
- private var title = ""
- private var items: Array = arrayOf()
- private var listener: OnItemClickListener? = null
-
- fun title(id: Int): Builder {
- title = context.getString(id)
- return this
- }
-
- fun title(title: String): Builder {
- this.title = title
- return this
- }
-
- fun menuItems(items: Array): Builder {
- this.items = items
- return this
- }
-
- fun onItemClickListener(listener: OnItemClickListener?): Builder {
- this.listener = listener
- return this
- }
-
- fun build(): BottomMenu {
- val menu = BottomMenu(context)
- menu.items = items
- menu.title = title
- menu.listener = listener
- return menu
- }
- }
-
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/BottomMenuItemAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/BottomMenuItemAdapter.kt
deleted file mode 100644
index a8e5b9c..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/BottomMenuItemAdapter.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.wrbug.developerhelper.ui.widget.bottommenu
-
-import android.content.Context
-import android.view.Gravity
-import android.view.View
-import android.view.ViewGroup
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.commonutil.UiUtils
-
-class BottomMenuItemAdapter(val context: Context) : RecyclerView.Adapter() {
- var list: Array = arrayOf()
- set(value) {
- field = value
- notifyDataSetChanged()
- }
- var listener: OnItemClickListener? = null
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- val tv = TextView(context)
- tv.setTextColor(context.resources.getColor(R.color.text_color_666666))
- tv.gravity = Gravity.CENTER
- val dp10 = UiUtils.dp2px(context, 10F)
- tv.setPadding(dp10, dp10, dp10, dp10)
- val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
- tv.layoutParams = params
- return ViewHolder(tv)
- }
-
- override fun getItemCount(): Int = list.size
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- holder.tv.text = list[position]
- holder.index = position
- }
-
- fun setOnItemClickListener(listener: OnItemClickListener) {
- this.listener = listener
- }
-
- inner class ViewHolder(val tv: TextView) : RecyclerView.ViewHolder(tv) {
- var index = 0
-
- init {
- tv.setOnClickListener {
- listener?.onClick(index)
- }
- }
-
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/OnItemClickListener.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/OnItemClickListener.kt
deleted file mode 100644
index 2a4f90b..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/bottommenu/OnItemClickListener.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.wrbug.developerhelper.ui.widget.bottommenu
-
-interface OnItemClickListener {
- fun onClick(position: Int)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/boundsinfoview/BoundsInfoView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/boundsinfoview/BoundsInfoView.kt
index 20d5d2e..828526c 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/boundsinfoview/BoundsInfoView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/boundsinfoview/BoundsInfoView.kt
@@ -17,9 +17,9 @@ class BoundsInfoView : View {
field = value
invalidate()
}
- private val edgeLineSize = UiUtils.dp2px(context,4F).toFloat()
+ private val edgeLineSize = UiUtils.dp2px(context, 4F).toFloat()
private val paint = Paint()
- var unit: Unit = Unit.DP
+ private var unit: Unit = Unit.DP
set(value) {
if (field == value) {
return
@@ -27,13 +27,21 @@ class BoundsInfoView : View {
field = value
invalidate()
}
- private val textMargin = UiUtils.dp2px(context,3F)
+ private val textMargin = UiUtils.dp2px(context, 3F)
- constructor(context: Context) : super(context)
+ constructor(context: Context) : this(context, null)
- constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
+ setOnClickListener {
+ toggleUnit()
+ }
+ }
- override fun onDraw(canvas: Canvas?) {
+ private fun toggleUnit() {
+ unit = if (unit == Unit.DP) Unit.PX else Unit.DP
+ }
+
+ override fun onDraw(canvas: Canvas) {
val rect = drawRect(canvas)
val lineRect = drawEdge(rect, canvas)
drawAl(rect, lineRect, canvas)
@@ -45,16 +53,16 @@ class BoundsInfoView : View {
bounds?.let {
paint.reset()
paint.isAntiAlias = true
- paint.textSize = UiUtils.dp2px(context,14F).toFloat()
+ paint.textSize = UiUtils.dp2px(context, 14F).toFloat()
var leftMargin = it.left
var topMargin = it.top
var rightMargin = UiUtils.getDeviceWidth() - it.right
var bottomMargin = UiUtils.getDeviceHeight() - it.bottom
if (unit == Unit.DP) {
- leftMargin = UiUtils.px2dp(context,leftMargin.toFloat()).toInt()
- topMargin = UiUtils.px2dp(context,topMargin.toFloat()).toInt()
- rightMargin = UiUtils.px2dp(context,rightMargin.toFloat()).toInt()
- bottomMargin = UiUtils.px2dp(context,bottomMargin.toFloat()).toInt()
+ leftMargin = UiUtils.px2dp(context, leftMargin.toFloat()).toInt()
+ topMargin = UiUtils.px2dp(context, topMargin.toFloat()).toInt()
+ rightMargin = UiUtils.px2dp(context, rightMargin.toFloat()).toInt()
+ bottomMargin = UiUtils.px2dp(context, bottomMargin.toFloat()).toInt()
}
val leftMarginText = "$leftMargin ${unit.s}"
val topMarginText = "$topMargin ${unit.s}"
@@ -100,13 +108,13 @@ class BoundsInfoView : View {
var width = it.right - it.left
var height = it.bottom - it.top
if (unit == Unit.DP) {
- width = UiUtils.px2dp(context,width.toFloat()).toInt()
- height = UiUtils.px2dp(context,height.toFloat()).toInt()
+ width = UiUtils.px2dp(context, width.toFloat()).toInt()
+ height = UiUtils.px2dp(context, height.toFloat()).toInt()
}
val text = "$width ${unit.s} × $height ${unit.s}"
paint.reset()
paint.isAntiAlias = true
- paint.textSize = UiUtils.dp2px(context,14F).toFloat()
+ paint.textSize = UiUtils.dp2px(context, 14F).toFloat()
val bounds = Rect()
paint.getTextBounds(text, 0, text.length, bounds)
val textWidth = bounds.width()
@@ -127,7 +135,7 @@ class BoundsInfoView : View {
paint.style = Paint.Style.STROKE
paint.isAntiAlias = true
paint.color = resources.getColor(R.color.colorAccent)
- paint.strokeWidth = UiUtils.dp2px(context,1F).toFloat()
+ paint.strokeWidth = UiUtils.dp2px(context, 1F).toFloat()
CanvasHelper.drawAL(
rect.left,
lineRect.left + edgeLineSize / 2,
@@ -174,7 +182,12 @@ class BoundsInfoView : View {
val lineWidth = measuredWidth / 6
val lineHeight = measuredHeight / 6
val lineRect =
- RectF(rect.left / 2F, rect.top / 2F, measuredWidth - rect.left / 2F, measuredHeight - rect.top / 2F)
+ RectF(
+ rect.left / 2F,
+ rect.top / 2F,
+ measuredWidth - rect.left / 2F,
+ measuredHeight - rect.top / 2F
+ )
canvas?.run {
drawLine(
lineRect.left,
@@ -213,7 +226,7 @@ class BoundsInfoView : View {
paint.style = Paint.Style.STROKE
paint.isAntiAlias = true
paint.color = resources.getColor(R.color.colorAccent)
- paint.strokeWidth = UiUtils.dp2px(context,2F).toFloat()
+ paint.strokeWidth = UiUtils.dp2px(context, 2F).toFloat()
val width = measuredWidth / 3F
val height = measuredHeight / 4F
val top = measuredHeight * 3 / 8F
@@ -224,6 +237,6 @@ class BoundsInfoView : View {
enum class Unit(var s: String) {
- DP("dp"), PX("dp")
+ DP("dp"), PX("px")
}
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/emptyview/EmptyView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/emptyview/EmptyView.kt
index e5c3504..92af967 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/emptyview/EmptyView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/emptyview/EmptyView.kt
@@ -3,48 +3,21 @@ package com.wrbug.developerhelper.ui.widget.emptyview
import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
-import android.view.View
+import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintLayout
import com.wrbug.developerhelper.R
import com.wrbug.developerhelper.commonutil.UiUtils
+import com.wrbug.developerhelper.databinding.ViewEmptyViewBinding
-class EmptyView : LinearLayout {
- val icoIv: ImageView by lazy {
- val icoIv = ImageView(context)
- icoIv.setImageResource(R.drawable.ic_ic_empty_666666)
- icoIv
- }
- val textTv: TextView by lazy {
- val tv = TextView(context)
- tv.setTextColor(resources.getColor(R.color.text_color_666666))
- tv.text = "无数据"
- tv.textSize = 20F
- tv.gravity = Gravity.CENTER
- val params = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
- params.topMargin = UiUtils.dp2px(context, 20F)
- tv.layoutParams = params
- tv
- }
-
- constructor(context: Context) : super(context) {
- }
-
- constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet) {
- init()
- initView()
- }
-
- private fun init() {
- orientation = VERTICAL
- gravity = Gravity.CENTER
- }
+class EmptyView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null
+) : ConstraintLayout(context, attrs) {
+ private val binding = ViewEmptyViewBinding.inflate(LayoutInflater.from(context), this)
- private fun initView() {
- addView(icoIv)
- addView(textTv)
+ fun setTitle(title: String) {
+ binding.tvTitle.text = title
}
-
-
}
\ No newline at end of file
diff --git a/commonwidget/src/main/java/com/wrbug/developerhelper/commonwidget/flexibletoast/FlexibleToast.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/flexibletoast/FlexibleToast.kt
similarity index 63%
rename from commonwidget/src/main/java/com/wrbug/developerhelper/commonwidget/flexibletoast/FlexibleToast.kt
rename to app/src/main/java/com/wrbug/developerhelper/ui/widget/flexibletoast/FlexibleToast.kt
index f492466..ddd5aa0 100644
--- a/commonwidget/src/main/java/com/wrbug/developerhelper/commonwidget/flexibletoast/FlexibleToast.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/flexibletoast/FlexibleToast.kt
@@ -1,6 +1,8 @@
-package com.wrbug.developerhelper.commonwidget.flexibletoast
+package com.wrbug.developerhelper.ui.widget.flexibletoast
import android.content.Context
+import android.os.Handler
+import android.os.Looper
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
@@ -8,9 +10,36 @@ import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import com.wrbug.developerhelper.commonutil.UiUtils
-import com.wrbug.developerhelper.commonwidget.R
+import com.wrbug.developerhelper.databinding.LayoutToastFlexibleBinding
-class FlexibleToast(private val mContext: Context) {
+class FlexibleToast private constructor(private val mContext: Context) {
+
+ companion object {
+ const val GRAVITY_BOTTOM = 0
+ const val GRAVITY_CENTER = 1
+ const val GRAVITY_TOP = 2
+ const val TOAST_SHORT = 0
+ const val TOAST_LONG = 1
+ private var instance: FlexibleToast? = null
+ private fun getInstance(context: Context): FlexibleToast {
+ if (instance == null) {
+ instance = FlexibleToast(context.applicationContext)
+ }
+ return instance as FlexibleToast
+
+ }
+
+ fun toastShow(context: Context, msg: String) {
+ val toast = getInstance(context)
+ val builder = Builder(context).setGravity(GRAVITY_BOTTOM)
+ builder.setSecondText(msg)
+ if (Looper.myLooper() != Looper.getMainLooper()) {
+ Handler(Looper.getMainLooper()).post { toast.toastShow(builder) }
+ } else {
+ toast.toastShow(builder)
+ }
+ }
+ }
private val flexibleToast: Toast by lazy {
Toast(mContext)
@@ -23,11 +52,13 @@ class FlexibleToast(private val mContext: Context) {
0,
0
)
+
builder.mGravity == GRAVITY_TOP -> flexibleToast.setGravity(
Gravity.TOP or Gravity.CENTER_VERTICAL,
0,
UiUtils.dp2px(mContext, 20F)
)
+
else -> flexibleToast.setGravity(
Gravity.BOTTOM or Gravity.CENTER_VERTICAL,
0,
@@ -42,7 +73,7 @@ class FlexibleToast(private val mContext: Context) {
if (builder.hasCustomerView && builder.mCustomerView != null) {
flexibleToast.view = builder.mCustomerView
} else {
- flexibleToast.view = builder.mDefaultView
+ flexibleToast.view = builder.binding.root
}
flexibleToast.show()
}
@@ -51,46 +82,31 @@ class FlexibleToast(private val mContext: Context) {
* 控制Toast的显示样式
*/
class Builder(context: Context) {
- val mDefaultView: View = LayoutInflater.from(context)
- .inflate(R.layout.layout_toast_flexible, null)
+ val binding = LayoutToastFlexibleBinding.inflate(LayoutInflater.from(context))
var mCustomerView: View? = null
- private val mIvImage: ImageView
- private val mTvFirst: TextView
- private val mTvSecond: TextView
-
- private val dividerFirst: View
- private val dividerSecond: View
var mDuration = Toast.LENGTH_SHORT// 0 short, 1 long
var mGravity = 0
var hasCustomerView = false // 是否使用自定义layout
- init {
- mIvImage = mDefaultView.findViewById(R.id.imgIv)
- mTvFirst = mDefaultView.findViewById(R.id.firstTv)
- mTvSecond = mDefaultView.findViewById(R.id.secondTv)
- dividerFirst = mDefaultView.findViewById(R.id.firstDividerView)
- dividerSecond = mDefaultView.findViewById(R.id.secondDividerView)
- }
-
fun setImageResource(resId: Int): Builder {
- this.mIvImage.setImageResource(resId)
- this.mIvImage.visibility = View.VISIBLE
- this.dividerFirst.visibility = View.VISIBLE
+ binding.imgIv.setImageResource(resId)
+ binding.imgIv.visibility = View.VISIBLE
+ binding.firstDividerView.visibility = View.VISIBLE
return this
}
fun setFirstText(firstText: String): Builder {
- this.mTvFirst.text = firstText
- this.mTvFirst.visibility = View.VISIBLE
- this.dividerSecond.visibility = View.VISIBLE
+ binding.firstTv.text = firstText
+ binding.firstTv.visibility = View.VISIBLE
+ binding.secondDividerView.visibility = View.VISIBLE
return this
}
fun setSecondText(secondText: String): Builder {
- this.mTvSecond.text = secondText
- this.mTvSecond.visibility = View.VISIBLE
+ binding.secondTv.text = secondText
+ binding.secondTv.visibility = View.VISIBLE
return this
}
@@ -116,14 +132,4 @@ class FlexibleToast(private val mContext: Context) {
}
}
- companion object {
-
- const val GRAVITY_BOTTOM = 0
- const val GRAVITY_CENTER = 1
- const val GRAVITY_TOP = 2
- const val TOAST_SHORT = 0
- const val TOAST_LONG = 1
- }
-
-
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyDetailView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyDetailView.kt
index 1309219..fb54b6e 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyDetailView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyDetailView.kt
@@ -6,15 +6,16 @@ import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.widget.FrameLayout
-import com.wrbug.developerhelper.model.entity.HierarchyNode
+import com.wrbug.developerhelper.base.entry.HierarchyNode
import com.wrbug.developerhelper.R
import com.wrbug.developerhelper.ui.widget.helper.CanvasHelper
import com.wrbug.developerhelper.commonutil.UiUtils
class HierarchyDetailView : FrameLayout {
+
private val paint: Paint by lazy {
val paint = Paint()
- paint.color = context.resources.getColor(R.color.colorAccent)
+ paint.color = context.resources.getColor(R.color.material_color_blue_800)
paint.style = Paint.Style.STROKE
paint.strokeWidth = 3F
paint
@@ -34,7 +35,6 @@ class HierarchyDetailView : FrameLayout {
initView()
}
-
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initView()
}
@@ -50,14 +50,13 @@ class HierarchyDetailView : FrameLayout {
setWillNotDraw(false)
}
-
- override fun onDraw(canvas: Canvas?) {
+ override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (hierarchyNode != null) {
- drawNode(canvas)
if (hierarchyNode?.parentId!! > -1) {
drawParentNode(canvas)
}
+ drawNode(canvas)
}
}
@@ -65,7 +64,7 @@ class HierarchyDetailView : FrameLayout {
if (parentHierarchyNode == null) {
return
}
- val bounds = parentHierarchyNode?.screenBounds
+ val bounds = parentHierarchyNode?.screenBounds ?: return
canvas?.drawRect(bounds, parentpPaint)
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyView.kt
index fd4c119..93d95f5 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/HierarchyView.kt
@@ -7,8 +7,9 @@ import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
-import com.wrbug.developerhelper.model.entity.HierarchyNode
+import com.wrbug.developerhelper.base.entry.HierarchyNode
import com.wrbug.developerhelper.service.DeveloperHelperAccessibilityService
+import kotlin.math.pow
class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
private val strokePaint = Paint()
@@ -18,6 +19,7 @@ class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attr
private var onHierarchyNodeClickListener: OnHierarchyNodeClickListener? = null
private var selectedNode: HierarchyNode? = null
private var selectedParentNode: HierarchyNode? = null
+ private var isFromLeftDown = false
constructor(context: Context) : this(context, null)
@@ -36,6 +38,7 @@ class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attr
mHierarchyNodes.addAll(it)
}
nodeMap.putAll(DeveloperHelperAccessibilityService.nodeMap)
+ visibility = View.VISIBLE
invalidate()
}
@@ -46,15 +49,25 @@ class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attr
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
+ isFromLeftDown = event.x <= 15
+ if (isFromLeftDown) {
+ return super.onTouchEvent(event)
+ }
getSelectedNode(event.x, event.y)
return true
}
+
MotionEvent.ACTION_MOVE -> {
- getSelectedNode(event.x, event.y)
+ if (!isFromLeftDown) {
+ getSelectedNode(event.x, event.y)
+ }
}
+
MotionEvent.ACTION_UP -> {
- selectedNode?.let {
- onHierarchyNodeClickListener?.onClick(it, selectedParentNode)
+ if (!isFromLeftDown) {
+ selectedNode?.let {
+ onHierarchyNodeClickListener?.onClick(it, selectedParentNode)
+ }
}
}
}
@@ -69,15 +82,17 @@ class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attr
}
selectedNode = hierarchyNode.selectedNode
selectedParentNode = hierarchyNode.parentNode
- onHierarchyNodeClickListener?.onSelectedNodeChanged(hierarchyNode.selectedNode, hierarchyNode.parentNode)
+ onHierarchyNodeClickListener?.onSelectedNodeChanged(
+ hierarchyNode.selectedNode, hierarchyNode.parentNode
+ )
}
}
- override fun onDraw(canvas: Canvas?) {
+ override fun onDraw(canvas: Canvas) {
drawRect(canvas, mHierarchyNodes)
}
- private fun drawRect(canvas: Canvas?, hierarchyNodes: List) {
+ private fun drawRect(canvas: Canvas, hierarchyNodes: List) {
for (hierarchyNode in hierarchyNodes) {
drawWidget(canvas, hierarchyNode)
drawRect(canvas, hierarchyNode.childId)
@@ -107,10 +122,10 @@ class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attr
} else {
var left = info.selectedNode.screenBounds?.left ?: 0
var top = info.selectedNode.screenBounds?.top ?: 0
- val len = Math.pow(x.toDouble() - left, 2.0) + Math.pow(y.toDouble() - top, 2.0)
+ val len = (x.toDouble() - left).pow(2.0) + (y.toDouble() - top).pow(2.0)
left = list[index].selectedNode.screenBounds?.left ?: 0
top = list[index].selectedNode.screenBounds?.top ?: 0
- val len1 = Math.pow(x.toDouble() - left, 2.0) + Math.pow(y.toDouble() - top, 2.0)
+ val len1 = (x.toDouble() - left).pow(2.0) + (y.toDouble() - top).pow(2.0)
if (len1 < len) {
info = list[index]
}
@@ -119,10 +134,12 @@ class HierarchyView(context: Context, attrs: AttributeSet?) : View(context, attr
return info
}
- private fun getNode(x: Float, y: Float, hierarchyNode: HierarchyNode, list: ArrayList) {
+ private fun getNode(
+ x: Float, y: Float, hierarchyNode: HierarchyNode, list: ArrayList
+ ) {
val rect = hierarchyNode.screenBounds ?: return
if (rect.contains(x.toInt(), y.toInt())) {
- if (!hierarchyNode.childId.isEmpty()) {
+ if (hierarchyNode.childId.isNotEmpty()) {
for (child in hierarchyNode.childId.reversed()) {
getNode(x, y, child, list)
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/SelectedNodeInfo.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/SelectedNodeInfo.kt
index c9bfae6..c960bfd 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/SelectedNodeInfo.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/hierarchyView/SelectedNodeInfo.kt
@@ -1,7 +1,6 @@
package com.wrbug.developerhelper.ui.widget.hierarchyView
-import android.graphics.Rect
-import com.wrbug.developerhelper.model.entity.HierarchyNode
+import com.wrbug.developerhelper.base.entry.HierarchyNode
class SelectedNodeInfo(var selectedNode: HierarchyNode, var parentNode: HierarchyNode?) {
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoDialog.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoDialog.kt
new file mode 100644
index 0000000..96bdc1f
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoDialog.kt
@@ -0,0 +1,100 @@
+package com.wrbug.developerhelper.ui.widget.layoutinfoview
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentManager
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.base.ExtraKey
+import com.wrbug.developerhelper.base.entry.HierarchyNode
+import com.wrbug.developerhelper.commonutil.UiUtils
+import com.wrbug.developerhelper.commonutil.dp2px
+import com.wrbug.developerhelper.databinding.ViewLayoutInfoBinding
+import com.wrbug.developerhelper.util.isPortrait
+
+class LayoutInfoDialog : DialogFragment() {
+
+ companion object {
+ fun show(
+ fragmentManager: FragmentManager,
+ list: List?,
+ selectedNode: HierarchyNode,
+ listener: ((HierarchyNode, HierarchyNode?) -> Unit)
+ ) {
+ LayoutInfoDialog().apply {
+ arguments = Bundle().apply {
+ putParcelableArrayList(ExtraKey.DATA, list?.let { ArrayList(it) })
+ putParcelable(ExtraKey.SELECTED, selectedNode)
+ }
+ onNodeChangedListener = listener
+ }.show(fragmentManager, "LayoutInfoDialog")
+ }
+ }
+
+ private val nodeList: List? by lazy {
+ arguments?.getParcelableArrayList(ExtraKey.DATA)
+ }
+ private val hierarchyNode: HierarchyNode? by lazy {
+ arguments?.getParcelable(ExtraKey.SELECTED)
+ }
+ private var onNodeChangedListener: ((HierarchyNode, HierarchyNode?) -> Unit)? = null
+
+ val adapter by lazy {
+ LayoutInfoViewPagerAdapter(requireContext(), nodeList, hierarchyNode!!)
+ }
+
+ private lateinit var binding: ViewLayoutInfoBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setStyle(STYLE_NORMAL, R.style.FullScreenDialog)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = ViewLayoutInfoBinding.inflate(layoutInflater)
+ return binding.root
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return super.onCreateDialog(savedInstanceState).apply {
+ setCanceledOnTouchOutside(true)
+ window?.run {
+ val layoutParams = attributes
+ if (isPortrait()) {
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
+ layoutParams.height = UiUtils.getDeviceHeight() / 2
+ setGravity(Gravity.BOTTOM)
+ } else {
+ layoutParams.width = UiUtils.getDeviceWidth() / 2
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
+ setGravity(Gravity.END)
+ }
+ attributes = layoutParams
+ }
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ if (dialog?.window?.attributes?.gravity != Gravity.BOTTOM) {
+ binding.layoutInfoContainer.setPadding(0, UiUtils.getStatusHeight(), 0, 0)
+ }
+ onNodeChangedListener?.let {
+ adapter.setOnNodeChangedListener(it)
+ }
+ initViewpager()
+ }
+
+ private fun initViewpager() {
+ binding.viewPager.adapter = adapter
+ binding.tabLayout.setupWithViewPager(binding.viewPager)
+ }
+}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoView.kt
deleted file mode 100644
index f077e16..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoView.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.wrbug.developerhelper.ui.widget.layoutinfoview
-
-import android.content.Context
-import com.google.android.material.bottomsheet.BottomSheetDialog
-import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.model.entity.HierarchyNode
-import com.wrbug.developerhelper.commonutil.UiUtils
-import kotlinx.android.synthetic.main.view_layout_info.*
-
-
-class LayoutInfoView(
- context: Context,
- private val nodeList: List?,
- private val hierarchyNode: HierarchyNode
-) : BottomSheetDialog(context) {
- val adapter = LayoutInfoViewPagerAdapter(context, nodeList, hierarchyNode)
-
- init {
- init()
- }
-
- fun setOnNodeChangedListener(listener: OnNodeChangedListener) {
- adapter.setOnNodeChangedListener(listener)
- }
-
- private fun init() {
- setContentView(R.layout.view_layout_info)
- val layoutParams = layoutInfoContainer.layoutParams
- layoutParams.height = UiUtils.getDeviceHeight(context) / 2
- layoutInfoContainer.layoutParams = layoutParams
- initViewpager()
- }
-
- private fun initViewpager() {
- viewPager.adapter = adapter
- tabLayout.setupWithViewPager(viewPager)
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoViewPagerAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoViewPagerAdapter.kt
index 3c6c383..bb9148e 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoViewPagerAdapter.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/LayoutInfoViewPagerAdapter.kt
@@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.wrbug.developerhelper.R
-import com.wrbug.developerhelper.model.entity.HierarchyNode
+import com.wrbug.developerhelper.base.entry.HierarchyNode
import com.wrbug.developerhelper.ui.widget.boundsinfoview.BoundsInfoView
import com.wrbug.developerhelper.ui.widget.layoutinfoview.infopage.InfoAdapter
import com.wrbug.developerhelper.ui.widget.layoutinfoview.infopage.ItemInfo
@@ -30,7 +30,7 @@ class LayoutInfoViewPagerAdapter(
private val infoAdapter: InfoAdapter = InfoAdapter(context)
private lateinit var graphView: GraphView
private val boundsInfoView = BoundsInfoView(context)
- private var onNodeChangedListener: OnNodeChangedListener? = null
+ private var onNodeChangedListener: ((HierarchyNode, HierarchyNode?) -> Unit)? = null
init {
initInfoTab()
@@ -38,14 +38,14 @@ class LayoutInfoViewPagerAdapter(
initViewTreeTab()
}
- fun setOnNodeChangedListener(listener: OnNodeChangedListener) {
+ fun setOnNodeChangedListener(listener: (HierarchyNode, HierarchyNode?) -> Unit) {
onNodeChangedListener = listener
}
private fun initViewTreeTab() {
tabList.add("ViewTree")
graphView =
- LayoutInflater.from(context).inflate(R.layout.layout_hierarchy_tree, null) as GraphView
+ LayoutInflater.from(context).inflate(R.layout.layout_hierarchy_tree, null) as GraphView
val adapter = ViewTreeGraphAdapter(context, R.layout.item_tree_node_view)
graphView.adapter = adapter
adapter.setOnItemClickListener(object : ViewTreeGraphAdapter.OnItemClickListener {
@@ -54,9 +54,8 @@ class LayoutInfoViewPagerAdapter(
resetInfoTab()
resetLayoutTable()
resetViewTreeTab(node)
- onNodeChangedListener?.onChanged(node.node, node.parent?.node)
+ onNodeChangedListener?.invoke(node.node, node.parent?.node)
}
-
})
val configuration = BuchheimWalkerConfiguration.Builder()
.setSiblingSeparation(100)
@@ -151,7 +150,7 @@ class LayoutInfoViewPagerAdapter(
"${resourceId.replace(packageName, "app")}[${idHex?.replace("#", "0x") ?: "NO_ID"}]"
)
)
- if (!text.isEmpty()) {
+ if (text.isNotEmpty()) {
list.add(ItemInfo("Text", text))
}
list.add(ItemInfo("Enable", enabled))
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/OnNodeChangedListener.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/OnNodeChangedListener.kt
deleted file mode 100644
index 2aa5773..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/OnNodeChangedListener.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.wrbug.developerhelper.ui.widget.layoutinfoview
-
-import com.wrbug.developerhelper.model.entity.HierarchyNode
-
-interface OnNodeChangedListener {
- fun onChanged(node: HierarchyNode, parentNode: HierarchyNode?)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphAdapter.kt
index bafec3c..1871acd 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphAdapter.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphAdapter.kt
@@ -9,7 +9,7 @@ import androidx.cardview.widget.CardView
import com.wrbug.developerhelper.R
import de.blox.graphview.BaseGraphAdapter
-class ViewTreeGraphAdapter(@NonNull val context: Context, @LayoutRes val layoutRes: Int) :
+class ViewTreeGraphAdapter(val context: Context, @LayoutRes val layoutRes: Int) :
BaseGraphAdapter(context, layoutRes) {
private var listener: OnItemClickListener? = null
override fun onCreateViewHolder(view: View?) = ViewHolder(view!!)
@@ -18,6 +18,7 @@ class ViewTreeGraphAdapter(@NonNull val context: Context, @LayoutRes val layoutR
val node = data as ViewTreeGraphNode
widgetTv.text = node.node.widget
cardView.setOnClickListener {
+ widgetTv.text = node.node.widget
listener?.onClick(node, position)
}
when {
@@ -27,13 +28,6 @@ class ViewTreeGraphAdapter(@NonNull val context: Context, @LayoutRes val layoutR
cardView.setCardBackgroundColor(context.resources.getColor(R.color.colorPrimary))
if (node.shortName) {
widgetTv.text = toShortName(node.node.widget)
- cardView.setOnClickListener {
- widgetTv.text = node.node.widget
- node.shortName = false
- cardView.setOnClickListener{
- listener?.onClick(node, position)
- }
- }
} else {
widgetTv.text = node.node.widget
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphNode.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphNode.kt
index 5827dc7..21a3846 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphNode.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/ViewTreeGraphNode.kt
@@ -1,6 +1,6 @@
package com.wrbug.developerhelper.ui.widget.layoutinfoview
-import com.wrbug.developerhelper.model.entity.HierarchyNode
+import com.wrbug.developerhelper.base.entry.HierarchyNode
class ViewTreeGraphNode(val node: HierarchyNode) {
var selected: Boolean = false
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/InfoAdapter.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/InfoAdapter.kt
index 4a66f6f..f37bfe6 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/InfoAdapter.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/InfoAdapter.kt
@@ -2,25 +2,56 @@ package com.wrbug.developerhelper.ui.widget.layoutinfoview.infopage
import android.content.Context
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
-import com.wrbug.developerhelper.R
+import com.airbnb.lottie.LottieDrawable
+import com.wrbug.developerhelper.commonutil.ClipboardUtils
import com.wrbug.developerhelper.commonutil.print
-import kotlinx.android.synthetic.main.item_view_info.view.*
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+import com.wrbug.developerhelper.util.visible
+import com.wrbug.developerhelper.databinding.ItemInfoLoadingBinding
+import com.wrbug.developerhelper.databinding.ItemViewInfoBinding
-class InfoAdapter(val context: Context) : RecyclerView.Adapter() {
- private val list = arrayListOf()
- override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ViewHolder {
- return ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_view_info, p0, false))
+class InfoAdapter(val context: Context, private val topItem: ItemInfo? = null) :
+ RecyclerView.Adapter() {
+ companion object {
+ private const val VIEW_TYPE_ITEM = 0
+ private const val VIEW_TYPE_LOADING = 1
+ }
+
+ private val list = arrayListOf()
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
+ if (p1 == VIEW_TYPE_LOADING) {
+ return LoadingViewHolder(
+ ItemInfoLoadingBinding.inflate(
+ LayoutInflater.from(p0.context), p0, false
+ )
+ )
+ }
+ return InfoViewHolder(
+ ItemViewInfoBinding.inflate(
+ LayoutInflater.from(p0.context), p0, false
+ )
+ )
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return if (list[position] is LoadingItem) {
+ VIEW_TYPE_LOADING
+ } else {
+ VIEW_TYPE_ITEM
+ }
}
override fun getItemCount(): Int {
return list.size
}
- fun setItems(list: ArrayList) {
+ fun setItems(list: List) {
this.list.clear()
+ topItem?.let {
+ this.list.add(it)
+ }
if (list.isEmpty().not()) {
this.list.addAll(list)
}
@@ -35,15 +66,27 @@ class InfoAdapter(val context: Context) : RecyclerView.Adapter Unit) {
+ setOnClickListener(View.OnClickListener { v -> v.onclick() })
+ }
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/LoadingItem.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/LoadingItem.kt
new file mode 100644
index 0000000..a0dc06e
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/layoutinfoview/infopage/LoadingItem.kt
@@ -0,0 +1,4 @@
+package com.wrbug.developerhelper.ui.widget.layoutinfoview.infopage
+
+object LoadingItem {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/ui/widget/settingitemview/SettingItemView.kt b/app/src/main/java/com/wrbug/developerhelper/ui/widget/settingitemview/SettingItemView.kt
index 4128255..8fed9fa 100644
--- a/app/src/main/java/com/wrbug/developerhelper/ui/widget/settingitemview/SettingItemView.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/ui/widget/settingitemview/SettingItemView.kt
@@ -1,17 +1,25 @@
package com.wrbug.developerhelper.ui.widget.settingitemview
import android.content.Context
+import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
-import android.text.TextUtils
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.CompoundButton
-import android.widget.FrameLayout
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import androidx.core.view.updatePadding
import com.wrbug.developerhelper.R
-import kotlinx.android.synthetic.main.view_setting_item.view.*
+import com.wrbug.developerhelper.commonutil.dpInt
+import com.wrbug.developerhelper.util.setOnDoubleCheckClickListener
+import com.wrbug.developerhelper.databinding.ViewSettingItemBinding
+
+class SettingItemView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null
+) : ConstraintLayout(context, attrs) {
-class SettingItemView : FrameLayout {
var checkable: Boolean = true
set(value) {
field = value
@@ -21,35 +29,34 @@ class SettingItemView : FrameLayout {
var checked: Boolean = false
set(value) {
field = value
- switcher.isChecked = checked
+ binding.switcher.isChecked = checked
}
+ private var switcherMaskViewClicked = false
+ private val binding = ViewSettingItemBinding.inflate(LayoutInflater.from(context), this)
-
- constructor(context: Context) : super(context) {
- initView()
- }
-
- constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
+ init {
initView()
initAttrs(attrs)
}
private fun initView() {
- LayoutInflater.from(context).inflate(R.layout.view_setting_item, this)
+ updatePadding(top = 8.dpInt(context), bottom = 8.dpInt(context))
setBackgroundResource(R.drawable.ripple_with_color_mask)
}
- private fun initAttrs(attrs: AttributeSet) {
+ private fun initAttrs(attrs: AttributeSet?) {
+ attrs ?: return
with(context.obtainStyledAttributes(attrs, R.styleable.SettingItemView)) {
val src = getDrawable(R.styleable.SettingItemView_src)
- src?.let {
- setImage(it)
+ setImage(src)
+ getColorStateList(R.styleable.SettingItemView_icoTint)?.let {
+ setIconTint(it)
}
val title = getString(R.styleable.SettingItemView_title)
- titleTv.text = title
+ binding.titleTv.text = title
setSummary(getString(R.styleable.SettingItemView_summary))
val switchVisible = getBoolean(R.styleable.SettingItemView_switchVisible, true)
- switcher.visibility = if (switchVisible) View.VISIBLE else View.GONE
+ binding.switcher.visibility = if (switchVisible) View.VISIBLE else View.GONE
checked = getBoolean(R.styleable.SettingItemView_checked, false)
checkable = getBoolean(R.styleable.SettingItemView_checkable, true)
recycle()
@@ -57,40 +64,40 @@ class SettingItemView : FrameLayout {
}
+ private fun setIconTint(colorStateList: ColorStateList?) {
+ binding.icoIv.imageTintList = colorStateList
+ }
+
override fun setOnClickListener(l: OnClickListener?) {
super.setOnClickListener(l)
- switcherMaskView.setOnClickListener(l)
+ if (switcherMaskViewClicked.not()) {
+ binding.switcherMaskView.setOnClickListener(l)
+ }
+ }
+
+ fun setOnSwitcherClickListener(listener: View.() -> Unit) {
+ switcherMaskViewClicked = true
+ binding.switcherMaskView.setOnDoubleCheckClickListener(clickListener = listener)
}
- fun isChecked() = switcher.isChecked
+ fun isChecked() = binding.switcher.isChecked
private fun setSwitchCheckable() {
- if (checkable) {
-// switcher.setOnTouchListener(null)
- switcherMaskView.visibility = View.GONE
- } else {
-// switcher.setOnTouchListener { _, _ -> true }
- switcherMaskView.visibility = View.VISIBLE
- }
+ binding.switcherMaskView.isGone = checkable
}
fun setOnCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener) {
- switcher.setOnCheckedChangeListener(listener)
+ binding.switcher.setOnCheckedChangeListener(listener)
}
- fun setImage(drawable: Drawable) {
- icoIv.setImageDrawable(drawable)
- icoIv.visibility = View.VISIBLE
+ fun setImage(drawable: Drawable?) {
+ binding.icoIv.setImageDrawable(drawable)
+ binding.icoIv.isVisible = drawable != null
}
fun setSummary(summary: String?) {
- summary.takeIf {
- !TextUtils.isEmpty(it)
- }?.let {
- summaryTv.text = it
- summaryTv.visibility = View.VISIBLE
- }
+ binding.summaryTv.text = summary
+ binding.summaryTv.isVisible = !summary.isNullOrEmpty()
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/AppStatusRegister.kt b/app/src/main/java/com/wrbug/developerhelper/util/AppStatusRegister.kt
new file mode 100644
index 0000000..1d49973
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/util/AppStatusRegister.kt
@@ -0,0 +1,56 @@
+package com.wrbug.developerhelper.util
+
+import android.app.Activity
+import android.app.Application
+import android.os.Bundle
+
+object AppStatusRegister {
+ private var count = 0
+ private val backgroundMap = hashMapOf Unit>()
+ fun init(application: Application) {
+ application.registerActivityLifecycleCallbacks(object :
+ Application.ActivityLifecycleCallbacks {
+ override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
+
+ }
+
+ override fun onActivityStarted(activity: Activity) {
+ count++
+ }
+
+ override fun onActivityResumed(activity: Activity) {
+ }
+
+ override fun onActivityPaused(activity: Activity) {
+ }
+
+ override fun onActivityStopped(activity: Activity) {
+ count--
+ backgroundCheck()
+ }
+
+ override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
+ }
+
+ override fun onActivityDestroyed(activity: Activity) {
+ }
+
+ })
+ }
+
+
+ fun registerBackgroundListener(key: String, listener: () -> Unit) {
+ backgroundMap[key] = listener
+ }
+
+ fun removeBackgroundListener(key: String) {
+ backgroundMap.remove(key)
+ }
+
+ private fun backgroundCheck() {
+ if (count == 0) {
+ backgroundMap.values.forEach { it() }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/BackupUtils.kt b/app/src/main/java/com/wrbug/developerhelper/util/BackupUtils.kt
index 90f8bf3..8ba7977 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/BackupUtils.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/BackupUtils.kt
@@ -1,34 +1,176 @@
package com.wrbug.developerhelper.util
-import android.net.Uri
import android.os.Environment
+import com.wrbug.developerhelper.commonutil.Constant
+import com.wrbug.developerhelper.commonutil.entity.ApkInfo
+import com.wrbug.developerhelper.commonutil.fromJson
+import com.wrbug.developerhelper.commonutil.safeCreateSingle
+import com.wrbug.developerhelper.commonutil.safeRead
import com.wrbug.developerhelper.commonutil.shell.ShellManager
-import com.wrbug.developerhelper.commonutil.zip
+import com.wrbug.developerhelper.commonutil.toJson
+import com.wrbug.developerhelper.model.entity.BackupAppData
+import com.wrbug.developerhelper.model.entity.BackupAppInfo
+import com.wrbug.developerhelper.model.entity.BackupAppItemInfo
+import io.reactivex.rxjava3.core.Single
+import net.dongliu.apk.parser.ApkFile
import java.io.File
object BackupUtils {
- private val backupDir: File by lazy {
- val file = File(Environment.getExternalStorageDirectory(), "com.wrbug.developerHelper/backup")
+ private const val ANDROID_DATA_TAR = "android_data.tar"
+ private const val DATA_TAR = "data.tar"
+ private const val CONFIG_JSON = "config.json"
+ private const val ICON_PNG = "icon.png"
+ private val backupRootDir: File by lazy {
+ val file =
+ File(Environment.getExternalStorageDirectory(), "DeveloperHelper/backup")
if (file.exists().not()) {
file.mkdirs()
}
file
}
- fun backupApk(packageName: String, apkPath: String, fileName: String): Uri? {
- val apkDir = File(backupDir, "apks/$packageName/$fileName")
+ fun getCurrentAppBackupDir(packageName: String, dateDir: String): File {
+ return File(getAppBackupDir(packageName), dateDir)
+ }
+
+ fun getAppBackupDir(packageName: String): File {
+ return File(backupRootDir, packageName).apply {
+ if (!exists()) {
+ mkdirs()
+ }
+ }
+ }
+
+ fun backupApk(
+ packageName: String,
+ dateDir: String,
+ apkPath: String,
+ fileName: String
+ ): String? {
+ val apkDir = File(getCurrentAppBackupDir(packageName, dateDir), fileName)
if (ShellManager.cpFile(apkPath, apkDir.absolutePath)) {
- return apkDir.toUri()
+ return apkDir.absolutePath
}
return null
}
- fun backupAppData(packageName: String, dataDir: String): File? {
- val backupDataDir =
- File(backupDir, "datas/$packageName/${System.currentTimeMillis().format("yyyy-MM-dd-HH_mm_ss")}")
- if (ShellManager.cpFile(dataDir, backupDataDir.absolutePath)) {
+ fun backupAppData(dateDir: String, packageName: String): File? {
+ val backupDataDir = File(getCurrentAppBackupDir(packageName, dateDir), DATA_TAR)
+ val dataDir = Constant.getDataDir(packageName)
+ if (ShellManager.tarCF(backupDataDir.absolutePath, dataDir)) {
return backupDataDir
}
return null
}
+
+ fun backupAppAndroidData(dateDir: String, packageName: String): String? {
+ val backupDataDir = File(
+ getCurrentAppBackupDir(packageName, dateDir), ANDROID_DATA_TAR
+ )
+ val dataDir =
+ Environment.getExternalStorageDirectory().absolutePath + "/Android/data/" + packageName
+ if (!File(dataDir).exists()) {
+ return ""
+ }
+ if (ShellManager.tarCF(backupDataDir.absolutePath, dataDir)) {
+ return backupDataDir.absolutePath
+ }
+ return null
+ }
+
+ fun saveBackupInfo(
+ apkInfo: ApkInfo,
+ backupAppItemInfo: BackupAppItemInfo,
+ tarFile: String
+ ): Boolean {
+ val apkFile = apkInfo.applicationInfo.publicSourceDir
+ val tmpApkFile = File(getAppBackupDir(apkInfo.applicationInfo.packageName), "tmp.apk")
+ ShellManager.cpFile(apkFile, tmpApkFile.absolutePath)
+ runCatching {
+ ApkFile(tmpApkFile).allIcons.find { it.isFile }?.data?.let {
+ File(getAppBackupDir(apkInfo.applicationInfo.packageName), ICON_PNG).writeBytes(it)
+ }
+ }
+ tmpApkFile.delete()
+ backupAppItemInfo.androidDataFile = ANDROID_DATA_TAR
+ backupAppItemInfo.dataFile = DATA_TAR
+ val configFile = File(getAppBackupDir(apkInfo.applicationInfo.packageName), CONFIG_JSON)
+ val info = configFile.safeRead().fromJson() ?: BackupAppInfo()
+ info.appName = apkInfo.getAppName()
+ info.packageName = apkInfo.applicationInfo.packageName
+ info.backupMap[tarFile] = backupAppItemInfo
+ configFile.writeText(info.toJson().orEmpty())
+ return true
+ }
+
+
+ fun zipBackupFile(packageName: String, dateDir: String): File? {
+ val target = File(getAppBackupDir(packageName), "$dateDir.tar")
+ val src = getCurrentAppBackupDir(packageName, dateDir).absolutePath
+ if (ShellManager.tarCF(target.absolutePath, src)) {
+ ShellManager.rmFile(src)
+ return target
+ }
+ return null
+ }
+
+ fun getAllBackupInfo(): Single> {
+ return safeCreateSingle {
+ val list = arrayListOf()
+ backupRootDir.listFiles()?.forEach { root ->
+ val configJson = File(root, CONFIG_JSON)
+ if (!configJson.exists()) {
+ return@forEach
+ }
+ val info = configJson.safeRead().fromJson() ?: return@forEach
+ val map = info.backupMap.filter { File(root, it.key).exists() }
+ if (map.isEmpty()) {
+ configJson.delete()
+ return@forEach
+ }
+ val icoFile = File(root, ICON_PNG).takeIf { it.exists() }
+ list.add(BackupAppData(info.appName, info.packageName, root, HashMap(map), icoFile))
+ }
+ it.onSuccess(list)
+ }
+ }
+
+ fun getBackupAppInfo(packageName: String): Single {
+ return safeCreateSingle {
+ val dir = backupRootDir.listFiles { _, name -> name == packageName }?.getOrNull(0)
+ val configJson = File(dir, CONFIG_JSON)
+ val info = configJson.safeRead().fromJson()
+ if (info == null) {
+ it.onError(Exception())
+ return@safeCreateSingle
+ }
+ it.onSuccess(info)
+ }
+ }
+
+ fun deleteBackupItem(packageName: String, tarFile: String): Single {
+ return safeCreateSingle {
+ val dir = backupRootDir.listFiles { _, name -> name == packageName }?.getOrNull(0)
+ val backupArch = dir?.let { File(it, tarFile) }
+ if (dir == null || !dir.exists() || backupArch?.exists() != true) {
+ it.onError(Exception())
+ return@safeCreateSingle
+ }
+ backupArch.delete()
+ val configJson = File(dir, CONFIG_JSON)
+ val info = configJson.safeRead().fromJson()
+ if (info == null) {
+ it.onError(Exception())
+ return@safeCreateSingle
+ }
+ val newInfo = info.copy(
+ backupMap = info.backupMap.apply { remove(tarFile) }
+ )
+ configJson.writeText(newInfo.toJson().orEmpty())
+ it.onSuccess(newInfo)
+ }
+
+ }
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/DateUtilsExt.kt b/app/src/main/java/com/wrbug/developerhelper/util/DateUtilsExt.kt
index 3e6e0cd..6fc9513 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/DateUtilsExt.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/DateUtilsExt.kt
@@ -1,9 +1,11 @@
package com.wrbug.developerhelper.util
+import android.annotation.SuppressLint
import java.text.SimpleDateFormat
import java.util.*
+@SuppressLint("SimpleDateFormat")
fun Date.format(format: String="yyyy-MM-dd HH:mm:ss"): String {
val simpleDateFormat = SimpleDateFormat(format)
return simpleDateFormat.format(this)
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/DeviceUtils.kt b/app/src/main/java/com/wrbug/developerhelper/util/DeviceUtils.kt
index b44b4c9..59742b1 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/DeviceUtils.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/DeviceUtils.kt
@@ -3,9 +3,10 @@ package com.wrbug.developerhelper.util
import android.content.Context
import android.os.Build
import android.provider.Settings
-import android.text.TextUtils
-import com.wrbug.developerhelper.basecommon.BaseApp
-import com.wrbug.developerhelper.commonutil.ShellUtils
+import android.util.DisplayMetrics
+import android.view.WindowManager
+import com.wrbug.developerhelper.base.BaseApp
+import com.wrbug.developerhelper.commonutil.shell.ShellUtils
object DeviceUtils {
@@ -14,10 +15,27 @@ object DeviceUtils {
}
fun isFloatWindowOpened(): Boolean {
- return isFloatWindowOpened(BaseApp.instance!!)
+ return isFloatWindowOpened(BaseApp.instance)
}
fun isFloatWindowOpened(context: Context): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context)
}
+
+
+ fun getScreenWidth(): Int {
+ val manager: WindowManager =
+ BaseApp.instance.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val outMetrics = DisplayMetrics()
+ manager.defaultDisplay.getMetrics(outMetrics)
+ return outMetrics.widthPixels
+ }
+
+ fun getScreenHeight(): Int {
+ val manager: WindowManager =
+ BaseApp.instance.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val outMetrics = DisplayMetrics()
+ manager.defaultDisplay.getMetrics(outMetrics)
+ return outMetrics.heightPixels
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/EnforceUtils.kt b/app/src/main/java/com/wrbug/developerhelper/util/EnforceUtils.kt
deleted file mode 100644
index c79da14..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/util/EnforceUtils.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.wrbug.developerhelper.util
-import com.wrbug.developerhelper.commonutil.shell.ShellManager
-
-object EnforceUtils {
- fun getEnforceType(packageName: String): EnforceType {
- val files = ShellManager.getZipFileList(ShellManager.findApkDir(packageName)).toString().trim()
- return when {
- isIjiaMi(files) -> EnforceType.I_JIA_MI
- is360(files) -> EnforceType.QI_HOO
- isLeGu(files) -> EnforceType.LE_GU
- isBangcle(files) -> EnforceType.BANGCLE
- else -> EnforceType.UN_KNOWN
- }
- }
-
- private fun isIjiaMi(files: String): Boolean {
- return files.contains("ijm") or files.contains("ijiami")
-
- }
-
- private fun is360(files: String): Boolean {
- return files.contains("libjiagu.so")
- }
-
- private fun isLeGu(files: String): Boolean {
- return files.contains("tencent_stub")
- }
-
- private fun isBangcle(files: String): Boolean {
- return files.contains("bangcle")
- }
-
-
- enum class EnforceType(val type: String) {
- QI_HOO("360"),
- BAI_DU("百度"),
- I_JIA_MI("爱加密"),
- LE_GU("乐固"),
- BANGCLE("梆梆"),
- UN_KNOWN("未知/无加固"),
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/FileUtils.kt b/app/src/main/java/com/wrbug/developerhelper/util/FileUtils.kt
deleted file mode 100644
index ca7532c..0000000
--- a/app/src/main/java/com/wrbug/developerhelper/util/FileUtils.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.wrbug.developerhelper.util
-
-import android.media.MediaMetadataRetriever
-import android.net.Uri
-import android.os.Build
-import androidx.core.content.FileProvider
-import com.wrbug.developerhelper.basecommon.BaseApp
-import org.dom4j.Document
-import org.dom4j.io.OutputFormat
-import org.dom4j.io.XMLWriter
-
-import java.io.*
-
-
-/**
- * Created by wrbug on 2017/8/23.
- */
-object FileUtils {
-
- fun inputstreamtofile(ins: InputStream, file: File) {
- try {
- if (file.exists()) {
- file.createNewFile()
- }
- val os = FileOutputStream(file)
- os.write(ins.readBytes())
- os.close()
- ins.close()
- } catch (t: Throwable) {
-
- }
-
- }
-
-
- fun whiteXml(file: File, document: Document) {
- try {
- if (!file.exists()) {
- file.createNewFile()
- }
- val format = OutputFormat.createPrettyPrint()
- format.encoding = "utf-8"
- val writer = XMLWriter(OutputStreamWriter(FileOutputStream(file), "utf-8"), format)
- writer.write(document)
- writer.close()
- } catch (e: IOException) {
- }
-
- }
-
- fun inputStream2String(ins: InputStream): String {
- val out = StringBuffer()
- val b = ByteArray(4096)
- try {
- var n: Int = ins.read(b)
- while (n != -1) {
- out.append(String(b, 0, n))
- n = ins.read(b)
- }
- } catch (e: IOException) {
- return ""
- }
-
- return out.toString()
- }
-
-
- // 根据文件后缀名获得对应的MIME类型。
- private fun getMimeType(filePath: String?): String {
- val mmr = MediaMetadataRetriever()
- var mime = "*/*"
- if (filePath != null) {
- try {
- mmr.setDataSource(filePath)
- mime = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE)
- } catch (e: IllegalStateException) {
- return mime
- } catch (e: IllegalArgumentException) {
- return mime
- } catch (e: RuntimeException) {
- return mime
- }
-
- }
- return mime
- }
-
-}
-
-fun File.toUri(): Uri? {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- FileProvider.getUriForFile(BaseApp.instance, "com.wrbug.developerhelper.fileprovider", this)
- } else {
- Uri.fromFile(this)
- }
-}
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/OutSharedPreferenceManager.kt b/app/src/main/java/com/wrbug/developerhelper/util/OutSharedPreferenceManager.kt
index cc64336..5a6c852 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/OutSharedPreferenceManager.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/OutSharedPreferenceManager.kt
@@ -1,37 +1,95 @@
package com.wrbug.developerhelper.util
+import android.annotation.SuppressLint
import android.content.Context
+import com.wrbug.developerhelper.commonutil.Constant
+import com.wrbug.developerhelper.commonutil.shell.ShellManager
import com.wrbug.developerhelper.commonutil.toBoolean
import com.wrbug.developerhelper.commonutil.toInt
import com.wrbug.developerhelper.commonutil.toLong
import com.wrbug.developerhelper.model.entity.SharedPreferenceItemInfo
+import io.reactivex.rxjava3.core.Single
import java.io.File
-object OutSharedPreferenceManager {
- fun saveToFile(context: Context, list: Array): File {
- val name = System.currentTimeMillis().toString()
- val sp = context.applicationContext.getSharedPreferences(name, Context.MODE_PRIVATE)
- val edit = sp.edit()
- for (sharedPreferenceItemInfo in list) {
- when (sharedPreferenceItemInfo.type.toLowerCase()) {
- "string" -> {
- edit.putString(sharedPreferenceItemInfo.key, sharedPreferenceItemInfo.getValidValue())
- }
- "int" -> {
- edit.putInt(sharedPreferenceItemInfo.key, sharedPreferenceItemInfo.getValidValue().toInt())
- }
- "long" -> {
- edit.putLong(sharedPreferenceItemInfo.key, sharedPreferenceItemInfo.getValidValue().toLong())
- }
- "boolean" -> {
- edit.putBoolean(sharedPreferenceItemInfo.key, sharedPreferenceItemInfo.getValidValue().toBoolean())
- }
- "float" -> {
- edit.putFloat(sharedPreferenceItemInfo.key, sharedPreferenceItemInfo.getValidValue().toFloat())
- }
+class OutSharedPreference(private val context: Context, private val filePath: String) {
+ private val fileName by lazy {
+ System.currentTimeMillis().toString()
+ }
+ private val tmpSpFile by lazy {
+ File("${Constant.getDataDir(context.packageName)}/shared_prefs/${fileName}.xml")
+ }
+ private val tmpFile by lazy {
+ File(context.cacheDir, "$fileName.xml")
+ }
+
+ fun parse(): Single> {
+ return Single.just(filePath).map {
+ if (!ShellManager.catFile(it, tmpFile.absolutePath, "777")) {
+ return@map emptyArray()
}
+ val xml = tmpFile.readText()
+ XmlUtil.parseSharedPreference(xml)
}
- edit.commit()
- return File("/data/data/${context.packageName}/shared_prefs/$name.xml")
+ }
+
+ @SuppressLint("ApplySharedPref")
+ fun saveToFile(context: Context, list: Array): Single {
+ return Single.just(list).map {
+ val sp = context.applicationContext.getSharedPreferences(fileName, Context.MODE_PRIVATE)
+ val edit = sp.edit()
+ for (sharedPreferenceItemInfo in list) {
+ when (sharedPreferenceItemInfo.type.lowercase()) {
+ "string" -> {
+ edit.putString(
+ sharedPreferenceItemInfo.key,
+ sharedPreferenceItemInfo.getValidValue()
+ )
+ }
+
+ "int" -> {
+ edit.putInt(
+ sharedPreferenceItemInfo.key,
+ sharedPreferenceItemInfo.getValidValue().toInt()
+ )
+ }
+
+ "long" -> {
+ edit.putLong(
+ sharedPreferenceItemInfo.key,
+ sharedPreferenceItemInfo.getValidValue().toLong()
+ )
+ }
+
+ "boolean" -> {
+ edit.putBoolean(
+ sharedPreferenceItemInfo.key,
+ sharedPreferenceItemInfo.getValidValue().toBoolean()
+ )
+ }
+
+ "float" -> {
+ edit.putFloat(
+ sharedPreferenceItemInfo.key,
+ sharedPreferenceItemInfo.getValidValue().toFloat()
+ )
+ }
+
+ "set" -> {
+ edit.putStringSet(
+ sharedPreferenceItemInfo.key,
+ sharedPreferenceItemInfo.getValidValue().split(",").toSet()
+ )
+ }
+ }
+ }
+ edit.commit()
+ ShellManager.catFile(tmpSpFile.absolutePath, filePath, "666")
+ }.onErrorReturn { false }
+ }
+
+
+ fun deleteTmpFile() {
+ tmpSpFile.delete()
+ tmpFile.delete()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/ResourceUtilsExt.kt b/app/src/main/java/com/wrbug/developerhelper/util/ResourceUtilsExt.kt
index 4effcd8..a5083dc 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/ResourceUtilsExt.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/ResourceUtilsExt.kt
@@ -1,12 +1,27 @@
package com.wrbug.developerhelper.util
import android.content.Context
-import com.wrbug.developerhelper.basecommon.BaseApp
+import android.content.res.Configuration
+import androidx.core.content.ContextCompat
+import com.wrbug.developerhelper.base.BaseApp
-fun Int.toResString(context: Context = BaseApp.instance): String {
+fun Int.getString(context: Context = BaseApp.instance): String {
return context.getString(this)
}
+fun Int.getColor(context: Context = BaseApp.instance): Int {
+ return ContextCompat.getColor(context, this)
+}
+
+fun Int.getString(vararg formatArgs: Any): String {
+ return BaseApp.instance.getString(this, *formatArgs)
+}
+
fun getString(resId: Int): String {
return BaseApp.instance.getString(resId)
+}
+
+
+fun isPortrait(): Boolean {
+ return BaseApp.instance.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/UpdateUtils.kt b/app/src/main/java/com/wrbug/developerhelper/util/UpdateUtils.kt
index 3010f62..c991959 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/UpdateUtils.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/UpdateUtils.kt
@@ -1,42 +1,11 @@
package com.wrbug.developerhelper.util
-import com.wrbug.developerhelper.commonutil.HttpUtil
-import com.wrbug.developerhelper.commonutil.shell.Callback
import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
-import com.wrbug.developerhelper.commonutil.OkhttpUtils
-import com.wrbug.developerhelper.model.entity.VersionInfo
-import org.jsoup.Jsoup
-import java.lang.Exception
object UpdateUtils {
- private const val URL = "https://www.coolapk.com/apk/com.wrbug.developerhelper"
- fun checkUpdate(callback: Callback) {
+ fun checkUpdate() {
doAsync {
- try {
- val document = Jsoup.connect(URL)
- .sslSocketFactory(OkhttpUtils.createSSLSocketFactory()).get()
- val versionName = document.getElementsByClass("list_app_info").text() ?: ""
- val feature = document.getElementsByClass("apk_left_title_info").first().html().replace("
", "\n")
- val size = document.getElementsByClass("apk_topba_message").html().split("/")[0].trim()
- val updateTime =
- document.getElementsByClass("apk_left_title_info")[2].html().split("
")[1].replace(
- "更新时间:",
- ""
- )
- val info = VersionInfo()
- info.versionName = versionName
- info.feature = feature
- info.size = size
- info.updateDate = updateTime
- info.downloadUrl = URL
- uiThread {
- callback.onSuccess(info)
- }
- } catch (e: Exception) {
- uiThread { callback.onFailed() }
- }
}
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/ViewExt.kt b/app/src/main/java/com/wrbug/developerhelper/util/ViewExt.kt
new file mode 100644
index 0000000..4a39531
--- /dev/null
+++ b/app/src/main/java/com/wrbug/developerhelper/util/ViewExt.kt
@@ -0,0 +1,94 @@
+package com.wrbug.developerhelper.util
+
+import android.app.ActionBar.LayoutParams
+import android.os.SystemClock
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.ImageView
+import android.widget.Toast
+import androidx.core.view.isVisible
+import com.airbnb.lottie.LottieAnimationView
+import com.airbnb.lottie.LottieDrawable
+import com.bumptech.glide.Glide
+import com.wrbug.developerhelper.R
+import com.wrbug.developerhelper.mmkv.ConfigKv
+import com.wrbug.developerhelper.mmkv.manager.MMKVManager
+
+private val configKv by lazy {
+ MMKVManager.get(ConfigKv::class.java)
+}
+
+fun View?.setOnDoubleCheckClickListener(duration: Long = 800, clickListener: (View) -> Unit) {
+ this?.setOnClickListener {
+ val time = SystemClock.elapsedRealtime()
+ val lastTime = (it.getTag(R.id.double_check_click) as? Long) ?: 0
+ if (time - lastTime > duration) {
+ it.setTag(R.id.double_check_click, time)
+ clickListener(it)
+ }
+ }
+}
+
+
+fun View?.setOnRootCheckClickListener(clickListener: (View) -> Unit) {
+ setOnDoubleCheckClickListener {
+ if (!configKv.isOpenRoot()) {
+ Toast.makeText(it.context, R.string.open_root_notice, Toast.LENGTH_SHORT).show()
+ return@setOnDoubleCheckClickListener
+ }
+ clickListener(it)
+ }
+}
+
+fun FrameLayout.startPageLoading() {
+ val lottieView = LottieAnimationView(context)
+ lottieView.id = R.id.lottie_loading
+ lottieView.setAnimation(R.raw.lottie_page_loading)
+ lottieView.playAnimation()
+ lottieView.repeatCount = LottieDrawable.INFINITE
+ removeAllViews()
+ isVisible = true
+ addView(
+ lottieView,
+ FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
+ )
+}
+
+fun FrameLayout.stopPageLoading() {
+ val lottieView: LottieAnimationView? = findViewById(R.id.lottie_loading)
+ lottieView?.cancelAnimation()
+ removeAllViews()
+ isVisible = false
+}
+
+
+fun ImageView.loadImage(url: Any?, default: Int? = null) {
+ Glide.with(this).load(url).apply {
+ if (default != null) {
+ error(default)
+ }
+ }.into(this)
+}
+
+
+inline var View.visible: Boolean
+ set(value) {
+ visibility = if (value) {
+ View.VISIBLE
+ } else {
+ View.GONE
+ }
+ }
+ get() = visibility == View.VISIBLE
+
+
+inline var View.inVisible: Boolean
+ set(value) {
+ visibility = if (value) {
+ View.INVISIBLE
+ } else {
+ View.VISIBLE
+ }
+ }
+ get() = visibility == View.INVISIBLE
\ No newline at end of file
diff --git a/app/src/main/java/com/wrbug/developerhelper/util/XmlUtil.kt b/app/src/main/java/com/wrbug/developerhelper/util/XmlUtil.kt
index 1347a91..4b89580 100644
--- a/app/src/main/java/com/wrbug/developerhelper/util/XmlUtil.kt
+++ b/app/src/main/java/com/wrbug/developerhelper/util/XmlUtil.kt
@@ -3,6 +3,7 @@ package com.wrbug.developerhelper.util
import com.wrbug.developerhelper.model.entity.SharedPreferenceItemInfo
import org.dom4j.DocumentHelper
import org.dom4j.Element
+import org.dom4j.tree.DefaultElement
/**
* xml相关的工具类
@@ -28,6 +29,11 @@ object XmlUtil {
if (type == "string") {
info.value = child.text
info.newValue = child.text
+ } else if (type == "set") {
+ info.value = child.content().filterIsInstance(DefaultElement::class.java)
+ .joinToString(",") { it.text }
+ info.newValue = child.content().filterIsInstance(DefaultElement::class.java)
+ .joinToString(",") { it.text }
} else {
info.value = child.attributeValue("value")
info.newValue = child.attributeValue("value")
diff --git a/app/src/main/res/drawable/bg_round_8dp_white.xml b/app/src/main/res/drawable/bg_round_8dp_white.xml
new file mode 100644
index 0000000..3edf0a7
--- /dev/null
+++ b/app/src/main/res/drawable/bg_round_8dp_white.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_accessibility.xml b/app/src/main/res/drawable/ic_accessibility.xml
new file mode 100644
index 0000000..c872987
--- /dev/null
+++ b/app/src/main/res/drawable/ic_accessibility.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_accessibility_666666.xml b/app/src/main/res/drawable/ic_accessibility_666666.xml
deleted file mode 100644
index 0204f1a..0000000
--- a/app/src/main/res/drawable/ic_accessibility_666666.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_accessibility_black.xml b/app/src/main/res/drawable/ic_accessibility_black.xml
deleted file mode 100644
index 3239379..0000000
--- a/app/src/main/res/drawable/ic_accessibility_black.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_application.xml b/app/src/main/res/drawable/ic_application.xml
new file mode 100644
index 0000000..630ea85
--- /dev/null
+++ b/app/src/main/res/drawable/ic_application.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_canceled.xml b/app/src/main/res/drawable/ic_canceled.xml
new file mode 100644
index 0000000..99b4c15
--- /dev/null
+++ b/app/src/main/res/drawable/ic_canceled.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_chevron_left.xml b/app/src/main/res/drawable/ic_chevron_left.xml
new file mode 100644
index 0000000..2fd7c1c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chevron_left.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_chevron_left_white_24dp.xml b/app/src/main/res/drawable/ic_chevron_left_24dp.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_chevron_left_white_24dp.xml
rename to app/src/main/res/drawable/ic_chevron_left_24dp.xml
diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml
new file mode 100644
index 0000000..ce2744c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chevron_right.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_chevron_right_white_24dp.xml b/app/src/main/res/drawable/ic_chevron_right_24dp.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_chevron_right_white_24dp.xml
rename to app/src/main/res/drawable/ic_chevron_right_24dp.xml
diff --git a/app/src/main/res/drawable/ic_copy.xml b/app/src/main/res/drawable/ic_copy.xml
new file mode 100644
index 0000000..5b54247
--- /dev/null
+++ b/app/src/main/res/drawable/ic_copy.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_default_app_ico_place_holder.xml b/app/src/main/res/drawable/ic_default_app_ico_place_holder.xml
new file mode 100644
index 0000000..0eaded5
--- /dev/null
+++ b/app/src/main/res/drawable/ic_default_app_ico_place_holder.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_fail.xml b/app/src/main/res/drawable/ic_fail.xml
new file mode 100644
index 0000000..65ffd33
--- /dev/null
+++ b/app/src/main/res/drawable/ic_fail.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_float_air_bubble_666666.xml b/app/src/main/res/drawable/ic_float_air_bubble_666666.xml
deleted file mode 100644
index 31149a0..0000000
--- a/app/src/main/res/drawable/ic_float_air_bubble_666666.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_ic_empty_666666.xml b/app/src/main/res/drawable/ic_ic_empty.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_ic_empty_666666.xml
rename to app/src/main/res/drawable/ic_ic_empty.xml
diff --git a/app/src/main/res/drawable/ic_ignore.xml b/app/src/main/res/drawable/ic_ignore.xml
new file mode 100644
index 0000000..04dbaad
--- /dev/null
+++ b/app/src/main/res/drawable/ic_ignore.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/onboarding_indicator_selected.xml b/app/src/main/res/drawable/ic_marker.xml
similarity index 59%
rename from app/src/main/res/drawable/onboarding_indicator_selected.xml
rename to app/src/main/res/drawable/ic_marker.xml
index 3d6e9fa..2837621 100644
--- a/app/src/main/res/drawable/onboarding_indicator_selected.xml
+++ b/app/src/main/res/drawable/ic_marker.xml
@@ -1,6 +1,5 @@
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_marker_active.xml b/app/src/main/res/drawable/ic_marker_active.xml
new file mode 100644
index 0000000..011e399
--- /dev/null
+++ b/app/src/main/res/drawable/ic_marker_active.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_marker_inactive.xml b/app/src/main/res/drawable/ic_marker_inactive.xml
new file mode 100644
index 0000000..e8e5572
--- /dev/null
+++ b/app/src/main/res/drawable/ic_marker_inactive.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml
new file mode 100644
index 0000000..b60ed3d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_notification.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_root_666666.xml b/app/src/main/res/drawable/ic_root.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_root_666666.xml
rename to app/src/main/res/drawable/ic_root.xml
diff --git a/app/src/main/res/drawable/ic_search_white_24dp.xml b/app/src/main/res/drawable/ic_search_24.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_search_white_24dp.xml
rename to app/src/main/res/drawable/ic_search_24.xml
diff --git a/app/src/main/res/drawable/ic_sheldon_root.xml b/app/src/main/res/drawable/ic_sheldon_root.xml
new file mode 100644
index 0000000..ef66512
--- /dev/null
+++ b/app/src/main/res/drawable/ic_sheldon_root.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_shield_666666.xml b/app/src/main/res/drawable/ic_shield.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_shield_666666.xml
rename to app/src/main/res/drawable/ic_shield.xml
diff --git a/app/src/main/res/drawable/ic_success.xml b/app/src/main/res/drawable/ic_success.xml
new file mode 100644
index 0000000..309b83d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_success.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_switch.xml b/app/src/main/res/drawable/ic_switch.xml
new file mode 100644
index 0000000..fce0772
--- /dev/null
+++ b/app/src/main/res/drawable/ic_switch.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_waiting.xml b/app/src/main/res/drawable/ic_waiting.xml
new file mode 100644
index 0000000..b090eb1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_waiting.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_xposed_666666.xml b/app/src/main/res/drawable/ic_xposed_666666.xml
deleted file mode 100644
index 247f7a8..0000000
--- a/app/src/main/res/drawable/ic_xposed_666666.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_xposed_custom_666666.xml b/app/src/main/res/drawable/ic_xposed_custom_666666.xml
deleted file mode 100644
index 80f08b0..0000000
--- a/app/src/main/res/drawable/ic_xposed_custom_666666.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/onboarding_indicator_unselected.xml b/app/src/main/res/drawable/onboarding_indicator_unselected.xml
deleted file mode 100644
index 7461fa9..0000000
--- a/app/src/main/res/drawable/onboarding_indicator_unselected.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/commonwidget/src/main/res/drawable/toast_bg_circle_cornor_rect.xml b/app/src/main/res/drawable/toast_bg_circle_cornor_rect.xml
similarity index 100%
rename from commonwidget/src/main/res/drawable/toast_bg_circle_cornor_rect.xml
rename to app/src/main/res/drawable/toast_bg_circle_cornor_rect.xml
diff --git a/app/src/main/res/drawable/widget_ic_no_data.xml b/app/src/main/res/drawable/widget_ic_no_data.xml
new file mode 100644
index 0000000..35be377
--- /dev/null
+++ b/app/src/main/res/drawable/widget_ic_no_data.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_app_backup_detail.xml b/app/src/main/res/layout/activity_app_backup_detail.xml
new file mode 100644
index 0000000..6960008
--- /dev/null
+++ b/app/src/main/res/layout/activity_app_backup_detail.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_app_recover.xml b/app/src/main/res/layout/activity_app_recover.xml
new file mode 100644
index 0000000..6b9438b
--- /dev/null
+++ b/app/src/main/res/layout/activity_app_recover.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_backup_app.xml b/app/src/main/res/layout/activity_backup_app.xml
new file mode 100644
index 0000000..bc844e7
--- /dev/null
+++ b/app/src/main/res/layout/activity_backup_app.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_database_edit.xml b/app/src/main/res/layout/activity_database_edit.xml
index bfacaa4..4492843 100644
--- a/app/src/main/res/layout/activity_database_edit.xml
+++ b/app/src/main/res/layout/activity_database_edit.xml
@@ -25,7 +25,8 @@
android:padding="20dp"
android:text="@string/table_data_is_empty"
android:textSize="18sp"
- android:visibility="gone" />
+ android:visibility="gone"
+ app:layout_constraintTop_toTopOf="parent" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 17742be..7325ea0 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,41 +1,35 @@
-
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".ui.activity.main.MainActivity">
-
-
+
-
-
+
+
-
-
-
-
-
-
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
+ android:paddingHorizontal="24dp">
@@ -43,20 +37,18 @@
android:id="@+id/accessibilitySettingView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:onClick="@{()->presenter.onAccessibilityClick()}"
app:checkable="false"
- app:checked="@{mainVm.openAccessibility}"
- app:src="@drawable/ic_accessibility_666666"
+ app:icoTint="@color/iconPrimary"
+ app:src="@drawable/ic_accessibility"
app:title="@string/open_accessibility_service" />
@@ -75,21 +68,47 @@
android:id="@+id/rootSettingView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:onClick="@{()->presenter.onRootClick()}"
app:checkable="false"
- app:checked="@{mainVm.openRoot}"
- app:src="@drawable/ic_root_666666"
+ app:icoTint="@color/iconPrimary"
+ app:src="@drawable/ic_sheldon_root"
app:summary="@string/open_root_permission_summary"
app:title="@string/open_root_permission_title" />
+ app:checkable="false"
+ app:icoTint="@color/iconPrimary"
+ app:src="@drawable/ic_notification"
+ app:summary="@string/open_notification_summary"
+ app:title="@string/open_notification_title"
+ tools:visibility="visible" />
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/layout/activity_shared_preference_edit.xml b/app/src/main/res/layout/activity_shared_preference_edit.xml
index 3bec598..8f95392 100644
--- a/app/src/main/res/layout/activity_shared_preference_edit.xml
+++ b/app/src/main/res/layout/activity_shared_preference_edit.xml
@@ -17,5 +17,19 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ tools:listitem="@layout/item_shared_preference_info" />
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_shell_app_manager.xml b/app/src/main/res/layout/activity_shell_app_manager.xml
deleted file mode 100644
index 5b1cc8a..0000000
--- a/app/src/main/res/layout/activity_shell_app_manager.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_xposed_setting.xml b/app/src/main/res/layout/activity_xposed_setting.xml
deleted file mode 100644
index 8b6e95f..0000000
--- a/app/src/main/res/layout/activity_xposed_setting.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_apk_info.xml b/app/src/main/res/layout/dialog_apk_info.xml
index 7d8a32a..e3d19ea 100644
--- a/app/src/main/res/layout/dialog_apk_info.xml
+++ b/app/src/main/res/layout/dialog_apk_info.xml
@@ -1,4 +1,5 @@
+
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/layout/dialog_backup_app.xml b/app/src/main/res/layout/dialog_backup_app.xml
new file mode 100644
index 0000000..9211711
--- /dev/null
+++ b/app/src/main/res/layout/dialog_backup_app.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_backup_app_select.xml b/app/src/main/res/layout/dialog_backup_app_select.xml
new file mode 100644
index 0000000..0083b0a
--- /dev/null
+++ b/app/src/main/res/layout/dialog_backup_app_select.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_guide.xml b/app/src/main/res/layout/fragment_guide.xml
index e67d07d..4e15b75 100644
--- a/app/src/main/res/layout/fragment_guide.xml
+++ b/app/src/main/res/layout/fragment_guide.xml
@@ -1,4 +1,5 @@
@@ -48,5 +49,4 @@
tools:text="Your awesome description about the app" />
-
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/item_backup_app_info.xml b/app/src/main/res/layout/item_backup_app_info.xml
new file mode 100644
index 0000000..6f9cb2e
--- /dev/null
+++ b/app/src/main/res/layout/item_backup_app_info.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_backup_detail_info.xml b/app/src/main/res/layout/item_backup_detail_info.xml
new file mode 100644
index 0000000..55a8d33
--- /dev/null
+++ b/app/src/main/res/layout/item_backup_detail_info.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_empty_data.xml b/app/src/main/res/layout/item_empty_data.xml
new file mode 100644
index 0000000..c90c36a
--- /dev/null
+++ b/app/src/main/res/layout/item_empty_data.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_info_loading.xml b/app/src/main/res/layout/item_info_loading.xml
new file mode 100644
index 0000000..89661e5
--- /dev/null
+++ b/app/src/main/res/layout/item_info_loading.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_loading_data.xml b/app/src/main/res/layout/item_loading_data.xml
new file mode 100644
index 0000000..54f2089
--- /dev/null
+++ b/app/src/main/res/layout/item_loading_data.xml
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_recover_app_time_line.xml b/app/src/main/res/layout/item_recover_app_time_line.xml
new file mode 100644
index 0000000..cb22188
--- /dev/null
+++ b/app/src/main/res/layout/item_recover_app_time_line.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_shared_preference_info.xml b/app/src/main/res/layout/item_shared_preference_info.xml
index 44c755d..6b6eb94 100644
--- a/app/src/main/res/layout/item_shared_preference_info.xml
+++ b/app/src/main/res/layout/item_shared_preference_info.xml
@@ -16,8 +16,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:textColor="@color/item_title_text"
- android:textSize="16sp"
+ android:textAppearance="@style/TextAppearance.ItemTitle"
tools:text="标题" />
+ android:textColor="@color/material_color_light_blue_500"
+ android:visibility="gone" />
diff --git a/app/src/main/res/layout/item_shell_app_info.xml b/app/src/main/res/layout/item_shell_app_info.xml
index 3e0a3d0..c24e1f3 100644
--- a/app/src/main/res/layout/item_shell_app_info.xml
+++ b/app/src/main/res/layout/item_shell_app_info.xml
@@ -1,5 +1,6 @@
-
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:background="@color/material_color_red_500" />
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_view_info.xml b/app/src/main/res/layout/item_view_info.xml
index a92cd12..57ce62b 100644
--- a/app/src/main/res/layout/item_view_info.xml
+++ b/app/src/main/res/layout/item_view_info.xml
@@ -1,28 +1,45 @@
-
+ android:paddingHorizontal="24dp">
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_float_window_button.xml b/app/src/main/res/layout/layout_float_window_button.xml
index 4d1c2c5..c52392b 100644
--- a/app/src/main/res/layout/layout_float_window_button.xml
+++ b/app/src/main/res/layout/layout_float_window_button.xml
@@ -1,8 +1,7 @@
diff --git a/commonwidget/src/main/res/layout/layout_toast_flexible.xml b/app/src/main/res/layout/layout_toast_flexible.xml
similarity index 100%
rename from commonwidget/src/main/res/layout/layout_toast_flexible.xml
rename to app/src/main/res/layout/layout_toast_flexible.xml
diff --git a/app/src/main/res/layout/layout_toolbar.xml b/app/src/main/res/layout/layout_toolbar.xml
index 5532922..9b16398 100644
--- a/app/src/main/res/layout/layout_toolbar.xml
+++ b/app/src/main/res/layout/layout_toolbar.xml
@@ -1,13 +1,13 @@
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_app_bar.xml b/app/src/main/res/layout/view_app_bar.xml
new file mode 100644
index 0000000..ba968b3
--- /dev/null
+++ b/app/src/main/res/layout/view_app_bar.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_app_data_info.xml b/app/src/main/res/layout/view_app_data_info.xml
index bca1bbc..104f635 100644
--- a/app/src/main/res/layout/view_app_data_info.xml
+++ b/app/src/main/res/layout/view_app_data_info.xml
@@ -17,8 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Apk目录"
- android:textColor="@color/item_title_text"
- android:textSize="16sp" />
+ android:textAppearance="@style/TextAppearance.ItemTitle" />
+ android:textAppearance="@style/TextAppearance.ItemTitle" />
+ android:textAppearance="@style/TextAppearance.ItemTitle" />
+ android:textAppearance="@style/TextAppearance.ItemTitle" />
+ android:textAppearance="@style/TextAppearance.ItemTitle" />
-
+ android:paddingTop="24dp"
+ app:constraint_referenced_ids="backupAppBtn,restoreAppBtn,restartAppBtn,stopAppBtn,deleteAppDataBtn,uninstallAppBtn"
+ app:flow_verticalGap="16dp"
+ app:flow_wrapMode="aligned"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ android:text="@string/backup_app_file"
+ app:layout_constraintWidth_percent="0.45" />
+ android:text="@string/restore_app_file"
+ app:layout_constraintWidth_percent="0.45" />
+ app:layout_constraintWidth_percent="0.45" />
+ app:layout_constraintWidth_percent="0.45" />
+ app:layout_constraintWidth_percent="0.45" />
-
-
+ app:layout_constraintWidth_percent="0.45" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_backup_progress.xml b/app/src/main/res/layout/view_backup_progress.xml
new file mode 100644
index 0000000..102ea64
--- /dev/null
+++ b/app/src/main/res/layout/view_backup_progress.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_empty_view.xml b/app/src/main/res/layout/view_empty_view.xml
new file mode 100644
index 0000000..6b19298
--- /dev/null
+++ b/app/src/main/res/layout/view_empty_view.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_layout_info.xml b/app/src/main/res/layout/view_layout_info.xml
index 381235f..531797c 100644
--- a/app/src/main/res/layout/view_layout_info.xml
+++ b/app/src/main/res/layout/view_layout_info.xml
@@ -3,12 +3,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layoutInfoContainer"
android:layout_width="match_parent"
- android:layout_height="300dp">
+ android:layout_height="match_parent"
+ android:background="@android:color/white">
-
+ android:paddingVertical="8dp"
+ tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
-
+ tools:src="@drawable/ic_accessibility" />
-
+ app:layout_constraintTop_toTopOf="@+id/titleTv" />
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/raw/lottie_list_loading.json b/app/src/main/res/raw/lottie_list_loading.json
new file mode 100644
index 0000000..8fa429d
--- /dev/null
+++ b/app/src/main/res/raw/lottie_list_loading.json
@@ -0,0 +1 @@
+{"v":"5.7.4","fr":29.9700012207031,"ip":0,"op":48.0000019550801,"w":400,"h":400,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1L 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,289,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.928477328431,0.15922648112,0.723155182483,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[50]},{"t":36.0000014663101,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[25]},{"t":36.0000014663101,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":21.0000008553475,"op":55.0000022401959,"st":21.0000008553475,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1L 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,289,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.928477328431,0.15922648112,0.723155182483,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[50]},{"t":32.0000013033867,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[25]},{"t":32.0000013033867,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":17.0000006924242,"op":51.0000020772726,"st":17.0000006924242,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1L","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,289,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.928477328431,0.15922648112,0.723155182483,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[50]},{"t":20.0000008146167,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[25]},{"t":20.0000008146167,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5.00000020365417,"op":39.0000015885026,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2R 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,339,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.482111194087,0.119379574645,0.946568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[50]},{"t":32.0000013033867,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[25]},{"t":32.0000013033867,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":17.0000006924242,"op":52.0000021180034,"st":17.0000006924242,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2R 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,339,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.482111194087,0.119379574645,0.946568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[50]},{"t":37.0000015070409,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[25]},{"t":37.0000015070409,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":22.0000008960784,"op":57.0000023216576,"st":22.0000008960784,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 2R","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,339,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.482111194087,0.119379574645,0.946568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[50]},{"t":24.00000097754,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[25]},{"t":24.00000097754,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":9.00000036657752,"op":44.0000017921567,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 3L 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,389,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.096529941933,0.306382272758,0.935631127451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[50]},{"t":37.0000015070409,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[25]},{"t":37.0000015070409,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":22.0000008960784,"op":56.0000022809268,"st":22.0000008960784,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 3L 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,389,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.096529941933,0.306382272758,0.935631127451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[50]},{"t":33.0000013441176,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[25]},{"t":33.0000013441176,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":18.000000733155,"op":52.0000021180034,"st":18.000000733155,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 3L","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,389,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.096529941933,0.306382272758,0.935631127451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[50]},{"t":20.0000008146167,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[25]},{"t":20.0000008146167,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5.00000020365417,"op":39.0000015885026,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 4R 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,439,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.069122576246,0.9015625,0.230790366378,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[50]},{"t":28.0000011404634,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[25]},{"t":28.0000011404634,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":13.0000005295009,"op":48.0000019550801,"st":13.0000005295009,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 4R 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,439,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.069122576246,0.9015625,0.230790366378,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[50]},{"t":37.0000015070409,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[25]},{"t":37.0000015070409,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":22.0000008960784,"op":57.0000023216576,"st":22.0000008960784,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 4R","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,439,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.069122576246,0.9015625,0.230790366378,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[50]},{"t":18.000000733155,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[25]},{"t":18.000000733155,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":3.00000012219251,"op":38.0000015477717,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 5L 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,179,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078822124706,0.739201085708,0.917202818627,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[50]},{"t":27.0000010997325,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[25]},{"t":27.0000010997325,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":12.00000048877,"op":46.0000018736184,"st":12.00000048877,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 5L 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,179,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078822124706,0.739201085708,0.917202818627,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[50]},{"t":34.0000013848484,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[25]},{"t":34.0000013848484,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":19.0000007738859,"op":53.0000021587343,"st":19.0000007738859,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Shape Layer 5L 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,179,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078822124706,0.739201085708,0.917202818627,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[50]},{"t":16.0000006516934,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[25]},{"t":16.0000006516934,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":1.00000004073083,"op":35.0000014255792,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 5L","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,179,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078822124706,0.739201085708,0.917202818627,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[50]},{"t":23.0000009368092,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[25]},{"t":23.0000009368092,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":8.00000032584668,"op":42.0000017106951,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 6R 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,239,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.524494904163,0.884911151961,0.087406652114,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":23,"s":[50]},{"t":30.0000012219251,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":23,"s":[25]},{"t":30.0000012219251,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":15.0000006109625,"op":50.0000020365418,"st":15.0000006109625,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 6R 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,239,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.524494904163,0.884911151961,0.087406652114,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[50]},{"t":37.0000015070409,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[25]},{"t":37.0000015070409,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":22.0000008960784,"op":57.0000023216576,"st":22.0000008960784,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Shape Layer 6R","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,239,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.524494904163,0.884911151961,0.087406652114,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[50]},{"t":20.0000008146167,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[25]},{"t":20.0000008146167,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5.00000020365417,"op":40.0000016292334,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 7L 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,489,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.611406034582,0.891253063725,0.090217530494,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0],"y":[0]},"t":21,"s":[50]},{"t":28.0000011404634,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[25]},{"t":28.0000011404634,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":13.0000005295009,"op":47.0000019143492,"st":13.0000005295009,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Shape Layer 7L 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,489,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.611406034582,0.891253063725,0.090217530494,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0],"y":[0]},"t":25,"s":[50]},{"t":32.0000013033867,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[25]},{"t":32.0000013033867,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":17.0000006924242,"op":51.0000020772726,"st":17.0000006924242,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 7L","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,489,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.611406034582,0.891253063725,0.090217530494,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0],"y":[0]},"t":12,"s":[50]},{"t":19.0000007738859,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":12,"s":[25]},{"t":19.0000007738859,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":4.00000016292334,"op":38.0000015477717,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Shape Layer 8R 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,532,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.954534313725,0.324577391381,0.102267328898,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[50]},{"t":27.0000010997325,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[25]},{"t":27.0000010997325,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":12.00000048877,"op":47.0000019143492,"st":12.00000048877,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Shape Layer 8R 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,532,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.954534313725,0.324577391381,0.102267328898,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[50]},{"t":37.0000015070409,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[25]},{"t":37.0000015070409,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":22.0000008960784,"op":57.0000023216576,"st":22.0000008960784,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Shape Layer 8R","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[197.852,532,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-198,-154],[200,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.954534313725,0.324577391381,0.102267328898,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[114.784,101.093],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[50]},{"t":21.0000008553475,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[25]},{"t":21.0000008553475,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":6.00000024438501,"op":41.0000016699642,"st":6.00000024438501,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/app/src/main/res/raw/lottie_loading.json b/app/src/main/res/raw/lottie_loading.json
new file mode 100644
index 0000000..6347c41
--- /dev/null
+++ b/app/src/main/res/raw/lottie_loading.json
@@ -0,0 +1 @@
+{"nm":"Main Scene","ddd":0,"h":100,"w":180,"meta":{"g":"@lottiefiles/creator 1.25.0"},"layers":[{"ty":0,"nm":" Comp 1","sr":1,"st":0,"op":31.00000126265584,"ip":4.00000016292334,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[63,24]},"s":{"a":0,"k":[250,250]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"w":200,"h":100,"refId":"precomp_Comp 1_ff1747d4-671c-4717-aeaa-23476b2a6335","ind":1}],"v":"5.7.0","fr":29.9700012207031,"op":31,"ip":0,"assets":[{"nm":"","id":"comp_0_85618a3e-3dd7-43d3-a8a7-28422c05ed7d","layers":[{"ty":4,"nm":"Shape Layer 2","sr":1,"st":-4.00000016292334,"op":90.00000366577514,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-32.5,5,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[20,20,100],"t":9.000000162923339},{"s":[100,100,100],"t":18.00000073315504}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[72,74.8,0],"t":10.000000162923339},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[72,62.8,0],"t":16.00000016292334},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[72,66.1,0],"t":22.00000016292334},{"o":{"x":0.167,"y":0},"i":{"x":0.667,"y":1},"s":[72,64.5,0],"t":28.00000016292334},{"s":[72,64.8,0],"t":34.00000138484844}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":9.000000162923339},{"s":[100],"t":18.00000073315504}],"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[15,15],"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.498,0.4902,0.5176],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-32.618,4.916],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":94.00000382869844,"ip":4.00000016292334,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-32.5,5,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100,100,100],"t":6.00000016292334},{"s":[120,120,100],"t":15.000000610962541}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[72,64.75,0],"t":4.00000016292334},{"s":[72,44.8,0],"t":13.00000052950086}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":4.00000016292334},{"s":[0],"t":13.00000052950086}],"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[15,15],"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.498,0.4902,0.5176],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-32.618,4.916],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2}]},{"nm":"Comp 1","id":"precomp_Comp 1_ff1747d4-671c-4717-aeaa-23476b2a6335","fr":29.9700012207031,"layers":[{"ty":0,"nm":"å个ç¹","sr":1,"st":0,"op":94.00000382869844,"ip":4.00000016292334,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[49.75,38.5,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"w":100,"h":100,"refId":"comp_0_85618a3e-3dd7-43d3-a8a7-28422c05ed7d","ind":1},{"ty":0,"nm":"å个ç¹","sr":1,"st":2.00000008146167,"op":96.00000391016015,"ip":6.00000024438501,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[74.75,38.5,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"w":100,"h":100,"refId":"comp_0_85618a3e-3dd7-43d3-a8a7-28422c05ed7d","ind":2},{"ty":4,"nm":"Shape Layer 3","sr":1,"st":0,"op":7.000000285115849,"ip":4.00000016292334,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-32.5,5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[96.75,53.25,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[15,15],"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.498,0.4902,0.5176],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-32.618,4.916],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3},{"ty":4,"nm":"Shape Layer 2","sr":1,"st":0,"op":10.000000407308349,"ip":4.00000016292334,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-32.5,5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[121.75,53.25,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[15,15],"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.498,0.4902,0.5176],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-32.618,4.916],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":4},{"ty":0,"nm":"å个ç¹","sr":1,"st":4.00000016292334,"op":98.00000399162184,"ip":8.00000032584668,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[99.75,38.5,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"w":100,"h":100,"refId":"comp_0_85618a3e-3dd7-43d3-a8a7-28422c05ed7d","ind":5}]}]}
\ No newline at end of file
diff --git a/app/src/main/res/raw/lottie_page_loading.json b/app/src/main/res/raw/lottie_page_loading.json
new file mode 100644
index 0000000..016f5fd
--- /dev/null
+++ b/app/src/main/res/raw/lottie_page_loading.json
@@ -0,0 +1 @@
+{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.21","a":"Syed Mubarak","k":"Loading","d":"Loading Animation","tc":"#FFFFFF"},"fr":29.9700012207031,"ip":0,"op":71.0000028918893,"w":1080,"h":1080,"nm":"Loading2","ddd":0,"assets":[{"id":"image_0","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4XuzdT6sdV7of4FXaGtxBwO5PYDU3cIdWk0kQp463ByGZBKs/gWVIRglY/gDBx5C51ZCMEmj5E7QMGSSZ9NZZmwOBQEuzEC60PMi4pdGdeKtCqbeu/0unalftXe9azwFzB7f+rPd5X7mt36la1SQ/BAgQIECAAAECBAgQIECAAIHgAk3w9Vs+AQIECBAgQIAAAQIECBAgQCAJOAwBAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQI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AgQIECBAgEABAgKOApqoBAIECBAgQIAAAQIECBAgULuAgKP2CVA/AQIECBAgQIAAAQIECBAoQEDAUUATlUCAAAECBAgQIECAAAECBGoXEHDUPgHqJ0CAAAECBAgQIECAAAECBQgIOApoohIIECBAgAABAgQIECBAgEDtAgKO2idA/QQIECBAgAABAgQIECBAoAABAUcBTVQCAQIECBAgQIAAAQIECBCoXUDAUfsEqJ8AAQIECBAgQIAAAQIECBQgIOAooIlKIECAAAECBAgQIECAAAECtQsIOGqfAPUTIECAAAECBAgQIECAAIECBAQcBTRRCQQIECBAgAABAgQIECBAoHYBAUftE6B+AgQIECBAgAABAgQIECBQgICAo4AmKoEAAQIECBAgQIAAAQIECNQuIOCofQLUT4AAAQIECBAgQIAAAQIEChAQcBTQRCUQIECAAAECBAgQIECAAIHaBQQctU+A+gkQIECAAAECBAgQIECAQAECAo4CmqgEAgQIECBAgAABAgQIECBQu4CAo/YJUD8BAgQIECBAgAABAgQIEChAQMBRQBOVQIAAAQIECBAgQIAAAQIEahcQcNQ+AeonQIAAAQIECBAgQIAAAQIFCAg4CmiiEggQIECAAAECBAgQIECAQO0CAo7aJ0D9BAgQIECAAAECBAgQIECgAAEBRwFNVAIBAgQIECBAgAABAgQIEKhdQMBR+wSonwABAgQIECBAgAABAgQIFCAg4CigiUogQIAAAQIECBAgQIAAAQK1Cwg4ap8A9RMgQIAAAQIECBAgQIAAgQIEBBwFNFEJBAgQIECAAAECBAgQIECgdgEBR+0ToH4CBAgQIECAAAECBAgQIFCAgICjgCYqgQABAgQIECBAgAABAgQI1C4g4Kh9AtRPgAABAgQIECBAgAABAgQKEBBwFNBEJRAgQIAAAQIECBAgQIAAgdoFBBy1T4D6CRAgQIAAAQIECBAgQIBAAQICjgKaqAQCBAgQIECAAAECBAgQIFC7gICj9glQPwECBAgQIECAAAECBAgQKEBAwFFAE5VAgAABAgQIECBAgAABAgRqFxBw1D4B6idAgAABAgQIECBAgAABAgUICDgKaKISCBAgQIAAAQIECBAgQIBA7QICjtonQP0ECBAgQIAAAQIECBAgQKAAAQFHAU1UAgECBAgQIECAAAECBAgQqF1AwFH7BKifAAECBAgQIECAAAECBAgUICDgKKCJSiBAgAABAgQIECBAgAABArULCDhqnwD1EyBAgAABAgQIECBAgACBAgQEHAU0UQkECBAgQIAAAQIECBAgQKB2AQFH7ROgfgIECBAgQIAAAQIECBAgUICAgKOAJiqBAAECBAgQIECAAAECBAjULiDgqH0C1E+AAAECBAgQIECAAAECBAoQEHAU0EQlECBAgAABAgQIECBAgACB2gUEHLVPgPoJECBAgAABAgQIECBAgEABAgKOApqoBAIECBAgQIAAAQIECBAgULuAgKP2CVA/AQIECBAgQIAAAQIECBAoQEDAUUATlUCAAAECBAgQIECAAAECBGoXEHDUPgHqJ0CAAAECBAgQIECAAAECBQgIOApoohIIECBAgAABAgQIECBAgEDtAgKO2idA/QQIECBAgAABAgQIECBAoAABAUcBTVQCAQIECBAgQIAAAQIECBCoXUDAUfsEqJ8AAQIECBAgQIAAAQIECBQgIOAooIlKIECAAAECBAgQIECAAAECtQsIOGqfAPUTIECAAAECBAgQIECAAIECBAQcBTRRCQQIECBAgAABAgQIECBAoHYBAUftE6B+AgQIECBAgAABAgQIECBQgICAo4AmKoEAAQIECBAgQIAAAQIECNQuIOCofQLUT4AAAQIECBAgQIAAAQIEChAQcBTQRCUQIECAAAECBAgQIECAAIHaBQQctU+A+gkQIECAAAECBAgQIECAQAECAo4CmqgEAgQIECBAgAABAgQIECBQu4CAo/YJUD8BAgQIECBAgAABAgQIEChAQMBRQBOVQIAAAQIECBAgQIAAAQIEahcQcNQ+AeonQIAAAQIECBAgQIAAAQIFCAg4CmiiEggQIECAAAECBAgQIECAQO0CAo7aJ0D9BAgQIECAAAECBAgQIECgAAEBRwFNVAIBAgQIECBAgAABAgQIEKhdQMBR+wSonwABAgQIECBAgAABAgQIFCAg4CigiUogQIAAAQIECBAgQIAAAQK1Cwg4ap8A9RMgQIAAAQIECBAgQIAAgQIEBBwFNFEJBAgQIECAAAECBAgQIECgdgEBR+0ToH4CBAgQIECAAAECBAgQIFCAgICjgCYqgQABAgQIECBAgAABAgQI1C4g4Kh9AtRPgAABAgQIECBAgAABAgQKEBBwFNBEJRAgQIAAAQIECBAgQIAAgdoFBBy1T4D6CRAgQIAAAQIECBAgQIBAAQICjgKaqAQCBAgQIECAAAECBAgQIFC7gICj9glQPwECBAgQIECAAAECBAgQKEBAwFFAE5VAgAABAgQIECBAgAABAgRqFxBw1D4B6idAgAABAgQIECBAgAABAgUICDgKaKISCBAgQIAAAQIECBAgQIBA7QICjtonQP0ECBAgQIAAAQIECBAgQKAAAQFHAU1UAgECBAgQIECAAAECBAgQqF1AwFH7BKifAAECBAgQIECAAAECBAgUICDgKKCJSiBAgAABAgQIECBAgAABArULCDhqnwD1EyBAgAABAgQIECBAgACBAgQEHAU0UQkECBAgQIAAAQIECBAgQKB2AQFH7ROgfgIECBAgQIAAAQIECBAgUICAgKOAJiqBAAECBAgQIECAAAECBAjULiDgqH0C1E+AAAECBAgQIECAAAECBAoQEHAU0EQlECBAgAABAgQIECBAgACB2gUEHLVPgPoJECBAgAABAgQIECBAgEABAgKOApqoBAIECBAgQIAAAQIECBAgULuAgKP2CVA/AQIECBAgQIAAAQIECBAoQEDAUUATlUCAAAECBAgQIECAAAECBGoXEHDUPgHqJ0CAAAECBAgQIECAAAECBQgIOApoohIIECBAgAABAgQIECBAgEDtAgKO2idA/QQIECBAgAABAgQIECBAoAABAUcBTVQCAQIECBAgQIAAAQIECBCoXUDAUfsEqJ8AAQIECBAgQIAAAQIECBQgIOAooIlKIECAAAECBAgQIECAAAECtQsIOGqfAPUTIECAAAECBAgQIECAAIECBAQcBTRRCQQIECBAgAABAgQIECBAoHYBAUftE6B+AgQIECBAgAABAgQIECBQgICAo4AmKoEAAQIECBAgQIAAAQIECNQuIOCofQLUT4AAAQIECBAgQIAAAQIEChAQcBTQRCUQIECAAAECBAgQIECAAIHaBQQctU+A+gkQIECAAAECBAgQIECAQAECAo4CmqgEAgQIECBAgAABAgQIECBQu4CAo/YJUD8BAgQIECBAgAABAgQIEChAQMBRQBOVQIAAAQIECBAg8P/bsYMCAAAAAmL9W+vhFsF4IUCAAAECdQEHR30B8hMgQIAAAQIECBAgQIAAgQMBB8dBiSIQIECAAAECBAgQIECAAIG6gIOjvgD5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","e":1},{"id":"image_1","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4XuzdXZIU15kG4JOk7qVZgdAKxNwSla3yCoRXAFqB8AqEViC0goEVCK3Apc4Obo1WYLQCw72LnMh2y20hZPIU/ffmeTrCMRdzsvp8z/v573V1VVf8ECBAgAABAgQIECBAgAABAgTCBbrw+7s+AQIECBAgQIAAAQIECBAgQKAoOCwBAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAAAECBAgQIECAAAEC8QIKjvgIDUCAAAECBAgQIECAAAECBAgoOOwAAQIECBAgQIAAAQIECBAgEC+g4IiP0AAECBAgQIAAAQIECBAgQICAgsMOECBAgAABAgQIECBAgAABAvECCo74CA1AgAABAgQIECBAgAABAgQIKDjsAAECBAgQIECAAAECBAgQIBAvoOCIj9AABAgQIECAAAECBAgQIECAgILDDhAgQIAAAQIECBAgQIAAAQLxAgqO+AgNQIAAAQIECBAgQIAAAQIECCg47AABAgQIECBAgAABAgQIECAQL6DgiI/QAAQIECBAgAABAgQIECBAgICCww4QIECAwJUJbDab7ZX9Mr+IQJjARx999HK3270Mu7brEiBAgACBGyOg4LgxUbgIAQIE1iOw3W5v7/f77TRNd7quu1NK+WI905mEwKUL/FxKedl13Ys3b97sTk5Odpf+G/0CAgQIECCwAgEFxwpCNAIBAgRugsDdu3fv3Lp160HXdfdKKZ/ehDu5A4GVCLwupcwlx7O+75/tdrtXK5nLGAQIECBA4EIFFBwXyunFCBAg0JbAdrv95M2bNw+naXqg1Ggre9Neq8DTaUd8TlMAACAASURBVJqeeGfHtWbglxMgQIDADRRQcNzAUFyJAAECN13g7E9QHpVS7t/0u7ofgRUL/DRN0yNFx4oTNhoBAgQIVAkoOKq4HCZAgEDbAvM7Nvb7/WPFRtt7YPobJ6DouHGRuBABAgQIXIeAguM61P1OAgQIBAoMw/CwlDK/a+PjwOu7MoEWBJ72ff/QZ3S0ELUZCRAgQOBdAgoOe0GAAAEC/1Xg7M9RnvgmFItCIEJg/kDSB+M4Pou4rUsSIECAAIELFFBwXCCmlyJAgMDaBIZhmD88dP6TFO/aWFu45lm7gHdzrD1h8xEgQIDA7wQUHJaCAAECBN4psNlsHndd9zUeAgRiBX7u+/7ebrd7GTuBixMgQIAAgQoBBUcFlqMECBBoQeDsg0TnP0n5soV5zUhg5QKv9/v99vnz5y9WPqfxCBAgQIBAUXBYAgIECBD4t8BZubErpXyOhQCB1QgoOVYTpUEIECBA4L8JKDjsBwECBAicCig3LAKBVQsoOVYdr+EIECBAYBZQcNgDAgQIEDgVGIZhfgu7d27YBwLrFVByrDdbkxEgQICAgsMOECBAgMBZuTF/5sZ9GgQIrF7gdd/3d3zw6OpzNiABAgSaFPAOjiZjNzQBAgTOBY6Ojh5N0/QNEwIEmhGYv11lu9vtXjUzsUEJECBAoAkBBUcTMRuSAAEC7xbYbDbbruv+yocAgeYEno7j+KC5qQ1MgAABAqsWUHCsOl7DESBA4I8Fzj5U9GUp5WNOBAg0KfDncRyfNTm5oQkQIEBglQIKjlXGaigCBAi8X2AYhvm/2Hz5/pNOECCwUoH58zhu+1OVlaZrLAIECDQooOBoMHQjEyBAwJ+m2AECBM4EfhzH8R4NAgQIECCwBgEFxxpSNAMBAgQqBYZhmP805dPKxxwnQGCFAtM0/enk5GS3wtGMRIAAAQKNCSg4GgvcuAQIEBiGYf5gwf8jQYAAgTOBn8Zx3NIgQIAAAQLpAgqO9ATdnwABApUCwzDMXw3pg0Ur3RwnsGYB7+JYc7pmI0CAQDsCCo52sjYpAQIEindvWAICBP5AwLs4rAYBAgQIxAsoOOIjNAABAgSWC/jsjeVWThJoTcC7OFpL3LwECBBYn4CCY32ZmogAAQLvFPDNKRaDAIH3CDwdx3H+jB4/BAgQIEAgUkDBERmbSxMgQKBeYBiGJ6WU+/VPeoIAgVYE+r7/n91uN39Ojx8CBAgQIBAnoOCIi8yFCRAgUC+w3W4/2e/3/6h/0hMECDQm8NU4jnMZ6ocAAQIECMQJKDjiInNhAgQI1AsMw3CvlPJD/ZOeIECgMYEfx3Gc//XCDwECBAgQiBNQcMRF5sIECBCoF/DnKfVmniDQqsA4jv7zYavhm5sAAQLhAv4NLDxA1ydAgMASAd+eskTJGQIEZgHfpmIPCBAgQCBVQMGRmpx7EyBAYKHAdru9vd/v/77wuGMECDQu0HXdt8fHx48aZzA+AQIECAQKKDgCQ3NlAgQI1Aj4/I0aLWcJECil+BwOa0CAAAECkQIKjsjYXJoAAQLLBY6Ojh5N0/TN8iecJECgcYFfxnG83biB8QkQIEAgUEDBERiaKxMgQKBGwAeM1mg5S4DALOCDRu0BAQIECCQKKDgSU3NnAgQIVAgMw7ArpXxR8YijBAg0LtD3/We73e5l4wzGJ0CAAIEwAQVHWGCuS4AAgVoB36BSK+Y8AQK+ScUOECBAgECigIIjMTV3JkCAQIXAMAxTxXFHCRAg4Kti7QABAgQIRAooOCJjc2kCBAgsF1BwLLdykgCBfwl4B4dNIECAAIFEAQVHYmruTIAAgQoBBUcFlqMECPwq8JdxHB/jIECAAAECSQIKjqS03JUAAQIHCCg4DkDzCIHGBbqu+/b4+PhR4wzGJ0CAAIEwAQVHWGCuS4AAgVoBBUetmPMECCg47AABAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgVEDBYREIECBAIFFAwZGYmjsTIECgQkDBUYHlKAECCg47QIAAAQKxAgqO2OhcnAABAssEFBzLnJwiQOBcwDs4bAMBAgQIJAooOBJTc2cCBAhUCCg4KrAcJUDgV4E/j+P4DAcBAgQIEEgSUHAkpeWuBAgQOEBAwXEAmkcINC4wTdOfTk5Odo0zGJ8AAQIEwgQUHGGBuS4BAgRqBRQctWLOEyCg4LADBAgQIJAooOBITM2dCRAgUCGg4KjAcpQAgVMBBYdFIECAAIFEAQVHYmruTIAAgQoBBUcFlqMECCg47AABAgQIxAooOGKjc3ECBAgsExiG4UUp5fNlp50iQICAd3DYAQIECBDIFFBwZObm1gQIEFgsMAzD/EGBXyx+wEECBJoX8Ccqza8AAAIECEQKKDgiY3NpAgQILBdQcCy3cpIAgX8J9H3/2W63e8mDAAECBAgkCSg4ktJyVwIECBwgoOA4AM0jBBoXGMfRf0ZsfAeMT4AAgUQB/+aVmJo7EyBAoEJgGIYnpZT7FY84SoBA4wIKjsYXwPgECBAIFVBwhAbn2gQIEFgqcHR09Giapm+WnneOAAECCg47QIAAAQKJAgqOxNTcmQABAhUCCo4KLEcJEJgFfhrHcYuCAAECBAikCSg40hJzXwIECFQKDMNwr5TyQ+VjjhMg0K6AgqPd7E1OgACBaAEFR3R8Lk+AAIH3C2w2m23XdX99/0knCBAgcCrwdBzHBywIECBAgECagIIjLTH3JUCAQKXA3bt37/R9/7fKxxwnQKBRga7rvj0+Pn7U6PjGJkCAAIFgAQVHcHiuToAAgaUCwzBMS886R4BA8wJ/GcfxcfMKAAgQIEAgTkDBEReZCxMgQKBeYBiGV6WUj+uf9AQBAq0JTNP0p5OTk11rc5uXAAECBPIFFBz5GZqAAAEC7xUYhmH+LytfvPegAwQINC/Q9/1nu93uZfMQAAgQIEAgTkDBEReZCxMgQKBeYBiGJ6WU+/VPeoIAgdYExnH0nw9bC928BAgQWImAfwNbSZDGIECAwH8TODo6ejRN0zeUCBAg8B6Bn8dxvEOJAAECBAgkCig4ElNzZwIECFQKDMNwr5TyQ+VjjhMg0J7AT+M4btsb28QECBAgsAYBBccaUjQDAQIE3iPgq2KtCAECSwR8RewSJWcIECBA4KYKKDhuajLuRYAAgQsW8FWxFwzq5QisU+CrcRznz+zxQ4AAAQIE4gQUHHGRuTABAgQOExiG4UUp5fPDnvYUAQItCOz3+/99/vz5/K8VfggQIECAQJyAgiMuMhcmQIDAYQK+SeUwN08RaEnAN6i0lLZZCRAgsD4BBcf6MjURAQIE3ikwDMPDUsp3eAgQIPAHAr5BxWoQIECAQLSAgiM6PpcnQIDAcoHNZrPtuu6vy59wkgCBxgSejuP4oLGZjUuAAAECKxJQcKwoTKMQIEDgfQI+aPR9Qv7/BJoW8AGjTcdveAIECOQLKDjyMzQBAQIEFgv4oNHFVA4SaE7AB4w2F7mBCRAgsDoBBcfqIjUQAQIE/lhgs9k87rrua0YECBB4S+D1OI6fUCFAgAABAskCCo7k9NydAAEClQLDMNwrpfxQ+ZjjBAisX+DHcRznf33wQ4AAAQIEYgUUHLHRuTgBAgTqBbbb7e39fv/3+ic9QYDAmgW6rvv2+Pj40ZpnNBsBAgQIrF9AwbH+jE1IgACB3wgMw/CylPIpFgIECPwq4PM37AIBAgQIrEFAwbGGFM1AgACBCoFhGJ6UUu5XPOIoAQLrFvD5G+vO13QECBBoRkDB0UzUBiVAgMC/BHwOh00gQOAtAZ+/YSUIECBAYBUCCo5VxGgIAgQILBfYbref7Pf7fyx/wkkCBFYu8JdxHB+vfEbjESBAgEADAgqOBkI2IgECBN4WGIZhV0r5ggwBAgT6vv9st9vNn83jhwABAgQIRAsoOKLjc3kCBAgcJjAMw8NSyneHPe0pAgRWJPDLOI63VzSPUQgQIECgYQEFR8PhG50AgXYF7t69e6fv+7+1K2ByAgRmgWmavj85OZkLTz8ECBAgQCBeQMERH6EBCBAgcJiAr4s9zM1TBNYk4Oth15SmWQgQIEBAwWEHCBAg0KjAZrN53HXd142Ob2wCBErx9bC2gAABAgRWJaDgWFWchiFAgMByAX+mstzKSQIrFXg6juODlc5mLAIECBBoUEDB0WDoRiZAgMCvAv5MxS4QaFrgz+M4PmtawPAECBAgsCoBBceq4jQMAQIE6gT8mUqdl9MEViTg21NWFKZRCBAgQOBfAgoOm0CAAIGGBfyZSsPhG71pAd+e0nT8hidAgMBqBRQcq43WYAQIEFgmMAzDi1LK58tOO0WAwBoEfHvKGlI0AwECBAi8LaDgsBMECBBoXGAYhoellO8aZzA+gZYEfh7H8U5LA5uVAAECBNoQUHC0kbMpCRAg8IcC2+32k/1+/w9EBAg0I/CXcRwfNzOtQQkQIECgGQEFRzNRG5QAAQJ/LDAMw/xNCl8yIkBg/QJ93//Pbrd7tf5JTUiAAAECrQkoOFpL3LwECBB4h8AwDPdKKT/AIUBg9QJPx3F8sPopDUiAAAECTQooOJqM3dAECBD4vcAwDC9LKZ+yIUBgvQLTNP3p5ORkt94JTUaAAAECLQsoOFpO3+wECBD4DwEfNmodCKxe4JdxHG+vfkoDEiBAgECzAgqOZqM3OAECBH4r4MNGbQSB1Qt8NY7jk9VPaUACBAgQaFZAwdFs9AYnQIDA7wWGYZj/y899NgQIrE7gdd/3t3246OpyNRABAgQI/IeAgsM6ECBAgMC/Bbbb7e39fv93JAQIrEug67pvj4+PH61rKtMQIECAAIHfCig4bAQBAgQI/EbAV8ZaCALrE+j7/rPdbjd/kLAfAgQIECCwWgEFx2qjNRgBAgQOE9hsNtuu6/562NOeIkDgBgr4atgbGIorESBAgMDFCyg4Lt7UKxIgQCBeYBiG+Wskv4gfxAAECBTv3rAEBAgQINCKgIKjlaTNSYAAgQoB7+KowHKUwM0W8O6Nm52P2xEgQIDABQooOC4Q00sRIEBgTQLexbGmNM3SqoB3b7SavLkJECDQpoCCo83cTU2AAIH3CngXx3uJHCBw0wW8e+OmJ+R+BAgQIHChAgqOC+X0YgQIEFiXgHdxrCtP07Ql4N0bbeVtWgIECBAoRcFhCwgQIEDgDwW8i8NyEIgV8O6N2OhcnAABAgQOFVBwHCrnOQIECDQiMAzDs1LKl42Ma0wCaxB43ff97d1u92oNw5iBAAECBAgsFVBwLJVyjgABAo0KbLfb2/v9/u+Njm9sAnECXdd9e3x8/Cju4i5MgAABAgQ+UEDB8YGAHidAgEALApvN5nHXdV+3MKsZCYQLePdGeICuT4AAAQKHCyg4DrfzJAECBJoR2G63n+z3+5ellI+bGdqgBDIFvhrH8Unm1d2aAAECBAh8mICC48P8PE2AAIFmBIZheFhK+a6ZgQ1KIE/gp3Ect3nXdmMCBAgQIHAxAgqOi3H0KgQIEGhCYBiGF6WUz5sY1pAEwgT2+/3/Pn/+fP7nqB8CBAgQINCkgIKjydgNTYAAgcMEfG3sYW6eInDZAtM0fX9ycjK/y8oPAQIECBBoVkDB0Wz0BidAgMBhAj5w9DA3TxG4RAEfLHqJuF6aAAECBHIEFBw5WbkpAQIEboSADxy9ETG4BIH/FPjzOI7PkBAgQIAAgdYFFBytb4D5CRAgcIDAMAz3Sik/HPCoRwgQuFiBH8dxnP/56IcAAQIECDQvoOBofgUAECBA4DCBYRjm/8X4y8Oe9hQBAhcgMP9pyp3dbjd/hbMfAgQIECDQvICCo/kVAECAAIHDBPypymFuniJwgQJfjeP45AJfz0sRIECAAIFoAQVHdHwuT4AAgesV8Kcq1+vvtzct4E9Tmo7f8AQIECDwLgEFh70gQIAAgQ8SGIZh/l+Q73/Qi3iYAIEaAd+aUqPlLAECBAg0I6DgaCZqgxIgQOByBM7+VOVFKeXTy/kNXpUAgbcEfGuKlSBAgAABAu8QUHBYCwIECBD4YIG7d+/e6fv+bx/8Ql6AAIH/KjBN0/cnJycPMREgQIAAAQK/F1Bw2AoCBAgQuBCBo6OjR9M0fXMhL+ZFCBB4l8DP4zjeQUOAAAECBAi8W0DBYTMIECBA4MIEfHXshVF6IQJvC/hKWDtBgAABAgTeI6DgsCIECBAgcGECPo/jwii9EIG3BXzuhp0gQIAAAQIKDjtAgAABAlcp4PM4rlLb72pBwOdutJCyGQkQIEDgIgS8g+MiFL0GAQIECPxGYBiGB6WU/8NCgMAHC/w0juP2g1/FCxAgQIAAgQYEFBwNhGxEAgQIXIfAMAxPSin3r+N3+50EViLwS9/3d3a73auVzGMMAgQIECBwqQIKjkvl9eIECBBoW2AYhl0p5Yu2FUxP4CCB1/v9fvv8+fMXBz3tIQIECBAg0KCAgqPB0I1MgACBqxI4+9DRueT4/Kp+p99DYCUCPlR0JUEagwABAgSuTkDBcXXWfhMBAgSaFNhut7f3+/38v0J/3CSAoQnUC3w1juP8J15+CBAgQIAAgQoBBUcFlqMECBAgcJjA2TerzO/kUHIcRuipRgR8Y0ojQRuTAAECBC5FQMFxKaxelAABAgTeFhiG4V4p5QcyBAj8ocDTcRznbyDyQ4AAAQIECBwgoOA4AM0jBAgQIHCYgK+PPczNU00I+DrYJmI2JAECBAhcpoCC4zJ1vTYBAgQI/E5AyWEpCPxO4Oe+77e+DtZmECBAgACBDxNQcHyYn6cJECBA4ACBo6OjR9M0fXPAox4hsDYB5cbaEjUPAQIECFybgILj2uj9YgIECLQtMAzD/C0R99tWMH3jAsqNxhfA+AQIECBwsQIKjov19GoECBAgUCGg5KjAcnRtAsqNtSVqHgIECBC4dgEFx7VH4AIECBBoW0DJ0Xb+jU6v3Gg0eGMTIECAwOUKKDgu19erEyBAgMACgc1m87jruq8XHHWEQLqAciM9QfcnQIAAgRsroOC4sdG4GAECBNoS8O0qbeXd6LTKjUaDNzYBAgQIXI2AguNqnP0WAgQIEFggoORYgORIqsCPfd8/8FWwqfG5NwECBAgkCCg4ElJyRwIECDQkcFZyPC6lfNzQ2EZdt8DTcRwfrHtE0xEgQIAAgesXUHBcfwZuQIAAAQJvCdy9e/dO3/c7JYfVSBeYpun7k5OTh+lzuD8BAgQIEEgQUHAkpOSOBAgQaFDgrOR4Ukr5vMHxjbwOga/GcZx32A8BAgQIECBwBQIKjitA9isIECBA4DCB7Xb7yX6/n9/JoeQ4jNBT1yPwepqmeycnJ/Pu+iFAgAABAgSuSEDBcUXQfg0BAgQIHC4wDMP8v4LfP/wVPEngygR+3u/3D54/f/7iyn6jX0SAAAECBAicCig4LAIBAgQIRAgMwzB/jsF3EZd1yVYFfFNKq8mbmwABAgRuhICC40bE4BIECBAgsERgs9lsu6575sNHl2g5c5UCXdd9e3x8/Ogqf6ffRYAAAQIECPxWQMFhIwgQIEAgSuDscznmkuOLqIu77FoFXpdSHozjOO+kHwIECBAgQOAaBRQc14jvVxMgQIDA4QJHR0ePpmn65vBX8CSBDxb4ue/7e7vd7uUHv5IXIECAAAECBD5YQMHxwYRegAABAgSuS8CfrFyXvN87TdP3Jycn8+fC+CFAgAABAgRuiICC44YE4RoECBAgcJjA2Z+szN+y8uVhr+ApAlUCv0zT9MBXwFaZOUyAAAECBK5EQMFxJcx+CQECBAhctsDZt6zMH/L48WX/Lq/frIBvSWk2eoMTIECAQIKAgiMhJXckQIAAgUUC2+329n6/n9/N4QNIF4k5tFDAB4kuhHKMAAECBAhcp4CC4zr1/W4CBAgQuBQB7+a4FNZWX9S7NlpN3twECBAgECeg4IiLzIUJECBAYInA2bs5HvtsjiVazrxDwGdtWAsCBAgQIBAmoOAIC8x1CRAgQKBOYBiGe6WUuej4tO5Jp1sV6Lru21u3bj3e7XavWjUwNwECBAgQSBRQcCSm5s4ECBAgUCUwf9PKmzdvHk7T9E3Vgw63JvBT3/cPdrvdy9YGNy8BAgQIEFiDgIJjDSmagQABAgQWCfizlUVMLR76pZTycBzHZy0Ob2YCBAgQILAWAQXHWpI0BwECBAgsFthsNtuu6+avlPVtK4vVVnnwddd1j4+Pj+dd8EOAAAECBAiECyg4wgN0fQIECBA4XGAYhgellPm/3Pp8jsMZE588LTZ8zkZidO5MgAABAgT+WEDBYTsIECBAoHkBRUdTK/C07/uHPkC0qcwNS4AAAQKNCCg4GgnamAQIECDwfgFFx/uNgk/MxcYjHyAanKCrEyBAgACB9wgoOKwIAQIECBB4S0DRsZqV8Kcoq4nSIAQIECBA4P0CCo73GzlBgAABAo0K+DDS2ODnb0V53Pf9E3+KEpuhixMgQIAAgWoBBUc1mQcIECBAoDWBs6+XnT+M9F4p5ePW5g+a96dSypNxHJ8E3dlVCRAgQIAAgQsSUHBcEKSXIUCAAIH1aG0q4QAAIABJREFUC2y320/2+/38zSsPffPKjcn7dSnlmc/XuDF5uAgBAgQIELg2AQXHtdH7xQQIECCQLHD37t0787dxeFfHtaXo3RrXRu8XEyBAgACBmymg4LiZubgVAQIECAQJnH0o6fznK18GXTvxqj/Pf4LS9/0z34aSGJ87EyBAgACByxVQcFyur1cnQIAAgYYEzv6EZS46lB0Xl7tS4+IsvRIBAgQIEFi1gIJj1fEajgABAgSuS+Cs7NielR0+nLQuiPnPT+bP1fBOjTo3pwkQIECAQNMCCo6m4zc8AQIECFyVwPyZHR999NG9aZrm0uOLq/q9Ib9n/lrX3VmpsfPVriGpuSYBAgQIELhhAgqOGxaI6xAgQIBAGwKbzWZ769atbaOFx/xnJy/mUqPv+7nQeNlG6qYkQIAAAQIELlNAwXGZul6bAAECBAgsFJgLj67r7pRSfv3H5wsfvenH5ndnvOi67sWbN292H3300Qvv0LjpkbkfAQIECBDIFFBwZObm1gQIECDQgMDZV9He6bru9tk7PT4ppdzU4mMuMl5O0zSXGaf/V5nRwJIakQABAgQI3CABBccNCsNVCBAgQIDAEoH5A0z/+c9/zsXHJ2fv+ihnBcivj1/0Z3zMf1Lyan7xubi4devWq2ma5n/M78p49fz58/nPTfwQIECAAAECBK5VQMFxrfx+OQECBAgQuHyB+Z0gt27dmt/9sejn5ORk/sBPPwQIECBAgACBKAEFR1RcLkuAAAECBAgQIECAAAECBAi8S0DBYS8IECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACB/2/HjmkAAAAQhvl3PR1LKoHCxV7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGKKR1pAAAI3klEQVSvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF7AwbGvUAACBAgQIECAAAECBAgQIEDAwWEDBAgQIECAAAECBAgQIECAwF4gdmkykxIWeegAAAAASUVORK5CYII=","e":1},{"id":"image_2","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4Xuzdf4xl53kf9vc9596ZoahaQyAN16ldDeumWsGNNazTcJ3U1RAJqg2CVKMijagoNndRJFq1ELSEY0u2a3kZwVYiO6a0iWwkMEARbaIi/4T6j0BRaJkgCeu6zTJIE6o/wGWbOoyQ1rsOJc7uzj1vce7uypS4uzNz5/44zzmfAQjZ4j3nvM/neeZo7veee05OfggQIECAAAECBAgQIECAAAECwQVy8PVbPgECBAgQIECAAAECBAgQIEAgCTgMAQECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIJSAE/8AACAASURBVECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDBAgQIAAAQIECBAgQIAAAQLhBQQc4VuoAAIECBAgQIAAAQIECBAgQEDAYQYIECBAgAABAgQIECBAgACB8AICjvAtVAABAgQIECBAgAABAgQIECAg4DADBAgQIECAAAECBAgQIECAQHgBAUf4FiqAAAECBAgQIECAAAECBAgQEHCYAQIECBAgQIAAAQIECBAgQCC8gIAjfAsVQIAAAQIECBAgQIAAAQIECAg4zAABAgQIECBAgAABAgQIECAQXkDAEb6FCiBAgAABAgQIECBAgAABAgQEHGaAAAECBAgQIECAAAECBAgQCC8g4AjfQgUQIECAAAECBAgQIECAAAECAg4zQIAAAQIECBAgQIAAAQIECIQXEHCEb6ECCBAgQIAAAQIECBAgQIAAAQGHGSBAgAABAgQIECBAgAABAgTCCwg4wrdQAQQIECBAgAABAgQIECBAgICAwwwQIECAAAECBAgQIECAAAEC4QUEHOFbqAACBAgQIECAAAECBAgQIEBAwGEGCBAgQIAAAQIECBAgQIAAgfACAo7wLVQAAQIECBAgQIAAAQIECBAgIOAwAwQIECBAgAABAgQIECBAgEB4AQFH+BYqgAABAgQIECBAgAABAgQIEBBwmAECBAgQIECAAAECBAgQIEAgvICAI3wLFUCAAAECBAgQIECAAAECBAgIOMwAAQIECBAgQIAAAQIECBAgEF5AwBG+hQogQIAAAQIECBAgQIAAAQIEBBxmgAABAgQIECBAgAABAgQIEAgvIOAI30IFECBAgAABAgQIECBAgAABAgIOM0CAAAECBAgQIECAAAECBAiEFxBwhG+hAggQIECAAAECBAgQIECAAAEBhxkgQIAAAQIECBAgQIAAAQIEwgsIOMK3UAEECBAgQIAAAQIECBAgQICAgMMMECBAgAABAgQIECBAgAABAuEFBBzhW6gAAgQIECBAgAABAgQIECBAQMBhBggQIECAAAECBAgQIECAAIHwAgKO8C1UAAECBAgQIECAAAECBAgQICDgMAMECBAgQIAAAQIECBAgQIBAeAEBR/gWKoAAAQIECBAgQIAAAQIECBAQcJgBAgQIECBAgAABAgQIECBAILyAgCN8CxVAgAABAgQIECBAgAABAgQICDjMAAECBAgQIECAAAECBAgQIBBeQMARvoUKIECAAAECBAgQIECAAAECBAQcZoAAAQIECBAgQIAAAQIECBAILyDgCN9CBRAgQIAAAQIECBAgQIAAAQICDjNAgAABAgQIECBAgAABAgQIhBcQcIRvoQIIECBAgAABAgQIECBAgAABAYcZIECAAAECBAgQIECAAAECBMILCDjCt1ABBAgQIECAAAECBAgQIECAgIDDDPRSoHwtjdLV9M5DFXc17eWzae9Qr/UiAgQ6K/C23/ubaSNN0sahF1zSG+mBtP/t12+mN/Ljb/n/D70jLyRAoEsCbzs3fDO9M9VpdOg1TtJ+ejC94dxwaDEvJECAwMoEBBwro3fgWQTKV9LW7e2+8z+rtJGadGKWfb5tm5yuppKuTv/7kl5POe19+z/30uvCkLko2wmBIwuUv5M2017aTDmdSGUaXNw6D/zu/3/kfR5pgyq9nppvh6FXvuMc4dxwJEovJjBPgZWdG+78fXCrmCvf/nthI13NH7r9d8Q8C7UvAgQIEDhQQMBxIJEXrEJgGmQ0t9/I3HrzstnktLmKtdztmFX7h0wbgrRveNoQxJubrrTGOnoiMD0HtL/7bXCZ02ZzJ8zocH3VnTc7zg0d7pKlRReIdG747r8V8kfSrWDUDwECBAgsTEDAsTBaOz6sQHk2baa1229mcjoR4Y3MXUOPW1d9XJmGHlW6kv90ev2wBl5HYMgC5dm0kdanV2NMQ42o54B79bBybhjyeKv9GAJ9PDfcDj3avw+upOvpiqtCjzEgNiVAgMBdBAQcxmLpAtM/WNbSyUlOW/nWG5rOXJkxV4yc9kpKV+pboYfAY664dhZdoPytdHI/pa0qT4ON+Xy9LAqKc0OUTlnnCgQGeG54vSnpyiinV1zhsYKBc0gCBHonIODoXUu7WVD52+nE/iSdrFI6Obg3M3daUtLV24HHK/nPpFe62SmrIrAYgW8Hm3U6mcv0PODHucEMEEjODW8Zgjvh5yS9km6kV1zd4ReEAAECRxcQcBzdzBaHFJiGGvtpexpqlJ5epXFIi7e9rP0jpkyv7vBHzKyGtuu8wPSNyzhtN3XanttNgDtf9fEXWFJ6xbnh+I720F2Bb4caKZ3Mtz748HMXAecCY0GAAIGjCwg4jm5mi/sIvDXUaIQah5qV9saEd/6IcWXHoci8qOMCN/7mrWCzeONy7E7lnC63YYdzw7Ep7aADAs4Nszcht8FnTpedC2Y3tCUBAsMQEHAMo88LrbL9JObmWjqZqnQqN9Wwvks/Z9mSm6vtHzGj6+mlfNYj5ubMa3cLFGjDzcl+OjUNNUrVPsLVzzwFcrOXUrrs3DBPVPtahkB7I/H99XQqpbTt3DAHceeCOSDaBQECfRYQcPS5uwuuzRuaxQKX1FwpOb207n4di4W292MJtJ/Itm9ccqram4X6WYJAe25ow461j6bLSzicQxCYScC5YSa2I23k74QjcXkxAQIDERBwDKTR8yzz+t+a3iTwlDc081S9975KadrHz740vpkuu+HYcswd5f4C7VVb+6N0quS0nXPVz6cgBRiC9tyQS7o82p9e8dVe4eGHwEoFpld0jqeh5ynnhuW1wt8Jy7N2JAIEui8g4Oh+jzqzwumnMSXtFG9oVtKTqr0sdZJe8mZmJfwOmtL0aQdtsJHqdKrxNZTOzMT03ODrK53pxxAX4tzQja77O6EbfbAKAgRWKyDgWK1/iKMLNjrYptxcXrueLrlPRwd708Mltd+hv7GedlKp2k9m/XRZwLmhy93p3doEG91sqaCjm32xKgIEliMg4FiOc8ijtMFGU9JOLi5B724Dm8tr++kFl6d3t0ORV9a+edkbpVNVTqfcHDBaJ6fnBiFotLYFWa9zQ5BG5WavKemlDV9jC9IwyyRAYB4CAo55KPZsH3eCjSLYCNHZ9pMaf8CEaFWYRb71zYuvooRp2z0W2lzy5iZ6D7u1/jf/m7TThp7ODd3qy/1W0/6dMEnp0jv+bHopzqqtlAABArMJCDhmc+vlVm9+JW2lJu2kxtMQIja4/QMm5/SCJytE7F531izg7E4v5rUSb27mJTns/bQ3GC9NOu3Dj7hzkNtH0VfpBU9ni9tDKydA4GABAcfBRr1/xfT79aO00yTfr+9Ds3NpXi+T9MIDZ1P7KMlO/5SvpJ23LPCt//fv/td5enPbW0/qyOlqKnd5NOZb//s6Xc1/2uMzj9r4N55NJ+o6nU5ZwHlUuyivb9/clJvp+S6cG8rfSZtpb/q0jfbn/ueBnNpHEL/7bc4lvfi2/y6ny6mk9slTd37a8+Ctc6Fzw0yj2v6NsFenXeeGmfi6uVFprmxM0vNdvI/XEc8N778H8LW7/K3wu+eCW+eEK84J3RxPqyJwXAEBx3EFg2//rf82nWr/uMyeiBC8k29ffpOay+9Y8f05yt9O22kyDSd2Uk6bqaTt6X+m9L4lgb88fbPzu296LrV/1OSPdD/8WZLP9Mko10dpp6SqPRf4GYBAKc0r1yfphYfOfkcQsJDKb4eYbUDR/nPrPLC83/9713QnHHFuuKfRna+qpVTdPXxeyMTY6XIFmksP/Fhq/3dx6T8dOzfcCUTuhCD+Vlj6RDgggfkJCDjmZxlqT28+m7ZynU6XXJ0ItXCLPZJAufX4yKV873b6x0pJ201O2zlNP5ldVohxJJO3vPjFktKVqr0ipKRL+aPDu+qjveR80qTTbiQ86wjF3W4R54aA54B7NfDFUtLlqv2Ed6DnhvZvhDJOu84NcX/HD7vy0n5tZcFXdgU/N9w5H1xqPyzxAclhJ8vrCKxOQMCxOvuVHLn9ROabo7STG5/WrqQBKzpolZsre5P0/Lw+sW0vWU7r7dea0k7O08vLux5mHFa+DT0uTUOPHj+Gtz0PvFmn3VKqk4eF8bp+Chzn3NC+aZmeA259xeRel4r3BW4w5wZ/I/RlZI9WR6malx689eSl9oORY/30/Nzw2vTvhDS98uWSwONYo2JjAgsREHAshLWbO51+InPrTc2t+xn4GZRATs1eqme/muPmV9JOVdrvYfcq0LjvDJSUXsztHzJNer4vV3hcfzadnFRpt6RqY1C/AIq9p8Bhzw3lK2mrKWm3DTVLSh8cMmkfzw3+RhjyRN+qfXoT0snR79Mz8HPDa23QUUp6fvRn0vOmiACB1QsIOFbfg4WvwFUbCycOdYCSmys3D3E1R3uVxmTt1puZlNJuSuldoQqd/2KvpZSeLynmHzGu2pj/QPRtj3c7N5S/Of3a2Znb54C33+izbwiz1RP+3OCqjdka39etDnM1h3PD3bufc/pq06Tn6xvdvIlrX2dWXQTeKiDg6Pk8+ESm5w2esbySmr3qLldz3Ak1UpV2Uxn2J7QH0E7f0LT/RPjE5neeTSerKu1mV23M+BsznM3ac8PaKP0/OacfzreCTaHG0dof7twwau/H5crOo3V5AK9ur+ZoJum/e+fZ9PqdctsrNfZLOu/ccMgByOmrSdhxSCwvIzA/AQHH/Cw7t6d//exoJ1WNu593rjPdWVDO+UqaTF5Y30gnc/n2p7RDv1LjqA2avqFpSvrCWsduVPrbz6bNUV2fTqW418ZRuzqw19cpbdR12a5y2c45PTyw8hdV7q0rO3L68vgjq3lSxb0Ka6/oeqOud50bFtX6/uy3Svk310eT35NzOl/6c7+tZTeos+eCZUM4HoFlCAg4lqG85GO0b2rW6uqJpiRPSFmyfaTD1SltVlXZruvpE0+EGnNoXknptZTKF8bX05fzEh7Beb8ltwFnrppTJSX32phDb/u6i1GVtqo22PDGZaEt7tK54VvPplNNVbX3UXFuWGjXY+/cuWEx/evSuWAxFdorgdULCDhW34O5rqC9FD1V1W72h8tcXfu0s6pKW6PcflLbmyefdLI9JefnUmmWflXHbz+btsZ1tVtKcjPhTk5GNxbVXq0xytMnoAg3l9wS54YlgzvckQRunxtO5eRKriPBzfDi9lwwyc2FBz6SrsywuU0IELiHgICjR6PxO8/WuzmV9tN4PwTeJlCPy/YopVPJ5efLno4Xc1MujH9ssZeov/FsOtGk+nROZWvZBTpeDIFcpY1RVU5VVTqVUlqPseper/LFkssX1hf85IX2qs46Tf8+cG7o9TjNXtxbzg2u6Jyd8ThbLuXvhOMs0LYEIgkIOCJ16x5rnX7PPlVPNMlXUnrQzrmXMB6X7dontXN3nWGH7ddXLqx9NH15hm3vucntNy87Rbg5T9Ze7auu0mbdfh1NsNHVvjo3dLUzPV9XXaWNuiqnnBs60+ilhJ6dqdZCCCxIQMCxINhl7ba9HL1O1RO+S7ss8TjHGdfTNzTtTWZdgt6ttr2W8/GDDsFGt5raxdVMbxw6KjtVTo91cX3W9DYB5wZDsRSB2+eGU9WtqzpdzbUU9SMd5OWmlPMPLPjKzyOtyIsJBBIQcARq1ncv9dqz7WXG1enAJVj6AgQEGwtAXcwuX0ulnF//senjZg/9I9g4NNVgX+jNS/jWzxR0ODeE7/vCC3BuWDjxXA9QSnqxpHJB0DFXVjsbgICAI2CT28e7/etUn3ZJesDmLXDJdXvz0LrsumJjgciL2PUh/4C5dbVWve33fhFN6M8+R3U51X4lzaeyvejpy+UQn+Levv/OKeeGXvR8YUWM2qs6czrt3LAw4sXtuP07YVTOuBnp4ojtuV8CAo5g/WzDjWupOlPcbyNY5xa33FGVToyqcjrn9O7FHcWelyDw1VKX89/9B8xvP9s+xrfeTm4QuIQWxD3EnYCz8pW0uE2818rv8eamfWraJNWnnBv61/J5VtSeG8a3/kZ4eJ77ta8VCOT8xfUbzYVVP4Z+BZU7JIEjCQg4jsS12he3n9LcTNUTKXn842o70Y2jTy81rX2/vhvdmM8qSkrXcspf2NtvvpDSaDulpr2jvce9zoe3l3sZpbRZ19M3L+/pZYGKeotAfjpVzbN7N0aPODcYjIME2r8R2qs6nRsOkor176d/J7RXdv34fG9YHkvBagncX0DAEWRC2nBjv5leubERZMmWuUCBUZVOjkbTr6O4OdgCnVe16/YPmP39/PykSVdWtQbH7b7AeFR2PP2g+32a5wrbc8NkP7+w36RX5rlf++qXwHg0fTJKe5NxfyP0q7VvrebFSVXOv/Oj6XJ/S1QZgdkEBByzuS11q+kl6k3Vvpn1M3CBqkqbtz+R8XWUIcxCSV+/McnPlybtDaFcNR5OoK7SifrWJ7MuOT8cWf9e5dzQv57OoaLb5wZfWZ2DZZRdlJSffvDHmgtR1mudBJYhIOBYhvIxjiHcOAZezzYdtc+qr30i07O2Hqac6zcn+fnGJ7aHser9a9qrNqqc3t/7QhV4GAHnhsMoDeQ1zg0DafTdy3y5mZQz7zzrao5BT4Hivy0g4OjwMPy/vz46nXJzqsNLtLQlCIzbT2tz2c2VT2uXwN3dQ5T09b32ao7iao7uNmlxK3MeWJxt+D07N4Rv4XEKcG44jl6/ti0lP/3gk67m6FdXVTOLgIBjFrUlbPOvfr3ezTm3Nxj0M2CBtWpyqqrTBwZMoPTvFLi+P8nP7zeV798PaDLGVdmp68ZVGwPq+QylOjfMgBZ9E+eG6B1cyPpfLq7mWAisncYREHB0sFfCjQ42ZclLqnL7ZIRmt0oe/bpk+hCHKyl9/eakcjVHiG7NvshRVbaq7PGOswsOb8v23LA/qV5oSro6vOqHU3HO5cS4ch+e4XT8yJVeSzldeOePt09k80NgeAICjo71XLjRsYasYDl1VU6OKk9IWQF9tENenzTl0n5TvxRt4dZ7f4Gc08Yol52qKo+xIjCDgHPDDGgRNnFuiNCl7qyxpPLV/aaceeiswLM7XbGSZQgIOJahfMhjtOFGKb6Wckiu3r0s12ljrW5OVym9r3fFKWhhAk1Kr00m+dL+JHuk7MKUl7fjtdFku67yaY93XJ55X49USvqX+01+wbmhHx12buhHH1dQxWulqc78G2f3L63g2A5JYCUCAo6VsL/9oMKNjjRiRcuo63KivWrDYx9X1IAeHLak9PLNSXWpmfikJmI7q7psjStfR4nYu66v+fZX2l5wbuh6p+6+vum5oS472VdWYzawI6vOOT3lKysdaYZlLFxAwLFw4oMPINw42KjPrxjVk+2RT2z73OJl1nZ9UvJL+5P8kqetLJN99mNVddoc5+Z0zuk9s+/FlgQOFpiU/KJzw8FOXXnF7XPDTs6u6uxKT8Kvo5Sv7idfWQnfRwUcKCDgOJBosS8QbizWt+t7H4+a3cofL11vU8T1XW+a/NLNSXZJake7d/tGwjt+/zvaoP4ua3pu2G+EoF1tsXNDVzvTk3Xl9HLVNGfeeTZd7klFyiDwNgEBxwqH4hu/PjpdSjq1wiU49IoE2huFrdfNGV9JWVEDBnLYktK12zcifcUVHd1oep3T5qhuBBvdaMeQV3F90oaggo7OzIBzQ2daMYSFXEsln/mes5Pnh1CsGocnIOBYUc+/8TfG2yVPn5ThZ2ACo1xOjOpyxk0EB9b41ZZ7vSnezKyyBe2bl7oSbKyyB459VwHnhhUPhnPDihsw7MM//a6zzYVhE6i+jwICjhV0dRpuFOHGCuhXfshxPdmu6/zBlS/EAoYq0N6j43J7ifrEzUiXMgN1XbZGVTnlHhtL4XaQ2QWuNyW9MmmqS84NsyMeZcv23FBXZdvX1I6i5rULEHjuXWeb9kM3PwR6IyDgWHIr/8Wvpa2qGjmRLNm9C4cbj8vpKpfHurAWayDQlPT1W0GHx8vOexraRz6P0uRkrnIbbDw87/3bH4FFCrTnhkmTLzeT/MoijzPUfbcfdDg3DLX7na375ZKanYfOegpbZztkYUcSEHAciet4L/7Gl9KJZlSdKanaON6ebB1JoH2zs1Y1p31KE6lrw1lre5+Opikv3Sz15TJJe8OpfP6Vjupyoq7KqSqnk76CNn9fe1yuwK17+OTLTcmXXdVxPPu6TpvtlVxVLtvODceztPXCBNqQY/ehs+nKwo5gxwSWJCDgWBL0q8+mjQduVOeFG0sC78hh7txMNPkUtyMdsYz7CZT2qo5SXrk5qd1d/ZCj0n5/vqonJ+uUt/2eHxLNy8IJ3Dk37De1GxYfsnvt//63j4F3bjgkmJd1QeBaytMrOfwN0IVuWMPMAgKOmekOv2Ebbqxfr87kXJ04/FZeGV2gfeMzrpsnvOmJ3slBrn/6ffymya/sNy5T/+4JaN+41NXkZJ3zSffWGOTvx5CLdm64T/edG4b8q9Gb2oUcvWnlcAsRcCyh97/11+vd3H6652cwAlUuJ8YjT0oZTMP7Xej1UtKV9sqOyYA/vW1/p+u62WrP5e6r0e+BV93hBe5c2THkc8Odq7hymgae7z68nlcS6K5ALvnsQ//F5MvdXaGVEbi3gIBjwdPxL35ttJOqtLPgw9h9hwSm4YbHwHaoI5YyT4GS0r8sTX6lSenKpOnvDUrbT2KrXLbqXNo3LVsppXfN09G+CPRNYHpuKPnKraex9P/cUOW0VeXS3m/HuaFvw6yeqUBOQg6jEFNAwLHAvv3WX187WZrmiQUewq47JlDX5cSoTmdySusdW5rlEFiIQCnptfYKj9JUr09yudIEvVFp+yls+9jGlEt7lcYJV2ksZFzsdEAC/Ts3pBM5pS3nhgENsVJTSens73Elh0kIJiDgWFDDXn02ba7fGJ0rTfLElAUZd2234yqfrEbNrnCja52xnmUKtE9eSCW/3pTyemqq15vcXJ1M8uvLXMNBxxqN8lZKzWZOabP9FDbl6RsXoeRBcP49gWMIODccA8+mBFYoIORYIb5DzyQg4JiJ7f4btTcVHV8fn8mluKnoAny7uMtRXbbrKn2wi2uzJgJdEGgvX08l7ZV06xF0JVXT/5xMytVS0tV5rrGuyolcVRupNJs5p/afjVRSe1XGpsvJ5yltXwSOL/Dd54amqV7PVdpb5Lmh/fCpqpr2nODccPwW2sMQBLIrOYbQ5r7UKOBYQCd/61fr3Ul2U9EF0HZyl+O6bI+EG53sjUWFE2hvaDrT1R5u7heu1xZM4CgCzg1H0fJaAosQEHIsQtU+FyAg4Jgz6j//0ni7VGV3zru1u44KjKq8NaqbJzu6PMsiQIAAAQIECBAgMBeBktPZ3+ueHHOxtJPFCQg45mj76pfSiVE1OpOS+27MkbWzu2ovgx/Xqe237+53tksWRoAAAQIECBAgMC8BIce8JO1nUQICjjnK/vNfHZ8r7rsxR9Hu7qoelRPjSrjR3Q5ZGQECBAgQIECAwGIE8uP/5p/bv7SYfdsrgeMJCDiO5/ftrf/vL41ONymdmtPu7KbDAuNROTESbnS4Q5ZGgAABAgQIECCwQIFrqVQ7v/fP37y8wGPYNYGZBAQcM7F950av/trGVtXst19V8NNzgbpKm+O6nPO1lJ43WnkECBAgQIAAAQL3E7iWk5DDiHRPQMBxzJ60j4St3hyfS6W0jx/002OBKqeN8aicySk93OMylUaAAAECBAgQIEDgMAKvrY0n2w+dne/j3g9zYK8hcC8BAccxZ+P/+tV6txSPhD0mY+c3n4YbdTmTs3Cj882yQAIECBAgQIAAgSUJlJfXxs2OkGNJ3A5zoICA40Cie7/g1b+6djJVzRPH2IVNgwisj5rdKuf3BVmuZRIgQIAAAQIECBBYikDO6bmH/9zE1/WXou0gBwkIOA4Suse/b7+akr45Ppeyr6bMSBhms7W6nK5zeizMgi2UAAECBAgQIECAwDIFSv7iiXP755d5SMcicDcBAceMc/Hql0anU1N5asqMflE2G42a7VFVPhhlvdZJgAABAgQIECBAYCUCOZ393j8/+fJKju2gBG4LCDhmGIX2qSlpv3EZ1gx2kTapq3JiPCofi7RmayVAgAABAgQIECCwIoFrk5x3vs/jY1fE77CtgIBjhjl49a+Nz6eSPTVlBrswm+S0sT5q2svs1sOs2UIJECBAgAABAgQIrFbg2vX1/a1HPFlltV0Y8NEFHEds/qt/dbTTpGrniJt5eTCBjXFzzuNggzXNcgkQIECAAAECBFYvUNKLv+/j+94vrb4Tg1yBgOMIbX/1mbTZjEbnUqo2jrCZlwYTWJs+MSV5YkqwvlkuAQIECBAgQIBANwRKSl/8Pjcd7UYzBrYKAccRGv5//LW1J3JJJ4+wiZcGE5jeVDQnNxUN1jfLJUCAAAECBAgQ6JZAzuVDv+9jk+e7tSqr6buAgOOQyJRBhAAAIABJREFUHX71mY2tZuTGoofkCvmyKpcT47q0N491342QHbRoAgQIECBAgACBDglcq9No+3s/vnelQ2uylJ4LCDgO2eD/8+L4fOPGoofUiveyqr2paN2cSVV6ON7qrZgAAQIECBAgQIBAJwVe/r6P7293cmUW1UsBAcch2vq/PTPezlXePcRLvSSowPq42c3uuxG0e5ZNgAABAgQIECDQYYGnv//j+xc6vD5L65GAgOOAZr76bNrYf2N0PjVuLNqjuf+OUkajcnKUy4f7Wp+6CBAgQIAAAQIECKxUIKfHv//j+5dWugYHH4SAgOOANv/vz4x2UuWxsH39bahS2RyPyzn33ehrh9VFgAABAgQIECCwaoGc8mv7129uP/JUurrqtTh+vwUEHPfp7/TqjWuj80129UZffw02RuVMzuXdfa1PXQQIECBAgAABAgS6IJBz+uL3f3z/fBfWYg39FRBw3Ke3X39mbTdVyU1xejr/46o5VVfpAz0tT1kECBAgQIAAAQIEOiXQPjr23/4vPTq2U03p2WIEHPdo6KvPpM0b1ZqEsWcDf6ecuv1qyshXU3raXmURIECAAAECBAh0U+Bac2N/y1dVutmcPqxKwHGPLk6v3kiu3ujDkN+thrWxr6b0tbfqIkCAAAECBAgQ6K5ASemLj/xXvqrS3Q7FXpmA4y79a6/e2Euu3og92vde/XiUTo2qxldT+tpgdREgQIAAAQIECHRaoDTp8Uc+4akqnW5S0MUJOO7SuPbqjcbVG0FH+v7LrquyuVYnT03pZXcVRYAAAQIECBAgEETgtXLTU1WC9CrUMgUc39Wuf/RM2txw9UaoIT7KYtfH5Ymc0nuOso3XEiBAgAABAgQIECAwZ4GSn37kEzcuzHmvdjdwAQHHdw3AK7+yfrrkcmrgc9HL8kd1OllX5cO9LE5RBAgQIECAAAECBIIJ5Lp+5JGP710JtmzL7bCAgOMtzXn1QtrY+5618ymnjQ73zNJmEMglbayNp09NedcMm9uEAAECBAgQIECAAIH5C7z473zi5s78d2uPQxUQcLyl8//smY2dJjV+wXr427BWl506p/f3sDQlESBAgAABAgQIEAgrkFP+0COfuPF82AIsvFMCAo63tOOf/pX18yWVzU51yGKOLZCrsrk+Sp889o7sgAABAgQIECBAgACBeQu89gOfuLk1753a3zAFBBy3+/5Pnhlv5ybvDnMM+l31+ricyTm9u99Vqo4AAQIECBAgQIBAVIH89A+44WjU5nVq3QKO2+34X39lfC6VfKJT3bGYYwuMqrRV1+XJY+/IDggQIECAAAECBAgQWJTAtXpyc+uRp9LVRR3AfochIOBIKf2zZza29pvmzDBaPqwqN8blfHZj0WE1XbUECBAgQIAAAQLxBHJ67t/9xE3vyeJ1rlMrFnCklP7pL6/tTnLa7lRnLObYAuOq2a7r/MFj78gOCBAgQIAAAQIECBBYuMD+pH7kvU95bOzCoXt8gMEHHO2jYd94cO3TPe7xIEvLVdpYq8u5nD0WdpADoGgCBAgQIECAAIFwAiWl5/69T7qKI1zjOrTgwQccL/+V8amqyac71BNLmYPAeFR2qspjYedAaRcECBAgQIAAAQIEliaQm/L4739q/9LSDuhAvRIQcPzS+vnk0bC9Guq6ShvjUTmfUlrvVWGKIUCAAAECBAgQINBzgZLSiyc/eXOn52Uqb0ECgw44/snnHzwxyZNzC7K12xUJrLVXb+Tm/Ss6vMMSIECAAAECBAgQIHAMgaaUx9/rKo5jCA5300EHHP/4l9d2S6ncXLRH89/ee2O9bly90aOeKoUAAQIECBAgQGBYAqXkF08+dd1VHMNq+1yqHXTAcfnza5/OudqYi6SddEJgXLf33iiu3uhENyyCAAECBAgQIECAwGwCpVSPv/epPffimI1vsFsNNuD4x7+8dnJSqicG2/keFt5evbHh6o0edlZJBAgQIECAAAECgxMo6asnn7qxO7i6FXwsgcEGHC//0toTTVOdPJaejTsl0D45pXb1Rqd6YjEECBAgQIAAAQIEZheoHnnvU3tXZt/elkMTGGTA8bULaWPzgY1PD63Zfa93Y61pe+rJKX1vtPoIECBAgAABAgSGIvDce5+6cWYoxarz+AKDDDj+0efH26nULnc6/vx0Zg/jUbNdVemDnVmQhRAgQIAAAQIECBAgcGyBnFzFcWzEAe1gkAHH//JLa08UX0/p1Zivj5vzVUrv6lVRiiFAgAABAgQIECAwcIFS0tM/+BM3LgycQfmHFBhkwPE//+UNvyCHHJAILxvV6eSoaj4cYa3WSIAAAQIECBAgQIDA4QVKStdu5htbjz6Vrh5+K68cqsDgAo7f/MW1k7n29JQ+Dfz6qDmTc3p3n2pSCwECBAgQIECAAAECtwRKKWf//Z+4+WUeBA4SGF7A8ZfXdnOqtg+C8e9jCFS5bK7V5ZMxVmuVBAgQIECAAAECBAjMIPDyD/7EDe/hZoAb2ibDCzj+0tqnS6k2htbovta7Pm52q5ze19f61EWAAAECBAgQIECAQEqlqR7/Az+5d4kFgfsJDCrg+I3PP3giTybnjEQ/BHKVNtZHzXmPhu1HP1VBgAABAgQIECBA4F4CpaTnfugveGSsCbm/wKACjv/pcxs7KaX2Hz89EFirPRq2B21UAgECBAgQIECAAIFDCezXNx5ys9FDUQ32RYMKOH7zc+vnSsonBtvtnhW+Xk/O5So/3LOylEOAAAECBAgQIECAwF0ESi5nf8jNRs3GfQQGE3B87ULaeMf6xqdNQz8ERnU5Ma7Kx/pRjSoIECBAgAABAgQIEDiEwMs/9BfcbPQQToN9yWACjvbxsJPs8bB9mfS1ujld5fxYX+pRBwECBAgQIECAAAECBws0pXn00Z+6efngV3rFEAUGE3D8xufWT5eUTw2xyX2seWNU2qtx1vtYm5oIECBAgAABAgQIELiHQElffN9PXW8fNOCHwNsEBhNw/I+fWz+XGvff6MPvwGiUTo6q8uE+1KIGAgQIECBAgAABAgSOJPDa+37y+taRtvDiwQgMIuCY3n9j7P4bfZnqtXF5Iuf0nr7Uow4CBAgQIECAAAECBA4vUFJ+/NGf3Lt0+C28cigCgwg4/sEvrp3Mxf03+jDUVUob6+PyqT7UogYCBAgQIECAAAECBI4ukHN57n0/eePM0be0Rd8FBhFw/MPPbuykKu30vZlDqG9cl+26Sh8cQq1qJECAAAECBAgQIEDgrgLXHv2p65tsCHy3wDACjl/YaNM939PqwfyvjXw9pQdtVAIBAgQIECBAgACBYwnk7GsqxwLs6cZDCTgu9LR/gyqr/XrKeOTrKYNqumIJECBAgAABAgQI3EWglPTFH/60p6kYju8U6H3A8Ruff/DEzZuTcxofX2BUle2xr6fEb6QKCBAgQIAAAQIECBxf4LX/4FOepnJ8xn7tofcBx9//hQe3UzPZ7VfbhlnN+rjs5pzeN8zqVU2AAAECBAgQIECAwFsFqtw8+uhP3bxMhcAdgd4HHP/gs+unS8qntDy+wMZa+XRKaT1+JSogQIAAAQIECBAgQOD4AvnpH/7UntsRHB+yN3vofcDx99sbjDZuMBp9Yqs6bY2r8mT0OqyfAAECBAgQIECAAIG5Cbz8Bz99fXtue7Oj8AK9Dzj+3mc3JHrhxzSltVFzus75sR6UogQCBAgQIECAAAECBOYkUK9ff+jRp9LVOe3OboIL9Drg+NqFzc1RfeN88B5Zfvu9lNHkXM7pYRgECBAgQIAAAQIECBC4I5Bz+dAf/NSN54kQaAV6HnBsbI3q6oxWxxaoqrK5VpVPxq7C6gkQIECAAAECBAgQmLdASem5P/TTe97zzRs26P56HXD8vc9u7KSm2gnaG8u+LVCPyvaoKh8EQoAAAQIECBAgQIAAgbcKlJRee+yn97aoEGgFeh5wPHi6aYonqASf9fbxsFUuHg8bvI+WT4AAAQIECBAgQGARApOUHvmRn967soh922csgV4HHH/3L26cKaWS5sWaybetdmPctPdReVfwMiyfAAECBAgQIECAAIEFCOSSzv6hn9378gJ2bZfBBHodcLz4Fzc+nUq1EawnlvsWgen9N2r33zAUBAgQIECAAAECBAjcU+C5x37GfTjMR8+/ovLi0+/wiNjgUz6qy3bt/hvBu2j5BAgQIECAAAECBBYq8Nqpn3EfjoUKB9l5b6/g+NqFB09UuZwL0gfLvIfAWl12c+X+GwaEAAECBAgQIECAAIF7C6zf2Hjo0QtXrzIatkCPA46NrZQ8Ijb6eG+MmnM5p4ej12H9BAgQIECAAAECBAgsTiDn6kOP/cy3nl/cEew5gkCPA44HTqWUT0dogjXeQyCXjY1R+RQfAgQIECBAgAABAgQIHCDw9I/87J5bFAx8THoccGzspFTtDLy/ocuv67Q1qponQxdh8QQIECBAgAABAgQILEPgxT/8s3ve/y1DusPH6HHA8eDplMqpDttb2gECa3Wzk3N6PygCBAgQIECAAAECBAgcIHDtD//Xe5uUhi3Q44Bj40yTqq1htzd29et180TO6T2xq7B6AgQIECBAgAABAgSWIVDV6ZEf+em9K8s4lmN0U0DA0c2+WFVKaWPUnE8pvQsGAQIECBAgQIAAAQIEDhJoSnr8R39u79JBr/Pv+yvQ24Djf7jwwPmUskuUAs/uxqj5+cDLt3QCBAgQIECAAAECBJYpUNLTf+Tn3Gh0meRdO1Z/A47PvMMddLs2bUdYT1WlrXHtBqNHIPNSAgQIECBAgAABAsMWKPmr/9Fn3twdNsKwq+9twPHfCzhCT/Za3ZyqqvyB0EVYPAECBAgQIECAAAECyxR4+Ud/7s3tZR7QsbolIODoVj+s5rbA2qicrnJ6DAgBAgQIECBAgAABAgQOK/CjP/dmb9/jHtZgyK/rZfMvXEjVH2ne8ZkhNzZ67et1OZNzenf0OqyfAAECBAgQIECAAIHlCew35ZHHL3iSyvLEu3Wk3gYcPyLg6NakHXE17RNUcsqeoHJENy8nQIAAAQIECBAgMGSBnIsnqQx4AAQcA25+l0t/YFQ8QaXLDbI2AgQIECBAgAABAt0UeOo//sybX+jm0qxq0QICjkUL2/+RBeqUTozr8rEjb2gDAgQIECBAgAABAgQGLpCffv/Pf8sTNQc6Bf0NOPbdgyPqTNfTR8SWJ6Ou37oJECBAgAABAgQIEFiZwIvv//k3d1Z2dAdeqYCAY6X8Dn43gXrUnBplj4g1HQQIECBAgAABAgQIHE0gpyTgOBpZr17d24DjMVdwhB3UtVHZqVN6f9gCLJwAAQIECBAgQIAAgdUIlHJt5+m9zdUc3FFXLSDgWHUHHP9tAuuj8kRO6T1oCBAgQIAAAQIECBAgcFSBxy+82cv3uUd1GOLre9n4CxdS5QqOuOO8PipnckrvjluBlRMgQIAAAQIECBAgsDqB6nsfv/DN11d3fEdelYCAY1XyjntPgbVROZdLehgRAQIECBAgQIAAAQIEjiqQc/Xo4xe+efmo23l9fIHeBhz/oXtwhJ3OB+ry82EXb+EECBAgQIAAAQIECKxUQMCxUv6VHry/AceNd35mpbIOPrPAxngi4JhZz4YECBAgQIAAAQIEhi1QcvXH/9iFb74wbIVhVi/gGGbfO1t1XZWNcV0+1dkFWhgBAgQIECBAgAABAt0WyPnsH73wzS93e5FWtwgBAcciVO1zZoGcyub6qHxy5h3YkAABAgQIECBAgACBYQuUfPaPflbAMcQh6G3A8cO+ohJynutUNtcEHCF7Z9EECBAgQIAAAQIEuiCQBRxdaMNK1iDgWAm7g95LoA04xgIOA0KAAAECBAgQIECAwIwCOadf/GNPf+tnZ9zcZoEFBByBm9fHpVcpnVirm4/1sTY1ESBAgAABAgQIECCweIGS8sX/5LPf9LX3xVN37ggCjs61ZNgLqnPZGlXlyWErqJ4AAQIECBAgQIAAgdkFBByz28XesrcBx6N7HhMbcTTHtYAjYt+smQABAgQIECBAgEB3BAQc3enFclci4Fiut6MdICDgMCIECBAgQIAAAQIECBxPQMBxPL+4Wws44vaulytvA446+4pKL5urKAIECBAgQIAAAQLLEMj54gfcg2MZ0p07hoCjcy0Z9oKm9+CoBRzDngLVEyBAgAABAgQIEJhdIAs4ZscLvqWAI3gD+7Z8AUffOqoeAgQIECBAgAABAssVEHAs17tLR+ttwPE+Nxnt0pwdei2jXLbGnqJyaC8vJECAAAECBAgQIEDgOwVyyhc/8AseEzvEuehvwPEtT1GJONCjyldUIvbNmgkQIECAAAECBAh0RyBf/OMCju60Y4krEXAsEduhDhYQcBxs5BUECBAgQIAAAQIECNxPQMAx1PkQcAy18x2te1Tlrbpqnuzo8iyLAAECBAgQIECAAIGOC5SSLv6Jz/mKSsfbtJDl9Tbg+AO+orKQgVn0TtuAYyzgWDSz/RMgQIAAAQIECBDorYCAo7etPbAwAceBRF6wTIE24BgJOJZJ7lgECBAgQIAAAQIE+iXgCo5+9fMI1Qg4joDlpYsXqKq8tSbgWDy0IxAgQIAAAQIECBDoq4CAo6+dPbAuAceBRF6wTIE24Bhn9+BYprljESBAgAABAgQIEOiTQEnp4p90D44+tfTQtfQ24PjBNzwm9tBT0KEXTu/BUQs4OtQSSyFAgAABAgQIECAQSkDAEapdc12sgGOunHZ2XIHpPTgEHMdltD0BAgQIECBAgACBIQu4gmOg3RdwDLTxXS279hSVrrbGuggQIECAAAECBAhEEbj4J/+Sx8RGadY81yngmKemfR1boE55azTyFZVjQ9oBAQIECBAgQIAAgeEKXPxPBRyD7H5vA473ugdHyIEeCzhC9s2iCRAgQIAAAQIECHRIQMDRoWYscykCjmVqO9aBAgKOA4m8gAABAgQIECBAgACB+wsIOAY6If0NOH7HU1QizvT0HhxuMhqxddZMgAABAgQIECBAoBMCOScBRyc6sfxFCDiWb+6I9xFoAw5PUTEiBAgQIECAAAECBAjMLJDTxV334JiZL/KGAo7I3evh2gUcPWyqkggQIECAAAECBAgsU0DAsUztTh2rtwHHe37nez7TKWmLOZTAqCpbo8pTVA6F5UUECBAgQIAAAQIECLxNIKd0cffzHhM7xNEQcAyx6x2ueZTL1qguT3Z4iZZGgAABAgQIECBAgECHBW4FHG98ssNLtLQFCQg4FgRrt7MJCDhmc7MVAQIECBAgQIAAAQK3BAQcw52E3gYcv99XVEJOdRtwjCtXcIRsnkUTIECAAAECBAgQ6IJAThf/M1dwdKETS19DfwOOq+7BsfRpmsMBR3V7Dw4Bxxwo7YIAAQIECBAgQIDAIAVKThf/lIBjkL0XcAyy7d0tWsDR3d5YGQECBAgQIECAAIEIAgKOCF1azBoFHItxtdcZBaq6bK25gmNGPZsRIECAAAECBAgQICDgGO4M9Dbg+AFfUQk51dN7cHiKSsjeWTQBAgQIECBAgACBjghc/FO/7CkqHenFUpch4Fgqt4MdJCDgOEjIvydAgAABAgQIECBA4AABAcdAR0TAMdDGd7Xs6WNifUWlq+2xLgIECBAgQIAAAQLdFyjp4n/+K67g6H6j5r9CAcf8Te3xGAK1x8QeQ8+mBAgQIECAAAECBAgkAcdgh6C/Acf/5zGxEae6rsrWyD04IrbOmgkQIECAAAECBAh0QiALODrRh1UsorcBxyMCjlXM07GPORZwHNvQDggQIECAAAECBAgMWUDAMdzuCziG2/tOVt4GHLV7cHSyNxZFgAABAgQIECBAIIjAxQ+7B0eQVs13mQKO+Xra2zEF2q+ojAUcx1S0OQECBAgQIECAAIFBCwg4Btp+AcdAG9/VsusqeYpKV5tjXQQIECBAgAABAgQCCORUBBwB+rSIJfY24Hi3e3AsYl4Wvs9RlbbGuTy58AM5AAECBAgQIECAAAECvRSYBhzPeExsL5t7QFECjiF2vcM1twHHSMDR4Q5ZGgECBAgQIECAAIGuC5SLHxFwdL1JC1lffwOOf+UxsQuZmAXvdBpweEzsgpXtngABAgQIECBAgECfBQQcfe7u/WoTcAy18x2tuw04agFHR7tjWQQIECBAgAABAgS6L1BSufhRV3B0v1ELWGFvA47vdwXHAsZl8buc3oPDU1QWD+0IBAgQIECAAAECBHoqULKAo6etPbAsAceBRF6wTIFRSlujkZuMLtPcsQgQIECAAAECBAj0SkDA0at2HqUYAcdRtLx24QICjoUTOwABAgQIECBAgACBfgsIOPrd3/tUJ+AYbOu7WXiV0tbYPTi62RyrIkCAAAECBAgQIBBCoFz8s1/0mNgQrZrzInsbcPxb3/AUlTnPylJ2N70Hh4BjKdYOQoAAAQIECBAgQKCfAgKOfvb14KoEHAcbecUSBQQcS8R2KAIECBAgQIAAAQK9FBBw9LKthyhKwHEIJC9ZnkDtKSrLw3YkAgQIECBAgAABAj0UyFnA0cO2HqokAcehmLxoWQJtwDHymNhlcTsOAQIECBAgQIAAgf4J5HLxx92Do399PURFAo5DIHnJ8gTqnLZG7sGxPHBHIkCAAAECBAgQINA3AQFH3zp66Hp6G3B87zc2P3NoBS/sjMD4/2/vjnHjKMMADM9vOxVF3NH6IBQ+CVhEUYIUKVdBiwhIKXIIDpDrUCJ6dtEGaLG0Y4/mnXlqtN75nu+rXs2GcRQ4VrMND0KAAAECBAgQIEAgKCBwBJf2NI8scDyNo7/yRALX43j34mr67on+nD9DgAABAgQIECBAgMDOBMY0Hb796c/3OxvbuNM0bTdw/O4NjuKFX18f724EjuLqPDMBAgQIECBAgACBtQgcHgSOtexi0ecQOBbl9mWPCQgcjwn57wQIECBAgAABAgQIPCIgcOz0RDYbOL72BkfypG+uj3cvhp+oJJfnoQkQIECAAAECBAisQeA0HR5+9hOVNaxi6WcQOJYW933/K3AOHDcChyshQIAAAQIECBAgQOBCgdNpOnwvcFyo1/7YJgPHaZrGjw+3L9ur2efTv/zqr2/GGL/tc3pTEyBAgAABAgQIECAwV0DgmCvY/fwmA0d3HZ7807vb+9N0/EyCAAECBAgQIECAAAECFwl4g+Miti18SODYwhY3NMOXwHESODa0UqMQIECAAAECBAgQWFrAT1SWFl/J9wkcK1mEx/hH4OO72/srgcM5ECBAgAABAgQIECBwucDhlX+D43K98CcFjvDytvjoAscWt2omAgQIECBAgAABAosKCByLcq/nywSO9ezCk/z7Bsc4+omKYyBAgAABAgQIECBA4DKBMU2HVx/8b2Iv02t/SuBo729zT39+g0Pg2NxaDUSAAAECBAgQIEBgMQGBYzHq1X2RwLG6lez7gc6BY/IGx76PwPQECBAgQIAAAQIE5gkcXnuDY55g9NMCR3RxW33sj29v76fhJypb3a+5CBAgQIAAAQIECDy7wJgEjmdHXucXCBzr3Mtun+ocOE7j9Hm3AAYnQIAAAQIECBAgQGCWwBjj8PrDH+9n/REfTgoIHMm1bfehBY7t7tZkBAgQIECAAAECBJYQEDiWUF7ndwgc69zLbp/ql7e391fe4Njt/g1OgAABAgQIECBAYLbAGIc33uCYzVj8AwJHcWsbfuYvgWPyE5UNr9hoBAgQIECAAAECBJ5ZYBze/OonKs+MvMo/L3Csci37fahz4BgCx34PwOQECBAgQIAAAQIEZgqcpnH4QeCYqdj8uMDR3Ntmn1rg2OxqDUaAAAECBAgQIEBgEQGBYxHmVX6JwLHKtez3oc6BYzr5icp+L8DkBAgQIECAAAECBGYKDG9wzBTMflzgyK7OgxMgQIAAAQIECBAgQIAAAQL/CQgcboEAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAW8XlIAAAeVElEQVQAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECDwN4UTT/xKUkEiAAAAAElFTkSuQmCC","e":1},{"id":"image_3","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4Xuzd4Ynlh3nF4WtUgNVB1EFIASM2HagEpYN0kHQQd2B1kKQDwRX67FQQq4O4gGGDQIFgYpRd71j+vecR7CfN/d97nvOCxGFm9lcP/xAgQIAAAQIECBAgQIAAAQIE4gK/in9+H58AAQIECBAgQIAAAQIECBAg8DBwOAICBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgElK5UcAACAASURBVAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIECBAgAABAgTyAgaOfIUCECBAgAABAgQIECBAgAABAgYON0CAAAECBAgQIECAAAECBAjkBQwc+QoFIECAAAECBAgQIECAAAECBAwcboAAAQIECBAgQIAAAQIECBDICxg48hUKQIAAAQIECBAgQIAAAQIECBg43AABAgQIECBAgAABAgQIECCQFzBw5CsUgAABAgQIECBAgAABAgQIEDBwuAECBAgQIECAAAECBAgQIEAgL2DgyFcoAAECBAgQIECAAAECBAgQIGDgcAMECBAgQIAAAQIECBAgQIBAXsDAka9QAAIECBAgQIAAAQIECBAgQMDA4QYIECBAgAABAgQIECBAgACBvICBI1+hAAQIECBAgAABAgQIECBAgICBww0QIECAAAECBAgQIECAAAECeQEDR75CAQgQIECAAAECBAgQIECAAAEDhxsgQIAAAQIECBAgQIAAAQIE8gIGjnyFAhAgQIAAAQIECBAgQIAAAQIGDjdAgAABAgQIECBAgAABAgQI5AUMHPkKBSBAgAABAgQIECBAgAABAgQMHG6AAAECBAgQIECAAAECBAgQyAsYOPIVCkCAAAECBAgQIECAAAECBAgYONwAAQIECBAgQIAAAQIECBAgkBcwcOQrFIAAAQIECBAgQIAAAQIECBAwcLgBAgQIECBAgAABAgQIECBAIC9g4MhXKAABAgQIECBAgAABAgQIECBg4HADBAgQIECAAAECBAgQIECAQF7AwJGvUAACBAgQIECAAAECBAgQIEDAwOEGCBAgQIAAAQIECBAgQIAAgbyAgSNfoQAECBAgQIAAAQIECBAgQICAgcMNECBAgAABAgQIECBAgAABAnkBA0e+QgEIECBAgAABAgQIECBAgAABA4cbIECAAAECBAgQIECAAAECBPICBo58hQIQIECAAAECBAgQIECAAAECBg43QIAAAQIECBAgQIAAAQIECOQFDBz5CgUgQIAAAQIECBAgQIAAAQIEDBxugAABAgQIECBAgAABAgQIEMgLGDjyFQpAgAABAgQIECBAgAABAgQIGDjcAAECBAgQIECAAAECBAgQIJAXMHDkKxSAAAECBAgQIECAAAECBAgQMHC4AQIECBAgQIAAAQIECBAgQCAvYODIVygAAQIECBAgQIAAAQIECBAgYOBwAwQIECBAgAABAgQIECBAgEBewMCRr1AAAgQIECBAgAABAgQIECBAwMDhBggQIECAAAECBAgQIECAAIG8gIEjX6EABAgQIECAAAECBAgQIECAgIHDDRAgQIAAAQIECBAgQIAAAQJ5AQNHvkIBCBAgQIAAAQIECBAgQIAAAQOHGyBAgAABAgQIvKHAu3fvPn99ff368Xj8+Odv/+it/uPxeHzz2WefffPtt9/+1xt+DI8mQIAAAQLnBQwc5ysWkAABAgQIEPilBF5eXn4cNX7zeDx+/TOf4Yf3799//d133337S31W70uAAAECBOoCBo56gz4/AQIECBAg8Fcp8OWXX/7z+/fv/+kDP9w/PJ/Pbz7wNb6cAAECBAgQeDweBg5nQIAAAQIECBD4xAI/fefGbz/mse/fv/9738nxMXJeQ4AAAQLrAgaO9QuQnwABAgQIEPikAj/9zo3f/z9+LOVPve8Pz+fzi0/6oTyMAAEC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gAABAuMCBo7xAxCfAAECBAgQIECAAAECBAhcEDBwXGhRBgIECBAgQIAAAQIECBAgMC5g4Bg/APEJECBAgAABAgQIECBAgMAFAQPHhRZlIECAAAECBAgQIECAAAEC4wIGjvEDEJ8AAQIECBAgQIAAAQIECFwQMHBcaFEGAgQIECBAgAABAgQIECAwLmDgGD8A8QkQIECAAAECBAgQIECAwAUBA8eFFmUgQIAAAQIECPx3O3ZQAAAAQECsf2s93CIYLwQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQcDB8dCiDAQIECBAgAABAgQIECBAIC7g4IgPQHwCBAgQIECAAAECBAgQIPAg4OB4aFEGAgQIECBAgAABAgQIECAQF3BwxAcgPgECBAgQIECAAAECBAgQeBBwcDy0KAMBAgQIECBAgAABAgQIEIgLODjiAxCfAAECBAgQIECAAAECBAg8CDg4HlqUgQABAgQIECBAgAABAgQIxAUcHPEBiE+AAAECBAgQIECAAAECBB4EHBwPLcpAgAABAgQIECBAgAABAgTiAg6O+ADEJ0CAAAECBAgQIECAAAECDwIOjocWZSBAgAABAgQIECBAgAABAnEBB0d8AOITIECAAAECBAgQIECAAIEHAQfHQ4syECBAgAABAgQIECBAgACBuICDIz4A8QkQIECAAAECBAgQIECAwIOAg+OhRRkIECBAgAABAgQIECBAgEBcwMERH4D4BAgQIECAAAECBAgQIEDgQWAbGIM51m4xaQAAAABJRU5ErkJggg==","e":1},{"id":"image_4","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4Xuzd0Ymu53WG4V9MAU4HTgfRsdCAOojdgV1COkkHUQnqIBt+nQd3YHdgFSAUNvZB8InJ7HkWc6NL4MN5v1nXWmBzs7f81cM/BAgQIECAAAECBAgQIECAAIG4wFfx39+vT4AAAQIECBAgQIAAAQIECBB4CByOgAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAtAImrMAACAASURBVAQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQK/UoHvvvvuX37++ec/PB6Pz//5t39g+NPj8fj+5eXl+0+fPv31V0pkbAIECBAICQgcoWX5VQkQIECAAAEC7yXw+vr6u88B4/F4/OafvPnT5wDyfD5/eK9ve4cAAQIECCwEBI6FqjcJECBAgAABAh9Y4PX19fOf2Piv/+ev+Mfn8/k5iPiHAAECBAh8SAGB40OuxS9FgAABAgQIENgIfPvtt9999dVX//3G13/vT3K8Uc6PESBAgMBcQOCYE/sAAQIECBAgQODjCLy+vv758Xj89o2/0U8vLy//6t/J8UY9P0aAAAECUwGBY8rrcQIECBAgQIDAxxF4419N+ccB/uP5fP7nx5nKb0KAAAECBP4mIHC4BAIECBAgQIDAr0Tg9fX1878o9N+/cNw/PZ/Pr7/wDT9OgAABAgTeXUDgeHdSDxIgQIAAAQIEPqbA6+vrL+/xmz2fT/8b8j0gvUGAAAEC7yrgv5zeldNjBAgQIECAAIGPKyBwfNzd+M0IECBA4MsFBI4vN/QCAQIECBAgQCAhIHAk1uSXJECAAIE3Cggcb4TzYwQIECBAgACBmsDr6+tfH4/Hb7709/ZXVL5U0M8TIECAwEJA4FioepMAAQIECBAg8AEF/EtGP+BS/EoECBAg8G4CAse7UXqIAAECBAgQIPCxBfzfxH7s/fjtCBAgQODLBASOL/Pz0wQIECBAgACBlMDr6+ufH4/Hb9/4S//l5eXl60+fPn3+qy7+IUCAAAECH0pA4PhQ6/DLECBAgAABAgS2At98883XLy8v//PGr/z++Xz+8Maf9WMECBAgQGAqIHBMeT1OgAABAgQIEPh4Am/8qyp/fD6f33+8afxGBAgQIEDgbwICh0sgQIAAAQIECPwKBf7+Jzk+/2mMf/bXVf7yyy+//OHHH3/89CtkMjIBAgQIhAQEjtCy/KoECBAgQIAAgfcW+Puf5vjd4/H47v/8X8j+9Hg8PgeNH/ypjfcW9x4BAgQIrAQEjpWsdwkQIECAAAECBAgQIECAAIEzAYHjjNqHCBAgQIAAAQIECBAgQIAAgZWAwLGS9S4BAgQIECBAgAABAgQIECBwJiBwnFH7EAECBAgQIECAAAECBAgQILASEDhWst4lQIAAAQIECBAgQIAAAQIEzgQEjjNqHyJAgAABAgQIECBAgAABAgRWAgLHSta7BAgQIECAAAECBAgQIECAwJmAwHFG7UMECBAgQIAAAQIECBAgQIDASkDgWMl6lwABAgQIECBAgAABAgQIEDgTEDjOqH2IAAECBAgQIECAAAECBAgQWAkIHCtZ7xIgQIAAAQIECBAgQIAAAQJnAgLHGbUPESBAgAABAgQIECBAgAABAisBgWMl610CBAgQIECAAAECBAgQIEDgTEDgOKP2IQIECBAgQIAAAQIECBAgQGAlIHCsZL1LgAABAgQIECBAgAABAgQInAkIHGfUPkSAAAECBAgQIECAAAECBAisBASOlax3CRAgQIAAAQIECBAgQIAAgTMBgeOM2ocIECBAgAABAgQIECBAgACBlYDAsZL1LgECBAgQIECAAAECBAgQIHAmIHCcUfsQAQIECBAgQIAAAQIECBAgsBIQOFay3iVAgAABAgQIECBAgAABAgTOBASOM2ofIkCAAAECBAgQIECAAAECBFYCAsdK1rsECBAgQIAAAQIECBAgQIDAmYDAcUbtQwQIECBAgAABAgQIECBAgMBKQOBYyXqXAAECBAgQIECAAAECBAgQOBMQOM6ofYgAAQIECBAgQIAAAQIECBBYCQgcK1nvEiBAgAABAgQIECBAgAABAmcCAscZtQ8RIECAAAECBAgQIECAAAECKwGBYyXrXQIECBAgQIAAAQIECBAgQOBMQOA4o/YhAgQIECBAgAABAgQIECBAYCUgcKxkvUuAAAECBAgQIECAAAECBAicCQgcZ9Q+RIAAAQIECBAgQIAAAQIECKwEBI6VrHcJECBAgAABAgQIECBAgACBMwGB44zahwgQIECAAAECBAgQIECAAIGVgMCxkvUuAQIECBAgQIAAAQIECBAgcCYgcJxR+xABAgQIECBAgAABAgQIECCwEhA4VrLeJUCAAAECBAgQIECAAAECBM4EBI4zah8iQIAAAQIECBAgQIAAAQIEVgICx0rWuwQIECBAgAABAgQIECBAgMCZgMBxRu1DBAgQIECAAAECBAgQIECAwEpA4FjJepcAAQIECBAgQIAAAQIECBA4ExA4zqh9iAABAgQIECBAgAABAgQIEFgJCBwrWe8SIECAAAECBAgQIECAAAECZwICxxm1DxEgQIAAAQIECBAgQIAAAQIrAYFjJetdAgQIECBAgAABAgQIECBA4ExA4Dij9iECBAgQIECAAAECBAgQIEBgJSBwrGS9S4AAAQIECBAgQIAAAQIECJwJCBxn1D5EgAABAgQIECBAgAABAgQIrAQEjpWsdwkQIECAAAECBAgQIECAAIEzAYHjjNqHCBAgQIAAAQIECBAgQIAAgZWAwLGS9S4BAgQIECBAgAABAgQIECBwJiBwnFH7EAECBAgQIECAAAECBAgQILASEDhWst4lQIAAAQIECBAgQIAAAQIEzgQEjjNqHyJAgAABAgQIECBAgAABAgRWAgLHSta7BAgQIECAAAECBAgQIECAwJmAwHFG7UMECBAgQIAAAQIECBAgQIDASkDgWMl6lwABAgQIECBAgAABAgQIEDgTEDjOqH2IAAECBAgQIECAAAECBAgQWAkIHCtZ7xIgQIAAAQIECBAgQIAAAQJnAgLHGbUPESBAgAABAgQIECBAgAABAisBgWMl610CBAgQIECAAAECBAgQIEDgTEDgOKP2IQIECBAgQIAAAQIECBAgQGAlIHCsZL1LgAABAgQIECBAgAABAgQInAkIHGfUPkSAAAECBAgQIECAAAECBAisBASOlax3CRAgQIAAAQIECBAgQIAAgTMBgeOM2ocIECBAgAABAgQIECBAgACBlYDAsZL1LgECBAgQIECAAAECBAgQU93xWAAAHR1JREFUIHAmIHCcUfsQAQIECBAgQIAAAQIECBAgsBIQOFay3iVAgAABAgQIECBAgAABAgTOBASOM2ofIkCAAAECBAgQIECAAAECBFYCAsdK1rsECBAgQIAAAQIECBAgQIDAmYDAcUbtQwQIECBAgAABAgQIECBAgMBKQOBYyXqXAAECBAgQIECAAAECBAgQOBMQOM6ofYgAAQIECBAgQIAAAQIECBBYCQgcK1nvEiBAgAABAgQIECBAgAABAmcCAscZtQ8RIECAAAECBAgQIECAAAECKwGBYyXrXQIECBAgQIAAAQIECBAgQOBMQOA4o/YhAgQIECBAgAABAgQIECBAYCUgcKxkvUuAAAECBAgQIECAAAECBAicCQgcZ9Q+RIAAAQIECBAgQIAAAQIECKwEBI6VrHcJECBAgAABAgQIECBAgACBMwGB44zahwgQIECAAAECBAgQIECAAIGVgMCxkvUuAQIECBAgQIAAAQIECBAgcCYgcJxR+xABAgQIECBAgAABAgQIECCwEhA4VrLeJUCAAAECBAgQIECAAAECBM4EBI4zah8iQIAAAQIECBAgQIAAAQIEVgICx0rWuwQIECBAgAABAgQIECBAgMCZgMBxRu1DBAgQIECAAAECBAgQIECAwEpA4FjJepcAAQIECBAgQIAAAQIECBA4ExA4zqh9iAABAgQIECBAgAABAgQIEFgJCBwrWe8SIECAAAECBAgQIECAAAECZwICxxm1DxEgQIAAAQIECBAgQIAAAQIrAYFjJetdAgQIECBAgAABAgQIECBA4ExA4Dij9iECBAgQIECAAAECBAgQIEBgJSBwrGS9S4AAAQIECBAgQIAAAQIECJwJCBxn1D5EgAABAgQIECBAgAABAgQIrAQEjpWsdwkQIECAAAECBAgQIECAAIEzAYHjjNqHCBAgQIAAAQIECBAgQIAAgZWAwLGS9S4BAgQIECBAgAABAgQIECBwJiBwnFH7EAECBAgQIECAAAECBAgQILASEDhWst4lQIAAAQIECBAgQIAAAQIEzgQEjjNqHyJAgAABAgQIECBAgAABAgRWAgLHSta7BAgQIECAAAECBAgQIECAwJmAwHFG7UMECBAgQIAAAQIECBAgQIDASkDgWMl6lwABAgQIECBAgAABAgQIEDgTEDjOqH2IAAECBAgQIECAAAECBAgQWAkIHCtZ7xIgQIAAAQIECBAgQIAAAQJnAgLHGbUPESBAgAABAgQIECBAgAABAisBgWMl610CBAgQIECAAAECBAgQIEDgTEDgOKP2IQIECBAgQIAAAQIECBAgQGAlIHCsZL1LgAABAgQIECBAgAABAgQInAkIHGfUPkSAAAECBAgQIECAAAECBAisBASOlax3CRAgQIAAAQIECBAgQIAAgTMBgeOM2ocIECBAgAABAgQIECBAgACBlYDAsZL1LgECBAgQIECAAAECBAgQIHAmIHCcUfsQAQIECBAgQIAAAQIECBAgsBIQOFay3iVAgAABAgQIECBAgAABAgTOBASOM2ofIkCAAAECBAgQIECAAAECBFYCAsdK1rsECBAgQIAAAQIECBAgQIDAmYDAcUbtQwQIECBAgAABAgQIECBAgMBKQOBYyXqXAAECBAgQIECAAAECBAgQOBMQOM6ofYgAAQIECBAgQIAAAQIECBBYCQgcK1nvEiBAgAABAgQIECBAgAABAmcCAscZtQ8RIECAAAECBAgQIECAAAECKwGBYyXrXQIECBAgQIAAAQIECBAgQOBMQOA4o/YhAgQIECBAgAABAgQIECBAYCUgcKxkvUuAAAECBAgQIECAAAECBAicCQgcZ9Q+RIAAAQIECBAgQIAAAQIECKwEBI6VrHcJECBAgAABAgQIECBAgACBMwGB44zahwgQIECAAAECBAgQIECAAIGVgMCxkvUuAQIECBAgQIAAAQIECBAgcCYgcJxR+xABAgQIECBAgAABAgQIECCwEhA4VrLeJUCAAAECBAgQIECAAAECBM4EBI4zah8iQIAAAQIECBAgQIAAAQIEVgICx0rWuwQIECBAgAABAgQIECBAgMCZgMBxRu1DBAgQIECAAAECBAgQIECAwEpA4FjJepcAAQIECBAgQIAAAQIECBA4ExA4zqh9iAABAgQIECBAgAABAgQIEFgJCBwrWe8SIECAAAECBAgQIECAAAECZwICxxm1DxEgQIAAAQIECBAgQIAAAQIrAYFjJetdAgQIECBAgAABAgQIECBA4ExA4Dij9iECBAgQIECAAAECBAgQIEBgJSBwrGS9S4AAAQIECBAgQIAAAQIECJwJCBxn1D5EgAABAgQIECBAgAABAgQIrAQEjpWsdwkQIECAAAECBAgQIECAAIEzAYHjjNqHCBAgQIAAAQIECBAgQIAAgZWAwLGS9S4BAgQIECBAgAABAgQIECBwJiBwnFH7EAECBAgQIECAAAECBAgQILASEDhWst4lQIAAAQIECBAgQIAAAQIEzgQEjjNqHyJAgAABAgQIECBAgAABAgRWAgLHSta7BAgQIECAAAECBAgQIECAwJmAwHFG7UMECBAgQIAAAQIECBAgQIDASkDgWMl6lwABAgQIECBAgAABAgQIEDgTEDjOqH2IAAECBAgQIECAAAECBAgQWAkIHCtZ7xIgQIAAAQIECBAgQIAAAQJnAgLHGbUPESBAgAABAgQIECBAgAABAisBgWMl610CBAgQIECAAAECBAgQIEDgTEDgOKP2IQIECBAgQIAAAQIECBAgQGAlIHCsZL1LgAABAgQIECBAgAABAgQInAkIHGfUPkSAAAECBAgQIECAAAECBAisBASOlax3CRAgQIAAAQIECBAgQIAAgTMBgeOM2ocIECBAgAABAgQIECBAgACBlYDAsZL1LgECBAgQIECAAAECBAgQIHAmIHCcUfsQAQIECBAgQIAAAQIECBAgsBIQOFay3iVAgAABAgQIECBAgAABAgTOBASOM2ofIkCAAAECBAgQIECAAAECBFYCAsdK1rsECBAgQIAAAQIECBAgQIDAmYDAcUbtQwQIECBAgAABAgQIECBAgMBKQOBYyXqXAAECBAgQIECAAAECBAgQOBMQOM6ofYgAAQIECBAgQIAAAQIECBBYCQgcK1nvEiBAgAABAgQIECBAgAABAmcCAscZtQ8RIECAAAECBAgQIECAAAECKwGBYyXrXQIECBAgQIAAAQIECBAgQOBMQOA4o/YhAgQIECBAgAABAgQIECBAYCUgcKxkvUuAAAECBAgQIECAAAECBAicCQgcZ9Q+RIAAAQIECBAgQIAAAQIECKwEBI6VrHcJECBAgAABAgQIECBAgACBMwGB44zahwgQIECAAAECBAgQIECAAIGVgMCxkvUuAQIECBAgQIAAAQIECBAgcCYgcJxR+xABAgQIECBAgAABAgQIECCwEhA4VrLeJUCAAAECBAgQIECAAAECBM4EBI4zah8iQIAAAQIECBAgQIAAAQIEVgICx0rWuwQIECBAgAABAgQIECBAgMCZgMBxRu1DBAgQIECAAAECBAgQIECAwEpA4FjJepcAAQIECBAgQIAAAQIECBA4ExA4zqh9iAABAgQIECBAgAABAgQIEFgJCBwrWe8SIECAAAECBAgQIECAAAECZwICxxm1DxEgQIAAAQIECBAgQIAAAQIrAYFjJetdAgQIECBAgAABAgQIECBA4ExA4Dij9iECBAgQIECAAAECBAgQIEBgJSBwrGS9S4AAAQIECBAgQIAAAQIECJwJCBxn1D5EgAABAgQIECBAgAABAgQIrAQEjpWsdwkQIECAAAECBAgQIECAAIEzAYHjjNqHCBAgQIAAAQIECBAgQIAAgZWAwLGS9S4BAgQIECBAgAABAgQIECBwJiBwnFH7EAECBAgQIECAAAECBAgQILASEDhWst4lQIAAAQIECBAgQIAAAQIEzgQEjjNqHyJAgAABAgQIECBAgAABAgRWAgLHSta7BAgQIECAAAECBAgQIECAwJmAwHFG7UMECBAgQIAAAQIECBAgQIDASkDgWMl6lwABAgQIECBAgAABAgQIEDgTEDjOqH2IAAECBAgQIECAAAECBAgQWAkIHCtZ7xIgQIAAAQIECBAgQIAAAQJnAgLHGbUPESBAgAABAgQIECBAgAABAisBgWMl610CBAgQIECAAAECBAgQIEDgTEDgOKP2IQIECBAgQIAAAQIECBAgQGAlIHCsZL1LgAABAgQIECBAgAABAgQInAkIHGfUPkSAAAECBAgQIECAAAECBAisBASOlax3CRAgQIAAAQIECBAgQIAAgTMBgeOM2ocIECBAgAABAgQIECBAgACBlYDAsZL1LgECBAgQIECAAAECBAgQIHAmIHCcUfsQAQIECBAgQIAAAQIECBAgsBIQOFay3iVAgAABAgQIECBAgAABAgTOBASOM2ofIkCAAAECBAgQIECAAAECBFYCAsdK1rsECBAgQIAAAQIECBAgQIDAmYDAcUbtQwQIECBAgAABAgQIECBAgMBKQOBYyXqXAAECBAgQIECAAAECBAgQOBMQOM6ofYgAAQIECBAgQIAAAQIECBBYCQgcK1nvEiBAgAABAgQIECBAgAABAmcCAscZtQ8RIECAAAECBAgQIECAAAECKwGBYyXrXQIECBAgQIAAAQIECBAgQOBMQOA4o/YhAgQIECBAgAABAgQIECBAYCUgcKxkvUuAAAECBAgQIECAAAECBAicCQgcZ9Q+RIAAAQIECBAgQIAAAQIECKwEBI6VrHcJECBAgAABAgQIECBAgACBMwGB44zahwgQIECAAAECBAgQIECAAIGVgMCxkvUuAQIECBAgQIAAAQIECBAgcCYgcJxR+xABAgQIECBAgAABAgQIECCwEhA4VrLeJUCAAAECBAgQIECAAAECBM4EBI4zah8iQIAAAQIECBAgQIAAAQIEVgICx0rWuwQIECBAgAABAgQIECBAgMCZgMBxRu1DBAgQIECAAAECBAgQIECAwEpA4FjJepcAAQIECBAgQIAAAQIECBA4ExA4zqh9iAABAgQIECBAgAABAgQIEFgJCBwrWe8SIECAAAECBAgQIECAAAECZwICxxm1DxEgQIAAAQIECBAgQIAAAQIrAYFjJetdAgQIECBAgAABAgQIECBA4ExA4Dij9iECBAgQIECAAAECBAgQIEBgJSBwrGS9S4AAAQIECBAgQIAAAQIECJwJCBxn1D5EgAABAgQIECBAgAABAgQIrAQEjpWsdwkQIECAAAECBAgQIECAAIEzAYHjjNqHCBAgQIAAAQIECBAgQIAAgZWAwLGS9S4BAgQIECBAgAABAgQIECBwJiBwnFH7EAECBAgQIECAAAECBAgQILASEDhWst4lQIAAAQIECBAgQIAAAQIEzgQEjjNqHyJAgAABAgQIECBAgAABAgRWAgLHSta7BAgQIECAAAECBAgQIECAwJmAwHFG7UMECBAgQIAAAQIECBAgQIDASkDgWMl6lwABAgQIECBAgAABAgQIEDgTEDjOqH2IAAECBAgQIECAAAECBAgQWAkIHCtZ7xIgQIAAAQIECBAgQIAAAQJnAgLHGbUPESBAgAABAgQIECBAgAABAisBgWMl610CBAgQIECAwP+2Y8c0AAAACMP8u0YFu2oAkp4jQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl4DA8ZK1S4AAAQIECBAgQIAAAQIECGQCAkdG7YgAAQIECBAgQIAAAQIECBB4CQgcL1m7BAgQIECAAAECBAgQIECAQCYgcGTUjggQIECAAAECBAgQIECAAIGXgMDxkrVLgAABAgQIECBAgAABAgQIZAICR0btiAABAgQIECBAgAABAgQIEHgJCBwvWbsECBAgQIAAAQIECBAgQIBAJiBwZNSOCBAgQIAAAQIECBAgQIAAgZeAwPGStUuAAAECBAgQIECAAAECBAhkAgJHRu2IAAECBAgQIECAAAECBAgQeAkIHC9ZuwQIECBAgAABAgQIECBAgEAmIHBk1I4IECBAgAABAgQIECBAgACBl8AADOloOb9ayHQAAAAASUVORK5CYII=","e":1},{"id":"image_5","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4Xuzd0Y3n91WH4f96CkBUQDqIr1ceJXSQDggdQAehg1ABpgLcAYvH90AH0AGuYNFKFhcRIocdYz7v+LHku9+Mv+c55+rV2n738BcBAgQIECBAgAABAgQIECBAIC7wLv5+zydAgAABAgQIECBAgAABAgQIPAQOR0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAPAKgAUAACAASURBVAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABAgQIECBAgEBeQODIr9AABAgQIECAAAECBAgQIECAgMDhBggQIECAAAECBAgQIECAAIG8gMCRX6EBCBAgQIAAAQIECBAgQIAAAYHDDRAgQIAAAQIECBAgQIAAAQJ5AYEjv0IDECBAgAABAgQIECBAgAABAgKHGyBAgAABAgQIECBAgAABAgTyAgJHfoUGIECAAAECBAgQIECAAAECBAQON0CAAAECBAgQIECAAAECBAjkBQSO/AoNQIAAAQIECBAgQIAAAQIECAgcboAAAQIECBAgQIAAAQIECBDICwgc+RUagAABAgQIECBAgAABAgQIEBA43AABAgQIECBAgAABAgQIECCQFxA48is0AAECBAgQIECAAAECBAgQICBwuAECBAgQIECAAAECBAgQIEAgLyBw5FdoAAIECBAgQIAAAQIECBAgQEDgcAMECBAgQIAAAQIECBAgQIBAXkDgyK/QAAQIECBAgAABAgQIECBAgIDA4QYIECBAgAABAgQIECBAgACBvIDAkV+hAQgQIECAAAECBAgQIECAAAGBww0QIECAAAECBAgQIECAAAECeQGBI79CAxAgQIAAAQIECBAgQIAAAQIChxsgQIAAAQIECBAgQIAAAQIE8gICR36FBiBAgAABAgQIECBAgAABAgQEDjdAgAABAgQIECBAgAABAgQI5AUEjvwKDUCAAAECBAgQIECAAAECBAgIHG6AAAECBAgQIECAAAECBAgQyAsIHPkVGoAAAQIECBAgQIAAAQIECBAQONwAAQIECBAgQIAAAQIECBAgkBcQOPIrNAABAgQIECBAgAABAgQIECAgcLgBAgQIECBAgAABAgQIECBAIC8gcORXaAACBAgQIECAAAECBAgQIEBA4HADBAgQIECAAAECBAgQIECAQF5A4Miv0AAECBAgQIAAAQIECBAgQICAwOEGCBAgQIAAAQIECBAgQIAAgbyAwJFfoQEIECBAgAABAgQIECBAgAABgcMNECBAgAABAgQIECBAgAABAnkBgSO/QgMQIECAAAECBAgQIECAAAECAocbIECAAAECBAgQIECAAAECBPICAkd+hQYgQIAAAQIECBAgQIAAAQIEBA43QIAAAQIECBAgQIAAAQIECOQFBI78Cg1AgAABAgQIECBAgAABAgQICBxugAABAgQIECBAgAABAgQIEMgLCBz5FRqAAAECBAgQIECAAAECBAgQEDjcAAECBAgQIECAAAECBAgQIJAXEDjyKzQAAQIECBAgQIAAAQIECBAgIHC4AQIECBAgQIAAAQIECBAgQCAvIHDkV2gAAgQIECBAgAABAgQIECBAQOBwAwQIECBAgAABApMCz8/Pv308Hp/+/tUfPPBf3717980XX3zx+w8fPvzH5OM9igABAgR+cgGB4ycn9w8kQIAAAQIECBD4nwTev3//5dPT0zePx+PP/ojU94/H43cvLy+/J0qAAAECBAQON0CAAAECBAgQIDAj8MOf2vi7/+WD/v7l5eXTn/TwFwECBAj8jAUEjp/x8o1OgAABAgQIEFgS+OFPbvzzZ77pr/1Jjs+U82MECBB4IwICxxtZpDEIECBAgAABAnWB5+fnf3k8Hr/8zDm+f3p6+vLDhw//9pk/78cIECBAIC4gcMQX6PkECBAgQIAAgbcg8Pz8/JvH4/EPr5nl48ePf/vdd9/91Wt+h58lQIAAga6AwNHdnZcTIECAAAECBN6MwPPz89ePx+MvXjnQv7+8vPzilb/DjxMgQIBAVEDgiC7OswkQIECAAAECb0nglf96yn9RPD09/an/dexbugyzECBA4C4gcNytfEmAAAECBAgQIPB/JPD8/Pzxx/jVHz9+/PPvvvvuw4/xu/wOAgQIEGgJCBytfXktAQIECBAgQOBNCggcb3KthiJAgMBPKiBw/KTc/mEECBAgQIAAAQL/nYB/RcVdECBAgMBrBQSO1wr6eQIECBAgQIAAgVcL+I+MvprQLyBAgMDPXkDg+NmfAAACBAgQIECAwP+/wFdfffXrd+/e/eNrXvLu3bu/+fbbb3/3mt/hZwkQIECgKyBwdHfn5QQIECBAgACBNyXw/Pz86T8O+qvPHOr7p6enX/g/qHymnh8jQIDAGxAQON7AEo1AgAABAgQIEHgLAu/fv//y6enpU+T4k8+Y5y9fXl6+/oyf8yMECBAg8EYEBI43skhjECBAgAABAgTegsBnRg5x4y0s3wwECBB4pYDA8UpAP06AAAECBAgQIPDjCvwQOT79aYxf/pHf/P3j8fjty8vLNz/uC/w2AgQIECgKCBzFrXkzAQIECBAgQOBnIPD8/PybTwHj8Xj8+g/+tZV/ejwe3zw9PX3tv7nxMzgEIxIgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIEB+TyDQAAHYZJREFUCBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAAQIECBAgQOAoIHAcoXxGgAABAgQIECBAgAABAgQI7AoIHLu78TICBAgQIECAAAECBAgQIEDgKCBwHKF8RoAAAQIECBAgQIAAAQIECOwKCBy7u/EyAgQIECBAgAABAgQIECBA4CggcByhfEaAAAECBAgQIECAAAECBAjsCggcu7vxMgIECBAgQIAAgf9sxw6JAAAAEIj1b02Fl4h5BDccBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBRwcEQoMQIECBAgQIAAAQIECBAgQOBXwMHxu41mBAgQIECAAAECBAgQIECAQBQYSPdvOfe969kAAAAASUVORK5CYII=","e":1},{"id":"image_6","w":1080,"h":1080,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAQ4CAYAAADsEGyPAAAgAElEQVR4Xuzd35Hb9rkGYHCx93YqiFJBlFvNwtlUEKWC2BVEp4KjVBCdCixXELmCrAWNbo9UQawKYt2LwpmfDtYjrYg/JLgi3+WzM74Sl8T3vJ+d4BUIrCo/BAgQIECAAAECBAgQIECAAIFwgVX48Tt8AgQIECBAgAABAgQIECBAgECl4LAEBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQILK6KqsAACAASURBVECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIAAAQIECBAgQIAAAQIKDjtAgAABAgQIECBAgAABAgQIxAsoOOIjNAABAgQIECBAgAABAgQIECCg4LADBAgQIECAAAECBAgQIECAQLyAgiM+QgMQIECAAAECBAgQIECAAAECCg47QIAAAQIECBAgQIAAAQIECMQLKDjiIzQAAQIECBAgQIAAAQIECBAgoOCwAwQIECBAgAABAgQIECBAgEC8gIIjPkIDECBAgAABAgQIECBAgAABAgoOO0CAAAECBAgQIECAAAECBAjECyg44iM0AAECBAgQIECAAAECBAgQIKDgsAMECBAgQIAAAQIECBAgQIBAvICCIz5CAxAgQIBAssA333zzuOu6yzLDarW6Ojs7e3J1dfVL8kyOnQABAgQIECBwCAEFxyHUfSYBAgQIEKiq6uLi4slqtfrbDYyf2rb9UHhM/TRN821VVeW19/py5OnV1dXPU7/nzwkQIECAAAECd1FAwXEXUzUTAQIECBy9wOXl5dfr9fo/mw50vV7/4eXLl6+Ghuh/96qqqt/feM3bqqq+bdv22dEDOEACBAgQIECAwJ4FFBx7BvV2BAgQIEBgjsDFxcXlarX616bXdl33pxcvXpQCY+NP0zRPq6r668Afv63r+p6vucxJwWsIECBAgACBuySg4LhLaZqFAAECBGIEFhYc3cSg37VtW0oQPwQIECBAgACBkxFQcJxM1AYlQCBZ4MGDB/fPz88flhnevXv3bOzrC8lzntKx32bBsVqt/v78+fPHp+RpVgIECBAgQICAgsMOECBA4MgF+htJfn/jMP0N/ZHnNnV4CwuO8pSVr0Y+w35MBeDPCRAgQIAAgTsnoOC4c5EaiACBuyQwciNK91kID3pJwTHw9JVrEbsRvhsOnwABAgQIENhNQMGxm5vfIkCAwBcRWHIS/EUO0IfsLLA024Ebjb5dr9eXvsK0cyx+kQABAgQIEAgWUHAEh+fQCRC4+wJLT4LvvlDuhPvItrzH2dnZZVHouu7nuq6feXpK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AAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQIECBAgAABAgQIECBAQMFhBwgQIECAAAECBAgQIECAAIF4AQVHfIQGIECAAAECBAgQIECAAAECBBQcdoAAAQIECBAgQIAAAQIECBCIF1BwxEdoAAIECBAgQIAAAQIECBAgQEDBYQcIECBAgAABAgQIECBAgACBeAEFR3yEBiBAgAABAgQIECBAgAABAgQUHHaAAAECBAgQIECAAAECBAgQiBdQcMRHaAACBAgQIECAAAECBAgQIEBAwWEHCBAgQIAAAQIECBAgQIAAgXgBBUd8hAYgQIAAAQIECBAgQIAAAQIEFBx2gAABAgQIECBAgAABAgQIEIgXUHDER2gAAgQI/F87dlADAAADIcy/a3SQVMK6e0GAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwjAafQZAAAH3klEQVQQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvYDAsX+hAwgQIECAAAECBAgQIECAAAGBwwYIECBAgAABAgQIECBAgACBvUCsBGHPV4DBmQAAAABJRU5ErkJggg==","e":1}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"Cup/loading animation.ai","cl":"ai","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"cup shape/loading animation.ai","cl":"ai","td":1,"refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[94.556,94.556,100],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"wave/loading animation.ai","cl":"ai","tt":1,"refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.607,"y":0.595},"o":{"x":0.529,"y":0},"t":0,"s":[660.805,540,0],"to":[-30.035,0,0],"ti":[68.54,0,0]},{"i":{"x":0.507,"y":1},"o":{"x":0.21,"y":0.779},"t":30,"s":[469.965,532,0],"to":[-30.703,0,0],"ti":[13.455,0,0]},{"t":70.0000028511585,"s":[399.866,540,0]}],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"dot 1/loading animation.ai","cl":"ai","refId":"image_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[608,678,0],"ix":2},"a":{"a":0,"k":[608,678,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":10,"s":[131.78,131.78,100]},{"t":20.0000008146167,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"dot 2/loading animation.ai","cl":"ai","refId":"image_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[646,676,0],"ix":2},"a":{"a":0,"k":[646,676,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":25,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":35,"s":[131.78,131.78,100]},{"t":45.0000018328876,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"Dot 3/loading animation.ai","cl":"ai","refId":"image_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[684.966,675.302,0],"ix":2},"a":{"a":0,"k":[684.966,675.302,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":50,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":60,"s":[131.78,131.78,100]},{"t":70.0000028511585,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"text/loading animation.ai","cl":"ai","refId":"image_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":71.0000028918893,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index a942b60..ca76bf8 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -1,11 +1,18 @@
+
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 449df2b..a0dbd7e 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,7 +2,9 @@
#03a9f4
#0288d1
+ #f6f6f6
#ffab40
+ #2c2c2c
#ffc77f
#30000000
@android:color/white
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
new file mode 100644
index 0000000..2291a30
--- /dev/null
+++ b/app/src/main/res/values/ids.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 059db9b..b2a5755 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,5 +1,6 @@
易开发
+ 该功能需要读写内部存储权限,点击前往设置
GuideActivity
Settings
上一步
@@ -11,18 +12,20 @@
无障碍功能已开启
该设备未root,无法开启
基本设置
- 高级功能设置
+ 高级功能
+ 备注
开启无障碍辅助
开启悬浮窗权限
- 推荐开启,用于获取应用数据库等信息,不开启部分信息无法显示,Xposed无法使用
+ 推荐开启,用于获取应用SharedPreference、数据库等数据,关闭后部分信息无法显示
开启root权限
启用Xposed特性
支持脱壳,更多功能持续开发中,点击进入管理
辅助功能用于界面布局分析等
关于
软件开发中,交流群:627962572
- 界面分析
- 点击分析
+ 界面布局
+ 功能需要root权限,请开启后使用!
+ 点击查看
首次安装时间
最后更新时间
守护进程
@@ -36,7 +39,7 @@
恢复
保存失败,请按错误提示修改后再提交
检测到值有修改,是否保存?
- 保存成功,由于缓存原因,新数据重启后才会生效
+ 保存成功,由于缓存原因,新数据重启后才会生效,是否立即重启%1$s?
退出
是否退出应用?
确定
@@ -47,24 +50,23 @@
基本信息
加固类型
正在分析
- 请稍后...
+ 请稍后…
正在获取应用信息
请开启无障碍功能
表
该表数据为空
获取数据库信息失败
- 获取中...
+ 获取中…
数据库列表
无
应用设置
- 备份Apk文件
- 备份data目录
+ 备份应用
+ 还原应用
重启应用
停止应用
清理应用数据
卸载应用
请开启root权限
- 部分功能需要root权限,请打开后使用!
是否清除数据和缓存?
清理完成
是否停止该应用?
@@ -74,13 +76,49 @@
备份失败
备份成功,文件已备份到内部存储下com.wrbug.developerHelper目录中,是否立即分享给好友?
分享失败
- 导出脱壳数据
正在打包文件
导出失败!
- 无脱壳文件
- Xposed设置
- 管理、移除需要脱壳的应用
- 脱壳应用管理
移除该项
请先开启Xposed设置
+ 检查更新
+ 正在检查新版本…
+ 暂无新版本
+ 检查失败…
+ 发现新版本
+ 下载
+ 通知栏常驻
+ 用于进程保活,当应用经常被杀死时,请打开该功能
+ 请选择需要备份的内容,备份所有数据支持无损恢复
+ 正在备份数据
+ 备份失败
+ 跳过该备份
+ 备份正在进行中,请勿关闭该窗口
+ 应用安装包
+ Data目录
+ sdcard/Data目录
+ 备份已完成,您可以前往 %1$s 目录查看备份文件
+ 等待中
+ 打包备份文件
+ 暂无数据
+ %1$d个备份(%2$s)
+ 上一次:%1$s
+ [系统]
+ [未安装]
+ 其他功能
+ 无需备份
+ 备份管理
+ 恢复应用
+ 管理/恢复已备份的应用
+ 已取消
+ %1$s 的备份
+ 删除
+ 恢复
+ 是否删除该备份?
+ 删除备份失败,请重试
+ 选择需要恢复的数据
+ 恢复%1$s
+ 未安装该应用,且apk未备份,无法恢复
+ 当前应用版本[%1$s]与备份版本[%2$s]不一致,备份数据可能不兼容,建议勾选恢复安装包,是否继续
+ 正在恢复%1$s数据
+ 正在启动 %1$s
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ddc3fd5..906b089 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -7,6 +7,7 @@
- @color/colorPrimaryDark
- @color/colorAccent
- @android:color/white
+ - @color/colorWindowBackground
@@ -36,6 +37,25 @@
- @android:color/white
+
+
+
+
+
+
+
+
+
diff --git a/app/src/test/java/com/wrbug/developerhelper/ExampleUnitTest.kt b/app/src/test/java/com/wrbug/developerhelper/ExampleUnitTest.kt
deleted file mode 100644
index 34b59a3..0000000
--- a/app/src/test/java/com/wrbug/developerhelper/ExampleUnitTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.wrbug.developerhelper
-
-import org.junit.Test
-
-import org.junit.Assert.*
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
- @Test
- fun addition_isCorrect() {
- assertEquals(4, 2 + 2)
- }
-}
diff --git a/basecommon/build.gradle b/basecommon/build.gradle
deleted file mode 100644
index 922788e..0000000
--- a/basecommon/build.gradle
+++ /dev/null
@@ -1,41 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlin-kapt'//kapt 插件
-
-android {
- compileSdkVersion 28
-
-
-
- defaultConfig {
- minSdkVersion 21
- targetSdkVersion 28
- versionCode 1
- versionName "1.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-def lifecycle_version = "2.0.0"
-dependencies {
- implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'androidx.appcompat:appcompat:1.0.2'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'com.google.android.material:material:1.1.0-alpha01'
- implementation 'android.arch.lifecycle:extensions:1.1.1'
- annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
- implementation project(':commonutil')
- implementation project(':commonwidget')
-}
-repositories {
- mavenCentral()
-}
diff --git a/basecommon/src/androidTest/java/com/wrbug/developerhelper/basecommon/ExampleInstrumentedTest.java b/basecommon/src/androidTest/java/com/wrbug/developerhelper/basecommon/ExampleInstrumentedTest.java
deleted file mode 100644
index 7e11c97..0000000
--- a/basecommon/src/androidTest/java/com/wrbug/developerhelper/basecommon/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.wrbug.developerhelper.basecommon;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.wrbug.developerhelper.basecommon.test", appContext.getPackageName());
- }
-}
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/AppCompatActivityExt.kt b/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/AppCompatActivityExt.kt
deleted file mode 100644
index e81bde5..0000000
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/AppCompatActivityExt.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.wrbug.developerhelper.basecommon
-
-import androidx.annotation.IdRes
-import androidx.appcompat.app.ActionBar
-import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentTransaction
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProviders
-
-/**
- * Various extension functions for AppCompatActivity.
- */
-
-
-fun AppCompatActivity.setupActionBar(@IdRes toolbarId: Int, action: ActionBar.() -> Unit) {
- setSupportActionBar(findViewById(toolbarId))
- supportActionBar?.run {
- setDisplayHomeAsUpEnabled(false)
- action()
- }
-}
-
-fun AppCompatActivity.obtainViewModel(viewModelClass: Class) =
- ViewModelProviders.of(this).get(viewModelClass)
-
-/**
- * Runs a FragmentTransaction, then calls commit().
- */
-private inline fun FragmentManager.transact(action: FragmentTransaction.() -> Unit) {
- beginTransaction().apply {
- action()
- }.commit()
-}
-
-
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseActivity.kt b/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseActivity.kt
deleted file mode 100644
index 3dd8673..0000000
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/BaseActivity.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.wrbug.developerhelper.basecommon
-
-import android.annotation.TargetApi
-import android.content.pm.PackageManager
-import android.os.Build
-import android.os.Bundle
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import com.google.android.material.snackbar.Snackbar
-import java.util.ArrayList
-
-abstract class BaseActivity : AppCompatActivity() {
- private lateinit var toastRootView: View
- protected lateinit var context: BaseActivity
- private var mPermissionCallback: PermissionCallback? = null
-
- companion object {
- private const val PERMISSION_REQUEST_CODE = 0xAADF1
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- context = this
- super.onCreate(savedInstanceState)
- }
-
- override fun setContentView(layoutResID: Int) {
- toastRootView = layoutInflater.inflate(layoutResID, null)
- setContentView(toastRootView)
- }
-
- fun showSnack(msg: String) {
- Snackbar.make(toastRootView, msg, Snackbar.LENGTH_SHORT).show()
- }
-
- fun showSnack(id: Int) {
- Snackbar.make(toastRootView, id, Snackbar.LENGTH_SHORT).show()
- }
-
-
- @TargetApi(Build.VERSION_CODES.M)
- fun requestPermission(permissions: Array, callback: PermissionCallback) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
- callback.granted()
- return
- }
- val list = ArrayList()
- for (permission in permissions) {
- val hasPermission = checkSelfPermission(permission)
- if (hasPermission != PackageManager.PERMISSION_GRANTED) {
- list.add(permission)
- }
- }
- if (list.isEmpty()) {
- callback.granted()
- return
- }
- mPermissionCallback = callback
- requestPermissions(list.toTypedArray(), PERMISSION_REQUEST_CODE)
- }
-
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
- if (requestCode == PERMISSION_REQUEST_CODE) {
- val list = ArrayList()
- for (i in grantResults.indices) {
- if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
- list.add(permissions[i])
- }
- }
- if (list.isEmpty()) {
- mPermissionCallback?.granted()
- return
- }
- mPermissionCallback?.denied(list)
- return
- }
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- }
-
- abstract class PermissionCallback {
- abstract fun granted()
-
- open fun denied(permissions: List) {
-
- }
- }
-}
\ No newline at end of file
diff --git a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/ToastExts.kt b/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/ToastExts.kt
deleted file mode 100644
index bd5c601..0000000
--- a/basecommon/src/main/java/com/wrbug/developerhelper/basecommon/ToastExts.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.wrbug.developerhelper.basecommon
-
-import android.app.Application
-import android.os.Handler
-import android.os.Looper
-import androidx.annotation.StringRes
-import com.wrbug.developerhelper.commonwidget.flexibletoast.FlexibleToast
-
-//fun Activity.showToast(msg: CharSequence?) {
-// Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
-//
-//}
-
-
-fun showToast(msg: CharSequence) {
- BaseApp.instance.showToast(msg.toString())
-}
-
-fun showToast(@StringRes id: Int) {
- BaseApp.instance.showToast(id)
-}
-
-fun Application.showToast(msg: CharSequence) {
- val appHandler = Handler()
- val flexibleToast = FlexibleToast(this)
- val builder = FlexibleToast.Builder(this).setGravity(FlexibleToast.GRAVITY_BOTTOM)
- builder.setSecondText(msg.toString())
- if (Looper.myLooper() !== Looper.getMainLooper()) {
- appHandler.post { flexibleToast.toastShow(builder) }
- } else {
- flexibleToast.toastShow(builder)
- }
-}
diff --git a/basecommon/src/main/res/values/strings.xml b/basecommon/src/main/res/values/strings.xml
deleted file mode 100644
index 717ea7a..0000000
--- a/basecommon/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- baseCommon
-
diff --git a/basecommon/src/test/java/com/wrbug/developerhelper/basecommon/ExampleUnitTest.java b/basecommon/src/test/java/com/wrbug/developerhelper/basecommon/ExampleUnitTest.java
deleted file mode 100644
index 99a6b24..0000000
--- a/basecommon/src/test/java/com/wrbug/developerhelper/basecommon/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.wrbug.developerhelper.basecommon;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index d875d87..183b457 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,34 +1,11 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
- ext.kotlin_version = '1.3.11'
- ext.gradle_version = '3.2.0'
- repositories {
- google()
- jcenter()
- maven {
- url "https://jitpack.io"
- }
- }
- dependencies {
- classpath "com.android.tools.build:gradle:$gradle_version"
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
- }
-}
-allprojects {
- repositories {
- google()
- jcenter()
- maven {
- url "https://jitpack.io"
- }
- }
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '8.2.2' apply false
+ id 'com.android.library' version '8.2.2' apply false
+ id 'org.jetbrains.kotlin.android' version '1.9.22' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
-}
+}
\ No newline at end of file
diff --git a/common.gradle b/common.gradle
new file mode 100644
index 0000000..a84c948
--- /dev/null
+++ b/common.gradle
@@ -0,0 +1,19 @@
+apply plugin: 'kotlin-parcelize'
+
+android {
+ buildFeatures {
+ viewBinding true
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ lintOptions {
+ abortOnError true
+ disable 'UnusedResources'
+ ignoreWarnings true
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
\ No newline at end of file
diff --git a/commonutil/build.gradle b/commonutil/build.gradle
index b18203f..b39d840 100644
--- a/commonutil/build.gradle
+++ b/commonutil/build.gradle
@@ -1,14 +1,13 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
+apply from: "${rootDir}/common.gradle"
android {
- compileSdkVersion 28
-
-
-
+ namespace "com.wrbug.developerhelper.commonutil"
+ compileSdk 34
defaultConfig {
- minSdkVersion 21
- targetSdkVersion 28
+ minSdkVersion 23
+ targetSdkVersion 34
versionCode 1
versionName "1.0"
@@ -27,19 +26,16 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'com.jaredrummler:android-shell:1.0.0'
- implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0-alpha3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha3'
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation project(':mmkv')
- implementation "org.jetbrains.anko:anko-commons:0.10.8"
- implementation 'com.google.code.gson:gson:2.8.5'
- implementation 'com.elvishew:xlog:1.6.1'
+ api "org.jetbrains.anko:anko-commons:0.10.8"
+ api 'com.google.code.gson:gson:2.8.5'
+ api 'com.elvishew:xlog:1.6.1'
api 'com.squareup.okhttp3:okhttp:3.12.1'
api group: 'org.jsoup', name: 'jsoup', version: '1.11.3'
-}
-repositories {
- mavenCentral()
+ api "io.reactivex.rxjava3:rxjava:3.0.3"
+ api 'io.reactivex.rxjava3:rxandroid:3.0.0'
}
diff --git a/commonutil/src/androidTest/java/com/wrbug/developerhelper/commonutil/ExampleInstrumentedTest.java b/commonutil/src/androidTest/java/com/wrbug/developerhelper/commonutil/ExampleInstrumentedTest.java
deleted file mode 100644
index 87b387b..0000000
--- a/commonutil/src/androidTest/java/com/wrbug/developerhelper/commonutil/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.wrbug.developerhelper.commonutil;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.wrbug.developerhelper.commonutil.test", appContext.getPackageName());
- }
-}
diff --git a/commonutil/src/main/AndroidManifest.xml b/commonutil/src/main/AndroidManifest.xml
index 68282c7..cf5f98d 100644
--- a/commonutil/src/main/AndroidManifest.xml
+++ b/commonutil/src/main/AndroidManifest.xml
@@ -1,2 +1,8 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.wrbug.developerhelper.commonutil">
+
+
+
diff --git a/commonutil/src/main/assets/busybox_arm64 b/commonutil/src/main/assets/busybox_arm64
new file mode 100644
index 0000000..cf9e5be
Binary files /dev/null and b/commonutil/src/main/assets/busybox_arm64 differ
diff --git a/commonutil/src/main/assets/busybox_x86_64 b/commonutil/src/main/assets/busybox_x86_64
new file mode 100755
index 0000000..77523e2
Binary files /dev/null and b/commonutil/src/main/assets/busybox_x86_64 differ
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppInfoManager.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppInfoManager.kt
index ab0b1d1..9cbce45 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppInfoManager.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppInfoManager.kt
@@ -4,13 +4,12 @@ import com.wrbug.developerhelper.commonutil.entity.ApkInfo
import com.wrbug.developerhelper.commonutil.shell.ShellManager
import java.io.File
-object AppInfoManager {
- private val appMap = HashMap()
+object AppInfoManager {
/**
* 获取所有应用
*/
- fun getAllApps(): HashMap {
+ private fun getAllApps(): HashMap {
val apkMap = HashMap()
val pManager = CommonUtils.application.packageManager
// 获取手机内所有应用
@@ -21,18 +20,21 @@ object AppInfoManager {
return apkMap
}
- fun getAppByPackageName(packageName: String): ApkInfo? {
- if (appMap.containsKey(packageName)) {
- return appMap[packageName]
- }
- appMap.putAll(getAllApps())
+ fun isInstalled(packageName: String): Boolean {
+ return getAppByPackageName(packageName) != null
+ }
- return appMap[packageName]
+ fun getAppByPackageName(packageName: String): ApkInfo? {
+ return getAllApps()[packageName]
}
fun getSharedPreferencesFiles(packageName: String): Array {
- val path = "/data/data/$packageName/shared_prefs"
+ return getSharedPreferencesFiles(Constant.dataDir, packageName)
+ }
+
+ private fun getSharedPreferencesFiles(dir: String, packageName: String): Array {
+ val path = "$dir/$packageName/shared_prefs"
val list = ShellManager.lsDir(path)
val files = ArrayList()
for (file in list) {
@@ -46,5 +48,4 @@ object AppInfoManager {
return files.toTypedArray()
}
-
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppManagerUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppManagerUtils.kt
index 1a50b09..06e1e1f 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppManagerUtils.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/AppManagerUtils.kt
@@ -3,6 +3,7 @@ package com.wrbug.developerhelper.commonutil
import android.content.Context
import android.content.Intent
import android.net.Uri
+import android.widget.Toast
import com.wrbug.developerhelper.commonutil.shell.ShellManager
@@ -20,4 +21,18 @@ object AppManagerUtils {
fun forceStopApp(packageName: String): Boolean {
return ShellManager.forceStopApp(packageName)
}
+
+ fun restartApp(context: Context, packageName: String) {
+ if (!forceStopApp(packageName)) {
+ Toast.makeText(context, "重启失败", Toast.LENGTH_SHORT).show()
+ return
+ }
+ startApp(context, packageName)
+ }
+
+ fun startApp(context: Context, packageName: String) {
+ val intent = context.packageManager.getLaunchIntentForPackage(packageName)
+ intent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ context.startActivity(intent)
+ }
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ApplicationLifeCycleCallback.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ApplicationLifeCycleCallback.kt
new file mode 100644
index 0000000..ad4562c
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ApplicationLifeCycleCallback.kt
@@ -0,0 +1,10 @@
+package com.wrbug.developerhelper.commonutil
+
+import android.app.Application
+import android.content.Context
+
+interface ApplicationLifeCycleCallback {
+ fun attachBaseContext(context: Context)
+
+ fun onCreate(application: Application)
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/BundleExt.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/BundleExt.kt
new file mode 100644
index 0000000..0c9706b
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/BundleExt.kt
@@ -0,0 +1,43 @@
+package com.wrbug.developerhelper.commonutil
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.os.Parcelable
+import androidx.core.content.IntentCompat
+import androidx.core.os.BundleCompat
+import java.io.Serializable
+
+
+inline fun Bundle.getParcelableCompat(key: String): T? {
+ return BundleCompat.getParcelable(this, key, T::class.java)
+}
+
+inline fun Bundle.getSerializableCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= 33) {
+ getSerializable(key, T::class.java)
+ } else {
+ getSerializable(key) as T?
+ }
+}
+
+
+inline fun Intent.getSerializableCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= 33) {
+ getSerializableExtra(key, T::class.java)
+ } else {
+ getSerializableExtra(key) as T?
+ }
+}
+
+inline fun Intent.getParcelableCompat(key: String): T? {
+ return IntentCompat.getParcelableExtra(this, key, T::class.java)
+}
+
+inline fun Intent.getParcelableArrayListCompat(key: String): List? {
+ return IntentCompat.getParcelableArrayListExtra(this, key, T::class.java)
+}
+
+inline fun Bundle.getParcelableArrayListCompat(key: String): List? {
+ return BundleCompat.getParcelableArrayList(this, key, T::class.java)
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ClipboardUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ClipboardUtils.kt
index 79e719d..4f54f22 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ClipboardUtils.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ClipboardUtils.kt
@@ -31,7 +31,7 @@ object ClipboardUtils {
try {
val cm = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
// 将文本内容放到系统剪贴板里。
- cm.primaryClip = ClipData.newPlainText(null, text)
+ cm.setPrimaryClip(ClipData.newPlainText(null, text))
} catch (t: Throwable) {
}
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/CommonUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/CommonUtils.kt
index f112bd2..d7430fa 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/CommonUtils.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/CommonUtils.kt
@@ -2,10 +2,41 @@ package com.wrbug.developerhelper.commonutil
import android.app.Application
import android.content.Context
+import com.wrbug.developerhelper.commonutil.entity.CpuABI
+import com.wrbug.developerhelper.commonutil.shell.ShellUtils
+import org.jetbrains.anko.doAsync
+
object CommonUtils {
lateinit var application: Application
fun register(ctx: Context) {
application = ctx.applicationContext as Application
+ releaseBusyBox(ctx)
+ }
+
+ private fun releaseBusyBox(ctx: Context) {
+ doAsync {
+ val name = when (getCPUABI()) {
+ CpuABI.ARM -> "busybox_arm64"
+ CpuABI.X86 -> "busybox_x86_64"
+ }
+ val data = ctx.resources.assets.open(name).readBytes()
+ val file = ShellUtils.busyBoxFile
+ file.writeBytes(data)
+ ShellUtils.run("chmod +x " + file.absolutePath)
+ }
+ }
+
+
+ private fun getCPUABI(): CpuABI {
+ val result = ShellUtils.run("getprop ro.product.cpu.abi")
+ if (result.isSuccessful.not()) {
+ return CpuABI.ARM
+ }
+ return if (result.getStdout().contains("x86")) {
+ CpuABI.X86
+ } else {
+ CpuABI.ARM
+ }
}
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/Constant.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/Constant.kt
new file mode 100644
index 0000000..bb71dcf
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/Constant.kt
@@ -0,0 +1,23 @@
+package com.wrbug.developerhelper.commonutil
+
+import android.os.Build
+
+object Constant {
+ const val ONE_KB = 1024L
+ const val ONE_MB = ONE_KB * 1024
+ const val ONE_GB = ONE_MB * 1024
+ private const val DATA_MIRROR_DIR = "/data_mirror/data_ce/null/0"
+ private const val DATA_DIR = "/data/data"
+
+ fun getDataDir(packageName: String): String {
+ return "$dataDir/$packageName"
+ }
+
+ val dataDir by lazy {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ DATA_MIRROR_DIR
+ } else {
+ DATA_DIR
+ }
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/FileExt.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/FileExt.kt
new file mode 100644
index 0000000..ec660ce
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/FileExt.kt
@@ -0,0 +1,9 @@
+package com.wrbug.developerhelper.commonutil
+
+import java.io.File
+
+fun File.safeRead(): String {
+ return runCatching {
+ readText()
+ }.getOrDefault("")
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/GlobalEvent.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/GlobalEvent.kt
new file mode 100644
index 0000000..23e7cfb
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/GlobalEvent.kt
@@ -0,0 +1,25 @@
+package com.wrbug.developerhelper.commonutil
+
+object GlobalEvent {
+ private val cache = hashMapOf Unit>>()
+
+ fun register(action: Action, bindKey: Any, callback: () -> Unit) {
+ cache[action] = (cache[action] ?: HashMap()).apply {
+ put(bindKey, callback)
+ }
+ }
+
+ fun unRegister(action: Action, bindKey: Any) {
+ cache[action]?.remove(bindKey)
+ }
+
+ fun postEvent(action: Action) {
+ cache[action]?.values?.forEach {
+ it()
+ }
+ }
+
+ enum class Action {
+ CloseAll
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/JsonHelper.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/JsonHelper.kt
index 62be985..0d743bf 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/JsonHelper.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/JsonHelper.kt
@@ -3,6 +3,7 @@ package com.wrbug.developerhelper.commonutil
import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.JsonObject
+import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
@@ -12,6 +13,19 @@ import java.lang.reflect.Type
* @author wrbug
* @since 2017/9/29
*/
+
+fun Any.toJson(): String? {
+ return try {
+ JsonHelper.toJson(this)
+ } catch (t: Throwable) {
+ null
+ }
+}
+
+inline fun String.fromJson(): T? {
+ return JsonHelper.fromJson(this, object : TypeToken() {}.type)
+}
+
object JsonHelper {
val gson = Gson()
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/LogUtilsExt.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/LogUtilsExt.kt
index ef9a1a4..b9acf57 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/LogUtilsExt.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/LogUtilsExt.kt
@@ -1,13 +1,26 @@
package com.wrbug.developerhelper.commonutil
+import com.elvishew.xlog.LogConfiguration
+import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
+import com.elvishew.xlog.internal.DefaultsFactory
import com.wrbug.developerhelper.commonutil.JsonHelper
+private var init = false
fun Any.print() {
+ if (!init) {
+ XLog.init(
+ LogConfiguration.Builder().logLevel(LogLevel.ALL).tag("developerHelper.print-->").build(),
+ DefaultsFactory.createPrinter()
+ )
+ init = true
+ }
+
XLog.i("----------易开发Log----------")
when (this) {
is CharSequence, is Number, is Boolean -> XLog.i(this)
+ is Throwable -> XLog.e(this)
else -> XLog.json(JsonHelper.toJson(this))
}
XLog.i("----------结束----------")
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/NotificationExt.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/NotificationExt.kt
new file mode 100644
index 0000000..cc0d8c7
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/NotificationExt.kt
@@ -0,0 +1,54 @@
+package com.wrbug.developerhelper.commonutil
+
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.core.app.NotificationCompat
+
+
+fun notifyNotification(
+ context: Context,
+ channelId: String,
+ channelName: String,
+ notificationId: Int,
+ block: NotificationCompat.Builder.() -> Unit
+) {
+ val notification = createNotification(context, channelId, channelName, block)
+ val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ manager.notify(notificationId, notification)
+}
+
+
+fun createNotification(
+ context: Context,
+ channelId: String,
+ channelName: String,
+ block: NotificationCompat.Builder.() -> Unit
+): Notification {
+ val builder = NotificationCompat.Builder(context, channelId)
+ block.invoke(builder)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ createNotificationChannel(context, channelId, channelName)
+ }
+ return builder.build()
+}
+
+@RequiresApi(Build.VERSION_CODES.O)
+private fun createNotificationChannel(
+ context: Context,
+ channelId: String,
+ channelName: String
+): NotificationChannel {
+ val notificationManager =
+ context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ val channel =
+ NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ notificationManager.createNotificationChannel(channel)
+ }
+ return channel
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/NumberExts.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/NumberExts.kt
new file mode 100644
index 0000000..ebb50a5
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/NumberExts.kt
@@ -0,0 +1,3 @@
+package com.wrbug.developerhelper.commonutil
+
+fun Int?.toInt(): Int = this ?: 0
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ProcessUtil.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ProcessUtil.kt
new file mode 100644
index 0000000..c8164c7
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ProcessUtil.kt
@@ -0,0 +1,75 @@
+package com.wrbug.developerhelper.commonutil
+
+import android.app.ActivityManager
+import android.content.Context
+import android.os.Process
+import android.text.TextUtils
+
+import java.io.FileInputStream
+import java.io.IOException
+
+object ProcessUtil {
+
+ fun isMainProc(context: Context): Boolean {
+ val myPid = Process.myPid()
+ var procName = readProcName(context, myPid)
+ if (TextUtils.isEmpty(procName)) {
+ procName = readProcName(myPid)
+ }
+ return context.packageName == procName
+ }
+
+
+ fun readProcName(context: Context, myPid: Int): String? {
+ var myProcess: ActivityManager.RunningAppProcessInfo? = null
+ val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ try {
+ val list = activityManager.runningAppProcesses
+ if (list != null) {
+ for (info in list) {
+ if (info.pid == myPid) {
+ myProcess = info
+ break
+ }
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ if (myProcess != null) {
+ return myProcess.processName
+ }
+
+ return null
+ }
+
+ fun readProcName(myPid: Int=Process.myPid()): String? {
+ var fileInputStream: FileInputStream? = null
+ try {
+ fileInputStream = FileInputStream("/proc/$myPid/cmdline")
+ val buffer = ByteArray(128)
+ val len = fileInputStream.read(buffer)
+ if (len <= 0) {
+ return null
+ }
+ var index = 0
+ while (index < buffer.size) {
+ if (buffer[index] > 128 || buffer[index] <= 0) {
+ break
+ }
+ index++
+ }
+ return String(buffer, 0, index)
+ } catch (ignore: Exception) {
+ ignore.printStackTrace()
+ } finally {
+ try {
+ fileInputStream?.close()
+ } catch (ignore: IOException) {
+ }
+
+ }
+ return null
+ }
+}
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ReflectExts.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ReflectExts.kt
new file mode 100644
index 0000000..5066229
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ReflectExts.kt
@@ -0,0 +1,115 @@
+package com.wrbug.developerhelper.commonutil
+import java.lang.reflect.Field
+import java.lang.reflect.Method
+
+fun Class<*>.setValue(obj: Any?, fieldName: String, value: Any?) {
+ this.matchField(fieldName)?.set(obj, value)
+}
+
+fun Class.getValue(obj: T?, fieldName: String): Any? {
+ return this.matchField(fieldName)?.get(obj)
+}
+
+fun Any.getFieldValue(fieldName: String): Any? {
+ return javaClass.getValue(this, fieldName)
+}
+
+fun Any.setFieldValue(fieldName: String, value: Any?) {
+ javaClass.setValue(this, fieldName, value)
+}
+
+fun Any.callMethod(methodName: String, vararg args: Any?): Any? {
+ return this.javaClass.matchMethod(methodName, *args)?.invoke(this, *args)
+}
+
+fun Class.callMethod(obj: T?, methodName: String, vararg args: Any?): Any? {
+ return this.matchMethod(methodName, *args)?.invoke(obj, *args)
+}
+
+fun Class<*>.matchMethod(methodName: String, vararg args: Any?): Method? {
+ return findDeclaredMethod(methodName, *args) ?: findMethod(methodName, *args)
+}
+
+fun Class<*>.matchField(fieldName: String): Field? {
+ return findDeclaredField(fieldName) ?: findField(fieldName)
+}
+
+fun Class<*>.findDeclaredField(fieldName: String): Field? {
+ return runCatching {
+ this.getDeclaredField(fieldName).apply {
+ if (!isAccessible) {
+ isAccessible = true
+ }
+ }
+ }.getOrElse {
+ if (this == Any::class.java) {
+ return null
+ }
+ this.superclass.findDeclaredField(fieldName)
+ }
+}
+
+fun Class<*>.findDeclaredMethod(methodName: String, vararg args: Any?): Method? {
+ val method =
+ this.declaredMethods.asSequence()
+ .filter { it.name == methodName && it.parameterCount == args.size }
+ .find {
+ val size = args.size
+ for (i in 0 until size) {
+ val arg = args[i] ?: continue
+ if (!it.parameterTypes[i].isAssignableFrom(arg.javaClass)) {
+ return@find false
+ }
+ }
+ return@find true
+ }?.apply {
+ if (!isAccessible) {
+ isAccessible = true
+ }
+ }
+ return method ?: if (this == Any::class.java) {
+ null
+ } else {
+ superclass.findDeclaredMethod(methodName, *args)
+ }
+}
+
+fun Class<*>.findField(fieldName: String): Field? {
+ return runCatching {
+ this.getField(fieldName).apply {
+ if (!isAccessible) {
+ isAccessible = true
+ }
+ }
+ }.getOrElse {
+ if (this == Any::class.java) {
+ return null
+ }
+ this.superclass.findField(fieldName)
+ }
+}
+
+fun Class<*>.findMethod(methodName: String, vararg args: Any?): Method? {
+ val method =
+ this.methods.asSequence()
+ .filter { it.name == methodName && it.parameterCount == args.size }
+ .find {
+ val size = args.size
+ for (i in 0..size) {
+ val arg = args[i] ?: continue
+ if (!it.parameterTypes[i].isAssignableFrom(arg.javaClass)) {
+ return@find false
+ }
+ }
+ return@find true
+ }?.apply {
+ if (!isAccessible) {
+ isAccessible = true
+ }
+ }
+ return method ?: if (this == Any::class.java) {
+ null
+ } else {
+ superclass.findDeclaredMethod(methodName, *args)
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/RootUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/RootUtils.kt
new file mode 100644
index 0000000..6f7864a
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/RootUtils.kt
@@ -0,0 +1,9 @@
+package com.wrbug.developerhelper.commonutil
+
+import com.wrbug.developerhelper.mmkv.ConfigKv
+import com.wrbug.developerhelper.mmkv.manager.MMKVManager
+
+object RootUtils {
+ val configKv = MMKVManager.get(ConfigKv::class.java)
+ fun isRoot() = configKv.isOpenRoot()
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/RxJavaExt.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/RxJavaExt.kt
new file mode 100644
index 0000000..4bfefc3
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/RxJavaExt.kt
@@ -0,0 +1,31 @@
+package com.wrbug.developerhelper.commonutil
+
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
+import io.reactivex.rxjava3.core.Single
+import io.reactivex.rxjava3.core.SingleEmitter
+import io.reactivex.rxjava3.core.SingleOnSubscribe
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.disposables.Disposable
+import io.reactivex.rxjava3.schedulers.Schedulers
+
+fun Single.runOnIO(): Single {
+ return this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+}
+
+fun Single.observeOnMain(): Single {
+ return this.observeOn(AndroidSchedulers.mainThread())
+}
+
+fun safeCreateSingle(source: (SingleEmitter) -> Unit): Single {
+ return Single.create { emit ->
+ runCatching {
+ source(emit)
+ }.getOrElse {
+ emit.onError(it)
+ }
+ }
+}
+
+fun Disposable.addTo(compositeDisposable: CompositeDisposable) {
+ compositeDisposable.add(this)
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ShellUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ShellUtils.kt
deleted file mode 100644
index 8c36c0f..0000000
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ShellUtils.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.wrbug.developerhelper.commonutil
-
-import com.jaredrummler.android.shell.CommandResult
-import com.jaredrummler.android.shell.Shell
-import com.wrbug.developerhelper.mmkv.ConfigKv
-import com.wrbug.developerhelper.mmkv.manager.MMKVManager
-import org.jetbrains.anko.doAsync
-
-object ShellUtils {
- val configKv = MMKVManager.get(ConfigKv::class.java)
- fun run(cmds: Array, callback: ShellResultCallback) {
- doAsync {
- val run = Shell.SH.run(*cmds)
- callback.onComplete(run)
- }
- }
-
- fun run(vararg cmds: String): CommandResult {
- return Shell.SH.run(*cmds)
- }
-
- fun runWithSu(cmds: Array, callback: ShellResultCallback) {
- if (!configKv.isOpenRoot()) {
- callback.onError("未开启root权限")
- return
- }
- doAsync {
- val run = Shell.SU.run(*cmds)
- callback.onComplete(run)
- }
- }
-
- fun runWithSuIgnoreSetting(vararg cmds: String): CommandResult {
- return Shell.SU.run(*cmds)
- }
-
-
- fun runWithSu(vararg cmds: String): CommandResult {
- if (configKv.isOpenRoot().not()) {
- return CommandResult(arrayListOf("未开启root权限"), arrayListOf("未开启root权限"), 1)
- }
- return Shell.SU.run(*cmds)
- }
-
- fun isRoot(): Boolean {
- return Shell.SU.available()
- }
-
- abstract class ShellResultCallback(vararg args: Any) {
- protected var args = args
- open fun onComplete(result: CommandResult) {
-
- }
-
- open fun onError(msg: String) {
-
- }
- }
-
-}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/SpannableBuilder.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/SpannableBuilder.kt
new file mode 100644
index 0000000..acd44ff
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/SpannableBuilder.kt
@@ -0,0 +1,125 @@
+package com.wrbug.developerhelper.commonutil
+
+import android.content.Context
+import android.graphics.Typeface
+import android.text.Spannable
+import android.text.SpannableStringBuilder
+import android.text.Spanned
+import android.text.TextPaint
+import android.text.style.ClickableSpan
+import android.text.style.ForegroundColorSpan
+import android.text.style.StrikethroughSpan
+import android.text.style.StyleSpan
+import android.text.style.TextAppearanceSpan
+import android.view.View
+
+class SpannableBuilder private constructor(private val context: Context, private val text: String) {
+
+ private val spanMap = hashMapOf>>()
+
+ companion object {
+ fun with(context: Context, strRes: Int): SpannableBuilder {
+ return SpannableBuilder(context, strRes)
+ }
+
+ fun with(context: Context, text: String): SpannableBuilder {
+ return SpannableBuilder(context, text)
+ }
+ }
+
+ private var strRes: Int = -1
+
+ private constructor(context: Context, strRes: Int) : this(context, "") {
+ this.strRes = strRes
+ }
+
+ fun addSpanWithTextAppearance(
+ value: String,
+ textAppearance: Int,
+ color: Int? = null,
+ index: Int = 0
+ ): SpannableBuilder {
+ addSpan(value, TextAppearanceSpan(context, textAppearance), index)
+ if (color != null) {
+ addSpan(value, ForegroundColorSpan(color), index)
+ }
+ return this
+ }
+
+ fun addSpanWithClickListener(
+ key: String,
+ linkColor: Int,
+ index: Int = 0,
+ listener: () -> Unit
+ ): SpannableBuilder {
+ addSpan(key, object : ClickableSpan() {
+ override fun onClick(widget: View) {
+ listener()
+ }
+
+ override fun updateDrawState(ds: TextPaint) {
+ ds.isUnderlineText = true
+ ds.color = linkColor
+ }
+ }, index)
+ return this
+ }
+
+ fun addSpanWithColor(value: String, color: Int, index: Int = 0): SpannableBuilder {
+ addSpan(value, ForegroundColorSpan(color), index)
+ return this
+ }
+
+
+ fun addSpanWithDeleteLine(value: String, index: Int = 0): SpannableBuilder {
+ addSpan(value, StrikethroughSpan(), index)
+ return this
+ }
+
+ fun addSpanWithBold(value: String, index: Int = 0): SpannableBuilder {
+ addSpan(value, StyleSpan(Typeface.BOLD), index)
+ return this
+ }
+
+ fun addCustomSpan(value: String, what: Any, index: Int = 0): SpannableBuilder {
+ addSpan(value, what, index)
+ return this
+ }
+
+ private fun addSpan(key: String, what: Any, index: Int) {
+ spanMap[key] = (spanMap[key] ?: arrayListOf()).apply { add(index to what) }
+ }
+
+ fun build(): Spannable {
+ val originStr = if (strRes == -1) {
+ text
+ } else {
+ context.getString(strRes)
+ }
+ val spannableBuilder = SpannableStringBuilder(originStr)
+ spanMap.forEach { (key, pair) ->
+ pair.forEach { (index, what) ->
+ val strIndex = index.let {
+ var i = it
+ var currentIndex = 0
+ while (i != 0) {
+ i--
+ currentIndex = originStr.indexOf(key, currentIndex) + key.length
+ }
+ originStr.indexOf(key, currentIndex)
+ }
+ if (strIndex == -1) {
+ return@forEach
+ }
+ spannableBuilder.setSpan(
+ what,
+ strIndex,
+ strIndex + key.length,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ }
+
+ }
+ return spannableBuilder
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringConvertUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringConvertUtils.kt
index 4aca828..4161d02 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringConvertUtils.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringConvertUtils.kt
@@ -2,9 +2,9 @@ package com.wrbug.developerhelper.commonutil
import java.math.BigDecimal
import java.math.BigInteger
+import java.math.RoundingMode
import java.util.regex.Pattern
-
fun String.isInt(): Boolean {
if (isNumber()) {
return BigInteger(this).toLong() < Integer.MAX_VALUE && BigInteger(this).toLong() > Integer.MIN_VALUE
@@ -39,32 +39,48 @@ fun String.toBoolean(): Boolean {
return false
}
-fun String.toInt(): Int {
+fun String?.toInt(): Int {
+ this ?: return 0
if (isInt()) {
return BigInteger(this).toInt()
}
return 0
}
-
-fun String.toLong(): Long {
+fun String?.toLong(): Long {
+ this ?: return 0
if (isNumber()) {
return BigInteger(this).toLong()
}
return 0L
}
-
-fun String.toFloat(): Float {
+fun String?.toFloat(): Float {
+ this ?: return 0F
if (isDecimal()) {
return BigDecimal(this).toFloat()
}
return 0F
}
-fun String.toDouble(): Double {
+fun String?.toDouble(): Double {
+ this ?: return 0.0
if (isDecimal()) {
return BigDecimal(this).toDouble()
}
return 0.0
+}
+
+fun Long.byteToShowSize(): String {
+ if (this >= Constant.ONE_GB) {
+ return (this.toDouble() / Constant.ONE_GB).toBigDecimal()
+ .setScale(2, RoundingMode.HALF_DOWN).toPlainString() + " GB"
+ }
+ if (this >= Constant.ONE_MB) {
+ return (this.toDouble() / Constant.ONE_MB).toBigDecimal()
+ .setScale(2, RoundingMode.HALF_DOWN).toPlainString() + " MB"
+ }
+ return (this.toDouble() / Constant.ONE_KB).toBigDecimal()
+ .setScale(2, RoundingMode.HALF_DOWN).toPlainString() + " KB"
+
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringExt.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringExt.kt
new file mode 100644
index 0000000..5df7270
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/StringExt.kt
@@ -0,0 +1,8 @@
+package com.wrbug.developerhelper.commonutil
+
+fun String?.ifNotEmpty(call: (String) -> String): String {
+ if (isNullOrEmpty()) {
+ return ""
+ }
+ return call(this)
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/UiUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/UiUtils.kt
index be487bf..fe73ddd 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/UiUtils.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/UiUtils.kt
@@ -10,21 +10,17 @@ fun Context.dp2px(dpVal: Float): Int = UiUtils.dp2px(this, dpVal)
fun Fragment.dp2px(dpVal: Float): Int = UiUtils.dp2px(activity!!, dpVal)
fun Dialog.dp2px(dpVal: Float): Int = UiUtils.dp2px(context, dpVal)
fun View.dp2px(dpVal: Float): Int = UiUtils.dp2px(context, dpVal)
+fun Float.dpInt(context: Context) = UiUtils.dp2px(context, this)
+fun Int.dpInt(context: Context = CommonUtils.application) = UiUtils.dp2px(context, toFloat())
object UiUtils {
-
+ private var statusBarHeight: Int = -1
fun dp2px(context: Context = CommonUtils.application, dpVal: Float): Int {
return TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- dpVal,
- context.resources?.displayMetrics
+ TypedValue.COMPLEX_UNIT_DIP, dpVal, context.resources?.displayMetrics
).toInt()
}
- fun sp2px(context: Context = CommonUtils.application, spVal: Float): Int {
- return TypedValue.applyDimension(2, spVal, context.resources?.displayMetrics).toInt()
- }
-
fun px2dp(context: Context = CommonUtils.application, pxVal: Float): Float {
val scale = context.resources?.displayMetrics?.density!!
return pxVal / scale
@@ -54,12 +50,16 @@ object UiUtils {
* 获取状态栏的高度
*/
fun getStatusHeight(context: Context = CommonUtils.application): Int {
+ if (statusBarHeight != -1) {
+ return statusBarHeight
+ }
var result: Int? = 10
val resourceId =
context.resources?.getIdentifier("status_bar_height", "dimen", "android") ?: 0
if (resourceId > 0) {
result = context.resources?.getDimensionPixelOffset(resourceId)
}
- return result ?: 0
+ statusBarHeight = result ?: 0
+ return statusBarHeight
}
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ZipUtil.java b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ZipUtil.java
new file mode 100644
index 0000000..f61ac17
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/ZipUtil.java
@@ -0,0 +1,229 @@
+package com.wrbug.developerhelper.commonutil;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+public class ZipUtil {
+
+ /**
+ * 缓冲器大小
+ */
+ private static final int BUFFER = 512;
+
+ /**
+ * 压缩得到的文件的后缀名
+ */
+ private static final String SUFFIX = ".zip";
+
+ /**
+ * 得到源文件路径的所有文件
+ *
+ * @param dirFile 压缩源文件路径
+ */
+ public static List getAllFile(File dirFile) {
+
+ List fileList = new ArrayList<>();
+
+ File[] files = dirFile.listFiles();
+ for (File file : files) {//文件
+ if (file.isFile()) {
+ fileList.add(file);
+ System.out.println("add file:" + file.getName());
+ } else {//目录
+ if (file.listFiles().length != 0) {//非空目录
+ fileList.addAll(getAllFile(file));//把递归文件加到fileList中
+ } else {//空目录
+ fileList.add(file);
+ System.out.println("add empty dir:" + file.getName());
+ }
+ }
+ }
+ return fileList;
+ }
+
+ /**
+ * 获取相对路径
+ *
+ * @param dirPath 源文件路径
+ * @param file 准备压缩的单个文件
+ */
+ public static String getRelativePath(String dirPath, File file) {
+ File dirFile = new File(dirPath);
+ String relativePath = file.getName();
+
+ while (true) {
+ file = file.getParentFile();
+ if (file == null) break;
+ if (file.equals(dirFile)) {
+ break;
+ } else {
+ relativePath = file.getName() + "/" + relativePath;
+ }
+ }
+ return relativePath;
+ }
+
+
+ /**
+ * @param destPath 解压目标路径
+ * @param fileName 解压文件的相对路径
+ */
+ public static File createFile(String destPath, String fileName) {
+
+ String[] dirs = fileName.split("/");//将文件名的各级目录分解
+ File file = new File(destPath);
+
+ if (dirs.length > 1) {//文件有上级目录
+ for (int i = 0; i < dirs.length - 1; i++) {
+ file = new File(file, dirs[i]);//依次创建文件对象知道文件的上一级目录
+ }
+
+ if (!file.exists()) {
+ file.mkdirs();//文件对应目录若不存在,则创建
+ try {
+ System.out.println("mkdirs: " + file.getCanonicalPath());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ file = new File(file, dirs[dirs.length - 1]);//创建文件
+
+ return file;
+ } else {
+ if (!file.exists()) {//若目标路径的目录不存在,则创建
+ file.mkdirs();
+ try {
+ System.out.println("mkdirs: " + file.getCanonicalPath());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ file = new File(file, dirs[0]);//创建文件
+
+ return file;
+ }
+
+ }
+
+ /**
+ * 没有指定压缩目标路径进行压缩,用默认的路径进行压缩
+ *
+ * @param dirPath 压缩源文件路径
+ */
+ public static void compress(String dirPath) {
+
+ int firstIndex = dirPath.indexOf("/");
+ int lastIndex = dirPath.lastIndexOf("/");
+ String zipFileName = dirPath.substring(0, firstIndex + 1) + dirPath.substring(lastIndex + 1);
+ compress(dirPath, zipFileName);
+ }
+
+ /**
+ * 压缩文件
+ *
+ * @param dirPath 压缩源文件路径
+ * @param zipFileName 压缩目标文件路径
+ */
+ public static void compress(String dirPath, String zipFileName) {
+
+
+ zipFileName = zipFileName + SUFFIX;//添加文件的后缀名
+
+ File dirFile = new File(dirPath);
+ List fileList = getAllFile(dirFile);
+
+ byte[] buffer = new byte[BUFFER];
+ ZipEntry zipEntry = null;
+ int readLength = 0; //每次读取出来的长度
+
+ try {
+ // 对输出文件做CRC32校验
+ CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(
+ zipFileName), new CRC32());
+ ZipOutputStream zos = new ZipOutputStream(cos);
+
+ for (File file : fileList) {
+
+ if (file.isFile()) { //若是文件,则压缩文件
+
+ zipEntry = new ZipEntry(getRelativePath(dirPath, file)); //
+ zipEntry.setSize(file.length());
+ zipEntry.setTime(file.lastModified());
+ zos.putNextEntry(zipEntry);
+
+ InputStream is = new BufferedInputStream(new FileInputStream(file));
+
+ while ((readLength = is.read(buffer, 0, BUFFER)) != -1) {
+ zos.write(buffer, 0, readLength);
+ }
+ is.close();
+ System.out.println("file compress:" + file.getCanonicalPath());
+ } else { //若是空目录,则写入zip条目中
+
+ zipEntry = new ZipEntry(getRelativePath(dirPath, file));
+ zos.putNextEntry(zipEntry);
+ System.out.println("dir compress: " + file.getCanonicalPath() + "/");
+ }
+ }
+ zos.close(); //最后得关闭流,不然压缩最后一个文件会出错
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 解压
+ */
+ public static void decompress(String zipFileName, String destPath) {
+
+ try {
+
+ zipFileName = zipFileName + SUFFIX;
+ ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName));
+ ZipEntry zipEntry = null;
+ byte[] buffer = new byte[BUFFER];//缓冲器
+ int readLength = 0;//每次读出来的长度
+ while ((zipEntry = zis.getNextEntry()) != null) {
+ if (zipEntry.isDirectory()) {//若是目录
+ File file = new File(destPath + "/" + zipEntry.getName());
+ if (!file.exists()) {
+ file.mkdirs();
+ System.out.println("mkdirs:" + file.getCanonicalPath());
+ continue;
+ }
+ }//若是文件
+ File file = createFile(destPath, zipEntry.getName());
+ System.out.println("file created: " + file.getCanonicalPath());
+ OutputStream os = new FileOutputStream(file);
+ while ((readLength = zis.read(buffer, 0, BUFFER)) != -1) {
+ os.write(buffer, 0, readLength);
+ }
+ os.close();
+ System.out.println("file uncompressed: " + file.getCanonicalPath());
+ }
+
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/ApkInfo.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/ApkInfo.kt
index 5e8b861..b7a912c 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/ApkInfo.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/ApkInfo.kt
@@ -3,16 +3,16 @@ package com.wrbug.developerhelper.commonutil.entity
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.graphics.drawable.Drawable
-import android.os.Parcel
import android.os.Parcelable
import com.wrbug.developerhelper.commonutil.CommonUtils
+import kotlinx.parcelize.Parcelize
-class ApkInfo(val packageInfo: PackageInfo, val applicationInfo: ApplicationInfo) : Parcelable {
-
- constructor(parcel: Parcel) : this(
- parcel.readParcelable(PackageInfo::class.java.classLoader),
- parcel.readParcelable(ApplicationInfo::class.java.classLoader)
- )
+@Parcelize
+class ApkInfo(
+ val packageInfo: PackageInfo,
+ val applicationInfo: ApplicationInfo,
+ var topActivity: String = ""
+) : Parcelable {
fun getIco(): Drawable {
return applicationInfo.loadIcon(CommonUtils.application.packageManager)
@@ -20,26 +20,15 @@ class ApkInfo(val packageInfo: PackageInfo, val applicationInfo: ApplicationInfo
fun getAppName(): String {
val label = CommonUtils.application.packageManager.getApplicationLabel(applicationInfo)
- return if (label == null) "" else label.toString()
- }
-
- override fun writeToParcel(parcel: Parcel, flags: Int) {
- parcel.writeParcelable(packageInfo, flags)
- parcel.writeParcelable(applicationInfo, flags)
+ return label.toString()
}
- override fun describeContents(): Int {
- return 0
+ fun isSystemApp(): Boolean {
+ return applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 1
}
- companion object CREATOR : Parcelable.Creator {
- override fun createFromParcel(parcel: Parcel): ApkInfo {
- return ApkInfo(parcel)
- }
-
- override fun newArray(size: Int): Array {
- return arrayOfNulls(size)
- }
+ fun generateBackupApkFileName(): String {
+ return packageInfo.versionName + ".apk"
}
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/CpuABI.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/CpuABI.kt
new file mode 100644
index 0000000..952e1b8
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/CpuABI.kt
@@ -0,0 +1,5 @@
+package com.wrbug.developerhelper.commonutil.entity
+
+enum class CpuABI {
+ ARM,X86
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/FragmentInfo.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/FragmentInfo.kt
index ab23081..cea0527 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/FragmentInfo.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/FragmentInfo.kt
@@ -1,71 +1,23 @@
package com.wrbug.developerhelper.commonutil.entity
-import android.os.Parcel
import android.os.Parcelable
-
-class FragmentInfo() : Parcelable {
- var name = ""
- var fragmentId = ""
- var containerId = ""
- var tag = ""
- var state = 0
- var index = 0
- var who = ""
- var backStackNesting = 0
- var added = false
- var removing = false
- var fromLayout = false
- var inLayout = false
- var hidden = true
- var detached = false
-
- constructor(parcel: Parcel) : this() {
- name = parcel.readString()
- fragmentId = parcel.readString()
- containerId = parcel.readString()
- tag = parcel.readString()
- state = parcel.readInt()
- index = parcel.readInt()
- who = parcel.readString()
- backStackNesting = parcel.readInt()
- added = parcel.readByte() != 0.toByte()
- removing = parcel.readByte() != 0.toByte()
- fromLayout = parcel.readByte() != 0.toByte()
- inLayout = parcel.readByte() != 0.toByte()
- hidden = parcel.readByte() != 0.toByte()
- detached = parcel.readByte() != 0.toByte()
- }
-
- override fun writeToParcel(parcel: Parcel, flags: Int) {
- parcel.writeString(name)
- parcel.writeString(fragmentId)
- parcel.writeString(containerId)
- parcel.writeString(tag)
- parcel.writeInt(state)
- parcel.writeInt(index)
- parcel.writeString(who)
- parcel.writeInt(backStackNesting)
- parcel.writeByte(if (added) 1 else 0)
- parcel.writeByte(if (removing) 1 else 0)
- parcel.writeByte(if (fromLayout) 1 else 0)
- parcel.writeByte(if (inLayout) 1 else 0)
- parcel.writeByte(if (hidden) 1 else 0)
- parcel.writeByte(if (detached) 1 else 0)
- }
-
- override fun describeContents(): Int {
- return 0
- }
-
- companion object CREATOR : Parcelable.Creator {
- override fun createFromParcel(parcel: Parcel): FragmentInfo {
- return FragmentInfo(parcel)
- }
-
- override fun newArray(size: Int): Array {
- return arrayOfNulls(size)
- }
- }
-
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class FragmentInfo(
+ var name: String = "",
+ var containerId: String = "",
+ var tag: String = "",
+ var state: Int = 0,
+ var index: Int = 0,
+ var who: String = "",
+ var backStackNesting: Int = 0,
+ var added: Boolean = false,
+ var removing: Boolean = false,
+ var fromLayout: Boolean = false,
+ var inLayout: Boolean = false,
+ var hidden: Boolean = true,
+ var detached: Boolean = false
+): Parcelable {
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/TopActivityInfo.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/TopActivityInfo.kt
index d5e415a..2dd2b58 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/TopActivityInfo.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/entity/TopActivityInfo.kt
@@ -1,36 +1,22 @@
package com.wrbug.developerhelper.commonutil.entity
-import android.os.Parcel
import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
-class TopActivityInfo() : Parcelable {
- var activity = ""
- var viewIdHex = HashMap()
+@Parcelize
+class TopActivityInfo(
+ var packageName: String = "",
+ var activity: String = "",
var fragments: Array? = null
+): Parcelable {
- constructor(parcel: Parcel) : this() {
- activity = parcel.readString()
- fragments = parcel.createTypedArray(FragmentInfo)
- }
-
- override fun writeToParcel(parcel: Parcel, flags: Int) {
- parcel.writeString(activity)
- parcel.writeTypedArray(fragments, flags)
- }
-
- override fun describeContents(): Int {
- return 0
- }
-
- companion object CREATOR : Parcelable.Creator {
- override fun createFromParcel(parcel: Parcel): TopActivityInfo {
- return TopActivityInfo(parcel)
- }
-
- override fun newArray(size: Int): Array {
- return arrayOfNulls(size)
+ fun setFullActivity(ac: String) {
+ kotlin.runCatching {
+ val arr = ac.split("/")
+ packageName = arr[0]
+ activity = arr[0] + arr[1]
}
}
-
+ var viewIdHex = HashMap()
}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/Callback.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/Callback.kt
deleted file mode 100644
index 4bc41c9..0000000
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/Callback.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.wrbug.developerhelper.commonutil.shell
-
-interface Callback {
- fun onSuccess(data: T)
- fun onFailed(msg: String = "") {}
-}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/CommandResult.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/CommandResult.kt
new file mode 100644
index 0000000..4894b56
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/CommandResult.kt
@@ -0,0 +1,28 @@
+package com.wrbug.developerhelper.commonutil.shell
+
+data class CommandResult(
+ val stdout: List,
+ val stderr: List,
+ val exitCode: Int,
+ val details: Shell.Command.Result.Details?
+) {
+ val isSuccessful: Boolean
+ get() = exitCode == 0
+
+ fun getStdout(): String {
+ return toString(stdout)
+ }
+
+ /**
+ * Get the standard error.
+ *
+ * @return The standard error as a string.
+ */
+ fun getStderr(): String {
+ return toString(stderr)
+ }
+
+ private fun toString(lines: List?): String {
+ return lines?.joinToString("\n").orEmpty()
+ }
+}
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/Shell.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/Shell.kt
new file mode 100644
index 0000000..4841d47
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/Shell.kt
@@ -0,0 +1,826 @@
+package com.wrbug.developerhelper.commonutil.shell
+
+import com.wrbug.developerhelper.commonutil.toInt
+import java.io.BufferedReader
+import java.io.DataOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.InputStreamReader
+import java.io.OutputStream
+import java.util.Collections
+import java.util.UUID
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.locks.ReentrantLock
+import java.util.regex.Pattern
+
+/** Environment variable. */
+typealias Variable = String
+/** Environment variable value. */
+typealias Value = String
+/** A [Map] for the environment variables used in the shell. */
+typealias EnvironmentMap = Map
+
+
+/**
+ * A shell starts a [Process] with the provided shell and additional/optional environment variables.
+ * The shell handles maintaining the [Process] and reads standard output and standard error streams,
+ * returning stdout, stderr, and the last exit code as a [Command.Result] when a command is complete.
+ *
+ * Example usage:
+ *
+ * val sh = Shell("sh")
+ * val result = sh.run("echo 'Hello, World!'")
+ * assert(result.isSuccess)
+ * assert(result.stdout() == "Hello, World")
+ *
+ * @property path The path to the shell to start.
+ * @property environment Map of all environment variables to include with the system environment.
+ * Default value is an empty map.
+ * @throws Shell.NotFoundException If the shell cannot be opened this runtime exception is thrown.
+ * @author Jared Rummler (jaredrummler@gmail.com)
+ * @since 05-05-2021
+ */
+class Shell @Throws(NotFoundException::class) @JvmOverloads constructor(
+ val path: String,
+ val environment: EnvironmentMap = emptyMap()
+) {
+
+
+ /**
+ * Construct a new [Shell] with optional environment variable arguments as a [Pair].
+ *
+ * @param shell The path to the shell to start.
+ * @param environment varargs of all environment variables as a [Pair] which are included
+ * with the system environment.
+ */
+ constructor(shell: String, vararg environment: Pair) :
+ this(shell, environment.toEnvironmentMap())
+
+ /**
+ * Construct a new [Shell] with optional environment variable arguments as an array.
+ *
+ * @param shell The path to the shell to start.
+ * @param environment varargs of all environment variables as a [Pair] which are included
+ * with the system environment.
+ */
+ constructor(shell: String, environment: Array) :
+ this(shell, environment.toEnvironmentMap())
+
+ /**
+ * Get the current state of the shell
+ */
+ var state: State = State.Idle
+ private set
+
+ private val onResultListeners = mutableSetOf()
+ private val onStdOutListeners = mutableSetOf()
+
+ private val onStdErrListeners = mutableSetOf()
+ private val stdin: StandardInputStream
+ private val stdoutReader: StreamReader
+ private val stderrReader: StreamReader
+ private var watchdog: Watchdog? = null
+
+ private val process: Process
+
+ init {
+ try {
+ process = runWithEnv(path, environment)
+ stdin = StandardInputStream(process.outputStream)
+ stdoutReader = StreamReader.createAndStart(THREAD_NAME_STDOUT, process.inputStream)
+ stderrReader = StreamReader.createAndStart(THREAD_NAME_STDERR, process.errorStream)
+ } catch (cause: Exception) {
+ throw NotFoundException(String.format(EXCEPTION_SHELL_CANNOT_OPEN, path), cause)
+ }
+ }
+
+ /**
+ * Add a listener that will be invoked each time a command finishes.
+ *
+ * @param listener The listener to receive callbacks when commands finish executing.
+ * @return This shell instance for chaining calls.
+ */
+ fun addOnCommandResultListener(listener: OnCommandResultListener) = apply {
+ onResultListeners.add(listener)
+ }
+
+ /**
+ * Remove a listener previously added to stop receiving callbacks when commands finish.
+ *
+ * @param listener The listener registered via [addOnCommandResultListener].
+ * @return This shell instance for chaining calls.
+ */
+ fun removeOnCommandResultListener(listener: OnCommandResultListener) = apply {
+ onResultListeners.remove(listener)
+ }
+
+ /**
+ * Add a listener that will be invoked each time the STDOUT stream reads a new line.
+ *
+ * @param listener The listener to receive callbacks when the STDOUT stream reads a line.
+ * @return This shell instance for chaining calls.
+ */
+ fun addOnStdoutLineListener(listener: OnLineListener) = apply {
+ onStdOutListeners.add(listener)
+ }
+
+ /**
+ * Remove a listener previously added to stop receiving callbacks for STDOUT read lines.
+ *
+ * @param listener The listener registered via [addOnStdoutLineListener].
+ * @return This shell instance for chaining calls.
+ */
+ fun removeOnStdoutLineListener(listener: OnLineListener) = apply {
+ onStdOutListeners.remove(listener)
+ }
+
+ /**
+ * Add a listener that will be invoked each time the STDERR stream reads a new line.
+ *
+ * @param listener The listener to receive callbacks when the STDERR stream reads a line.
+ * @return This shell instance for chaining calls.
+ */
+ fun addOnStderrLineListener(listener: OnLineListener) = apply {
+ onStdErrListeners.add(listener)
+ }
+
+ /**
+ * Remove a listener previously added to stop receiving callbacks for STDERR read lines.
+ *
+ * @param listener The listener registered via [addOnStderrLineListener].
+ * @return This shell instance for chaining calls.
+ */
+ fun removeOnStderrLineListener(listener: OnLineListener) = apply {
+ onStdErrListeners.remove(listener)
+ }
+
+ /**
+ * Run a command in the current shell and return its [result][Command.Result].
+ *
+ * @param command The command to execute.
+ * @param config The [options][Command.Config] to set when running the command.
+ * @return The [result][Command.Result] containing stdout, stderr, status of running the command.
+ * @throws ClosedException if the shell was closed prior to running the command.
+ * @see shutdown
+ * @see run
+ */
+ @Throws(ClosedException::class)
+ @Synchronized
+ fun run(
+ command: String,
+ config: Command.Config.Builder.() -> Unit,
+ ) = run(command, Command.Config.Builder().apply(config).create())
+
+ /**
+ * Run a command in the current shell and return its [result][Command.Result].
+ *
+ * @param command The command to execute.
+ * @param config The [options][Command.Config] to set when running the command.
+ * @return The [result][Command.Result] containing stdout, stderr, status of running the command.
+ * @throws ClosedException if the shell was closed prior to running the command.
+ * @see shutdown
+ * @see run
+ */
+ @Throws(ClosedException::class)
+ @Synchronized
+ @JvmOverloads
+ fun run(
+ command: String,
+ config: Command.Config = Command.Config.default(),
+ ): Command.Result {
+ // If the shell is shutdown, throw a ShellClosedException.
+ if (state == State.Shutdown) throw ClosedException(EXCEPTION_SHELL_SHUTDOWN)
+
+ val stdout = Collections.synchronizedList(mutableListOf())
+ val stderr = Collections.synchronizedList(mutableListOf())
+
+ val watchdog = Watchdog().also { watchdog = it }
+ var exitCode = Command.Status.INVALID
+ val uuid = config.uuid
+
+ val onComplete = { marker: Command.Marker ->
+ when (marker.uuid) {
+ uuid ->
+ try { // Reached the end of reading the stream for the command.
+ if (marker.status != Command.Status.INVALID) {
+ exitCode = marker.status
+ }
+ } finally {
+ watchdog.signal()
+ }
+ }
+ }
+
+ val lock = ReentrantLock()
+ val output = Collections.synchronizedList(mutableListOf())
+
+ // Function to process stderr and stdout streams.
+ fun onLine(
+ buffer: MutableList,
+ listeners: Set,
+ onLine: (line: String) -> Unit,
+ ) = { line: String ->
+ try {
+ lock.lock()
+ if (config.notify) {
+ listeners.forEach { listener -> listener.onLine(line) }
+ }
+ buffer.add(line)
+ output.add(line)
+ onLine(line)
+ } finally {
+ lock.unlock()
+ }
+ }
+
+ stdoutReader.onComplete = onComplete
+ stderrReader.onComplete = onComplete
+ stdoutReader.onReadLine = onLine(stdout, onStdOutListeners, config.onStdOut)
+ stderrReader.onReadLine = when (config.redirectStdErr) {
+ true -> onLine(stdout, onStdOutListeners, config.onStdOut)
+ else -> onLine(stderr, onStdErrListeners, config.onStdErr)
+ }
+
+ val startTime = System.currentTimeMillis()
+ try {
+ state = State.Running
+ // Write the command and command end marker to stdin.
+ write(command, "echo '$uuid' $?", "echo '$uuid' >&2")
+ // Wait for the result with a timeout, if provided.
+ if (!watchdog.await(config.timeout)) {
+ exitCode = Command.Status.TIMEOUT
+ config.onTimeout()
+ }
+ } catch (e: InterruptedException) {
+ exitCode = Command.Status.TERMINATED
+ config.onCancelled()
+ } finally {
+ this.watchdog = null
+ state = State.Idle
+ }
+
+ if (exitCode != Command.Status.SUCCESS) {
+ // Exit with the error code in a subshell
+ // This is necessary because we send commands to signal a command was completed
+ write("$(exit $exitCode)")
+ }
+
+ // Create the result from running the command.
+ val result = Command.Result.create(
+ uuid,
+ command,
+ stdout,
+ stderr,
+ output,
+ exitCode,
+ startTime
+ )
+
+ if (config.notify) {
+ onResultListeners.forEach { listener ->
+ listener.onResult(result)
+ }
+ }
+
+ return result
+ }
+
+ /**
+ * Check if the shell is idle.
+ *
+ * @return True if the shell is open but not running any commands.
+ */
+ fun isIdle() = state is State.Idle
+
+ /**
+ * Check if the shell is running a command.
+ *
+ * @return True if the shell is executing a command.
+ */
+ fun isRunning() = state is State.Running
+
+ /**
+ * Check if the shell is shutdown.
+ *
+ * @return True if the shell is closed.
+ * @see shutdown
+ */
+ fun isShutdown() = state is State.Shutdown
+
+ /**
+ * Check if the shell is alive and able to execute commands.
+ *
+ * @return True if the shell is running or idle.
+ */
+ fun isAlive() = try {
+ process.exitValue(); false
+ } catch (e: IllegalThreadStateException) {
+ true
+ }
+
+ /**
+ * Interrupt waiting for a command to complete.
+ */
+ fun interrupt() {
+ watchdog?.abort()
+ }
+
+ /**
+ * Shutdown the shell instance. After a shell is shutdown it can no longer execute commands
+ * and should be garbage collected.
+ */
+ @Synchronized
+ fun shutdown() {
+ try {
+ write("exit")
+ process.waitFor()
+ stdin.closeQuietly()
+ onStdOutListeners.clear()
+ onStdErrListeners.clear()
+ stdoutReader.join()
+ stderrReader.join()
+ process.destroy()
+ } catch (ignored: IOException) {
+ } finally {
+ state = State.Shutdown
+ }
+ }
+
+ private fun write(vararg commands: String) = try {
+ commands.forEach { command -> stdin.write(command) }
+ stdin.flush()
+ } catch (ignored: IOException) {
+ }
+
+ private fun DataOutputStream.closeQuietly() = try {
+ close()
+ } catch (ignored: IOException) {
+ }
+
+ /**
+ * Contains data classes used for running commands in a [Shell].
+ *
+ * @see Command.Result
+ * @see Command.Config
+ * @see Command.Status
+ */
+ object Command {
+
+ /**
+ * The result of running a command in a shell.
+ *
+ * @property stdout A list of lines read from the standard input stream.
+ * @property stderr A list of lines read from the standard error stream.
+ * @property exitCode The status code of running the command.
+ * @property details Additional command result details.
+ */
+ data class Result(
+ val stdout: List,
+ val stderr: List,
+ val output: List,
+ val exitCode: Int,
+ val details: Details?
+ ) {
+
+ /**
+ * True when the exit code is equal to 0.
+ */
+ val isSuccess: Boolean get() = exitCode == Status.SUCCESS
+
+ /**
+ * Get [stdout] and [stderr] as a string, separated by new lines.
+ *
+ * @return The output of running the command in a shell.
+ */
+ fun output(): String = output.joinToString("\n")
+
+ /**
+ * Get [stdout] as a string, separated by new lines.
+ *
+ * @return The standard ouput string.
+ */
+ fun stdout(): String = stdout.joinToString("\n")
+
+ /**
+ * Get [stdout] as a string, separated by new lines.
+ *
+ * @return The standard ouput string.
+ */
+ fun stderr(): String = stderr.joinToString("\n")
+
+ /**
+ * Additional details pertaining to running a command in a shell.
+ *
+ * @property uuid The unique identifier associated with the command.
+ * @property command The command sent to the shell to execute.
+ * @property startTime The time—in milliseconds since January 1, 1970, 00:00:00 GMT—when
+ * the command started execution.
+ * @property endTime The time—in milliseconds since January 1, 1970, 00:00:00 GMT—when
+ * the command completed execution.
+ * @property elapsed The number of milliseconds it took to execute the command.
+ */
+ data class Details internal constructor(
+ val uuid: UUID,
+ val command: String,
+ val startTime: Long,
+ val endTime: Long,
+ val elapsed: Long = endTime - startTime
+ )
+
+ companion object {
+ internal fun create(
+ uuid: UUID,
+ command: String,
+ stdout: List,
+ stderr: List,
+ output: List,
+ exitCode: Int,
+ startTime: Long,
+ endTime: Long = System.currentTimeMillis(),
+ ) = Result(
+ stdout,
+ stderr,
+ output,
+ exitCode,
+ Details(uuid, command, startTime, endTime)
+ )
+ }
+ }
+
+ /**
+ * Optional configuration settings when running a command in a [shell][Shell].
+ *
+ * @property uuid The unique identifier associated with the command.
+ * @property redirectStdErr True to redirect STDERR to STDOUT.
+ * @property onStdOut Callback that is invoked when reading a line from stdout.
+ * @property onStdErr Callback that is invoked when reading a line from stderr.
+ * @property onCancelled Callback that is invoked when the command is interrupted.
+ * @property onTimeout Callback that is invoked when the command timed-out.
+ * @property timeout The time to wait before killing the command.
+ * @property notify True to notify any [OnLineListener] and [OnCommandResultListener] of the command.
+ */
+ class Config private constructor(
+ val uuid: UUID = UUID.randomUUID(),
+ val redirectStdErr: Boolean = false,
+ val onStdOut: (line: String) -> Unit = {},
+ val onStdErr: (line: String) -> Unit = {},
+ val onCancelled: () -> Unit = {},
+ val onTimeout: () -> Unit = {},
+ val timeout: Timeout? = null,
+ val notify: Boolean = true
+ ) {
+
+ /**
+ * Optional configuration settings when running a command in a [shell][Shell].
+ *
+ * @property uuid The unique identifier associated with the command.
+ * @property redirectErrorStream True to redirect STDERR to STDOUT.
+ * @property onStdOut Callback that is invoked when reading a line from stdout.
+ * @property onStdErr Callback that is invoked when reading a line from stderr.
+ * @property onCancelled Callback that is invoked when the command is interrupted.
+ * @property onTimeout Callback that is invoked when the command timed-out.
+ * @property timeout The time to wait before killing the command.
+ * @property notify True to notify any [OnLineListener] and [OnCommandResultListener] of the command.
+ */
+ class Builder {
+ var uuid: UUID = UUID.randomUUID()
+ var redirectErrorStream = false
+ var onStdOut: (line: String) -> Unit = {}
+ var onStdErr: (line: String) -> Unit = {}
+ var onCancelled: () -> Unit = {}
+ var onTimeout: () -> Unit = {}
+ var timeout: Timeout? = null
+ var notify = true
+
+ /**
+ * Create the [Config] from this builder.
+ *
+ * @return A new [Config] for a command.
+ */
+ fun create() =
+ Config(
+ uuid,
+ redirectErrorStream,
+ onStdOut,
+ onStdErr,
+ onCancelled,
+ onTimeout,
+ timeout,
+ notify
+ )
+ }
+
+ companion object {
+
+ /**
+ * The default configuration for running a command in a shell.
+ *
+ * @return The default config.
+ */
+ fun default(): Config = Builder().create()
+
+ /**
+ * Config that doesn't invoke callbacks for line and command complete listeners.
+ */
+ fun silent(): Config = Builder().apply { notify = false }.create()
+ }
+ }
+
+ /**
+ * The command marker to process standard input/error streams.
+ *
+ * @property uuid The unique ID for a command.
+ * @property status the exit code for the last run command.
+ */
+ internal data class Marker(val uuid: UUID, val status: Int)
+
+ /** Exit codes */
+ object Status {
+ /** OK exit code value */
+ const val SUCCESS = 0
+
+ /** Command timeout exit status */
+ const val TIMEOUT = 124
+
+ /** Command failed exit status */
+ const val COMMAND_FAILED = 125
+
+ /** Command not executable exit status */
+ const val NOT_EXECUTABLE = 126
+
+ /** Command not found exit status */
+ const val NOT_FOUND = 127
+
+ /** Command terminated exit status. */
+ const val TERMINATED = 128 + 30
+ internal const val INVALID = 0x100
+ }
+ }
+
+ /**
+ * Interface to receive a callback when reading a line from standard output/error streams.
+ */
+ interface OnLineListener {
+
+ /**
+ * Called when a line was read from standard output/error streams
+ *
+ * @param line The string that was read.
+ */
+ fun onLine(line: String)
+ }
+
+ /**
+ * Interface to receive a callback when a command completes.
+ */
+ interface OnCommandResultListener {
+
+ /**
+ * Called when a command finishes running.
+ *
+ * @param result The result of running the command in a shell.
+ */
+ fun onResult(result: Command.Result)
+ }
+
+ /**
+ * A timeout used when running a command in a shell.
+ *
+ * @property value The value of the time based on the [unit].
+ * @property unit The time unit for the [value].
+ */
+ data class Timeout(val value: Long, val unit: TimeUnit)
+
+ /**
+ * The exception thrown when a command is passed to a closed shell.
+ */
+ class ClosedException(message: String) : IOException(message)
+
+ /**
+ * The exception thrown when the shell could not be opened.
+ */
+ class NotFoundException(message: String, cause: Throwable) : RuntimeException(message, cause)
+
+ /**
+ * Represents the possible states of the shell.
+ */
+ sealed class State {
+ /** The shell is idle; no commands are in progress. */
+ object Idle : State()
+
+ /** The shell is currently running a command. */
+ object Running : State()
+
+ /** The shell has been shutdown. */
+ object Shutdown : State()
+ }
+
+ /**
+ * A class to cause the current thread to wait until a command completes or is aborted.
+ */
+ private class Watchdog : CountDownLatch(STREAM_READER_COUNT) {
+
+ private var aborted = false
+
+ /**
+ * Releases the thread immediately instead of waiting for [signal] to be invoked twice.
+ */
+ fun abort() {
+ if (count == 0L) return
+ aborted = true
+ while (count > 0) countDown()
+ }
+
+ /**
+ * Signal that either standard output or standard input streams are finished processing.
+ */
+ fun signal() = countDown()
+
+ /**
+ * Causes the current thread to wait until [signal] is called twice.
+ *
+ * @param timeout The maximum time to wait before [AbortedException] is thrown.
+ * @throws AbortedException if the timeout completes before [signal] is called twice
+ * or if the thread is interrupted.
+ */
+ @Throws(AbortedException::class)
+ fun await(timeout: Timeout?): Boolean {
+ return when (timeout) {
+ null -> {
+ await(); true
+ }
+
+ else -> await(timeout.value, timeout.unit)
+ }
+ }
+
+ override fun await() = super.await().also {
+ if (aborted) throw AbortedException()
+ }
+
+ override fun await(timeout: Long, unit: TimeUnit) = super.await(timeout, unit).also {
+ if (aborted) throw AbortedException()
+ }
+
+ companion object {
+ /**
+ * The number of times [signal] should be called to release the latch.
+ */
+ private const val STREAM_READER_COUNT = 2
+
+ /**
+ * The exception thrown when [abort] is called and the [CountDownLatch] has not finished
+ */
+ class AbortedException : InterruptedException()
+ }
+ }
+
+ /**
+ * The [OutputStream] for writing commands to the shell.
+ */
+ private class StandardInputStream(stream: OutputStream) : DataOutputStream(stream) {
+
+ /**
+ * The helper function to write commands to the stream with an appended new line character.
+ *
+ * @param command The command to write.
+ */
+ fun write(command: String) = write("$command\n".toByteArray(Charsets.UTF_8))
+ }
+
+ /**
+ * A thread that parses the standard/error streams for the shell.
+ *
+ * @param name The name of the stream. One of: [THREAD_NAME_STDOUT], [THREAD_NAME_STDERR]
+ * @param stream Either the [Process.getInputStream] or [Process.getErrorStream]
+ */
+ private class StreamReader private constructor(
+ name: String,
+ private val stream: InputStream
+ ) : Thread(name) {
+
+ /**
+ * The lambda that is invoked when a line is read from the stream.
+ */
+ var onReadLine: (line: String) -> Unit = {}
+
+ /**
+ * The lambda that is invoked when a command completes.
+ */
+ var onComplete: (marker: Command.Marker) -> Unit = {}
+
+ override fun run() = BufferedReader(InputStreamReader(stream)).forEachLine { line ->
+ pattern.matcher(line).let { matcher ->
+ if (matcher.matches()) {
+ val uuid = UUID.fromString(matcher.group(GROUP_UUID))
+ onComplete(
+ when (val exitCode = matcher.group(GROUP_CODE)) {
+ null -> Command.Marker(uuid, Command.Status.INVALID)
+ else -> Command.Marker(uuid, exitCode.toInt())
+ }
+ )
+ } else {
+ onReadLine(line)
+ }
+ }
+ }
+
+ companion object {
+
+ private const val GROUP_UUID = 1
+
+ private const val GROUP_CODE = 2
+
+ //
+ private val pattern: Pattern = Pattern.compile(
+ "^([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})\\s?([0-9]{1,3})?$",
+ Pattern.CASE_INSENSITIVE
+ )
+
+ internal fun createAndStart(name: String, stream: InputStream) =
+ StreamReader(name, stream).also { reader -> reader.start() }
+ }
+ }
+
+ companion object {
+
+ private const val THREAD_NAME_STDOUT = "STDOUT"
+ private const val THREAD_NAME_STDERR = "STDERR"
+
+ private const val EXCEPTION_SHELL_CANNOT_OPEN = "Error opening shell: '%s'"
+ private const val EXCEPTION_SHELL_SHUTDOWN = "The shell is shutdown"
+ private val instances by lazy { mutableMapOf() }
+
+ /**
+ * Returns a [Shell] instance using the [path] as the path to the shell/executable.\
+ */
+ operator fun get(path: String): Shell = instances[path]?.takeIf { shell ->
+ shell.isAlive()
+ } ?: Shell(path).also { shell ->
+ instances[path] = shell
+ }
+
+ /** The Bourne shell (sh) */
+ val SH: Shell get() = this["sh"]
+
+ /** Switch to root, and run it as a shell */
+ val SU: Shell get() = this["su"]
+
+ /**
+ * Execute a command with the provided environment.
+ *
+ * @param command
+ * The name of the program to execute. E.g. "su" or "sh".
+ * @param environment
+ * Map of all environment variables to include with the system environment.
+ * @return The new [Process] instance.
+ * @throws IOException
+ * If the requested program could not be executed.
+ */
+ @Throws(IOException::class)
+ private fun runWithEnv(command: String, environment: EnvironmentMap): Process =
+ Runtime.getRuntime().exec(command, (System.getenv() + environment).toArray())
+
+ /**
+ * Convert an array to an [EnvironmentMap] with each variable/value separated by '='.
+ *
+ * @return The array converted to an [EnvironmentMap].
+ */
+ private fun Array.toEnvironmentMap(): EnvironmentMap =
+ mutableMapOf().also { map ->
+ forEach { str ->
+ str.split("=").takeIf { arr ->
+ arr.size == 2
+ }?.let { (variable, value) ->
+ map[variable] = value
+ }
+ }
+ }.toMap()
+
+ /**
+ * Convert an array of [Pair] to an [EnvironmentMap].
+ *
+ * @return The array of variable/value pairs as a new [EnvironmentMap].
+ */
+ private fun Array>.toEnvironmentMap(): EnvironmentMap =
+ mutableMapOf().also { map ->
+ forEach { (variable, value) ->
+ map[variable] = value
+ }
+ }
+
+ /**
+ * Converts an [EnvironmentMap] to an array of strings with the variable/value
+ * separated by an '=' character.
+ *
+ * @return An array of environment variables.
+ */
+ private fun EnvironmentMap.toArray(): Array =
+ mutableListOf().also { list ->
+ forEach { (variable, value) ->
+ list.add("$variable=$value")
+ }
+ }.toTypedArray()
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellException.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellException.kt
new file mode 100644
index 0000000..7c6f82b
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellException.kt
@@ -0,0 +1,4 @@
+package com.wrbug.developerhelper.commonutil.shell
+
+class ShellException(message: String) : Exception(message) {
+}
\ No newline at end of file
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellManager.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellManager.kt
index 801eb3c..f798ae2 100644
--- a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellManager.kt
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellManager.kt
@@ -1,18 +1,20 @@
package com.wrbug.developerhelper.commonutil.shell
-import com.jaredrummler.android.shell.CommandResult
-import com.wrbug.developerhelper.commonutil.CommonUtils
-import com.wrbug.developerhelper.commonutil.ShellUtils
-import com.wrbug.developerhelper.commonutil.entity.FragmentInfo
+import com.wrbug.developerhelper.commonutil.Constant
import com.wrbug.developerhelper.commonutil.entity.LsFileInfo
import com.wrbug.developerhelper.commonutil.entity.TopActivityInfo
+import com.wrbug.developerhelper.commonutil.ifNotEmpty
+import com.wrbug.developerhelper.commonutil.runOnIO
+import io.reactivex.rxjava3.core.Single
import java.io.File
import java.util.regex.Pattern
-
object ShellManager {
+
private const val SHELL_TOP_ACTIVITY = "dumpsys activity top"
- private const val SHELL_PROCESS_PID_1 = "ps -ef | grep \"%1\$s\" | grep -v %1\$s:| grep -v grep | awk '{print \$2}'"
+ private const val SHELL_APP_ACTIVITY = "dumpsys activity %1\$s"
+ private const val SHELL_PROCESS_PID_1 =
+ "ps -ef | grep \"%1\$s\" | grep -v %1\$s:| grep -v grep | awk '{print \$2}'"
private const val SHELL_PROCESS_PID_2 = "top -b -n 1 |grep %1\$s |grep -v grep|grep -v %1\$s:"
private const val SHELL_PROCESS_PID_3 = "top -n 1 |grep %1\$s |grep -v grep|grep -v %1\$s:"
private var SHELL_OPEN_ACCESSiBILITY_SERVICE = arrayOf(
@@ -20,27 +22,24 @@ object ShellManager {
"settings put secure accessibility_enabled 1"
)
private const val SHELL_LS_FILE = "ls -l %1\$s"
- private const val SHELL_GET_ZIP_FILE_LIST =
- "app_process -Djava.class.path=/data/local/tmp/zip.dex /data/local/tmp Zip %s"
private const val SHELL_CHECK_IS_SQLITE = "od -An -tx %1\$s |grep '694c5153'"
private const val SHELL_UNINSTALL_APP = "pm uninstall %1\$s"
private const val SHELL_CLEAR_APP_DATA = "pm clear %1\$s"
private const val SHELL_FORCE_STOP_APP = "am force-stop %1\$s"
- private val SHELL_OPEN_ADB_WIFI = arrayOf("setprop service.adb.tcp.port 5555", "stop adbd", "start adbd")
- fun getTopActivity(callback: Callback) {
- ShellUtils.runWithSu(arrayOf(SHELL_TOP_ACTIVITY), object : ShellUtils.ShellResultCallback() {
- override fun onComplete(result: CommandResult) {
- callback.onSuccess(getTopActivity(result))
- }
+ private val SHELL_OPEN_ADB_WIFI =
+ arrayOf("setprop service.adb.tcp.port 5555", "stop adbd", "start adbd")
- override fun onError(msg: String) {
- callback.onSuccess(null)
- }
- })
+ fun getTopActivity(): Single {
+ return ShellUtils.runWithSuAsync(SHELL_TOP_ACTIVITY, useBusyBox = false).map {
+ getTopActivity(it)
+ }.runOnIO()
+ }
+ private fun tabCount(str: String): Int {
+ return (str.length - str.trimStart().length) / 2
}
- fun getTopActivity(result: CommandResult): TopActivityInfo {
+ private fun getTopActivity(result: CommandResult): TopActivityInfo {
val stdout = result.getStdout()
val topActivityInfo = TopActivityInfo()
val task_s = stdout.split("TASK ")
@@ -50,10 +49,9 @@ object ShellManager {
val pattern = Pattern.compile(regex)
val matcher = pattern.matcher(task_)
if (matcher.find()) {
- topActivityInfo.activity = matcher.group().split(" ")[1]
+ topActivityInfo.setFullActivity(matcher.group().split(" ")[1])
}
- val split =
- task_.split("\n[ ]{4}[A-Z]".toRegex()).dropLastWhile { it.isEmpty() }
+ val split = task_.split("\n[ ]{4}[A-Z]".toRegex()).dropLastWhile { it.isEmpty() }
for (s in split) {
if (s.contains("iew Hierarchy")) {
for (s1 in s.split("\n".toRegex()).dropLastWhile { it.isEmpty() }) {
@@ -65,67 +63,9 @@ object ShellManager {
continue
}
topActivityInfo.viewIdHex[split1[5].substring(split1[5].indexOf("id/"))] =
- split1[4]
- }
- }
- } else if (s.contains("ocal Activity")) {
- } else if (s.contains("ctive Fragments")) {
- val list = ArrayList()
- val split2 =
- s.split("\n {6}#[0-9]+:".toRegex()).filterNot { it.isBlank() }
- for (s2 in split2) {
- if (s2.contains("mFragmentId=")) {
- val name = s2.trim { it <= ' ' }.substring(0, s2.indexOf("{") - 1)
- val fragmentInfo = FragmentInfo()
- list.add(fragmentInfo)
- fragmentInfo.name = name
- val split3 =
- s2.replace("Child FragmentManager", "Child_FragmentManager").split(" ".toRegex())
- .dropLastWhile { it.isEmpty() }
- for (s31 in split3) {
- if (s31.contains("Child_FragmentManager")) {
- break
- }
- val s3 = s31.replace("\n", "").replace(" ", "")
- when {
- s3.startsWith("mFragmentId=") -> fragmentInfo.fragmentId =
- s3.replace("mFragmentId=", "")
- s3.startsWith("mContainerId=") -> fragmentInfo.containerId =
- s3.replace("mContainerId=", "")
- s3.startsWith("mTag=") -> fragmentInfo.tag = s3.replace("mTag=", "")
- s3.startsWith("mState=") -> fragmentInfo.state =
- s3.replace("mState=", "").toInt()
- s3.startsWith("mIndex=") -> fragmentInfo.index =
- s3.replace("mIndex=", "").toInt()
- s3.startsWith("mWho=") -> fragmentInfo.who = s3.replace("mWho=", "")
- s3.startsWith("mBackStackNesting=") -> fragmentInfo.backStackNesting =
- s3.replace("mBackStackNesting=", "").toInt()
- s3.startsWith("mAdded=") -> fragmentInfo.added = s3.replace("mAdded=", "") ==
- "true"
- s3.startsWith("mRemoving=") -> fragmentInfo.removing = s3.replace(
- "mRemoving=",
- ""
- ) == "true"
- s3.startsWith("mFromLayout=") -> fragmentInfo.fromLayout = s3.replace(
- "mFromLayout=",
- ""
- ) ==
- "true"
- s3.startsWith("mInLayout=") -> fragmentInfo.inLayout = s3.replace(
- "mInLayout=",
- ""
- ) == "true"
- s3.startsWith("mHidden=") -> fragmentInfo.hidden = s3.replace("mHidden=", "") ==
- "true"
- s3.startsWith("mDetached=") -> fragmentInfo.detached = s3.replace(
- "mDetached=",
- ""
- ) == "true"
- }
- }
+ split1[4]
}
}
- topActivityInfo.fragments = list.toTypedArray()
}
}
break
@@ -151,13 +91,23 @@ object ShellManager {
}
fun getPid(packageName: String): String {
- var result: CommandResult = ShellUtils.runWithSu(String.format(SHELL_PROCESS_PID_1, packageName))
+ var result: CommandResult =
+ ShellUtils.runWithSu(
+ String.format(SHELL_PROCESS_PID_1, packageName),
+ useBusyBox = false
+ )
if (result.isSuccessful) {
return result.getStdout()
}
- result = ShellUtils.runWithSu(String.format(SHELL_PROCESS_PID_2, packageName))
+ result = ShellUtils.runWithSu(
+ String.format(SHELL_PROCESS_PID_2, packageName),
+ useBusyBox = false
+ )
if (result.isSuccessful.not()) {
- result = ShellUtils.runWithSu(String.format(SHELL_PROCESS_PID_3, packageName))
+ result = ShellUtils.runWithSu(
+ String.format(SHELL_PROCESS_PID_3, packageName),
+ useBusyBox = false
+ )
}
if (result.isSuccessful.not()) {
return ""
@@ -166,7 +116,11 @@ object ShellManager {
}
fun getSqliteFiles(packageName: String): Array {
- val dbPath = "/data/data/$packageName/databases"
+ return getSqliteFiles(Constant.dataDir, packageName)
+ }
+
+ private fun getSqliteFiles(dir: String, packageName: String): Array {
+ val dbPath = "$dir/$packageName/databases"
val list = lsDir(dbPath)
val files = ArrayList()
for (file in list) {
@@ -182,91 +136,143 @@ object ShellManager {
return files.toTypedArray()
}
- fun openAccessibilityService(callback: Callback? = null) {
- ShellUtils.runWithSu(SHELL_OPEN_ACCESSiBILITY_SERVICE, object : ShellUtils.ShellResultCallback() {
- override fun onComplete(result: CommandResult) {
- callback?.onSuccess(result.isSuccessful && result.getStdout().isEmpty())
- }
-
- override fun onError(msg: String) {
- callback?.onSuccess(false)
- }
- })
+ fun openAccessibilityService(): Single {
+ return ShellUtils.runWithSuAsync(*SHELL_OPEN_ACCESSiBILITY_SERVICE, useBusyBox = false)
+ .map {
+ it.isSuccessful && it.getStdout().isEmpty()
+ }.onErrorReturn { false }.runOnIO()
}
fun catFile(filaPath: String): String {
- val commandResult = ShellUtils.runWithSu("cat $filaPath")
- return commandResult.getStdout()
+ val result = ShellUtils.runWithSu("cat $filaPath")
+ return result.getStdout()
+ }
+
+ fun rmFile(file: File): Boolean {
+ return rmFile(file.absolutePath)
+ }
+
+ fun mkDir(file: String): Boolean {
+ val result = ShellUtils.runWithSu("mkdir $file")
+ return result.isSuccessful
}
fun rmFile(file: String): Boolean {
- val commandResult = ShellUtils.runWithSu("rm -rf $file")
- return commandResult.isSuccessful
+ val result = ShellUtils.runWithSu("rm -rf $file")
+ return result.isSuccessful
}
fun modifyFile(filaPath: String, content: String): Boolean {
- val commandResult = ShellUtils.runWithSu("echo $content >> $filaPath")
- return commandResult.isSuccessful
+ val result = ShellUtils.runWithSu("echo $content >> $filaPath")
+ return result.isSuccessful
}
fun cpFile(source: String, dst: String, mod: String = "666"): Boolean {
val dir = dst.substring(0, dst.lastIndexOf("/"))
- var commandResult = ShellUtils.runWithSu("mkdir -p $dir")
- if (commandResult.isSuccessful.not()) {
+ var result = ShellUtils.runWithSu("mkdir -p $dir")
+ if (result.isSuccessful.not()) {
+ return false
+ }
+ result = ShellUtils.runWithSu("cp -R $source $dst && chmod $mod $dst")
+ return result.isSuccessful || result.getStderr()
+ .contains("Operation not permitted")
+ }
+
+ fun tarCF(tarPath: String, srcPath: String): Boolean {
+ val dir = tarPath.substring(0, tarPath.lastIndexOf("/"))
+ var result = ShellUtils.runWithSu("mkdir -p $dir")
+ if (result.isSuccessful.not()) {
return false
}
- commandResult = ShellUtils.runWithSu("cp -R $source $dst && chmod $mod $dst")
- return commandResult.isSuccessful || commandResult.getStderr()?.contains("Operation not permitted") ?: false
+ result = ShellUtils.runWithSu("tar -pcf $tarPath -C $srcPath .")
+ return result.isSuccessful || result.getStderr()
+ .contains("Operation not permitted")
}
+ fun tarXF(tarPath: String, dst: String): Boolean {
+ val result = ShellUtils.runWithSu("tar -xf $tarPath -C $dst")
+ return result.isSuccessful
+ }
+
+
fun catFile(source: String, dst: String, mod: String? = null): Boolean {
val cmds = arrayListOf()
cmds.add("cat $source > $dst")
if (mod != null) {
cmds.add("chmod $mod $dst")
}
- val commandResult = ShellUtils.runWithSu(*(cmds.toTypedArray()))
- return commandResult.isSuccessful
- }
-
- fun getZipFileList(path: String): List {
- val file = File(CommonUtils.application.cacheDir, "zip.dex")
- if (file.exists()) {
- ShellUtils.runWithSu("cp ${file.absolutePath} /data/local/tmp", "rm -rf ${file.absolutePath}")
- }
- val commandResult = ShellUtils.runWithSu(String.format(SHELL_GET_ZIP_FILE_LIST, path))
- return commandResult.stdout
+ val result = ShellUtils.runWithSu(*(cmds.toTypedArray()))
+ return result.isSuccessful
}
fun lsDir(path: String): List {
- val commandResult = ShellUtils.runWithSu("ls $path")
- return commandResult.stdout
+ val result = ShellUtils.runWithSu("ls $path")
+ return result.stdout
}
- fun findApkDir(packageName: String): String {
- val cmd = "ls /data/app/|grep $packageName"
- val dir = ShellUtils.runWithSu(cmd).getStdout()
- return "/data/app/$dir/base.apk"
+ fun clearAppData(packageName: String): Boolean {
+ val result = ShellUtils.runWithSu(
+ String.format(SHELL_CLEAR_APP_DATA, packageName),
+ useBusyBox = false
+ )
+ return result.isSuccessful
}
- fun uninstallApp(packageName: String): Boolean {
- val commandResult = ShellUtils.runWithSu(String.format(SHELL_UNINSTALL_APP, packageName))
- return commandResult.isSuccessful
+ fun forceStopApp(packageName: String): Boolean {
+ val result = ShellUtils.runWithSu(
+ String.format(SHELL_FORCE_STOP_APP, packageName),
+ useBusyBox = false
+ )
+ return result.isSuccessful
}
- fun clearAppData(packageName: String): Boolean {
- val commandResult = ShellUtils.runWithSu(String.format(SHELL_CLEAR_APP_DATA, packageName))
- return commandResult.isSuccessful
+ fun uninstallApk(packageName: String): Boolean {
+ val result = ShellUtils.runWithSu("pm uninstall $packageName", useBusyBox = false)
+ return result.isSuccessful
}
- fun forceStopApp(packageName: String): Boolean {
- val commandResult = ShellUtils.runWithSu(String.format(SHELL_FORCE_STOP_APP, packageName))
- return commandResult.isSuccessful
+ fun installApk(apkDir: String): Boolean {
+ val result = ShellUtils.runWithSu("pm install -r $apkDir", useBusyBox = false)
+ return result.isSuccessful
}
fun openAdbWifi(): Boolean {
- val commandResult = ShellUtils.runWithSu(*SHELL_OPEN_ADB_WIFI)
- return commandResult.isSuccessful
+// val result = ShellUtils.runWithSu(*SHELL_OPEN_ADB_WIFI)
+ return false
+ }
+
+
+ fun chownDataDir(dir: String, map: Map>): Boolean {
+ val result = ShellUtils.runWithSu("ls $dir")
+ if (!result.isSuccessful) {
+ return false
+ }
+
+ val dirs = arrayOf("") + result.stdout
+ dirs.forEach {
+ val (user, group) = map[it] ?: map[""] ?: return@forEach
+ ShellUtils.runWithSu("chown -R $user:$group $dir${it.ifNotEmpty { "/$it" }}")
+ }
+ return true
+ }
+
+ fun getDataDirUserAndGroup(dir: String): Map> {
+ val result = ShellUtils.runWithSu("ls $dir")
+ if (!result.isSuccessful) {
+ return emptyMap()
+ }
+ val dirs = result.stdout
+ val map = hashMapOf>()
+ ShellUtils.runWithSu("stat -c \"%U %G\" $dir").takeIf { it.isSuccessful }?.let {
+ map[""] = it.getStdout().split(" ").let { it[0] to it[1] }
+ }
+ dirs.forEach {
+ val r = ShellUtils.runWithSu("stat -c \"%U %G\" $dir/$it")
+ if (r.isSuccessful) {
+ map[it] = r.getStdout().split(" ").let { it[0] to it[1] }
+ }
+ }
+ return map
}
}
diff --git a/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellUtils.kt b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellUtils.kt
new file mode 100644
index 0000000..10def5f
--- /dev/null
+++ b/commonutil/src/main/java/com/wrbug/developerhelper/commonutil/shell/ShellUtils.kt
@@ -0,0 +1,84 @@
+package com.wrbug.developerhelper.commonutil.shell
+
+import android.util.Log
+import com.wrbug.developerhelper.commonutil.CommonUtils
+import com.wrbug.developerhelper.commonutil.RootUtils
+import io.reactivex.rxjava3.core.Single
+import java.io.File
+
+object ShellUtils {
+ private const val TAG = "ShellUtils"
+ private const val AVAILABLE_TEST_COMMANDS = "echo -BOC- \n id"
+ val busyBoxFile by lazy {
+ File(CommonUtils.application.cacheDir, "busybox")
+ }
+
+ fun run(cmd: String, useBusyBox: Boolean = true): CommandResult {
+ return Shell.SH.run(appendBusyBox(useBusyBox, cmd)).convert()
+ }
+
+ fun runWithSuAsync(vararg cmds: String, useBusyBox: Boolean = true): Single {
+ return Single.just(cmds).map {
+ if (!RootUtils.isRoot()) {
+ throw ShellException("未开启root权限")
+ }
+ Shell.SU.run(appendBusyBox(useBusyBox, *cmds)).convert()
+ }
+ }
+
+ fun runWithSu(vararg cmd: String, useBusyBox: Boolean = true): CommandResult {
+ if (!RootUtils.isRoot()) {
+ return CommandResult(
+ emptyList(),
+ listOf("未开启root权限"),
+ -1, null
+ )
+ }
+ return Shell.SU.run(appendBusyBox(useBusyBox, *cmd)).convert()
+ }
+
+ private fun Shell.Command.Result.convert(): CommandResult {
+ return apply {
+ if (isSuccess.not()) {
+ Log.e(TAG, stderr.joinToString("\n"))
+ }
+ }.let {
+ CommandResult(it.stdout, it.stderr, exitCode, it.details)
+ }
+ }
+
+ private fun appendBusyBox(useBusyBox: Boolean, vararg cmds: String): String {
+ if (cmds.isEmpty()) {
+ return ""
+ }
+ if (useBusyBox && busyBoxFile.exists() && busyBoxFile.canExecute()) {
+ return cmds.joinToString("\n") { busyBoxFile.absolutePath + " " + it }
+ }
+ return cmds.joinToString("\n")
+ }
+
+ fun isRoot(): Boolean {
+ val result = Shell.SU.run(AVAILABLE_TEST_COMMANDS)
+ return parseAvailableResult(result.stdout, true)
+ }
+
+
+ private fun parseAvailableResult(stdout: List?, checkForRoot: Boolean): Boolean {
+ if (stdout == null) {
+ return false
+ }
+ // this is only one of many ways this can be done
+ var echoSeen = false
+ for (line in stdout) {
+ if (line.contains("uid=")) {
+ // id command is working, let's see if we are actually root
+ return !checkForRoot || line.contains("uid=0")
+ } else if (line.contains("-BOC-")) {
+ // if we end up here, at least the su command starts some kind of shell, let's hope it has root privileges -
+ // no way to know without additional native binaries
+ echoSeen = true
+ }
+ }
+ return echoSeen
+ }
+}
\ No newline at end of file
diff --git a/commonutil/src/test/java/com/wrbug/developerhelper/commonutil/ExampleUnitTest.java b/commonutil/src/test/java/com/wrbug/developerhelper/commonutil/ExampleUnitTest.java
deleted file mode 100644
index e4cabfb..0000000
--- a/commonutil/src/test/java/com/wrbug/developerhelper/commonutil/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.wrbug.developerhelper.commonutil;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/commonwidget/.gitignore b/commonwidget/.gitignore
deleted file mode 100644
index 796b96d..0000000
--- a/commonwidget/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/commonwidget/proguard-rules.pro b/commonwidget/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/commonwidget/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/commonwidget/src/androidTest/java/com/wrbug/developerhelper/commonwidget/ExampleInstrumentedTest.java b/commonwidget/src/androidTest/java/com/wrbug/developerhelper/commonwidget/ExampleInstrumentedTest.java
deleted file mode 100644
index 78375d2..0000000
--- a/commonwidget/src/androidTest/java/com/wrbug/developerhelper/commonwidget/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.wrbug.developerhelper.commonwidget;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.wrbug.developerhelper.commonwidget.test", appContext.getPackageName());
- }
-}
diff --git a/commonwidget/src/main/AndroidManifest.xml b/commonwidget/src/main/AndroidManifest.xml
deleted file mode 100644
index 1099276..0000000
--- a/commonwidget/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
diff --git a/commonwidget/src/main/res/values/strings.xml b/commonwidget/src/main/res/values/strings.xml
deleted file mode 100644
index f6c0897..0000000
--- a/commonwidget/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- commonwidget
-
diff --git a/commonwidget/src/test/java/com/wrbug/developerhelper/commonwidget/ExampleUnitTest.java b/commonwidget/src/test/java/com/wrbug/developerhelper/commonwidget/ExampleUnitTest.java
deleted file mode 100644
index 0cf0c5a..0000000
--- a/commonwidget/src/test/java/com/wrbug/developerhelper/commonwidget/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.wrbug.developerhelper.commonwidget;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 4a5855f..02743a0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,4 +14,6 @@ org.gradle.jvmargs=-Xmx1536m
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
android.useAndroidX=true
-android.enableJetifier=true
\ No newline at end of file
+android.enableJetifier=true
+kotlin.jvm.target.validation.mode = IGNORE
+android.defaults.buildfeatures.buildconfig=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 9a4163a..534885b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
+#Wed Sep 11 19:29:17 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/basecommon/.gitignore b/ipc/.gitignore
similarity index 100%
rename from basecommon/.gitignore
rename to ipc/.gitignore
diff --git a/commonwidget/build.gradle b/ipc/build.gradle
similarity index 52%
rename from commonwidget/build.gradle
rename to ipc/build.gradle
index 9e215c4..773da94 100644
--- a/commonwidget/build.gradle
+++ b/ipc/build.gradle
@@ -1,14 +1,16 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
+apply from: "${rootDir}/common.gradle"
android {
- compileSdkVersion 28
+ namespace "com.wrbug.developerhelper.ipc"
+ compileSdk 34
defaultConfig {
- minSdkVersion 21
- targetSdkVersion 28
+ minSdkVersion 16
+ targetSdkVersion 34
versionCode 1
versionName "1.0"
@@ -19,18 +21,15 @@ android {
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
- implementation fileTree(include: ['*.jar'], dir: 'libs')
- testImplementation 'junit:junit:4.12'
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':commonutil')
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-}
-repositories {
- mavenCentral()
}
diff --git a/basecommon/proguard-rules.pro b/ipc/proguard-rules.pro
similarity index 100%
rename from basecommon/proguard-rules.pro
rename to ipc/proguard-rules.pro
diff --git a/mmkv/src/androidTest/java/com/wrbug/developerhelper/mmkv/ExampleInstrumentedTest.java b/ipc/src/androidTest/java/com/wrbug/developerhelper/ipc/ExampleInstrumentedTest.java
similarity index 82%
rename from mmkv/src/androidTest/java/com/wrbug/developerhelper/mmkv/ExampleInstrumentedTest.java
rename to ipc/src/androidTest/java/com/wrbug/developerhelper/ipc/ExampleInstrumentedTest.java
index 161e03c..6463c6b 100644
--- a/mmkv/src/androidTest/java/com/wrbug/developerhelper/mmkv/ExampleInstrumentedTest.java
+++ b/ipc/src/androidTest/java/com/wrbug/developerhelper/ipc/ExampleInstrumentedTest.java
@@ -1,4 +1,4 @@
-package com.wrbug.developerhelper.mmkv;
+package com.wrbug.developerhelper.ipc;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
@@ -21,6 +21,6 @@ public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
- assertEquals("com.wrbug.developerhelper.mmkv.test", appContext.getPackageName());
+ assertEquals("com.wrbug.developerhelper.ipc.test", appContext.getPackageName());
}
}
diff --git a/basecommon/src/main/AndroidManifest.xml b/ipc/src/main/AndroidManifest.xml
similarity index 56%
rename from basecommon/src/main/AndroidManifest.xml
rename to ipc/src/main/AndroidManifest.xml
index 443e74f..f10ccab 100644
--- a/basecommon/src/main/AndroidManifest.xml
+++ b/ipc/src/main/AndroidManifest.xml
@@ -1,2 +1,2 @@
+ package="com.wrbug.developerhelper.ipc" />
diff --git a/ipc/src/main/java/com/wrbug/developerhelper/ipc/processshare/AppXposedProcessData.kt b/ipc/src/main/java/com/wrbug/developerhelper/ipc/processshare/AppXposedProcessData.kt
new file mode 100644
index 0000000..59ede7f
--- /dev/null
+++ b/ipc/src/main/java/com/wrbug/developerhelper/ipc/processshare/AppXposedProcessData.kt
@@ -0,0 +1,21 @@
+package com.wrbug.developerhelper.ipc.processshare
+
+import androidx.annotation.Keep
+import com.wrbug.developerhelper.ipc.processshare.annotation.Url
+import io.reactivex.rxjava3.core.Observable
+
+/**
+ *
+ * class: AppXposedProcessData.kt
+ * author: wrbug
+ * date: 2020-05-14
+ * description:
+ *
+ */
+@Keep
+interface AppXposedProcessData : ProcessData {
+ fun setAppXposedStatus(map: Map)
+
+ fun setAppXposedStatus(packageName: String, open: Boolean)
+ fun getAppXposedStatus(): Observable