merged with upstream/master

This commit is contained in:
csoler 2015-12-22 18:33:01 -05:00
commit 5d9272055f
2052 changed files with 8495 additions and 3638 deletions

View file

@ -364,7 +364,7 @@ Changes for 0.5.5a
* Bug fixes
- Fixed proper display of crypto params for UDP connections
- Added missing location from cert when addign new friend
- Added missing location from cert when adding new friend
- Added missing IndicateConfigChanged to p3PeerMgrIMPL::setDynDNS
- Fixed crash when closing the main window without the setting "Minimize to Tray Icon"
- Renamed the setting "Do not Minimize to Tray Icon" to "Minimize to Tray
@ -1189,7 +1189,7 @@ Changes for v0.5.3b
- Added BSD specific changes - data directory and #including <sys/params.h>
- improved plugin management to allow services to be used, and config pages to be added
- Improvement to plugin system:
- made config page system more automatic, to allow addign config pages from plugins
- made config page system more automatic, to allow adding config pages from plugins
- added (disabled) checkbox and function to allow all plugins for development
- added config page methods to RsPlugin class
- Mark local existing files in SearchDialog with red text color.
@ -1202,7 +1202,7 @@ Changes for v0.5.3b
- Added Cache system for GPG Certificates.
- This should reduce gpg calls by 90+%.
- Added translation for "[ ... Missing Message ... ]".
- removed cache adding strategy to DL queue that was O(n^2). Now addign cache at the end of the queue
- removed cache adding strategy to DL queue that was O(n^2). Now adding cache at the end of the queue
- The channel message (in channels) is set to read when the user clicks on the show more button.
- The forum/channel news feed is removed when the user reads the message in forums/channels.
- The standard font is now used for new chat lobbies.

View file

@ -1037,8 +1037,9 @@ void IdDialog::chatIdentity()
RsGxsId from_gxs_id(action->data().toString().toStdString());
uint32_t error_code ;
DistantChatPeerId did ;
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, error_code))
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, did, error_code))
QMessageBox::information(NULL, tr("Distant chat cannot work"), QString("%1 %2: %3").arg(tr("Distant chat refused with this person.")).arg(tr("Error code")).arg(error_code)) ;
}

View file

@ -401,7 +401,7 @@ void MainWindow::initStackedPage()
else
icon = QIcon(":images/extension_48.png") ;
std::cerr << " Addign widget page for plugin " << rsPlugins->plugin(i)->getPluginName() << std::endl;
std::cerr << " Adding widget page for plugin " << rsPlugins->plugin(i)->getPluginName() << std::endl;
pluginPage->setIconPixmap(icon);
pluginPage->setPageName(QString::fromUtf8(rsPlugins->plugin(i)->getPluginName().c_str()));
addPage(pluginPage, grp, &notify);

View file

@ -1341,7 +1341,7 @@ void FlatStyle_RDM::updateRefs()
if(details->type == DIR_TYPE_FILE) // only push files, not directories nor persons.
_ref_entries.push_back(std::pair<void*,QString>(ref,computeDirectoryPath(*details)));
#ifdef RDM_DEBUG
std::cerr << "FlatStyle_RDM::postMods(): addign ref " << ref << std::endl;
std::cerr << "FlatStyle_RDM::postMods(): adding ref " << ref << std::endl;
#endif
for(std::list<DirStub>::const_iterator it = details->children.begin(); it != details->children.end(); ++it)
_ref_stack.push_back(it->ref) ;

View file

@ -300,16 +300,16 @@ void SearchDialog::initialiseFileTypeMappings()
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_AUDIO,
"aac aif flac iff m3u m4a mid midi mp3 mpa ogg ra ram wav wma");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_ARCHIVE,
"7z bz2 gz pkg rar sea sit sitx tar zip");
"7z bz2 gz pkg rar sea sit sitx tar zip tgz");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_CDIMAGE,
"iso nrg mdf");
"iso nrg mdf bin");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_DOCUMENT,
"doc odt ott rtf pdf ps txt log msg wpd wps" );
"doc odt ott rtf pdf ps txt log msg wpd wps ods xls epub" );
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_PICTURE,
"3dm 3dmf ai bmp drw dxf eps gif ico indd jpe jpeg jpg mng pcx pcc pct pgm "
"pix png psd psp qxd qxprgb sgi svg tga tif tiff xbm xcf");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_PROGRAM,
"app bat cgi com bin exe js pif py pl sh vb ws ");
"app bat cgi com bin exe js pif py pl sh vb ws bash");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_VIDEO,
"3gp asf asx avi mov mp4 mkv flv mpeg mpg qt rm swf vob wmv");
SearchDialog::initialised = true;

View file

@ -96,7 +96,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if (cd == NULL) {
if(id.isGxsId())
if(id.isDistantChatId())
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // force open for distant chat
if (chatflags & RS_CHAT_OPEN) {
@ -104,12 +104,16 @@ void ChatDialog::init(ChatId id, const QString &title)
ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId());
cld->init();
cd = cld;
} else if(id.isGxsId()) {
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog();
QString peer_name = pdcd->getPeerName(id) ;
pdcd->init(id.toGxsId(), tr("Talking to")+" "+peer_name) ;
}
else if(id.isDistantChatId())
{
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
pdcd->init(id.toDistantChatId());
cd = pdcd;
} else {
}
else
{
RsPeerDetails sslDetails;
if (rsPeers->getPeerDetails(id.toPeerId(), sslDetails)) {
PopupChatDialog* pcd = new PopupChatDialog();
@ -168,7 +172,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if(msg.chat_id.isBroadcast())
return; // broadcast is not handled by a chat dialog
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isGxsId()))
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isDistantChatId()))
// play sound when recv a message
SoundManager::play(SOUND_NEW_CHAT_MESSAGE);
@ -334,8 +338,8 @@ void ChatDialog::setPeerStatus(uint32_t status)
RsPeerId vpid;
if(mChatId.isPeerId())
vpid = mChatId.toPeerId();
if(mChatId.isGxsId())
vpid = RsPeerId(mChatId.toGxsId());
if(mChatId.isDistantChatId())
vpid = RsPeerId(mChatId.toDistantChatId());
cw->updateStatus(QString::fromStdString(vpid.toStdString()), status);
}
}

View file

