Refactor: separated everything to different activities

This commit is contained in:
leca 2024-10-05 01:56:09 +03:00
parent 19fd23e616
commit 609544c387
20 changed files with 256 additions and 194 deletions

View File

@ -25,7 +25,11 @@
android:theme="@style/Theme.BarcodeScannerForEmployees"
tools:targetApi="31">
<activity
android:name=".FullscreenActivity"
android:name=".activities.AddProductActivity"
android:exported="false"
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
<activity
android:name=".activities.FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false"
android:label="@string/title_activity_fullscreen"
@ -33,20 +37,21 @@
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.google.firebase.components.MainActivity.provider;com.google.firebase.components.FullscreenActivity.provider"
android:authorities="com.google.firebase.components.activities.StorageActivity.provider;com.google.firebase.components.activities.FullscreenActivity.provider;com.google.firebase.components.activities.AddProductActivity.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path"/>
</provider>
<meta-data
android:name="com.google.mlkit.vision.DEPENDENCIES"
android:value="barcode_ui">
</meta-data>
<activity
android:name=".MainActivity"
android:name=".activities.StorageActivity"
android:exported="true"
android:theme="@style/Theme.BarcodeScannerForEmployees">
<intent-filter>

View File

@ -1,42 +0,0 @@
package org.foxarmy.barcodescannerforemployees
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import org.foxarmy.barcodescannerforemployees.databinding.FragmentSecondBinding
/**
* A simple [Fragment] subclass as the second destination in the navigation.
*/
class MainScreenFragment : Fragment() {
private var _binding: FragmentSecondBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentSecondBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// binding..setOnClickListener {
// findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
// }
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -1,59 +1,131 @@
package org.foxarmy.barcodescannerforemployees
package org.foxarmy.barcodescannerforemployees.activities
import android.Manifest
import android.content.ContentValues
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.appcompat.app.AppCompatActivity
import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
import org.foxarmy.barcodescannerforemployees.databinding.AddProductFragmentBinding
import org.foxarmy.barcodescannerforemployees.*
import org.foxarmy.barcodescannerforemployees.databinding.ActivityAddProductBinding
import java.io.File
import java.nio.file.Files
import java.nio.file.StandardCopyOption
class AddProductActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
class AddProductFragment : Fragment() {
private lateinit var saveButton: Button
private lateinit var takePictureButton: Button
private lateinit var scanButton: Button
private lateinit var productNameText: TextView
private lateinit var netWeightText: TextView
private var _binding: AddProductFragmentBinding? = null
private lateinit var pictureFile: File
private val binding get() = _binding!!
private lateinit var picturesPath: File
private lateinit var binding: ActivityAddProductBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
picturesPath = File(requireContext().filesDir, "pictures")
setContentView(R.layout.fragment_add_product)
picturesPath = File(filesDir, "pictures")
picturesPath.mkdirs()
// imageView = binding.includeContent.addProductLayout
imageView = findViewById(R.id.imageView)
saveButton = findViewById(R.id.saveButton)
takePictureButton = findViewById(R.id.takePictureButton)
scanButton = findViewById(R.id.scan_button)
productNameText = findViewById(R.id.productName)
netWeightText = findViewById(R.id.netWeight)
saveButton.setOnClickListener {
val productName = productNameText.text.toString()
val netWeight = netWeightText.text
if (!this::pictureFile.isInitialized || !pictureFile.exists()) {
Toast.makeText(this, "Please, make a picture of a product!", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (productName == "") {
Toast.makeText(this, "Please, write a name of a product!", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
Toast.makeText(this, "Please, write a valid net weight of a product!", Toast.LENGTH_SHORT).show()
}
val db = DBStorageController(this).writableDatabase
Log.d("QWERTYUIOP", "Putting ${pictureFile.name}")
val values = ContentValues().apply {
put(ProductContract.ProductEntry.PRODUCT_NAME, productName)
put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
}
db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
finish()
}
takePictureButton.setOnClickListener {
Log.d("QWERTYUIOP", "test")
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
}
scanButton.setOnClickListener {
val options = GmsBarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_EAN_13
)
.build()
val scanner = GmsBarcodeScanning.getClient(this)
scanner.startScan()
.addOnSuccessListener { barcode ->
productNameText.setText(barcode.rawValue)
}
.addOnFailureListener { e ->
Toast.makeText(
this,
"Failed to scan barcode. Please, try again or enter data manually",
Toast.LENGTH_LONG
).show()
}
}
// binding = ActivityAddProductBinding.inflate(layoutInflater)
// setContentView(binding.root)
_binding = AddProductFragmentBinding.inflate(inflater, container, false)
return binding.root
}
@RequiresApi(Build.VERSION_CODES.R)
val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
if (success) {
//Move picture to a proper directory according to its calculated hash
val tempfile = File(requireContext().filesDir, "image.png")
val tempfile = File(filesDir, "image.png")
val imageContent = tempfile.inputStream().readBytes()
val imageHash = imageContent.toString(Charsets.UTF_8).md5()
pictureFile = File(picturesPath, "$imageHash.png")
Files.move(tempfile.toPath(), pictureFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
tempfile.delete()
generateThumbnailForImage(context!!, imageHash)
generateThumbnailForImage(this, imageHash)
binding.imageView.setImageURI(getImageUri(requireActivity(), pictureFile))
imageView.setImageURI(getImageUri(this, pictureFile))
Log.i("QWERTYUIOP", "Picture saved")
} else {
Log.e("QWERTYUIOP", "Cannot save a picture")
@ -63,8 +135,8 @@ class AddProductFragment : Fragment() {
@RequiresApi(Build.VERSION_CODES.R)
fun getPicture () {
//Saving picture to a temp file for further hash calculation and moving to a proper directory
val imageFile = File(requireContext().filesDir, "image.png")
val imageUri = getImageUri(requireActivity(), imageFile)
val imageFile = File(this.filesDir, "image.png")
val imageUri = getImageUri(this, imageFile)
takePicture.launch(imageUri)
}
@ -76,71 +148,7 @@ class AddProductFragment : Fragment() {
if (isGranted) {
getPicture()
} else {
Toast.makeText(requireContext(), "I need permission in order to take a picture", Toast.LENGTH_LONG).show()
Toast.makeText(this, "I need permission in order to take a picture", Toast.LENGTH_LONG).show()
}
}
@RequiresApi(Build.VERSION_CODES.R)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.saveButton.setOnClickListener {
val productName = binding.productName.text.toString()
val netWeight = binding.netWeight.text
if (!this::pictureFile.isInitialized || !pictureFile.exists()) {
Toast.makeText(context, "Please, make a picture of a product!", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (productName == "") {
Toast.makeText(context, "Please, write a name of a product!", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
Toast.makeText(context, "Please, write a valid net weight of a product!", Toast.LENGTH_SHORT).show()
}
val db = DBStorageController(requireContext()).writableDatabase
Log.d("QWERTYUIOP", "Putting ${pictureFile.name}")
val values = ContentValues().apply {
put(ProductContract.ProductEntry.PRODUCT_NAME, productName)
put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
}
db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
findNavController().navigate(R.id.storageFragment)
}
binding.takePictureButton.setOnClickListener {
requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
}
binding.scanButton.setOnClickListener {
val options = GmsBarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_EAN_13
)
.build()
val scanner = GmsBarcodeScanning.getClient(requireContext())
scanner.startScan()
.addOnSuccessListener { barcode ->
binding.productName.setText(barcode.rawValue)
}
.addOnFailureListener { e ->
Toast.makeText(
requireContext(),
"Failed to scan barcode. Please, try again or enter data manually",
Toast.LENGTH_LONG
).show()
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -1,4 +1,4 @@
package org.foxarmy.barcodescannerforemployees
package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity
import android.os.Bundle
@ -7,7 +7,9 @@ import android.os.Looper
import android.util.Log
import android.widget.ImageView
import android.widget.LinearLayout
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.ActivityFullscreenBinding
import org.foxarmy.barcodescannerforemployees.getImageUri
import java.io.File

View File

@ -1,34 +1,39 @@
package org.foxarmy.barcodescannerforemployees
package org.foxarmy.barcodescannerforemployees.activities
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import org.foxarmy.barcodescannerforemployees.databinding.ActivityMainBinding
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.ActivityStorageBinding
class MainActivity : AppCompatActivity() {
class StorageActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
private lateinit var binding: ActivityStorageBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
binding = ActivityStorageBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
val navController = findNavController(R.id.nav_host_fragment_content_storage)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.addProductFab.setOnClickListener { view ->
navController.navigate(R.id.AddProductFragment)
val addProductIntent = Intent(this, AddProductActivity::class.java)
val extras = Bundle()
ContextCompat.startActivity(this, addProductIntent, extras)
}
}
@ -47,7 +52,7 @@ class MainActivity : AppCompatActivity() {
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
val navController = findNavController(R.id.nav_host_fragment_content_storage)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}

View File

@ -0,0 +1,30 @@
package org.foxarmy.barcodescannerforemployees.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.FragmentAddProductBinding
import java.io.File
class AddProductFragment : Fragment() {
private lateinit var binding: FragmentAddProductBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
Log.d("QWERTYUIOP", "хуета1")
binding = FragmentAddProductBinding.inflate(layoutInflater)
return inflater.inflate(R.layout.fragment_add_product, container, false)
}
}

View File

@ -1,4 +1,4 @@
package org.foxarmy.barcodescannerforemployees
package org.foxarmy.barcodescannerforemployees.fragments
import android.os.Bundle
import android.provider.BaseColumns
@ -8,6 +8,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.gridlayout.widget.GridLayout
import org.foxarmy.barcodescannerforemployees.*
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
/**
* A simple [Fragment] subclass.
@ -28,11 +30,23 @@ class StorageFragment : Fragment() {
return inflater.inflate(R.layout.fragment_storage, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun onResume() {
super.onResume()
refillWithContent()
}
public fun refillWithContent() {
val grv = getView()?.findViewById<GridLayout>(R.id.contentGridLayout)
grv?.removeAllViews()
val db = DBStorageController(requireContext()).readableDatabase
val projection = arrayOf(BaseColumns._ID, ProductContract.ProductEntry.PRODUCT_NAME, ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, ProductContract.ProductEntry.IMAGE_FILENAME)
val projection = arrayOf(BaseColumns._ID,
ProductContract.ProductEntry.PRODUCT_NAME,
ProductContract.ProductEntry.PRODUCT_NET_WEIGHT,
ProductContract.ProductEntry.IMAGE_FILENAME
)
val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, null, null, null, null, null)
@ -52,7 +66,7 @@ class StorageFragment : Fragment() {
netWeight,
1
)
getView()?.findViewById<GridLayout>(R.id.contentGridLayout)?.addView(abstractProduct)
grv?.addView(abstractProduct)
abstractProduct.setOnClickListener {
Log.d("QWERTYUIOP", "Clicked view")
@ -61,4 +75,10 @@ class StorageFragment : Fragment() {
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
refillWithContent()
}
}

View File

@ -1,4 +1,4 @@
package org.foxarmy.barcodescannerforemployees
package org.foxarmy.barcodescannerforemployees.views
import android.app.Activity
import android.content.Context
@ -12,6 +12,9 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.startActivity
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.activities.FullscreenActivity
import org.foxarmy.barcodescannerforemployees.getImageUri
import java.io.File
class AbstractProductView: LinearLayout {

View File

@ -5,9 +5,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainScreenFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"/>
tools:context=".fragments.AddProductFragment">
<include layout="@layout/content_add_product" android:id="@+id/include_content"/>
</androidx.core.widget.NestedScrollView>

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
tools:context=".FullscreenActivity">
tools:context=".activities.FullscreenActivity">
<!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,

View File

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
tools:context=".activities.StorageActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
@ -26,7 +26,7 @@
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main"/>
<include layout="@layout/content_storage"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_product_fab"

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" android:id="@+id/addProductLayout">
<androidx.fragment.app.FragmentContainerView
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" app:navGraph="@navigation/nav_graph_add_product"
app:defaultNavHost="true" android:id="@+id/fragmentContainerView"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -7,7 +7,7 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior" android:id="@+id/storageLayout">
<fragment
android:id="@+id/nav_host_fragment_content_main"
android:id="@+id/nav_host_fragment_content_storage"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
@ -16,5 +16,5 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
app:navGraph="@navigation/nav_graph_storage"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -5,7 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AddProductFragment">
tools:context=".fragments.AddProductFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StorageFragment">
android:id="@+id/fragment_storage"
tools:context=".fragments.StorageFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

View File

@ -1,7 +1,7 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="org.foxarmy.barcodescannerforemployees.MainActivity">
tools:context="org.foxarmy.barcodescannerforemployees.activities.StorageActivity">
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/storageFragment">
<fragment
android:id="@+id/AddProductFragment"
android:name="org.foxarmy.barcodescannerforemployees.AddProductFragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/add_product_fragment">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/MainScreenFragment"/>
</fragment>
<fragment
android:id="@+id/MainScreenFragment"
android:name="org.foxarmy.barcodescannerforemployees.MainScreenFragment"
android:label="@string/second_fragment_label"
tools:layout="@layout/fragment_second">
<action
android:id="@+id/action_SecondFragment_to_FirstFragment"
app:destination="@id/AddProductFragment"/>
</fragment>
<fragment android:id="@+id/storageFragment" android:name="org.foxarmy.barcodescannerforemployees.StorageFragment"
android:label="fragment_storage" tools:layout="@layout/fragment_storage">
<action android:id="@+id/action_storageFragment_to_AddProductFragment"
app:destination="@id/AddProductFragment"/>
</fragment>
</navigation>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_add_product"
app:startDestination="@id/addProductFragment">
<fragment android:id="@+id/addProductFragment" android:name="org.foxarmy.barcodescannerforemployees.fragments.AddProductFragment"
android:label="add_product_fragment" tools:layout="@layout/fragment_add_product"/>
</navigation>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_storage"
app:startDestination="@id/storageFragment">
<fragment android:id="@+id/storageFragment" android:name="org.foxarmy.barcodescannerforemployees.fragments.StorageFragment"
android:label="fragment_storage" tools:layout="@layout/fragment_storage"/>
</navigation>

View File

@ -21,4 +21,36 @@
<string name="dummy_button">Dummy Button</string>
<string name="dummy_content">DUMMY\nCONTENT</string>
<string name="fullscreen_image">Fullscreen image</string>
<string name="next">Next</string>
<string name="lorem_ipsum">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris volutpat, dolor id
interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus dui nec risus. Maecenas non sodales
nisi, vel dictum dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Suspendisse blandit eleifend diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet,
imperdiet nisl a, ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus egestas, est a
condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed neque. Morbi tellus erat, dapibus ut
sem a, iaculis tincidunt dui. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur et eros
porttitor, ultricies urna vitae, molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl
nec dolor bibendum, vel congue leo egestas.\n\n
Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit amet auctor at,
mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel, molestie quam. Fusce blandit tincidunt
nulla, quis sollicitudin libero facilisis et. Integer interdum nunc ligula, et fermentum metus hendrerit id.
Vestibulum lectus felis, dictum at lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse
sodales nunc ligula, in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
est.\n\n
Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh. Morbi laoreet, tortor
sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui non lorem. Nam mollis ipsum quis auctor
varius. Quisque elementum eu libero sed commodo. In eros nisl, imperdiet vel imperdiet et, scelerisque a mauris.
Pellentesque varius ex nunc, quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non
viverra ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a placerat
diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus convallis.\n\n
Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis
egestas. In volutpat arcu ut felis sagittis, in finibus massa gravida. Pellentesque id tellus orci. Integer
dictum, lorem sed efficitur ullamcorper, libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec
maximus ullamcorper sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus vestibulum. Fusce
dictum libero quis erat maximus, vitae volutpat diam dignissim.
</string>
</resources>