diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index f9e09cc3c..76262912c 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -15,7 +15,7 @@ jobs:
coverageReport:
strategy:
matrix:
- api-level: [21, 21]
+ api-level: [21, 21, 30]
fail-fast: false
runs-on: macOS-latest
steps:
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 1bea36eb9..5b5d76bce 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -10,7 +10,7 @@ jobs:
instrumentation_tests:
strategy:
matrix:
- api-level: [21, 22, 23, 24, 25, 27, 28]
+ api-level: [21, 22, 23, 24, 25, 27, 28, 30]
fail-fast: false
runs-on: macOS-latest
steps:
diff --git a/app/detekt_baseline.xml b/app/detekt_baseline.xml
index 40e2c3c8a..2c43a15d6 100644
--- a/app/detekt_baseline.xml
+++ b/app/detekt_baseline.xml
@@ -11,7 +11,7 @@
MagicNumber:ShareFiles.kt$ShareFiles$24
MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$5
MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$500
- MagicNumber:ZimHostFragment.kt$ZimHostFragment$4
+ NestedBlockDepth:LocalLibraryFragment.kt$LocalLibraryFragment$checkPermissions
NestedBlockDepth:PeerGroupHandshake.kt$PeerGroupHandshake$readHandshakeAndExchangeMetaData
NestedBlockDepth:ReceiverHandShake.kt$ReceiverHandShake$exchangeFileTransferMetadata
PackageNaming:AvailableSpaceCalculator.kt$package org.kiwix.kiwixmobile.zim_manager.library_view
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 53648ce78..a68032508 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,8 @@
+
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt
index 592471fc5..e97562289 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt
@@ -20,7 +20,9 @@ package org.kiwix.kiwixmobile.nav.destination.library
import android.Manifest
import android.content.pm.PackageManager
+import android.os.Build
import android.os.Bundle
+import android.os.Environment
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
@@ -31,6 +33,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
+import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
@@ -49,9 +52,12 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
+import org.kiwix.kiwixmobile.core.navigateToSettings
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.REQUEST_STORAGE_PERMISSION
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
+import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
+import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BookOnDiskDelegate
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
@@ -69,6 +75,7 @@ class LocalLibraryFragment : BaseFragment() {
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject lateinit var sharedPreferenceUtil: SharedPreferenceUtil
+ @Inject lateinit var dialogShower: DialogShower
private var actionMode: ActionMode? = null
private val disposable = CompositeDisposable()
@@ -202,7 +209,27 @@ class LocalLibraryFragment : BaseFragment() {
REQUEST_STORAGE_PERMISSION
)
} else {
- requestFileSystemCheck()
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ if (Environment.isExternalStorageManager()) {
+ // We already have permission!!
+ requestFileSystemCheck()
+ } else {
+ if (sharedPreferenceUtil.manageExternalFilesPermissionDialog) {
+ // We should only ask for first time, If the users wants to revoke settings
+ // then they can directly toggle this feature from settings screen
+ sharedPreferenceUtil.manageExternalFilesPermissionDialog = false
+ // Show Dialog and Go to settings to give permission
+ dialogShower.show(
+ KiwixDialog.ManageExternalFilesPermissionDialog,
+ {
+ this.activity?.let(FragmentActivity::navigateToSettings)
+ }
+ )
+ }
+ }
+ } else {
+ requestFileSystemCheck()
+ }
}
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt
index 76e6408a5..4453b0818 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt
@@ -49,11 +49,13 @@ import org.kiwix.kiwixmobile.core.downloader.Downloader
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
+import org.kiwix.kiwixmobile.core.extensions.closeKeyboard
import org.kiwix.kiwixmobile.core.extensions.snack
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.utils.BookUtils
import org.kiwix.kiwixmobile.core.utils.NetworkUtils
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
+import org.kiwix.kiwixmobile.core.utils.SimpleRecyclerViewScrollListener
import org.kiwix.kiwixmobile.core.utils.SimpleTextListener
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
@@ -141,6 +143,13 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
zimManageViewModel.shouldShowWifiOnlyDialog.value = false
}
})
+
+ // hides keyboard when scrolled
+ libraryList.addOnScrollListener(SimpleRecyclerViewScrollListener { _, newState ->
+ if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
+ libraryList.closeKeyboard()
+ }
+ })
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/settings/KiwixPrefsFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/settings/KiwixPrefsFragment.kt
index 8956f3678..948466170 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/settings/KiwixPrefsFragment.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/settings/KiwixPrefsFragment.kt
@@ -18,10 +18,15 @@
package org.kiwix.kiwixmobile.settings
+import android.os.Build
import android.os.Bundle
+import android.os.Environment
import androidx.core.content.ContextCompat
+import androidx.fragment.app.FragmentActivity
import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
import org.kiwix.kiwixmobile.R
+import org.kiwix.kiwixmobile.core.navigateToSettings
import org.kiwix.kiwixmobile.core.settings.CorePrefsFragment
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.Companion.PREF_STORAGE
@@ -31,6 +36,7 @@ class KiwixPrefsFragment : CorePrefsFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
super.onCreatePreferences(savedInstanceState, rootKey)
setUpLanguageChooser(SharedPreferenceUtil.PREF_LANG)
+ setMangeExternalStoragePermission()
}
override fun setStorage() {
@@ -43,4 +49,34 @@ class KiwixPrefsFragment : CorePrefsFragment() {
private fun internalStorage(): String? =
ContextCompat.getExternalFilesDirs(requireContext(), null).firstOrNull()?.path
+
+ private fun setMangeExternalStoragePermission() {
+ val permissionPref = findPreference(PREF_MANAGE_EXTERNAL_STORAGE_PERMISSION)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ showPermissionPreference()
+ val externalStorageManager = Environment.isExternalStorageManager()
+ if (externalStorageManager) {
+ permissionPref!!.setSummary(org.kiwix.kiwixmobile.core.R.string.allowed)
+ } else {
+ permissionPref!!.setSummary(org.kiwix.kiwixmobile.core.R.string.not_allowed)
+ }
+ permissionPref.onPreferenceClickListener =
+ Preference.OnPreferenceClickListener {
+ activity?.let(FragmentActivity::navigateToSettings)
+ true
+ }
+ }
+ }
+
+ private fun showPermissionPreference() {
+ val preferenceCategory = findPreference(
+ PREF_PERMISSION
+ )
+ preferenceCategory!!.isVisible = true
+ }
+
+ companion object {
+ const val PREF_MANAGE_EXTERNAL_STORAGE_PERMISSION =
+ "pref_manage_external_storage"
+ }
}
diff --git a/app/src/main/res/drawable-night-v24/kiwix_icon.xml b/app/src/main/res/drawable-night-v24/kiwix_icon.xml
new file mode 100644
index 000000000..4f41c3eba
--- /dev/null
+++ b/app/src/main/res/drawable-night-v24/kiwix_icon.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-night/kiwix_icon.xml b/app/src/main/res/drawable-night/kiwix_icon.xml
new file mode 100644
index 000000000..048ced6b3
--- /dev/null
+++ b/app/src/main/res/drawable-night/kiwix_icon.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-night/launch_screen.xml b/app/src/main/res/drawable-night/launch_screen.xml
index 1d4d00751..1f69c6193 100644
--- a/app/src/main/res/drawable-night/launch_screen.xml
+++ b/app/src/main/res/drawable-night/launch_screen.xml
@@ -21,9 +21,6 @@
android:opacity="opaque">
- -
-
-
+
diff --git a/app/src/main/res/drawable-v24/kiwix_icon.xml b/app/src/main/res/drawable-v24/kiwix_icon.xml
new file mode 100644
index 000000000..16b1c0e76
--- /dev/null
+++ b/app/src/main/res/drawable-v24/kiwix_icon.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/kiwix_icon.xml b/app/src/main/res/drawable/kiwix_icon.xml
new file mode 100644
index 000000000..32fbbca20
--- /dev/null
+++ b/app/src/main/res/drawable/kiwix_icon.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/launch_screen.xml b/app/src/main/res/drawable/launch_screen.xml
index 0752c6b8e..6c38d8aa4 100644
--- a/app/src/main/res/drawable/launch_screen.xml
+++ b/app/src/main/res/drawable/launch_screen.xml
@@ -21,9 +21,6 @@
android:opacity="opaque">
- -
-
-
+
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/Intents.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/Intents.kt
index ea6f46326..80eda6769 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/Intents.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/Intents.kt
@@ -20,8 +20,20 @@ package org.kiwix.kiwixmobile.core
import android.app.Activity
import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.provider.Settings
+import androidx.annotation.RequiresApi
object Intents {
@JvmStatic fun internal(clazz: Class): Intent =
Intent(clazz.canonicalName).setPackage(CoreApp.instance.packageName)
}
+@RequiresApi(Build.VERSION_CODES.R)
+fun Activity.navigateToSettings() {
+ val intent = Intent().apply {
+ action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
+ data = Uri.fromParts("package", packageName, null)
+ }
+ startActivity(intent)
+}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt
index 17919d1ca..eeadaa799 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt
@@ -19,6 +19,7 @@
package org.kiwix.kiwixmobile.core.extensions
import android.content.Context
+import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.fragment.app.Fragment
@@ -41,4 +42,9 @@ fun Fragment.closeKeyboard() {
inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}
+fun View.closeKeyboard() {
+ val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(windowToken, 0)
+}
+
val Fragment.coreMainActivity get() = activity as CoreMainActivity
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageFragment.kt
index 0b5a8aaee..375029a52 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageFragment.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageFragment.kt
@@ -42,6 +42,7 @@ import kotlinx.android.synthetic.main.layout_toolbar.toolbar
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.base.BaseFragment
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
+import org.kiwix.kiwixmobile.core.extensions.closeKeyboard
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.page.adapter.OnItemClickListener
import org.kiwix.kiwixmobile.core.page.adapter.Page
@@ -50,6 +51,7 @@ import org.kiwix.kiwixmobile.core.page.viewmodel.Action
import org.kiwix.kiwixmobile.core.page.viewmodel.PageState
import org.kiwix.kiwixmobile.core.page.viewmodel.PageViewModel
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
+import org.kiwix.kiwixmobile.core.utils.SimpleRecyclerViewScrollListener
import org.kiwix.kiwixmobile.core.utils.SimpleTextListener
import javax.inject.Inject
@@ -135,6 +137,13 @@ abstract class PageFragment : OnItemClickListener, BaseFragment(), FragmentActiv
pageViewModel.actions.offer(Action.UserClickedShowAllToggle(isChecked))
}
pageViewModel.state.observe(viewLifecycleOwner, Observer(::render))
+
+ // hides keyboard when scrolled
+ recycler_view.addOnScrollListener(SimpleRecyclerViewScrollListener { _, newState ->
+ if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
+ recycler_view.closeKeyboard()
+ }
+ })
}
override fun onCreateView(
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java
index badbf0f49..5a38303cf 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java
@@ -62,6 +62,7 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
public static final String PREF_CLEAR_ALL_HISTORY = "pref_clear_all_history";
public static final String PREF_CLEAR_ALL_NOTES = "pref_clear_all_notes";
public static final String PREF_CREDITS = "pref_credits";
+ public static final String PREF_PERMISSION = "pref_permissions";
private static final int ZOOM_OFFSET = 2;
private static final int ZOOM_SCALE = 25;
private static final String INTERNAL_TEXT_ZOOM = "text_zoom";
@@ -174,6 +175,9 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
versionPref.setSummary(getVersionName() + " Build: " + getVersionCode());
}
+
+
+
private int getVersionCode() {
try {
return getActivity().getPackageManager()
@@ -282,4 +286,5 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
}
return Unit.INSTANCE;
}
+
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
index 8c7cc8ea9..19c4d0ac7 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
@@ -140,6 +140,13 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
fun updateNightMode() = nightModes.offer(nightMode)
+ var manageExternalFilesPermissionDialog: Boolean
+ get() = sharedPreferences.getBoolean(PREF_MANAGE_EXTERNAL_FILES, true)
+ set(prefManageExternalFilesPermissionDialog) =
+ sharedPreferences.edit {
+ putBoolean(PREF_MANAGE_EXTERNAL_FILES, prefManageExternalFilesPermissionDialog)
+ }
+
var hostedBooks: Set
get() = sharedPreferences.getStringSet(PREF_HOSTED_BOOKS, null)?.toHashSet() ?: HashSet()
set(hostedBooks) {
@@ -172,5 +179,6 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
const val PREF_NIGHT_MODE = "pref_night_mode"
private const val TEXT_ZOOM = "true_text_zoom"
private const val DEFAULT_ZOOM = 100
+ private const val PREF_MANAGE_EXTERNAL_FILES = "pref_manage_external_files"
}
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SimpleRecyclerViewScrollListener.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SimpleRecyclerViewScrollListener.kt
new file mode 100644
index 000000000..64d5614c9
--- /dev/null
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SimpleRecyclerViewScrollListener.kt
@@ -0,0 +1,34 @@
+/*
+ * Kiwix Android
+ * Copyright (c) 2021 Kiwix
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package org.kiwix.kiwixmobile.core.utils
+
+import androidx.recyclerview.widget.RecyclerView
+
+class SimpleRecyclerViewScrollListener(
+ private val onLayoutScrollListener: (RecyclerView, Int) -> Unit
+) :
+ RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+ onLayoutScrollListener(
+ recyclerView,
+ newState
+ )
+ }
+}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt
index 53ce42151..7bb1139ac 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt
@@ -84,6 +84,14 @@ sealed class KiwixDialog(
cancelable = false
)
+ object ManageExternalFilesPermissionDialog : KiwixDialog(
+ R.string.all_files_permission_needed,
+ R.string.all_files_permission_needed_message,
+ R.string.yes,
+ R.string.no,
+ cancelable = false
+ )
+
data class ShowHotspotDetails(override val args: List) : KiwixDialog(
R.string.hotspot_turned_on,
R.string.hotspot_details_message,
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index af11074bc..4de469255 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -68,6 +68,7 @@
Clear history
Clear recent searches and tabs history
Notes
+ Permissions
All History Cleared
Clear bookmarks
Clear All History?
@@ -255,6 +256,7 @@
Status
Clears all notes on all articles
Clear all notes
+ Allow to read and write ZIM files on SD card
Change text size with 25\% increments.
Pic
Vid
@@ -289,6 +291,10 @@
Close Drawer
How to update content?
To update content (a zim file) you need to download the full latest version of this very same content. You can do that via the download section.
+ All Files Permission Needed
+ In order to access all the zim files across device we need to have All Files Permission
+ Allowed
+ Not allowed
- @string/on
- @string/off
diff --git a/core/src/main/res/xml/preferences.xml b/core/src/main/res/xml/preferences.xml
index e8e0c52cb..081a15b34 100644
--- a/core/src/main/res/xml/preferences.xml
+++ b/core/src/main/res/xml/preferences.xml
@@ -95,6 +95,18 @@
android:title="@string/pref_clear_all_notes_title"
app:iconSpaceReserved="false" />
+
+
+
+
+