@ -53,6 +53,8 @@
#define COLUMN_ID 3
#define COLUMN_COUNT 4
#define ROLE_SORT Qt::UserRole + 1
const static uint32_t timeToInactivity = 60 * 10; // in seconds
/** Default constructor */
@ -79,10 +81,25 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
muteAct = new QAction(QIcon(), tr("Mute participant"), this);
distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this);
sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this);
QActionGroup *sortgrp = new QActionGroup(this);
actionSortByName = new QAction(QIcon(), tr("Sort by Name"), this);
actionSortByName->setCheckable(true);
actionSortByName->setChecked(true);
actionSortByName->setActionGroup(sortgrp);
actionSortByActivity = new QAction(QIcon(), tr("Sort by Activity"), this);
actionSortByActivity->setCheckable(true);
actionSortByActivity->setChecked(false);
actionSortByActivity->setActionGroup(sortgrp);
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState()));
connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant()));
connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage()));
connect(actionSortByName, SIGNAL(triggered()), this, SLOT(sortParcipants()));
connect(actionSortByActivity, SIGNAL(triggered()), this, SLOT(sortParcipants()));
// Add a button to invite friends.
//
@ -94,7 +111,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
inviteFriendsButton->setToolTip(tr("Invite friends to this lobby"));
mParticipantCompareRole = new RSTreeWidgetItemCompareRole;
mParticipantCompareRole->setRole(0, Qt::UserRole);
mParticipantCompareRole->setRole(COLUMN_ACTIVITY, ROLE_SORT);
{
QIcon icon ;
@ -179,6 +196,9 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
contextMnu.addAction(sendMessageAct);
contextMnu.addSeparator();
contextMnu.addAction(muteAct);
contextMnu.addSeparator();
contextMnu.addAction(actionSortByActivity);
contextMnu.addAction(actionSortByName);
muteAct->setCheckable(true);
@ -450,6 +470,9 @@ void ChatLobbyDialog::updateParticipantsList()
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
time_t now = time(NULL);
widgetitem->setSizeHint(COLUMN_ICON, QSize(20,20));
if(isParticipantMuted(it2->first))
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_red_128.png"));
@ -472,7 +495,7 @@ void ChatLobbyDialog::updateParticipantsList()
}
}
ui.participantsList->setSortingEnabled(true);
ui.participantsList->sortItems(COLUMN_NAME, Qt::AscendingOrder);
sortParcipants();
}
/**
@ -562,8 +585,9 @@ void ChatLobbyDialog::distantChatParticipant()
rsMsgs->getIdentityForChatLobby(lobbyId, own_id);
uint32_t error_code ;
DistantChatPeerId tunnel_id;
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,error_code))
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,tunnel_id,error_code))
{
QString error_str ;
switch(error_code)
@ -761,3 +785,14 @@ void ChatLobbyDialog::showDialog(uint chatflags)
dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->setCurrentChatPage(this) ;
}
}
void ChatLobbyDialog::sortParcipants()
{
if (actionSortByActivity->isChecked()) {
ui.participantsList->sortItems(COLUMN_ACTIVITY, Qt::DescendingOrder);
} else if (actionSortByName->isChecked()) {
ui.participantsList->sortItems(COLUMN_NAME, Qt::AscendingOrder);
}
}

View file

@ -47,6 +47,7 @@ public:
void setIdentity(const RsGxsId& gxs_id);
bool isParticipantMuted(const RsGxsId &participant);
ChatLobbyId id() const { return lobbyId ;}
void sortParcipants();
private slots:
void participantsTreeWidgetCustomPopupMenu( QPoint point );
@ -104,6 +105,8 @@ private:
QAction *muteAct;
QAction *distantChatAct;
QAction *actionSortByName;
QAction *actionSortByActivity;
QWidgetAction *checkableAction;
QAction *sendMessageAct;

View file

@ -267,10 +267,12 @@ static QString getStyle(const QDir &styleDir, const QString &styleVariant, enumG
QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag)
{
bool me = false;
QDomDocument doc ;
QString styleOptimized ;
QString errorMsg ; int errorLine ; int errorColumn ;
QString messageBody = message ;
me = me || message.trimmed().startsWith("/me ");
if (doc.setContent(messageBody, &errorMsg, &errorLine, &errorColumn)) {
QDomElement body = doc.documentElement();
if (!body.isNull()){
@ -279,6 +281,12 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
for (int curs = 0; curs < count; ++curs){
QDomNode it = body.childNodes().item(curs);
if (it.nodeName().toLower() != "style") {
//find out if the message starts with /me
if(it.isText()){
me = me || it.toText().data().trimmed().startsWith("/me ");
}else if(it.isElement()){
me = me || it.toElement().text().trimmed().startsWith("/me ");
}
QString str;
QTextStream stream(&str);
it.toElement().save(stream, -1);
@ -354,7 +362,22 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
QString strDate = DateTime::formatDate(timestamp.date()).prepend(QString("<a name=\"date\">")).append(QString("</a>"));
QString strTime = DateTime::formatTime(timestamp.time()).prepend(QString("<a name=\"time\">")).append(QString("</a>"));
int bi = name.lastIndexOf(QRegExp(" \\(.*\\)")); //trim location from the end
QString strShortName = RsHtml::plainText(name.left(bi)).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
//handle /me
//%nome% and %me% for including formatting conditionally
//meName class for modifying the style of the name in the palce of /me
if(me){
messageBody = messageBody.replace(messageBody.indexOf("/me "), 3, strShortName.prepend(QString("<span class=\"meName\">")).append(QString("</span>"))); //replace only the first /me
style = style.remove(QRegExp("%nome%.*%/nome%")).remove("%me%").remove("%/me%");
} else {
style = style.remove(QRegExp("%me%.*%/me%")).remove("%nome%").remove("%/nome%");
}
QString formatMsg = style.replace("%name%", strName)
.replace("%shortname%", strShortName)
.replace("%date%", strDate)
.replace("%time%", strTime)
#ifdef COLORED_NICKNAMES

View file

@ -109,7 +109,7 @@ void ChatUserNotify::chatMessageReceived(ChatMessage msg)
if(!msg.chat_id.isBroadcast()
&&( ChatDialog::getExistingChat(msg.chat_id)
|| (Settings->getChatFlags() & RS_CHAT_OPEN)
|| msg.chat_id.isGxsId()))
|| msg.chat_id.isDistantChatId()))
{
ChatDialog::chatMessageReceived(msg);
}

View file

@ -51,6 +51,7 @@
#include "util/HandleRichText.h"
#include "gui/chat/ChatUserNotify.h"//For BradCast
#include "util/DateTime.h"
#include "util/imageutil.h"
#include <retroshare/rsstatus.h>
#include <retroshare/rsidentity.h>
@ -125,6 +126,8 @@ ChatWidget::ChatWidget(QWidget *parent) :
connect(ui->actionChooseFont, SIGNAL(triggered()), this, SLOT(chooseFont()));
connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor()));
connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont()));
connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote()));
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
@ -255,7 +258,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
RsPeerId ownId = rsPeers->getOwnId();
setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()));
if(chatId.isPeerId() || chatId.isGxsId())
if(chatId.isPeerId() || chatId.isDistantChatId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
if(chatId.isBroadcast() || chatId.isLobbyId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC);
@ -334,7 +337,8 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
continue;
QString name;
if (chatId.isLobbyId() || chatId.isGxsId()) {
if (chatId.isLobbyId() || chatId.isDistantChatId())
{
RsIdentityDetails details;
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
name = QString::fromUtf8(details.mNickname.c_str());
@ -366,7 +370,7 @@ ChatWidget::ChatType ChatWidget::chatType()
// but maybe it is good to have separate types in libretroshare and gui
if(chatId.isPeerId())
return CHATTYPE_PRIVATE;
if(chatId.isGxsId())
if(chatId.isDistantChatId())
return CHATTYPE_DISTANT;
if(chatId.isLobbyId())
return CHATTYPE_LOBBY;
@ -974,6 +978,14 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
contextMnu->addSeparator();
contextMnu->addAction(ui->actionClearChatHistory);
contextMnu->addAction(ui->actionQuote);
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
if(ImageUtil::checkImage(cursor))
{
ui->actionSave_image->setData(point);
contextMnu->addAction(ui->actionSave_image);
}
contextMnu->exec(ui->textBrowser->viewport()->mapToGlobal(point));
delete(contextMnu);
@ -1522,77 +1534,83 @@ void ChatWidget::updateStatus(const QString &peer_id, int status)
// make virtual peer id from gxs id in case of distant chat
RsPeerId vpid;
if(chatId.isGxsId())
vpid = RsPeerId(chatId.toGxsId());
if(chatId.isDistantChatId())
vpid = RsPeerId(chatId.toDistantChatId());
else
vpid = chatId.toPeerId();
/* set font size for status */
if (peer_id.toStdString() == vpid.toStdString()) {
// the peers status has changed
if (peer_id.toStdString() == vpid.toStdString())
{
// the peers status has changed
QString peerName ;
if(chatId.isGxsId())
{
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(chatId.toGxsId(),details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(chatId.toGxsId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
QString peerName ;
if(chatId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
RsIdentityDetails details ;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
if(rsMsgs->getDistantChatStatus(chatId.toDistantChatId(),dcpinfo))
if(rsIdentity->getIdDetails(dcpinfo.to_id,details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(dcpinfo.to_id.toStdString()) ;
else
peerName = QString::fromStdString(chatId.toDistantChatId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
break;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
peerStatus = status;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
peerStatus = status;
emit infoChanged(this);
emit statusChanged(status);
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
emit infoChanged(this);
emit statusChanged(status);
return;
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
return;
}
// ignore status change
}
@ -1661,3 +1679,21 @@ bool ChatWidget::setStyle()
return false;
}
void ChatWidget::quote()
{
QString text = ui->textBrowser->textCursor().selection().toPlainText();
if(text.length() > 0)
{
QStringList sl = text.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
text = sl.join("\n>");
emit ui->chatTextEdit->append(QString(">") + text);
}
}
void ChatWidget::saveImage()
{
QPoint point = ui->actionSave_image->data().toPoint();
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
ImageUtil::extractImage(window(), cursor);
}

View file

@ -185,6 +185,9 @@ private slots:
bool fileSave();
bool fileSaveAs();
void quote();
void saveImage();
private:
bool findText(const QString& qsStringToFind);
bool findText(const QString& qsStringToFind, bool bBackWard, bool bForceMove);

View file

@ -972,6 +972,23 @@ border-image: url(:/images/closepressed.png)
<string>Search Box</string>
</property>
</action>
<action name="actionQuote">
<property name="text">
<string>Quote</string>
</property>
<property name="toolTip">
<string>Quotes the selected text</string>
</property>
</action>
<action name="actionSave_image">
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/document_save.png</normaloff>:/images/document_save.png</iconset>
</property>
<property name="text">
<string>Save image</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View file

@ -43,9 +43,11 @@ PopupDistantChatDialog::~PopupDistantChatDialog()
delete _update_timer ;
}
PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags flags)
PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_id,QWidget *parent, Qt::WindowFlags flags)
: PopupChatDialog(parent,flags)
{
_tunnel_id = tunnel_id ;
_status_label = new QToolButton ;
_update_timer = new QTimer ;
@ -61,97 +63,98 @@ PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags
updateDisplay() ;
}
void PopupDistantChatDialog::init(const RsGxsId &gxs_id,const QString & title)
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
{
_pid = gxs_id ;
PopupChatDialog::init(ChatId(gxs_id), title) ;
_tunnel_id = peer_id;
DistantChatPeerInfo tinfo;
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
return ;
RsIdentityDetails iddetails ;
if(rsIdentity->getIdDetails(tinfo.to_id,iddetails))
PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ;
else
PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ;
RsGxsId own_gxs_id ;
uint32_t status ;
// do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// it will not be transmitted.
if(rsMsgs->getDistantChatStatus(gxs_id,status,&own_gxs_id))
ui.ownAvatarWidget->setId(ChatId(own_gxs_id));
ui.ownAvatarWidget->setOwnId() ; // sets the flag
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
}
void PopupDistantChatDialog::updateDisplay()
{
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
if(!isVisible())
return ;
if(!isVisible())
return ;
//std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ;
//std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
ui.avatarWidget->setId(ChatId(_pid));
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
ui.avatarWidget->setId(ChatId(_tunnel_id));
QString msg;
switch(status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
msg = tr("Hash Error. No tunnel.");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
switch(tinfo.status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
msg = tr("Chat remotely closed. Please close this window.");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
msg = QObject::tr("Tunnel is pending...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: //std::cerr << "Tunnel is ok. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_YEL_LED)) ;
msg = QObject::tr("Secured tunnel established. Waiting for ACK...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
msg = QObject::tr("Secured tunnel is working. You can talk!");
_status_label->setToolTip(msg) ;
getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
}
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
msg = QObject::tr("Tunnel is pending...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
msg = QObject::tr("Secured tunnel is working. You can talk!");
_status_label->setToolTip(msg) ;
getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
}
}
void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
{
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ;
DistantChatPeerInfo tinfo ;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
if(status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
if(tinfo.status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
{
QString msg = tr("Closing this window will end the conversation, notify the peer and remove the encrypted tunnel.") ;
if(QMessageBox::Ok == QMessageBox::critical(NULL,tr("Kill the tunnel?"),msg, QMessageBox::Ok | QMessageBox::Cancel))
rsMsgs->closeDistantChatConnexion(_pid) ;
rsMsgs->closeDistantChatConnexion(_tunnel_id) ;
else
{
e->ignore() ;
@ -166,23 +169,26 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
QString PopupDistantChatDialog::getPeerName(const ChatId &id) const
{
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(id.toGxsId(),details))
if(rsIdentity->getIdDetails(tinfo.to_id,details))
return QString::fromUtf8( details.mNickname.c_str() ) ;
else
return QString::fromStdString(id.toGxsId().toStdString()) ;
return QString::fromStdString(tinfo.to_id.toStdString()) ;
}
QString PopupDistantChatDialog::getOwnName() const
{
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
RsGxsId from_gxs_id ;
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_pid,status,&from_gxs_id) ;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(from_gxs_id,details))
if(rsIdentity->getIdDetails(tinfo.own_id,details))
return QString::fromUtf8( details.mNickname.c_str() ) ;
else
return QString::fromStdString(from_gxs_id.toStdString()) ;
return QString::fromStdString(tinfo.own_id.toStdString()) ;
}

View file

@ -22,6 +22,7 @@
#pragma once
#include <retroshare/rsgxstunnel.h>
#include "PopupChatDialog.h"
class QTimer ;
@ -33,11 +34,11 @@ class PopupDistantChatDialog: public PopupChatDialog
protected:
/** Default constructor */
PopupDistantChatDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
PopupDistantChatDialog(const DistantChatPeerId &tunnel_id, QWidget *parent = 0, Qt::WindowFlags flags = 0);
/** Default destructor */
virtual ~PopupDistantChatDialog();
virtual void init(const RsGxsId &gxs_id, const QString &title);
virtual void init(const DistantChatPeerId& peer_id);
virtual void closeEvent(QCloseEvent *e) ;
virtual QString getPeerName(const ChatId &id) const ;
@ -48,7 +49,7 @@ class PopupDistantChatDialog: public PopupChatDialog
private:
QTimer *_update_timer ;
RsGxsId _pid ;
DistantChatPeerId _tunnel_id ;
QToolButton *_status_label ;
friend class ChatDialog;

View file

@ -124,24 +124,33 @@ void AvatarWidget::setFrameType(FrameType type)
void AvatarWidget::setId(const ChatId &id)
{
mId = id;
// mPgpId = rsPeers->getGPGId(id) ;
// mFlag.isGpg = false ;
mGxsId.clear();
setPixmap(QPixmap());
if (id.isNotSet()) {
setEnabled(false);
}
refreshAvatarImage();
refreshStatus();
}
void AvatarWidget::setGxsId(const RsGxsId &id)
{
mId = ChatId();
mGxsId = id;
setPixmap(QPixmap());
if (id.isNull()) {
setEnabled(false);
}
refreshAvatarImage();
refreshStatus();
}
void AvatarWidget::setOwnId(const RsGxsId& own_gxs_id)
{
mFlag.isOwnId = true;
setId(ChatId(own_gxs_id));
}
void AvatarWidget::setOwnId()
{
mFlag.isOwnId = true;
@ -181,7 +190,7 @@ void AvatarWidget::refreshStatus()
rsStatus->getOwnStatus(statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
else if(mId.isDistantChatId())
status = RS_STATUS_ONLINE ;
else
{
@ -198,11 +207,15 @@ void AvatarWidget::refreshStatus()
rsStatus->getStatus(mId.toPeerId(), statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
{
if(!rsMsgs->getDistantChatStatus(mId.toGxsId(),status))
status = RS_STATUS_OFFLINE ;
}
else if(mId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
status = dcpinfo.status ;
else
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl;
}
else
{
std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl;
@ -235,13 +248,22 @@ void AvatarWidget::updateStatus(int status)
void AvatarWidget::updateAvatar(const QString &peerId)
{
if(mId.isPeerId() && mId.toPeerId() == RsPeerId(peerId.toStdString()))
refreshAvatarImage() ;
if(mId.isGxsId() && mId.toGxsId() == RsGxsId(peerId.toStdString()))
refreshAvatarImage() ;
refreshAvatarImage() ;
else if(mId.isDistantChatId() && mId.toDistantChatId() == DistantChatPeerId(peerId.toStdString()))
refreshAvatarImage() ;
else
std::cerr << "(EE) cannot update avatar. mId has unhandled type." << std::endl;
}
void AvatarWidget::refreshAvatarImage()
{
if (mGxsId.isNull()==false)
{
QPixmap avatar;
AvatarDefs::getAvatarFromGxsId(mGxsId, avatar, defaultAvatar);
setPixmap(avatar);
return;
}
if (mId.isNotSet())
{
QPixmap avatar(defaultAvatar);
@ -262,12 +284,21 @@ void AvatarWidget::refreshAvatarImage()
setPixmap(avatar);
return;
}
else if (mId.isGxsId())
else if (mId.isDistantChatId())
{
QPixmap avatar;
AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
setPixmap(avatar);
return;
QPixmap avatar;
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
{
if(mFlag.isOwnId)
AvatarDefs::getAvatarFromGxsId(dcpinfo.own_id, avatar, defaultAvatar);
else
AvatarDefs::getAvatarFromGxsId(dcpinfo.to_id, avatar, defaultAvatar);
setPixmap(avatar);
return;
}
}
else
std::cerr << "WARNING: unhandled situation in AvatarWidget::refreshAvatarImage()" << std::endl;

View file

@ -50,8 +50,8 @@ public:
QString frameState();
void setFrameType(FrameType type);
void setId(const ChatId& id) ;
void setGxsId(const RsGxsId& id) ;
void setOwnId();
void setOwnId(const RsGxsId&);
void setDefaultAvatar(const QString &avatar_file_name);
protected:
@ -71,6 +71,7 @@ private:
Ui::AvatarWidget *ui;
ChatId mId;
RsGxsId mGxsId;
struct {
bool isOwnId : 1;

View file

@ -29,7 +29,7 @@
#include <QPushButton>
#include <iostream>
#include <math.h>
#include "Emoticons.h"
#include "util/HandleRichText.h"
@ -48,7 +48,7 @@ void Emoticons::load()
internalEmoticons = false;
} else {
// then embedded emotions
sm_file.setFileName(":/smileys/emotes.acs");
sm_file.setFileName(":/emojione/emotes.acs");
if(!sm_file.open(QIODevice::ReadOnly))
{
std::cout << "error opening ressource file" << std::endl ;
@ -56,7 +56,7 @@ void Emoticons::load()
}
}
#else
QFile sm_file(QString(":/smileys/emotes.acs"));
QFile sm_file(QString(":/emojione/emotes.acs"));
if(!sm_file.open(QIODevice::ReadOnly))
{
std::cout << "error opening ressource file" << std::endl ;
@ -128,9 +128,9 @@ void Emoticons::showSmileyWidget(QWidget *parent, QWidget *button, const char *s
const int buttonWidth = 26;
const int buttonHeight = 26;
const int countPerLine = 9;
int rowCount = (Smileys.size()/countPerLine) + ((Smileys.size() % countPerLine) ? 1 : 0);
int rowCount = (int)sqrt((double)Smileys.size());
int countPerLine = (Smileys.size()/rowCount) + ((Smileys.size() % rowCount) ? 1 : 0);
smWidget->setAttribute( Qt::WA_DeleteOnClose);
smWidget->setWindowTitle("Emoticons");

View file

@ -46,7 +46,7 @@ void GroupSelectionBox::selectedGroupIds(std::list<std::string> &groupIds) const
QListWidgetItem *listItem = item(i);
if (listItem->checkState() == Qt::Checked) {
groupIds.push_back(item(i)->data(ROLE_ID).toString().toStdString());
std::cerr << "Addign selected item " << groupIds.back() << std::endl;
std::cerr << "Adding selected item " << groupIds.back() << std::endl;
}
}
}
@ -74,7 +74,7 @@ void GroupSelectionBox::selectedGroupNames(QList<QString> &groupNames) const
QListWidgetItem *listItem = item(i);
if (listItem->checkState() == Qt::Checked) {
groupNames.push_back(item(i)->text());
std::cerr << "Addign selected item " << groupNames.back().toUtf8().constData() << std::endl;
std::cerr << "Adding selected item " << groupNames.back().toUtf8().constData() << std::endl;
}
}
}

View file

@ -41,6 +41,7 @@ MimeTextEdit::MimeTextEdit(QWidget *parent)
mCompleterKeyModifiers = Qt::ControlModifier;
mCompleterKey = Qt::Key_Space;
mForceCompleterShowNextKeyEvent = false;
highliter = new RsSyntaxHighlighter(this);
}
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
@ -231,6 +232,8 @@ void MimeTextEdit::contextMenuEvent(QContextMenuEvent *e)
/* Add actions for pasting links */
contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText()));
QAction *spoilerAction = contextMenu->addAction(tr("Spoiler"), this, SLOT(spoiler()));
spoilerAction->setToolTip(tr("Select text to hide, then push this button"));
contextMenu->addSeparator();
QAction *pasteLinkAction = contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
@ -268,3 +271,8 @@ void MimeTextEdit::pastePlainText()
{
insertPlainText(QApplication::clipboard()->text());
}
void MimeTextEdit::spoiler()
{
RsHtml::insertSpoilerText(this->textCursor());
}

View file

@ -24,11 +24,14 @@
#include <QCompleter>
#include "RSTextEdit.h"
#include "util/RsSyntaxHighlighter.h"
class MimeTextEdit : public RSTextEdit
{
Q_OBJECT
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
public:
MimeTextEdit(QWidget *parent = 0);
@ -44,6 +47,11 @@ public:
// Add QAction to context menu (action won't be deleted)
void addContextMenuAction(QAction *action);
QColor textColorQuote() const { return highliter->textColorQuote();}
public slots:
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
signals:
void calculateContextMenuActions();
@ -59,6 +67,8 @@ private slots:
void pasteLink();
void pasteOwnCertificateLink();
void pastePlainText();
void spoiler();
private:
QString textUnderCursor() const;
@ -69,6 +79,7 @@ private:
bool mForceCompleterShowNextKeyEvent;
QString mCompleterStartString;
QList<QAction*> mContextMenuActions;
RsSyntaxHighlighter *highliter;
};
#endif // MIMETEXTEDIT_H

View file

@ -14,6 +14,8 @@ RSTextBrowser::RSTextBrowser(QWidget *parent) :
mImageBlockWidget = NULL;
mLinkClickActive = true;
highliter = new RsSyntaxHighlighter(this);
connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
}

View file

@ -2,6 +2,7 @@
#define RSTEXTBROWSER_H
#include <QTextBrowser>
#include "util/RsSyntaxHighlighter.h"
class RSImageBlockWidget;
@ -9,6 +10,8 @@ class RSTextBrowser : public QTextBrowser
{
Q_OBJECT
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
public:
explicit RSTextBrowser(QWidget *parent = 0);
@ -20,8 +23,11 @@ public:
virtual QVariant loadResource(int type, const QUrl &name);
QColor textColorQuote() const { return highliter->textColorQuote();}
public slots:
void showImages();
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
private slots:
void linkClicked(const QUrl &url);
@ -35,6 +41,7 @@ private:
bool mShowImages;
RSImageBlockWidget *mImageBlockWidget;
bool mLinkClickActive;
RsSyntaxHighlighter *highliter;
};
#endif // RSTEXTBROWSER_H

View file

@ -0,0 +1,549 @@
<RCC>
<qresource prefix="/">
<file>emojione/00A9.png</file>
<file>emojione/00AE.png</file>
<file>emojione/1F004.png</file>
<file>emojione/1F4AA.png</file>
<file>emojione/1F4AB.png</file>
<file>emojione/1F4AC.png</file>
<file>emojione/1F4AD.png</file>
<file>emojione/1F4AE.png</file>
<file>emojione/1F4AF.png</file>
<file>emojione/1F4C0.png</file>
<file>emojione/1F4C1.png</file>
<file>emojione/1F4C2.png</file>
<file>emojione/1F4C3.png</file>
<file>emojione/1F4C4.png</file>
<file>emojione/1F4C5.png</file>
<file>emojione/1F4C6.png</file>
<file>emojione/1F4C7.png</file>
<file>emojione/1F4C8.png</file>
<file>emojione/1F4C9.png</file>
<file>emojione/1F4CA.png</file>
<file>emojione/1F4CB.png</file>
<file>emojione/1F4CC.png</file>
<file>emojione/1F4CD.png</file>
<file>emojione/1F4CE.png</file>
<file>emojione/1F4CF.png</file>
<file>emojione/1F4D0.png</file>
<file>emojione/1F4D1.png</file>
<file>emojione/1F4D2.png</file>
<file>emojione/1F4D3.png</file>
<file>emojione/1F4D4.png</file>
<file>emojione/1F4D5.png</file>
<file>emojione/1F4D6.png</file>
<file>emojione/1F4D7.png</file>
<file>emojione/1F4D8.png</file>
<file>emojione/1F4D9.png</file>
<file>emojione/1F4DA.png</file>
<file>emojione/1F4DB.png</file>
<file>emojione/1F4DC.png</file>
<file>emojione/1F4DD.png</file>
<file>emojione/1F4DE.png</file>
<file>emojione/1F4DF.png</file>
<file>emojione/1F4E0.png</file>
<file>emojione/1F4E1.png</file>
<file>emojione/1F4E2.png</file>
<file>emojione/1F4E3.png</file>
<file>emojione/1F4E4.png</file>
<file>emojione/1F4E5.png</file>
<file>emojione/1F4E6.png</file>
<file>emojione/1F4E7.png</file>
<file>emojione/1F4E8.png</file>
<file>emojione/1F4E9.png</file>
<file>emojione/1F4EA.png</file>
<file>emojione/1F4EB.png</file>
<file>emojione/1F4EC.png</file>
<file>emojione/1F4ED.png</file>
<file>emojione/1F4EE.png</file>
<file>emojione/1F4EF.png</file>
<file>emojione/1F4F0.png</file>
<file>emojione/1F4F1.png</file>
<file>emojione/1F4F2.png</file>
<file>emojione/1F4F3.png</file>
<file>emojione/1F4F4.png</file>
<file>emojione/1F4F5.png</file>
<file>emojione/1F4F6.png</file>
<file>emojione/1F4F7.png</file>
<file>emojione/1F4F8.png</file>
<file>emojione/1F4F9.png</file>
<file>emojione/1F4FA.png</file>
<file>emojione/1F4FB.png</file>
<file>emojione/1F4FC.png</file>
<file>emojione/1F4FD.png</file>
<file>emojione/1F4FE.png</file>
<file>emojione/1F5E2.png</file>
<file>emojione/1F17E.png</file>
<file>emojione/1F17F.png</file>
<file>emojione/1F18E.png</file>
<file>emojione/1F19A.png</file>
<file>emojione/1F21A.png</file>
<file>emojione/1F22F.png</file>
<file>emojione/1F23A.png</file>
<file>emojione/1F32A.png</file>
<file>emojione/1F32B.png</file>
<file>emojione/1F32C.png</file>
<file>emojione/1F36A.png</file>
<file>emojione/1F37A.png</file>
<file>emojione/1F37B.png</file>
<file>emojione/1F43A.png</file>
<file>emojione/1F43B.png</file>
<file>emojione/1F43C.png</file>
<file>emojione/1F43D.png</file>
<file>emojione/1F43E.png</file>
<file>emojione/1F43F.png</file>
<file>emojione/1F44A.png</file>
<file>emojione/1F44B.png</file>
<file>emojione/1F44C.png</file>
<file>emojione/1F44D.png</file>
<file>emojione/1F44E.png</file>
<file>emojione/1F44F.png</file>
<file>emojione/1F46A.png</file>
<file>emojione/1F46B.png</file>
<file>emojione/1F46C.png</file>
<file>emojione/1F46D.png</file>
<file>emojione/1F46E.png</file>
<file>emojione/1F46F.png</file>
<file>emojione/1F47A.png</file>
<file>emojione/1F47B.png</file>
<file>emojione/1F47C.png</file>
<file>emojione/1F47D.png</file>
<file>emojione/1F47E.png</file>
<file>emojione/1F47F.png</file>
<file>emojione/1F48A.png</file>
<file>emojione/1F48B.png</file>
<file>emojione/1F48C.png</file>
<file>emojione/1F48D.png</file>
<file>emojione/1F48E.png</file>
<file>emojione/1F48F.png</file>
<file>emojione/1F49A.png</file>
<file>emojione/1F49B.png</file>
<file>emojione/1F49C.png</file>
<file>emojione/1F49D.png</file>
<file>emojione/1F49E.png</file>
<file>emojione/1F49F.png</file>
<file>emojione/1F54A.png</file>
<file>emojione/1F60A.png</file>
<file>emojione/1F60B.png</file>
<file>emojione/1F60C.png</file>
<file>emojione/1F60D.png</file>
<file>emojione/1F60E.png</file>
<file>emojione/1F60F.png</file>
<file>emojione/1F61A.png</file>
<file>emojione/1F61B.png</file>
<file>emojione/1F61C.png</file>
<file>emojione/1F61D.png</file>
<file>emojione/1F61E.png</file>
<file>emojione/1F61F.png</file>
<file>emojione/1F62A.png</file>
<file>emojione/1F62B.png</file>
<file>emojione/1F62C.png</file>
<file>emojione/1F62D.png</file>
<file>emojione/1F62E.png</file>
<file>emojione/1F62F.png</file>
<file>emojione/1F63A.png</file>
<file>emojione/1F63B.png</file>
<file>emojione/1F63C.png</file>
<file>emojione/1F63D.png</file>
<file>emojione/1F63E.png</file>
<file>emojione/1F63F.png</file>
<file>emojione/1F64A.png</file>
<file>emojione/1F64B.png</file>
<file>emojione/1F64C.png</file>
<file>emojione/1F64D.png</file>
<file>emojione/1F64E.png</file>
<file>emojione/1F64F.png</file>
<file>emojione/1F68A.png</file>
<file>emojione/1F68B.png</file>
<file>emojione/1F68C.png</file>
<file>emojione/1F68D.png</file>
<file>emojione/1F68E.png</file>
<file>emojione/1F68F.png</file>
<file>emojione/1F69A.png</file>
<file>emojione/1F69B.png</file>
<file>emojione/1F69C.png</file>
<file>emojione/1F69D.png</file>
<file>emojione/1F69E.png</file>
<file>emojione/1F69F.png</file>
<file>emojione/1F170.png</file>
<file>emojione/1F171.png</file>
<file>emojione/1F191.png</file>
<file>emojione/1F192.png</file>
<file>emojione/1F193.png</file>
<file>emojione/1F194.png</file>
<file>emojione/1F195.png</file>
<file>emojione/1F196.png</file>
<file>emojione/1F197.png</file>
<file>emojione/1F198.png</file>
<file>emojione/1F199.png</file>
<file>emojione/1F201.png</file>
<file>emojione/1F202.png</file>
<file>emojione/1F232.png</file>
<file>emojione/1F233.png</file>
<file>emojione/1F234.png</file>
<file>emojione/1F235.png</file>
<file>emojione/1F236.png</file>
<file>emojione/1F237.png</file>
<file>emojione/1F238.png</file>
<file>emojione/1F239.png</file>
<file>emojione/1F250.png</file>
<file>emojione/1F251.png</file>
<file>emojione/1F300.png</file>
<file>emojione/1F301.png</file>
<file>emojione/1F302.png</file>
<file>emojione/1F303.png</file>
<file>emojione/1F304.png</file>
<file>emojione/1F305.png</file>
<file>emojione/1F306.png</file>
<file>emojione/1F307.png</file>
<file>emojione/1F308.png</file>
<file>emojione/1F309.png</file>
<file>emojione/1F310.png</file>
<file>emojione/1F311.png</file>
<file>emojione/1F312.png</file>
<file>emojione/1F313.png</file>
<file>emojione/1F314.png</file>
<file>emojione/1F315.png</file>
<file>emojione/1F316.png</file>
<file>emojione/1F317.png</file>
<file>emojione/1F318.png</file>
<file>emojione/1F319.png</file>
<file>emojione/1F320.png</file>
<file>emojione/1F321.png</file>
<file>emojione/1F327.png</file>
<file>emojione/1F328.png</file>
<file>emojione/1F329.png</file>
<file>emojione/1F330.png</file>
<file>emojione/1F331.png</file>
<file>emojione/1F332.png</file>
<file>emojione/1F333.png</file>
<file>emojione/1F334.png</file>
<file>emojione/1F335.png</file>
<file>emojione/1F336.png</file>
<file>emojione/1F337.png</file>
<file>emojione/1F338.png</file>
<file>emojione/1F339.png</file>
<file>emojione/1F340.png</file>
<file>emojione/1F341.png</file>
<file>emojione/1F342.png</file>
<file>emojione/1F343.png</file>
<file>emojione/1F344.png</file>
<file>emojione/1F345.png</file>
<file>emojione/1F346.png</file>
<file>emojione/1F347.png</file>
<file>emojione/1F348.png</file>
<file>emojione/1F349.png</file>
<file>emojione/1F350.png</file>
<file>emojione/1F351.png</file>
<file>emojione/1F352.png</file>
<file>emojione/1F353.png</file>
<file>emojione/1F354.png</file>
<file>emojione/1F355.png</file>
<file>emojione/1F356.png</file>
<file>emojione/1F357.png</file>
<file>emojione/1F358.png</file>
<file>emojione/1F359.png</file>
<file>emojione/1F360.png</file>
<file>emojione/1F361.png</file>
<file>emojione/1F362.png</file>
<file>emojione/1F363.png</file>
<file>emojione/1F364.png</file>
<file>emojione/1F365.png</file>
<file>emojione/1F366.png</file>
<file>emojione/1F367.png</file>
<file>emojione/1F368.png</file>
<file>emojione/1F369.png</file>
<file>emojione/1F370.png</file>
<file>emojione/1F371.png</file>
<file>emojione/1F372.png</file>
<file>emojione/1F373.png</file>
<file>emojione/1F374.png</file>
<file>emojione/1F375.png</file>
<file>emojione/1F376.png</file>
<file>emojione/1F377.png</file>
<file>emojione/1F378.png</file>
<file>emojione/1F379.png</file>
<file>emojione/1F380.png</file>
<file>emojione/1F381.png</file>
<file>emojione/1F382.png</file>
<file>emojione/1F383.png</file>
<file>emojione/1F384.png</file>
<file>emojione/1F385.png</file>
<file>emojione/1F386.png</file>
<file>emojione/1F387.png</file>
<file>emojione/1F388.png</file>
<file>emojione/1F389.png</file>
<file>emojione/1F390.png</file>
<file>emojione/1F391.png</file>
<file>emojione/1F392.png</file>
<file>emojione/1F393.png</file>
<file>emojione/1F394.png</file>
<file>emojione/1F395.png</file>
<file>emojione/1F396.png</file>
<file>emojione/1F397.png</file>
<file>emojione/1F398.png</file>
<file>emojione/1F399.png</file>
<file>emojione/1F400.png</file>
<file>emojione/1F401.png</file>
<file>emojione/1F402.png</file>
<file>emojione/1F403.png</file>
<file>emojione/1F404.png</file>
<file>emojione/1F405.png</file>
<file>emojione/1F406.png</file>
<file>emojione/1F407.png</file>
<file>emojione/1F408.png</file>
<file>emojione/1F409.png</file>
<file>emojione/1F410.png</file>
<file>emojione/1F411.png</file>
<file>emojione/1F412.png</file>
<file>emojione/1F413.png</file>
<file>emojione/1F414.png</file>
<file>emojione/1F415.png</file>
<file>emojione/1F416.png</file>
<file>emojione/1F417.png</file>
<file>emojione/1F418.png</file>
<file>emojione/1F419.png</file>
<file>emojione/1F420.png</file>
<file>emojione/1F421.png</file>
<file>emojione/1F422.png</file>
<file>emojione/1F423.png</file>
<file>emojione/1F424.png</file>
<file>emojione/1F425.png</file>
<file>emojione/1F426.png</file>
<file>emojione/1F427.png</file>
<file>emojione/1F428.png</file>
<file>emojione/1F429.png</file>
<file>emojione/1F430.png</file>
<file>emojione/1F431.png</file>
<file>emojione/1F432.png</file>
<file>emojione/1F433.png</file>
<file>emojione/1F434.png</file>
<file>emojione/1F435.png</file>
<file>emojione/1F436.png</file>
<file>emojione/1F437.png</file>
<file>emojione/1F438.png</file>
<file>emojione/1F439.png</file>
<file>emojione/1F440.png</file>
<file>emojione/1F441.png</file>
<file>emojione/1F442.png</file>
<file>emojione/1F443.png</file>
<file>emojione/1F444.png</file>
<file>emojione/1F445.png</file>
<file>emojione/1F446.png</file>
<file>emojione/1F447.png</file>
<file>emojione/1F448.png</file>
<file>emojione/1F449.png</file>
<file>emojione/1F450.png</file>
<file>emojione/1F451.png</file>
<file>emojione/1F452.png</file>
<file>emojione/1F453.png</file>
<file>emojione/1F454.png</file>
<file>emojione/1F455.png</file>
<file>emojione/1F456.png</file>
<file>emojione/1F457.png</file>
<file>emojione/1F458.png</file>
<file>emojione/1F459.png</file>
<file>emojione/1F460.png</file>
<file>emojione/1F461.png</file>
<file>emojione/1F462.png</file>
<file>emojione/1F463.png</file>
<file>emojione/1F464.png</file>
<file>emojione/1F465.png</file>
<file>emojione/1F466.png</file>
<file>emojione/1F467.png</file>
<file>emojione/1F468.png</file>
<file>emojione/1F469.png</file>
<file>emojione/1F470.png</file>
<file>emojione/1F471.png</file>
<file>emojione/1F472.png</file>
<file>emojione/1F473.png</file>
<file>emojione/1F474.png</file>
<file>emojione/1F475.png</file>
<file>emojione/1F476.png</file>
<file>emojione/1F477.png</file>
<file>emojione/1F478.png</file>
<file>emojione/1F479.png</file>
<file>emojione/1F480.png</file>
<file>emojione/1F481.png</file>
<file>emojione/1F482.png</file>
<file>emojione/1F483.png</file>
<file>emojione/1F484.png</file>
<file>emojione/1F485.png</file>
<file>emojione/1F486.png</file>
<file>emojione/1F487.png</file>
<file>emojione/1F488.png</file>
<file>emojione/1F489.png</file>
<file>emojione/1F490.png</file>
<file>emojione/1F491.png</file>
<file>emojione/1F492.png</file>
<file>emojione/1F493.png</file>
<file>emojione/1F494.png</file>
<file>emojione/1F495.png</file>
<file>emojione/1F496.png</file>
<file>emojione/1F497.png</file>
<file>emojione/1F498.png</file>
<file>emojione/1F499.png</file>
<file>emojione/1F574.png</file>
<file>emojione/1F575.png</file>
<file>emojione/1F595.png</file>
<file>emojione/1F596.png</file>
<file>emojione/1F597.png</file>
<file>emojione/1F598.png</file>
<file>emojione/1F599.png</file>
<file>emojione/1F600.png</file>
<file>emojione/1F601.png</file>
<file>emojione/1F602.png</file>
<file>emojione/1F603.png</file>
<file>emojione/1F604.png</file>
<file>emojione/1F605.png</file>
<file>emojione/1F606.png</file>
<file>emojione/1F607.png</file>
<file>emojione/1F608.png</file>
<file>emojione/1F609.png</file>
<file>emojione/1F610.png</file>
<file>emojione/1F611.png</file>
<file>emojione/1F612.png</file>
<file>emojione/1F613.png</file>
<file>emojione/1F614.png</file>
<file>emojione/1F615.png</file>
<file>emojione/1F616.png</file>
<file>emojione/1F617.png</file>
<file>emojione/1F618.png</file>
<file>emojione/1F619.png</file>
<file>emojione/1F620.png</file>
<file>emojione/1F621.png</file>
<file>emojione/1F622.png</file>
<file>emojione/1F623.png</file>
<file>emojione/1F624.png</file>
<file>emojione/1F625.png</file>
<file>emojione/1F626.png</file>
<file>emojione/1F627.png</file>
<file>emojione/1F628.png</file>
<file>emojione/1F629.png</file>
<file>emojione/1F630.png</file>
<file>emojione/1F631.png</file>
<file>emojione/1F632.png</file>
<file>emojione/1F633.png</file>
<file>emojione/1F634.png</file>
<file>emojione/1F635.png</file>
<file>emojione/1F636.png</file>
<file>emojione/1F637.png</file>
<file>emojione/1F638.png</file>
<file>emojione/1F639.png</file>
<file>emojione/1F640.png</file>
<file>emojione/1F641.png</file>
<file>emojione/1F642.png</file>
<file>emojione/1F645.png</file>
<file>emojione/1F646.png</file>
<file>emojione/1F647.png</file>
<file>emojione/1F648.png</file>
<file>emojione/1F649.png</file>
<file>emojione/1F680.png</file>
<file>emojione/1F681.png</file>
<file>emojione/1F682.png</file>
<file>emojione/1F683.png</file>
<file>emojione/1F684.png</file>
<file>emojione/1F685.png</file>
<file>emojione/1F686.png</file>
<file>emojione/1F687.png</file>
<file>emojione/1F688.png</file>
<file>emojione/1F689.png</file>
<file>emojione/1F690.png</file>
<file>emojione/1F691.png</file>
<file>emojione/1F692.png</file>
<file>emojione/1F693.png</file>
<file>emojione/1F694.png</file>
<file>emojione/1F695.png</file>
<file>emojione/1F696.png</file>
<file>emojione/1F697.png</file>
<file>emojione/1F698.png</file>
<file>emojione/1F699.png</file>
<file>emojione/2B1B.png</file>
<file>emojione/2B1C.png</file>
<file>emojione/2B05.png</file>
<file>emojione/2B06.png</file>
<file>emojione/2B07.png</file>
<file>emojione/2B50.png</file>
<file>emojione/2B55.png</file>
<file>emojione/21A9.png</file>
<file>emojione/21AA.png</file>
<file>emojione/23E9.png</file>
<file>emojione/23EA.png</file>
<file>emojione/23EB.png</file>
<file>emojione/23EC.png</file>
<file>emojione/23F0.png</file>
<file>emojione/23F3.png</file>
<file>emojione/24C2.png</file>
<file>emojione/25AA.png</file>
<file>emojione/25AB.png</file>
<file>emojione/25B6.png</file>
<file>emojione/25C0.png</file>
<file>emojione/25FB.png</file>
<file>emojione/25FC.png</file>
<file>emojione/25FD.png</file>
<file>emojione/25FE.png</file>
<file>emojione/26A0.png</file>
<file>emojione/26A1.png</file>
<file>emojione/26AA.png</file>
<file>emojione/26AB.png</file>
<file>emojione/26BD.png</file>
<file>emojione/26BE.png</file>
<file>emojione/26C4.png</file>
<file>emojione/26C5.png</file>
<file>emojione/26CE.png</file>
<file>emojione/26D4.png</file>
<file>emojione/26EA.png</file>
<file>emojione/26F2.png</file>
<file>emojione/26F3.png</file>
<file>emojione/26F5.png</file>
<file>emojione/26FA.png</file>
<file>emojione/26FD.png</file>
<file>emojione/27A1.png</file>
<file>emojione/27B0.png</file>
<file>emojione/27BF.png</file>
<file>emojione/203C.png</file>
<file>emojione/231A.png</file>
<file>emojione/231B.png</file>
<file>emojione/260E.png</file>
<file>emojione/261D.png</file>
<file>emojione/263A.png</file>
<file>emojione/264A.png</file>
<file>emojione/264B.png</file>
<file>emojione/264C.png</file>
<file>emojione/264D.png</file>
<file>emojione/264E.png</file>
<file>emojione/264F.png</file>
<file>emojione/267B.png</file>
<file>emojione/267F.png</file>
<file>emojione/270A.png</file>
<file>emojione/270B.png</file>
<file>emojione/270C.png</file>
<file>emojione/270F.png</file>
<file>emojione/274C.png</file>
<file>emojione/274E.png</file>
<file>emojione/303D.png</file>
<file>emojione/2049.png</file>
<file>emojione/2600.png</file>
<file>emojione/2601.png</file>
<file>emojione/2611.png</file>
<file>emojione/2614.png</file>
<file>emojione/2615.png</file>
<file>emojione/2708.png</file>
<file>emojione/2744.png</file>
<file>emojione/2764.png</file>
<file>emojione/2934.png</file>
<file>emojione/2935.png</file>
<file>emojione/3030.png</file>
<file>emojione/3297.png</file>
<file>emojione/3299.png</file>
<file>emojione/1f910.png</file>
<file>emojione/1f911.png</file>
<file>emojione/1f912.png</file>
<file>emojione/1f913.png</file>
<file>emojione/1f914.png</file>
<file>emojione/1f915.png</file>
<file>emojione/1f916.png</file>
<file>emojione/1f643.png</file>
<file>emojione/emotes.acs</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,009 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

Some files were not shown because too many files have changed in this diff Show more