MAINT-6257 Textures loading issues.
parent
783cc9756a
commit
0e155c51a9
|
|
@ -83,7 +83,12 @@ void LLIconCtrl::draw()
|
|||
|
||||
// virtual
|
||||
// value might be a string or a UUID
|
||||
void LLIconCtrl::setValue(const LLSD& value )
|
||||
void LLIconCtrl::setValue(const LLSD& value)
|
||||
{
|
||||
setValue(value, mPriority);
|
||||
}
|
||||
|
||||
void LLIconCtrl::setValue(const LLSD& value, S32 priority)
|
||||
{
|
||||
LLSD tvalue(value);
|
||||
if (value.isString() && LLUUID::validate(value.asString()))
|
||||
|
|
@ -94,11 +99,11 @@ void LLIconCtrl::setValue(const LLSD& value )
|
|||
LLUICtrl::setValue(tvalue);
|
||||
if (tvalue.isUUID())
|
||||
{
|
||||
mImagep = LLUI::getUIImageByID(tvalue.asUUID(), mPriority);
|
||||
mImagep = LLUI::getUIImageByID(tvalue.asUUID(), priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
mImagep = LLUI::getUIImage(tvalue.asString(), mPriority);
|
||||
mImagep = LLUI::getUIImage(tvalue.asString(), priority);
|
||||
}
|
||||
|
||||
if(mImagep.notNull()
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ protected:
|
|||
LLIconCtrl(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
void setValue(const LLSD& value, S32 priority);
|
||||
|
||||
public:
|
||||
virtual ~LLIconCtrl();
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
|
|||
}
|
||||
else
|
||||
{
|
||||
LLIconCtrl::setValue(mDefaultIconName);
|
||||
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +243,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
|
|||
// *TODO: Consider getting avatar icon/badge directly from
|
||||
// People API, rather than sending AvatarPropertyRequest
|
||||
// messages. People API already hits the user table.
|
||||
LLIconCtrl::setValue(mDefaultIconName);
|
||||
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
|
||||
app->addObserver(mAvatarId, this);
|
||||
app->sendAvatarPropertiesRequest(mAvatarId);
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ bool LLAvatarIconCtrl::updateFromCache()
|
|||
}
|
||||
else
|
||||
{
|
||||
LLIconCtrl::setValue(mDefaultIconName);
|
||||
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ LLGroupIconCtrl::LLGroupIconCtrl(const LLGroupIconCtrl::Params& p)
|
|||
}
|
||||
else
|
||||
{
|
||||
LLIconCtrl::setValue(mDefaultIconName);
|
||||
//TODO: Consider implementing dedicated setDefault() function instead of passing priority for local file
|
||||
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +74,11 @@ LLGroupIconCtrl::~LLGroupIconCtrl()
|
|||
LLGroupMgr::getInstance()->removeObserver(this);
|
||||
}
|
||||
|
||||
void LLGroupIconCtrl::setIconId(const LLSD& value)
|
||||
{
|
||||
LLIconCtrl::setValue(value);
|
||||
}
|
||||
|
||||
void LLGroupIconCtrl::setValue(const LLSD& value)
|
||||
{
|
||||
if (value.isUUID())
|
||||
|
|
@ -91,7 +97,7 @@ void LLGroupIconCtrl::setValue(const LLSD& value)
|
|||
// Check if cache already contains image_id for that group
|
||||
if (!updateFromCache())
|
||||
{
|
||||
LLIconCtrl::setValue(mDefaultIconName);
|
||||
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
|
||||
gm->addObserver(this);
|
||||
gm->sendGroupPropertiesRequest(mGroupId);
|
||||
}
|
||||
|
|
@ -122,7 +128,7 @@ bool LLGroupIconCtrl::updateFromCache()
|
|||
}
|
||||
else
|
||||
{
|
||||
LLIconCtrl::setValue(mDefaultIconName);
|
||||
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
|
||||
}
|
||||
|
||||
if (mDrawTooltip && !group_data->mName.empty())
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ public:
|
|||
*/
|
||||
virtual void setValue(const LLSD& value);
|
||||
|
||||
void setIconId(const LLSD& value);
|
||||
|
||||
// LLGroupMgrObserver observer trigger
|
||||
virtual void changed(LLGroupChange gc);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
// libs
|
||||
#include "llbutton.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llgroupiconctrl.h"
|
||||
#include "llmenugl.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltextutil.h"
|
||||
|
|
@ -319,7 +319,7 @@ LLGroupListItem::~LLGroupListItem()
|
|||
//virtual
|
||||
BOOL LLGroupListItem::postBuild()
|
||||
{
|
||||
mGroupIcon = getChild<LLIconCtrl>("group_icon");
|
||||
mGroupIcon = getChild<LLGroupIconCtrl>("group_icon");
|
||||
mGroupNameBox = getChild<LLTextBox>("group_name");
|
||||
|
||||
mInfoBtn = getChild<LLButton>("info_btn");
|
||||
|
|
@ -381,7 +381,7 @@ void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id)
|
|||
{
|
||||
if (group_icon_id.notNull())
|
||||
{
|
||||
mGroupIcon->setValue(group_icon_id);
|
||||
mGroupIcon->setIconId(group_icon_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ private:
|
|||
};
|
||||
|
||||
class LLButton;
|
||||
class LLIconCtrl;
|
||||
class LLGroupIconCtrl;
|
||||
class LLTextBox;
|
||||
|
||||
class LLGroupListItem : public LLPanel
|
||||
|
|
@ -113,7 +113,7 @@ private:
|
|||
|
||||
LLTextBox* mGroupNameBox;
|
||||
LLUUID mGroupID;
|
||||
LLIconCtrl* mGroupIcon;
|
||||
LLGroupIconCtrl* mGroupIcon;
|
||||
LLButton* mInfoBtn;
|
||||
|
||||
std::string mGroupName;
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ LLLocalBitmap::~LLLocalBitmap()
|
|||
}
|
||||
|
||||
// delete self from gimagelist
|
||||
LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD);
|
||||
gTextureList.deleteImage(image);
|
||||
|
||||
if (image)
|
||||
|
|
@ -207,7 +207,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
|
|||
texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);
|
||||
texture->ref();
|
||||
|
||||
gTextureList.addImage(texture, TEX_LIST_DISCARD);
|
||||
gTextureList.addImage(texture, TEX_LIST_STANDARD);
|
||||
|
||||
if (optional_firstupdate != UT_FIRSTUSE)
|
||||
{
|
||||
|
|
@ -215,7 +215,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
|
|||
replaceIDs(old_id, mWorldID);
|
||||
|
||||
// remove old_id from gimagelist
|
||||
LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
|
||||
if (image != NULL)
|
||||
{
|
||||
gTextureList.deleteImage(image);
|
||||
|
|
@ -384,7 +384,7 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
|
|||
std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)
|
||||
{
|
||||
std::vector<LLViewerObject*> obj_list;
|
||||
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
|
||||
|
||||
for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)
|
||||
{
|
||||
|
|
@ -502,7 +502,7 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
|
|||
|
||||
void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id)
|
||||
{
|
||||
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
|
||||
for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++)
|
||||
{
|
||||
LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter];
|
||||
|
|
|
|||
|
|
@ -2214,7 +2214,7 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
|
|||
LLTextureEntry *te = object->getTE(te_index);
|
||||
if (te)
|
||||
{
|
||||
LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL;
|
||||
LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
|
||||
if(!tex)
|
||||
{
|
||||
tex = LLViewerFetchedTexture::sDefaultImagep;
|
||||
|
|
|
|||
|
|
@ -1393,7 +1393,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
|
|||
|
||||
void LLTextureCtrl::setImageAssetName(const std::string& name)
|
||||
{
|
||||
LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
|
||||
LLPointer<LLUIImage> imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW);
|
||||
if(imagep)
|
||||
{
|
||||
LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
|
||||
|
|
|
|||
|
|
@ -4460,7 +4460,7 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
|
|||
mRefetchedAllData += worker->mFormattedImage->getDataSize();
|
||||
|
||||
// refetch list only requests/creates normal images, so requesting ui='false'
|
||||
LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD);
|
||||
if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end())
|
||||
{
|
||||
if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "llfocusmgr.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llgroupiconctrl.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryicon.h"
|
||||
#include "llnotifications.h"
|
||||
|
|
@ -65,8 +65,10 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
|
|||
}
|
||||
|
||||
//group icon
|
||||
LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
|
||||
pGroupIcon->setValue(groupData.mInsigniaID);
|
||||
LLGroupIconCtrl* pGroupIcon = getChild<LLGroupIconCtrl>("group_icon", TRUE);
|
||||
|
||||
// We should already have this data preloaded, so no sense in setting icon through setValue(group_id)
|
||||
pGroupIcon->setIconId(groupData.mInsigniaID);
|
||||
|
||||
//header title
|
||||
std::string from_name = payload["sender_name"].asString();
|
||||
|
|
|
|||
|
|
@ -3323,7 +3323,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
|
|||
|
||||
setCategory(LLGLTexture::MEDIA);
|
||||
|
||||
LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
|
||||
LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
|
||||
if(tex) //this media is a parcel media for tex.
|
||||
{
|
||||
tex->setParcelMedia(this);
|
||||
|
|
@ -3333,7 +3333,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
|
|||
//virtual
|
||||
LLViewerMediaTexture::~LLViewerMediaTexture()
|
||||
{
|
||||
LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
|
||||
LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
|
||||
if(tex) //this media is a parcel media for tex.
|
||||
{
|
||||
tex->setParcelMedia(NULL);
|
||||
|
|
@ -3388,7 +3388,7 @@ BOOL LLViewerMediaTexture::findFaces()
|
|||
|
||||
BOOL ret = TRUE;
|
||||
|
||||
LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
|
||||
LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
|
||||
if(tex) //this media is a parcel media for tex.
|
||||
{
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
|
|
@ -3497,7 +3497,7 @@ void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
|
|||
const LLTextureEntry* te = facep->getTextureEntry();
|
||||
if(te && te->getID().notNull())
|
||||
{
|
||||
LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD);
|
||||
LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
|
||||
if(tex)
|
||||
{
|
||||
mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it.
|
||||
|
|
@ -3526,7 +3526,7 @@ void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
|
|||
const LLTextureEntry* te = facep->getTextureEntry();
|
||||
if(te && te->getID().notNull())
|
||||
{
|
||||
LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD);
|
||||
LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
|
||||
if(tex)
|
||||
{
|
||||
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
|
||||
|
|
@ -3635,10 +3635,10 @@ void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
|
|||
const LLTextureEntry* te = facep->getTextureEntry();
|
||||
if(te)
|
||||
{
|
||||
LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL;
|
||||
LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
|
||||
if(!tex && te->getID() != mID)//try parcel media.
|
||||
{
|
||||
tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
|
||||
tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
|
||||
}
|
||||
if(!tex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -72,20 +72,14 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMAGES("Process Images");
|
|||
|
||||
ETexListType get_element_type(S32 priority)
|
||||
{
|
||||
// don't discard flag can be used in some cases, but it usually is not set yet
|
||||
if (priority == LLViewerFetchedTexture::BOOST_ICON
|
||||
|| priority == LLViewerFetchedTexture::BOOST_UI)
|
||||
{
|
||||
return TEX_LIST_UI;
|
||||
}
|
||||
return TEX_LIST_DISCARD;
|
||||
return (priority == LLViewerFetchedTexture::BOOST_ICON) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLTextureKey::LLTextureKey()
|
||||
: textureId(LLUUID::null),
|
||||
textureType(TEX_LIST_DISCARD)
|
||||
textureType(TEX_LIST_STANDARD)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -591,7 +585,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
|
|||
|
||||
void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output)
|
||||
{
|
||||
LLTextureKey search_key(image_id, TEX_LIST_DISCARD);
|
||||
LLTextureKey search_key(image_id, TEX_LIST_STANDARD);
|
||||
uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key);
|
||||
while (iter != mUUIDMap.end() && iter->first.textureId == image_id)
|
||||
{
|
||||
|
|
@ -1597,14 +1591,14 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **
|
|||
LLUUID image_id;
|
||||
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id);
|
||||
|
||||
LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_STANDARD);
|
||||
if( image )
|
||||
{
|
||||
LL_WARNS() << "Image not in db" << LL_ENDL;
|
||||
image->setIsMissingAsset();
|
||||
}
|
||||
|
||||
image = gTextureList.findImage(image_id, TEX_LIST_UI);
|
||||
image = gTextureList.findImage(image_id, TEX_LIST_SCALE);
|
||||
if (image)
|
||||
{
|
||||
LL_WARNS() << "Icon not in db" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ typedef void (*LLImageCallback)(BOOL success,
|
|||
|
||||
enum ETexListType
|
||||
{
|
||||
TEX_LIST_DISCARD = 0,
|
||||
TEX_LIST_UI
|
||||
TEX_LIST_STANDARD = 0,
|
||||
TEX_LIST_SCALE
|
||||
};
|
||||
|
||||
struct LLTextureKey
|
||||
|
|
|
|||
|
|
@ -1992,7 +1992,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU
|
|||
uuid == IMG_INVISIBLE)
|
||||
{
|
||||
// Should already exist, don't need to find it on sim or baked-texture host.
|
||||
result = gTextureList.findImage(uuid, TEX_LIST_DISCARD);
|
||||
result = gTextureList.findImage(uuid, TEX_LIST_STANDARD);
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
|
|
@ -4313,7 +4313,7 @@ bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const
|
|||
{
|
||||
for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
|
||||
{
|
||||
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
|
||||
if (imagep && imagep->getDiscardLevel()!=0)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -4385,7 +4385,7 @@ S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
|
|||
S32Bytes result(0);
|
||||
for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
|
||||
{
|
||||
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
|
||||
if (imagep)
|
||||
{
|
||||
result += imagep->getTextureMemory();
|
||||
|
|
@ -4473,7 +4473,7 @@ void LLVOAvatar::releaseOldTextures()
|
|||
{
|
||||
if (new_texture_ids.find(*it) == new_texture_ids.end())
|
||||
{
|
||||
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);
|
||||
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
|
||||
if (imagep)
|
||||
{
|
||||
current_texture_mem += imagep->getTextureMemory();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
top="0"
|
||||
visible="false"
|
||||
width="320" />
|
||||
<icon
|
||||
<group_icon
|
||||
height="20"
|
||||
image_name="Generic_Group"
|
||||
name="group_icon"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
name="header"
|
||||
top="0"
|
||||
width="305">
|
||||
<icon
|
||||
<group_icon
|
||||
follows="all"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
|
|
|
|||
Loading…
Reference in New Issue