Commit 4986da08 authored by Philip Rinn's avatar Philip Rinn

Imported Upstream version 1.1.3

parent 9ce9423d
install:
- set QTDIR=C:\Qt\5.5\mingw492_32
- set QTDIR=C:\Qt\5.6\mingw49_32
- choco install -y InnoSetup
- set PATH=%QTDIR%\bin;C:\MinGW\bin;%PATH%;"C:\Program Files (x86)\Inno Setup 5"
build_script:
- qmake qtpass.pro CONFIG+=static
- mingw32-make
after_build:
- cmd: copy README.md release\README.txt
- cmd: copy LICENSE release\LICENSE.txt
- iscc qtpass.iss
- qmake qtpass.pro CONFIG+=static
- mingw32-make
#after_build:
- cmd: copy README.md release\README.txt
- cmd: copy LICENSE release\LICENSE.txt
- iscc qtpass.iss
artifacts:
- path: Output\qtpass-*.exe
- path: release\qtpass.exe
......
[Default]
bears = SpaceConsistencyBear
files = *.cpp, *.h, *.ui
use_spaces = true
default_actions = SpaceConsistencyBear: ApplyPatchAction
[DOCS]
bears = SpaceConsistencyBear
files = *.md
[commit]
bears = GitCommitBear
......@@ -3,7 +3,8 @@ debian/qtpass*
debian/files
build-stamp
qtpass
QtPass.*
QtPass.app
QtPass.dmg
qtpass.pro.user
qtpass.xcodeproj/project.xcworkspace/xcuserdata/*
qtpass.xcodeproj/xcuserdata/*
......
language: cpp
sudo: false
sudo: true
os:
- linux
- osx
compiler:
- gcc
- clang
addons:
apt:
packages:
- qt5-default
install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq qt5 || brew install qt5;
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH=$PATH:/usr/local/opt/qt5/bin;
fi
env:
global:
secure: WaZq3f6KIAc0dnR4WOXYWDvUYiqlrzsZC/PQse47FnvC0oQC65J5w3kJOj/P26DgsUEqKQF3ukXogkM2mp5pS4+CMgivEmQmAbgQTtwcKpC5HPZxgI+8FgkCjcalJKWGWYoxlScNVNiKMs+89ApcSQE9kH9PZeUS9dukN2Php1U=
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo add-apt-repository -y ppa:beineri/opt-qt56; fi
addons:
coverity_scan:
project:
name: "IJHack/qtpass"
description: "Build submitted via Travis CI"
name: IJHack/qtpass
description: Build submitted via Travis CI
notification_email: brouwer@annejan.com
build_command_prepend: "qmake; make clean"
build_command: "make"
build_command_prepend: qmake; make clean
build_command: make
branch_pattern: coverity_scan
install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew unlink node; brew install node; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq qt5 || brew install qt5; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH=$PATH:/usr/local/opt/qt5/bin; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install pandoc; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then npm install -g appdmg; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install qt56base qt56tools qt56svg; fi
before_script:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then source /opt/qt56/bin/qt56-env.sh; fi
script:
- qmake -v
- qmake -Wall qtpass.pro
- make -j$(nproc)
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then macdeployqt QtPass.app; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then pandoc --standalone --from=markdown --to=rtf --output=README.rtf README.md; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then appdmg appdmg.json qtpass-$(grep ^VERSION qtpass.pro | cut -d " " -f 6).dmg; fi
notifications:
irc:
channels:
- chat.freenode.net#IJhack
on_success: change
on_failure: always
deploy:
provider: releases
api_key:
secure: O6LAl2R5QIe/mgQwG5/pzbdC8gS58wtGVF2ebTVGgYsCgY0nRjLZ19H7BiQrYjbbXs8yw6cQjA+xbxNiVsIVs+Dx9j/fy2JOBeBTrGijlWLcJPT6/Ab65EjI2T96XvI8/YejRmbgjIdXFfuKtD/V4MM12LrvrvktwJp00G9l1Go=
file: qtpass-$(grep ^VERSION qtpass.pro | cut -d " " -f 6).dmg
on:
repo: IJHack/qtpass
tags: true
condition: $TRAVIS_OS_NAME = osx && $CC = clang
skip_cleanup: true
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -55,7 +55,7 @@ git for Windows comes with an `ssh-askpass` compatible command, git `gui--askpas
### Can I import from KeePass, LastPass or X?
* Yes, check [passwordstore.org/#migration](http://www.passwordstore.org/#migration)
* Yes, check [passwordstore.org/#migration](https://www.passwordstore.org/#migration)
for more info.
### I don't see icons on the buttons
......@@ -70,12 +70,12 @@ Please install using your favorite package manager.
export DESKTOP_SESSION=gnome
```
* Another possible reason is, that the currently installed Qt Version makes problems (e.g. on Linux Mint 17.3)
* Another possible reason is, that the currently installed Qt Version makes problems (e.g. on Linux Mint 17.3)
Then you have to install the current version via your package manager or if this is not up-to-date,
download it from http://www.qt.io/download/ install it and run:
download it from https://www.qt.io/download/ install it and run:
```
/PATHTOYOURQTINSTALLATION/5.5/gcc_64/bin/qmake
make
make
(sudo) make install
```
where `PATHTOYOURINSTALLATION` is the path you selected in the qt installer (default `/home/YOURUSER/Qt/` )
......@@ -97,4 +97,4 @@ and 5.5 has to be adapted for the Qt version you downloaded.
* Participate in our bug bounty, you submit an issue and help us
fix it, I send you a bounty.
* Money:
* IJhack takes donations in [bitcoin](https://blockchain.info/address/146dqz8zXn9iNZMv5s7JVqwZKjrmumHBfb)
* IJhack takes donations in [Bitcoin](https://blockchain.info/address/146dqz8zXn9iNZMv5s7JVqwZKjrmumHBfb)
......@@ -5,7 +5,7 @@ QtPass
[![Build status](https://ci.appveyor.com/api/projects/status/9rjnj72rdir7u9eg/branch/master?svg=true)](https://ci.appveyor.com/project/annejan/qtpass/branch/master)
[![Coverity scan](https://scan.coverity.com/projects/5266/badge.svg)](https://scan.coverity.com/projects/ijhack-qtpass)
QtPass is a GUI for [pass](http://www.passwordstore.org/),
QtPass is a GUI for [pass](https://www.passwordstore.org/),
the standard unix password manager.
Features
......
#include "configdialog.h"
#include "ui_configdialog.h"
#include "mainwindow.h"
#include "keygendialog.h"
#include "mainwindow.h"
#include "ui_configdialog.h"
#include <QDebug>
#include <QMessageBox>
#include <QDir>
#include <QMessageBox>
#ifdef Q_OS_WIN
#include <windows.h>
#endif
......@@ -203,7 +203,7 @@ void ConfigDialog::on_toolButtonPass_clicked() {
*/
void ConfigDialog::on_toolButtonStore_clicked() {
QString store = selectFolder();
if (!store.isEmpty()) // TODO(annejan) call check
if (!store.isEmpty()) // TODO(annejan) call check
ui->storePath->setText(store);
}
......@@ -451,7 +451,7 @@ void ConfigDialog::on_addButton_clicked() {
* @brief ConfigDialog::on_deleteButton_clicked
*/
void ConfigDialog::on_deleteButton_clicked() {
QSet<int> selectedRows; // we use a set to prevent doubles
QSet<int> selectedRows; // we use a set to prevent doubles
QList<QTableWidgetItem *> itemList = ui->profileTable->selectedItems();
if (itemList.count() == 0) {
QMessageBox::warning(this, tr("No profile selected"),
......@@ -459,13 +459,13 @@ void ConfigDialog::on_deleteButton_clicked() {
return;
}
QTableWidgetItem *item;
foreach(item, itemList)
foreach (item, itemList)
selectedRows.insert(item->row());
// get a list, and sort it big to small
QList<int> rows = selectedRows.toList();
qSort(rows.begin(), rows.end());
// now actually do the removing:
foreach(int row, rows)
foreach (int row, rows)
ui->profileTable->removeRow(row);
if (ui->profileTable->rowCount() < 1)
ui->deleteButton->setEnabled(false);
......@@ -727,11 +727,14 @@ void ConfigDialog::setPasswordChars(QString pwChars) {
*/
bool ConfigDialog::usePwgen() { return ui->checkBoxUsePwgen->isChecked(); }
bool ConfigDialog::avoidCapitals() { return ui->checkBoxAvoidCapitals->isChecked(); }
bool ConfigDialog::avoidNumbers() { return ui->checkBoxAvoidNumbers->isChecked(); }
bool ConfigDialog::avoidCapitals() {
return ui->checkBoxAvoidCapitals->isChecked();
}
bool ConfigDialog::avoidNumbers() {
return ui->checkBoxAvoidNumbers->isChecked();
}
bool ConfigDialog::lessRandom() { return ui->checkBoxLessRandom->isChecked(); }
/**
* @brief ConfigDialog::useSymbols
* @return
......@@ -861,7 +864,7 @@ void ConfigDialog::templateAllFields(bool templateAll) {
* @param alwaysOnTop
*/
void ConfigDialog::alwaysOnTop(bool alwaysOnTop) {
ui->checkBoxAlwaysOnTop->setChecked(alwaysOnTop);
ui->checkBoxAlwaysOnTop->setChecked(alwaysOnTop);
}
/**
......@@ -869,5 +872,5 @@ void ConfigDialog::alwaysOnTop(bool alwaysOnTop) {
* @return
*/
bool ConfigDialog::alwaysOnTop() {
return ui->checkBoxAlwaysOnTop->isChecked();
return ui->checkBoxAlwaysOnTop->isChecked();
}
#ifndef CONFIGDIALOG_H_
#define CONFIGDIALOG_H_
#include "mainwindow.h"
#include <QCloseEvent>
#include <QDialog>
#include <QFileDialog>
#include <QTableWidgetItem>
#include <QCloseEvent>
#include "mainwindow.h"
namespace Ui {
struct UserInfo;
......@@ -13,10 +13,16 @@ struct UserInfo;
class ConfigDialog;
}
/*!
\class ConfigDialog
\brief The ConfigDialog handles the configuration interface.
This class should also take the handling from the MainWindow class.
*/
class ConfigDialog : public QDialog {
Q_OBJECT
public:
public:
explicit ConfigDialog(MainWindow *parent);
~ConfigDialog();
void setPassPath(QString);
......@@ -86,10 +92,10 @@ class ConfigDialog : public QDialog {
bool alwaysOnTop();
void alwaysOnTop(bool alwaysOnTop);
protected:
protected:
void closeEvent(QCloseEvent *event);
private slots:
private slots:
void on_radioButtonNative_clicked();
void on_radioButtonPass_clicked();
void on_toolButtonGit_clicked();
......@@ -107,7 +113,7 @@ class ConfigDialog : public QDialog {
void on_checkBoxUsePwgen_clicked();
void on_checkBoxUseTemplate_clicked();
private:
private:
QScopedPointer<Ui::ConfigDialog> ui;
void setGroupBoxState();
QString selectExecutable();
......@@ -118,4 +124,4 @@ class ConfigDialog : public QDialog {
MainWindow *mainWindow;
};
#endif // CONFIGDIALOG_H_
#endif // CONFIGDIALOG_H_
......@@ -595,7 +595,7 @@
<item>
<widget class="QLabel" name="zx2c4">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://www.passwordstore.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;www.passwordstore.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://www.passwordstore.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;www.passwordstore.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
......@@ -786,7 +786,7 @@ email</string>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;a href=&quot;http://QtPass.org/&quot;&gt;QtPass&lt;/a&gt; version </string>
<string>&lt;a href=&quot;https://QtPass.org/&quot;&gt;QtPass&lt;/a&gt; version </string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
......
#include "keygendialog.h"
#include "qprogressindicator.h"
#include "ui_keygendialog.h"
#include <QDebug>
#include <QMessageBox>
#include "ui_keygendialog.h"
#include "qprogressindicator.h"
KeygenDialog::KeygenDialog(ConfigDialog *parent)
: QDialog(parent), ui(new Ui::KeygenDialog) {
......@@ -56,7 +56,7 @@ void KeygenDialog::replace(QString key, QString value) {
QStringList clear;
QString expert = ui->plainTextEdit->toPlainText();
QStringList lines = expert.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
foreach(QString line, lines) {
foreach (QString line, lines) {
line.replace(QRegExp(key + ":.*"), key + ": " + value);
if (key == "Passphrase")
line.replace("%no-protection", "Passphrase: " + value);
......@@ -73,7 +73,7 @@ void KeygenDialog::no_protection(bool enable) {
QStringList clear;
QString expert = ui->plainTextEdit->toPlainText();
QStringList lines = expert.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
foreach(QString line, lines) {
foreach (QString line, lines) {
bool remove = false;
if (!enable) {
if (line.indexOf("%no-protection") == 0)
......@@ -93,7 +93,7 @@ void KeygenDialog::no_protection(bool enable) {
* @param r
*/
void KeygenDialog::done(int r) {
if (QDialog::Accepted == r) { // ok was pressed
if (QDialog::Accepted == r) { // ok was pressed
ui->widget->setEnabled(false);
ui->buttonBox->setEnabled(false);
ui->checkBox->setEnabled(false);
......@@ -116,7 +116,7 @@ void KeygenDialog::done(int r) {
this->show();
dialog->genKey(ui->plainTextEdit->toPlainText(), this);
} else { // cancel, close or exc was pressed
} else { // cancel, close or exc was pressed
QDialog::done(r);
return;
}
......
#ifndef KEYGENDIALOG_H_
#define KEYGENDIALOG_H_
#include <QDialog>
#include <QCloseEvent>
#include "configdialog.h"
#include <QCloseEvent>
#include <QDialog>
namespace Ui {
class KeygenDialog;
}
/*!
\class KeygenDialog
\brief Handles GPG keypair generation.
*/
class KeygenDialog : public QDialog {
Q_OBJECT
public:
public:
explicit KeygenDialog(ConfigDialog *parent = 0);
~KeygenDialog();
protected:
protected:
void closeEvent(QCloseEvent *event);
private slots:
private slots:
void on_passphrase1_textChanged(const QString &arg1);
void on_passphrase2_textChanged(const QString &arg1);
void on_checkBox_stateChanged(int arg1);
void on_email_textChanged(const QString &arg1);
void on_name_textChanged(const QString &arg1);
private:
private:
Ui::KeygenDialog *ui;
void replace(QString, QString);
void done(int r);
......@@ -34,4 +38,4 @@ class KeygenDialog : public QDialog {
ConfigDialog *dialog;
};
#endif // KEYGENDIALOG_H_
#endif // KEYGENDIALOG_H_
......@@ -151,13 +151,13 @@
<string># QtPass GPG key generator
#
# first test version please comment
#
#
%echo Generating a default key
Key-Type: default
Subkey-Type: default
Name-Real:
Name-Real:
Name-Comment: QtPass
Name-Email:
Name-Email:
Expire-Date: 0
%no-protection
# Do a commit here, so that we can later print &quot;done&quot; :-)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -329,9 +329,9 @@
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; font-weight:600; color:#333333;&quot;&gt;QtPass&lt;/span&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; color:#333333;&quot;&gt; is a GUI for &lt;/span&gt;&lt;a href=&quot;http://www.passwordstore.org/&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; text-decoration: underline; color:#4183c4; background-color:transparent;&quot;&gt;pass&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; color:#333333;&quot;&gt;, the standard unix password manager.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; font-weight:600; color:#333333;&quot;&gt;QtPass&lt;/span&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; color:#333333;&quot;&gt; is a GUI for &lt;/span&gt;&lt;a href=&quot;https://www.passwordstore.org/&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; text-decoration: underline; color:#4183c4; background-color:transparent;&quot;&gt;pass&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; color:#333333;&quot;&gt;, the standard unix password manager.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; color:#333333;&quot;&gt;&lt;br /&gt;Please report any &lt;/span&gt;&lt;a href=&quot;https://github.com/IJHack/qtpass/issues&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; text-decoration: underline; color:#4183c4;&quot;&gt;issues&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; color:#333333;&quot;&gt; you might have with this software.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://qtpass.org/&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; text-decoration: underline; color:#4183c4; background-color:transparent;&quot;&gt;Documentation&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://qtpass.org/&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; text-decoration: underline; color:#4183c4; background-color:transparent;&quot;&gt;Documentation&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://github.com/IJHack/qtpass&quot;&gt;&lt;span style=&quot; font-family:'Helvetica Neue,Helvetica,Segoe UI,Arial,freesans,sans-serif'; font-size:13pt; text-decoration: underline; color:#4183c4; background-color:transparent;&quot;&gt;Source code&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
.TH QtPass "1" "Sep 16, 2015"
.SH NAME
qtpass \- GUI for password manager pass
.SH SYNOPSIS
\fBqtpass\fP [directory of the password\-store]
.SH DESCRIPTION
\fBQtPass\fP is a GUI password manager based on pass with the following
features:
* Reading pass password stores
* Decrypting and displaying the password info
* Updating from the git repository
* Editing and adding of passwords
* Adding and removing people from gpg-id per folder
* Read operations also supported without pass (using gpg and git)
* Configuration options for backends and executable/folder locations
* Copying password to clipboard
* Hiding of password against shouldersurfing
* Experimental WebDAV support
.SH AUTHOR
This manual page was written by Philip Rinn <rinni@inventati.org> for the
Debian GNU/Linux system (but may be used by others).
This diff is collapsed.
This diff is collapsed.
......@@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "QtPass"
#define MyAppVersion "1.1.1"
#define MyAppVersion "1.1.3"
#define MyAppPublisher "IJhack"
#define MyAppURL "https://qtpass.org/"
#define MyAppExeName "qtpass.exe"
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment