Blurring spoiler post images is now available. Change spoiler and flair text background colors. Fixed collapsed comments shown after orientation change.

This commit is contained in:
Alex Ning 2019-09-27 16:58:57 +08:00
parent edf85c2bc3
commit 47832e1e91
19 changed files with 129 additions and 37 deletions

View File

@ -159,8 +159,8 @@
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_verified_user_14dp" />
<entry key="sourceFile" value="$USER_HOME$/Downloads/verified_user-24px.svg" />
<entry key="outputName" value="ic_font_size_24dp" />
<entry key="sourceFile" value="$USER_HOME$/Downloads/format_size-24px.svg" />
</map>
</option>
</PersistentState>

Binary file not shown.

View File

@ -6,8 +6,8 @@ android {
applicationId "ml.docilealligator.infinityforreddit"
minSdkVersion 21
targetSdkVersion 29
versionCode 12
versionName "1.1.1"
versionCode 13
versionName "1.1.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {

View File

@ -17,6 +17,7 @@ import javax.inject.Inject;
import ml.docilealligator.infinityforreddit.ChangeNSFWBlurEvent;
import ml.docilealligator.infinityforreddit.ChangeNSFWEvent;
import ml.docilealligator.infinityforreddit.ChangeSpoilerBlurEvent;
import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.SharedPreferencesUtils;
@ -44,6 +45,7 @@ public class MainPreferenceFragment extends PreferenceFragmentCompat {
SwitchPreference nsfwSwitch = findPreference(SharedPreferencesUtils.NSFW_KEY);
SwitchPreference blurNSFWSwitch = findPreference(SharedPreferencesUtils.BLUR_NSFW_KEY);
SwitchPreference blurSpoilerSwitch = findPreference(SharedPreferencesUtils.BLUR_SPOILER_KEY);
ListPreference themePreference = findPreference(SharedPreferencesUtils.THEME_KEY);
if(nsfwSwitch != null) {
@ -71,6 +73,13 @@ public class MainPreferenceFragment extends PreferenceFragmentCompat {
});
}
if(blurSpoilerSwitch != null) {
blurSpoilerSwitch.setOnPreferenceChangeListener((preference, newValue) -> {
EventBus.getDefault().post(new ChangeSpoilerBlurEvent((Boolean) newValue));
return true;
});
}
boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
if(themePreference != null) {

View File

@ -0,0 +1,8 @@
package ml.docilealligator.infinityforreddit;
public class ChangeSpoilerBlurEvent {
public boolean needBlurSpoiler;
public ChangeSpoilerBlurEvent(boolean needBlurSpoiler) {
this.needBlurSpoiler = needBlurSpoiler;
}
}

View File

@ -52,6 +52,8 @@ import jp.wasabeef.glide.transformations.BlurTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import retrofit2.Retrofit;
import static ml.docilealligator.infinityforreddit.CommentActivity.WRITE_COMMENT_REQUEST_CODE;
class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_POST_DETAIL = 0;
private static final int VIEW_TYPE_FIRST_LOADING = 1;
@ -78,6 +80,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
private String mSingleCommentId;
private boolean mIsSingleCommentThreadMode;
private boolean mNeedBlurNSFW;
private boolean mNeedBlurSpoiler;
private CommentRecyclerViewAdapterCallback mCommentRecyclerViewAdapterCallback;
private boolean isInitiallyLoading;
private boolean isInitiallyLoadingFailed;
@ -92,9 +95,10 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
CommentAndPostRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit,
RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide,
String accessToken, String accountName, Post post,
Locale locale, String singleCommentId, boolean isSingleCommentThreadMode,
boolean needBlurNSFW, CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) {
String accessToken, String accountName, Post post, Locale locale,
String singleCommentId, boolean isSingleCommentThreadMode,
boolean needBlurNSFW, boolean needBlurSpoiler,
CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) {
mActivity = activity;
mRetrofit = retrofit;
mOauthRetrofit = oauthRetrofit;
@ -128,6 +132,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
mSingleCommentId = singleCommentId;
mIsSingleCommentThreadMode = isSingleCommentThreadMode;
mNeedBlurNSFW = needBlurNSFW;
mNeedBlurSpoiler = needBlurSpoiler;
mCommentRecyclerViewAdapterCallback = commentRecyclerViewAdapterCallback;
isInitiallyLoading = true;
isInitiallyLoadingFailed = false;
@ -353,15 +358,11 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
if(mPost.isSpoiler()) {
((PostDetailViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE);
((PostDetailViewHolder) holder).spoilerTextView
.setBackgroundColor(mActivity.getResources().getColor(R.color.backgroundColorPrimaryDark));
}
if(mPost.getFlair() != null) {
((PostDetailViewHolder) holder).flairTextView.setVisibility(View.VISIBLE);
((PostDetailViewHolder) holder).flairTextView.setText(mPost.getFlair());
((PostDetailViewHolder) holder).flairTextView
.setBackgroundColor(mActivity.getResources().getColor(R.color.backgroundColorPrimaryDark));
}
if(mPost.isNSFW()) {
@ -493,7 +494,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, mPost.getTitle());
intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false);
intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0);
mActivity.startActivity(intent);
mActivity.startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE);
});
((PostDetailViewHolder) holder).commentsCountTextView.setText(Integer.toString(mPost.getnComments()));
@ -942,7 +943,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
}
});
if(mPost.isNSFW() && mNeedBlurNSFW) {
if((mPost.isNSFW() && mNeedBlurNSFW) || (mPost.isSpoiler() && mNeedBlurSpoiler)) {
imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2)))
.into(holder.mImageView);
} else {
@ -1093,6 +1094,10 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
mIsSingleCommentThreadMode = isSingleCommentThreadMode;
}
ArrayList<CommentData> getVisibleComments() {
return mVisibleComments;
}
void initiallyLoading() {
if(mVisibleComments.size() != 0) {
int previousSize = mVisibleComments.size();
@ -1162,6 +1167,10 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
mNeedBlurNSFW = needBlurNSFW;
}
void setBlurSpoiler(boolean needBlurSpoiler) {
mNeedBlurSpoiler = needBlurSpoiler;
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof CommentViewHolder) {

View File

@ -260,6 +260,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN);
boolean nsfw = mSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_KEY, false);
boolean needBlurNsfw = mSharedPreferences.getBoolean(SharedPreferencesUtils.BLUR_NSFW_KEY, true);
boolean needBlurSpoiler = mSharedPreferences.getBoolean(SharedPreferencesUtils.BLUR_SPOILER_KEY, false);
PostViewModel.Factory factory;
@ -268,7 +269,8 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
String query = getArguments().getString(EXTRA_QUERY);
mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase,
accessToken, postType, true, needBlurNsfw, new PostRecyclerViewAdapter.Callback() {
accessToken, postType, true, needBlurNsfw, needBlurSpoiler,
new PostRecyclerViewAdapter.Callback() {
@Override
public void retryLoadingMore() {
mPostViewModel.retryLoadingMore();
@ -300,7 +302,8 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
boolean displaySubredditName = subredditName != null && (subredditName.equals("popular") || subredditName.equals("all"));
mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase,
accessToken, postType, displaySubredditName, needBlurNsfw, new PostRecyclerViewAdapter.Callback() {
accessToken, postType, displaySubredditName, needBlurNsfw, needBlurSpoiler,
new PostRecyclerViewAdapter.Callback() {
@Override
public void retryLoadingMore() {
mPostViewModel.retryLoadingMore();
@ -336,7 +339,8 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase,
accessToken, postType, true, needBlurNsfw, new PostRecyclerViewAdapter.Callback() {
accessToken, postType, true, needBlurNsfw, needBlurSpoiler,
new PostRecyclerViewAdapter.Callback() {
@Override
public void retryLoadingMore() {
mPostViewModel.retryLoadingMore();
@ -365,7 +369,8 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
} else {
mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mRedditDataRoomDatabase,
accessToken, postType, true, needBlurNsfw, new PostRecyclerViewAdapter.Callback() {
accessToken, postType, true, needBlurNsfw, needBlurSpoiler,
new PostRecyclerViewAdapter.Callback() {
@Override
public void retryLoadingMore() {
mPostViewModel.retryLoadingMore();
@ -558,7 +563,16 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
@Subscribe
public void onChangeNSFWBlurEvent(ChangeNSFWBlurEvent event) {
mAdapter.setBlurNSFW(event.needBlurNSFW);
refreshAdapter();
}
@Subscribe
public void onChangeSpoilerBlurEvent(ChangeSpoilerBlurEvent event) {
mAdapter.setBlurSpoiler(event.needBlurSpoiler);
refreshAdapter();
}
private void refreshAdapter() {
int previousPosition = -1;
if(mLinearLayoutManager != null) {
previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition();

View File

@ -62,6 +62,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
private int mPostType;
private boolean mDisplaySubredditName;
private boolean mNeedBlurNSFW;
private boolean mNeedBlurSpoiler;
private static final int VIEW_TYPE_DATA = 0;
private static final int VIEW_TYPE_ERROR = 1;
@ -76,9 +77,9 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
}
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, Retrofit retrofit,
RedditDataRoomDatabase redditDataRoomDatabase,
String accessToken, int postType,
boolean displaySubredditName, boolean needBlurNSFW, Callback callback) {
RedditDataRoomDatabase redditDataRoomDatabase, String accessToken,
int postType, boolean displaySubredditName, boolean needBlurNSFW,
boolean needBlurSpoiler, Callback callback) {
super(DIFF_CALLBACK);
if(context != null) {
mContext = context;
@ -88,6 +89,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
mPostType = postType;
mDisplaySubredditName = displaySubredditName;
mNeedBlurNSFW = needBlurNSFW;
mNeedBlurSpoiler = needBlurSpoiler;
mGlide = Glide.with(mContext.getApplicationContext());
mRedditDataRoomDatabase = redditDataRoomDatabase;
mUserDao = redditDataRoomDatabase.userDao();
@ -710,7 +712,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
}
});
if(post.isNSFW() && mNeedBlurNSFW) {
if((post.isNSFW() && mNeedBlurNSFW) || post.isSpoiler() && mNeedBlurSpoiler) {
imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2)))
.into(((DataViewHolder) holder).imageView);
} else {
@ -744,6 +746,10 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo
mNeedBlurNSFW = needBlurNSFW;
}
void setBlurSpoiler(boolean needBlurSpoiler) {
mNeedBlurSpoiler = needBlurSpoiler;
}
private boolean hasExtraRow() {
return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS;
}

View File

@ -10,6 +10,7 @@ public class SharedPreferencesUtils {
public static final String LAZY_MODE_INTERVAL_KEY = "lazy_mode_interval";
public static final String NSFW_KEY = "nsfw";
public static final String BLUR_NSFW_KEY = "blur_nsfw";
public static final String BLUR_SPOILER_KEY = "blur_spoiler";
public static final String THEME_KEY = "theme";
public static final String ICON_FOREGROUND_KEY = "icon_foreground";
public static final String ICON_BACKGROUND_KEY = "icon_background";

View File

@ -80,6 +80,7 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
private int postListPosition = -1;
private String mSingleCommentId;
private boolean mNeedBlurNsfw;
private boolean mNeedBlurSpoiler;
@State
boolean mNullAccessToken = false;
@ -228,6 +229,7 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
setSupportActionBar(toolbar);
mNeedBlurNsfw = mSharedPreferences.getBoolean(SharedPreferencesUtils.BLUR_NSFW_KEY, true);
mNeedBlurSpoiler = mSharedPreferences.getBoolean(SharedPreferencesUtils.BLUR_SPOILER_KEY, false);
mGlide = Glide.with(this);
mLocale = getResources().getConfiguration().locale;
@ -372,7 +374,7 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit,
mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mAccountName, mPost,
mLocale, mSingleCommentId, isSingleCommentThreadMode, mNeedBlurNsfw,
mLocale, mSingleCommentId, isSingleCommentThreadMode, mNeedBlurNsfw, mNeedBlurSpoiler,
new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@Override
public void updatePost(Post post) {
@ -484,7 +486,7 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this,
mRetrofit, mOauthRetrofit, mRedditDataRoomDatabase, mGlide,
mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId,
isSingleCommentThreadMode, mNeedBlurNsfw,
isSingleCommentThreadMode, mNeedBlurNsfw, mNeedBlurSpoiler,
new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@Override
public void updatePost(Post post) {
@ -927,7 +929,16 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
@Subscribe
public void onChangeNSFWBlurEvent(ChangeNSFWBlurEvent event) {
mAdapter.setBlurNSFW(event.needBlurNSFW);
refreshAdapter();
}
@Subscribe
public void onChangeSpoilerBlurEvent(ChangeSpoilerBlurEvent event) {
mAdapter.setBlurSpoiler(event.needBlurSpoiler);
refreshAdapter();
}
private void refreshAdapter() {
int previousPosition = -1;
if(mLinearLayoutManager != null) {
previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition();
@ -1201,13 +1212,15 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
if(requestCode == WRITE_COMMENT_REQUEST_CODE) {
if(data != null && resultCode == RESULT_OK) {
if(data.hasExtra(EXTRA_COMMENT_DATA_KEY)) {
CommentData comment = data.getExtras().getParcelable(EXTRA_COMMENT_DATA_KEY);
if(comment.getDepth() == 0) {
CommentData comment = data.getParcelableExtra(EXTRA_COMMENT_DATA_KEY);
if(comment != null && comment.getDepth() == 0) {
mAdapter.addComment(comment);
} else {
String parentFullname = data.getExtras().getString(CommentActivity.EXTRA_PARENT_FULLNAME_KEY);
int parentPosition = data.getExtras().getInt(CommentActivity.EXTRA_PARENT_POSITION_KEY);
mAdapter.addChildComment(comment, parentFullname, parentPosition);
String parentFullname = data.getStringExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY);
int parentPosition = data.getIntExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, -1);
if(parentFullname != null && parentPosition >= 0) {
mAdapter.addChildComment(comment, parentFullname, parentPosition);
}
}
} else {
Toast.makeText(this, R.string.send_comment_failed, Toast.LENGTH_SHORT).show();
@ -1219,7 +1232,7 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
}
} else if(requestCode == EDIT_COMMENT_REQUEST_CODE) {
if(resultCode == RESULT_OK) {
mAdapter.editComment(data.getExtras().getString(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT),
mAdapter.editComment(data.getStringExtra(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT),
data.getExtras().getInt(EditCommentActivity.EXTRA_EDITED_COMMENT_POSITION));
}
}
@ -1228,6 +1241,7 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
comments = mAdapter.getVisibleComments();
Bridge.saveInstanceState(this, outState);
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M9,4v3h5v12h3L17,7h5L22,4L9,4zM3,12h3v7h3v-7h3L12,9L3,9v3z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M9,4v3h5v12h3L17,7h5L22,4L9,4zM3,12h3v7h3v-7h3L12,9L3,9v3z"/>
</vector>

View File

@ -204,8 +204,8 @@
android:padding="4dp"
android:visibility="gone"
app:lib_setRadius="3dp"
app:lib_setRoundedBGColor="@color/backgroundColorPrimaryDark"
app:lib_setRoundedBorderColor="@color/backgroundColorPrimaryDark"
app:lib_setRoundedBGColor="@color/spoilerBackgroundColor"
app:lib_setRoundedBorderColor="@color/spoilerBackgroundColor"
app:lib_setRoundedView="true"
app:lib_setShape="rectangle" />
@ -220,8 +220,8 @@
android:padding="4dp"
android:visibility="gone"
app:lib_setRadius="3dp"
app:lib_setRoundedBGColor="@color/backgroundColorPrimaryDark"
app:lib_setRoundedBorderColor="@color/backgroundColorPrimaryDark"
app:lib_setRoundedBGColor="@color/flairBackgroundColor"
app:lib_setRoundedBorderColor="@color/flairBackgroundColor"
app:lib_setRoundedView="true"
app:lib_setShape="rectangle" />

View File

@ -209,7 +209,8 @@
android:padding="4dp"
android:visibility="gone"
app:lib_setRadius="3dp"
app:lib_setRoundedBorderColor="@color/colorPrimaryDarkDayNightTheme"
app:lib_setRoundedBGColor="@color/spoilerBackgroundColor"
app:lib_setRoundedBorderColor="@color/spoilerBackgroundColor"
app:lib_setRoundedView="true"
app:lib_setShape="rectangle" />
@ -224,7 +225,8 @@
android:textColor="@android:color/white"
android:visibility="gone"
app:lib_setRadius="3dp"
app:lib_setRoundedBorderColor="@color/colorPrimaryDarkDayNightTheme"
app:lib_setRoundedBGColor="@color/flairBackgroundColor"
app:lib_setRoundedBorderColor="@color/flairBackgroundColor"
app:lib_setRoundedView="true"
app:lib_setShape="rectangle" />

View File

@ -90,7 +90,7 @@
<item>Normal</item>
<item>Large</item>
<item>Extra Large</item>
<item>Enormous Large</item>
<item>Enormously Large</item>
</string-array>
<string-array name="settings_content_font_size_values">

View File

@ -75,4 +75,8 @@
<color name="submitter">#EE8A02</color>
<color name="moderator">#00BA81</color>
<color name="spoilerBackgroundColor">#EE02EB</color>
<color name="flairBackgroundColor">#00AA8C</color>
</resources>

View File

@ -278,7 +278,8 @@
<string name="settings_title_font_size_title">Title Font Size</string>
<string name="settings_content_font_size_title">Content Font Size</string>
<string name="settings_enable_nsfw_title">Enable NSFW</string>
<string name="settings_blur_nsfw_title">Blur NSFW images</string>
<string name="settings_blur_nsfw_title">Blur NSFW Images</string>
<string name="settings_blur_spoiler_title">Blur Spoiler Images</string>
<string name="settings_layout_no_limits_title">Display Under Navigation bar and Status Bar</string>
<string name="settings_about_master_title">About</string>
<string name="settings_acknowledgement_master_title">Acknowledgement</string>

View File

@ -26,6 +26,7 @@
<Preference
app:title="@string/settings_font_size_title"
app:icon="@drawable/ic_font_size_24dp"
app:fragment="Settings.FontSizePreferenceFragment" />
<SwitchPreference
@ -39,6 +40,11 @@
app:title="@string/settings_blur_nsfw_title"
app:isPreferenceVisible="false" />
<SwitchPreference
app:defaultValue="false"
app:key="blur_spoiler"
app:title="@string/settings_blur_spoiler_title" />
<Preference
app:title="@string/settings_about_master_title"
app:fragment="Settings.AboutPreferenceFragment" />