Rename
This commit is contained in:
1 parent
b86d90021c
commit
6c0757c91b
972 files changed
+6885
-7321
No files matched your search
@@ -0,0 +1,231 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupMenu
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.VMBaseActivity
|
||||
import io.legato.kazusa.base.adapter.ItemViewHolder
|
||||
import io.legato.kazusa.base.adapter.RecyclerAdapter
|
||||
import io.legato.kazusa.constant.AppConst
|
||||
import io.legato.kazusa.databinding.ActivityFileManageBinding
|
||||
import io.legato.kazusa.databinding.ItemFileBinding
|
||||
import io.legato.kazusa.databinding.ItemPathPickerBinding
|
||||
//import io.legado.app.lib.theme.primaryTextColor
|
||||
import io.legato.kazusa.ui.file.utils.FilePickerIcon
|
||||
import io.legato.kazusa.ui.widget.recycler.VerticalDivider
|
||||
import io.legato.kazusa.utils.ConvertUtils
|
||||
import io.legato.kazusa.utils.applyNavigationBarPadding
|
||||
import io.legato.kazusa.utils.openFileUri
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
import java.io.File
|
||||
|
||||
class FileManageActivity : VMBaseActivity<ActivityFileManageBinding, FileManageViewModel>() {
|
||||
|
||||
override val binding by viewBinding(ActivityFileManageBinding::inflate)
|
||||
override val viewModel by viewModels<FileManageViewModel>()
|
||||
private val dirParent = ".."
|
||||
private val searchView: SearchView by lazy {
|
||||
binding.titleBar.findViewById(R.id.search_view)
|
||||
}
|
||||
private val pathAdapter by lazy {
|
||||
PathAdapter()
|
||||
}
|
||||
private val fileAdapter by lazy {
|
||||
FileAdapter()
|
||||
}
|
||||
private val currentFiles = arrayListOf<File>()
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
initView()
|
||||
initSearchView()
|
||||
viewModel.upFiles(viewModel.rootDoc)
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.rvPath.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
|
||||
binding.rvPath.adapter = pathAdapter
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
binding.recyclerView.addItemDecoration(VerticalDivider(this))
|
||||
binding.recyclerView.adapter = fileAdapter
|
||||
binding.recyclerView.applyNavigationBarPadding()
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
if (viewModel.lastDir != viewModel.rootDoc) {
|
||||
gotoLastDir()
|
||||
return@addCallback
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initSearchView() {
|
||||
//searchView.applyTint(primaryTextColor)
|
||||
searchView.queryHint = getString(R.string.screen) + " • " + getString(R.string.file_manage)
|
||||
searchView.isSubmitButtonEnabled = true
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
updateFiles()
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun updateFiles() {
|
||||
if (searchView.query.isNotEmpty()) {
|
||||
currentFiles.filter {
|
||||
it.name == dirParent || it.name.contains(searchView.query)
|
||||
}.let {
|
||||
fileAdapter.setItems(it)
|
||||
}
|
||||
} else {
|
||||
fileAdapter.setItems(currentFiles)
|
||||
}
|
||||
}
|
||||
|
||||
private fun gotoLastDir() {
|
||||
viewModel.subDocs.removeLastOrNull()
|
||||
pathAdapter.setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(viewModel.lastDir)
|
||||
}
|
||||
|
||||
override fun observeLiveBus() {
|
||||
viewModel.filesLiveData.observe(this) {
|
||||
searchView.setQuery("", false)
|
||||
currentFiles.clear()
|
||||
currentFiles.addAll(it)
|
||||
updateFiles()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
inner class PathAdapter :
|
||||
RecyclerAdapter<File, ItemPathPickerBinding>(this@FileManageActivity) {
|
||||
|
||||
private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getArrow())
|
||||
|
||||
init {
|
||||
addHeaderView {
|
||||
ItemPathPickerBinding.inflate(inflater, it, false).apply {
|
||||
textView.text = "root"
|
||||
imageView.setImageDrawable(arrowIcon)
|
||||
root.setOnClickListener {
|
||||
viewModel.subDocs.clear()
|
||||
setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(viewModel.rootDoc)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemPathPickerBinding {
|
||||
return ItemPathPickerBinding.inflate(inflater, parent, false).apply {
|
||||
imageView.setImageDrawable(arrowIcon)
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemPathPickerBinding) {
|
||||
binding.root.setOnClickListener {
|
||||
viewModel.subDocs = viewModel.subDocs.subList(0, holder.layoutPosition)
|
||||
setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(viewModel.subDocs.lastOrNull())
|
||||
}
|
||||
}
|
||||
|
||||
override fun convert(
|
||||
holder: ItemViewHolder,
|
||||
binding: ItemPathPickerBinding,
|
||||
item: File,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
binding.textView.text = item.name
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inner class FileAdapter : RecyclerAdapter<File, ItemFileBinding>(this@FileManageActivity) {
|
||||
private val upIcon = ConvertUtils.toDrawable(FilePickerIcon.getUpDir())!!
|
||||
private val folderIcon = ConvertUtils.toDrawable(FilePickerIcon.getFolder())!!
|
||||
private val fileIcon = ConvertUtils.toDrawable(FilePickerIcon.getFile())!!
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemFileBinding {
|
||||
return ItemFileBinding.inflate(inflater, parent, false)
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemFileBinding) {
|
||||
binding.root.setOnClickListener {
|
||||
val item = getItemByLayoutPosition(holder.layoutPosition)
|
||||
item?.let {
|
||||
if (item == viewModel.lastDir) {
|
||||
gotoLastDir()
|
||||
} else if (item.isDirectory) {
|
||||
viewModel.subDocs.add(item)
|
||||
pathAdapter.setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(item)
|
||||
} else {
|
||||
openFileUri(
|
||||
FileProvider.getUriForFile(
|
||||
this@FileManageActivity,
|
||||
AppConst.authority,
|
||||
item
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.root.setOnLongClickListener { view ->
|
||||
val item = getItemByLayoutPosition(holder.layoutPosition)
|
||||
if (item == viewModel.lastDir) {
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
item?.let {
|
||||
showFileMenu(view, item)
|
||||
}
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
}
|
||||
|
||||
override fun convert(
|
||||
holder: ItemViewHolder,
|
||||
binding: ItemFileBinding,
|
||||
item: File,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
if (item == viewModel.lastDir) {
|
||||
binding.imageView.setImageDrawable(upIcon)
|
||||
binding.textView.text = dirParent
|
||||
} else if (item.isDirectory) {
|
||||
binding.imageView.setImageDrawable(folderIcon)
|
||||
binding.textView.text = item.name
|
||||
} else {
|
||||
binding.imageView.setImageDrawable(fileIcon)
|
||||
binding.textView.text = item.name
|
||||
}
|
||||
}
|
||||
|
||||
private fun showFileMenu(view: View, file: File) {
|
||||
val popupMenu = PopupMenu(context, view)
|
||||
popupMenu.inflate(R.menu.file_long_click)
|
||||
popupMenu.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_del -> viewModel.delFile(file)
|
||||
}
|
||||
true
|
||||
}
|
||||
popupMenu.show()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import io.legato.kazusa.base.BaseViewModel
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import java.io.File
|
||||
|
||||
class FileManageViewModel(application: Application) : BaseViewModel(application) {
|
||||
|
||||
val rootDoc = context.getExternalFilesDir(null)?.parentFile
|
||||
var subDocs = mutableListOf<File>()
|
||||
val filesLiveData = MutableLiveData<List<File>>()
|
||||
|
||||
val lastDir: File? get() = subDocs.lastOrNull() ?: rootDoc
|
||||
|
||||
fun upFiles(parentFile: File?) {
|
||||
execute {
|
||||
parentFile ?: return@execute emptyList()
|
||||
if (parentFile == rootDoc) {
|
||||
parentFile.listFiles()?.sortedWith(
|
||||
compareBy({ it.isFile }, { it.name })
|
||||
)
|
||||
} else {
|
||||
val list = arrayListOf(parentFile)
|
||||
parentFile.listFiles()?.sortedWith(
|
||||
compareBy({ it.isFile }, { it.name })
|
||||
)?.let {
|
||||
list.addAll(it)
|
||||
}
|
||||
list
|
||||
}
|
||||
}.onStart {
|
||||
filesLiveData.postValue(emptyList())
|
||||
}.onSuccess {
|
||||
filesLiveData.postValue(it ?: emptyList())
|
||||
}.onError {
|
||||
context.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
fun delFile(file: File) {
|
||||
execute {
|
||||
file.delete()
|
||||
}.onSuccess {
|
||||
upFiles(lastDir)
|
||||
}.onError {
|
||||
context.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.BaseDialogFragment
|
||||
import io.legato.kazusa.base.adapter.ItemViewHolder
|
||||
import io.legato.kazusa.base.adapter.RecyclerAdapter
|
||||
import io.legato.kazusa.databinding.DialogEditTextBinding
|
||||
import io.legato.kazusa.databinding.DialogFileChooserBinding
|
||||
import io.legato.kazusa.databinding.ItemFilePickerBinding
|
||||
import io.legato.kazusa.databinding.ItemPathPickerBinding
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
//import io.legado.app.lib.theme.getPrimaryDisabledTextColor
|
||||
//import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
//import io.legado.app.lib.theme.primaryColor
|
||||
import io.legato.kazusa.ui.file.HandleFileContract.Companion.FILE
|
||||
import io.legato.kazusa.ui.widget.recycler.VerticalDivider
|
||||
import io.legato.kazusa.utils.FileUtils
|
||||
import io.legato.kazusa.utils.applyTint
|
||||
import io.legato.kazusa.utils.getCompatColor
|
||||
import io.legato.kazusa.utils.setLayout
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
import java.io.File
|
||||
|
||||
|
||||
class FilePickerDialog : BaseDialogFragment(R.layout.dialog_file_chooser),
|
||||
Toolbar.OnMenuItemClickListener {
|
||||
|
||||
companion object {
|
||||
const val tag = "FileChooserDialog"
|
||||
|
||||
fun show(
|
||||
manager: FragmentManager,
|
||||
mode: Int = FILE,
|
||||
title: String? = null,
|
||||
initPath: String? = null,
|
||||
isShowHideDir: Boolean = false,
|
||||
allowExtensions: Array<String>? = null,
|
||||
) {
|
||||
FilePickerDialog().apply {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt("mode", mode)
|
||||
bundle.putString("title", title)
|
||||
bundle.putBoolean("isShowHideDir", isShowHideDir)
|
||||
bundle.putString("initPath", initPath)
|
||||
bundle.putStringArray("allowExtensions", allowExtensions)
|
||||
arguments = bundle
|
||||
}.show(manager, tag)
|
||||
}
|
||||
}
|
||||
|
||||
private val binding by viewBinding(DialogFileChooserBinding::bind)
|
||||
private val viewModel by viewModels<FilePickerViewModel>()
|
||||
private val dirParent = ".."
|
||||
private val pathAdapter by lazy { PathAdapter() }
|
||||
private val fileAdapter by lazy { FileAdapter() }
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setLayout(0.9f, 0.8f)
|
||||
}
|
||||
|
||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||
//binding.toolBar.setBackgroundColor(primaryColor)
|
||||
//view.setBackgroundResource(R.color.background_card)
|
||||
initMenu()
|
||||
initContentView()
|
||||
viewModel.filesLiveData.observe(viewLifecycleOwner) {
|
||||
fileAdapter.selectFile = null
|
||||
fileAdapter.setItems(it)
|
||||
}
|
||||
viewModel.initData(arguments)
|
||||
binding.toolBar.title = arguments?.getString("title") ?: let {
|
||||
if (viewModel.isSelectDir) {
|
||||
getString(R.string.folder_chooser)
|
||||
} else {
|
||||
getString(R.string.file_chooser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initMenu() {
|
||||
binding.toolBar.inflateMenu(R.menu.file_chooser)
|
||||
binding.toolBar.menu.applyTint(requireContext())
|
||||
binding.toolBar.setOnMenuItemClickListener(this)
|
||||
}
|
||||
|
||||
private fun initContentView() {
|
||||
binding.rvPath.layoutManager = LinearLayoutManager(activity, RecyclerView.HORIZONTAL, false)
|
||||
binding.rvPath.adapter = pathAdapter
|
||||
|
||||
binding.rvFile.addItemDecoration(VerticalDivider(requireContext()))
|
||||
binding.rvFile.layoutManager = LinearLayoutManager(activity)
|
||||
binding.rvFile.adapter = fileAdapter
|
||||
|
||||
binding.tvOk.setOnClickListener {
|
||||
if (viewModel.isSelectDir) {
|
||||
viewModel.lastDir?.let {
|
||||
setResultData(it.path)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
} else {
|
||||
val file = fileAdapter.selectFile
|
||||
if (file == null) {
|
||||
toastOnUi("请选择文件")
|
||||
} else {
|
||||
setResultData(file.path)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
when (item?.itemId) {
|
||||
R.id.menu_create -> alert(R.string.create_folder) {
|
||||
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
|
||||
editView.hint = "文件夹名"
|
||||
}
|
||||
customView { alertBinding.root }
|
||||
okButton {
|
||||
val text = alertBinding.editView.text?.toString()
|
||||
if (text.isNullOrBlank()) {
|
||||
toastOnUi("文件夹名不能为空")
|
||||
} else {
|
||||
viewModel.createFolder(text.trim())
|
||||
}
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun setResultData(path: String) {
|
||||
val data = Intent().setData(Uri.fromFile(File(path)))
|
||||
(parentFragment as? CallBack)?.onResult(data)
|
||||
(activity as? CallBack)?.onResult(data)
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
activity?.finish()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
inner class PathAdapter :
|
||||
RecyclerAdapter<File, ItemPathPickerBinding>(requireContext()) {
|
||||
|
||||
private val arrowIcon = ContextCompat.getDrawable(requireContext(),R.drawable.ic_arrow_right)
|
||||
|
||||
init {
|
||||
addHeaderView {
|
||||
ItemPathPickerBinding.inflate(inflater, it, false).apply {
|
||||
textView.text = "root"
|
||||
imageView.setImageDrawable(arrowIcon)
|
||||
root.setOnClickListener {
|
||||
viewModel.subDocs.clear()
|
||||
setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(viewModel.rootDoc)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemPathPickerBinding {
|
||||
return ItemPathPickerBinding.inflate(inflater, parent, false).apply {
|
||||
imageView.setImageDrawable(arrowIcon)
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemPathPickerBinding) {
|
||||
binding.root.setOnClickListener {
|
||||
viewModel.subDocs = viewModel.subDocs.subList(0, holder.layoutPosition)
|
||||
setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(viewModel.subDocs.lastOrNull())
|
||||
}
|
||||
}
|
||||
|
||||
override fun convert(
|
||||
holder: ItemViewHolder,
|
||||
binding: ItemPathPickerBinding,
|
||||
item: File,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
binding.textView.text = item.name
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inner class FileAdapter : RecyclerAdapter<File, ItemFilePickerBinding>(requireContext()) {
|
||||
private val upIcon = ContextCompat.getDrawable(requireContext(),R.drawable.ic_return)
|
||||
private val folderIcon = ContextCompat.getDrawable(requireContext(),R.drawable.ic_folder)
|
||||
private val fileIcon = ContextCompat.getDrawable(requireContext(),R.drawable.ic_file)
|
||||
private val selectDrawable =
|
||||
ResourcesCompat.getDrawable(resources, R.drawable.shape_radius_1dp, null)!!.apply {
|
||||
// 从主题获取颜色
|
||||
val typedValue = TypedValue()
|
||||
requireContext().theme.resolveAttribute(android.R.attr.colorPrimary, typedValue, true)
|
||||
val primaryColor = typedValue.data
|
||||
DrawableCompat.setTint(this, primaryColor)
|
||||
}
|
||||
var selectFile: File? = null
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemFilePickerBinding {
|
||||
return ItemFilePickerBinding.inflate(inflater, parent, false)
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemFilePickerBinding) {
|
||||
binding.root.setOnClickListener {
|
||||
val item = getItemByLayoutPosition(holder.layoutPosition)
|
||||
item?.let {
|
||||
if (item == viewModel.lastDir) {
|
||||
viewModel.subDocs.removeLastOrNull()
|
||||
pathAdapter.setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(viewModel.subDocs.lastOrNull() ?: viewModel.rootDoc)
|
||||
} else if (item.isDirectory) {
|
||||
viewModel.subDocs.add(item)
|
||||
pathAdapter.setItems(viewModel.subDocs)
|
||||
viewModel.upFiles(item)
|
||||
} else if (viewModel.isSelectFile) {
|
||||
viewModel.allowExtensions.let {
|
||||
if (it.isNullOrEmpty() || it.contains(FileUtils.getExtension(item.path))) {
|
||||
selectFile = item
|
||||
notifyItemRangeChanged(getHeaderCount(), itemCount, "selectFile")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun convert(
|
||||
holder: ItemViewHolder,
|
||||
binding: ItemFilePickerBinding,
|
||||
item: File,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
if (payloads.isEmpty()) {
|
||||
if (item == viewModel.lastDir) {
|
||||
binding.imageView.setImageDrawable(upIcon)
|
||||
binding.textView.text = dirParent
|
||||
} else if (item.isDirectory) {
|
||||
binding.imageView.setImageDrawable(folderIcon)
|
||||
binding.textView.text = item.name
|
||||
} else {
|
||||
binding.imageView.setImageDrawable(fileIcon)
|
||||
binding.textView.text = item.name
|
||||
}
|
||||
if (item.isDirectory) {
|
||||
//binding.textView.setTextColor(primaryTextColor)
|
||||
} else {
|
||||
if (viewModel.isSelectDir) {
|
||||
//binding.textView.setTextColor(disabledTextColor)
|
||||
} else {
|
||||
viewModel.allowExtensions?.let {
|
||||
if (it.isEmpty() || it.contains(FileUtils.getExtension(item.path))) {
|
||||
//binding.textView.setTextColor(primaryTextColor)
|
||||
} else {
|
||||
//binding.textView.setTextColor(disabledTextColor)
|
||||
}
|
||||
}// ?: binding.textView.setTextColor(primaryTextColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.root.isSelected = item == selectFile
|
||||
if (item == selectFile) {
|
||||
binding.root.background = selectDrawable
|
||||
} else {
|
||||
binding.root.setBackgroundColor(getCompatColor(R.color.transparent))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface CallBack {
|
||||
fun onResult(data: Intent)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import io.legato.kazusa.base.BaseViewModel
|
||||
import io.legato.kazusa.exception.NoStackTraceException
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import java.io.File
|
||||
|
||||
class FilePickerViewModel(application: Application) : BaseViewModel(application) {
|
||||
|
||||
var rootDoc: File? = Environment.getExternalStorageDirectory()
|
||||
var subDocs = mutableListOf<File>()
|
||||
val filesLiveData = MutableLiveData<List<File>>()
|
||||
var mode: Int = HandleFileContract.FILE
|
||||
var isShowHideDir: Boolean = false
|
||||
var allowExtensions: Array<String>? = null
|
||||
val isSelectDir: Boolean get() = mode == HandleFileContract.DIR
|
||||
val isSelectFile: Boolean get() = mode == HandleFileContract.FILE
|
||||
val lastDir: File? get() = subDocs.lastOrNull() ?: rootDoc
|
||||
|
||||
fun initData(arguments: Bundle?) {
|
||||
arguments?.let {
|
||||
mode = it.getInt("mode", HandleFileContract.FILE)
|
||||
isShowHideDir = it.getBoolean("isShowHideDir")
|
||||
it.getString("initPath")?.let { path ->
|
||||
rootDoc = File(path)
|
||||
}
|
||||
allowExtensions = it.getStringArray("allowExtensions")
|
||||
}
|
||||
upFiles(rootDoc)
|
||||
}
|
||||
|
||||
fun upFiles(parentFile: File?) {
|
||||
execute {
|
||||
parentFile ?: return@execute emptyList()
|
||||
if (parentFile == rootDoc) {
|
||||
parentFile.listFiles()?.sortedWith(
|
||||
compareBy({ it.isFile }, { it.name })
|
||||
)
|
||||
} else {
|
||||
val list = arrayListOf(parentFile)
|
||||
parentFile.listFiles()?.sortedWith(
|
||||
compareBy({ it.isFile }, { it.name })
|
||||
)?.let {
|
||||
list.addAll(it)
|
||||
}
|
||||
list
|
||||
}
|
||||
}.onStart {
|
||||
filesLiveData.postValue(emptyList())
|
||||
}.onSuccess {
|
||||
filesLiveData.postValue(it ?: emptyList())
|
||||
}.onError {
|
||||
context.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
fun createFolder(name: String) {
|
||||
execute {
|
||||
val dir = lastDir ?: throw NoStackTraceException("父文件夹不存在")
|
||||
val folder = File(dir, name)
|
||||
if (!folder.canonicalPath.contains(dir.canonicalPath)) {
|
||||
throw NoStackTraceException("非法文件名")
|
||||
}
|
||||
folder.mkdir()
|
||||
}.onSuccess {
|
||||
upFiles(lastDir)
|
||||
}.onError {
|
||||
context.toastOnUi(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.VMBaseActivity
|
||||
import io.legato.kazusa.constant.AppLog
|
||||
import io.legato.kazusa.databinding.ActivityTranslucenceBinding
|
||||
import io.legato.kazusa.databinding.DialogEditTextBinding
|
||||
import io.legato.kazusa.help.IntentData
|
||||
import io.legato.kazusa.lib.dialogs.SelectItem
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
import io.legato.kazusa.lib.permission.Permissions
|
||||
import io.legato.kazusa.lib.permission.PermissionsCompat
|
||||
import io.legato.kazusa.utils.checkWrite
|
||||
import io.legato.kazusa.utils.externalFiles
|
||||
import io.legato.kazusa.utils.getJsonArray
|
||||
import io.legato.kazusa.utils.isContentScheme
|
||||
import io.legato.kazusa.utils.launch
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
|
||||
class HandleFileActivity :
|
||||
VMBaseActivity<ActivityTranslucenceBinding, HandleFileViewModel>(),
|
||||
FilePickerDialog.CallBack {
|
||||
|
||||
override val binding by viewBinding(ActivityTranslucenceBinding::inflate)
|
||||
override val viewModel by viewModels<HandleFileViewModel>()
|
||||
private var mode = 0
|
||||
|
||||
private val selectDocTree =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
|
||||
uri?.let {
|
||||
if (uri.isContentScheme()) {
|
||||
val modeFlags =
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
contentResolver.takePersistableUriPermission(uri, modeFlags)
|
||||
}
|
||||
onResult(Intent().setData(uri))
|
||||
} ?: finish()
|
||||
}
|
||||
|
||||
private val selectDoc = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
|
||||
it?.let {
|
||||
if (it.isContentScheme()) {
|
||||
val modeFlags =
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
contentResolver.takePersistableUriPermission(it, modeFlags)
|
||||
}
|
||||
onResult(Intent().setData(it))
|
||||
} ?: finish()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
mode = intent.getIntExtra("mode", 0)
|
||||
viewModel.errorLiveData.observe(this) {
|
||||
toastOnUi(it)
|
||||
finish()
|
||||
}
|
||||
val allowExtensions = intent.getStringArrayExtra("allowExtensions")
|
||||
val selectList: ArrayList<SelectItem<Int>> = when (mode) {
|
||||
HandleFileContract.DIR_SYS -> getDirActions(true)
|
||||
HandleFileContract.DIR -> getDirActions()
|
||||
HandleFileContract.FILE -> getFileActions()
|
||||
HandleFileContract.EXPORT -> arrayListOf(
|
||||
SelectItem(getString(R.string.upload_url), 111)
|
||||
).apply {
|
||||
addAll(getDirActions())
|
||||
}
|
||||
|
||||
else -> arrayListOf()
|
||||
}
|
||||
intent.getJsonArray<SelectItem<Int>>("otherActions")?.let {
|
||||
selectList.addAll(it)
|
||||
}
|
||||
val title = intent.getStringExtra("title") ?: let {
|
||||
when (mode) {
|
||||
HandleFileContract.EXPORT -> return@let getString(R.string.export)
|
||||
HandleFileContract.DIR -> return@let getString(R.string.select_folder)
|
||||
else -> return@let getString(R.string.select_file)
|
||||
}
|
||||
}
|
||||
alert(title) {
|
||||
items(selectList) { _, item, _ ->
|
||||
when (item.value) {
|
||||
HandleFileContract.DIR -> kotlin.runCatching {
|
||||
selectDocTree.launch()
|
||||
}.onFailure {
|
||||
AppLog.put(getString(R.string.open_sys_dir_picker_error), it, true)
|
||||
checkPermissions {
|
||||
FilePickerDialog.show(
|
||||
supportFragmentManager,
|
||||
mode = HandleFileContract.DIR
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
HandleFileContract.FILE -> kotlin.runCatching {
|
||||
selectDoc.launch(typesOfExtensions(allowExtensions))
|
||||
}.onFailure {
|
||||
AppLog.put(getString(R.string.open_sys_dir_picker_error), it, true)
|
||||
checkPermissions {
|
||||
FilePickerDialog.show(
|
||||
supportFragmentManager,
|
||||
mode = HandleFileContract.FILE,
|
||||
allowExtensions = allowExtensions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
10 -> checkPermissions {
|
||||
@Suppress("DEPRECATION")
|
||||
lifecycleScope.launchWhenResumed {
|
||||
FilePickerDialog.show(
|
||||
supportFragmentManager,
|
||||
mode = HandleFileContract.DIR
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
11 -> checkPermissions {
|
||||
@Suppress("DEPRECATION")
|
||||
lifecycleScope.launchWhenResumed {
|
||||
FilePickerDialog.show(
|
||||
supportFragmentManager,
|
||||
mode = HandleFileContract.FILE,
|
||||
allowExtensions = allowExtensions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
111 -> getFileData()?.let {
|
||||
viewModel.upload(it.first, it.second, it.third) { url ->
|
||||
val uri = Uri.parse(url)
|
||||
setResult(RESULT_OK, Intent().setData(uri))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
112 -> checkPermissions { // 手动输入目录路径
|
||||
showInputDirectoryDialog()
|
||||
}
|
||||
|
||||
else -> {
|
||||
val path = item.title
|
||||
val uri = if (path.isContentScheme()) {
|
||||
Uri.parse(path)
|
||||
} else {
|
||||
Uri.fromFile(File(path))
|
||||
}
|
||||
onResult(Intent().setData(uri))
|
||||
}
|
||||
}
|
||||
}
|
||||
onCancelled {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showInputDirectoryDialog() {
|
||||
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
|
||||
editView.hint = getString(R.string.enter_directory_path)
|
||||
}
|
||||
|
||||
alert(getString(R.string.manual_input)) {
|
||||
customView { alertBinding.root }
|
||||
okButton {
|
||||
val inputPath = alertBinding.editView.text.toString()
|
||||
if (inputPath.isBlank()) {
|
||||
toastOnUi(getString(R.string.empty_directory_input))
|
||||
return@okButton
|
||||
}
|
||||
val file = File(inputPath)
|
||||
if (file.exists() &&
|
||||
file.isDirectory &&
|
||||
isExternalStorage(file) &&
|
||||
file.checkWrite()
|
||||
) {
|
||||
onResult(Intent().setData(Uri.fromFile(file)))
|
||||
} else {
|
||||
toastOnUi(getString(R.string.invalid_directory))
|
||||
}
|
||||
}
|
||||
onDismiss {
|
||||
finish()
|
||||
}
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
|
||||
private fun isExternalStorage(path: File): Boolean {
|
||||
if (path.canonicalPath.startsWith(appCtx.externalFiles.parent!!)) {
|
||||
return false
|
||||
}
|
||||
try {
|
||||
if (Environment.isExternalStorageEmulated(path)) {
|
||||
return true
|
||||
}
|
||||
} catch (_: IllegalArgumentException) {
|
||||
}
|
||||
try {
|
||||
if (Environment.isExternalStorageRemovable(path)) {
|
||||
return true
|
||||
}
|
||||
} catch (_: IllegalArgumentException) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getFileData(): Triple<String, Any, String>? {
|
||||
val fileName = intent.getStringExtra("fileName")
|
||||
val file = intent.getStringExtra("fileKey")?.let {
|
||||
IntentData.get<Any>(it)
|
||||
}
|
||||
val contentType = intent.getStringExtra("contentType")
|
||||
if (fileName != null && file != null && contentType != null) {
|
||||
return Triple(fileName, file, contentType)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getDirActions(onlySys: Boolean = false): ArrayList<SelectItem<Int>> {
|
||||
return if (onlySys) {
|
||||
arrayListOf(
|
||||
SelectItem(getString(R.string.sys_folder_picker), HandleFileContract.DIR),
|
||||
SelectItem(getString(R.string.manual_input), 112) // 添加手动输入选项
|
||||
)
|
||||
} else {
|
||||
arrayListOf(
|
||||
SelectItem(getString(R.string.sys_folder_picker), HandleFileContract.DIR),
|
||||
SelectItem(getString(R.string.app_folder_picker), 10),
|
||||
SelectItem(getString(R.string.manual_input), 112) // 添加手动输入选项
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFileActions(): ArrayList<SelectItem<Int>> {
|
||||
return arrayListOf(
|
||||
SelectItem(getString(R.string.sys_file_picker), HandleFileContract.FILE),
|
||||
SelectItem(getString(R.string.app_file_picker), 11)
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkPermissions(success: (() -> Unit)? = null) {
|
||||
PermissionsCompat.Builder()
|
||||
.addPermissions(*Permissions.Group.STORAGE)
|
||||
.rationale(R.string.tip_perm_request_storage)
|
||||
.onGranted {
|
||||
success?.invoke()
|
||||
}
|
||||
.onDenied {
|
||||
finish()
|
||||
}
|
||||
.onError {
|
||||
finish()
|
||||
}
|
||||
.request()
|
||||
}
|
||||
|
||||
private fun typesOfExtensions(allowExtensions: Array<String>?): Array<String> {
|
||||
val types = hashSetOf<String>()
|
||||
if (allowExtensions.isNullOrEmpty()) {
|
||||
types.add("*/*")
|
||||
} else {
|
||||
allowExtensions.forEach {
|
||||
when (it) {
|
||||
"*" -> types.add("*/*")
|
||||
"txt", "xml" -> types.add("text/*")
|
||||
else -> {
|
||||
val mime = MimeTypeMap.getSingleton()
|
||||
.getMimeTypeFromExtension(it)
|
||||
?: "application/octet-stream"
|
||||
types.add(mime)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return types.toTypedArray()
|
||||
}
|
||||
|
||||
override fun onResult(data: Intent) {
|
||||
val uri = data.data
|
||||
uri ?: let {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
if (mode == HandleFileContract.EXPORT) {
|
||||
getFileData()?.let { fileData ->
|
||||
viewModel.saveToLocal(uri, fileData.first, fileData.second) { savedUri ->
|
||||
setResult(RESULT_OK, Intent().setData(savedUri))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data.putExtra("value", intent.getStringExtra("value"))
|
||||
setResult(RESULT_OK, data)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import io.legato.kazusa.help.IntentData
|
||||
import io.legato.kazusa.lib.dialogs.SelectItem
|
||||
import io.legato.kazusa.utils.RealPathUtil
|
||||
import io.legato.kazusa.utils.externalFiles
|
||||
import io.legato.kazusa.utils.putJson
|
||||
import splitties.init.appCtx
|
||||
|
||||
@Suppress("unused")
|
||||
class HandleFileContract :
|
||||
ActivityResultContract<(HandleFileContract.HandleFileParam.() -> Unit)?, HandleFileContract.Result>() {
|
||||
|
||||
private var requestCode: Int = 0
|
||||
|
||||
override fun createIntent(context: Context, input: (HandleFileParam.() -> Unit)?): Intent {
|
||||
val intent = Intent(context, HandleFileActivity::class.java)
|
||||
val handleFileParam = HandleFileParam()
|
||||
input?.let {
|
||||
handleFileParam.apply(input)
|
||||
}
|
||||
handleFileParam.let {
|
||||
requestCode = it.requestCode
|
||||
intent.putExtra("mode", it.mode)
|
||||
intent.putExtra("title", it.title)
|
||||
intent.putExtra("allowExtensions", it.allowExtensions)
|
||||
intent.putJson("otherActions", it.otherActions)
|
||||
it.fileData?.let { fileData ->
|
||||
intent.putExtra("fileName", fileData.name)
|
||||
intent.putExtra("fileKey", IntentData.put(fileData.data))
|
||||
intent.putExtra("contentType", fileData.type)
|
||||
}
|
||||
intent.putExtra("value", it.value)
|
||||
}
|
||||
return intent
|
||||
}
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): Result {
|
||||
val uri = if (resultCode != RESULT_OK || intent?.data == null ||
|
||||
RealPathUtil.getTreePath(intent.data!!)
|
||||
?.startsWith(appCtx.externalFiles.parent!!) == true
|
||||
) {
|
||||
null
|
||||
} else {
|
||||
intent.data
|
||||
}
|
||||
return Result(uri, requestCode, intent?.getStringExtra("value"))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DIR = 0
|
||||
const val FILE = 1
|
||||
const val DIR_SYS = 2
|
||||
const val EXPORT = 3
|
||||
}
|
||||
|
||||
@Suppress("ArrayInDataClass")
|
||||
data class HandleFileParam(
|
||||
var mode: Int = DIR,
|
||||
var title: String? = null,
|
||||
var allowExtensions: Array<String> = arrayOf(),
|
||||
var otherActions: ArrayList<SelectItem<Int>>? = null,
|
||||
var fileData: FileData? = null,
|
||||
var requestCode: Int = 0,
|
||||
var value: String? = null
|
||||
)
|
||||
|
||||
data class Result(
|
||||
val uri: Uri?,
|
||||
val requestCode: Int,
|
||||
val value: String?
|
||||
)
|
||||
|
||||
data class FileData(
|
||||
val name: String,
|
||||
val data: Any,
|
||||
val type: String
|
||||
)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.legato.kazusa.ui.file
|
||||
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import io.legato.kazusa.base.BaseViewModel
|
||||
import io.legato.kazusa.constant.AppLog
|
||||
import io.legato.kazusa.help.DirectLinkUpload
|
||||
import io.legato.kazusa.utils.*
|
||||
|
||||
import java.io.File
|
||||
|
||||
class HandleFileViewModel(application: Application) : BaseViewModel(application) {
|
||||
|
||||
val errorLiveData = MutableLiveData<String>()
|
||||
|
||||
fun upload(
|
||||
fileName: String,
|
||||
file: Any,
|
||||
contentType: String,
|
||||
success: (url: String) -> Unit
|
||||
) {
|
||||
execute {
|
||||
DirectLinkUpload.upLoad(fileName, file, contentType)
|
||||
}.onSuccess {
|
||||
success.invoke(it)
|
||||
}.onError {
|
||||
AppLog.put("上传文件失败\n${it.localizedMessage}", it)
|
||||
it.printOnDebug()
|
||||
errorLiveData.postValue(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveToLocal(uri: Uri, fileName: String, data: Any, success: (uri: Uri) -> Unit) {
|
||||
execute {
|
||||
val bytes = when (data) {
|
||||
is File -> data.readBytes()
|
||||
is ByteArray -> data
|
||||
is String -> data.toByteArray()
|
||||
else -> GSON.toJson(data).toByteArray()
|
||||
}
|
||||
return@execute if (uri.isContentScheme()) {
|
||||
val doc = DocumentFile.fromTreeUri(context, uri)!!
|
||||
doc.findFile(fileName)?.delete()
|
||||
val newDoc = doc.createFile("", fileName)
|
||||
newDoc!!.writeBytes(context, bytes)
|
||||
newDoc.uri
|
||||
} else {
|
||||
val file = File(uri.path ?: uri.toString())
|
||||
val newFile = FileUtils.createFileIfNotExist(file, fileName)
|
||||
newFile.writeBytes(bytes)
|
||||
Uri.fromFile(newFile)
|
||||
}
|
||||
}.onError {
|
||||
it.printOnDebug()
|
||||
errorLiveData.postValue(it.localizedMessage)
|
||||
}.onSuccess {
|
||||
success.invoke(it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
package io.legato.kazusa.ui.file.utils;
|
||||
|
||||
/**
|
||||
* Generated by https://github.com/gzu-liyujiang/Image2ByteVar
|
||||
*
|
||||
* @author 李玉江[QQ:1023694760]
|
||||
* @since 2017/01/04 06:03
|
||||
*/
|
||||
public class FilePickerIcon {
|
||||
|
||||
public static byte[] getFile() {
|
||||
return FILE;
|
||||
}
|
||||
|
||||
public static byte[] getFolder() {
|
||||
return FOLDER;
|
||||
}
|
||||
|
||||
public static byte[] getHome() {
|
||||
return HOME;
|
||||
}
|
||||
|
||||
public static byte[] getUpDir() {
|
||||
return UPDIR;
|
||||
}
|
||||
|
||||
public static byte[] getArrow() {
|
||||
return ARROW;
|
||||
}
|
||||
|
||||
// fixed: 17-1-7 "static final" arrays should be "private"
|
||||
private static final byte[] FILE = {
|
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42,
|
||||
0, 0, 0, 40, 8, 6, 0, 0, 0, -120, 11, 104, 80, 0, 0, 0, 6, 98, 75, 71,
|
||||
68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 0, 9, 112, 72, 89, 115, 0,
|
||||
0, 14, -60, 0, 0, 14, -60, 1, -107, 43, 14, 27, 0, 0, 1, -73, 73, 68, 65, 84,
|
||||
88, -123, -19, -106, 63, 75, 3, 49, 24, -121, 127, -74, 69, -37, 110, -30, -94, -109, -120, -126,
|
||||
-125, -101, 56, 72, 63, -125, -97, -64, -63, 77, 28, 69, 20, 81, 68, 113, 83, 113, -12, 91,
|
||||
-120, -96, -117, -120, -85, 31, 65, 29, 28, -100, -124, -94, -101, 46, -83, -105, 92, 114, 113, -24,
|
||||
31, -38, -110, 59, -34, -9, 114, 87, 69, -14, 64, 41, -92, 73, -34, -89, -55, -17, 114, 1,
|
||||
60, 30, -113, -25, 79, 50, 66, -19, 120, -7, 16, 26, 0, -112, 82, -61, 24, 3, 41, 35,
|
||||
0, -128, 20, 10, 74, 69, -48, 58, -126, 82, -90, -37, -90, -75, -127, 82, 81, 119, 124, 16,
|
||||
40, -100, 109, 79, -109, -21, 13, 82, -94, 118, -108, 82, 99, -91, 54, -58, 25, 2, 0, 120,
|
||||
-85, 7, -72, -71, 127, -57, -18, -58, 12, -102, -51, 87, 115, 113, 56, -105, 74, -74, 64, -19,
|
||||
104, -116, 73, 51, 63, 0, -96, 88, 104, -107, 57, -34, -102, -59, -6, -63, 75, -86, -119, -56,
|
||||
-94, -99, -83, -26, -96, 123, -122, 20, -37, -107, 78, -9, -25, -79, -74, -13, -52, -106, 37, -117,
|
||||
114, -23, 72, 42, 109, -96, -93, 8, 66, 0, -97, 95, -83, -49, -55, -34, 2, 86, 55, 31,
|
||||
89, -78, -12, -116, 10, -59, 18, -20, 48, 90, -86, -96, -47, -48, -72, -66, -5, 64, -40, -98,
|
||||
-94, 90, -27, -81, 15, 89, -76, -9, 9, -114, 99, 80, 18, 0, -90, 38, -127, -38, -46, 4,
|
||||
-76, 78, -97, 113, -128, 33, 42, -124, 78, -4, -35, 38, -87, -62, -42, -9, -14, -30, 120, 127,
|
||||
-69, 6, -82, 110, -21, -44, -46, 0, -72, 103, 77, 12, 73, -110, 125, 109, -55, -1, 53, 17,
|
||||
86, 70, 109, 66, 113, -72, 72, -39, 32, -89, -38, 53, 99, -82, 100, -14, 48, -39, -74, 57,
|
||||
107, -100, -49, -47, -84, -77, 24, 7, 121, 69, -125, -64, 126, -114, 82, -91, -66, 3, 106, 37,
|
||||
59, -12, 21, 85, -46, -87, 80, -91, -20, 52, -100, 46, -38, -108, -87, 111, 104, -103, -64, 58,
|
||||
71, -121, -15, -48, -60, -63, -54, -24, -80, -14, 104, 35, -73, -37, 83, -42, -112, 69, 5, -15,
|
||||
-10, -108, 23, -12, 3, 63, -92, -65, 63, 43, 101, -5, -10, 7, 14, -111, 112, -66, -108, -28,
|
||||
-111, 71, 27, -1, 47, -93, -65, 77, 38, -9, 81, 27, 46, 121, -76, -63, 18, 29, 86, 30,
|
||||
109, -80, 68, -113, -50, -97, -14, -14, -16, 120, 60, -98, 1, 126, 0, -110, 81, -78, -5, 36,
|
||||
19, -64, 3, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126};
|
||||
private static final byte[] FOLDER = {
|
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42,
|
||||
0, 0, 0, 40, 8, 6, 0, 0, 0, -120, 11, 104, 80, 0, 0, 0, 6, 98, 75, 71,
|
||||
68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 0, 9, 112, 72, 89, 115, 0,
|
||||
0, 14, -60, 0, 0, 14, -60, 1, -107, 43, 14, 27, 0, 0, 2, -102, 73, 68, 65, 84,
|
||||
88, -123, -19, -105, 61, -113, 19, 49, 16, -122, 95, 111, -110, 75, -124, -124, -60, -49, 65, 20,
|
||||
-48, 34, 81, 80, 32, 81, 83, 80, -94, 52, 72, 8, 78, 66, -94, 64, 20, -108, 124, 20,
|
||||
39, -47, 64, -51, -11, -7, 87, -96, 11, -38, -75, 61, 99, 15, -59, 110, 54, 118, -42, -5,
|
||||
113, -71, 77, 117, -5, 54, -55, -50, -38, -42, -77, -81, 61, 99, 27, -104, 52, 105, -46, -92,
|
||||
73, -73, 66, 106, 104, -61, -51, 57, -92, -21, -3, -29, 79, -61, -57, 58, 70, -13, 33, -115,
|
||||
54, -25, -112, 71, -17, 127, 0, 0, -106, -38, -105, 65, 93, 64, -56, 0, 108, 33, 76, -72,
|
||||
-28, -113, -14, -20, -77, 59, 25, 108, 54, 4, -14, -63, -6, 59, -112, 123, -84, -4, -84, -114,
|
||||
-117, 39, 96, -74, -17, -2, -12, -59, 91, 92, -66, -103, 117, -70, 126, 19, 117, 58, -80, 57,
|
||||
-121, 60, 92, 127, 5, 0, -84, -106, -53, -3, 11, 93, -108, -96, 0, 96, 52, -124, 9, 96,
|
||||
6, 116, -127, -33, -65, -66, -44, -51, 56, -117, -121, -73, 62, 3, -7, 56, -74, 123, 126, -11,
|
||||
-83, -24, 100, -23, -99, -6, -43, -67, -5, -119, -96, -119, -66, 80, 1, -128, 49, 0, -128, -25,
|
||||
31, -98, -108, 65, 103, -93, 46, -62, -36, 24, -58, -27, -37, -6, -65, -39, -66, -108, -41, 63,
|
||||
-13, 86, -40, 65, 107, 84, -7, 43, 64, -103, 70, 92, 108, 17, -45, 82, -94, -115, -47, 77,
|
||||
-40, -22, 35, -108, 53, 32, 34, 56, 34, 112, -49, -14, 30, 4, 90, 66, -2, -119, 99, -34,
|
||||
2, -69, -23, -33, -119, -10, -32, 18, -66, -37, -63, 114, 16, 99, -122, 2, -64, 87, 127, 97,
|
||||
-56, -61, -53, 24, -96, -121, -14, -107, 35, 103, 11, -120, -91, 116, 27, -25, -45, -15, 96, 9,
|
||||
80, -95, 97, -56, -61, 114, 127, 14, -10, 102, 125, 27, 36, -128, 86, -56, -70, 34, -52, 50,
|
||||
-128, 109, -78, 77, 40, 118, -82, -73, 77, -65, -93, 98, 26, -128, -111, -62, 41, 62, -101, 67,
|
||||
116, -111, 110, -41, 34, -53, 2, -26, 22, -9, 3, 29, 53, -11, -111, -109, -39, -94, -4, -83,
|
||||
0, 85, -74, -120, -41, -25, 72, -22, 4, -27, -86, -58, -119, 45, -102, -119, 3, 52, -36, -124,
|
||||
61, 40, 65, 81, -58, 55, -5, -117, 99, -80, 115, -89, 115, 52, 9, 93, 65, -90, -36, 76,
|
||||
65, 94, 87, -67, -96, 74, -52, -2, 52, -46, 54, -91, -95, -109, -119, 108, 87, -13, -59, 126,
|
||||
-9, 74, 40, -109, 27, 58, 106, 124, 6, -79, 40, -117, -7, 33, 100, 0, 23, -71, -72, -37,
|
||||
-1, -85, 105, 31, -61, 77, 96, -24, -44, -109, 1, 40, -19, 70, 50, 113, -126, -75, -39, -22,
|
||||
-26, 53, -85, -61, 113, 89, 127, 8, 23, 78, 119, 80, 55, -5, -36, -12, 117, 34, -11, 23,
|
||||
-4, 78, 80, -14, 10, 112, 22, -30, 92, -5, -6, 28, 2, 25, -70, -103, 112, -46, -75, -19,
|
||||
98, 67, 65, 57, 60, -110, -11, 13, 118, 4, -92, -9, 2, 79, 4, -94, 17, 118, 38, 97,
|
||||
6, -104, 64, -108, -34, -103, -124, -35, -63, 115, -20, -68, -46, 58, 124, 2, 0, 56, 91, -18,
|
||||
118, -123, -74, -48, 122, 88, -78, 117, -126, 90, 95, 102, -80, 49, 5, -88, 26, 80, -101, -46,
|
||||
33, 83, -24, -42, 126, 53, 116, 42, 97, -104, -22, 2, -97, 111, 115, 108, -13, 17, 64, 1,
|
||||
-64, 85, 103, 71, 50, 84, 1, -106, 110, 88, 106, 95, 10, 93, -5, -67, -81, 62, -44, 22,
|
||||
26, 84, 1, -33, -67, -77, -24, 5, -19, -67, -116, 93, -84, 87, 2, 32, -70, 66, -104, -32,
|
||||
-112, -53, 94, -63, -113, 112, 1, 125, 119, -15, -17, -92, -73, -40, 73, -109, 38, 77, -70, -19,
|
||||
-6, 15, -2, -54, -98, -96, -19, -118, -95, -10, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66,
|
||||
96, -126};
|
||||
private static final byte[] HOME = {
|
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42,
|
||||
0, 0, 0, 40, 8, 4, 0, 0, 0, 34, 2, -96, -37, 0, 0, 0, 1, 115, 82, 71,
|
||||
66, 0, -82, -50, 28, -23, 0, 0, 0, 2, 98, 75, 71, 68, 0, -1, -121, -113, -52, -65,
|
||||
0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 46, 35, 0, 0, 46, 35, 1, 120, -91, 63,
|
||||
118, 0, 0, 0, 7, 116, 73, 77, 69, 7, -37, 8, 4, 10, 36, 16, -22, -9, -18, -50,
|
||||
0, 0, 2, -84, 73, 68, 65, 84, 72, -57, -19, -106, 91, 72, 20, 97, 20, -57, 127, -77,
|
||||
-18, -106, -41, 54, -14, -106, -23, -102, 4, 21, 97, 5, 5, 61, 70, 74, -76, -122, -94, -11,
|
||||
18, -108, -92, 121, 41, 16, -124, 96, -95, 48, -118, -108, -94, 18, -70, 96, 33, 68, -81, -127,
|
||||
15, 25, 68, 15, 21, 89, 80, 42, 25, 42, -91, 97, -106, -103, -122, 107, 41, -19, -86, -37,
|
||||
-22, 122, -39, 77, -73, -103, -81, 7, -105, 84, -36, -85, -26, -125, -44, -127, -31, 59, -52, -103,
|
||||
-7, 113, -50, -103, -17, -4, -65, -127, -1, -74, 44, 76, -102, 113, -29, 22, -119, 50, -3, -15,
|
||||
84, 75, -111, -87, -38, -81, -89, 84, 24, -120, 1, -96, -106, -102, -65, 83, -66, -118, 59, -119,
|
||||
39, 54, 97, 69, -31, -109, 115, -14, 8, 15, 124, -107, -17, 27, 42, 113, 123, 125, 81, 46,
|
||||
102, 28, 8, -84, -68, 116, 78, -26, 80, 77, 5, -79, 104, -48, -48, 70, -39, 124, -88, -38,
|
||||
103, 37, -107, -70, -94, 28, -6, 105, 7, 34, 89, 67, -86, -90, -74, 106, 82, -51, 65, 125,
|
||||
-110, 13, 27, -99, 43, 2, -17, -87, -60, -51, -124, -30, 99, -104, -88, -63, -12, 20, -93, -90,
|
||||
96, 111, -80, -106, 20, 117, -3, -35, -97, -65, 54, -13, 29, 21, 8, -9, -3, -14, -122, -68,
|
||||
17, 127, 50, 15, 51, -49, 49, 85, -109, 73, -79, 51, -81, 94, -103, 96, 21, 123, -126, 66,
|
||||
86, 10, 64, 4, 12, -107, -72, -70, -50, -112, -57, 0, 47, -24, 123, 66, 46, 50, 80, -19,
|
||||
40, 121, -59, 20, -31, -20, 102, 0, 121, 1, -48, -14, -72, 83, -7, 12, 81, -121, -79, -106,
|
||||
67, 76, -71, -18, 94, -73, 85, 54, 34, 19, -122, 115, -102, 23, 16, -12, 114, 92, 73, 1,
|
||||
22, 26, -24, 110, -26, 0, -114, 89, 17, -61, -32, -61, 22, 4, 2, -127, -30, -31, 125, -9,
|
||||
-48, -117, -79, 103, -13, -79, -48, 68, -57, 123, -46, 25, -101, 19, -109, 57, -38, -41, -40, -127,
|
||||
64, 16, -127, 70, -113, -34, 63, 104, 105, -52, -7, 2, -84, -76, -48, -42, 69, 26, -42, 121,
|
||||
113, 59, 89, 93, -35, -67, 8, -126, -39, -87, 81, -35, 103, -69, 111, -24, -71, -24, 11, -123,
|
||||
12, -45, -58, -37, -81, -20, -61, -20, -74, 18, 11, -23, -19, -125, 102, 20, -76, 36, 107, 121,
|
||||
76, -68, 119, -24, -103, -88, 75, -123, -116, -16, -111, 38, 51, 122, -66, 121, -4, -116, 95, 68,
|
||||
-42, 59, -5, 8, -126, 24, 54, -24, 120, 68, -124, 103, -24, -23, -88, -14, -29, -40, -24, -28,
|
||||
-75, 85, -92, -47, -27, 117, 48, -102, -27, -20, 86, 121, 28, 5, 29, 107, 119, 112, 111, -10,
|
||||
24, 5, -51, -72, 17, -122, -32, 107, -39, -110, -99, 30, -22, -58, -108, -3, -76, -6, 20, -93,
|
||||
-49, -78, -59, -102, 17, -50, 40, -126, -47, -115, 66, 59, 94, -29, 78, 80, -86, -40, 74, -108,
|
||||
20, -119, 34, 50, -88, -13, 83, 58, -81, -112, 73, 47, 70, -116, 52, -104, -34, 120, 86, 41,
|
||||
-119, 4, 10, 1, 24, -26, -106, 71, 88, 10, 41, 0, 60, -93, -47, 31, -107, 18, -124, -123,
|
||||
-106, -19, -30, 7, 31, 122, -68, 64, 83, 19, 75, -75, -12, 51, 108, -101, -127, -6, -40, -4,
|
||||
97, -92, -110, -20, 67, 18, -109, -40, -58, 106, -113, -86, -66, 96, 83, -36, 15, -2, 34, -96,
|
||||
-110, 88, 8, 84, -8, 60, -37, 60, 67, -43, -18, -127, 2, 1, 26, -74, 120, -124, 70, 11,
|
||||
20, -108, 64, -113, 104, -119, 88, -99, -24, 112, -105, -71, 112, 117, -44, 22, 88, -90, 32, 8,
|
||||
-27, 48, 33, 76, 119, 78, -52, 89, 101, 20, -100, -12, 49, 21, 24, 84, 97, 12, 59, 19,
|
||||
46, -44, -36, 75, 65, 70, 70, 118, -83, -2, 67, 101, -21, 80, -123, -65, -69, -64, -79, -68,
|
||||
127, -48, -106, 4, -6, -113, -37, 111, 38, -57, 11, 112, 71, 102, 113, -50, 0, 0, 0, 0,
|
||||
73, 69, 78, 68, -82, 66, 96, -126};
|
||||
private static final byte[] UPDIR = {
|
||||
-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 42,
|
||||
0, 0, 0, 40, 8, 6, 0, 0, 0, -120, 11, 104, 80, 0, 0, 0, 6, 98, 75, 71,
|
||||
68, 0, -1, 0, -1, 0, -1, -96, -67, -89, -109, 0, 0, 0, 9, 112, 72, 89, 115, 0,
|
||||
0, 14, -60, 0, 0, 14, -60, 1, -107, 43, 14, 27, 0, 0, 2, -111, 73, 68, 65, 84,
|
||||
88, -123, -19, -106, -51, 74, -21, 64, 20, -57, -1, -87, -47, 7, -15, 41, 92, 118, -47, 82,
|
||||
10, -59, 110, 20, -95, 32, 77, -101, 44, -92, -37, -66, 80, -23, 3, 8, -126, -76, -48, -115,
|
||||
-120, 43, 117, -19, -109, -44, -113, -50, -57, -103, 115, 87, 103, 76, 106, -117, 77, 19, -17, -107,
|
||||
75, -2, 48, -52, -112, 100, 38, -65, 57, -25, -52, 57, 3, 84, -86, 84, -87, -46, -1, -83,
|
||||
36, 73, 56, 73, 18, -2, -87, -11, -61, 50, 22, -119, -29, -104, 47, 47, 47, 97, -116, -127,
|
||||
-75, -106, 39, -109, 73, 80, -58, -70, 105, 21, 94, 48, -114, 99, 78, -110, 4, 68, 4, -91,
|
||||
20, -116, 49, 120, 121, 121, -63, 120, 60, 46, 21, -74, 86, 100, -14, 112, 56, -28, -85, -85,
|
||||
43, 0, -128, -75, 22, -50, 57, 48, 51, -114, -113, -113, -47, -21, -11, 74, 13, -125, -67, 65,
|
||||
-121, -61, 33, -113, 70, 35, 4, 65, 0, 99, -116, 111, -42, 90, 16, 17, 58, -99, 14, 46,
|
||||
46, 46, 74, -125, -35, 11, 84, 44, -23, -100, -61, -57, -57, 7, 86, -85, 21, -116, 49, 32,
|
||||
34, 111, 89, 107, 45, 90, -83, 22, -50, -50, -50, 74, -127, -51, 125, -104, 6, -125, 1, -57,
|
||||
113, -20, -83, -89, -108, -126, -75, 22, 0, -32, -100, -13, 45, 8, 2, 48, 51, -102, -51, 38,
|
||||
-100, 115, 124, 125, 125, 93, 40, 102, 115, -127, 14, 6, 3, -114, -94, -56, -69, 87, 107, 13,
|
||||
34, 2, 0, -1, 44, 8, -78, 60, 68, -124, 70, -93, 1, 34, -30, -101, -101, -101, -67, 97,
|
||||
119, 6, -115, -94, -120, 123, -67, -98, -121, 19, 43, 10, -88, -12, -58, 24, 56, -25, -4, 55,
|
||||
-78, -127, 122, -67, 14, 34, -30, -37, -37, -37, -67, 96, 119, -102, 20, 69, 17, 119, -69, 93,
|
||||
15, 98, -83, -59, -63, -63, 1, 0, 32, 12, -61, 12, -88, -124, -61, -37, -37, 27, -34, -33,
|
||||
-33, -3, -122, 68, 15, 15, 15, -104, -49, -25, -71, 97, -65, -99, -48, -17, -9, -71, -35, 110,
|
||||
-5, 83, 45, 58, 58, 58, -14, -112, 34, -79, -30, -21, -21, 43, -106, -53, 37, -76, -42, 0,
|
||||
0, -26, -49, -13, 20, -122, 33, -18, -17, -17, -79, 88, 44, 114, -63, 126, -21, 122, 102, -58,
|
||||
108, 54, -13, 22, 19, 32, 0, 56, 61, 61, -3, -14, 76, 107, -115, -43, 106, 5, 34, -62,
|
||||
-45, -45, 83, -26, -35, -6, -72, 84, -48, -23, 116, -70, 113, -25, -25, -25, -25, -20, -100, -53,
|
||||
-4, 60, 29, -109, 114, -6, 103, -77, 89, 41, 21, 106, -17, 90, 47, -112, 2, 8, -64, 3,
|
||||
-118, -85, -45, -33, 20, -43, -34, -96, -52, -100, 57, -35, -64, 103, -116, -82, 3, -1, 83, 80,
|
||||
-87, 62, 2, -72, -98, 79, 5, -74, 44, -107, 2, 42, 112, 0, 50, -15, -7, 43, 64, -103,
|
||||
121, 35, -24, -81, 118, -67, -28, -41, -76, -53, -91, -43, -21, 117, -106, 119, -23, 94, -58, -113,
|
||||
-113, -113, 59, 101, -123, -62, -96, -101, -54, -87, 88, -14, -28, -28, 4, -121, -121, -121, 25, 48,
|
||||
-71, 35, 40, -91, -16, -4, -4, -68, -13, -1, 10, -71, 62, 125, -75, 91, 7, -83, -43, 106,
|
||||
30, 74, 42, -104, -28, 89, -83, 53, -76, -42, -71, 98, -72, -112, 69, -91, 68, 110, -69, -96,
|
||||
-92, 123, -7, 70, 41, 5, -91, 84, -18, 10, 85, 10, 104, 58, 70, -45, 125, -6, -80, 73,
|
||||
47, 22, -51, -85, 66, -82, 87, 74, 1, -128, -17, 55, -127, 109, 2, -1, -85, -96, 98, -47,
|
||||
-76, 91, -73, 1, -82, -113, 1, -8, 107, -30, -113, -125, -34, -35, -35, 5, 68, -28, 19, -27,
|
||||
-74, -12, 83, 102, -46, -81, 84, -87, 82, -91, 95, -88, 63, 49, -122, -88, 68, 127, -55, -90,
|
||||
73, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126};
|
||||
private static final byte[] ARROW = {-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 48,
|
||||
0, 0, 0, 117, 8, 3, 0, 0, 0, 63, 73, -110, 106, 0, 0, 2, -9, 80, 76, 84,
|
||||
69, -46, -46, -46, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -65, -65, -65, 0,
|
||||
0, 0, -52, -52, -52, -49, -49, -49, -47, -47, -47, -47, -47, -47, -48, -48, -48, -54, -54, -54,
|
||||
-48, -48, -48, -48, -48, -48, -47, -47, -47, -47, -47, -47, -49, -49, -49, -86, -86, -86, -48, -48,
|
||||
-48, -48, -48, -48, -47, -47, -47, -52, -52, -52, -49, -49, -49, -48, -48, -48, -48, -48, -48, -1,
|
||||
-1, -1, -49, -49, -49, -48, -48, -48, -48, -48, -48, -51, -51, -51, -50, -50, -50, -48, -48, -48,
|
||||
-48, -48, -48, -50, -50, -50, -48, -48, -48, -48, -48, -48, -48, -48, -48, -52, -52, -52, -48, -48,
|
||||
-48, -48, -48, -48, -48, -48, -48, -46, -46, -46, -47, -47, -47, -52, -52, -52, -48, -48, -48, -48,
|
||||
-48, -48, -1, -1, -1, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
|
||||
-48, -48, -48, -41, -41, -41, -48, -48, -48, -49, -49, -49, -43, -43, -43, -47, -47, -47, -49, -49,
|
||||
-49, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -49, -49, -49, -47,
|
||||
-47, -47, -49, -49, -49, -47, -47, -47, -48, -48, -48, -48, -48, -48, -48, -48, -48, -49, -49, -49,
|
||||
-47, -47, -47, -44, -44, -44, -48, -48, -48, -48, -48, -48, -1, -1, -1, -46, -46, -46, -48, -48,
|
||||
-48, -49, -49, -49, -47, -47, -47, -49, -49, -49, -35, -35, -35, -49, -49, -49, -49, -49, -49, -49,
|
||||
-49, -49, -47, -47, -47, -40, -40, -40, -49, -49, -49, -48, -48, -48, -48, -48, -48, -47, -47, -47,
|
||||
-47, -47, -47, -47, -47, -47, -48, -48, -48, -60, -60, -60, -53, -53, -53, -48, -48, -48, -46, -46,
|
||||
-46, -65, -65, -65, -48, -48, -48, -54, -54, -54, -45, -45, -45, -47, -47, -47, -49, -49, -49, -48,
|
||||
-48, -48, -49, -49, -49, -51, -51, -51, -48, -48, -48, -48, -48, -48, -46, -46, -46, -47, -47, -47,
|
||||
-47, -47, -47, -37, -37, -37, -47, -47, -47, -49, -49, -49, -50, -50, -50, -48, -48, -48, -128, -128,
|
||||
-128, -48, -48, -48, -48, -48, -48, -50, -50, -50, -48, -48, -48, -48, -48, -48, -43, -43, -43, -47,
|
||||
-47, -47, -48, -48, -48, -48, -48, -48, -48, -48, -48, -43, -43, -43, -47, -47, -47, -48, -48, -48,
|
||||
-50, -50, -50, -49, -49, -49, -48, -48, -48, -48, -48, -48, -33, -33, -33, -48, -48, -48, -52, -52,
|
||||
-52, -51, -51, -51, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -52,
|
||||
-52, -52, -48, -48, -48, -46, -46, -46, -48, -48, -48, -37, -37, -37, -29, -29, -29, -48, -48, -48,
|
||||
-48, -48, -48, -47, -47, -47, -48, -48, -48, -49, -49, -49, -46, -46, -46, -48, -48, -48, -49, -49,
|
||||
-49, -47, -47, -47, -58, -58, -58, -49, -49, -49, -47, -47, -47, -48, -48, -48, -50, -50, -50, -47,
|
||||
-47, -47, -50, -50, -50, -48, -48, -48, -48, -48, -48, -50, -50, -50, -48, -48, -48, -48, -48, -48,
|
||||
-48, -48, -48, -55, -55, -55, -45, -45, -45, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
|
||||
-48, -46, -46, -46, -47, -47, -47, -48, -48, -48, -47, -47, -47, -51, -51, -51, -47, -47, -47, -51,
|
||||
-51, -51, -48, -48, -48, -47, -47, -47, -48, -48, -48, -65, -65, -65, -48, -48, -48, -50, -50, -50,
|
||||
-48, -48, -48, -47, -47, -47, -49, -49, -49, -47, -47, -47, -47, -47, -47, -48, -48, -48, -48, -48,
|
||||
-48, -50, -50, -50, -47, -47, -47, -49, -49, -49, -49, -49, -49, -47, -47, -47, -48, -48, -48, -47,
|
||||
-47, -47, -49, -49, -49, -39, -39, -39, -50, -50, -50, -47, -47, -47, -48, -48, -48, -42, -42, -42,
|
||||
-47, -47, -47, -46, -46, -46, -47, -47, -47, -47, -47, -47, -48, -48, -48, -49, -49, -49, -49, -49,
|
||||
-49, -47, -47, -47, -48, -48, -48, -47, -47, -47, -48, -48, -48, -50, -50, -50, -47, -47, -47, -48,
|
||||
-48, -48, -47, -47, -47, -49, -49, -49, -48, -48, -48, -49, -49, -49, -50, -50, -50, -47, -47, -47,
|
||||
-56, -56, -56, -48, -48, -48, -48, -48, -48, -40, -40, -40, -45, -45, -45, -47, -47, -47, -47, -47,
|
||||
-47, -49, -49, -49, -48, -48, -48, -43, -43, -43, -52, -52, -52, -49, -49, -49, -47, -47, -47, -47,
|
||||
-47, -47, -50, -50, -50, -49, -49, -49, -47, -47, -47, -49, -49, -49, -48, -48, -48, -49, -49, -49,
|
||||
-115, 52, -27, 40, 0, 0, 0, -3, 116, 82, 78, 83, 34, -37, -1, -7, 120, 4, 0, 5,
|
||||
118, -9, -41, 38, 24, -46, -2, -100, 78, 69, 3, -98, -54, 28, 40, -37, -8, 115, 3, 122,
|
||||
-6, -43, 36, 31, -49, -109, 78, 70, -93, -50, 20, 43, -38, -10, 113, 123, 30, -45, -115, 2,
|
||||
86, -5, -9, 65, -94, -55, 19, -29, 111, 6, 127, 32, -39, -3, -114, 92, -4, 58, -86, -63,
|
||||
22, -32, 109, -126, -5, -51, 36, -44, -121, 1, 90, -11, 59, -79, -59, 15, 48, -11, 106, -123,
|
||||
26, 37, -40, 98, -3, -14, -80, -61, 13, 44, -25, 103, 8, -120, 29, 35, -35, -4, -127, 101,
|
||||
46, -76, -71, 17, -24, 99, 7, -118, -58, 42, 124, 2, 103, -13, 47, -67, -65, 12, 55, -27,
|
||||
-116, -57, 24, 44, -35, 119, 112, -21, 49, 8, -70, 10, 51, -19, -14, 93, -111, -62, 25, -30,
|
||||
119, -78, 14, 9, -108, 113, 117, -18, -53, 63, -23, -15, 89, 9, -106, -2, -66, 21, 50, -125,
|
||||
-33, -28, 57, 97, -97, -73, 19, 69, -12, -17, 81, -87, 57, 94, -99, -73, 72, -18, 82, -88,
|
||||
-20, 27, 12, -100, 67, -16, 83, 16, -91, -122, 54, -26, 104, -101, 64, 85, 11, -82, 100, -101,
|
||||
20, 84, -47, 125, 31, -102, 62, -57, -88, -125, 107, -102, -69, -15, -53, -77, 52, -31, -105, 66,
|
||||
-21, 87, 121, 110, -67, 23, -60, -84, 13, 46, 111, 88, -75, 119, 42, 50, -32, 106, -107, 63,
|
||||
91, -78, 117, 114, -108, 41, -51, -28, -65, 0, 0, 3, -107, 73, 68, 65, 84, 88, -61, -107,
|
||||
-40, 105, 84, -108, 85, 24, 7, 112, -4, -113, -13, -112, -37, -101, -111, -96, 78, 67, -94, 38,
|
||||
-18, -66, 14, 46, 52, -38, -28, -96, 34, 90, -67, -31, -106, 75, -114, 70, 74, 42, 90, 86,
|
||||
-109, 4, 38, -88, -111, -90, 50, -126, -72, -46, -54, -102, 38, -102, -53, 104, -101, 123, -88, -71,
|
||||
78, -18, -91, -90, 88, 82, 46, 89, 90, -71, -107, -27, 7, 95, 62, 120, -114, -100, -93, -121,
|
||||
-5, 127, 63, -65, -65, 15, -9, -36, 123, -97, -5, 127, -98, -96, -96, 106, -80, 84, -73, -118,
|
||||
-14, 23, 20, -4, 64, 13, -44, -84, 69, 0, -87, 93, 7, -38, -125, 12, -112, -70, 22, -32,
|
||||
33, 6, -124, 60, 12, -44, 11, 37, -128, -124, -43, 71, -125, -122, 33, 4, -80, 61, 98, 71,
|
||||
-8, -93, 4, -112, 70, 17, -48, 26, 51, 64, -102, 0, 53, -102, 50, 64, 30, -45, -48, 44,
|
||||
-110, 1, -51, 91, -96, 101, 43, 43, 1, -84, -83, -19, -88, -39, -122, 0, 18, -38, 22, 104,
|
||||
-89, 19, 64, -38, 59, 16, -43, -127, 1, -42, -114, 64, -89, -50, 4, -112, -80, 104, 68, 61,
|
||||
-82, 19, -64, -39, -59, -126, -120, -82, 4, -112, -48, 39, -32, 122, -110, 1, -46, -51, 1, 119,
|
||||
12, 3, -84, -35, -127, 30, 61, 9, 32, -51, 99, 17, -43, 75, 39, 64, 112, 92, 111, -12,
|
||||
105, 68, 0, 121, -22, 105, 104, -49, 48, -64, 120, 22, -120, -17, 75, 0, -111, 126, 64, -1,
|
||||
1, 12, 24, 24, -117, -25, 6, -39, 8, -32, 28, -20, 64, -77, 33, 4, -112, -95, -49, 3,
|
||||
113, 6, 1, 100, -104, 7, -61, 99, 24, -32, 28, 1, -68, -112, 64, 0, 121, 113, 36, -30,
|
||||
71, -23, 4, 72, 124, -55, -114, 78, -93, 9, 32, 99, -58, 34, 105, 28, 3, 100, -68, 27,
|
||||
13, 94, 102, -128, -13, 21, 96, -62, -85, 4, -112, -127, -81, 33, -2, 117, -125, 0, -34, 55,
|
||||
-110, 48, 49, -108, 0, -110, -36, 2, -82, 55, 25, -112, -110, 10, 76, 122, -117, 0, 34, -109,
|
||||
-127, -76, 116, 6, 76, -103, -118, 73, -61, 116, 2, 120, -89, -71, -15, 118, 6, 1, -28, -99,
|
||||
-23, -64, 12, -125, 0, -58, -69, -64, -52, 89, 4, -112, -39, -26, -70, 51, 125, 4, -112, 57,
|
||||
89, -56, -98, -101, 66, 0, 95, -114, 3, -13, -26, 19, 64, -110, 23, -64, -79, -112, 1, 82,
|
||||
-35, -123, -8, -95, 12, -16, -103, -21, 94, -76, -104, 0, 50, 101, 38, -122, 119, 51, 8, -112,
|
||||
-5, -98, 11, 105, -75, 9, 80, 81, 58, -19, -17, 51, 64, -1, 0, -8, 112, 12, 1, -60,
|
||||
-6, -111, -71, -18, -39, 4, -112, -113, -13, -112, 95, -112, 66, -128, -62, 34, -83, -8, -109, 37,
|
||||
4, -112, -91, -79, -16, -92, 50, -64, -8, 20, 88, -58, 0, -55, 1, 74, 24, -80, 124, 36,
|
||||
44, 43, 8, -112, -16, -103, -85, 120, -27, 42, 2, -84, 94, 3, -1, 90, 67, 29, -92, -41,
|
||||
1, -42, 89, -43, 55, -50, 54, 24, -120, 14, 34, -114, -58, -25, 37, 112, 127, 65, 28, 62,
|
||||
-33, -105, -59, -38, 87, -99, 9, -16, -11, 122, -8, 55, 16, 23, -56, 23, 14, 108, -12, -86,
|
||||
95, 81, 91, 28, -80, 105, 51, 81, 4, -52, 10, 110, 73, 37, -54, -52, -106, -83, 46, -84,
|
||||
-116, 36, -64, 55, 107, 80, -70, -115, -88, -83, -37, -21, 1, 59, -104, 98, -4, -83, -122, -84,
|
||||
-47, 68, -71, -33, -71, 11, -10, -35, -60, 11, -108, -66, -57, -115, -52, 72, 2, -20, -51, -122,
|
||||
127, -97, -95, 14, 2, 17, -64, 119, 78, -11, 103, 87, -17, 98, -34, -29, 90, -60, -61, -66,
|
||||
60, 26, -98, -3, 68, 116, -16, 29, -48, -76, -52, -125, 4, 88, -67, 9, -2, 67, 68, -4,
|
||||
-15, 30, 6, -70, 39, -86, 7, 44, -37, 17, 32, -21, 40, 17, -31, 118, -106, -64, 50, -120,
|
||||
8, -119, -127, -17, 93, -104, -80, -124, 0, 63, 100, 35, -65, 61, -111, -116, -73, 31, 3, -114,
|
||||
7, 8, 112, -62, 60, -43, 109, -120, -80, -66, 116, 42, -20, 63, 18, -3, 67, -32, -92, 27,
|
||||
-89, 14, 18, -96, 111, -39, -67, 79, -11, -3, -128, -17, 52, -16, -109, 83, -67, 105, -46, -51,
|
||||
61, -34, 21, 70, -76, 101, 63, -97, -127, 103, 60, -47, -8, 21, -106, 87, 122, -110, -85, 6,
|
||||
-65, -4, -118, -46, -77, -122, 58, -16, -98, -82, 28, 43, -86, 2, 33, -25, -52, -32, 114, -108,
|
||||
104, -64, -25, -100, -127, -3, 60, -47, -30, -5, -54, 93, -72, -16, 27, 1, 98, -4, -56, 46,
|
||||
32, -26, 26, 9, 23, -127, -33, -1, 32, -64, 17, 13, 101, 42, 73, -27, -50, 63, -105, 74,
|
||||
-48, -5, 50, 49, -3, 9, 20, 37, -95, -86, 61, -82, 4, 98, 74, -111, -1, -89, -95, 14,
|
||||
114, -51, 123, -4, 87, -94, -6, -56, -53, -8, 27, -56, -69, 66, 12, -43, -82, 94, -125, -25,
|
||||
58, 49, -74, 43, -68, -95, 21, 87, 57, -109, -71, 27, -4, -109, -121, -78, 127, 83, -44, -127,
|
||||
-43, 124, -113, 111, 22, -118, 50, -48, -1, 3, -4, -86, -109, -54, 10, 80, 17, -8, -1, 23,
|
||||
117, -112, 123, -53, 108, 41, 50, -44, -63, 109, -80, -19, 79, -78, 17, 39, 44, -102, 0, 0,
|
||||
0, 0, 73, 69, 78, 68, -82, 66, 96, -126};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user