1
0
forked from BRT/arc

Remove CommonBirbankScript and its derived classes from the codebase

Deleted `CommonBirbankScript` and its associated derived classes (`GetLastDaysHistoryBirbankScript`, `LoginAndCheckAccountsBirbankScript`, `PayByCardBirbankScript`). Removed dependencies on these scripts, including XML parsing, account handling, and transaction workflows related to the Birbank app.
This commit is contained in:
slava 2026-03-21 17:41:05 +07:00
parent 10897164e9
commit 712b73316c
273 changed files with 983 additions and 70809 deletions

View File

@ -92,6 +92,10 @@ add_executable(ARCDesktopProject WIN32
${ANDROID_SOURCES}
views/bank/BankSettingsWindow.cpp
views/bank/BankSettingsWindow.h
views/log/FileLogWindow.cpp
views/log/FileLogWindow.h
database/dao/GeneralLogDAO.cpp
database/dao/GeneralLogDAO.h
)
elseif (APPLE)
add_executable(ARCDesktopProject
@ -103,6 +107,10 @@ elseif (APPLE)
${ANDROID_SOURCES}
views/bank/BankSettingsWindow.cpp
views/bank/BankSettingsWindow.h
views/log/FileLogWindow.cpp
views/log/FileLogWindow.h
database/dao/GeneralLogDAO.cpp
database/dao/GeneralLogDAO.h
)
endif ()

View File

@ -4,6 +4,7 @@
#include <QString>
#include <QCoreApplication>
#include <QFileInfo>
#include <QThread>
AdbUtils::AdbUtils(QObject *parent) : QObject(parent) {
}
@ -198,9 +199,18 @@ QString AdbUtils::getScreenDumpAsXml(const QString &deviceId, int idx, bool scre
const QString adb = adbPath();
QString output;
// 1. Dump UI hierarchy
if (!startProcess(adb, {"-s", deviceId, "shell", "uiautomator", "dump", "/sdcard/uidump.xml"})) {
qWarning() << "Failed to dump UI hierarchy.";
// 1. Dump UI hierarchy (retry up to 3 times — uiautomator may be killed by Android)
bool dumpOk = false;
for (int attempt = 0; attempt < 3; ++attempt) {
if (startProcess(adb, {"-s", deviceId, "shell", "uiautomator", "dump", "/sdcard/uidump.xml"})) {
dumpOk = true;
break;
}
qWarning() << "[AdbUtils] uiautomator dump failed, attempt" << (attempt + 1) << "of 3";
QThread::msleep(1000);
}
if (!dumpOk) {
qWarning() << "Failed to dump UI hierarchy after 3 attempts.";
return {};
}
// 2. Optionally pull and save the XML file

View File

@ -1,217 +0,0 @@
#include "CommonBirbankScript.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include "adb/AdbUtils.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
CommonBirbankScript::CommonBirbankScript(QObject *parent)
: QObject(parent) {
}
CommonBirbankScript::~CommonBirbankScript() = default;
void CommonBirbankScript::start() {
doStart();
emit finished();
}
Node CommonBirbankScript::swipeToButton(
const QString &deviceId,
const QString &text, int &counter, const int width, const int height
) {
for (int i = 0; i < 10; ++i) {
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
return button;
}
const int x = width / 2;
const int offset = height / 4;
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
return {};
}
bool CommonBirbankScript::runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
const int width,
const int height
) {
// Запустить устройство
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
qDebug() << "Process already running, pid: " << pid;
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
AdbUtils::tryToKillApplication(deviceId, packageName);
}
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
AdbUtils::takeScreenshot(deviceId, "run_app_error");
qWarning() << "Process has not started";
return false;
}
// Даем минимальное время на запуск
QThread::msleep(2500);
int counter = 0;
bool findAndInputPincode = false;
while (true) {
counter++;
// Если более 10 раз мы пытаемся перейти на домашнюю
if (counter > 10) {
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
return false;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
continue;
}
if (xmlScreenParser.isHomeScreen()) {
return true;
}
// Проверяем, что это экран ввода пин-кода
if (!findAndInputPincode) {
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(pinCode); pincode.size() == 4) {
for (const Node &node: pincode) {
AdbUtils::makeTap(deviceId, node.x(), node.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
findAndInputPincode = true;
QThread::msleep(3000);
continue;
}
}
QThread::msleep(1000);
}
}
bool CommonBirbankScript::goToAllProducts(
const QString &deviceId,
const int width,
const int height
) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(500);
}
if (xmlScreenParser.isHomeScreen()) {
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
if (!allMyAccountBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
QThread::msleep(500);
return true;
}
}
return false;
}
void CommonBirbankScript::postAccountsData(const QList<AccountInfo> &accounts) {
if (accounts.isEmpty()) {
return;
}
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonArray list;
for (const AccountInfo &account: accounts) {
QJsonObject obj;
obj["appName"] = account.appCode;
obj["lastNumbers"] = account.lastNumbers;
obj["amount"] = account.amount;
obj["currency"] = account.currency;
obj["description"] = account.description;
obj["status"] = accountStatusToString(account.status);
list.append(obj);
}
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(accounts.first().deviceId);
worker->setPayload(QJsonDocument(list).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonBirbankScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transaction.id;
obj["amount"] = transaction.amount;
obj["name"] = transaction.name;
obj["fee"] = transaction.fee;
obj["status"] = transactionStatusToString(transaction.status);
obj["type"] = transactionTypeToString(transaction.type);
obj["phone"] = transaction.phone;
obj["description"] = transaction.description + " | " + transaction.bankTime;
obj["updatedDescription"] = transaction.updatedDescription;
obj["bankName"] = transaction.bankName;
obj["bankTime"] = DateUtils::toUtcString(transaction.completeTime);
obj["bankTransactionId"] = transaction.bankTrExternalId;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->addExtra("transactionId", transaction.id);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonBirbankScript::updateTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transactionId;
obj["status"] = transactionStatusToString(status);
obj["description"] = newDesc;
obj["updatedDescription"] = oldDesc;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonBirbankScript::stop() {
m_running = false;
}

View File

@ -1,68 +0,0 @@
#pragma once
#include <QObject>
#include "ScreenXmlBirbankParser.h"
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
class CommonBirbankScript : public QObject {
Q_OBJECT
public:
explicit CommonBirbankScript(QObject *parent = nullptr);
~CommonBirbankScript() override;
protected:
virtual void doStart() = 0;
bool goToAllProducts(
const QString &deviceId,
int width,
int height
);
void postAccountsData(const QList<AccountInfo> &accounts);
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
void updateTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
Node swipeToButton(
const QString &deviceId,
const QString &text,
int &counter, int width, int height
);
bool runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
int width,
int height
);
bool m_running = true;
ScreenXmlBirbankParser xmlScreenParser;
int m_counter = 0;
signals:
void finished();
void finishedWithResult(const QString &result);
public slots:
virtual void start() final;
virtual void stop() final;
private:
Q_DISABLE_COPY(CommonBirbankScript);
};

View File

@ -1,164 +0,0 @@
#include "GetLastDaysHistoryBirbankScript.h"
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/DeviceInfo.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
GetLastDaysHistoryBirbankScript::GetLastDaysHistoryBirbankScript(
AccountInfo account,
QObject *parent
) : CommonBirbankScript(parent),
m_account(std::move(account)) {
}
GetLastDaysHistoryBirbankScript::~GetLastDaysHistoryBirbankScript() = default;
bool GetLastDaysHistoryBirbankScript::saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
) {
TransactionInfo tr;
tr.accountId = account.id;
tr.description = transaction.description;
tr.bankTime = transaction.bankTime;
tr.bankName = transaction.bankName;
tr.amount = transaction.amount;
tr.phone = transaction.phone;
tr.updateTime = DateUtils::getUtcNow();
tr.fee = transaction.fee;
tr.name = transaction.name;
tr.bankTrExternalId = transaction.bankTrExternalId;
tr.status = status;
tr.type = TransactionType::Card;
tr.completeTime = transaction.completeTime;
tr.id = TransactionDAO::insertTransaction(tr);
if (tr.id == -1) {
return false;
}
postNewTransactionData(account, tr);
return true;
}
bool GetLastDaysHistoryBirbankScript::updateAndPostTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
return true;
}
return false;
}
void GetLastDaysHistoryBirbankScript::doStart() {
// берем все транзакции из БД
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(device.id, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
}
if (xmlScreenParser.isHomeScreen()) {
// QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
QMap<QString, AccountInfo> accountMap;
for (AccountInfo &oldAccount: oldAccounts) {
if (oldAccount.status == AccountStatus::Active) {
accountMap.insert(oldAccount.lastNumbers, oldAccount);
}
}
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
for (auto account: accounts) {
if (accountMap.contains(account.lastNumbers)) {
account.deviceId = m_account.deviceId;
account.appCode = m_account.appCode;
account.currency = accountMap[account.lastNumbers].currency;
account.description = accountMap[account.lastNumbers].description;
account.status = AccountStatus::Active;
if (!AccountDAO::upsertAccount(account)) {
m_error = "Not updated: " + account.lastNumbers;
qCritical() << m_error;
}
}
}
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
postAccountsData(savedAccounts);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node cardText = xmlScreenParser.findTextNode(m_account.lastNumbers);
if (!cardText.isEmpty()) {
AdbUtils::makeTap(device.id, cardText.x(), cardText.y());
QThread::msleep(2000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node cardTitleText = xmlScreenParser.findTextNode(m_account.lastNumbers);
Node cardHistory = xmlScreenParser.findTextNode("История платежей");
if (!cardTitleText.isEmpty() && !cardHistory.isEmpty()) {
QList<TransactionInfo> transactions = xmlScreenParser.parsePositiveTransactions();
QList<TransactionInfo> savedTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
for (TransactionInfo &transaction: transactions) {
bool isSaved = false;
for (TransactionInfo &savedTransaction: savedTransactions) {
if (savedTransaction.amount == transaction.amount
&& savedTransaction.bankTime == transaction.bankTime) {
isSaved = true;
break;
}
}
if (!isSaved) {
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
qDebug() << "--- saveAndPostNewTransactionData failed";
}
}
}
} else {
m_error = "Card page not found: " + m_account.deviceId + " " + m_account.lastNumbers;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Card not found: " + m_account.deviceId + " " + m_account.lastNumbers;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
}
AdbUtils::goBack(m_account.deviceId);
emit finishedWithResult(m_error);
}

View File

@ -1,35 +0,0 @@
#pragma once
#include "CommonBirbankScript.h"
class GetLastDaysHistoryBirbankScript final : public CommonBirbankScript {
Q_OBJECT
public:
~GetLastDaysHistoryBirbankScript() override;
explicit GetLastDaysHistoryBirbankScript(
AccountInfo account,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
QString m_error;
bool saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
);
bool updateAndPostTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
};

View File

@ -1,161 +0,0 @@
#include "LoginAndCheckAccountsBirbankScript.h"
#include <QThread>
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "time/DateUtils.h"
LoginAndCheckAccountsBirbankScript::LoginAndCheckAccountsBirbankScript(
QString deviceId,
QString appCode,
QObject *parent
) : CommonBirbankScript(parent),
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
}
LoginAndCheckAccountsBirbankScript::~LoginAndCheckAccountsBirbankScript() = default;
void LoginAndCheckAccountsBirbankScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
if (true) {
// xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
// if (!xmlScreenParser.isHomeScreen()) {
// if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
// m_error = "Не смогли дойти до домашней страницы";
// qCritical() << m_error;
// emit finishedWithResult(m_error);
// return;
// }
// }
//
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(m_deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
if (xmlScreenParser.isHomeScreen()) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node cardText = xmlScreenParser.findTextNode("2480");
if (!cardText.isEmpty()) {
AdbUtils::makeTap(m_deviceId, cardText.x(), cardText.y());
QThread::msleep(2000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node payBtn = xmlScreenParser.findTextNode("Перевести");
if (!payBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, payBtn.x(), payBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node payByCardBtn = xmlScreenParser.findTextNode("На карту любого банка");
if (!payByCardBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, payByCardBtn.x(), payByCardBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node cardEditText = xmlScreenParser.findEditText("Номер карты");
Node amountEditText = xmlScreenParser.findEditText("Сумма");
if (!cardEditText.isEmpty() && !amountEditText.isEmpty()) {
AdbUtils::makeTap(m_deviceId, cardEditText.x(), cardEditText.y());
QThread::msleep(200);
AdbUtils::inputText(m_deviceId, "1111222233334444");
AdbUtils::hideKeyboard(m_deviceId);
AdbUtils::makeTap(m_deviceId, amountEditText.x(), amountEditText.y());
QThread::msleep(200);
AdbUtils::inputText(m_deviceId, "10");
AdbUtils::hideKeyboard(m_deviceId);
// дальше оплата, но хз как
}
} else {
m_error = "Pay by card button not found: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Pay button not found: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
}
}
} else {
// "Maraqlı deyil" - не интересно
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
} else {
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
QThread::msleep(2000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
QMap<QString, AccountInfo> accountMap;
for (AccountInfo &oldAccount: oldAccounts) {
if (oldAccount.status == AccountStatus::Active) {
accountMap.insert(oldAccount.lastNumbers, oldAccount);
}
}
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
for (auto account: accounts) {
if (accountMap.contains(account.lastNumbers)) {
account.deviceId = m_deviceId;
account.appCode = m_appCode;
account.currency = accountMap[account.lastNumbers].currency;
account.description = accountMap[account.lastNumbers].description;
account.status = AccountStatus::Active;
if (!AccountDAO::upsertAccount(account)) {
m_error = "Not updated: " + account.lastNumbers;
qCritical() << m_error;
}
}
}
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
postAccountsData(savedAccounts);
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
}
emit finishedWithResult(m_error);
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "CommonBirbankScript.h"
class LoginAndCheckAccountsBirbankScript final : public CommonBirbankScript {
Q_OBJECT
public:
~LoginAndCheckAccountsBirbankScript() override;
explicit LoginAndCheckAccountsBirbankScript(
QString deviceId,
QString appCode,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const QString m_deviceId;
const QString m_appCode;
QString m_error;
};

View File

@ -1,128 +0,0 @@
#include "PayByCardBirbankScript.h"
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/ApplicationInfo.h"
#include "db/DeviceInfo.h"
#include "time/DateUtils.h"
PayByCardBirbankScript::PayByCardBirbankScript(
AccountInfo account,
QString card,
QString fullName,
const double amount,
QObject *parent
) : CommonBirbankScript(parent),
m_account(std::move(account)), m_card(std::move(card)),
m_fullName(std::move(fullName)), m_amount(amount) {
}
PayByCardBirbankScript::~PayByCardBirbankScript() = default;
void PayByCardBirbankScript::makePayment(const DeviceInfo &device) {
// Оплата со страницы карты
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node cardEditText = xmlScreenParser.findEditText("Номер карты");
Node amountEditText = xmlScreenParser.findEditText("Сумма");
if (!cardEditText.isEmpty() && !amountEditText.isEmpty()) {
AdbUtils::makeTap(device.id, cardEditText.x(), cardEditText.y());
QThread::msleep(200);
AdbUtils::inputText(device.id, m_card);
AdbUtils::hideKeyboard(device.id);
AdbUtils::makeTap(device.id, amountEditText.x(), amountEditText.y());
QThread::msleep(200);
AdbUtils::inputText(device.id, QString::number(m_amount));
AdbUtils::hideKeyboard(device.id);
// дальше оплата, но хз как
} else {
m_error = "Не нашли поля ввода 'Номер карты' или 'Сумма'";
qDebug() << m_error;
}
}
void PayByCardBirbankScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found.";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
}
if (xmlScreenParser.isHomeScreen()) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node cardText = xmlScreenParser.findTextNode("2480");
if (!cardText.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, cardText.x(), cardText.y());
QThread::msleep(2000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node payBtn = xmlScreenParser.findTextNode("Перевести");
if (!payBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, payBtn.x(), payBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node payByCardBtn = xmlScreenParser.findTextNode("На карту любого банка");
if (!payByCardBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, payByCardBtn.x(), payByCardBtn.y());
QThread::msleep(1000);
makePayment(device);
} else {
m_error = "Pay by card button not found: " + m_account.deviceId + " " + m_account.appCode;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Pay button not found: " + m_account.deviceId + " " + m_account.appCode;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
}
}
if (!m_error.isEmpty()) {
AdbUtils::takeXmlDump(device.id, "pay_by_Card_Birbank_fail_transactions_" + QString::number(m_account.id));
}
emit finishedWithResult(m_error);
}

View File

@ -1,30 +0,0 @@
#pragma once
#include "CommonBirbankScript.h"
#include "db/DeviceInfo.h"
class PayByCardBirbankScript final : public CommonBirbankScript {
Q_OBJECT
public:
~PayByCardBirbankScript() override;
PayByCardBirbankScript(
AccountInfo account,
QString card,
QString fullName,
double amount,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
const QString m_card;
const QString m_fullName;
const double m_amount;
QString m_error;
void makePayment(const DeviceInfo &device);
};

View File

@ -1,747 +0,0 @@
#include "ScreenXmlBirbankParser.h"
#include <QRegularExpression>
#include <QMap>
#include <QSet>
#include <QList>
#include <QXmlStreamReader>
#include <QDomDocument>
#include <QFile>
#include <QDateTime>
#include "adb/AdbUtils.h"
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
#include "time/DateUtils.h"
ScreenXmlBirbankParser::ScreenXmlBirbankParser(QObject *parent) : QObject(parent) {
}
ScreenXmlBirbankParser::~ScreenXmlBirbankParser() = default;
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
static const QRegularExpression onlyDigitsRegex(R"([^0-9])");
static const QRegularExpression onlyDigitsAndDotRegex(R"([^0-9.])");
static const QRegularExpression rePhone(R"raw((\+7\(?\d{3}\)?[- ]?\d{3}[- ]?\d{2}[- ]?\d{2}))raw");
static const QRegularExpression reFromBank(R"raw(из (.+?) на)raw");
static const QRegularExpression reToBank(R"raw(в (.+?) через)raw");
static const QRegularExpression reSbpId(R"(СБП(?: С2С)? ([A-Z0-9]{30,}))");
static const QRegularExpression reIdAlt(R"(ID перевода (\d+))");
static const QRegularExpression reDate(R"((?:Дата операции|дата) (\d{2}\.\d{2}\.\d{4}(?: \d{2}:\d{2}:\d{2})?))");
static const QRegularExpression reSender(R"(от ([^\(]+))");
static const QRegularExpression reNameAlt(R"(Перевод ([А-Яа-яЁё\s\*]+) в)");
static const QRegularExpression reCardData(R"(цифрами\s+(\d\s\d\s\d\s\d).*?Сумма:\s([\d\s]+)\sруб)");
Node ScreenXmlBirbankParser::tryToFindBannerOrDialog(const int width, const int height) {
// 1. Ищем push banner - он перекрывает весь экран
Node first = m_nodes[0];
for (const Node &node: m_nodes) {
// Если это однозначно, что пуш-баннер
if (node.resourceId == "aft-popup-pushNotification-iconClose" && node.className == "android.widget.Button") {
return node;
}
// Если есть кнопка "Позже"
if (node.text.trimmed() == "Позже" && node.className == "android.widget.Button") {
return node;
}
// Если нашли пустую кнпоку
if (node.className == "android.widget.Button" && node.clickable
&& node.text.isEmpty() && node.contentDesc.isEmpty()) {
// <node class="android.widget.Button" package="ru.rshb.dbo" clickable="true" bounds="[630,142][691,205]"/>
if (node.x() > width / 2 && node.y() < width / 2) {
return node;
}
}
}
return {};
}
Node ScreenXmlBirbankParser::findAccountButton(const QString &numbers) {
// TODO возможно это не так, надо уточнять
return findTextNode(QString("LEVENT - %1").arg(numbers));
}
/**
* Смотрим что есть текс "Мы заботимся о вашей безопасности" и
* кнопка "Отложить"
* @return координаты кнопки для закрытия
*/
Node ScreenXmlBirbankParser::tryToFindSecurityBanner() {
Node text;
Node closeBtn;
for (const Node &node: m_nodes) {
if (node.text.trimmed() == "Мы заботимся о вашей безопасности" && node.className == "android.app.Dialog") {
text = node;
}
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
closeBtn = node;
}
}
// Не нужно проверять все, если хотя бы одна координата есть
if (!text.isEmpty() && !closeBtn.isEmpty()) {
return closeBtn;
}
return {};
}
Node ScreenXmlBirbankParser::tryToFindSelectBottomSheet() {
Node closeBtn;
for (const Node &node: m_nodes) {
if ((node.text.trimmed() == "Отмена" || node.text.trimmed() == "Отложить") && node.className ==
"android.widget.Button") {
closeBtn = node;
}
}
// Не нужно проверять все, если хотя бы одна координата есть
if (!closeBtn.isEmpty()) {
return closeBtn;
}
return {};
}
Node ScreenXmlBirbankParser::findTextNode(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
return node;
}
}
return {};
}
Node ScreenXmlBirbankParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
return node;
}
}
return {};
}
Node ScreenXmlBirbankParser::findEditText(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.text == text) {
return node;
}
}
return {};
}
Node ScreenXmlBirbankParser::findEditTextByResourceId(const QString &resourceId) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.resourceId == resourceId) {
return node;
}
}
return {};
}
Node ScreenXmlBirbankParser::findButtonNode(const QString &text, const bool contains) {
for (const Node &node: m_nodes) {
if (contains) {
if (node.className == "android.widget.Button" && node.text.contains(text)) {
return node;
}
} else {
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
return node;
}
}
}
return {};
}
bool ScreenXmlBirbankParser::isHomeScreen() {
Node activitiesBtn;
for (const Node &node: m_nodes) {
if (node.text.trimmed() == "Карты и счета") {
activitiesBtn = node;
}
}
return !activitiesBtn.isEmpty();
}
QList<Node> ScreenXmlBirbankParser::findPinCodeNodes(const QString &pinCode) {
QMap<QString, Node> buttons;
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
for (const Node &node: m_nodes) {
const QString &text = node.text.trimmed();
if (node.className == "android.widget.TextView" && numberSet.contains(text)) {
buttons[text] = node;
}
}
QList<Node> nodes;
for (int i = 0; i < pinCode.length(); ++i) {
nodes.append(buttons[QString(pinCode.at(i))]);
}
return nodes;
}
QList<Node> ScreenXmlBirbankParser::getLast2DaysTransactions() {
QList<Node> nodes;
for (const Node &node: m_nodes) {
if (node.className == "android.widget.Button" && node.text.contains("рубл")
&& (node.text.contains("Минус") || node.text.contains("Плюс"))) {
nodes.append(node);
}
}
return nodes;
}
/**
* <node NAF="true" index="1" text="" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[952,159][1039,248]"/>
*/
void ScreenXmlBirbankParser::parseAndSaveXml(const QString &xml) {
QDomDocument doc;
doc.setContent(xml);
m_xml = doc.documentElement();
m_nodes.clear();
QXmlStreamReader reader(xml);
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement() && reader.name() == "node") {
Node node = Node();
if (reader.attributes().hasAttribute("bounds")) {
QString bounds = reader.attributes().value("bounds").toString();
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
node.setBounds(
match.captured(1).toInt(),
match.captured(2).toInt(),
match.captured(3).toInt(),
match.captured(4).toInt()
);
}
}
if (reader.attributes().hasAttribute("text")) {
node.text = reader.attributes().value("text").toString();
}
if (reader.attributes().hasAttribute("content-desc")) {
node.contentDesc = reader.attributes().value("content-desc").toString();
}
if (reader.attributes().hasAttribute("class")) {
node.className = reader.attributes().value("class").toString();
}
if (reader.attributes().hasAttribute("clickable")) {
node.clickable = reader.attributes().value("clickable").toString() == "true";
}
if (reader.attributes().hasAttribute("focusable")) {
node.focusable = reader.attributes().value("focusable").toString() == "true";
}
if (reader.attributes().hasAttribute("resource-id")) {
node.resourceId = reader.attributes().value("resource-id").toString();
}
m_nodes.append(node);
}
}
}
QDomElement findSubElementBirbank(const QDomElement &elem, const QString &index) {
if (elem.hasChildNodes()) {
QDomNodeList subInfoList = elem.childNodes();
for (QDomNode subInfoNode: subInfoList) {
if (!subInfoNode.isElement()) continue;
QDomElement subInfo = subInfoNode.toElement();
if (subInfo.attribute("index") == index) {
return subInfo;
}
}
}
return {};
}
QString findSubInfoBirbank(const QDomElement &elem, const QString &index) {
QDomElement subInfo = findSubElementBirbank(elem, index);
if (!subInfo.isNull()) {
return subInfo.attribute("text");
}
return "";
}
bool hasTimeComponentBirbank(const QString &datetimeStr) {
QDateTime dt = QDateTime::fromString(datetimeStr, "dd.MM.yyyy HH:mm:ss");
if (!dt.isValid()) {
return false; // Строка не соответствует формату даты и времени
}
return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00
}
QString transformBankDateTimeBirbank(const QString &date) {
QDateTime dt;
if (date.contains(",")) {
// 10.05.2025, 15:03
dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm");
} else {
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss");
}
if (!dt.isValid()) {
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm");
}
if (!dt.isValid()) {
return date; // не распарсили
}
return dt.toString("dd.MM.yyyy HH:mm:ss");
}
void parseTransferInfoBirbank(const QString &text, TransactionInfo &info) {
if (const auto m = reSender.match(text); m.hasMatch()) {
info.name = m.captured(1).trimmed();
} else if (const auto m1 = reNameAlt.match(text); m1.hasMatch()) {
info.name = m1.captured(1).trimmed();
}
if (const auto m = rePhone.match(text); m.hasMatch()) {
info.phone = m.captured(1).trimmed().remove(onlyDigitsRegex);
}
if (const auto m = reFromBank.match(text); m.hasMatch()) {
if (const QString bank = m.captured(1).trimmed(); !bank.isEmpty()) {
info.bankName = bank;
}
} else if (const auto m1 = reToBank.match(text); m1.hasMatch()) {
if (const QString bank = m1.captured(1).trimmed(); !bank.isEmpty()) {
info.bankName = bank;
}
}
if (const auto m = reSbpId.match(text); m.hasMatch()) {
info.bankTrExternalId = m.captured(1);
} else if (const auto m1 = reIdAlt.match(text); m1.hasMatch()) {
info.bankTrExternalId = m1.captured(1);
}
if (const auto m = reDate.match(text); m.hasMatch()) {
const QString date = m.captured(1);
// если не пустая и дата у нас с 00:00
// if (hasTimeComponent2(date)) {
info.bankTime = transformBankDateTimeBirbank(date);
// }
}
}
void traverseNodesBirbank(const QDomNode &node) {
if (node.isElement()) {
QDomElement elem = node.toElement();
if (node.isElement()) {
QDomElement elem = node.toElement();
if (elem.tagName() == "node" &&
elem.attribute("class") == "android.widget.Button" &&
elem.attribute("text") == "Детали операции") {
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int j = 0; j < detailInfo.count(); ++j) {
QDomNode info = detailInfo.at(j);
if (!info.isElement()) continue;
QDomElement infoElement = info.toElement();
QString index = infoElement.attribute("index");
switch (index.toInt()) {
case 2:
qDebug() << "Дата операции:" << findSubInfoBirbank(infoElement, "1");
break;
case 5:
qDebug() << "Название:" << findSubInfoBirbank(infoElement, "1");
qDebug() << "-------------------------------------";
// parseTransfer(findSubInfo2(infoElement));
break;
case 7:
qDebug() << "Комиссия:" << findSubInfoBirbank(infoElement, "1");
break;
default:
qDebug() << "Прочее:" << findSubInfoBirbank(infoElement, "1");
break;
}
}
}
}
}
// Рекурсивно обходим всех детей
QDomNode child = node.firstChild();
while (!child.isNull()) {
traverseNodesBirbank(child);
child = child.nextSibling();
}
}
QDomNode findNodeBirbank(const QDomNode &node, const QString &text) {
if (node.isElement()) {
QString nodeText = node.toElement().attribute("text");
if (nodeText.toLower().startsWith(text)) {
return node;
}
}
QDomNode child = node.firstChild();
while (!child.isNull()) {
QDomNode result = findNodeBirbank(child, text);
if (!result.isNull()) {
return result;
}
child = child.nextSibling();
}
return {};
}
float extractAmountsBirbank(const QString &text) {
// Разрешаем пробелы внутри чисел, захватываем "рубль", "рубля", "рублей" и т.д.
// QRegularExpression re(R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)");
QRegularExpression re(
R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)",
QRegularExpression::UseUnicodePropertiesOption
);
QRegularExpressionMatch match = re.match(text);
if (match.hasMatch()) {
QString signStr = match.captured(1); // "Плюс" или "Минус"
QString rublesStr = match.captured(2).remove(' '); // "1 000" → "1000"
int rubles = rublesStr.toInt();
int kopecks = match.captured(3).toInt();
int totalKopecks = rubles * 100 + kopecks;
if (signStr == "Минус") {
totalKopecks *= -1;
}
return totalKopecks / 100.0f;
}
return 0;
}
QString beforeAmountBirbank(const QString &text) {
int index = text.indexOf(QRegularExpression("Плюс|Минус"));
if (index != -1) {
return text.left(index).trimmed();
}
return text; // если не найдено — вернуть всю строку
}
double parseAmountBirbank(const QString &amountAsString) {
QString numberString = amountAsString;
numberString.remove(QRegularExpression(R"([^\очка])"));
numberString.replace("точка", ".");
double amount = numberString.toDouble();
if (amountAsString.startsWith("-")) {
amount *= -1;
}
return amount;
}
QDomElement findElementWithPaymentsBirbank(const QDomElement &parent, const QString &resourceId) {
QDomElement element = parent.firstChildElement();
while (!element.isNull()) {
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
if (child.hasAttribute("resource-id") && child.attribute("resource-id") == resourceId) {
return child;
}
child = child.nextSiblingElement();
}
QDomElement found = findElementWithPaymentsBirbank(element, resourceId);
if (!found.isNull()) {
return found;
}
element = element.nextSiblingElement();
}
return {};
}
QDateTime getUtcFromBakuDate(const QString &date, const QString &time) {
QDate baseDate;
QTime parsedTime = QTime::fromString(time, "H:mm");
if (!parsedTime.isValid()) {
qWarning() << "Невалидное время:" << time;
return {};
}
QString dateLower = date.trimmed().toLower();
if (dateLower == "сегодня") {
baseDate = QDate::currentDate();
} else if (dateLower == "вчера") {
baseDate = QDate::currentDate().addDays(-1);
} else if (dateLower == "позавчера") {
baseDate = QDate::currentDate().addDays(-2);
} else {
// Пробуем разобрать обычную дату, например "24 июля"
QLocale ruLocale(QLocale::Russian, QLocale::Russia);
int year = QDate::currentDate().year();
QString combined = QString("%1 %2 %3").arg(date).arg(year).arg(time); // "24 июля 2025 0:31"
QDateTime dt = ruLocale.toDateTime(combined, "d MMMM yyyy H:mm");
if (!dt.isValid()) {
qWarning() << "Ошибка разбора даты:" << combined;
return {};
}
dt.setTimeZone(QTimeZone("Asia/Baku"));
return dt.toTimeZone(QTimeZone::utc());
}
// Собираем и переводим в UTC, если дата относительная
QDateTime bakuDateTime(baseDate, parsedTime, QTimeZone("Asia/Baku"));
return bakuDateTime.toTimeZone(QTimeZone::utc());
}
QList<TransactionInfo> ScreenXmlBirbankParser::parsePositiveTransactions() {
QList<TransactionInfo> transactions;
QDomElement child = findElementWithPaymentsBirbank(m_xml, "az.kapitalbank.mbanking:id/rv_pfm_operations");
// QDomElement child = findElementWithPaymentsBirbank(m_xml, "az.kapitalbank.mbanking:id/rv_operations");
QDomNodeList listView = child.childNodes();
qDebug() << listView.count();
if (!listView.isEmpty()) {
QString date = "";
for (QDomNode node: listView) {
const QDomNodeList trBoxGroup = node.childNodes();
if (trBoxGroup.count() > 0) {
TransactionInfo transaction;
for (QDomNode item: trBoxGroup) {
QDomElement groupItem = item.toElement();
if ("az.kapitalbank.mbanking:id/tv_date" == groupItem.attribute("resource-id")) {
date = groupItem.attribute("text");
} else if ("az.kapitalbank.mbanking:id/transaction_title" == groupItem.attribute("resource-id")) {
transaction.description = groupItem.attribute("text");
} else if ("az.kapitalbank.mbanking:id/transaction_time" == groupItem.attribute("resource-id")) {
transaction.bankTime = date + " " + groupItem.attribute("text");
transaction.completeTime = getUtcFromBakuDate(date, groupItem.attribute("text"));
} else if ("az.kapitalbank.mbanking:id/transaction_amount" == groupItem.attribute("resource-id")) {
auto amount = groupItem.attribute("text");
if (amount.startsWith("+")) {
transaction.amount = amount.remove("+").remove("").replace(",", ".").trimmed().toFloat();
}
}
}
if (transaction.amount > 0) {
transactions.append(transaction);
qDebug().noquote().nospace() << convertTransactionToString(transaction);
}
}
}
} else {
qDebug() << "ListView is empty";
}
return transactions;
}
TransactionInfo parseExpandedInfoHistoryBirbank(const QDomElement &root) {
if (root.isElement()) {
QDomElement elem = root.toElement();
if (elem.tagName() == "node"
&& elem.attribute("class") == "android.widget.Button"
&& elem.attribute("text") == "Детали операции"
) {
TransactionInfo transaction;
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int i = 0; i < detailInfo.count(); ++i) {
QDomNode info = detailInfo.at(i);
if (!info.isElement()) continue;
switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) {
case 2:
// Дата операции
transaction.bankTime = transformBankDateTimeBirbank(findSubInfoBirbank(e, "1"));
break;
case 5:
transaction.description = findSubInfoBirbank(e, "1");
parseTransferInfoBirbank(transaction.description, transaction);
break;
case 7:
// Комиссия
transaction.fee = findSubInfoBirbank(e, "1").remove(onlyDigitsRegex).toFloat();
break;
default:
// qDebug() << "Прочее:" << findSubInfo2(e);
break;
}
}
return transaction;
}
}
// Рекурсивно обходим всех детей
QDomNode child = root.firstChild();
while (!child.isNull()) {
if (TransactionInfo info = parseExpandedInfoHistoryBirbank(child.toElement()); !info.bankTime.isEmpty()) {
return info;
}
child = child.nextSibling();
}
return {};
}
TransactionInfo ScreenXmlBirbankParser::parseTransactionInfoHistory(int screenWidth, int screenHeight) {
// 1. Распарсить описание транзакции
TransactionInfo transaction = parseExpandedInfoHistoryBirbank(m_xml);
// 1. Найти статус: Исполнен | Операция исполнена
transaction.status = TransactionStatus::Wait;
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
if (!status1.isEmpty() || !status2.isEmpty()) {
transaction.status = TransactionStatus::Complete;
}
return transaction;
}
TransactionInfo parseExpandedInfoBirbank(const QDomElement &root) {
if (root.isElement()) {
QDomElement elem = root.toElement();
if (elem.tagName() == "node"
&& elem.attribute("class") == "android.widget.Button"
&& elem.attribute("text") == "Детали операции"
) {
TransactionInfo transaction;
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int i = 0; i < detailInfo.count(); ++i) {
QDomNode info = detailInfo.at(i);
if (!info.isElement()) continue;
QDomElement infoElement = info.toElement();
QString index = infoElement.attribute("index");
QDomElement ee;
switch (index.toInt()) {
case 3:
transaction.bankTime = transformBankDateTimeBirbank(findSubInfoBirbank(infoElement, "1"));
break;
case 4:
ee = findSubElementBirbank(infoElement, "0");
ee = findSubElementBirbank(ee, "1");
transaction.phone = findSubInfoBirbank(ee, "0").remove(onlyDigitsRegex);
break;
case 5:
transaction.name = findSubInfoBirbank(infoElement, "1");
break;
case 6:
transaction.bankName = findSubInfoBirbank(infoElement, "1");
break;
case 9:
transaction.fee = findSubInfoBirbank(infoElement, "1").remove(onlyDigitsAndDotRegex).toFloat();
break;
case 10:
ee = findSubElementBirbank(infoElement, "1");
transaction.bankTrExternalId = findSubInfoBirbank(ee, "1");
break;
default:
break;
}
}
return transaction;
}
}
// Рекурсивно обходим всех детей
QDomNode child = root.firstChild();
while (!child.isNull()) {
if (TransactionInfo info = parseExpandedInfoBirbank(child.toElement()); !info.bankTime.isEmpty()) {
return info;
}
child = child.nextSibling();
}
return {};
}
TransactionInfo ScreenXmlBirbankParser::parseTransactionInfo(int screenWidth, int screenHeight) {
// 1. Распарсить описание транзакции
TransactionInfo transaction = parseExpandedInfoBirbank(m_xml);
// 1. Найти статус: Исполнен | Операция исполнена
transaction.status = TransactionStatus::Wait;
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
if (!status1.isEmpty() || !status2.isEmpty()) {
transaction.status = TransactionStatus::Complete;
}
return transaction;
}
QList<AccountInfo> ScreenXmlBirbankParser::parseAccountsInfo() {
const QDomNodeList nodes = m_xml.elementsByTagName("node");
QList<AccountInfo> accounts;
for (int i = 0; i < nodes.count(); ++i) {
const QDomElement el = nodes.at(i).toElement();
if (el.attribute("text").contains("")) {
// Нашли сумму
// el.attribute("text") - ₼ и трим
auto amount = el.attribute("text").replace("", "").trimmed();
const QDomElement parent = el.parentNode().parentNode().toElement();
// Перебираем потомков
QDomNode n = parent.firstChild().firstChild().firstChild().firstChild();
while (!n.isNull()) {
const QDomElement e = n.toElement();
if (e.attribute("resource-id") == "az.kapitalbank.mbanking:id/tvNumber") {
const QString account = e.attribute("text");
AccountInfo info;
info.lastNumbers = account;
info.amount = amount.toFloat();
info.description = account;
info.updateTime = DateUtils::getUtcNow();
accounts.append(info);
break;
}
n = n.nextSibling();
}
}
}
return accounts;
}
void ScreenXmlBirbankParser::test() {
// TransactionInfo info2 = parseExpandedInfo(m_xml);
// qDebug().noquote().nospace() << convertTransactionToString(info2);
// return;
QFile file("assets/rshb/all_products.xml");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Cannot open file";
}
QDomDocument doc;
if (!doc.setContent(&file)) {
qDebug() << "Failed to parse XML";
}
file.close();
qDebug() << "Start parsing XML:";
// Номер карты с последними цифрами
QDomElement root = doc.documentElement();
parseAndSaveXml(doc.toString());
// for (const AccountInfo &info: parseAccountsInfo()) {
// qDebug().noquote().nospace() << convertAccountToString(info);
// }
// TransactionInfo info = parseExpandedInfo(root);
// qDebug().noquote().nospace() << convertTransactionToString(info);
// ЕСПП
}

View File

@ -1,57 +0,0 @@
#pragma once
#include <QObject>
#include <QDomElement>
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
class ScreenXmlBirbankParser final : public QObject {
Q_OBJECT
public:
explicit ScreenXmlBirbankParser(QObject *parent = nullptr);
~ScreenXmlBirbankParser() override;
Node tryToFindBannerOrDialog(int width, int height);
Node tryToFindSecurityBanner();
Node tryToFindSelectBottomSheet();
Node findAccountButton(const QString &numbers);
Node findTextNode(const QString &text);
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
Node findEditText(const QString &text);
Node findEditTextByResourceId(const QString &resourceId);
Node findButtonNode(const QString &text, bool contains);
bool isHomeScreen();
QList<Node> getLast2DaysTransactions();
void parseAndSaveXml(const QString &xml);
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
QList<TransactionInfo> parsePositiveTransactions();
QList<AccountInfo> parseAccountsInfo();
QList<Node> findPinCodeNodes(const QString &pinCode);
void test();
private:
QList<Node> m_nodes;
QDomElement m_xml;
};

View File

@ -3,6 +3,8 @@
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QRegularExpression>
#include <QSettings>
#include <QThread>
#include "adb/AdbUtils.h"
@ -197,18 +199,37 @@ void CommonScript::updateTransactionData(
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
if (app.fullName.trimmed().isEmpty() || app.phone.trimmed().isEmpty()) {
qWarning() << "[Black] createBankProfileIfNeeded: skipping — fullName or phone is empty";
return;
}
const QMap<QString, int> currencyCodes = {
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
};
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 840);
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
// Нормализуем телефон: оставляем только цифры, добавляем код страны и "+"
const QSettings settings("config.ini", QSettings::IniFormat);
const QString phoneCode = settings.value(appCode + "/phone_code").toString();
QString phone = app.phone;
phone.remove(QRegularExpression("[^0-9]"));
if (!phoneCode.isEmpty() && !phone.startsWith(phoneCode)) {
if (phone.startsWith('8') && phoneCode != "8") {
phone.replace(0, 1, phoneCode);
} else {
phone.prepend(phoneCode);
}
}
phone.prepend('+');
QJsonObject profileBody;
profileBody["first_name"] = parts.value(0);
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
profileBody["bank_name"] = appCode;
profileBody["phone_number"] = app.phone.simplified().remove(' ');
profileBody["phone_number"] = phone;
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
profileBody["currency"] = currencyCode;

View File

@ -3,6 +3,8 @@
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QRegularExpression>
#include <QSettings>
#include <QThread>
#include "adb/AdbUtils.h"
@ -293,18 +295,37 @@ void CommonScript::updateTransactionData(
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
if (app.fullName.trimmed().isEmpty() || app.phone.trimmed().isEmpty()) {
qWarning() << "[Ozon] createBankProfileIfNeeded: skipping — fullName or phone is empty";
return;
}
const QMap<QString, int> currencyCodes = {
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
};
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 643);
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
// Нормализуем телефон: оставляем только цифры, добавляем код страны и "+"
const QSettings settings("config.ini", QSettings::IniFormat);
const QString phoneCode = settings.value(appCode + "/phone_code").toString();
QString phone = app.phone;
phone.remove(QRegularExpression("[^0-9]"));
if (!phoneCode.isEmpty() && !phone.startsWith(phoneCode)) {
if (phone.startsWith('8') && phoneCode != "8") {
phone.replace(0, 1, phoneCode);
} else {
phone.prepend(phoneCode);
}
}
phone.prepend('+');
QJsonObject profileBody;
profileBody["first_name"] = parts.value(0);
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : QString("");
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
profileBody["bank_name"] = appCode;
profileBody["phone_number"] = app.phone.simplified().remove(' ');
profileBody["phone_number"] = phone;
profileBody["balance"] = QString::number(qRound64(app.amount * 100));
profileBody["state"] = (app.status == "active") ? "enabled" : "disabled";
profileBody["currency"] = currencyCode;

View File

@ -1,297 +0,0 @@
#include "CommonScript.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include "adb/AdbUtils.h"
#include "net/NetworkService.h"
namespace Rshb {
CommonScript::CommonScript(QObject *parent)
: QObject(parent) {
}
CommonScript::~CommonScript() = default;
void CommonScript::start() {
doStart();
emit finished();
}
Node CommonScript::swipeToButton(
const QString &deviceId,
const QString &text, int &counter, const int width, const int height
) {
for (int i = 0; i < 10; ++i) {
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
return button;
}
const int x = width / 2;
const int offset = height / 4;
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
return {};
}
bool CommonScript::inputPinCode(const QString &deviceId, const QList<Node> &pincode) {
for (const Node &node: pincode) {
const bool completePincode = AdbUtils::makeTap(deviceId, node.x(), node.y());
if (!completePincode) {
AdbUtils::makeTap(deviceId, node.x(), node.y());
}
QThread::msleep(QRandomGenerator::global()->bounded(100, 901));
}
return true;
}
bool CommonScript::runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
const int width,
const int height
) {
// Запустить устройство
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
qDebug() << "Process already running, pid: " << pid;
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
AdbUtils::tryToKillApplication(deviceId, packageName);
}
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
AdbUtils::takeScreenshot(deviceId, "run_app_error");
qWarning() << "Process has not started";
return false;
}
// Даем минимальное время на запуск
QThread::msleep(4500);
int counter = 0;
bool findAndInputPincode = false;
while (true) {
counter++;
// Если более 10 раз мы пытаемся перейти на домашнюю
if (counter > 10) {
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
return false;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
if (xmlScreenParser.isHomeScreen()) {
return true;
}
// Проверяем на банеры после пин-кодом
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
QThread::msleep(1000);
continue;
}
// Проверяем на банеры перед пин-кодом
Node closeBannerNode = xmlScreenParser.tryToFindSecurityBanner();
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
continue;
}
// Проверяем, что это экран ввода пин-кода
if (!findAndInputPincode) {
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите ПИН");
pincode.size() == 4) {
// чтобы пробудить экран
if (Node textPinCodeNode = xmlScreenParser.findTextNode("Введите ПИН"); !textPinCodeNode.isEmpty()) {
AdbUtils::makeTap(deviceId, textPinCodeNode.x(), textPinCodeNode.y());
}
inputPinCode(deviceId, pincode);
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
findAndInputPincode = true;
QThread::msleep(3000);
continue;
}
}
QThread::msleep(1000);
}
}
bool CommonScript::tryToCloseAllBannersOnHomePage(const QString &deviceId, const int width, const int height) {
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
return true;
}
// TODO тут все другие банеры попробовать закрыть
return false;
}
bool CommonScript::goToAllProducts(
const QString &deviceId,
const int width,
const int height
) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
if (tryToCloseAllBannersOnHomePage(deviceId, width, height)) {
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
if (xmlScreenParser.isHomeScreen()) {
// идем на экран "Все продукты"
if (Node allCardTitle = xmlScreenParser.findTextNode("Счета и карты"); !allCardTitle.isEmpty()) {
// 1. Если нет кнопки видимой, свайпаем. Кликаем на "Все продукты"
for (int i = 0; i < 5; ++i) {
Node allProductsBtn = xmlScreenParser.findButtonNode("Все продукты", false);
if (allProductsBtn.x() > 0 && allProductsBtn.y() > 0 && allProductsBtn.y() < height - 200) {
AdbUtils::makeTap(deviceId, allProductsBtn.x(), allProductsBtn.y());
QThread::msleep(1000);
break;
}
AdbUtils::makeSwipe(deviceId,
allCardTitle.x(), allCardTitle.y(),
allCardTitle.x(), allCardTitle.y() - 200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
for (int i = 0; i < 5; ++i) {
Node allProductsTitle = xmlScreenParser.findTextNode("Все продукты");
// Проверяем что вверху заголовок
if (!allProductsTitle.isEmpty() && allProductsTitle.y() < 300) {
return true;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
} else {
// FIXME пишем в БД, что не дошли до домашней страницы, и завершаемся
// сохраняем скрин приложения
// дделаем алерт
}
} else {
// FIXME
qDebug() << "Not home screen...";
}
return false;
}
bool CommonScript::findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers) {
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
for (auto &[account, node]: accounts) {
// FIXME будем считать что числа последние везде уникальные
if (accountNumbers == account.lastNumbers) {
qDebug() << "findAndTapOnAccount: " << accountNumbers;
AdbUtils::makeTap(deviceId, node.x(), node.y());
QThread::msleep(1000);
return true;
}
}
return false;
}
void CommonScript::postAccountsData(const QList<QPair<AccountInfo, Node> > &accounts) {
if (accounts.isEmpty()) {
return;
}
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonArray list;
for (const QPair<AccountInfo, Node> &pair: accounts) {
QJsonObject obj;
AccountInfo account = pair.first;
obj["appName"] = account.appCode;
obj["lastNumbers"] = account.lastNumbers;
obj["amount"] = account.amount;
obj["description"] = account.description;
obj["currency"] = account.currency;
obj["status"] = accountStatusToString(account.status);
list.append(obj);
}
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(accounts.first().first.deviceId);
worker->setPayload(QJsonDocument(list).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transaction.id;
obj["amount"] = transaction.amount;
obj["name"] = transaction.name;
obj["fee"] = transaction.fee;
obj["status"] = transactionStatusToString(transaction.status);
obj["type"] = transactionTypeToString(transaction.type);
obj["phone"] = transaction.phone;
obj["description"] = transaction.description;
obj["updatedDescription"] = transaction.updatedDescription;
obj["bankName"] = transaction.bankName;
obj["bankTime"] = transaction.bankTime;
obj["bankTransactionId"] = transaction.bankTrExternalId;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->addExtra("transactionId", transaction.id);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonScript::updateTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transactionId;
obj["status"] = transactionStatusToString(status);
obj["description"] = newDesc;
obj["updatedDescription"] = oldDesc;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonScript::stop() {
m_running = false;
}
} // namespace Rshb

View File

@ -1,78 +0,0 @@
#pragma once
#include <QObject>
#include "ScreenXmlParser.h"
namespace Rshb {
class CommonScript : public QObject {
Q_OBJECT
public:
explicit CommonScript(QObject *parent = nullptr);
~CommonScript() override;
protected:
virtual void doStart() = 0;
// static method
static bool inputPinCode(const QString &deviceId, const QList<Node> &pincode);
bool goToAllProducts(
const QString &deviceId,
int width,
int height
);
bool findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers);
void postAccountsData(const QList<QPair<AccountInfo, Node> > &accounts);
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
void updateTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
Node swipeToButton(
const QString &deviceId,
const QString &text,
int &counter, int width, int height
);
bool runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
int width,
int height
);
bool tryToCloseAllBannersOnHomePage(
const QString &deviceId, int width, int height
);
bool m_running = true;
ScreenXmlParser xmlScreenParser;
int m_counter = 0;
signals:
void finished();
void finishedWithResult(const QString &result);
public slots:
virtual void start() final;
virtual void stop() final;
private:
Q_DISABLE_COPY(CommonScript);
};
} // namespace Rshb

View File

@ -1,399 +0,0 @@
#include "GetLastDaysHistoryScript.h"
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/DeviceInfo.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
namespace Rshb {
GetLastDaysHistoryScript::GetLastDaysHistoryScript(
AccountInfo account,
QObject *parent
) : CommonScript(parent),
m_account(std::move(account)) {
}
GetLastDaysHistoryScript::~GetLastDaysHistoryScript() = default;
QList<TransactionInfo> findSavedTransaction(
const QList<TransactionInfo> &transactions,
const TransactionInfo &parsed
) {
QList<TransactionInfo> txs;
const QDateTime dateTime = QDateTime::fromString(parsed.bankTime, "dd.MM.yyyy"); // Московское время
for (const TransactionInfo &info: transactions) {
QDateTime timestamp = info.timestamp;
QString description = parsed.description;
// если тот же день
if (dateTime.date() == timestamp.date() && parsed.amount == info.amount) {
// Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815...
if (description.contains("Перевод")) {
if (description.contains(info.name)) {
txs.append(info);
}
} else {
// Перевод по карте
if (description == info.description) {
txs.append(info);
}
}
}
}
return txs;
}
int countSimilar(const TransactionInfo &transaction, const QList<TransactionInfo> &transactions) {
int count = 0;
for (const TransactionInfo &info: transactions) {
if (info.amount == transaction.amount
&& info.description == transaction.description
&& info.bankTime == transaction.bankTime) {
++count;
}
}
return count;
}
QString formatPrice(const double value) {
QString sign = value < 0 ? "Минус" : "Плюс";
const auto intValue = static_cast<qint64>(std::abs(value)); // округление до целого
QString number = QString::number(intValue);
QString formatted;
int count = 0;
for (int i = number.length() - 1; i >= 0; --i) {
formatted.prepend(number[i]);
++count;
if (count % 3 == 0 && i != 0) {
formatted.prepend(' ');
}
}
return QString("%1 %2").arg(sign, formatted);
}
bool GetLastDaysHistoryScript::saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
) {
TransactionInfo tr;
tr.accountId = account.id;
tr.description = transaction.description;
tr.bankTime = transaction.bankTime;
tr.bankName = transaction.bankName;
tr.amount = transaction.amount;
tr.phone = transaction.phone;
tr.updateTime = DateUtils::getUtcNow();
tr.fee = transaction.fee;
tr.name = transaction.name;
tr.bankTrExternalId = transaction.bankTrExternalId;
tr.status = status;
tr.type = transaction.description.startsWith("Перевод") ? TransactionType::Phone : TransactionType::Card;
tr.completeTime = DateUtils::getUtcNow();
tr.id = TransactionDAO::insertTransaction(tr);
if (tr.id == -1) {
return false;
}
postNewTransactionData(account, tr);
return true;
}
bool GetLastDaysHistoryScript::updateAndPostTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
return true;
}
return false;
}
void GetLastDaysHistoryScript::doStart() {
// берем все транзакции из БД
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(device.screenWidth, device.screenHeight);
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
AdbUtils::makeTap(device.id, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
QThread::msleep(500);
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (xmlScreenParser.isHomeScreen()) {
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
for (auto &[account, node]: accounts) {
account.deviceId = m_account.deviceId;
account.appCode = m_account.appCode;
if (!AccountDAO::upsertAccount(account)) {
qDebug() << "Not updated: " << account.lastNumbers;
}
}
postAccountsData(accounts);
findAndTapOnAccount(device.id, m_account.lastNumbers);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node actionBtn = xmlScreenParser.findButtonNode("Действия", false);
if (!actionBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, actionBtn.x(), actionBtn.y());
QThread::msleep(200);
} else {
m_error = "All action btn not found";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
Node reportButton = swipeToButton(
m_account.deviceId,
"Выписка",
m_counter, device.screenWidth,
device.screenHeight
);
if (!reportButton.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, reportButton.x(), reportButton.y());
QThread::msleep(1000);
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node reportTitle = xmlScreenParser.findTextNode("Выписка");
if (!reportTitle.isEmpty() && reportTitle.y() < 300) {
QDate beforeYesterday = DateUtils::getMoscowNow().date().addDays(-2);
QString beforeYesterdayTitle = beforeYesterday.toString("dd.MM.yyyy");
for (int i = 0; i < 5; ++i) {
Node byDayTitle = xmlScreenParser.findTextNode(beforeYesterdayTitle);
if (!byDayTitle.isEmpty()) {
qWarning() << "--- beforeYesterdayTitle found!";
break;
}
AdbUtils::makeSwipe(
m_account.deviceId,
device.screenWidth / 2, device.screenHeight / 4 * 3,
device.screenWidth / 2, device.screenHeight / 4
);
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
}
} else {
m_error = "All action - report title not found";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
// все поддвержденные
QList<TransactionInfo> parsedTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
QSet<int> parsedTransactionIds;
for (const TransactionInfo &transaction: parsedTransactions) {
bool updated = false;
for (const TransactionInfo &saved: localTransactions) {
if (parsedTransactionIds.contains(saved.id)) {
continue;
}
QDate sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy HH:mm:ss").date();
if (!sDate.isValid()) {
sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy").date();
}
QDate pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy HH:mm:ss").date();
if (!pDate.isValid()) {
pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy").date();
}
// Если сумма и дата совпадают
if (saved.amount == transaction.amount && sDate == pDate) {
if (transaction.description.startsWith("Перевод")) {
// Перевод по номеру
if (saved.bankName == transaction.bankName && saved.phone == transaction.phone) {
parsedTransactionIds.insert(saved.id);
updated = true;
if (saved.status != TransactionStatus::Complete || saved.description.isEmpty()) {
if (!TransactionDAO::updateTransaction(
saved.id,
TransactionStatus::Complete,
saved.description,
transaction.description
)) {
qDebug().noquote().nospace() << "--- updated+phone failed" <<
convertTransactionToString(transaction);;
}
}
break;
}
} else {
// перевод по карте
// перезаписать saved.description -> updatedDescription если не равны
if (!saved.description.isEmpty()) {
if (saved.description == transaction.description) {
// описания совпадают
if (saved.status != TransactionStatus::Complete) {
if (!TransactionDAO::updateTransaction(
saved.id,
TransactionStatus::Complete,
saved.description,
transaction.description
)) {
qDebug().noquote().nospace() << "--- updated+card[description same] failed"
<<
convertTransactionToString(transaction);;
}
}
parsedTransactionIds.insert(saved.id);
updated = true;
break;
} else {
// описания не совпадают, то пробуем найти такое же, если не находим то это новая
bool findWithSameName = false;
for (const TransactionInfo &saved2: localTransactions) {
if (saved2.description == transaction.description && !parsedTransactionIds.
contains(
saved2.id)) {
// мы нашли с одинаковым описанием и еще не обработанную
if (saved2.status != TransactionStatus::Complete) {
if (!TransactionDAO::updateTransaction(
saved2.id,
TransactionStatus::Complete,
saved2.description,
transaction.description
)) {
qDebug().noquote().nospace() <<
"--- updated+card2[description same] failed"
<<
convertTransactionToString(transaction);;
}
}
parsedTransactionIds.insert(saved2.id);
updated = true;
findWithSameName = true;
break;
}
}
if (!findWithSameName) {
// обновляем описание
if (!TransactionDAO::updateTransaction(
saved.id,
TransactionStatus::Complete,
saved.description,
transaction.description
)) {
qDebug().noquote().nospace() <<
"--- updated+card2+new desc[description same] failed" <<
convertTransactionToString(transaction);;
}
}
parsedTransactionIds.insert(saved.id);
updated = true;
break;
}
} else {
// пустой описание
if (!TransactionDAO::updateTransaction(
saved.id,
TransactionStatus::Complete,
saved.description,
transaction.description
)) {
qDebug().noquote().nospace() <<
"--- updated+card[empty description]" <<
convertTransactionToString(transaction);;
}
parsedTransactionIds.insert(saved.id);
updated = true;
break;
}
}
}
}
if (!updated) {
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
qDebug() << "--- saveAndPostNewTransactionData failed";
}
}
// Если это перевод
// Если совпадает по сумме + телефон + банк дата (без времени) + банк
// Если по карте, мы знаем ток дату + сумма
}
Node waitTab = xmlScreenParser.findButtonNode("Ожидающие обработки", true);
if (!waitTab.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, waitTab.x(), waitTab.y());
QThread::msleep(1000);
QList<TransactionInfo> parsedWaitTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
for (const TransactionInfo &transaction: parsedWaitTransactions) {
QList<TransactionInfo> localActualTransactions = TransactionDAO::getTransactionsWithinHours(
m_account.id, 48
);
for (const TransactionInfo &saved: localActualTransactions) {
if (saved.status != TransactionStatus::Wait) {
continue;
}
QDate sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy HH:mm:ss").date();
if (!sDate.isValid()) {
sDate = QDateTime::fromString(saved.bankTime, "dd.MM.yyyy").date();
}
QDate pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy HH:mm:ss").date();
if (!pDate.isValid()) {
pDate = QDateTime::fromString(transaction.bankTime, "dd.MM.yyyy").date();
}
if (saved.amount == transaction.amount && sDate == pDate) {
// одно и тоже
} else {
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Wait)) {
qDebug() << "--- saveAndPostNewTransactionData - Wait failed";
}
}
}
}
}
}
} else {
m_error = "GetLastDaysHistoryScript - home screen not found";
qWarning() << m_error;
emit finishedWithResult(m_error);
}
AdbUtils::goBack(m_account.deviceId);
AdbUtils::goBack(m_account.deviceId);
AdbUtils::goBack(m_account.deviceId);
emit finishedWithResult(m_error);
}
} // namespace Rshb

View File

@ -1,39 +0,0 @@
#pragma once
#include "CommonScript.h"
namespace Rshb {
class GetLastDaysHistoryScript final : public CommonScript {
Q_OBJECT
public:
~GetLastDaysHistoryScript() override;
explicit GetLastDaysHistoryScript(
AccountInfo account,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
QString m_error;
bool saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
);
bool updateAndPostTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
};
} // namespace Rshb

View File

@ -1,513 +0,0 @@
#include "HomeScreenScript.h"
#include <QThread>
#include <QDebug>
#include <QProcess>
#include <QRandomGenerator>
#include "ScreenXmlParser.h"
#include "adb/AdbUtils.h"
namespace Rshb {
HomeScreenScript::HomeScreenScript(QObject *parent)
: QObject(parent) {
}
HomeScreenScript::~HomeScreenScript() = default;
bool HomeScreenScript::goToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
const int width,
const int height
) {
// Запустить устройство
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
qDebug() << "Process already running, pid: " << pid;
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
AdbUtils::tryToKillApplication(deviceId, packageName);
}
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
qWarning() << "Process has not started";
return false;
}
xmlScreenParser.parseAndSaveXml(
AdbUtils::getScreenDumpAsXml(deviceId, 0)
);
// Даем минимальное время на запуск
QThread::msleep(4500);
int counter = 0;
int restarted = 0;
int totalCounter = 0;
bool findAndInputPincode = false;
while (true) {
counter++;
totalCounter++;
// 3 раза уже перезапускали приложение, завершаем попытки
if (restarted > 2) {
return false;
}
// Если более 30 секунд мы пытаемся перейти на домашнюю, перезапускаем
if (counter > 30) {
AdbUtils::tryToKillApplication(deviceId, packageName);
QThread::msleep(4500);
++restarted;
counter = 0;
}
const QString xml = AdbUtils::getScreenDumpAsXml(deviceId, totalCounter + 1);
xmlScreenParser.parseAndSaveXml(xml);
qDebug() << "Created xml+screenshot, idx: " << (totalCounter + 1);
if (xmlScreenParser.isHomeScreen()) {
qDebug() << "isHomeScreen!!!!!!!";
return true;
}
// Проверяем на банеры после пин-кодом
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
qDebug() << "--- tryToFindBannerOrDialog";
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
QThread::msleep(1000);
continue;
}
// Проверяем на банеры перед пин-кодом
Node closeBannerNode = xmlScreenParser.tryToFindSecurityBanner();
if (!closeBannerNode.isEmpty()) {
qDebug() << "--- tryToFindSecurityBanner";
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
continue;
}
// Проверяем, что это экран ввода пин-кода
if (!findAndInputPincode) {
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите ПИН");
pincode.size() == 4) {
qDebug() << "--- tryToFindPinCode";
// делаем 4 тапа и ждем секунду и продолжаем
for (const Node &node: pincode) {
AdbUtils::makeTap(deviceId, node.x(), node.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
findAndInputPincode = true;
QThread::msleep(3000);
continue;
}
}
QThread::msleep(1000);
// Если что-то пойдет не по плану...
if (totalCounter > 100) {
return false;
}
}
}
QString getPriceAsString(const double value) {
QString sign = value < 0 ? "Минус" : "Плюс";
const auto intValue = static_cast<qint64>(std::abs(value)); // округление до целого
QString number = QString::number(intValue);
QString formatted;
int count = 0;
for (int i = number.length() - 1; i >= 0; --i) {
formatted.prepend(number[i]);
++count;
if (count % 3 == 0 && i != 0) {
formatted.prepend(' ');
}
}
return QString("%1 %2").arg(sign, formatted);
}
Node swipeToButton(
ScreenXmlParser &xmlScreenParser, const QString &deviceId,
const QString &text, int &counter, const int width, const int height
) {
for (int i = 0; i < 10; ++i) {
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
return button;
}
const int x = width / 2;
const int offset = height / 4;
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
return {};
}
void HomeScreenScript::start() {
// Достаем данные из БД по ИД транзакции, перед тем как запустить мы кладем в БД все данные
const QString deviceId = "6edc4a47";
const QString packageName = "ru.rshb.dbo";
const QString pinCode = "1102";
const int width = 720;
const int height = 1600;
const QString cardNumber = "7 1 8 3";
// В том числе и данные на каком устройстве это делать
// TODO тут код работы с БД
// +7 (964) 181-51-46
const QString phoneNumber = "+79641815146";
const QString bankName = "Альфа-Банк";
const QString paySum = "10";
int index = 0;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++index));
// xmlScreenParser.test();
// тут просто получаем инфу которую спарсил
// == 1. Входящий (TransactionType::Phone)
// Перевод через СБП от Егор Иванович Ж (+7(000)-000-00-87) из Озон Банк (Ozon) на 40817810328000022077 .
// Идентификатор операции в СБП С2С B5121111443333300170011491301 , Дата операции 01.05.2025 14:14:41 Статус перевода Исполнен
// == 2. Исходящий (TransactionType::Phone)
// Перевод Надежда Иванкина К** в Сбербанк через СБП, по номеру телефона +79000810046, ID перевода 445900141, дата 03.05.2025
// (TransactionType::Card) -> T-BANK CARD2CARD
// TransactionInfo trInfo = xmlScreenParser.parseTransactionInfoHistory(width, height);
// qDebug().noquote().nospace() << convertTransactionToString(trInfo);
// Если начинается с ЕСПП - то не кликаем еще, ждет обработку
// А все переводы по карте - они не начинаются со слова "Перевод" ->
// .. пробуем кликать, но если не кликается ???
QList<TransactionInfo> transactions = xmlScreenParser.parseTodayAndYesterdayHistory();
for (const TransactionInfo &info: transactions) {
QString text = QString("%1 %2").arg(info.description, getPriceAsString(info.amount));
qDebug().noquote().nospace() << convertTransactionToString(info);
// Node trButton = xmlScreenParser.findButtonNode(text, true);
Node trButton = swipeToButton(xmlScreenParser, deviceId, text, index, width, height);
if (!trButton.isEmpty()) {
AdbUtils::makeTap(deviceId, trButton.x(), trButton.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++index));
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
if (!moreDetailBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, moreDetailBtn.x(), moreDetailBtn.y());
QThread::msleep(200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++index));
TransactionInfo info = xmlScreenParser.parseTransactionInfoHistory(width, height);
qDebug().noquote().nospace() << convertTransactionToString(info);
}
AdbUtils::goBack(deviceId);
} else {
qWarning() << "--- trButton not found..........";
}
// Перевод ВЛАДИСЛАВ НИКОЛАЕВИЧ К** в Т-Банк через СБП, по номеру телефона +7985553... Минус 10 рублей 0 копеек
}
return;
int payCounter = 0;
if (false) {
// Оплата со страницы карты
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
Node payBtn = xmlScreenParser.findButtonNode("Оплатить", false);
if (!payBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, payBtn.x(), payBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- payBtn not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
// TODO - По номеру карты В РСХБ и другие банки
Node payTitle = xmlScreenParser.findTextNode("Платежи и переводы");
if (!payTitle.isEmpty() && payTitle.y() < 300) {
Node payByPhoneBtn = xmlScreenParser.findButtonNode("По номеру телефона В РСХБ и через", false);
if (!payByPhoneBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, payByPhoneBtn.x(), payByPhoneBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- payByPhoneBtn not found";
}
} else {
qWarning() << "--- payTitle not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
Node payByPhoneTitle = xmlScreenParser.findTextNode("Перевод по телефону");
Node continueBtn = xmlScreenParser.findButtonNode("Продолжить", false);
if (!payByPhoneTitle.isEmpty() && payByPhoneTitle.y() < 300 && continueBtn.isEmpty()) {
Node inputPhone = xmlScreenParser.findFirstEditText();
AdbUtils::makeTap(deviceId, inputPhone.x(), inputPhone.y());
QThread::msleep(500);
AdbUtils::inputText(deviceId, phoneNumber);
QThread::msleep(1000);
} else {
qWarning() << "--- payByPhoneTitle not found (no continueBtn)";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
QString payBankName;
payBankName = bankName == "Россельхозбанк" ? "Россельхозбанк" : "Другой банк через СБП";
Node payOtherBankBtn = xmlScreenParser.findButtonNode(payBankName, false);
if (!payOtherBankBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, payOtherBankBtn.x(), payOtherBankBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- payOtherBankBtn not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
for (int i = 0; i < 5; ++i) {
Node allBanksTitle = xmlScreenParser.findTextNode("Банки участники");
if (!allBanksTitle.isEmpty() && allBanksTitle.y() < 300) {
Node inputBankName = xmlScreenParser.findFirstEditText();
AdbUtils::makeTap(deviceId, inputBankName.x(), inputBankName.y());
QThread::msleep(500);
AdbUtils::enableAdbIMEKeyboard(deviceId);
AdbUtils::inputAdbIMEText(deviceId, bankName);
AdbUtils::disableAdbIMEKeyboard(deviceId);
QThread::msleep(1000);
break;
} else {
qWarning() << "--- allBanksTitle not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
for (int i = 0; i < 5; ++i) {
Node bankNameListItem = xmlScreenParser.findTextNode(bankName);
if (!bankNameListItem.isEmpty()) {
AdbUtils::makeTap(deviceId, bankNameListItem.x(), bankNameListItem.y());
QThread::msleep(1000);
break;
} else {
qWarning() << "--- bankNameListItem not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
Node payByPhoneScreenTitle = xmlScreenParser.findTextNode("Перевод по телефону");
Node continuePayBtn = xmlScreenParser.findButtonNode("Продолжить", false);
if (!payByPhoneScreenTitle.isEmpty() && payByPhoneScreenTitle.y() < 300 && !continuePayBtn.isEmpty()) {
Node sumBtn = xmlScreenParser.findButtonNode("0", false);
if (!sumBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, sumBtn.x(), sumBtn.y());
QThread::msleep(500);
AdbUtils::inputText(deviceId, paySum);
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
Node readyBtn = xmlScreenParser.findTextNode("Готово");
if (!readyBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, readyBtn.x(), readyBtn.y());
QThread::msleep(500);
AdbUtils::makeTap(deviceId, continuePayBtn.x(), continuePayBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- readyBtn not found";
}
} else {
qWarning() << "--- sumBtn not found";
}
} else {
qWarning() << "--- payByPhoneScreenTitle not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
for (int i = 0; i < 5; ++i) {
// TODO кнопка содержит "Перевести 10 ₽" если будет от 1000 то скорее всвего будет "Перевести 1 000 ₽",
// TODO не ясно как форматирование будет, поэтому пока на начало зашьем
Node makePayBtn = xmlScreenParser.findButtonNode("Перевести ", true);
if (!makePayBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, makePayBtn.x(), makePayBtn.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите код доступа");
pincode.size() == 4) {
// FIXME вынести в отдельный метод
// делаем 4 тапа и ждем секунду и продолжаем
for (const Node &node: pincode) {
AdbUtils::makeTap(deviceId, node.x(), node.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
// После ввода пин-кода, ждем 3с
QThread::msleep(3000);
}
break;
} else {
qWarning() << "--- makePayBtn not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
for (int i = 0; i < 5; ++i) {
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
if (!moreDetailBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, moreDetailBtn.x(), moreDetailBtn.y());
QThread::msleep(200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
Node paymentCompleted = xmlScreenParser.findTextNode("Исполнен", 0, 0, width, height / 2);
Node paymentInProgress = xmlScreenParser.findTextNode("Выполняется", 0, 0, width, height / 2);
if (!paymentCompleted.isEmpty()) {
// Если вдруг исполнен
} else if (!paymentInProgress.isEmpty()) {
// Если все еще в ожидании
} else {
qWarning() << "--- paymentCompleted or paymentInProgress not found...";
}
break;
} else {
qWarning() << "--- moreDetailBtn not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++payCounter));
}
return;
int counter = 0;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, counter));
Node closeBannerOrDialogNode = xmlScreenParser.tryToFindBannerOrDialog(width, height);
if (closeBannerOrDialogNode.x() != -1 && closeBannerOrDialogNode.y() != -1) {
qDebug() << "--- tryToFindBannerOrDialog";
AdbUtils::makeTap(deviceId, closeBannerOrDialogNode.x(), closeBannerOrDialogNode.y());
QThread::msleep(1000);
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
if (xmlScreenParser.isHomeScreen()) {
qDebug() << "--- isHomeScreen";
if (Node allCardTitle = xmlScreenParser.findTextNode("Счета и карты"); !allCardTitle.isEmpty()) {
// 1. Если нет кнопки видимой, свайпаем. Кликаем на "Все продукты"
for (int i = 0; i < 5; ++i) {
Node allProductsBtn = xmlScreenParser.findButtonNode("Все продукты", false);
// Node allProductsBtn = xmlScreenParser.findTextNode("Курсы валют и металлов"); для теста
if (allProductsBtn.x() > 0 && allProductsBtn.y() > 0) {
qDebug() << "--- All Product in focus";
AdbUtils::makeTap(deviceId, allProductsBtn.x(), allProductsBtn.y());
QThread::msleep(1000);
break;
}
AdbUtils::makeSwipe(deviceId,
allCardTitle.x(), allCardTitle.y(),
allCardTitle.x(), allCardTitle.y() - 200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
for (int i = 0; i < 5; ++i) {
Node allProductsTitle = xmlScreenParser.findTextNode("Все продукты");
// Проверяем что вверху заголовок
if (!allProductsTitle.isEmpty() && allProductsTitle.y() < 300) {
qDebug() << "--- All Product screen";
// TODO тут делаем синхронизацию данных все карт
Node cardNumberBtn = xmlScreenParser.findButtonNode(cardNumber, true);
AdbUtils::makeTap(deviceId, cardNumberBtn.x(), cardNumberBtn.y());
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
Node filterBtn = xmlScreenParser.findButtonNode("РСХБ Онлайн", false);
if (!filterBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, filterBtn.x(), filterBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- filterBtn not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
Node allTransactionFilerBtn = xmlScreenParser.findButtonNode("Все операции", false);
if (!allTransactionFilerBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, allTransactionFilerBtn.x(), allTransactionFilerBtn.y());
QThread::msleep(1000);
} else {
qWarning() << "--- allTransactionFilerBtn not found";
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
for (int i = 0; i < 5; ++i) {
QList<Node> transactions = xmlScreenParser.getLast2DaysTransactions();
if (!transactions.empty()) {
for (const Node &transaction: transactions) {
qDebug() << transaction.text;
// TODO вот мы дошли до списка транзакций
}
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
//
} else {
// пишем в БД, что не дошли до домашней страницы, и завершаемся
// сохраняем скрин приложения
// дделаем алерт
}
} else {
// пишем в БД, что не дошли до домашней страницы, и завершаемся
// сохраняем скрин приложения
// дделаем алерт
}
return;
// 1. Идем на домашнюю страницу
if (goToHomeScreen(deviceId, packageName, pinCode, width, height)) {
// мы на главном
// перед тем как юзать снова проверить на банеры
// Проверяем на банеры после пин-кодом
// Это уже для шага дальше
// если нулевые координаты, свайпаем вверх, чтобы текст "Счета и карты" был у верхнего края
} else {
// пишем в БД, что не дошли до домашней страницы, и завершаемся
// сохраняем скрин приложения
// дделаем алерт
}
// 2. Идем дальше
emit finished();
}
void HomeScreenScript::stop() {
m_running = false;
}
} // namespace Rshb

View File

@ -1,39 +0,0 @@
#pragma once
#include <QObject>
#include <QPair>
#include "ScreenXmlParser.h"
namespace Rshb {
class HomeScreenScript final : public QObject {
Q_OBJECT
public:
explicit HomeScreenScript(QObject *parent = nullptr);
~HomeScreenScript() override;
public slots:
void start();
void stop();
signals:
void finished();
private:
bool m_running = true;
ScreenXmlParser xmlScreenParser;
bool goToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
int width,
int height
);
};
} // namespace Rshb

View File

@ -1,69 +0,0 @@
#include "LoginAndCheckAccountsScript.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
namespace Rshb {
LoginAndCheckAccountsScript::LoginAndCheckAccountsScript(
QString deviceId,
QString appCode,
QObject *parent
) : CommonScript(parent),
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
}
LoginAndCheckAccountsScript::~LoginAndCheckAccountsScript() = default;
void LoginAndCheckAccountsScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
} else {
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
for (auto &[account, node]: accounts) {
account.deviceId = m_deviceId;
account.appCode = m_appCode;
if (!AccountDAO::upsertAccount(account)) {
m_error = "Not updated: " + account.lastNumbers;
qCritical() << m_error;
}
}
postAccountsData(accounts);
} else {
qWarning() << "Cant go to all products: " << m_deviceId << " " << m_appCode;
}
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
}
} // namespace Rshb

View File

@ -1,27 +0,0 @@
#pragma once
#include "CommonScript.h"
namespace Rshb {
class LoginAndCheckAccountsScript final : public CommonScript {
Q_OBJECT
public:
~LoginAndCheckAccountsScript() override;
explicit LoginAndCheckAccountsScript(
QString deviceId,
QString appCode,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const QString m_deviceId;
const QString m_appCode;
QString m_error;
};
} // namespace Rshb

View File

@ -1,340 +0,0 @@
#include "PayByPhoneScript.h"
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/ApplicationInfo.h"
#include "db/DeviceInfo.h"
namespace Rshb {
PayByPhoneScript::PayByPhoneScript(
AccountInfo account,
QString phone,
QString bankName,
const double amount,
QObject *parent
) : CommonScript(parent),
m_account(std::move(account)), m_phone(std::move(phone)),
m_bankName(std::move(bankName)), m_amount(amount) {
}
PayByPhoneScript::~PayByPhoneScript() = default;
void PayByPhoneScript::makePayment(
const QString &deviceId,
const QString &pinCode,
int width,
int height
) {
// Оплата со страницы карты
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
Node payBtn = xmlScreenParser.findButtonNode("Оплатить", false);
if (!payBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, payBtn.x(), payBtn.y());
QThread::msleep(1000);
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_pay_btn_not_found");
m_error = "Кнопка 'Оплатить' не нашлась";
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
// TODO - По номеру карты В РСХБ и другие банки
Node payTitle = xmlScreenParser.findTextNode("Платежи и переводы");
if (!payTitle.isEmpty() && payTitle.y() < 300) {
Node payByPhoneBtn = xmlScreenParser.findButtonNode("По номеру телефона В РСХБ и через", false);
if (!payByPhoneBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, payByPhoneBtn.x(), payByPhoneBtn.y());
QThread::msleep(1000);
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_not_found_pay_by_phone");
m_error = "Не смогли найти пункт 'По номеру телефона В РСХБ и через'";
qDebug() << m_error;
return;
}
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_go_to_payments");
m_error = "Не смогли перейти на экран 'Платежи и переводы'";
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
Node payByPhoneTitle = xmlScreenParser.findTextNode("Перевод по телефону");
Node continueBtn = xmlScreenParser.findButtonNode("Продолжить", false);
if (!payByPhoneTitle.isEmpty() && payByPhoneTitle.y() < 300 && continueBtn.isEmpty()) {
Node inputPhone = xmlScreenParser.findFirstEditText();
AdbUtils::makeTap(deviceId, inputPhone.x(), inputPhone.y());
QThread::msleep(500);
AdbUtils::inputText(deviceId, m_phone);
QThread::msleep(1000);
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_find_pay_by_phone");
m_error = "Не смогли найти пункт 'Перевод по телефону'";
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
QString payBankName = m_bankName == QStringLiteral("Россельхозбанк") ? "Россельхозбанк" : "Другой банк через СБП";
Node payOtherBankBtn = xmlScreenParser.findButtonNode(payBankName, false);
if (!payOtherBankBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, payOtherBankBtn.x(), payOtherBankBtn.y());
QThread::msleep(1000);
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_tap_on_bank");
m_error = "Не смогли нажать на первичный выбор банка";
qDebug() << m_error;
return;
}
if (m_bankName != QStringLiteral("Россельхозбанк")) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
for (int i = 0; i < 5; ++i) {
Node allBanksTitle = xmlScreenParser.findTextNode("Банки участники");
if (!allBanksTitle.isEmpty() && allBanksTitle.y() < 300) {
Node inputBankName = xmlScreenParser.findFirstEditText();
AdbUtils::makeTap(deviceId, inputBankName.x(), inputBankName.y());
QThread::msleep(500);
AdbUtils::enableAdbIMEKeyboard(deviceId);
AdbUtils::inputAdbIMEText(deviceId, m_bankName);
AdbUtils::disableAdbIMEKeyboard(deviceId);
QThread::msleep(1000);
break;
} else {
qDebug() << "--- allBanksTitle not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
for (int i = 0; i < 5; ++i) {
Node bankNameListItem = xmlScreenParser.findTextNode(m_bankName);
if (!bankNameListItem.isEmpty()) {
AdbUtils::makeTap(deviceId, bankNameListItem.x(), bankNameListItem.y());
QThread::msleep(1000);
break;
} else {
qDebug() << "--- bankNameListItem not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
const bool isRshbBank = m_bankName == QStringLiteral("Россельхозбанк");
QString payByPhoneScreenTitleText = isRshbBank ? "Перевод клиенту РСХБ" : "Перевод по телефону";
Node payByPhoneScreenTitle = xmlScreenParser.findTextNode(payByPhoneScreenTitleText);
Node continuePayBtn = xmlScreenParser.findButtonNode("Продолжить", false);
if (isRshbBank ||
!payByPhoneScreenTitle.isEmpty() && payByPhoneScreenTitle.y() < 300 && !continuePayBtn.isEmpty()) {
Node sumBtn = xmlScreenParser.findButtonNode("0", false);
if (isRshbBank || !sumBtn.isEmpty()) {
if (!isRshbBank) {
AdbUtils::makeTap(deviceId, sumBtn.x(), sumBtn.y());
QThread::msleep(500);
}
AdbUtils::inputText(deviceId, QString::number(m_amount));
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
Node readyBtn = xmlScreenParser.findTextNode("Готово");
if (!readyBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, readyBtn.x(), readyBtn.y());
QThread::msleep(500);
if (isRshbBank) {
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
continuePayBtn = xmlScreenParser.findButtonNode("Продолжить", false);
}
AdbUtils::makeTap(deviceId, continuePayBtn.x(), continuePayBtn.y());
QThread::msleep(1000);
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_tap_on_ready");
m_error = "Не смогли нажать 'Готово'";
qDebug() << m_error;
return;
}
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_tap_on_continue");
m_error = "Не смогли нажать 'Продолжить'";
qDebug() << m_error;
return;
}
} else {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_find_bank_title");
m_error = "Не смогли найти заголовок: " + payByPhoneScreenTitleText;
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
bool inputedPinCode = false;
for (int i = 0; i < 5; ++i) {
// TODO кнопка содержит "Перевести 10 ₽" если будет от 1000 то скорее всвего будет "Перевести 1 000 ₽",
// TODO не ясно как форматирование будет, поэтому пока на начало зашьем
Node makePayBtn = xmlScreenParser.findButtonNode("Перевести ", true);
if (!makePayBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, makePayBtn.x(), makePayBtn.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
if (const QList<Node> pincode = xmlScreenParser.tryToFindPinCode(pinCode, "Введите код доступа");
pincode.size() == 4) {
inputPinCode(deviceId, pincode);
inputedPinCode = true;
// После ввода пин-кода, ждем 3с
QThread::msleep(3000);
}
break;
} else {
qWarning() << "--- makePayBtn not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
if (!isRshbBank && !inputedPinCode) {
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_cant_input_pin_code");
m_error = "Не смогли ввести пин-код!'";
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
for (int i = 0; i < 10; ++i) {
Node moreDetailBtn = xmlScreenParser.findButtonNode("Детали операции", false);
if (!moreDetailBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, moreDetailBtn.x(), moreDetailBtn.y());
QThread::msleep(200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
// TODO считываем все данные по переводу
TransactionInfo transaction = xmlScreenParser.parseTransactionInfo(width, height);
if (isRshbBank) {
transaction.bankName = m_bankName;
}
transaction.accountId = m_account.id;
transaction.amount = -m_amount;
transaction.type = TransactionType::Phone;
transaction.id = TransactionDAO::insertTransaction(transaction);
if (transaction.id == -1) {
// FIXME alert!!
qDebug() << "Transaction has not inserted...";
}
// ждем 10 секунд смену статуса
for (int k = 0; k < 10; ++k) {
Node paymentCompleted = xmlScreenParser.findTextNode("Исполнен", 0, 0, width, height / 2);
if (!paymentCompleted.isEmpty()) {
transaction.status = TransactionStatus::Complete;
if (!TransactionDAO::updateTransactionStatus(transaction.id, TransactionStatus::Complete)) {
qDebug() << "Not updated: " << transaction.id;
}
// TODO обновляем данные
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
postNewTransactionData(m_account, transaction);
AdbUtils::takeScreenshot(deviceId, "pay_by_phone_finish_transactions_" + transaction.id);
AdbUtils::takeXmlDump(deviceId, "pay_by_phone_finish_transactions_" + transaction.id);
break;
} else {
qWarning() << "--- moreDetailBtn not found, i: " << i;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
}
Node homeBtn = xmlScreenParser.findButtonNode("Вернуться на главную", false);
AdbUtils::makeTap(deviceId, homeBtn.x(), homeBtn.y());
QThread::msleep(1000);
}
void PayByPhoneScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found....";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
}
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
QList<QPair<AccountInfo, Node> > accounts = xmlScreenParser.parseAccountsInfo();
for (auto &[account, node]: accounts) {
account.deviceId = m_account.deviceId;
account.appCode = m_account.appCode;
account.status = account.amount > 0 ? AccountStatus::Active : AccountStatus::Off;
if (!AccountDAO::upsertAccount(account)) {
qDebug() << "Not updated: " << account.lastNumbers;
}
}
postAccountsData(accounts);
for (auto &[account, node]: accounts) {
// FIXME будем считать что числа последние везде уникальные
if (m_account.lastNumbers == account.lastNumbers) {
if (account.amount >= m_amount) {
AdbUtils::makeTap(device.id, node.x(), node.y());
QThread::msleep(1000);
} else {
AdbUtils::takeScreenshot(device.id, "pay_by_phone_not_enough_money_" + QString::number(m_account.id));
m_error = "Not enough money, id: " + QString::number(m_account.id)
+ ", amount: " + QString::number(account.amount)
+ ", trx amount: " + QString::number(m_amount);
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
break;
}
}
makePayment(device.id, app.pinCode, device.screenWidth, device.screenHeight);
// AdbUtils::tryToKillApplication(device.id, app.package); TODO - надо ли это???
} else {
AdbUtils::takeScreenshot(device.id, "pay_by_phone_cant_open_all_products_" + QString::number(m_account.id));
AdbUtils::tryToKillApplication(device.id, app.package);
m_error = "Не смогли открыть 'Все продукты'";
qDebug() << m_error;
}
emit finishedWithResult(m_error);
}
} // namespace Rshb

View File

@ -1,38 +0,0 @@
#pragma once
#include "CommonScript.h"
namespace Rshb {
class PayByPhoneScript final : public CommonScript {
Q_OBJECT
public:
~PayByPhoneScript() override;
PayByPhoneScript(
AccountInfo account,
QString phone,
QString bankName,
double amount,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
const QString m_phone;
const QString m_bankName;
const double m_amount;
QString m_error;
void makePayment(
const QString &deviceId,
const QString &pinCode,
int width,
int height
);
};
} // namespace Rshb

View File

@ -1,980 +0,0 @@
#include "ScreenXmlParser.h"
#include <QRegularExpression>
#include <QMap>
#include <QSet>
#include <QList>
#include <QXmlStreamReader>
#include <QDomDocument>
#include <QFile>
#include <QDateTime>
#include "adb/AdbUtils.h"
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
#include "time/DateUtils.h"
namespace Rshb {
ScreenXmlParser::ScreenXmlParser(QObject *parent) : QObject(parent) {
}
ScreenXmlParser::~ScreenXmlParser() = default;
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
static const QRegularExpression onlyDigitsRegex(R"([^0-9])");
static const QRegularExpression onlyDigitsAndDotRegex(R"([^0-9.])");
static const QRegularExpression rePhone(R"raw((\+7\(?\d{3}\)?[- ]?\d{3}[- ]?\d{2}[- ]?\d{2}))raw");
static const QRegularExpression reFromBank(R"raw(из (.+?) на)raw");
static const QRegularExpression reToBank(R"raw(в (.+?) через)raw");
static const QRegularExpression reSbpId(R"(СБП(?: С2С)? ([A-Z0-9]{30,}))");
static const QRegularExpression reIdAlt(R"(ID перевода (\d+))");
static const QRegularExpression reDate(R"((?:Дата операции|дата) (\d{2}\.\d{2}\.\d{4}(?: \d{2}:\d{2}:\d{2})?))");
static const QRegularExpression reSender(R"(от ([^\(]+))");
static const QRegularExpression reNameAlt(R"(Перевод ([А-Яа-яЁё\s\*]+) в)");
static const QRegularExpression reCardData(R"(цифрами\s+(\d\s\d\s\d\s\d).*?Сумма:\s([\d\s]+)\sруб)");
Node ScreenXmlParser::tryToFindBannerOrDialog(const int width, const int height) {
// 1. Ищем push banner - он перекрывает весь экран
Node first = m_nodes[0];
for (const Node &node: m_nodes) {
// Если это однозначно, что пуш-баннер
if (node.resourceId == "aft-popup-pushNotification-iconClose" && node.className == "android.widget.Button") {
return node;
}
// Если есть кнопка "Позже"
if (node.text.trimmed() == "Позже" && node.className == "android.widget.Button") {
return node;
}
// Если нашли пустую кнпоку
if (node.className == "android.widget.Button" && node.clickable
&& node.text.isEmpty() && node.contentDesc.isEmpty()) {
// <node class="android.widget.Button" package="ru.rshb.dbo" clickable="true" bounds="[630,142][691,205]"/>
if (node.x() > width / 2 && node.y() < width / 2) {
return node;
}
}
}
return {};
}
/**
* Смотрим что есть текс "Мы заботимся о вашей безопасности" и
* кнопка "Отложить"
* @return координаты кнопки для закрытия
*/
Node ScreenXmlParser::tryToFindSecurityBanner() {
Node text;
Node closeBtn;
for (const Node &node: m_nodes) {
if (node.text.trimmed() == "Мы заботимся о вашей безопасности" && node.className == "android.app.Dialog") {
text = node;
}
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
closeBtn = node;
}
}
// Не нужно проверять все, если хотя бы одна координата есть
if (!text.isEmpty() && !closeBtn.isEmpty()) {
return closeBtn;
}
return {};
}
Node ScreenXmlParser::tryToFindSelectBottomSheet() {
Node closeBtn;
for (const Node &node: m_nodes) {
if ((node.text.trimmed() == "Отмена" || node.text.trimmed() == "Отложить") && node.className ==
"android.widget.Button") {
closeBtn = node;
}
}
// Не нужно проверять все, если хотя бы одна координата есть
if (!closeBtn.isEmpty()) {
return closeBtn;
}
return {};
}
Node ScreenXmlParser::findTextNode(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
return node;
}
}
return {};
}
Node ScreenXmlParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
return node;
}
}
return {};
}
Node ScreenXmlParser::findFirstEditText() {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.focusable) {
return node;
}
}
return {};
}
Node ScreenXmlParser::findButtonNode(const QString &text, const bool contains) {
for (const Node &node: m_nodes) {
if (contains) {
if (node.className == "android.widget.Button" && node.text.contains(text)) {
return node;
}
} else {
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
return node;
}
}
}
return {};
}
bool ScreenXmlParser::isHomeScreen() {
// Есть заголовок "Счета и карты" и кнопка "Все продукты"
Node text;
Node allProductBtn;
for (const Node &node: m_nodes) {
if (node.text.trimmed() == "Счета и карты" && node.className == "android.widget.TextView") {
text = node;
}
if (node.text.trimmed() == "Все продукты" && node.className == "android.widget.Button") {
allProductBtn = node;
}
}
return !text.isEmpty() && !allProductBtn.isEmpty();
}
QList<Node> ScreenXmlParser::findPinCodeNodes(const QString &pinCode) {
QMap<QString, Node> buttons;
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
for (const Node &node: m_nodes) {
const QString &text = node.text.trimmed();
if (node.className == "android.widget.Button" && numberSet.contains(text)) {
buttons[text] = node;
}
}
QList<Node> nodes;
for (int i = 0; i < pinCode.length(); ++i) {
nodes.append(buttons[QString(pinCode.at(i))]);
}
return nodes;
}
QList<Node> ScreenXmlParser::tryToFindPinCode(const QString &pinCode, const QString &title) {
for (const Node &node: m_nodes) {
// если там есть такая кнопка значит банер есть, и пин-код не прожать
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
return {};
}
}
for (const Node &node: m_nodes) {
// FIXME определение пин-кода лучше сделать
if (node.text.trimmed() == title) {
return findPinCodeNodes(pinCode);
}
}
return {};
}
QList<Node> ScreenXmlParser::getLast2DaysTransactions() {
QList<Node> nodes;
for (const Node &node: m_nodes) {
if (node.className == "android.widget.Button" && node.text.contains("рубл")
&& (node.text.contains("Минус") || node.text.contains("Плюс"))) {
nodes.append(node);
}
}
return nodes;
}
/**
* <node NAF="true" index="1" text="" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[952,159][1039,248]"/>
*/
void ScreenXmlParser::parseAndSaveXml(const QString &xml) {
QDomDocument doc;
doc.setContent(xml);
m_xml = doc.documentElement();
m_nodes.clear();
QXmlStreamReader reader(xml);
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement() && reader.name() == "node") {
Node node = Node();
if (reader.attributes().hasAttribute("bounds")) {
QString bounds = reader.attributes().value("bounds").toString();
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
node.setBounds(
match.captured(1).toInt(),
match.captured(2).toInt(),
match.captured(3).toInt(),
match.captured(4).toInt()
);
}
}
if (reader.attributes().hasAttribute("text")) {
node.text = reader.attributes().value("text").toString();
}
if (reader.attributes().hasAttribute("content-desc")) {
node.contentDesc = reader.attributes().value("content-desc").toString();
}
if (reader.attributes().hasAttribute("class")) {
node.className = reader.attributes().value("class").toString();
}
if (reader.attributes().hasAttribute("clickable")) {
node.clickable = reader.attributes().value("clickable").toString() == "true";
}
if (reader.attributes().hasAttribute("focusable")) {
node.focusable = reader.attributes().value("focusable").toString() == "true";
}
if (reader.attributes().hasAttribute("resource-id")) {
node.resourceId = reader.attributes().value("resource-id").toString();
}
m_nodes.append(node);
}
}
}
QString getDayOfWeekAsString(const int day_of_week) {
switch (day_of_week) {
case 1: return "понедельник";
case 2: return "вторник";
case 3: return "среда";
case 4: return "четверг";
case 5: return "пятница";
case 6: return "суббота";
case 7: return "воскресенье";
default: return "";
}
}
QString getMonthAsString(const int month) {
switch (month) {
case 1: return "января";
case 2: return "февраля";
case 3: return "марта";
case 4: return "апреля";
case 5: return "мая";
case 6: return "июня";
case 7: return "июля";
case 8: return "августа";
case 9: return "сентября";
case 10: return "октября";
case 11: return "ноября";
case 12: return "декабря";
default: return "";
}
}
QDomElement findSubElement(const QDomElement &elem, const QString &index) {
if (elem.hasChildNodes()) {
QDomNodeList subInfoList = elem.childNodes();
for (QDomNode subInfoNode: subInfoList) {
if (!subInfoNode.isElement()) continue;
QDomElement subInfo = subInfoNode.toElement();
if (subInfo.attribute("index") == index) {
return subInfo;
}
}
}
return {};
}
QString findSubInfo(const QDomElement &elem, const QString &index) {
QDomElement subInfo = findSubElement(elem, index);
if (!subInfo.isNull()) {
return subInfo.attribute("text");
}
return "";
}
bool hasTimeComponent(const QString &datetimeStr) {
QDateTime dt = QDateTime::fromString(datetimeStr, "dd.MM.yyyy HH:mm:ss");
if (!dt.isValid()) {
return false; // Строка не соответствует формату даты и времени
}
return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00
}
QString transformBankDateTime(const QString &date) {
QDateTime dt;
if (date.contains(",")) {
// 10.05.2025, 15:03
dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm");
} else {
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss");
}
if (!dt.isValid()) {
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm");
}
if (!dt.isValid()) {
return date; // не распарсили
}
return dt.toString("dd.MM.yyyy HH:mm:ss");
}
void parseTransferInfo(const QString &text, TransactionInfo &info) {
if (const auto m = reSender.match(text); m.hasMatch()) {
info.name = m.captured(1).trimmed();
} else if (const auto m1 = reNameAlt.match(text); m1.hasMatch()) {
info.name = m1.captured(1).trimmed();
}
if (const auto m = rePhone.match(text); m.hasMatch()) {
info.phone = m.captured(1).trimmed().remove(onlyDigitsRegex);
}
if (const auto m = reFromBank.match(text); m.hasMatch()) {
if (const QString bank = m.captured(1).trimmed(); !bank.isEmpty()) {
info.bankName = bank;
}
} else if (const auto m1 = reToBank.match(text); m1.hasMatch()) {
if (const QString bank = m1.captured(1).trimmed(); !bank.isEmpty()) {
info.bankName = bank;
}
}
if (const auto m = reSbpId.match(text); m.hasMatch()) {
info.bankTrExternalId = m.captured(1);
} else if (const auto m1 = reIdAlt.match(text); m1.hasMatch()) {
info.bankTrExternalId = m1.captured(1);
}
if (const auto m = reDate.match(text); m.hasMatch()) {
const QString date = m.captured(1);
// если не пустая и дата у нас с 00:00
// if (hasTimeComponent(date)) {
info.bankTime = transformBankDateTime(date);
// }
}
}
void traverseNodes(const QDomNode &node) {
if (node.isElement()) {
QDomElement elem = node.toElement();
if (node.isElement()) {
QDomElement elem = node.toElement();
if (elem.tagName() == "node" &&
elem.attribute("class") == "android.widget.Button" &&
elem.attribute("text") == "Детали операции") {
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int j = 0; j < detailInfo.count(); ++j) {
QDomNode info = detailInfo.at(j);
if (!info.isElement()) continue;
QDomElement infoElement = info.toElement();
QString index = infoElement.attribute("index");
switch (index.toInt()) {
case 2:
qDebug() << "Дата операции:" << findSubInfo(infoElement, "1");
break;
case 5:
qDebug() << "Название:" << findSubInfo(infoElement, "1");
qDebug() << "-------------------------------------";
// parseTransfer(findSubInfo(infoElement));
break;
case 7:
qDebug() << "Комиссия:" << findSubInfo(infoElement, "1");
break;
default:
qDebug() << "Прочее:" << findSubInfo(infoElement, "1");
break;
}
/**
Node: "2" ""
... Node: "0" "Дата операции"
... Node: "1" "30.04.2025 17:46:29"
Node: "5" ""
... Node: "0" "Название"
... Node: "1" "DBO TRANSFER RSHB INTERNET-BANK"
Node: "7" ""
... Node: "0" "Комиссия"
... Node: "1" "50 ₽"
*/
// if (sibElem.hasChildNodes()) {
// QDomNodeList sibChildren = sibElem.childNodes();
// for (int k = 0; k < sibChildren.count(); ++k) {
// QDomNode sibChild = sibChildren.at(k);
// if (!sibChild.isElement()) continue;
// QDomElement sibChildElem = sibChild.toElement();
// qDebug() << "... Node:"
// << sibChildElem.attribute("index")
// << sibChildElem.attribute("text");
// // << sibChildElem.attribute("class");
//
//
// if (sibChildElem.hasChildNodes()) {
// QDomNodeList sibChildren2 = sibChildElem.childNodes();
// for (int k = 0; k < sibChildren2.count(); ++k) {
// QDomNode sibChild2 = sibChildren2.at(k);
// if (!sibChild2.isElement()) continue;
// QDomElement sibChildElem2 = sibChild2.toElement();
//
// qDebug() << "...... Node:"
// << sibChildElem2.attribute("index")
// << sibChildElem2.attribute("text");
// // << sibChildElem2.attribute("class");
//
// if (sibChildElem2.hasChildNodes()) {
// QDomNodeList sibChildren3 = sibChildElem2.childNodes();
// for (int k = 0; k < sibChildren3.count(); ++k) {
// QDomNode sibChild3 = sibChildren3.at(k);
// if (!sibChild3.isElement()) continue;
// QDomElement sibChildElem3 = sibChild3.toElement();
//
// qDebug() << "......... Node:"
// << sibChildElem3.attribute("index")
// << sibChildElem3.attribute("text");
// // << sibChildElem2.attribute("class");
// }
// }
// }
// }
// }
// }
}
}
}
}
// Рекурсивно обходим всех детей
QDomNode child = node.firstChild();
while (!child.isNull()) {
traverseNodes(child);
child = child.nextSibling();
}
}
QDomNode findNode(const QDomNode &node, const QString &text) {
if (node.isElement()) {
QString nodeText = node.toElement().attribute("text");
if (nodeText.toLower().startsWith(text)) {
return node;
}
}
QDomNode child = node.firstChild();
while (!child.isNull()) {
QDomNode result = findNode(child, text);
if (!result.isNull()) {
return result;
}
child = child.nextSibling();
}
return {};
}
float extractAmounts(const QString &text) {
// Разрешаем пробелы внутри чисел, захватываем "рубль", "рубля", "рублей" и т.д.
// QRegularExpression re(R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)");
QRegularExpression re(
R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)",
QRegularExpression::UseUnicodePropertiesOption
);
QRegularExpressionMatch match = re.match(text);
if (match.hasMatch()) {
QString signStr = match.captured(1); // "Плюс" или "Минус"
QString rublesStr = match.captured(2).remove(' '); // "1 000" → "1000"
int rubles = rublesStr.toInt();
int kopecks = match.captured(3).toInt();
int totalKopecks = rubles * 100 + kopecks;
if (signStr == "Минус") {
totalKopecks *= -1;
}
return totalKopecks / 100.0f;
}
return 0;
}
QString beforeAmount(const QString &text) {
int index = text.indexOf(QRegularExpression("Плюс|Минус"));
if (index != -1) {
return text.left(index).trimmed();
}
return text; // если не найдено — вернуть всю строку
}
double parseAmount(const QString &amountAsString) {
QString numberString = amountAsString;
numberString.remove(QRegularExpression(R"([^\очка])"));
numberString.replace("точка", ".");
double amount = numberString.toDouble();
if (amountAsString.startsWith("-")) {
amount *= -1;
}
return amount;
}
QDomElement findElementWithListView(const QDomElement &parent) {
QDomElement element = parent.firstChildElement();
while (!element.isNull()) {
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
if (child.hasAttribute("class") && child.attribute("class") == "android.widget.ListView") {
return child;
}
child = child.nextSiblingElement();
}
QDomElement found = findElementWithListView(element);
if (!found.isNull()) {
return found;
}
element = element.nextSiblingElement();
}
return {};
}
QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayReportHistory() {
QList<TransactionInfo> transactions;
QDomElement child = findElementWithListView(m_xml);
QDomNodeList listView = findElementWithListView(m_xml).childNodes();
qDebug() << listView.count();
if (!listView.isEmpty()) {
QString date;
for (QDomNode node: listView) {
if (node.hasChildNodes()) {
QString text;
if (node.childNodes().count() > 1) {
date = node.firstChildElement().attribute("text");
text = node.lastChildElement().attribute("text");
} else if (node.childNodes().count() == 1) {
text = node.firstChildElement().attribute("text");
}
TransactionInfo transaction;
if (text.startsWith("Перевод")) {
QRegularExpression re(R"([+-] \d{1,3}(?: \d{3})* точка \d{2} Рубль$)");
QRegularExpressionMatch match = re.match(text);
if (match.hasMatch()) {
QString amount = match.captured(0);
transaction.amount = parseAmount(amount.trimmed());
text.chop(amount.length());
}
transaction.description = text.trimmed();
parseTransferInfo(text, transaction);
if (transaction.bankTime.isEmpty()) {
transaction.bankTime = transformBankDateTime(date);
}
} else {
// карта
if (text.contains("без учета комиссии")) {
QRegularExpression re(R"( без учета комиссии -\d{1,3}(?: \d{3})* точка \d{2} Рубль$)");
QRegularExpressionMatch match = re.match(text);
if (match.hasMatch()) {
QString fee = match.captured(0);
text.chop(fee.length());
transaction.fee = parseAmount(fee.replace("без учета комиссии", "").trimmed());
}
}
QRegularExpression re(R"([+-] \d{1,3}(?: \d{3})* точка \d{2} Рубль$)");
QRegularExpressionMatch match = re.match(text);
if (match.hasMatch()) {
QString amount = match.captured(0);
transaction.amount = parseAmount(amount.trimmed());
text.chop(amount.length());
}
transaction.description = text.trimmed();
if (transaction.bankTime.isEmpty()) {
transaction.bankTime = transformBankDateTime(date);
}
}
transactions.append(transaction);
}
}
} else {
qDebug() << "ListView is empty";
}
return transactions;
}
QList<TransactionInfo> ScreenXmlParser::parseTodayAndYesterdayHistory() {
QDate today = DateUtils::getMoscowNow().date();
QDate yesterday = today.addDays(-1);
QDate beforeYesterday = today.addDays(-2);
QString todayTitle = QString("сегодня, %1").arg(getDayOfWeekAsString(today.dayOfWeek()));
QString yesterdayTitle = QString("вчера, %1").arg(getDayOfWeekAsString(yesterday.dayOfWeek()));
QString beforeYesterdayTitle = QString("%1 %2, %3").arg(
QString::number(beforeYesterday.day()),
getMonthAsString(beforeYesterday.month()),
getDayOfWeekAsString(beforeYesterday.dayOfWeek())
);
QDomNode todayNode = findNode(m_xml, todayTitle);
QDomNode yesterdayNode = findNode(m_xml, yesterdayTitle);
QDomNode parentNode;
if (!yesterdayNode.isNull()) {
parentNode = yesterdayNode.parentNode();
} else if (!todayNode.isNull()) {
parentNode = todayNode.parentNode();
}
QList<TransactionInfo> transactions;
if (!parentNode.isNull()) {
QDate date = {};
for (QDomNode transactionNode: parentNode.childNodes()) {
QString transactionShortText = transactionNode.toElement().attribute("text");
const QString titleLowerCase = transactionShortText.toLower();
if (titleLowerCase.startsWith(beforeYesterdayTitle)) {
// только сегодня и вчера парсим, позавчера не трогаем
break;
}
if (titleLowerCase.startsWith(todayTitle)) {
date = today;
transactionShortText = transactionShortText.mid(todayTitle.length() + 1);
}
if (titleLowerCase.startsWith(yesterdayTitle)) {
date = yesterday;
transactionShortText = transactionShortText.mid(yesterdayTitle.length() + 1);
}
if (transactionShortText.contains("ЕСПП")) {
continue;
}
float amount = extractAmounts(transactionShortText);
QString shortDesc = beforeAmount(transactionShortText);
TransactionInfo info;
info.amount = amount;
info.bankTime = date.toString("dd.MM.yyyy");
info.description = shortDesc;
transactions.append(info);
}
}
return transactions;
}
void parse2daysHistory(const QDomNode &node) {
QDate today = DateUtils::getMoscowNow().date();
QDate tomorrow = today.addDays(-1);
QDate after2Days = today.addDays(-2);
QString todayTitle = QString("сегодня, %1").arg(getDayOfWeekAsString(today.dayOfWeek()));
QDomNode todayNode = findNode(node, todayTitle);
if (todayNode.isNull()) {
} else {
qDebug() << "todayNode: " << todayNode.toElement().attribute("text");
}
QString tomorrowTitle = QString("вчера, %1").arg(getDayOfWeekAsString(tomorrow.dayOfWeek()));
QDomNode tomorrowNode = findNode(node, tomorrowTitle);
if (tomorrowNode.isNull()) {
} else {
qDebug() << "tomorrowNode: " << tomorrowNode.toElement().attribute("text");
}
// 30 апреля, Среда
QString after2DaysTitle = QString("%1 %2, %3").arg(
QString::number(after2Days.day()),
getMonthAsString(after2Days.month()),
getDayOfWeekAsString(after2Days.dayOfWeek()));
QDomNode after2DaysNode = findNode(node, after2DaysTitle);
if (after2DaysNode.isNull()) {
qDebug() << "No after2DaysNode";
} else {
qDebug() << "after2DaysNode: " << after2DaysNode.toElement().attribute("text");
}
QDomNode parentNode;
if (!todayNode.isNull() || !tomorrowNode.isNull() || !after2DaysNode.isNull()) {
if (!todayNode.isNull()) {
parentNode = todayNode.parentNode();
}
if (!tomorrowNode.isNull()) {
parentNode = tomorrowNode.parentNode();
}
if (!after2DaysNode.isNull()) {
parentNode = after2DaysNode.parentNode();
}
}
if (!parentNode.isNull()) {
for (QDomNode child_node: parentNode.childNodes()) {
QString child_text = child_node.toElement().attribute("text");
if (child_text.toLower().startsWith(todayTitle)) {
qDebug() << "=== Today: " << todayTitle;
qDebug() << "node: " << beforeAmount(child_text.mid(todayTitle.length() + 1));
qDebug() << "--> sum: " << QString::number(extractAmounts(child_text), 'f', 2);
// qDebug() << "";
continue;
}
if (child_text.toLower().startsWith(tomorrowTitle)) {
qDebug() << "=== Yesterday: " << todayTitle;
qDebug() << "node: " << beforeAmount(child_text.mid(tomorrowTitle.length() + 1));
qDebug() << "--> sum: " << QString::number(extractAmounts(child_text), 'f', 2);
// qDebug() << "";
continue;
}
if (child_text.toLower().startsWith(after2DaysTitle)) {
qDebug() << "=== Before yesterday: " << todayTitle;
qDebug() << "node: " << beforeAmount(child_text.mid(after2DaysTitle.length() + 1));
qDebug() << "--> sum: " << QString::number(extractAmounts(child_text), 'f', 2);
// qDebug() << "";
continue;
}
qDebug() << "node: " << beforeAmount(child_node.toElement().attribute("text"));
qDebug() << "--> sum: " <<
QString::number(extractAmounts(child_node.toElement().attribute("text")), 'f', 2);
// qDebug() << "";
}
}
// QString d = today.day() > 9 ? QString::number(today.day()) : "0" + QString::number(today.day());
// QString m = today.month() > 9 ? QString::number(today.month()) : "0" + QString::number(today.month());
// QString y = QString::number(today.year());
// QString w = getDayOfWeekAsString(today.dayOfWeek());
// QString mm = getMonthAsString(today.month());
// qDebug() << "Date:" << d << m << y << w << mm;
// QString d2 = after2Days.day() > 9 ? QString::number(after2Days.day()) : "0" + QString::number(after2Days.day());
// QString m2 = after2Days.month() > 9
// ? QString::number(after2Days.month())
// : "0" + QString::number(after2Days.month());
// QString y2 = QString::number(after2Days.year());
// QString w2 = getDayOfWeekAsString(after2Days.dayOfWeek());
// QString mm2 = getMonthAsString(after2Days.month());
// qDebug() << "Date:" << d2 << m2 << y2 << w2 << mm2;
}
TransactionInfo parseExpandedInfoHistory(const QDomElement &root) {
if (root.isElement()) {
QDomElement elem = root.toElement();
if (elem.tagName() == "node"
&& elem.attribute("class") == "android.widget.Button"
&& elem.attribute("text") == "Детали операции"
) {
TransactionInfo transaction;
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int i = 0; i < detailInfo.count(); ++i) {
QDomNode info = detailInfo.at(i);
if (!info.isElement()) continue;
switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) {
case 2:
// Дата операции
transaction.bankTime = transformBankDateTime(findSubInfo(e, "1"));
break;
case 5:
transaction.description = findSubInfo(e, "1");
parseTransferInfo(transaction.description, transaction);
break;
case 7:
// Комиссия
transaction.fee = findSubInfo(e, "1").remove(onlyDigitsRegex).toFloat();
break;
default:
// qDebug() << "Прочее:" << findSubInfo(e);
break;
}
}
return transaction;
}
}
// Рекурсивно обходим всех детей
QDomNode child = root.firstChild();
while (!child.isNull()) {
if (TransactionInfo info = parseExpandedInfoHistory(child.toElement()); !info.bankTime.isEmpty()) {
return info;
}
child = child.nextSibling();
}
return {};
}
TransactionInfo ScreenXmlParser::parseTransactionInfoHistory(int screenWidth, int screenHeight) {
// 1. Распарсить описание транзакции
TransactionInfo transaction = parseExpandedInfoHistory(m_xml);
// 1. Найти статус: Исполнен | Операция исполнена
transaction.status = TransactionStatus::Wait;
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
if (!status1.isEmpty() || !status2.isEmpty()) {
transaction.status = TransactionStatus::Complete;
}
return transaction;
}
TransactionInfo parseExpandedInfo(const QDomElement &root) {
if (root.isElement()) {
QDomElement elem = root.toElement();
if (elem.tagName() == "node"
&& elem.attribute("class") == "android.widget.Button"
&& elem.attribute("text") == "Детали операции"
) {
TransactionInfo transaction;
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int i = 0; i < detailInfo.count(); ++i) {
QDomNode info = detailInfo.at(i);
if (!info.isElement()) continue;
QDomElement infoElement = info.toElement();
QString index = infoElement.attribute("index");
QDomElement ee;
switch (index.toInt()) {
case 3:
transaction.bankTime = transformBankDateTime(findSubInfo(infoElement, "1"));
break;
case 4:
ee = findSubElement(infoElement, "0");
ee = findSubElement(ee, "1");
transaction.phone = findSubInfo(ee, "0").remove(onlyDigitsRegex);
break;
case 5:
transaction.name = findSubInfo(infoElement, "1");
break;
case 6:
transaction.bankName = findSubInfo(infoElement, "1");
break;
case 9:
transaction.fee = findSubInfo(infoElement, "1").remove(onlyDigitsAndDotRegex).toFloat();
break;
case 10:
ee = findSubElement(infoElement, "1");
transaction.bankTrExternalId = findSubInfo(ee, "1");
break;
default:
break;
}
}
return transaction;
}
}
// Рекурсивно обходим всех детей
QDomNode child = root.firstChild();
while (!child.isNull()) {
if (TransactionInfo info = parseExpandedInfo(child.toElement()); !info.bankTime.isEmpty()) {
return info;
}
child = child.nextSibling();
}
return {};
}
TransactionInfo ScreenXmlParser::parseTransactionInfo(int screenWidth, int screenHeight) {
// 1. Распарсить описание транзакции
TransactionInfo transaction = parseExpandedInfo(m_xml);
// 1. Найти статус: Исполнен | Операция исполнена
transaction.status = TransactionStatus::Wait;
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
if (!status1.isEmpty() || !status2.isEmpty()) {
transaction.status = TransactionStatus::Complete;
}
return transaction;
}
QList<QPair<AccountInfo, Node> > ScreenXmlParser::parseAccountsInfo() {
QList<QPair<AccountInfo, Node> > accounts;
for (const Node &node: m_nodes) {
const QString text = node.text;
// Проверяем только нужные строки
if (!text.contains("Номер карты с последними цифрами")) {
continue;
}
QRegularExpressionMatch match = reCardData.match(text);
if (!match.hasMatch()) {
continue;
}
AccountInfo info;
info.lastNumbers = match.captured(1).remove(" ");
info.amount = match.captured(2).remove(" ").toFloat();
info.description = text.mid(0, text.indexOf("Номер карты"));
info.updateTime = DateUtils::getUtcNow();
accounts.append(qMakePair(info, node));
}
return accounts;
}
void ScreenXmlParser::test() {
// TransactionInfo info2 = parseExpandedInfo(m_xml);
// qDebug().noquote().nospace() << convertTransactionToString(info2);
// return;
QFile file("assets/rshb/all_products.xml");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Cannot open file";
}
QDomDocument doc;
if (!doc.setContent(&file)) {
qDebug() << "Failed to parse XML";
}
file.close();
qDebug() << "Start parsing XML:";
// Номер карты с последними цифрами
QDomElement root = doc.documentElement();
parseAndSaveXml(doc.toString());
// for (const AccountInfo &info: parseAccountsInfo()) {
// qDebug().noquote().nospace() << convertAccountToString(info);
// }
// TransactionInfo info = parseExpandedInfo(root);
// qDebug().noquote().nospace() << convertTransactionToString(info);
// ЕСПП
}
} // namespace Rshb

View File

@ -1,61 +0,0 @@
#pragma once
#include <QObject>
#include <QDomElement>
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
namespace Rshb {
class ScreenXmlParser final : public QObject {
Q_OBJECT
public:
explicit ScreenXmlParser(QObject *parent = nullptr);
~ScreenXmlParser() override;
Node tryToFindBannerOrDialog(int width, int height);
Node tryToFindSecurityBanner();
Node tryToFindSelectBottomSheet();
Node findTextNode(const QString &text);
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
Node findFirstEditText();
Node findButtonNode(const QString &text, bool contains);
bool isHomeScreen();
QList<Node> tryToFindPinCode(const QString &pinCode, const QString &title);
QList<Node> getLast2DaysTransactions();
void parseAndSaveXml(const QString &xml);
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
QList<TransactionInfo> parseTodayAndYesterdayReportHistory();
QList<TransactionInfo> parseTodayAndYesterdayHistory();
QList<QPair<AccountInfo, Node> > parseAccountsInfo();
void test();
private:
QList<Node> m_nodes;
QDomElement m_xml;
QList<Node> findPinCodeNodes(const QString &pinCode);
};
} // namespace Rshb

View File

@ -1,19 +0,0 @@
#include "SyncAccountDataScript.h"
namespace Rshb {
SyncAccountDataScript::SyncAccountDataScript(
QString deviceId,
QObject *parent
) : CommonScript(parent),
m_deviceId(std::move(deviceId)) {
}
SyncAccountDataScript::~SyncAccountDataScript() = default;
void SyncAccountDataScript::doStart() {
// 1.
}
} // namespace Rshb

View File

@ -1,24 +0,0 @@
#pragma once
#include "CommonScript.h"
namespace Rshb {
class SyncAccountDataScript final : public CommonScript {
Q_OBJECT
public:
~SyncAccountDataScript() override;
explicit SyncAccountDataScript(
QString deviceId,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const QString m_deviceId;
};
} // namespace Rshb

View File

@ -1,217 +0,0 @@
#include "CommonTossScript.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include "adb/AdbUtils.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
CommonTossScript::CommonTossScript(QObject *parent)
: QObject(parent) {
}
CommonTossScript::~CommonTossScript() = default;
void CommonTossScript::start() {
doStart();
emit finished();
}
Node CommonTossScript::swipeToButton(
const QString &deviceId,
const QString &text, int &counter, const int width, const int height
) {
for (int i = 0; i < 10; ++i) {
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
return button;
}
const int x = width / 2;
const int offset = height / 4;
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
return {};
}
bool CommonTossScript::runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
const int width,
const int height
) {
// Запустить устройство
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
qDebug() << "Process already running, pid: " << pid;
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
AdbUtils::tryToKillApplication(deviceId, packageName);
}
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
AdbUtils::takeScreenshot(deviceId, "run_app_error");
qWarning() << "Process has not started";
return false;
}
// Даем минимальное время на запуск
QThread::msleep(2500);
int counter = 0;
bool findAndInputPincode = false;
while (true) {
counter++;
// Если более 10 раз мы пытаемся перейти на домашнюю
if (counter > 10) {
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
return false;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
// Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
// if (!closeBannerNode.isEmpty()) {
// AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
// QThread::msleep(1000);
// continue;
// }
if (xmlScreenParser.isHomeScreen()) {
return true;
}
// Проверяем, что это экран ввода пин-кода
if (!findAndInputPincode) {
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(pinCode); pincode.size() == 6) {
for (const Node &node: pincode) {
AdbUtils::makeTap(deviceId, node.x(), node.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
findAndInputPincode = true;
QThread::msleep(3000);
continue;
}
}
QThread::msleep(1000);
}
}
bool CommonTossScript::goToAllProducts(
const QString &deviceId,
const int width,
const int height
) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(500);
}
if (xmlScreenParser.isHomeScreen()) {
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
if (!allMyAccountBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
QThread::msleep(500);
return true;
}
}
return false;
}
void CommonTossScript::postAccountsData(const QList<AccountInfo> &accounts) {
if (accounts.isEmpty()) {
return;
}
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonArray list;
for (const AccountInfo &account: accounts) {
QJsonObject obj;
obj["appName"] = account.appCode;
obj["lastNumbers"] = account.lastNumbers;
obj["amount"] = account.amount;
obj["currency"] = account.currency;
obj["description"] = account.description;
obj["status"] = accountStatusToString(account.status);
list.append(obj);
}
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(accounts.first().deviceId);
worker->setPayload(QJsonDocument(list).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonTossScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transaction.id;
obj["amount"] = transaction.amount;
obj["name"] = transaction.name;
obj["fee"] = transaction.fee;
obj["status"] = transactionStatusToString(transaction.status);
obj["type"] = transactionTypeToString(transaction.type);
obj["phone"] = transaction.phone;
obj["description"] = transaction.description + " | " + transaction.bankTime;
obj["updatedDescription"] = transaction.updatedDescription;
obj["bankName"] = transaction.bankName;
obj["bankTime"] = DateUtils::toUtcString(transaction.completeTime);
obj["bankTransactionId"] = transaction.bankTrExternalId;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->addExtra("transactionId", transaction.id);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonTossScript::updateTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transactionId;
obj["status"] = transactionStatusToString(status);
obj["description"] = newDesc;
obj["updatedDescription"] = oldDesc;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonTossScript::stop() {
m_running = false;
}

View File

@ -1,68 +0,0 @@
#pragma once
#include <QObject>
#include "ScreenXmlTossParser.h"
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
class CommonTossScript : public QObject {
Q_OBJECT
public:
explicit CommonTossScript(QObject *parent = nullptr);
~CommonTossScript() override;
protected:
virtual void doStart() = 0;
bool goToAllProducts(
const QString &deviceId,
int width,
int height
);
void postAccountsData(const QList<AccountInfo> &accounts);
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
void updateTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
Node swipeToButton(
const QString &deviceId,
const QString &text,
int &counter, int width, int height
);
bool runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
int width,
int height
);
bool m_running = true;
ScreenXmlTossParser xmlScreenParser;
int m_counter = 0;
signals:
void finished();
void finishedWithResult(const QString &result);
public slots:
virtual void start() final;
virtual void stop() final;
private:
Q_DISABLE_COPY(CommonTossScript);
};

View File

@ -1,160 +0,0 @@
#include "GetLastDaysHistoryTossScript.h"
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/DeviceInfo.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
GetLastDaysHistoryTossScript::GetLastDaysHistoryTossScript(
AccountInfo account,
QObject *parent
) : CommonTossScript(parent),
m_account(std::move(account)) {
}
GetLastDaysHistoryTossScript::~GetLastDaysHistoryTossScript() = default;
bool GetLastDaysHistoryTossScript::saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
) {
TransactionInfo tr;
tr.accountId = account.id;
tr.description = transaction.description;
tr.bankTime = transaction.bankTime;
tr.bankName = transaction.bankName;
tr.amount = transaction.amount;
tr.phone = transaction.phone;
tr.updateTime = DateUtils::getUtcNow();
tr.fee = transaction.fee;
tr.name = transaction.name;
tr.bankTrExternalId = transaction.bankTrExternalId;
tr.status = status;
tr.type = TransactionType::Card;
tr.completeTime = transaction.completeTime;
tr.id = TransactionDAO::insertTransaction(tr);
if (tr.id == -1) {
return false;
}
postNewTransactionData(account, tr);
return true;
}
bool GetLastDaysHistoryTossScript::updateAndPostTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
return true;
}
return false;
}
void GetLastDaysHistoryTossScript::doStart() {
// берем все транзакции из БД
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (xmlScreenParser.isHomeScreen()) {
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
QMap<QString, AccountInfo> accountMap;
for (AccountInfo &oldAccount: oldAccounts) {
if (oldAccount.status == AccountStatus::Active) {
accountMap.insert(oldAccount.lastNumbers, oldAccount);
}
}
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
if (accounts.length() == 1 && accountMap.size() == 1) {
AccountInfo account = accounts[0];
account.deviceId = m_account.deviceId;
account.appCode = m_account.appCode;
account.lastNumbers = accountMap.first().lastNumbers;
account.description = accountMap.first().description;
account.currency = accountMap.first().currency;
account.description = accountMap.first().description;
account.status = AccountStatus::Active;
if (!AccountDAO::upsertAccount(account)) {
m_error = "Not updated: " + account.lastNumbers;
qCritical() << m_error;
}
}
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_account.deviceId, m_account.appCode);
postAccountsData(savedAccounts);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node transferText = xmlScreenParser.findFirstAccountLine();
if (!transferText.isEmpty()) {
AdbUtils::makeTap(device.id, transferText.x(), transferText.y());
QThread::msleep(3000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
for (int i = 0; i < 5; ++i) {
Node myBankText = xmlScreenParser.findTextNode("My Toss Bank");
Node accountText = xmlScreenParser.findTextNode("Account");
if (!myBankText.isEmpty() && !accountText.isEmpty()) {
QList<TransactionInfo> transactions = xmlScreenParser.parsePositiveTransactions();
QList<TransactionInfo> savedTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
for (TransactionInfo &transaction: transactions) {
bool isSaved = false;
for (TransactionInfo &savedTransaction: savedTransactions) {
if (savedTransaction.amount == transaction.amount
&& savedTransaction.bankTime == transaction.bankTime) {
isSaved = true;
break;
}
}
if (!isSaved) {
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
qDebug() << "--- saveAndPostNewTransactionData failed";
}
}
}
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId , ++m_counter));
}
} else {
m_error = "Card not found: " + m_account.deviceId + " " + m_account.lastNumbers;
qWarning() << m_error;
emit finishedWithResult(m_error);
return;
}
}
AdbUtils::goBack(m_account.deviceId);
emit finishedWithResult(m_error);
}

View File

@ -1,35 +0,0 @@
#pragma once
#include "CommonTossScript.h"
class GetLastDaysHistoryTossScript final : public CommonTossScript {
Q_OBJECT
public:
~GetLastDaysHistoryTossScript() override;
explicit GetLastDaysHistoryTossScript(
AccountInfo account,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
QString m_error;
bool saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
);
bool updateAndPostTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
};

View File

@ -1,379 +0,0 @@
#include "LoginAndCheckAccountsTossScript.h"
#include <QRandomGenerator>
#include <QThread>
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "time/DateUtils.h"
LoginAndCheckAccountsTossScript::LoginAndCheckAccountsTossScript(
QString deviceId,
QString appCode,
QObject *parent
) : CommonTossScript(parent),
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
}
LoginAndCheckAccountsTossScript::~LoginAndCheckAccountsTossScript() = default;
/**
NongHyup
KakaoBank
Kookmin
Toss Bank
Shinhan
Woori
IBK
Hana
MG
Busan Bank
iM Bank(Daegu)
Kbank
Credit Union
Postal Sav.
SC
Kyongnam
Kwangju
Suhyup
Jeonbuk
Savings Banks
Jeju Bank
Jeonbuk
Savings Banks
Jeju Bank
Citibank
KDB
NFCF
SBI Sav.
BOA
Bank of China
HSBC
ICBC
Deutsche
JPMorgan
BNP Paribas
CCB
*/
void LoginAndCheckAccountsTossScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
if (true) {
if (true) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
auto accounts = xmlScreenParser.parseAccountsInfo();
if (!accounts.empty()) {
qDebug() << "--- Finish, amount: " << QString::number(accounts[0].amount);
}
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
// находим первую кнопку Transfer
Node transferText = xmlScreenParser.findButtonNode("Transfer", false);
if (!transferText.isEmpty()) {
AdbUtils::makeTap(m_deviceId, transferText.x(), transferText.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node enterAmount = xmlScreenParser.findEditText("Enter account number");
if (!enterAmount.isEmpty()) {
AdbUtils::makeTap(m_deviceId, enterAmount.x(), enterAmount.y());
QThread::msleep(200);
AdbUtils::inputText(m_deviceId, "51291082442507");
QThread::msleep(200);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node inputBank = xmlScreenParser.findNodeByClassName("android.widget.Spinner");
if (!inputBank.isEmpty()) {
AdbUtils::makeTap(m_deviceId, inputBank.x(), inputBank.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
bool foundBank = false;
for (int i = 0; i < 5; ++i) {
Node bank = xmlScreenParser.findTextNode("Hana");
if (!bank.isEmpty()) {
AdbUtils::makeTap(m_deviceId, bank.x(), bank.y());
QThread::msleep(200);
foundBank = true;
break;
} else {
AdbUtils::makeSwipe(
m_deviceId,
device.screenWidth / 2, device.screenHeight / 4 * 3,
device.screenWidth / 2, device.screenHeight / 2
);
QThread::msleep(500);
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
if (!foundBank) {
m_error = "Bank not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node confirmTransfer = xmlScreenParser.findButtonNode("Confirm", false);
if (!confirmTransfer.isEmpty()) {
AdbUtils::makeTap(m_deviceId, confirmTransfer.x(), confirmTransfer.y());
QThread::msleep(3000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
bool enterAmountFound = false;
for (int i = 0; i < 10; ++i) {
Node enterAmountText = xmlScreenParser.findTextNode("Enter amount");
if (!enterAmountText.isEmpty()) {
// AdbUtils::makeTap(m_deviceId, enterAmountText.x(), enterAmountText.y());
// QThread::msleep(500);
enterAmountFound = true;
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
if (!enterAmountFound) {
m_error = "Enter amount not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node closeBtn = xmlScreenParser.findButtonNode("확인", false);
if (!closeBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, closeBtn.x(), closeBtn.y());
QThread::msleep(200);
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
for (Node &number: xmlScreenParser.getNodeNumbers(4)) {
AdbUtils::makeTap(m_deviceId, number.x(), number.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
// AdbUtils::inputText(m_deviceId, "2");
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node nextBtn = xmlScreenParser.findButtonNode("Next", false);
if (!nextBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, nextBtn.x(), nextBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node sendBtn = xmlScreenParser.findButtonNode("Send", false);
if (!sendBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, sendBtn.x(), sendBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(
AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
Node sendAgainBtn = xmlScreenParser.findButtonNode("Send", false);
if (!sendAgainBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, sendAgainBtn.x(), sendAgainBtn.y());
QThread::msleep(1000);
}
bool findAndInputPincode = false;
xmlScreenParser.parseAndSaveXml(
AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(app.pinCode);
pincode.size() == 6) {
for (const Node &node: pincode) {
AdbUtils::makeTap(m_deviceId, node.x(), node.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
findAndInputPincode = true;
QThread::msleep(2000);
}
if (!findAndInputPincode) {
m_error = "Pincode not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(
AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
bool foundConfirmBtn = false;
for (int i = 0; i < 5; ++i) {
Node confirmBtn = xmlScreenParser.findButtonNode("Confirm", false);
if (!confirmBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, confirmBtn.x(), confirmBtn.y());
foundConfirmBtn = true;
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
if (!foundConfirmBtn) {
m_error = "Last Confirm button not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
for (int i = 0; i < 10; ++i) {
Node lastBtn = xmlScreenParser.findTextNode("닫기");
Node lastBtn2 = xmlScreenParser.findTextNode("Close");
if (!lastBtn.isEmpty()) {
AdbUtils::makeTap(m_deviceId, lastBtn.x(), lastBtn.y());
break;
}
if (!lastBtn2.isEmpty()) {
AdbUtils::makeTap(m_deviceId, lastBtn2.x(), lastBtn2.y());
break;
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
qDebug() << "--- Finish: " << xmlScreenParser.parseAccountAmount();
}
} else {
m_error = "Next button not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Confirm transfer button not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Input bank not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Enter account number not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
m_error = "Transfer button not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
} else {
// "Maraqlı deyil" - не интересно
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
} else {
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
Node mainAccount = xmlScreenParser.findTextContainsNode("Main account");
if (!mainAccount.isEmpty()) {
// AdbUtils::makeTap(device.id, mainAccount.x(), mainAccount.y());
// QThread::msleep(1000);
// for (int i = 0; i < 5; ++i) {
// xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
// Node mainAccount = xmlScreenParser.findTextContainsNode("Main account");
// if (!byDayTitle.isEmpty()) {
// qWarning() << "--- beforeYesterdayTitle found!";
// break;
// }
// AdbUtils::makeSwipe(
// m_account.deviceId,
// device.screenWidth / 2, device.screenHeight / 4 * 3,
// device.screenWidth / 2, device.screenHeight / 4
// );
// QThread::msleep(1000);
//
// }
}
QThread::msleep(2000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
QList<AccountInfo> oldAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
QMap<QString, AccountInfo> accountMap;
for (AccountInfo &oldAccount: oldAccounts) {
if (oldAccount.status == AccountStatus::Active) {
accountMap.insert(oldAccount.lastNumbers, oldAccount);
}
}
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
if (accounts.length() == 1 && accountMap.size() == 1) {
AccountInfo account = accounts[0];
account.deviceId = m_deviceId;
account.appCode = m_appCode;
account.lastNumbers = accountMap.first().lastNumbers;
account.description = accountMap.first().description;
account.currency = accountMap.first().currency;
account.description = accountMap.first().description;
account.status = AccountStatus::Active;
if (!AccountDAO::upsertAccount(account)) {
m_error = "Not updated: " + account.lastNumbers;
qCritical() << m_error;
}
}
// for (auto account: accounts) {
// if (accountMap.contains(account.lastNumbers)) {
// account.deviceId = m_deviceId;
// account.appCode = m_appCode;
// account.currency = accountMap[account.lastNumbers].currency;
// account.description = accountMap[account.lastNumbers].description;
// account.status = AccountStatus::Active;
// if (!AccountDAO::upsertAccount(account)) {
// m_error = "Not updated: " + account.lastNumbers;
// qCritical() << m_error;
// }
// }
// }
QList<AccountInfo> savedAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
postAccountsData(savedAccounts);
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
}
emit finishedWithResult(m_error);
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "CommonTossScript.h"
class LoginAndCheckAccountsTossScript final : public CommonTossScript {
Q_OBJECT
public:
~LoginAndCheckAccountsTossScript() override;
explicit LoginAndCheckAccountsTossScript(
QString deviceId,
QString appCode,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const QString m_deviceId;
const QString m_appCode;
QString m_error;
};

View File

@ -1,350 +0,0 @@
#include "PayByCardTossScript.h"
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/ApplicationInfo.h"
#include "db/DeviceInfo.h"
#include "time/DateUtils.h"
PayByCardTossScript::PayByCardTossScript(
AccountInfo account,
QString iban,
QString fullName,
const double amount,
QObject *parent
) : CommonTossScript(parent),
m_account(std::move(account)),
m_fullName(std::move(fullName)), m_amount(amount) {
}
PayByCardTossScript::~PayByCardTossScript() = default;
void PayByCardTossScript::makePayment(const DeviceInfo &device) {
// Оплата со страницы карты
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node editIbanEditText = xmlScreenParser.findEditTextByResourceId("com.Toss.Tossmobil:id/edit_iban");
Node fullNameEditText = xmlScreenParser.findEditTextByResourceId("com.Toss.Tossmobil:id/edit_full_name");
if (!editIbanEditText.isEmpty() && !fullNameEditText.isEmpty()) {
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
QThread::msleep(500);
// AdbUtils::inputText(device.id, m_iban);
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, m_fullName);
Node nextBtn = xmlScreenParser.findButtonNode("NEXT", false);
AdbUtils::makeTap(device.id, nextBtn.x(), nextBtn.y());
bool findSenderAccount = false;
for (int i = 0; i < 5; ++i) {
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node senderAccount = xmlScreenParser.findTextNode("Sender Account");
if (!senderAccount.isEmpty()) {
// Node inputBankName = xmlScreenParser.findAccountButton(m_account.lastNumbers);
// if (!inputBankName.isEmpty()) {
// AdbUtils::makeTap(device.id, inputBankName.x(), inputBankName.y());
// QThread::msleep(500);
// // FXIME скорее всего придется нажать кнопку NEXT
// findSenderAccount = true;
// }
break;
}
}
if (!findSenderAccount) {
m_error = "Не нашли Sender Account";
qDebug() << m_error;
return;
}
bool findAmountDetermination = false;
for (int i = 0; i < 5; ++i) {
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node amountDetermination = xmlScreenParser.findTextNode("Amount Determination");
if (!amountDetermination.isEmpty()) {
Node integerEditText = xmlScreenParser.findEditTextByResourceId(
"com.Toss.Tossmobil:id/edit_text_integer");
Node decimalEditText = xmlScreenParser.findEditTextByResourceId(
"com.Toss.Tossmobil:id/edit_text_decimal");
if (!integerEditText.isEmpty() && !decimalEditText.isEmpty()) {
int integerPart = static_cast<int>(m_amount);
AdbUtils::makeTap(device.id, integerEditText.x(), integerEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, QString::number(integerPart));
int decimalPart = static_cast<int>((m_amount - integerPart) * 100);
AdbUtils::makeTap(device.id, decimalEditText.x(), decimalEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, QString::number(decimalPart));
findAmountDetermination = true;
break;
} else {
m_error = "Не нашли поля ввода для ввода суммы перевода";
qDebug() << m_error;
return;
}
}
}
if (!findAmountDetermination) {
m_error = "Не нашли Amount Determination";
qDebug() << m_error;
return;
}
bool findDetailDefinition = false;
for (int i = 0; i < 5; ++i) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node fastTransferBtn = xmlScreenParser.findButtonNode("FAST TRANSFER", false);
if (!fastTransferBtn.isEmpty()) {
AdbUtils::makeTap(device.id, fastTransferBtn.x(), fastTransferBtn.y());
QThread::msleep(500);
continue;
}
Node detailDefinitionTitle = xmlScreenParser.findTextNode("Detail Definition");
Node pleaseChooseBtn = xmlScreenParser.findButtonNode("Please choose", false);
if (!detailDefinitionTitle.isEmpty() && !pleaseChooseBtn.isEmpty()) {
AdbUtils::makeTap(device.id, pleaseChooseBtn.x(), pleaseChooseBtn.y());
QThread::msleep(500);
Node searchEditText = xmlScreenParser.
findEditTextByResourceId("com.Toss.Tossmobil:id/input_search");
if (!searchEditText.isEmpty()) {
AdbUtils::makeTap(device.id, searchEditText.x(), searchEditText.y());
QThread::msleep(500);
// FIXME "Individual Payment" или "Other Payments" если нет одного, то надо другой
AdbUtils::inputText(device.id, "Other Payments");
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
if (!otherPaymentsText.isEmpty()) {
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
QThread::msleep(500);
findDetailDefinition = true;
break;
}
} else {
for (int i = 0; i < 5; ++i) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
if (otherPaymentsText.isEmpty()) {
AdbUtils::makeSwipe(
m_account.deviceId,
device.screenWidth / 2, device.screenHeight / 4 * 3,
device.screenWidth / 2, device.screenHeight / 4
);
} else {
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
QThread::msleep(500);
findDetailDefinition = true;
break;
}
QThread::msleep(500);
}
}
}
}
if (!findDetailDefinition) {
m_error = "Не нашли Detail Definition";
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node nextBtn4 = xmlScreenParser.findButtonNode("NEXT", false);
AdbUtils::makeTap(device.id, nextBtn4.x(), nextBtn4.y());
QThread::msleep(500);
Node checkInfo = xmlScreenParser.findTextNode(
"Check the details of the transaction you shall realize and approve your transaction.");
if (!checkInfo.isEmpty()) {
for (int i = 0; i < 5; ++i) {
Node confirmBtn = xmlScreenParser.findButtonNode("CONFIRM", false);
if (confirmBtn.isEmpty()) {
AdbUtils::makeSwipe(
m_account.deviceId,
device.screenWidth / 2, device.screenHeight / 4 * 3,
device.screenWidth / 2, device.screenHeight / 4
);
} else {
AdbUtils::makeTap(device.id, confirmBtn.x(), confirmBtn.y());
QThread::msleep(500);
break;
}
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node successText = xmlScreenParser.findTextNode("Your transaction is successfully realized.");
if (!successText.isEmpty()) {
Node receiptBtn = xmlScreenParser.findButtonNode("RECEIPT", false);
if (!receiptBtn.isEmpty()) {
AdbUtils::makeTap(device.id, receiptBtn.x(), receiptBtn.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node sendBtn = xmlScreenParser.findButtonNode("SEND E-MAIL", false);
if (!sendBtn.isEmpty()) {
AdbUtils::takeXmlDump(
device.id, "pay_by_iban_finish_transactions_" + QString::number(m_account.id)
);
// Успешная транзакция
// TODO считываем все данные по переводу
TransactionInfo transaction;
transaction.name = m_fullName;
transaction.accountId = m_account.id;
transaction.amount = -m_amount;
transaction.fee = 0;
transaction.status = TransactionStatus::Complete;
transaction.type = TransactionType::Iban;
transaction.updateTime = DateUtils::getUtcNow();
transaction.completeTime = DateUtils::getUtcNow();
transaction.timestamp = DateUtils::getUtcNow();
transaction.id = TransactionDAO::insertTransaction(transaction);
if (transaction.id == -1) {
// FIXME alert!!
qDebug() << "Transaction has not inserted...";
}
postNewTransactionData(m_account, transaction);
Node backBtn = xmlScreenParser.findButtonNode("BACK", false);
if (!backBtn.isEmpty()) {
AdbUtils::makeTap(device.id, backBtn.x(), backBtn.y());
QThread::msleep(500);
Node returnBtn = xmlScreenParser.findButtonNode("RETURN TO HOME PAGE", false);
if (!returnBtn.isEmpty()) {
AdbUtils::makeTap(device.id, returnBtn.x(), returnBtn.y());
}
}
} else {
//FIXME не успешная транзакция
AdbUtils::takeXmlDump(
device.id, "pay_by_iban_fail_transactions_receipt_" + QString::number(m_account.id)
);
m_error = "Транзакция не успешна";
qDebug() << m_error;
return;
}
}
} else {
m_error = "Транзакция не успешна";
qDebug() << m_error;
return;
}
} else {
m_error = "Не нашли Check the details title info";
qDebug() << m_error;
return;
}
} else {
m_error = "Не нашли поля ввода для IBAN";
qDebug() << m_error;
return;
}
}
void PayByCardTossScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found.";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node allTransactionsNav = xmlScreenParser.findTextNode("Transactions");
if (!allTransactionsNav.isEmpty()) {
AdbUtils::makeTap(device.id, allTransactionsNav.x(), allTransactionsNav.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
// перешли на страницу транзакций
Node allTransactionsTitle = xmlScreenParser.findTextNode(
"Transactions", 0, 0, device.screenWidth, device.screenHeight / 2
);
Node moneyTransfersBtn = xmlScreenParser.findTextNode("Money Transfers");
if (!allTransactionsTitle.isEmpty() && !moneyTransfersBtn.isEmpty()) {
AdbUtils::makeTap(device.id, moneyTransfersBtn.x(), moneyTransfersBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
// перешли на страницу переводов
Node moneyTransfersTitle = xmlScreenParser.findTextNode(
"Money Transfers", 0, 0, device.screenWidth, device.screenHeight / 2
);
Node transferToOtherAccountBtn = xmlScreenParser.findTextNode("Transfer to Other Account");
if (!moneyTransfersTitle.isEmpty() && !transferToOtherAccountBtn.isEmpty()) {
AdbUtils::makeTap(device.id, transferToOtherAccountBtn.x(), transferToOtherAccountBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node transferToOtherAccountTitle = xmlScreenParser.findTextNode(
"Transfer to Other Account", 0, 0, device.screenWidth, device.screenHeight / 2
);
Node aNewRecipientBtn = xmlScreenParser.findTextNode("A New Recipient");
if (!transferToOtherAccountTitle.isEmpty() && !aNewRecipientBtn.isEmpty()) {
AdbUtils::makeTap(device.id, aNewRecipientBtn.x(), aNewRecipientBtn.y());
QThread::msleep(1000);
makePayment(device);
} else {
m_error = "Не нашли кнопку 'A New Recipient'";
qDebug() << m_error;
}
} else {
m_error = "Не нашли кнопку 'Transfer to Other Account'";
qDebug() << m_error;
}
} else {
m_error = "Не нашли кнопку 'Money Transfers'";
qDebug() << m_error;
}
} else {
m_error = "Не нашли пункт меню 'Transactions'";
qDebug() << m_error;
}
if (!m_error.isEmpty()) {
AdbUtils::takeXmlDump(device.id, "pay_by_iban_fail_transactions_" + QString::number(m_account.id));
}
emit finishedWithResult(m_error);
}

View File

@ -1,30 +0,0 @@
#pragma once
#include "CommonTossScript.h"
#include "db/DeviceInfo.h"
class PayByCardTossScript final : public CommonTossScript {
Q_OBJECT
public:
~PayByCardTossScript() override;
PayByCardTossScript(
AccountInfo account,
QString CardToss,
QString fullName,
double amount,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
const QString m_CardToss;
const QString m_fullName;
const double m_amount;
QString m_error;
void makePayment(const DeviceInfo &device);
};

View File

@ -1,537 +0,0 @@
#include "ScreenXmlTossParser.h"
#include <QRegularExpression>
#include <QMap>
#include <QSet>
#include <QList>
#include <QXmlStreamReader>
#include <QDomDocument>
#include <QFile>
#include <QDateTime>
#include "adb/AdbUtils.h"
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
#include "time/DateUtils.h"
ScreenXmlTossParser::ScreenXmlTossParser(QObject *parent) : QObject(parent) {
}
ScreenXmlTossParser::~ScreenXmlTossParser() = default;
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
Node ScreenXmlTossParser::findTextNode(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
return node;
}
}
return {};
}
Node ScreenXmlTossParser::findTextContainsNode(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.contains(text)) {
return node;
}
}
return {};
}
Node ScreenXmlTossParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
return node;
}
}
return {};
}
Node ScreenXmlTossParser::findEditText(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.text == text) {
return node;
}
}
return {};
}
Node ScreenXmlTossParser::findEditTextByResourceId(const QString &resourceId) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.resourceId == resourceId) {
return node;
}
}
return {};
}
QList<Node> ScreenXmlTossParser::getNodeNumbers(double value) {
// Формат 'f' с precision = 0 — дробная часть отбрасывается
QString str = QString::number(value, 'f', 0);
// Разбиваем на отдельные символы
QList<Node> nodes;
for (QChar ch: str) {
QString num = QString(ch);
for (const Node &node: m_nodes) {
if (node.contentDesc == num && node.className == "android.widget.Button") {
nodes.append(node);
}
}
}
return nodes;
}
Node ScreenXmlTossParser::findNodeByClassName(const QString &className) {
for (const Node &node: m_nodes) {
if (node.className == className) {
return node;
}
}
return {};
}
Node ScreenXmlTossParser::findButtonNode(const QString &text, const bool contains) {
for (const Node &node: m_nodes) {
if (contains) {
if (node.className == "android.widget.Button" && node.text.contains(text)) {
return node;
}
} else {
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
return node;
}
}
}
return {};
}
bool ScreenXmlTossParser::isHomeScreen() {
Node activitiesBtn;
for (const Node &node: m_nodes) {
if (node.text.contains("Transfer") && node.resourceId == "viva.republica.toss:id/rightButton") {
activitiesBtn = node;
}
}
return !activitiesBtn.isEmpty();
}
QList<Node> ScreenXmlTossParser::findPinCodeNodes(const QString &pinCode) {
QMap<QString, Node> buttons;
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
for (const Node &node: m_nodes) {
const QString &text = node.text.trimmed();
if (node.className == "android.widget.Button" && numberSet.contains(text)) {
buttons[text] = node;
}
}
QList<Node> nodes;
for (int i = 0; i < pinCode.length(); ++i) {
nodes.append(buttons[QString(pinCode.at(i))]);
}
return nodes;
}
Node convertTossDomElementToNode(const QDomElement &element) {
auto node = Node();
if (element.hasAttribute("bounds")) {
const QString bounds = element.attribute("bounds");
if (const QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
node.setBounds(
match.captured(1).toInt(),
match.captured(2).toInt(),
match.captured(3).toInt(),
match.captured(4).toInt()
);
}
}
if (element.hasAttribute("text")) {
node.text = element.attribute("text");
}
if (element.hasAttribute("content-desc")) {
node.contentDesc = element.attribute("content-desc");
}
if (element.hasAttribute("class")) {
node.className = element.attribute("class");
}
if (element.hasAttribute("clickable")) {
node.clickable = element.attribute("clickable") == "true";
}
if (element.hasAttribute("focusable")) {
node.focusable = element.attribute("focusable") == "true";
}
if (element.hasAttribute("resource-id")) {
node.resourceId = element.attribute("resource-id");
}
return node;
}
void ScreenXmlTossParser::parseAndSaveXml(const QString &xml) {
QDomDocument doc;
doc.setContent(xml);
m_xml = doc.documentElement();
m_nodes.clear();
QXmlStreamReader reader(xml);
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement() && reader.name() == "node") {
Node node = Node();
if (reader.attributes().hasAttribute("bounds")) {
QString bounds = reader.attributes().value("bounds").toString();
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
node.setBounds(
match.captured(1).toInt(),
match.captured(2).toInt(),
match.captured(3).toInt(),
match.captured(4).toInt()
);
}
}
if (reader.attributes().hasAttribute("text")) {
node.text = reader.attributes().value("text").toString();
}
if (reader.attributes().hasAttribute("content-desc")) {
node.contentDesc = reader.attributes().value("content-desc").toString();
}
if (reader.attributes().hasAttribute("class")) {
node.className = reader.attributes().value("class").toString();
}
if (reader.attributes().hasAttribute("clickable")) {
node.clickable = reader.attributes().value("clickable").toString() == "true";
}
if (reader.attributes().hasAttribute("focusable")) {
node.focusable = reader.attributes().value("focusable").toString() == "true";
}
if (reader.attributes().hasAttribute("resource-id")) {
node.resourceId = reader.attributes().value("resource-id").toString();
}
m_nodes.append(node);
}
}
}
QDomElement findSubElementToss(const QDomElement &elem, const QString &index) {
if (elem.hasChildNodes()) {
QDomNodeList subInfoList = elem.childNodes();
for (QDomNode subInfoNode: subInfoList) {
if (!subInfoNode.isElement()) continue;
QDomElement subInfo = subInfoNode.toElement();
if (subInfo.attribute("index") == index) {
return subInfo;
}
}
}
return {};
}
QString findSubInfoToss(const QDomElement &elem, const QString &index) {
QDomElement subInfo = findSubElementToss(elem, index);
if (!subInfo.isNull()) {
return subInfo.attribute("text");
}
return "";
}
QDomNode findNodeToss(const QDomNode &node, const QString &text) {
if (node.isElement()) {
QString nodeText = node.toElement().attribute("text");
if (nodeText.toLower().startsWith(text)) {
return node;
}
}
QDomNode child = node.firstChild();
while (!child.isNull()) {
QDomNode result = findNodeToss(child, text);
if (!result.isNull()) {
return result;
}
child = child.nextSibling();
}
return {};
}
QList<QDomElement> findElementsWithPaymentsToss(const QDomElement &parent, const QString &attribute,
const QString &value) {
QList<QDomElement> result;
QDomElement element = parent.firstChildElement();
while (!element.isNull()) {
// Проверка самого element
// if (element.hasAttribute(attribute) && element.attribute(attribute) == value) {
// result.append(element);
// }
// Проверка его дочерних элементов
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
if (child.hasAttribute(attribute) && child.attribute(attribute) == value) {
result.append(child);
}
child = child.nextSiblingElement();
}
// Рекурсивный обход
result.append(findElementsWithPaymentsToss(element, attribute, value));
element = element.nextSiblingElement();
}
return result;
}
QDomElement findElementWithPaymentsToss(const QDomElement &parent, const QString &attribute, const QString &value) {
QDomElement element = parent.firstChildElement();
while (!element.isNull()) {
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
if (child.hasAttribute(attribute) && child.attribute(attribute) == value) {
return child;
}
child = child.nextSiblingElement();
}
QDomElement found = findElementWithPaymentsToss(element, attribute, value);
if (!found.isNull()) {
return found;
}
element = element.nextSiblingElement();
}
return {};
}
QDateTime getUtcFromSeoulDate(const QString &date, const QString &time) {
int year = QDate::currentDate().year(); // или укажи вручную нужный год
QString withYear = QString("%1년 %2 %3").arg(year).arg(date).arg(time); // "2025년 7월 28일 17:54"
QLocale korean(QLocale::Korean, QLocale::SouthKorea);
QString format = "yyyy년 M월 d일 H:mm";
QDateTime dt = korean.toDateTime(withYear, format);
if (dt.isValid()) {
dt.setTimeZone(QTimeZone("Asia/Seoul"));
return dt.toTimeZone(QTimeZone::utc());
} else {
qWarning() << "Ошибка разбора даты:" << withYear;
return {};
}
}
Node ScreenXmlTossParser::findFirstAccountLine() {
Node node;
auto elements = findElementsWithPaymentsToss(m_xml, "text", "Transfer");
if (elements.length() == 2) {
for (QDomElement &element: elements) {
qDebug() << "Found account: " << element.attribute("content-desc");
}
}
if (!elements.isEmpty()) {
node = convertTossDomElementToNode(elements[0].parentNode().toElement());
}
return node;
}
QList<TransactionInfo> ScreenXmlTossParser::parsePositiveTransactions() {
QList<TransactionInfo> transactions;
QDomElement child = findElementWithPaymentsToss(m_xml, "class", "android.widget.ListView");
QDomNodeList listView = child.childNodes();
qDebug() << listView.count();
if (!listView.isEmpty()) {
QString date = "";
for (QDomNode node: listView) {
QString title = node.toElement().attribute("text");
if (title == "전체" || title.startsWith("AD") || title.endsWith("AD")) {
continue;
}
if (!title.isEmpty()) {
date = node.toElement().attribute("text");
}
if (date.isEmpty()) {
continue;
}
const QDomNodeList trBoxGroup = node.childNodes();
if (trBoxGroup.count() > 0) {
TransactionInfo transaction;
for (QDomNode item: trBoxGroup) {
QDomElement groupItem = item.toElement();
QString line = groupItem.attribute("text");
if (line.contains("잔액") && line.contains("입금")) {
QString beforeBalance = line.split("잔액").first().trimmed();
QString time = beforeBalance.split("입금").first().trimmed().last(5);
QString desc = beforeBalance.split("입금").first().replace(time, "").trimmed();
QString amount = beforeBalance.split("입금").last().replace("", "").replace(",", "").trimmed();
transaction.amount = amount.toDouble();
transaction.description = desc;
transaction.bankTime = date + " " + time;
transaction.completeTime = getUtcFromSeoulDate(date, time);
}
}
if (transaction.amount > 0) {
transactions.append(transaction);
}
}
}
} else {
qDebug() << "ListView is empty";
}
return transactions;
}
float extractKoreanWonFromText(const QString &input) {
QRegularExpression re(R"(₩([\d,]+))");
QRegularExpressionMatch match = re.match(input);
if (!match.hasMatch()) {
qWarning() << "Не удалось найти сумму в строке:" << input;
return 0.0f;
}
QString numberStr = match.captured(1);
numberStr.remove(','); // удаляем запятые
return numberStr.toFloat();
}
double parseKoreanNumber(const QString &input) {
// Карта корейских единиц в числовые множители
static const QMap<QString, double> unitMap = {
{QStringLiteral(""), 1e12},
{QStringLiteral(""), 1e8},
{QStringLiteral(""), 1e4}
};
// Статические регулярки (Clazy: don't create temporaries)
static const QRegularExpression cleanRe(QStringLiteral("[^0-9.,만억조]"));
static const QRegularExpression segmentRe(QStringLiteral(R"(([\d,]+(?:\.\d+)?)(||))"));
QString s = input;
s.remove(cleanRe);
double total = 0.0;
auto it = segmentRe.globalMatch(s);
qsizetype pos = 0;
while (it.hasNext()) {
auto match = it.next();
QString numStr = match.captured(1);
QString unitStr = match.captured(2);
numStr.remove(',');
bool ok = false;
const double num = numStr.toDouble(&ok);
if (ok)
total += num * unitMap.value(unitStr);
pos = match.capturedEnd();
}
// Обработка остатка (обычное число, возможно с дробной частью)
QString rem = s.mid(static_cast<int>(pos));
rem.remove(',');
if (!rem.isEmpty()) {
bool ok = false;
const double num = rem.toDouble(&ok);
if (ok) total += num;
}
return total;
}
double ScreenXmlTossParser::parseAccountAmount() {
const QDomNodeList nodes = m_xml.elementsByTagName("node");
for (int i = 0; i < nodes.count(); ++i) {
const QDomElement el = nodes.at(i).toElement();
// Аккаунтов может быть несколько, вот берем первый по списку
if (el.attribute("text") == "Top up" && el.attribute("class") == "android.widget.Button") {
for (QDomNode node: el.parentNode().childNodes()) {
const QDomElement child = node.toElement();
if (child.attribute("text").contains("") || child.attribute("text").contains("")) {
return parseKoreanNumber(child.attribute("text"));
}
}
}
}
return 0;
}
QList<AccountInfo> ScreenXmlTossParser::parseAccountsInfo() {
const QDomNodeList nodes = m_xml.elementsByTagName("node");
QList<AccountInfo> accounts;
for (int i = 0; i < nodes.count(); ++i) {
const QDomElement el = nodes.at(i).toElement();
// Аккаунтов может быть несколько, вот берем первый по списку
if (el.attribute("text") == "Transfer") {
for (QDomNode node: el.parentNode().parentNode().parentNode().childNodes()) {
const QDomElement child = node.toElement();
if (child.attribute("content-desc").contains("")) {
AccountInfo info;
info.amount = extractKoreanWonFromText(child.attribute("content-desc"));
info.updateTime = DateUtils::getUtcNow();
accounts.append(info);
return accounts;
}
}
}
// if (el.attribute("content-desc").contains("토스뱅크 통장") && el.attribute("content-desc").contains("₩")) {
// AccountInfo info;
// info.amount = extractKoreanWonFromText(el.attribute("content-desc"));
// info.updateTime = DateUtils::getUtcNow();
// accounts.append(info);
// break;
// }
}
return accounts;
}
void ScreenXmlTossParser::test() {
// TransactionInfo info2 = parseExpandedInfo(m_xml);
// qDebug().noquote().nospace() << convertTransactionToString(info2);
// return;
QFile file("assets/rshb/all_products.xml");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Cannot open file";
}
QDomDocument doc;
if (!doc.setContent(&file)) {
qDebug() << "Failed to parse XML";
}
file.close();
qDebug() << "Start parsing XML:";
// Номер карты с последними цифрами
QDomElement root = doc.documentElement();
parseAndSaveXml(doc.toString());
// for (const AccountInfo &info: parseAccountsInfo()) {
// qDebug().noquote().nospace() << convertAccountToString(info);
// }
// TransactionInfo info = parseExpandedInfo(root);
// qDebug().noquote().nospace() << convertTransactionToString(info);
// ЕСПП
}

View File

@ -1,52 +0,0 @@
#pragma once
#include <QObject>
#include <QDomElement>
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
class ScreenXmlTossParser final : public QObject {
Q_OBJECT
public:
explicit ScreenXmlTossParser(QObject *parent = nullptr);
~ScreenXmlTossParser() override;
Node findTextNode(const QString &text);
Node findTextContainsNode(const QString &text);
Node findFirstAccountLine();
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
Node findEditText(const QString &text);
Node findEditTextByResourceId(const QString &resourceId);
Node findNodeByClassName(const QString &className);
Node findButtonNode(const QString &text, bool contains);
bool isHomeScreen();
void parseAndSaveXml(const QString &xml);
QList<TransactionInfo> parsePositiveTransactions();
QList<AccountInfo> parseAccountsInfo();
double parseAccountAmount();
QList<Node> findPinCodeNodes(const QString &pinCode);
QList<Node> getNodeNumbers(double value);
void test();
private:
QList<Node> m_nodes;
QDomElement m_xml;
};

View File

@ -1,223 +0,0 @@
#include "CommonZiraatScript.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include "adb/AdbUtils.h"
#include "net/NetworkService.h"
CommonZiraatScript::CommonZiraatScript(QObject *parent)
: QObject(parent) {
}
CommonZiraatScript::~CommonZiraatScript() = default;
void CommonZiraatScript::start() {
doStart();
emit finished();
}
Node CommonZiraatScript::swipeToButton(
const QString &deviceId,
const QString &text, int &counter, const int width, const int height
) {
for (int i = 0; i < 10; ++i) {
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
return button;
}
const int x = width / 2;
const int offset = height / 4;
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
return {};
}
bool CommonZiraatScript::runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
const int width,
const int height
) {
// Запустить устройство
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
qDebug() << "Process already running, pid: " << pid;
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
AdbUtils::tryToKillApplication(deviceId, packageName);
}
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
AdbUtils::takeScreenshot(deviceId, "run_app_error");
qWarning() << "Process has not started";
return false;
}
// Даем минимальное время на запуск
QThread::msleep(4500);
int counter = 0;
bool findAndInputPassword = false;
while (true) {
counter++;
// Если более 10 раз мы пытаемся перейти на домашнюю
if (counter > 10) {
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
return false;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
continue;
}
if (xmlScreenParser.isHomeScreen()) {
return true;
}
// Проверяем, что это экран ввода пин-кода
if (!findAndInputPassword) {
Node loginNode = xmlScreenParser.findButtonNode("Login", false);
if (!loginNode.isEmpty()) {
AdbUtils::makeTap(deviceId, loginNode.x(), loginNode.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
Node passwordEditText = xmlScreenParser.findEditText("Password");
if (!passwordEditText.isEmpty()) {
AdbUtils::makeTap(deviceId, passwordEditText.x(), passwordEditText.y());
QThread::msleep(500);
AdbUtils::inputText(deviceId, pinCode);
findAndInputPassword = true;
QThread::msleep(3000);
continue;
}
}
}
QThread::msleep(1000);
}
}
bool CommonZiraatScript::goToAllProducts(
const QString &deviceId,
const int width,
const int height
) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(500);
}
if (xmlScreenParser.isHomeScreen()) {
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
if (!allMyAccountBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
QThread::msleep(500);
return true;
}
}
return false;
}
void CommonZiraatScript::postAccountsData(const QList<AccountInfo> &accounts) {
if (accounts.isEmpty()) {
return;
}
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonArray list;
for (const AccountInfo &account: accounts) {
QJsonObject obj;
obj["appName"] = account.appCode;
obj["lastNumbers"] = account.lastNumbers;
obj["amount"] = account.amount;
obj["currency"] = account.currency;
obj["description"] = account.description;
obj["status"] = accountStatusToString(account.status);
list.append(obj);
}
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(accounts.first().deviceId);
worker->setPayload(QJsonDocument(list).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonZiraatScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transaction.id;
obj["amount"] = transaction.amount;
obj["name"] = transaction.name;
obj["fee"] = transaction.fee;
obj["status"] = transactionStatusToString(transaction.status);
obj["type"] = transactionTypeToString(transaction.type);
obj["phone"] = transaction.phone;
obj["description"] = transaction.description;
obj["updatedDescription"] = transaction.updatedDescription;
obj["bankName"] = transaction.bankName;
obj["bankTime"] = transaction.bankTime;
obj["bankTransactionId"] = transaction.bankTrExternalId;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->addExtra("transactionId", transaction.id);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonZiraatScript::updateTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transactionId;
obj["status"] = transactionStatusToString(status);
obj["description"] = newDesc;
obj["updatedDescription"] = oldDesc;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonZiraatScript::stop() {
m_running = false;
}

View File

@ -1,65 +0,0 @@
#pragma once
#include <QObject>
#include "ScreenXmlZiraatParser.h"
class CommonZiraatScript : public QObject {
Q_OBJECT
public:
explicit CommonZiraatScript(QObject *parent = nullptr);
~CommonZiraatScript() override;
protected:
virtual void doStart() = 0;
bool goToAllProducts(
const QString &deviceId,
int width,
int height
);
void postAccountsData(const QList<AccountInfo> &accounts);
void postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction);
void updateTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
Node swipeToButton(
const QString &deviceId,
const QString &text,
int &counter, int width, int height
);
bool runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
int width,
int height
);
bool m_running = true;
ScreenXmlZiraatParser xmlScreenParser;
int m_counter = 0;
signals:
void finished();
void finishedWithResult(const QString &result);
public slots:
virtual void start() final;
virtual void stop() final;
private:
Q_DISABLE_COPY(CommonZiraatScript);
};

View File

@ -1,160 +0,0 @@
#include "GetLastDaysHistoryZiraatScript.h"
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/DeviceInfo.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
GetLastDaysHistoryZiraatScript::GetLastDaysHistoryZiraatScript(
AccountInfo account,
QObject *parent
) : CommonZiraatScript(parent),
m_account(std::move(account)) {
}
GetLastDaysHistoryZiraatScript::~GetLastDaysHistoryZiraatScript() = default;
bool GetLastDaysHistoryZiraatScript::saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
) {
TransactionInfo tr;
tr.accountId = account.id;
tr.description = transaction.description;
tr.bankTime = transaction.bankTime;
tr.bankName = transaction.bankName;
tr.amount = transaction.amount;
tr.phone = transaction.phone;
tr.updateTime = DateUtils::getUtcNow();
tr.fee = transaction.fee;
tr.name = transaction.name;
tr.bankTrExternalId = transaction.bankTrExternalId;
tr.status = status;
tr.type = transaction.description.startsWith("Перевод") ? TransactionType::Phone : TransactionType::Card;
tr.completeTime = DateUtils::getUtcNow();
tr.id = TransactionDAO::insertTransaction(tr);
if (tr.id == -1) {
return false;
}
postNewTransactionData(account, tr);
return true;
}
bool GetLastDaysHistoryZiraatScript::updateAndPostTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
if (TransactionDAO::updateTransaction(transactionId, status, oldDesc, newDesc)) {
updateTransactionData(account, transactionId, status, oldDesc, newDesc);
return true;
}
return false;
}
void GetLastDaysHistoryZiraatScript::doStart() {
// берем все транзакции из БД
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(device.id, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
}
if (xmlScreenParser.isHomeScreen()) {
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
QList<TransactionInfo> localTransactions = TransactionDAO::getTransactionsWithinHours(m_account.id, 48);
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
for (auto &account: accounts) {
account.deviceId = m_account.deviceId;
account.appCode = m_account.appCode;
if (!AccountDAO::upsertAccount(account)) {
qDebug() << "Not updated: " << account.lastNumbers;
}
}
postAccountsData(accounts);
AdbUtils::goBack(device.id);
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node actionBtn = xmlScreenParser.findButtonNode("Account Activities", false);
if (!actionBtn.isEmpty()) {
AdbUtils::makeTap(m_account.deviceId, actionBtn.x(), actionBtn.y());
QThread::msleep(1000);
} else {
m_error = "Account Activities btn not found";
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
// localTransactions
// FIXME доделать так, чтобы свайпать и брать больше чем 5 транзакций
for (int i = 0; i < 5; ++i) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
QList<TransactionInfo> transactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
if (!transactions.isEmpty()) {
break;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
// все подтвержденные
QList<TransactionInfo> parsedTransactions = xmlScreenParser.parseTodayAndYesterdayReportHistory();
QSet<int> parsedTransactionIds;
for (const TransactionInfo &transaction: parsedTransactions) {
for (const TransactionInfo &saved: localTransactions) {
if (parsedTransactionIds.contains(saved.id)) {
continue;
}
if (transaction.bankTime == saved.bankTime && transaction.amount == saved.amount) {
parsedTransactionIds.insert(saved.id);
continue;
}
if (!saveAndPostNewTransactionData(m_account, transaction, TransactionStatus::Complete)) {
qDebug() << "--- saveAndPostNewTransactionData failed";
}
}
}
}
} else {
m_error = "GetLastDaysHistoryZiraatScript - home screen not found";
qWarning() << m_error;
emit finishedWithResult(m_error);
}
AdbUtils::goBack(m_account.deviceId);
emit finishedWithResult(m_error);
}

View File

@ -1,35 +0,0 @@
#pragma once
#include "CommonZiraatScript.h"
class GetLastDaysHistoryZiraatScript final : public CommonZiraatScript {
Q_OBJECT
public:
~GetLastDaysHistoryZiraatScript() override;
explicit GetLastDaysHistoryZiraatScript(
AccountInfo account,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
QString m_error;
bool saveAndPostNewTransactionData(
const AccountInfo &account,
const TransactionInfo &transaction,
const TransactionStatus &status
);
bool updateAndPostTransactionData(
const AccountInfo &account,
int transactionId,
TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
);
};

View File

@ -1,69 +0,0 @@
#include "LoginAndCheckAccountsZiraatScript.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
LoginAndCheckAccountsZiraatScript::LoginAndCheckAccountsZiraatScript(
QString deviceId,
QString appCode,
QObject *parent
) : CommonZiraatScript(parent),
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
}
LoginAndCheckAccountsZiraatScript::~LoginAndCheckAccountsZiraatScript() = default;
void LoginAndCheckAccountsZiraatScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Cant open the home screen: " + m_deviceId + " " + m_appCode;
qWarning() << m_error;
if (!ApplicationDAO::updatePinCodeStatus(app.id, "no", "Не прошла проверка [дата]")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
} else {
if (!ApplicationDAO::updatePinCodeStatus(app.id, "yes", "")) {
qWarning() << "Cant update the pincode: " << m_deviceId << " " << m_appCode;
}
if (goToAllProducts(device.id, device.screenWidth, device.screenHeight)) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
QList<AccountInfo> accounts = xmlScreenParser.parseAccountsInfo();
for (auto account: accounts) {
account.deviceId = m_deviceId;
account.appCode = m_appCode;
account.status = AccountStatus::Active;
if (!AccountDAO::upsertAccount(account)) {
m_error = "Not updated: " + account.lastNumbers;
qCritical() << m_error;
}
}
postAccountsData(accounts);
} else {
qWarning() << "Cant go to all products: " << m_deviceId << " " << m_appCode;
}
}
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "CommonZiraatScript.h"
class LoginAndCheckAccountsZiraatScript final : public CommonZiraatScript {
Q_OBJECT
public:
~LoginAndCheckAccountsZiraatScript() override;
explicit LoginAndCheckAccountsZiraatScript(
QString deviceId,
QString appCode,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const QString m_deviceId;
const QString m_appCode;
QString m_error;
};

View File

@ -1,350 +0,0 @@
#include "PayByIbanScript.h"
#include <QRandomGenerator>
#include <QThread>
#include <utility>
#include "DatabaseManager.h"
#include "adb/AdbUtils.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "dao/DeviceDAO.h"
#include "dao/TransactionDAO.h"
#include "db/ApplicationInfo.h"
#include "db/DeviceInfo.h"
#include "time/DateUtils.h"
PayByIbanScript::PayByIbanScript(
AccountInfo account,
QString iban,
QString fullName,
const double amount,
QObject *parent
) : CommonZiraatScript(parent),
m_account(std::move(account)), m_iban(std::move(iban)),
m_fullName(std::move(fullName)), m_amount(amount) {
}
PayByIbanScript::~PayByIbanScript() = default;
void PayByIbanScript::makePayment(const DeviceInfo &device) {
// Оплата со страницы карты
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node editIbanEditText = xmlScreenParser.findEditTextByResourceId("com.ziraat.ziraatmobil:id/edit_iban");
Node fullNameEditText = xmlScreenParser.findEditTextByResourceId("com.ziraat.ziraatmobil:id/edit_full_name");
if (!editIbanEditText.isEmpty() && !fullNameEditText.isEmpty()) {
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, m_iban);
AdbUtils::makeTap(device.id, editIbanEditText.x(), editIbanEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, m_fullName);
Node nextBtn = xmlScreenParser.findButtonNode("NEXT", false);
AdbUtils::makeTap(device.id, nextBtn.x(), nextBtn.y());
bool findSenderAccount = false;
for (int i = 0; i < 5; ++i) {
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node senderAccount = xmlScreenParser.findTextNode("Sender Account");
if (!senderAccount.isEmpty()) {
Node inputBankName = xmlScreenParser.findAccountButton(m_account.lastNumbers);
if (!inputBankName.isEmpty()) {
AdbUtils::makeTap(device.id, inputBankName.x(), inputBankName.y());
QThread::msleep(500);
// FXIME скорее всего придется нажать кнопку NEXT
findSenderAccount = true;
}
break;
}
}
if (!findSenderAccount) {
m_error = "Не нашли Sender Account";
qDebug() << m_error;
return;
}
bool findAmountDetermination = false;
for (int i = 0; i < 5; ++i) {
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node amountDetermination = xmlScreenParser.findTextNode("Amount Determination");
if (!amountDetermination.isEmpty()) {
Node integerEditText = xmlScreenParser.findEditTextByResourceId(
"com.ziraat.ziraatmobil:id/edit_text_integer");
Node decimalEditText = xmlScreenParser.findEditTextByResourceId(
"com.ziraat.ziraatmobil:id/edit_text_decimal");
if (!integerEditText.isEmpty() && !decimalEditText.isEmpty()) {
int integerPart = static_cast<int>(m_amount);
AdbUtils::makeTap(device.id, integerEditText.x(), integerEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, QString::number(integerPart));
int decimalPart = static_cast<int>((m_amount - integerPart) * 100);
AdbUtils::makeTap(device.id, decimalEditText.x(), decimalEditText.y());
QThread::msleep(500);
AdbUtils::inputText(device.id, QString::number(decimalPart));
findAmountDetermination = true;
break;
} else {
m_error = "Не нашли поля ввода для ввода суммы перевода";
qDebug() << m_error;
return;
}
}
}
if (!findAmountDetermination) {
m_error = "Не нашли Amount Determination";
qDebug() << m_error;
return;
}
bool findDetailDefinition = false;
for (int i = 0; i < 5; ++i) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node fastTransferBtn = xmlScreenParser.findButtonNode("FAST TRANSFER", false);
if (!fastTransferBtn.isEmpty()) {
AdbUtils::makeTap(device.id, fastTransferBtn.x(), fastTransferBtn.y());
QThread::msleep(500);
continue;
}
Node detailDefinitionTitle = xmlScreenParser.findTextNode("Detail Definition");
Node pleaseChooseBtn = xmlScreenParser.findButtonNode("Please choose", false);
if (!detailDefinitionTitle.isEmpty() && !pleaseChooseBtn.isEmpty()) {
AdbUtils::makeTap(device.id, pleaseChooseBtn.x(), pleaseChooseBtn.y());
QThread::msleep(500);
Node searchEditText = xmlScreenParser.
findEditTextByResourceId("com.ziraat.ziraatmobil:id/input_search");
if (!searchEditText.isEmpty()) {
AdbUtils::makeTap(device.id, searchEditText.x(), searchEditText.y());
QThread::msleep(500);
// FIXME "Individual Payment" или "Other Payments" если нет одного, то надо другой
AdbUtils::inputText(device.id, "Other Payments");
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
if (!otherPaymentsText.isEmpty()) {
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
QThread::msleep(500);
findDetailDefinition = true;
break;
}
} else {
for (int i = 0; i < 5; ++i) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node otherPaymentsText = xmlScreenParser.findTextNode("Other Payments");
if (otherPaymentsText.isEmpty()) {
AdbUtils::makeSwipe(
m_account.deviceId,
device.screenWidth / 2, device.screenHeight / 4 * 3,
device.screenWidth / 2, device.screenHeight / 4
);
} else {
AdbUtils::makeTap(device.id, otherPaymentsText.x(), otherPaymentsText.y());
QThread::msleep(500);
findDetailDefinition = true;
break;
}
QThread::msleep(500);
}
}
}
}
if (!findDetailDefinition) {
m_error = "Не нашли Detail Definition";
qDebug() << m_error;
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node nextBtn4 = xmlScreenParser.findButtonNode("NEXT", false);
AdbUtils::makeTap(device.id, nextBtn4.x(), nextBtn4.y());
QThread::msleep(500);
Node checkInfo = xmlScreenParser.findTextNode(
"Check the details of the transaction you shall realize and approve your transaction.");
if (!checkInfo.isEmpty()) {
for (int i = 0; i < 5; ++i) {
Node confirmBtn = xmlScreenParser.findButtonNode("CONFIRM", false);
if (confirmBtn.isEmpty()) {
AdbUtils::makeSwipe(
m_account.deviceId,
device.screenWidth / 2, device.screenHeight / 4 * 3,
device.screenWidth / 2, device.screenHeight / 4
);
} else {
AdbUtils::makeTap(device.id, confirmBtn.x(), confirmBtn.y());
QThread::msleep(500);
break;
}
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
}
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node successText = xmlScreenParser.findTextNode("Your transaction is successfully realized.");
if (!successText.isEmpty()) {
Node receiptBtn = xmlScreenParser.findButtonNode("RECEIPT", false);
if (!receiptBtn.isEmpty()) {
AdbUtils::makeTap(device.id, receiptBtn.x(), receiptBtn.y());
QThread::msleep(500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
Node sendBtn = xmlScreenParser.findButtonNode("SEND E-MAIL", false);
if (!sendBtn.isEmpty()) {
AdbUtils::takeXmlDump(
device.id, "pay_by_iban_finish_transactions_" + QString::number(m_account.id)
);
// Успешная транзакция
// TODO считываем все данные по переводу
TransactionInfo transaction;
transaction.name = m_fullName;
transaction.accountId = m_account.id;
transaction.amount = -m_amount;
transaction.fee = 0;
transaction.status = TransactionStatus::Complete;
transaction.type = TransactionType::Iban;
transaction.updateTime = DateUtils::getUtcNow();
transaction.completeTime = DateUtils::getUtcNow();
transaction.timestamp = DateUtils::getUtcNow();
transaction.id = TransactionDAO::insertTransaction(transaction);
if (transaction.id == -1) {
// FIXME alert!!
qDebug() << "Transaction has not inserted...";
}
postNewTransactionData(m_account, transaction);
Node backBtn = xmlScreenParser.findButtonNode("BACK", false);
if (!backBtn.isEmpty()) {
AdbUtils::makeTap(device.id, backBtn.x(), backBtn.y());
QThread::msleep(500);
Node returnBtn = xmlScreenParser.findButtonNode("RETURN TO HOME PAGE", false);
if (!returnBtn.isEmpty()) {
AdbUtils::makeTap(device.id, returnBtn.x(), returnBtn.y());
}
}
} else {
//FIXME не успешная транзакция
AdbUtils::takeXmlDump(
device.id, "pay_by_iban_fail_transactions_receipt_" + QString::number(m_account.id)
);
m_error = "Транзакция не успешна";
qDebug() << m_error;
return;
}
}
} else {
m_error = "Транзакция не успешна";
qDebug() << m_error;
return;
}
} else {
m_error = "Не нашли Check the details title info";
qDebug() << m_error;
return;
}
} else {
m_error = "Не нашли поля ввода для IBAN";
qDebug() << m_error;
return;
}
}
void PayByIbanScript::doStart() {
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found.";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
if (!xmlScreenParser.isHomeScreen()) {
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode, device.screenWidth, device.screenHeight)) {
m_error = "Не смогли дойти до домашней страницы";
qDebug() << m_error;
emit finishedWithResult(m_error);
return;
}
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node allTransactionsNav = xmlScreenParser.findTextNode("Transactions");
if (!allTransactionsNav.isEmpty()) {
AdbUtils::makeTap(device.id, allTransactionsNav.x(), allTransactionsNav.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
// перешли на страницу транзакций
Node allTransactionsTitle = xmlScreenParser.findTextNode(
"Transactions", 0, 0, device.screenWidth, device.screenHeight / 2
);
Node moneyTransfersBtn = xmlScreenParser.findTextNode("Money Transfers");
if (!allTransactionsTitle.isEmpty() && !moneyTransfersBtn.isEmpty()) {
AdbUtils::makeTap(device.id, moneyTransfersBtn.x(), moneyTransfersBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
// перешли на страницу переводов
Node moneyTransfersTitle = xmlScreenParser.findTextNode(
"Money Transfers", 0, 0, device.screenWidth, device.screenHeight / 2
);
Node transferToOtherAccountBtn = xmlScreenParser.findTextNode("Transfer to Other Account");
if (!moneyTransfersTitle.isEmpty() && !transferToOtherAccountBtn.isEmpty()) {
AdbUtils::makeTap(device.id, transferToOtherAccountBtn.x(), transferToOtherAccountBtn.y());
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_account.deviceId, ++m_counter));
Node transferToOtherAccountTitle = xmlScreenParser.findTextNode(
"Transfer to Other Account", 0, 0, device.screenWidth, device.screenHeight / 2
);
Node aNewRecipientBtn = xmlScreenParser.findTextNode("A New Recipient");
if (!transferToOtherAccountTitle.isEmpty() && !aNewRecipientBtn.isEmpty()) {
AdbUtils::makeTap(device.id, aNewRecipientBtn.x(), aNewRecipientBtn.y());
QThread::msleep(1000);
makePayment(device);
} else {
m_error = "Не нашли кнопку 'A New Recipient'";
qDebug() << m_error;
}
} else {
m_error = "Не нашли кнопку 'Transfer to Other Account'";
qDebug() << m_error;
}
} else {
m_error = "Не нашли кнопку 'Money Transfers'";
qDebug() << m_error;
}
} else {
m_error = "Не нашли пункт меню 'Transactions'";
qDebug() << m_error;
}
if (!m_error.isEmpty()) {
AdbUtils::takeXmlDump(device.id, "pay_by_iban_fail_transactions_" + QString::number(m_account.id));
}
emit finishedWithResult(m_error);
}

View File

@ -1,30 +0,0 @@
#pragma once
#include "CommonZiraatScript.h"
#include "db/DeviceInfo.h"
class PayByIbanScript final : public CommonZiraatScript {
Q_OBJECT
public:
~PayByIbanScript() override;
PayByIbanScript(
AccountInfo account,
QString iban,
QString fullName,
double amount,
QObject *parent = nullptr
);
protected:
void doStart() override;
private:
const AccountInfo m_account;
const QString m_iban;
const QString m_fullName;
const double m_amount;
QString m_error;
void makePayment(const DeviceInfo &device);
};

View File

@ -1,797 +0,0 @@
#include "ScreenXmlZiraatParser.h"
#include <QRegularExpression>
#include <QMap>
#include <QSet>
#include <QList>
#include <QXmlStreamReader>
#include <QDomDocument>
#include <QFile>
#include <QDateTime>
#include "adb/AdbUtils.h"
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
#include "time/DateUtils.h"
ScreenXmlZiraatParser::ScreenXmlZiraatParser(QObject *parent) : QObject(parent) {
}
ScreenXmlZiraatParser::~ScreenXmlZiraatParser() = default;
static const QRegularExpression boundsRegex(R"(\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\])");
static const QRegularExpression onlyDigitsRegex(R"([^0-9])");
static const QRegularExpression onlyDigitsAndDotRegex(R"([^0-9.])");
static const QRegularExpression rePhone(R"raw((\+7\(?\d{3}\)?[- ]?\d{3}[- ]?\d{2}[- ]?\d{2}))raw");
static const QRegularExpression reFromBank(R"raw(из (.+?) на)raw");
static const QRegularExpression reToBank(R"raw(в (.+?) через)raw");
static const QRegularExpression reSbpId(R"(СБП(?: С2С)? ([A-Z0-9]{30,}))");
static const QRegularExpression reIdAlt(R"(ID перевода (\d+))");
static const QRegularExpression reDate(R"((?:Дата операции|дата) (\d{2}\.\d{2}\.\d{4}(?: \d{2}:\d{2}:\d{2})?))");
static const QRegularExpression reSender(R"(от ([^\(]+))");
static const QRegularExpression reNameAlt(R"(Перевод ([А-Яа-яЁё\s\*]+) в)");
static const QRegularExpression reCardData(R"(цифрами\s+(\d\s\d\s\d\s\d).*?Сумма:\s([\d\s]+)\sруб)");
Node ScreenXmlZiraatParser::tryToFindBannerOrDialog(const int width, const int height) {
// 1. Ищем push banner - он перекрывает весь экран
Node first = m_nodes[0];
for (const Node &node: m_nodes) {
// Если это однозначно, что пуш-баннер
if (node.resourceId == "aft-popup-pushNotification-iconClose" && node.className == "android.widget.Button") {
return node;
}
// Если есть кнопка "Позже"
if (node.text.trimmed() == "Позже" && node.className == "android.widget.Button") {
return node;
}
// Если нашли пустую кнпоку
if (node.className == "android.widget.Button" && node.clickable
&& node.text.isEmpty() && node.contentDesc.isEmpty()) {
// <node class="android.widget.Button" package="ru.rshb.dbo" clickable="true" bounds="[630,142][691,205]"/>
if (node.x() > width / 2 && node.y() < width / 2) {
return node;
}
}
}
return {};
}
Node ScreenXmlZiraatParser::findAccountButton(const QString &numbers) {
// TODO возможно это не так, надо уточнять
return findTextNode(QString("LEVENT - %1").arg(numbers));
}
/**
* Смотрим что есть текс "Мы заботимся о вашей безопасности" и
* кнопка "Отложить"
* @return координаты кнопки для закрытия
*/
Node ScreenXmlZiraatParser::tryToFindSecurityBanner() {
Node text;
Node closeBtn;
for (const Node &node: m_nodes) {
if (node.text.trimmed() == "Мы заботимся о вашей безопасности" && node.className == "android.app.Dialog") {
text = node;
}
if (node.text.trimmed() == "Отложить" && node.className == "android.widget.Button") {
closeBtn = node;
}
}
// Не нужно проверять все, если хотя бы одна координата есть
if (!text.isEmpty() && !closeBtn.isEmpty()) {
return closeBtn;
}
return {};
}
Node ScreenXmlZiraatParser::tryToFindSelectBottomSheet() {
Node closeBtn;
for (const Node &node: m_nodes) {
if ((node.text.trimmed() == "Отмена" || node.text.trimmed() == "Отложить") && node.className ==
"android.widget.Button") {
closeBtn = node;
}
}
// Не нужно проверять все, если хотя бы одна координата есть
if (!closeBtn.isEmpty()) {
return closeBtn;
}
return {};
}
Node ScreenXmlZiraatParser::findTextNode(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text) {
return node;
}
}
return {};
}
Node ScreenXmlZiraatParser::findTextNode(const QString &text, const int x1, const int y1, const int x2, const int y2) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.TextView" && node.text.trimmed() == text
&& node.x() >= x1 && node.x() <= x2 && node.y() >= y1 && node.y() <= y2) {
return node;
}
}
return {};
}
Node ScreenXmlZiraatParser::findEditText(const QString &text) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.text == text) {
return node;
}
}
return {};
}
Node ScreenXmlZiraatParser::findEditTextByResourceId(const QString &resourceId) {
for (const Node &node: m_nodes) {
if (node.className == "android.widget.EditText" && node.resourceId == resourceId) {
return node;
}
}
return {};
}
Node ScreenXmlZiraatParser::findButtonNode(const QString &text, const bool contains) {
for (const Node &node: m_nodes) {
if (contains) {
if (node.className == "android.widget.Button" && node.text.contains(text)) {
return node;
}
} else {
if (node.className == "android.widget.Button" && node.text.trimmed() == text) {
return node;
}
}
}
return {};
}
bool ScreenXmlZiraatParser::isHomeScreen() {
Node activitiesBtn;
Node allProductBtn;
for (const Node &node: m_nodes) {
if (node.text.trimmed() == "Account Activities" && node.className == "android.widget.Button") {
activitiesBtn = node;
}
if (node.text.trimmed() == "All My Accounts" && node.className == "android.widget.Button") {
allProductBtn = node;
}
}
return !activitiesBtn.isEmpty() && !allProductBtn.isEmpty();
}
QList<Node> ScreenXmlZiraatParser::findPinCodeNodes(const QString &pinCode) {
QMap<QString, Node> buttons;
const QSet<QString> numberSet = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
for (const Node &node: m_nodes) {
const QString &text = node.text.trimmed();
if (node.className == "android.widget.Button" && numberSet.contains(text)) {
buttons[text] = node;
}
}
QList<Node> nodes;
for (int i = 0; i < pinCode.length(); ++i) {
nodes.append(buttons[QString(pinCode.at(i))]);
}
return nodes;
}
QList<Node> ScreenXmlZiraatParser::getLast2DaysTransactions() {
QList<Node> nodes;
for (const Node &node: m_nodes) {
if (node.className == "android.widget.Button" && node.text.contains("рубл")
&& (node.text.contains("Минус") || node.text.contains("Плюс"))) {
nodes.append(node);
}
}
return nodes;
}
/**
* <node NAF="true" index="1" text="" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[952,159][1039,248]"/>
*/
void ScreenXmlZiraatParser::parseAndSaveXml(const QString &xml) {
QDomDocument doc;
doc.setContent(xml);
m_xml = doc.documentElement();
m_nodes.clear();
QXmlStreamReader reader(xml);
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement() && reader.name() == "node") {
Node node = Node();
if (reader.attributes().hasAttribute("bounds")) {
QString bounds = reader.attributes().value("bounds").toString();
if (QRegularExpressionMatch match = boundsRegex.match(bounds); match.hasMatch()) {
node.setBounds(
match.captured(1).toInt(),
match.captured(2).toInt(),
match.captured(3).toInt(),
match.captured(4).toInt()
);
}
}
if (reader.attributes().hasAttribute("text")) {
node.text = reader.attributes().value("text").toString();
}
if (reader.attributes().hasAttribute("content-desc")) {
node.contentDesc = reader.attributes().value("content-desc").toString();
}
if (reader.attributes().hasAttribute("class")) {
node.className = reader.attributes().value("class").toString();
}
if (reader.attributes().hasAttribute("clickable")) {
node.clickable = reader.attributes().value("clickable").toString() == "true";
}
if (reader.attributes().hasAttribute("focusable")) {
node.focusable = reader.attributes().value("focusable").toString() == "true";
}
if (reader.attributes().hasAttribute("resource-id")) {
node.resourceId = reader.attributes().value("resource-id").toString();
}
m_nodes.append(node);
}
}
}
QDomElement findSubElement2(const QDomElement &elem, const QString &index) {
if (elem.hasChildNodes()) {
QDomNodeList subInfoList = elem.childNodes();
for (QDomNode subInfoNode: subInfoList) {
if (!subInfoNode.isElement()) continue;
QDomElement subInfo = subInfoNode.toElement();
if (subInfo.attribute("index") == index) {
return subInfo;
}
}
}
return {};
}
QString findSubInfo2(const QDomElement &elem, const QString &index) {
QDomElement subInfo = findSubElement2(elem, index);
if (!subInfo.isNull()) {
return subInfo.attribute("text");
}
return "";
}
bool hasTimeComponent2(const QString &datetimeStr) {
QDateTime dt = QDateTime::fromString(datetimeStr, "dd.MM.yyyy HH:mm:ss");
if (!dt.isValid()) {
return false; // Строка не соответствует формату даты и времени
}
return dt.time() != QTime(0, 0, 0); // Проверка, что время не равно 00:00:00
}
QString transformBankDateTime2(const QString &date) {
QDateTime dt;
if (date.contains(",")) {
// 10.05.2025, 15:03
dt = QDateTime::fromString(date, "dd.MM.yyyy, HH:mm");
} else {
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm:ss");
}
if (!dt.isValid()) {
dt = QDateTime::fromString(date, "dd.MM.yyyy HH:mm");
}
if (!dt.isValid()) {
return date; // не распарсили
}
return dt.toString("dd.MM.yyyy HH:mm:ss");
}
void parseTransferInfo2(const QString &text, TransactionInfo &info) {
if (const auto m = reSender.match(text); m.hasMatch()) {
info.name = m.captured(1).trimmed();
} else if (const auto m1 = reNameAlt.match(text); m1.hasMatch()) {
info.name = m1.captured(1).trimmed();
}
if (const auto m = rePhone.match(text); m.hasMatch()) {
info.phone = m.captured(1).trimmed().remove(onlyDigitsRegex);
}
if (const auto m = reFromBank.match(text); m.hasMatch()) {
if (const QString bank = m.captured(1).trimmed(); !bank.isEmpty()) {
info.bankName = bank;
}
} else if (const auto m1 = reToBank.match(text); m1.hasMatch()) {
if (const QString bank = m1.captured(1).trimmed(); !bank.isEmpty()) {
info.bankName = bank;
}
}
if (const auto m = reSbpId.match(text); m.hasMatch()) {
info.bankTrExternalId = m.captured(1);
} else if (const auto m1 = reIdAlt.match(text); m1.hasMatch()) {
info.bankTrExternalId = m1.captured(1);
}
if (const auto m = reDate.match(text); m.hasMatch()) {
const QString date = m.captured(1);
// если не пустая и дата у нас с 00:00
// if (hasTimeComponent2(date)) {
info.bankTime = transformBankDateTime2(date);
// }
}
}
void traverseNodes2(const QDomNode &node) {
if (node.isElement()) {
QDomElement elem = node.toElement();
if (node.isElement()) {
QDomElement elem = node.toElement();
if (elem.tagName() == "node" &&
elem.attribute("class") == "android.widget.Button" &&
elem.attribute("text") == "Детали операции") {
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int j = 0; j < detailInfo.count(); ++j) {
QDomNode info = detailInfo.at(j);
if (!info.isElement()) continue;
QDomElement infoElement = info.toElement();
QString index = infoElement.attribute("index");
switch (index.toInt()) {
case 2:
qDebug() << "Дата операции:" << findSubInfo2(infoElement, "1");
break;
case 5:
qDebug() << "Название:" << findSubInfo2(infoElement, "1");
qDebug() << "-------------------------------------";
// parseTransfer(findSubInfo2(infoElement));
break;
case 7:
qDebug() << "Комиссия:" << findSubInfo2(infoElement, "1");
break;
default:
qDebug() << "Прочее:" << findSubInfo2(infoElement, "1");
break;
}
/**
Node: "2" ""
... Node: "0" "Дата операции"
... Node: "1" "30.04.2025 17:46:29"
Node: "5" ""
... Node: "0" "Название"
... Node: "1" "DBO TRANSFER RSHB INTERNET-BANK"
Node: "7" ""
... Node: "0" "Комиссия"
... Node: "1" "50 ₽"
*/
// if (sibElem.hasChildNodes()) {
// QDomNodeList sibChildren = sibElem.childNodes();
// for (int k = 0; k < sibChildren.count(); ++k) {
// QDomNode sibChild = sibChildren.at(k);
// if (!sibChild.isElement()) continue;
// QDomElement sibChildElem = sibChild.toElement();
// qDebug() << "... Node:"
// << sibChildElem.attribute("index")
// << sibChildElem.attribute("text");
// // << sibChildElem.attribute("class");
//
//
// if (sibChildElem.hasChildNodes()) {
// QDomNodeList sibChildren2 = sibChildElem.childNodes();
// for (int k = 0; k < sibChildren2.count(); ++k) {
// QDomNode sibChild2 = sibChildren2.at(k);
// if (!sibChild2.isElement()) continue;
// QDomElement sibChildElem2 = sibChild2.toElement();
//
// qDebug() << "...... Node:"
// << sibChildElem2.attribute("index")
// << sibChildElem2.attribute("text");
// // << sibChildElem2.attribute("class");
//
// if (sibChildElem2.hasChildNodes()) {
// QDomNodeList sibChildren3 = sibChildElem2.childNodes();
// for (int k = 0; k < sibChildren3.count(); ++k) {
// QDomNode sibChild3 = sibChildren3.at(k);
// if (!sibChild3.isElement()) continue;
// QDomElement sibChildElem3 = sibChild3.toElement();
//
// qDebug() << "......... Node:"
// << sibChildElem3.attribute("index")
// << sibChildElem3.attribute("text");
// // << sibChildElem2.attribute("class");
// }
// }
// }
// }
// }
// }
}
}
}
}
// Рекурсивно обходим всех детей
QDomNode child = node.firstChild();
while (!child.isNull()) {
traverseNodes2(child);
child = child.nextSibling();
}
}
QDomNode findNode2(const QDomNode &node, const QString &text) {
if (node.isElement()) {
QString nodeText = node.toElement().attribute("text");
if (nodeText.toLower().startsWith(text)) {
return node;
}
}
QDomNode child = node.firstChild();
while (!child.isNull()) {
QDomNode result = findNode2(child, text);
if (!result.isNull()) {
return result;
}
child = child.nextSibling();
}
return {};
}
float extractAmounts2(const QString &text) {
// Разрешаем пробелы внутри чисел, захватываем "рубль", "рубля", "рублей" и т.д.
// QRegularExpression re(R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)");
QRegularExpression re(
R"((Плюс|Минус)\s+([\d\s]+)\s+рубл\w*\s+(\d+)\s+копе\w*)",
QRegularExpression::UseUnicodePropertiesOption
);
QRegularExpressionMatch match = re.match(text);
if (match.hasMatch()) {
QString signStr = match.captured(1); // "Плюс" или "Минус"
QString rublesStr = match.captured(2).remove(' '); // "1 000" → "1000"
int rubles = rublesStr.toInt();
int kopecks = match.captured(3).toInt();
int totalKopecks = rubles * 100 + kopecks;
if (signStr == "Минус") {
totalKopecks *= -1;
}
return totalKopecks / 100.0f;
}
return 0;
}
QString beforeAmount2(const QString &text) {
int index = text.indexOf(QRegularExpression("Плюс|Минус"));
if (index != -1) {
return text.left(index).trimmed();
}
return text; // если не найдено — вернуть всю строку
}
double parseAmount2(const QString &amountAsString) {
QString numberString = amountAsString;
numberString.remove(QRegularExpression(R"([^\очка])"));
numberString.replace("точка", ".");
double amount = numberString.toDouble();
if (amountAsString.startsWith("-")) {
amount *= -1;
}
return amount;
}
QDomElement findElementWithListView2(const QDomElement &parent) {
QDomElement element = parent.firstChildElement();
while (!element.isNull()) {
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
if (child.hasAttribute("class") && child.attribute("class") ==
"androidx.recyclerview.widget.RecyclerView") {
return child;
}
child = child.nextSiblingElement();
}
QDomElement found = findElementWithListView2(element);
if (!found.isNull()) {
return found;
}
element = element.nextSiblingElement();
}
return {};
}
QDateTime getUtcFromTurkey(const QString &d, const QString &m, const QString &t) {
const QMap<QString, int> monthMap = {
{"JAN", 1}, {"FEB", 2}, {"MAR", 3}, {"APR", 4},
{"MAY", 5}, {"JUN", 6}, {"JUL", 7}, {"AUG", 8},
{"SEP", 9}, {"OCT", 10}, {"NOV", 11}, {"DEC", 12}
};
const int day = d.toInt();
const int month = monthMap.value(m.toUpper(), 0);
const int year = QDate::currentDate().year();
const QDate date(year, month, day);
const QTime time = QTime::fromString(t, "HH:mm");
const QTimeZone tz("Europe/Istanbul"); // TRT (UTC+3, без перехода на зимнее время)
const QDateTime dtLocal(date, time, tz);
const QDateTime dtUtc = dtLocal.toTimeZone(QTimeZone::utc());
return dtUtc;
}
QList<TransactionInfo> ScreenXmlZiraatParser::parseTodayAndYesterdayReportHistory() {
QList<TransactionInfo> transactions;
QDomElement child = findElementWithListView2(m_xml);
QDomNodeList listView = child.childNodes();
qDebug() << listView.count();
if (!listView.isEmpty()) {
for (QDomNode node: listView) {
const QDomNodeList trBoxGroup = node.childNodes();
if (trBoxGroup.count() > 0) {
for (QDomNode item: trBoxGroup) {
TransactionInfo transaction;
QDomElement groupItem = item.toElement();
if (groupItem.attribute("index") == "0") {
for (QDomNode subDate: groupItem.childNodes()) {
QDomElement dateItem = subDate.toElement();
QString date;
QString month;
QString time;
if (dateItem.attribute("index") == "0") {
date = dateItem.attribute("text");
} else if (groupItem.attribute("index") == "1") {
month = groupItem.attribute("text");
} else if (groupItem.attribute("index") == "2") {
time = groupItem.attribute("text");
}
transaction.bankTime = date + " " + month + " " + time;
transaction.completeTime = getUtcFromTurkey(date, month, time);
transaction.timestamp = DateUtils::getUtcNow();
}
} else if (groupItem.attribute("index") == "2") {
transaction.description = groupItem.attribute("text");
} else if (groupItem.attribute("index") == "3") {
transaction.amount = groupItem.attribute("text").replace("TL", "").trimmed().toFloat();
}
transactions.append(transaction);
}
}
}
} else {
qDebug() << "ListView is empty";
}
return transactions;
}
TransactionInfo parseExpandedInfoHistory2(const QDomElement &root) {
if (root.isElement()) {
QDomElement elem = root.toElement();
if (elem.tagName() == "node"
&& elem.attribute("class") == "android.widget.Button"
&& elem.attribute("text") == "Детали операции"
) {
TransactionInfo transaction;
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int i = 0; i < detailInfo.count(); ++i) {
QDomNode info = detailInfo.at(i);
if (!info.isElement()) continue;
switch (QDomElement e = info.toElement(); e.attribute("index").toInt()) {
case 2:
// Дата операции
transaction.bankTime = transformBankDateTime2(findSubInfo2(e, "1"));
break;
case 5:
transaction.description = findSubInfo2(e, "1");
parseTransferInfo2(transaction.description, transaction);
break;
case 7:
// Комиссия
transaction.fee = findSubInfo2(e, "1").remove(onlyDigitsRegex).toFloat();
break;
default:
// qDebug() << "Прочее:" << findSubInfo2(e);
break;
}
}
return transaction;
}
}
// Рекурсивно обходим всех детей
QDomNode child = root.firstChild();
while (!child.isNull()) {
if (TransactionInfo info = parseExpandedInfoHistory2(child.toElement()); !info.bankTime.isEmpty()) {
return info;
}
child = child.nextSibling();
}
return {};
}
TransactionInfo ScreenXmlZiraatParser::parseTransactionInfoHistory(int screenWidth, int screenHeight) {
// 1. Распарсить описание транзакции
TransactionInfo transaction = parseExpandedInfoHistory2(m_xml);
// 1. Найти статус: Исполнен | Операция исполнена
transaction.status = TransactionStatus::Wait;
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
if (!status1.isEmpty() || !status2.isEmpty()) {
transaction.status = TransactionStatus::Complete;
}
return transaction;
}
TransactionInfo parseExpandedInfo2(const QDomElement &root) {
if (root.isElement()) {
QDomElement elem = root.toElement();
if (elem.tagName() == "node"
&& elem.attribute("class") == "android.widget.Button"
&& elem.attribute("text") == "Детали операции"
) {
TransactionInfo transaction;
// Все что ниже деталей операции
QDomNodeList detailInfo = elem.parentNode().childNodes();
for (int i = 0; i < detailInfo.count(); ++i) {
QDomNode info = detailInfo.at(i);
if (!info.isElement()) continue;
QDomElement infoElement = info.toElement();
QString index = infoElement.attribute("index");
QDomElement ee;
switch (index.toInt()) {
case 3:
transaction.bankTime = transformBankDateTime2(findSubInfo2(infoElement, "1"));
break;
case 4:
ee = findSubElement2(infoElement, "0");
ee = findSubElement2(ee, "1");
transaction.phone = findSubInfo2(ee, "0").remove(onlyDigitsRegex);
break;
case 5:
transaction.name = findSubInfo2(infoElement, "1");
break;
case 6:
transaction.bankName = findSubInfo2(infoElement, "1");
break;
case 9:
transaction.fee = findSubInfo2(infoElement, "1").remove(onlyDigitsAndDotRegex).toFloat();
break;
case 10:
ee = findSubElement2(infoElement, "1");
transaction.bankTrExternalId = findSubInfo2(ee, "1");
break;
default:
break;
}
}
return transaction;
}
}
// Рекурсивно обходим всех детей
QDomNode child = root.firstChild();
while (!child.isNull()) {
if (TransactionInfo info = parseExpandedInfo2(child.toElement()); !info.bankTime.isEmpty()) {
return info;
}
child = child.nextSibling();
}
return {};
}
TransactionInfo ScreenXmlZiraatParser::parseTransactionInfo(int screenWidth, int screenHeight) {
// 1. Распарсить описание транзакции
TransactionInfo transaction = parseExpandedInfo2(m_xml);
// 1. Найти статус: Исполнен | Операция исполнена
transaction.status = TransactionStatus::Wait;
Node status1 = findTextNode("Исполнен", 0, 0, screenWidth, screenHeight / 2);
Node status2 = findTextNode("Операция исполнена", 0, 0, screenWidth, screenHeight / 2);
if (!status1.isEmpty() || !status2.isEmpty()) {
transaction.status = TransactionStatus::Complete;
}
return transaction;
}
QList<AccountInfo> ScreenXmlZiraatParser::parseAccountsInfo() {
const QDomNodeList nodes = m_xml.elementsByTagName("node");
QList<AccountInfo> accounts;
for (int i = 0; i < nodes.count(); ++i) {
const QDomElement el = nodes.at(i).toElement();
if (el.attribute("resource-id") == "com.ziraat.ziraatmobil:id/text_account_or_bank_name") {
// Нашли нужный аккаунт
const QDomElement parent = el.parentNode().toElement(); // account_name_layout
const QDomElement balanceFrame = parent.parentNode().parentNode().lastChildElement("node");
// Перебираем потомков в поисках суммы
QDomNode n = balanceFrame;
while (!n.isNull()) {
const QDomElement e = n.toElement();
if (e.attribute("resource-id") == "com.ziraat.ziraatmobil:id/text_value") {
QString amount = e.attribute("text");
QString account = el.attribute("text");
AccountInfo info;
info.lastNumbers = account;
info.amount = amount.toFloat();
info.description = account;
info.updateTime = DateUtils::getUtcNow();
accounts.append(info);
break;
}
n = n.nextSibling();
}
}
}
return accounts;
}
void ScreenXmlZiraatParser::test() {
// TransactionInfo info2 = parseExpandedInfo(m_xml);
// qDebug().noquote().nospace() << convertTransactionToString(info2);
// return;
QFile file("assets/rshb/all_products.xml");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Cannot open file";
}
QDomDocument doc;
if (!doc.setContent(&file)) {
qDebug() << "Failed to parse XML";
}
file.close();
qDebug() << "Start parsing XML:";
// Номер карты с последними цифрами
QDomElement root = doc.documentElement();
parseAndSaveXml(doc.toString());
// for (const AccountInfo &info: parseAccountsInfo()) {
// qDebug().noquote().nospace() << convertAccountToString(info);
// }
// TransactionInfo info = parseExpandedInfo(root);
// qDebug().noquote().nospace() << convertTransactionToString(info);
// ЕСПП
}

View File

@ -1,56 +0,0 @@
#pragma once
#include <QObject>
#include <QDomElement>
#include "android/xml/Node.h"
#include "db/AccountInfo.h"
#include "db/TransactionInfo.h"
class ScreenXmlZiraatParser final : public QObject {
Q_OBJECT
public:
explicit ScreenXmlZiraatParser(QObject *parent = nullptr);
~ScreenXmlZiraatParser() override;
Node tryToFindBannerOrDialog(int width, int height);
Node tryToFindSecurityBanner();
Node tryToFindSelectBottomSheet();
Node findAccountButton(const QString &numbers);
Node findTextNode(const QString &text);
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
Node findEditText(const QString &text);
Node findEditTextByResourceId(const QString &resourceId);
Node findButtonNode(const QString &text, bool contains);
bool isHomeScreen();
QList<Node> getLast2DaysTransactions();
void parseAndSaveXml(const QString &xml);
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
QList<TransactionInfo> parseTodayAndYesterdayReportHistory();
QList<AccountInfo> parseAccountsInfo();
void test();
private:
QList<Node> m_nodes;
QDomElement m_xml;
QList<Node> findPinCodeNodes(const QString &pinCode);
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 KiB

View File

@ -1,124 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,2337]" drawing-order="0" hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,2337]" drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false" bounds="[0,136][1080,2337]"
drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/coordinator"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
<node NAF="true" index="0" text=""
resource-id="az.kapitalbank.mbanking:id/touch_outside" class="android.view.View"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="true" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,2337]" drawing-order="1" hint=""/>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/design_bottom_sheet"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,777][1080,2337]" drawing-order="2"
hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,777][1080,2337]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/popupImagesViewPager"
class="androidx.viewpager.widget.ViewPager"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,777][1080,1512]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/imageView"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,777][1080,1512]" drawing-order="1" hint=""/>
</node>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/vDrag"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[488,814][593,825]" drawing-order="2" hint=""/>
<node index="2" text="Sizə xidmət göstərən filiallarımız &#128467;"
resource-id="az.kapitalbank.mbanking:id/tvTitle"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,1554][1038,1741]" drawing-order="4" hint=""/>
<node index="3" text="" resource-id="" class="android.widget.ScrollView"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,1762][1080,1959]" drawing-order="5" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1762][1080,1959]"
drawing-order="1" hint="">
<node index="0"
text="26-27 iyul tarixlərində bankımızın müəyyən filialları saat 10:00-dan 21:45-dək öz fəaliyyətini davam etdirəcək."
resource-id="az.kapitalbank.mbanking:id/tvDescription"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,1762][1038,1917]" drawing-order="2"
hint=""/>
</node>
</node>
<node index="4" text="Ünvanların siyahısı"
resource-id="az.kapitalbank.mbanking:id/btnPrimary"
class="android.widget.Button" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,2001][1038,2148]" drawing-order="6" hint=""/>
<node index="5" text="Maraqlı deyil"
resource-id="az.kapitalbank.mbanking:id/btnSecondary"
class="android.widget.Button" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,2148][1038,2295]" drawing-order="7" hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,798 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2337]"
drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_drawer"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_screen_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/header"
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,283]" drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/vToolbar"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,136][1080,283]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,157][1080,262]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/ivCenteredHeaderBack"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="Back" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,178][131,241]" drawing-order="1"
hint=""/>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/ivHide"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[142,157][268,262]" drawing-order="2" hint="">
<node NAF="true" index="0" text=""
resource-id="az.kapitalbank.mbanking:id/ivHideAmounts"
class="android.widget.CheckBox"
package="az.kapitalbank.mbanking" content-desc=""
checkable="true" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[173,178][236,241]" drawing-order="1"
hint=""/>
</node>
<node index="2" text="" resource-id="az.kapitalbank.mbanking:id/flTitle"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[370,162][711,257]" drawing-order="3" hint="">
<node index="0" text="Birbank Cashback"
resource-id="az.kapitalbank.mbanking:id/tvTitleCentered_Header"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[370,181][711,238]" drawing-order="2"
hint=""/>
</node>
</node>
<node NAF="true" index="1" text=""
resource-id="az.kapitalbank.mbanking:id/ivButtonRight"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[933,136][1080,283]" drawing-order="2" hint=""/>
</node>
</node>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/root_progress_panel"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,283][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,283][1080,2337]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/refresh_layout"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,283][1080,2337]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/scroll_view_root"
class="android.widget.ScrollView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="false" scrollable="true"
long-clickable="false" password="false" selected="false"
bounds="[0,283][1080,2337]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/view_motion"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,283][1080,2337]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/cards_pager"
class="androidx.viewpager.widget.ViewPager"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="true" long-clickable="false" password="false"
selected="false" bounds="[0,283][1080,807]"
drawing-order="9" hint="">
<node index="0" text="" resource-id=""
class="androidx.recyclerview.widget.RecyclerView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,283][1080,807]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/card_motion_layout"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,283][1080,807]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/card_front"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="true"
enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[356,364][724,594]"
drawing-order="2" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_lens_front"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[356,364][724,594]"
drawing-order="2" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_pan_dot"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[377,406][382,411]"
drawing-order="3" hint=""/>
<node index="2" text="2480"
resource-id="az.kapitalbank.mbanking:id/tv_pan"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[393,385][640,427]"
drawing-order="4" hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/iv_provider_type"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[640,375][703,438]"
drawing-order="6" hint=""/>
<node index="4" text="Данные карты"
resource-id="az.kapitalbank.mbanking:id/tv_card_details"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[377,530][595,573]"
drawing-order="5" hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/card_rectangle"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[409,416][672,542]"
drawing-order="8" hint=""/>
<node index="6" text=""
resource-id="az.kapitalbank.mbanking:id/iv_more_dots"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[661,531][703,573]"
drawing-order="7" hint=""/>
</node>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/ll_shadow"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[356,542][724,647]"
drawing-order="1" hint=""/>
</node>
</node>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/ll_balance_details"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[459,677][620,813]"
drawing-order="1" hint="">
<node index="0" text="0 ₼"
resource-id="az.kapitalbank.mbanking:id/tv_balance"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[491,713][588,813]" drawing-order="2"
hint=""/>
</node>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/ll_actions"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,970][1080,1263]"
drawing-order="3" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/ll_action"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[42,991][360,1221]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_action_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[169,1023][232,1086]"
drawing-order="1" hint=""/>
<node index="1" text="Перевести"
resource-id="az.kapitalbank.mbanking:id/tv_action_name"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[120,1097][281,1189]"
drawing-order="2" hint=""/>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/ll_action"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[381,991][699,1221]" drawing-order="2"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_action_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[508,1023][571,1086]"
drawing-order="1" hint=""/>
<node index="1" text="Платежи"
resource-id="az.kapitalbank.mbanking:id/tv_action_name"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[473,1097][607,1189]"
drawing-order="2" hint=""/>
</node>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/ll_action"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[720,991][1038,1221]" drawing-order="3"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_action_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[847,1023][910,1086]"
drawing-order="1" hint=""/>
<node index="1" text="Пополнить"
resource-id="az.kapitalbank.mbanking:id/tv_action_name"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[796,1097][961,1189]"
drawing-order="2" hint=""/>
</node>
</node>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/ll_pfm_widget"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,1300][1038,2290]"
drawing-order="12" hint="">
<node index="0" text="В июле потрачено: "
resource-id="az.kapitalbank.mbanking:id/tv_pfm_title"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[84,1342][522,1407]" drawing-order="1"
hint=""/>
<node index="1" text="16 ₼"
resource-id="az.kapitalbank.mbanking:id/tv_pfm_title_amount"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[522,1342][611,1407]" drawing-order="2"
hint=""/>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/ll_pfm_content"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[42,1407][1038,2114]" drawing-order="3"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/rv_pfm_operations"
class="androidx.recyclerview.widget.RecyclerView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,1428][1038,2114]"
drawing-order="2" hint="">
<node index="0" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[84,1428][1038,1498]"
drawing-order="1" hint="">
<node index="0" text="24 июля"
resource-id="az.kapitalbank.mbanking:id/tv_date"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[84,1439][561,1482]"
drawing-order="2" hint=""/>
</node>
<node index="1" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="true"
enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,1503][1038,1671]"
drawing-order="2" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/transaction_logo_bg"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[84,1529][200,1645]"
drawing-order="1" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/transaction_logo_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[100,1545][184,1629]"
drawing-order="2" hint=""/>
<node index="2" text="Nar・+994703262002"
resource-id="az.kapitalbank.mbanking:id/transaction_title"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[232,1529][834,1591]"
drawing-order="5" hint=""/>
<node index="3" text="15 ₼"
resource-id="az.kapitalbank.mbanking:id/transaction_amount"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[918,1529][996,1586]"
drawing-order="8" hint=""/>
<node index="4" text="0:35"
resource-id="az.kapitalbank.mbanking:id/transaction_time"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[232,1596][294,1639]"
drawing-order="6" hint=""/>
<node index="5" text="・Связь"
resource-id="az.kapitalbank.mbanking:id/transaction_category"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[294,1594][996,1642]"
drawing-order="7" hint=""/>
</node>
<node index="2" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="true"
enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,1681][1038,1890]"
drawing-order="3" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/transaction_logo_bg"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[84,1707][200,1823]"
drawing-order="1" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/transaction_logo_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[100,1723][184,1807]"
drawing-order="2" hint=""/>
<node index="2"
text="Проверка привязки карты в Birbank"
resource-id="az.kapitalbank.mbanking:id/transaction_title"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[232,1707][737,1816]"
drawing-order="5" hint=""/>
<node index="3" text="+0,05 ₼"
resource-id="az.kapitalbank.mbanking:id/transaction_amount"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[821,1707][996,1764]"
drawing-order="8" hint=""/>
<node index="4" text="Bозврат"
resource-id="az.kapitalbank.mbanking:id/transaction_cashback"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[874,1769][996,1812]"
drawing-order="10" hint=""/>
<node index="5" text="0:31"
resource-id="az.kapitalbank.mbanking:id/transaction_time"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[232,1821][294,1864]"
drawing-order="6" hint=""/>
<node index="6" text="・Коммуналка"
resource-id="az.kapitalbank.mbanking:id/transaction_category"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[294,1819][874,1867]"
drawing-order="7" hint=""/>
</node>
<node index="3" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="true"
enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,1900][1038,2109]"
drawing-order="4" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/transaction_logo_bg"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[84,1926][200,2042]"
drawing-order="1" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/transaction_logo_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[100,1942][184,2026]"
drawing-order="2" hint=""/>
<node index="2"
text="Проверка привязки карты в Birbank"
resource-id="az.kapitalbank.mbanking:id/transaction_title"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[232,1926][813,2035]"
drawing-order="5" hint=""/>
<node index="3" text="0,05 ₼"
resource-id="az.kapitalbank.mbanking:id/transaction_amount"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[897,1926][996,1983]"
drawing-order="8" hint=""/>
<node index="4" text="0:31"
resource-id="az.kapitalbank.mbanking:id/transaction_time"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[232,2040][294,2083]"
drawing-order="6" hint=""/>
<node index="5" text="・Коммуналка"
resource-id="az.kapitalbank.mbanking:id/transaction_category"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[294,2038][996,2086]"
drawing-order="7" hint=""/>
</node>
</node>
</node>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/spr_tv_pfm_operation_history"
class="android.view.View"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[84,2140][996,2143]" drawing-order="4"
hint=""/>
<node index="4" text="История платежей"
resource-id="az.kapitalbank.mbanking:id/tv_pfm_operation_history"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[42,2143][1038,2290]" drawing-order="5"
hint=""/>
</node>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/pager_actions"
class="androidx.recyclerview.widget.RecyclerView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,2311][1080,2337]"
drawing-order="8" hint="">
<node index="0" text="" resource-id=""
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,2311][1080,2337]" drawing-order="1"
hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,2337][1080,2400]" drawing-order="2" hint=""/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,188 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2337]"
drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/lyCord"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/rootView"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/authContainer"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,136][1080,2337]" drawing-order="2"
hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,136][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/ivLogo"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[387,273][694,386]" drawing-order="1" hint=""/>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/ivAvatar"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[467,470][614,617]" drawing-order="2" hint=""/>
<node index="2" text="Добрый день"
resource-id="az.kapitalbank.mbanking:id/tvGreeting"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,659][1080,716]" drawing-order="3" hint=""/>
<node index="3" text="Nicat Cəlilov"
resource-id="az.kapitalbank.mbanking:id/tvUsername"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,721][1080,792]" drawing-order="4" hint=""/>
<node index="4" text="" resource-id="az.kapitalbank.mbanking:id/dsPasscodeInput"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,1042][1038,1097]" drawing-order="5" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[42,1042][1038,1097]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/passcode_first"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,1042][1038,1097]" drawing-order="2"
hint=""/>
</node>
</node>
<node index="5" text="" resource-id="az.kapitalbank.mbanking:id/dsNumpad"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,1347][1080,2190]" drawing-order="10" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/dsNumpadRecycler"
class="android.widget.GridView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,1559][1038,2190]" drawing-order="1" hint="">
<node index="0" text="1" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,1559][353,1701]" drawing-order="1" hint=""/>
<node index="1" text="2" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[395,1559][685,1701]" drawing-order="2" hint=""/>
<node index="2" text="3" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[727,1559][1038,1701]" drawing-order="3" hint=""/>
<node index="3" text="4" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,1721][353,1863]" drawing-order="4" hint=""/>
<node index="4" text="5" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[395,1721][685,1863]" drawing-order="5" hint=""/>
<node index="5" text="6" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[727,1721][1038,1863]" drawing-order="6" hint=""/>
<node index="6" text="7" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,1883][353,2025]" drawing-order="7" hint=""/>
<node index="7" text="8" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[395,1883][685,2025]" drawing-order="8" hint=""/>
<node index="8" text="9" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[727,1883][1038,2025]" drawing-order="9" hint=""/>
<node index="9" text="Не удается войти" resource-id=""
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,2045][353,2187]" drawing-order="10" hint=""/>
<node index="10" text="0" resource-id="" class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true" enabled="true"
focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[395,2045][685,2187]" drawing-order="11" hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,2337][1080,2400]" drawing-order="2" hint=""/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,800 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_drawer"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_screen_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/root_progress_panel"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][1080,2337]" drawing-order="1"
hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/transfers"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/header"
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,347]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/back_layout"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,226]" drawing-order="1" hint="">
<node index="0" text="" resource-id=""
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,79][1080,226]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/header_back"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc="Back"
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,79][147,226]" drawing-order="1"
hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/header_right"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc="Back"
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[933,79][1080,226]" drawing-order="6"
hint=""/>
</node>
</node>
<node index="1" text="На карту любого банка"
resource-id="az.kapitalbank.mbanking:id/title"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,226][851,326]" drawing-order="2" hint=""/>
</node>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/body"
class="android.widget.ScrollView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,347][1080,2122]" drawing-order="2" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,347][1080,2038]"
drawing-order="1" hint="">
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/group_details"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,347][1080,2038]" drawing-order="7"
hint=""/>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/source_container"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,368][1080,716]" drawing-order="3" hint="">
<node index="0" text="" resource-id=""
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,368][1080,716]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/product_view"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,368][1080,716]"
drawing-order="1" hint="">
<node index="0" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,368][1080,716]" drawing-order="1" hint="">
<node index="0" text="Оплатить с"
resource-id="az.kapitalbank.mbanking:id/title"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,411][248,464]"
drawing-order="1" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/container_product"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,506][1038,674]"
drawing-order="3" hint="">
<node index="0" text="" resource-id=""
class="androidx.cardview.widget.CardView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,506][1038,674]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/clContainer"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[42,506][1038,674]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/card"
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[74,546][210,635]"
drawing-order="1" hint="">
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_card"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="TODO"
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[74,546][210,635]"
drawing-order="2" hint=""/>
<node index="2" text="• 2480"
resource-id="az.kapitalbank.mbanking:id/card_text"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[139,598][199,627]"
drawing-order="4" hint=""/>
</node>
<node index="1" text="Birbank Cashback"
resource-id="az.kapitalbank.mbanking:id/tv_card_name"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[242,538][932,581]"
drawing-order="2" hint=""/>
<node index="2" text="50.00 AZN"
resource-id="az.kapitalbank.mbanking:id/tv_card_balance"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[242,591][932,642]"
drawing-order="4" hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/iv_selection"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[964,569][1006,611]"
drawing-order="7" hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/destination_container"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,716][1080,996]" drawing-order="4" hint="">
<node index="0" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,716][1080,996]" drawing-order="1"
hint="">
<node index="0" text="Зачислить на"
resource-id="az.kapitalbank.mbanking:id/title"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,758][289,822]"
drawing-order="1" hint=""/>
<node NAF="true" index="1" text=""
resource-id="az.kapitalbank.mbanking:id/flow_suggestion"
class="android.view.View"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[598,737][1038,821]"
drawing-order="3" hint=""/>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/iv_suggestion"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc="TODO"
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[630,758][672,800]"
drawing-order="4" hint=""/>
<node index="3" text="Выбрать получателя"
resource-id="az.kapitalbank.mbanking:id/tv_suggestion"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[693,758][1006,801]"
drawing-order="5" hint=""/>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/card_view"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,822][1080,996]"
drawing-order="2" hint="">
<node index="0" text="" resource-id=""
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,822][1080,996]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/card_number"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,822][1080,996]"
drawing-order="2" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/root"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,822][1038,996]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/card"
class="androidx.cardview.widget.CardView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[42,833][1038,985]"
drawing-order="3" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/input_container"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[42,833][1038,985]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/input_layout"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[42,833][1038,985]"
drawing-order="2" hint="">
<node index="0" text=""
resource-id=""
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[42,833][1038,985]"
drawing-order="1" hint="">
<node index="0"
text="Номер карты"
resource-id="az.kapitalbank.mbanking:id/value"
class="android.widget.EditText"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="true"
password="false"
selected="false"
bounds="[42,833][1038,985]"
drawing-order="1"
hint="Номер карты"/>
<node index="1" text=""
resource-id=""
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[901,833][1038,985]"
drawing-order="3" hint="">
<node index="0" text=""
resource-id=""
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[901,833][1038,985]"
drawing-order="2"
hint="">
<node NAF="true"
index="0" text=""
resource-id="az.kapitalbank.mbanking:id/text_input_end_icon"
class="android.widget.ImageButton"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[912,846][1038,972]"
drawing-order="1"
hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="4" text="Детали перевода"
resource-id="az.kapitalbank.mbanking:id/details_title"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,1038][363,1091]" drawing-order="8"
hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/amount_view"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,1102][1080,1535]" drawing-order="10" hint="">
<node index="0" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,1102][1080,1535]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/amount"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,1102][739,1330]"
drawing-order="4" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/root"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[42,1102][718,1330]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/card"
class="androidx.cardview.widget.CardView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,1113][718,1265]"
drawing-order="3" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/input_container"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[42,1113][718,1265]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/input_layout"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[42,1113][718,1265]"
drawing-order="2" hint="">
<node index="0" text="" resource-id=""
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[42,1113][718,1265]"
drawing-order="1" hint="">
<node index="0" text="Сумма"
resource-id="az.kapitalbank.mbanking:id/value"
class="android.widget.EditText"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="true"
enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="true"
password="false" selected="false"
bounds="[42,1113][718,1265]"
drawing-order="1" hint="Сумма"/>
<node index="1" text="" resource-id=""
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[581,1113][718,1265]"
drawing-order="3" hint="">
<node index="0" text=""
resource-id=""
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[581,1113][718,1265]"
drawing-order="2" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/text_input_end_icon"
class="android.widget.ImageButton"
package="az.kapitalbank.mbanking"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[592,1126][718,1252]"
drawing-order="1"
hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="Mин: 0.01AZN, Макс: 50.00AZN"
resource-id="az.kapitalbank.mbanking:id/helper"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[47,1276][557,1319]"
drawing-order="1" hint=""/>
</node>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/currency_view"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[739,1113][1038,1265]"
drawing-order="6" hint="">
<node index="0" text="" resource-id=""
class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[739,1113][1038,1265]" drawing-order="1"
hint="">
<node index="0" text="" resource-id=""
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[781,1139][954,1240]"
drawing-order="1" hint="">
<node index="0" text="Валюта"
resource-id="az.kapitalbank.mbanking:id/title_view"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[781,1139][895,1182]"
drawing-order="1" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/spinner"
class="android.widget.Spinner"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="true"
enabled="true" focusable="true"
focused="false" scrollable="true"
long-clickable="true" password="false"
selected="false" bounds="[781,1187][954,1240]"
drawing-order="3" hint="">
<node index="0" text="AZN"
resource-id="az.kapitalbank.mbanking:id/text"
class="android.widget.TextView"
package="az.kapitalbank.mbanking"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false"
bounds="[781,1187][954,1240]"
drawing-order="1" hint=""/>
</node>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/dropdown_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[954,1168][996,1210]"
drawing-order="2" hint=""/>
</node>
</node>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/fixed_buttons"
class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,1330][1080,1519]"
drawing-order="5" hint="">
<node index="0" text="10"
resource-id="az.kapitalbank.mbanking:id/pay_button"
class="android.widget.Button"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[42,1351][346,1498]" drawing-order="1"
hint=""/>
<node index="1" text="20"
resource-id="az.kapitalbank.mbanking:id/pay_button"
class="android.widget.Button"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[388,1351][692,1498]" drawing-order="2"
hint=""/>
<node index="2" text="50"
resource-id="az.kapitalbank.mbanking:id/pay_button"
class="android.widget.Button"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[734,1351][1038,1498]" drawing-order="3"
hint=""/>
</node>
</node>
</node>
</node>
</node>
<node index="2" text="" resource-id="" class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,2059][1080,2143]" drawing-order="3" hint=""/>
<node index="3" text="Продолжить" resource-id="az.kapitalbank.mbanking:id/next"
class="android.widget.Button" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="false" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[42,2143][1038,2295]" drawing-order="6" hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@ -1,719 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/action_bar_root"
class="android.widget.LinearLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
drawing-order="2" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_drawer"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/activity_screen_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2158]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/root_progress_panel"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][1080,2158]" drawing-order="1"
hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][1080,2158]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/header"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,0][1080,226]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,79][1080,226]"
drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/header_back"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="Back" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,79][147,226]" drawing-order="1"
hint=""/>
<node index="1" text="Переводы"
resource-id="az.kapitalbank.mbanking:id/header_text"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[147,79][918,226]" drawing-order="4"
hint=""/>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/header_text_one"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[918,79][995,226]" drawing-order="5"
hint=""/>
</node>
</node>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/rvCategories"
class="androidx.recyclerview.widget.RecyclerView"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,247][1080,1087]" drawing-order="2" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/cellCategory"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,247][1080,415]" drawing-order="1" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,247][1080,415]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[42,268][200,394]"
drawing-order="3" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,268][168,394]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,268][167,393]"
drawing-order="1" hint=""/>
</node>
<node index="2" text="Между моими картами и счетами"
resource-id="az.kapitalbank.mbanking:id/tv_header"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[200,307][922,356]" drawing-order="4"
hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[200,307][922,356]"
drawing-order="6" hint=""/>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[933,279][1017,384]"
drawing-order="10" hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[933,279][1017,384]"
drawing-order="13" hint=""/>
<node index="6" text=""
resource-id="az.kapitalbank.mbanking:id/separator"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[168,412][1038,415]"
drawing-order="14" hint=""/>
</node>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/cellCategory"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,415][1080,583]" drawing-order="2" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,415][1080,583]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[42,436][200,562]"
drawing-order="3" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,436][168,562]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,436][167,561]"
drawing-order="1" hint=""/>
</node>
<node index="2" text="На карту любого банка"
resource-id="az.kapitalbank.mbanking:id/tv_header"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[200,475][922,524]" drawing-order="4"
hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[200,475][922,524]"
drawing-order="6" hint=""/>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[933,447][1017,552]"
drawing-order="10" hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[933,447][1017,552]"
drawing-order="13" hint=""/>
<node index="6" text=""
resource-id="az.kapitalbank.mbanking:id/separator"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[168,580][1038,583]"
drawing-order="14" hint=""/>
</node>
</node>
<node index="2" text=""
resource-id="az.kapitalbank.mbanking:id/cellCategory"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,583][1080,751]" drawing-order="3" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,583][1080,751]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[42,604][200,730]"
drawing-order="3" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,604][168,730]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,604][167,729]"
drawing-order="1" hint=""/>
</node>
<node index="2" text="Перевод другу"
resource-id="az.kapitalbank.mbanking:id/tv_header"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[200,643][922,692]" drawing-order="4"
hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[200,643][922,692]"
drawing-order="6" hint=""/>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[933,615][1017,720]"
drawing-order="10" hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[933,615][1017,720]"
drawing-order="13" hint=""/>
<node index="6" text=""
resource-id="az.kapitalbank.mbanking:id/separator"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[168,748][1038,751]"
drawing-order="14" hint=""/>
</node>
</node>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/cellCategory"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,751][1080,919]" drawing-order="4" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,751][1080,919]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[42,772][200,898]"
drawing-order="3" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,772][168,898]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,772][167,897]"
drawing-order="1" hint=""/>
</node>
<node index="2" text="Запрос средств у друзей"
resource-id="az.kapitalbank.mbanking:id/tv_header"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[200,811][922,860]" drawing-order="4"
hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[200,811][922,860]"
drawing-order="6" hint=""/>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[933,783][1017,888]"
drawing-order="10" hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[933,783][1017,888]"
drawing-order="13" hint=""/>
<node index="6" text=""
resource-id="az.kapitalbank.mbanking:id/separator"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[168,916][1038,919]"
drawing-order="14" hint=""/>
</node>
</node>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/cellCategory"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,919][1080,1087]" drawing-order="5" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,919][1080,1087]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/flow_start_images"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[42,940][200,1066]"
drawing-order="3" hint=""/>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_field_l"
class="android.widget.FrameLayout"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,940][168,1066]" drawing-order="1"
hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/iv_start_icon_l"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[42,940][168,1066]"
drawing-order="1" hint=""/>
</node>
<node index="2" text="Перевод через AniPay"
resource-id="az.kapitalbank.mbanking:id/tv_header"
class="android.widget.TextView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[200,979][922,1028]"
drawing-order="4" hint=""/>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/flow_center_text"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[200,979][922,1028]"
drawing-order="6" hint=""/>
<node index="4" text=""
resource-id="az.kapitalbank.mbanking:id/iv_end_icon"
class="android.widget.ImageView"
package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[933,951][1017,1056]"
drawing-order="10" hint=""/>
<node index="5" text=""
resource-id="az.kapitalbank.mbanking:id/flow_end_items"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[933,951][1017,1056]" drawing-order="13" hint=""/>
<node index="6" text=""
resource-id="az.kapitalbank.mbanking:id/separator"
class="android.view.View" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[168,1084][1038,1087]" drawing-order="14" hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/bnv_activity_screen_navigation"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,2158][1080,2400]" drawing-order="2" hint="">
<node index="0" text="" resource-id="" class="android.view.ViewGroup"
package="az.kapitalbank.mbanking" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,2158][1080,2305]" drawing-order="1" hint="">
<node index="0" text="" resource-id="az.kapitalbank.mbanking:id/tab_home"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="Главная" checkable="false" checked="false" clickable="false"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="true"
bounds="[0,2158][216,2305]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="true"
bounds="[59,2236][157,2305]" drawing-order="2" hint="">
<node index="0" text="Главная"
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_large_label_view"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="true"
bounds="[59,2236][157,2302]" drawing-order="2" hint=""/>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="true"
bounds="[76,2179][139,2242]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="true"
bounds="[76,2179][139,2242]" drawing-order="2" hint=""/>
</node>
</node>
<node index="1" text="" resource-id="az.kapitalbank.mbanking:id/tab_umico_market"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="Выгода" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[216,2158][432,2305]" drawing-order="2" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[278,2236][369,2305]" drawing-order="2" hint="">
<node index="0" text="Выгода"
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[278,2236][369,2302]" drawing-order="1" hint=""/>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[292,2179][355,2242]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[292,2179][355,2242]" drawing-order="2" hint=""/>
</node>
</node>
<node index="2" text="" resource-id="az.kapitalbank.mbanking:id/tab_qr"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="QR" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[432,2158][648,2305]" drawing-order="3" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[508,2179][571,2242]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[508,2179][571,2242]" drawing-order="2" hint=""/>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[522,2236][557,2305]" drawing-order="2" hint="">
<node index="0" text="QR"
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[522,2236][556,2302]" drawing-order="1" hint=""/>
</node>
</node>
<node index="3" text=""
resource-id="az.kapitalbank.mbanking:id/tab_payments_and_transfers"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="Платежи" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[648,2158][864,2305]" drawing-order="4" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[701,2236][810,2305]" drawing-order="2" hint="">
<node index="0" text="Платежи"
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[701,2236][810,2302]" drawing-order="1" hint=""/>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[724,2179][787,2242]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[724,2179][787,2242]" drawing-order="2" hint=""/>
</node>
</node>
<node index="4" text="" resource-id="az.kapitalbank.mbanking:id/tab_more"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="Еще" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[864,2158][1080,2305]" drawing-order="5" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_container"
class="android.widget.FrameLayout" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[940,2179][1003,2242]" drawing-order="1" hint="">
<node index="0" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_icon_view"
class="android.widget.ImageView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[940,2179][1003,2242]" drawing-order="2" hint=""/>
</node>
<node index="1" text=""
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_labels_group"
class="android.view.ViewGroup" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[946,2236][998,2305]" drawing-order="2" hint="">
<node index="0" text="Еще"
resource-id="az.kapitalbank.mbanking:id/navigation_bar_item_small_label_view"
class="android.widget.TextView" package="az.kapitalbank.mbanking"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[946,2236][998,2302]" drawing-order="1" hint=""/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

View File

@ -1,297 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Все продукты" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][339,173]"/>
<node index="2" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[699,89][712,157]"/>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,188][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,188][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,190][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,190][720,773]">
<node index="0"
text="Нажмите на сердечко для отображения на главной"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,226][690,256]"/>
<node index="1" text="Карты" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[78,299][148,327]"/>
<node index="2"
text="Классическая карта МИР Моментального выпуска (Своя карта). Дебетовая. Номер карты с последними цифрами 5 2 6 4. Сумма: 160 рублей 0 копеек"
resource-id="aft-rsProduct"
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,370][690,442]"/>
<node index="3"
text="Классическая карта МИР. Дебетовая. Номер карты с последними цифрами 7 1 8 3. Сумма: 280 рублей 0 копеек"
resource-id="aft-rsProduct"
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,466][690,537]"/>
<node index="4"
text="Программа лояльности Подключить"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,563][690,698]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[1,1377][148,1439]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[144,1377][290,1439]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[286,1377][433,1439]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[429,1377][575,1439]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[571,1377][718,1439]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

View File

@ -1,205 +0,0 @@
Сбербанк
Т-Банк
ВТБ
Альфа-Банк
Филиал Открытие БМ-Банк
Почта Банк
Райффайзен Банк
Газпромбанк
Совкомбанк
ПСБ
Ак Барс Банк
МКБ (Московский кредитный банк)
Банк Синара
МТС-Банк
Золотая Корона Korona (РНКО Платежный Центр)
Банк Санкт-Петербург
Банк Русский Стандарт
VK Pay - ВК Платёжные решения
Wallet One (РНКО Единая касса)
Wildberries (Вайлдберриз Банк)
АБ РОССИЯ
АИКБ Енисейский объединенный банк
АКБ Держава
АКБ ЕВРОФИНАНС МОСНАРБАНК
АКБ Ланта Банк
АКБ НРБанк
АКБ СЛАВИЯ
АКБ Тендер Банк
АКИБАНК
Абсолют Банк
Авито Кошелек (Платежный конструктор)
Авто Финанс Банк
Автоторгбанк
Азиатско-Тихоокеанский Банк
Алеф-Банк
Алмазэргиэнбанк
БАНК МОСКВА СИТИ
БАНК ОРЕНБУРГ
БАНК СГБ
БАНК СНГБ
БАНК УРАЛСИБ
ББР Банк
БКС Банк
Банк АВАНГАРД
Банк АЛЕКСАНДРОВСКИЙ
Банк Аверс
Банк Агророс
Банк Акцепт
Банк БЖФ
Банк ВБРР
Банк Венец
Банк Вологжанин
Банк ДОМ.РФ
Банк ЗЕНИТ
Банк Заречье
Банк ИПБ
Банк ИТУРУП
Банк Интеза
Банк Йошкар-Ола
Банк Кремлевский
Банк Кузнецкий
Банк Левобережный
Банк МБА МОСКВА
Банк НОВИКОМ (НОВИКОМБАНК)
Банк Национальный стандарт
Банк Объединенный капитал
Банк Оранжевый
Банк ПСКБ
Банк Приморье
Банк РЕСО Кредит
Банк РСИ
Банк Развитие-Столица
Банк Саратов
Банк Снежинский
Банк Уралфинанс
Банк ФИНАМ
Банк Финсервис
Банк ЦентроКредит
Банк ЧБРР
Бланк банк
Братский АНКБ
БыстроБанк
ВЛАДБИЗНЕСБАНК
ВНЕШФИНБАНК
ВУЗ-банк
ГЕНБАНК
ГОРБАНК
ГУТА-БАНК
Газтрансбанк
Газэнергобанк
Далена Банк
Дальневосточный банк
Датабанк
Драйв Клик Банк
ЖИВАГО БАНК
Земский банк
ИК Банк
ИС Банк
ИШБАНК
Инбанк
Ингосстрах Банк
КБ РостФинанс
КБ АГРОПРОМКРЕДИТ
КБ АРЕСБАНК
КБ Долинск
КБ Крокус Банк
КБ ЛОКО-Банк
КБ Модульбанк
КБ Москоммерцбанк
КБ Пойдём
КБ Солидарность
КБ Стройлесбанк
КБ Хлынов
КБ ЭНЕРГОТРАНСБАНК
КБЭР Банк Казани
КОШЕЛЕВ-БАНК
Контур.Банк
Кошелек ЦУПИС (Мобильная карта)
Кредит Европа Банк (Россия)
Кредит Урал Банк
Кубань Кредит
Кубаньторгбанк
Кузнецкбизнесбанк
МБ Банк
МЕЖДУНАРОДНЫЙ ФИНАНСОВЫЙ КЛУБ
МЕТКОМБАНК
МОНЕТА
МОРСКОЙ БАНК
МОСКОМБАНК
МС Банк Рус
МТС Деньги (ЭКСИ Банк)
Металлинвестбанк
Мир Привилегий (МП Банк)
НБД-Банк
НИКО-БАНК
НК Банк
НКО МОБИ.Деньги
НКО Расчетные Решения
НОКССБАНК
НС Банк
Нацинвестпромбанк
Новобанк
Новый век
Норвик Банк
ОТП Банк
Озон Банк (Ozon)
ПЕРВОУРАЛЬСКБАНК
Первый Дортрансбанк
Первый Инвестиционный Банк
Прио-Внешторгбанк
ПроБанк
РНКБ Банк
РУСНАРБАНК
Реалист Банк
Ренессанс Банк (Ренессанс Кредит)
Рокетбанк
РосДорБанк
Роял Кредит Банк
Русьуниверсалбанк
СДМ-Банк
СИБСОЦБАНК
СИНКО-БАНК
СКБ Примсоцбанк
СОЦИУМ БАНК
Свой Банк
Северный Народный Банк
Солид Банк
Ставропольпромстройбанк
ТАТСОЦБАНК
ТРАНСКАПИТАЛБАНК
Таврический Банк
Тимер Банк
Тойота Банк
Тольяттихимбанк
Томскпромстройбанк
Точка Банк
Трансстройбанк
УБРиР
УКБ Белгородсоцбанк
УРАЛПРОМБАНК
Углеметбанк
Урал ФД
ФИНСТАР БАНК
ФОРА-БАНК
Форштадт
Хайс
Хакасский муниципальный банк
ЦМРБанк
Центр-инвест
Цифра банк
ЧЕЛИНДБАНК
ЧЕЛЯБИНВЕСТБАНК
ЭЛПЛАТ
Экономбанк
Экспобанк
Энергобанк
Эс-Би-Ай Банк
ЮГ-Инвестбанк
ЮМани
ЮНИСТРИМ БАНК
ЮниКредит Банк
ЯРИНТЕРБАНК
Яндекс
банк Раунд
банк Элита

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

View File

@ -1,430 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Выписка" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][260,173]"/>
<node index="2" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[641,89][712,157]">
<node index="0"
text="Информирование о сроке отображения операций по счету"
resource-id="aft-rbtnClass-buttonIcon"
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[650,89][712,157]"/>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,160][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="true"
focused="false" scrollable="true"
long-clickable="false" password="false"
selected="false" bounds="[0,160][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,162][720,1439]">
<node index="0" text="по счету 40817 .... 2077"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[206,205][513,258]"/>
<node index="1"
text="Период с 08.05.2025 по 10.05.2025 More"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,295][720,391]"/>
<node index="2"
text="Подтвержденные Ожидающие обработки"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,383][720,477]"/>
<node index="3" text="" resource-id=""
class="android.widget.ListView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,473][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,473][720,798]">
<node index="0" text="09.05.2025"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,473][691,517]"/>
<node index="1"
text="Перевод через СБП от Надежда Юрьевна К (+7(964)-181-51-46) из Сбербанк на 40817810328000022077 . Идентификатор операции в СБП С2С A5129141229250080000030011500701 , Дата операции 09.05.2025 17:12:29 Статус перевода Исполнен + 655 точка 00 Рубль"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,533][691,779]"/>
</node>
<node index="1" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,794][720,1017]">
<node index="0" text="08.05.2025"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,794][691,837]"/>
<node index="1"
text="Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +79641815146, ID перевода 448627512, дата 08.05.2025 - 250 точка 00 Рубль"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,854][691,995]"/>
</node>
<node index="2" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,1012][720,1193]">
<node index="0"
text="Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815146, ID перевода 448628517, дата 08.05.2025 - 305 точка 00 Рубль"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,1030][691,1173]"/>
</node>
<node index="3" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,1188][720,1370]">
<node index="0"
text="Перевод Надежда Юрьевна К** в Сбербанк через СБП, по номеру телефона +79641815146, ID перевода 448713642, дата 08.05.2025 - 405 точка 00 Рубль"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,1208][691,1349]"/>
</node>
<node index="4" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,1366][720,1439]">
<node index="0"
text="Перевод Надежда Юрьевна К** в Альфа-Банк через СБП, по номеру телефона +79641815146, ID перевода 448716504, дата 08.05.2025 - 310 точка 00 Рубль"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[28,1385][691,1439]"/>
</node>
</node>
</node>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[575,1235][684,1343]">
<node index="0" text="Отправить" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[575,1235][684,1343]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[1,1377][148,1439]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[144,1377][290,1439]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[286,1377][433,1439]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[429,1377][575,1439]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[571,1377][718,1439]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

View File

@ -1,869 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Мои продукты" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][350,173]"/>
<node index="2" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[699,89][712,157]"/>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="true" focused="false" scrollable="true"
long-clickable="false" password="false" selected="false"
bounds="[0,160][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,162][720,588]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,162][720,588]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,162][80,588]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,237][24,588]">
<node index="0" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,82][258,382]"/>
<node index="1" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]">
<node index="0" text=""
resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]">
<node index="0" text="160"
resource-id="aft-operationHistory-money"
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="1" text="точка 00"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="Рубль"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="3" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
</node>
<node index="1"
text="Классическая карта МИР Моментального выпуска (Своя карта)"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="дебетовая"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="3" text="** 5264"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node NAF="true" index="4" text=""
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="5" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
<node index="1" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,162][720,588]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[54,237][665,588]">
<node index="0" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[296,82][720,382]"/>
<node index="1" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,443][423,860]"/>
<node index="2" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[99,277][620,550]">
<node index="0" text=""
resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,312][620,368]">
<node index="0" text="2 095"
resource-id="aft-operationHistory-money"
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,312][215,367]"/>
<node index="1" text="точка 00"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[211,312][277,367]"/>
<node index="2" text="Рубль"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[286,312][315,367]"/>
<node index="3" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[311,312][371,368]"/>
</node>
<node index="1"
text="Классическая карта МИР"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,380][620,421]"/>
<node index="2" text="дебетовая"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,419][620,458]"/>
<node index="3" text="** 7183"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,517][620,550]"/>
<node NAF="true" index="4" text=""
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[571,277][620,322]"/>
<node index="5" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[541,524][639,550]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[54,172][665,211]"/>
</node>
</node>
<node index="1" text="Пополнить" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[78,622][268,773]"/>
<node index="2" text="Оплатить" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[264,622][455,773]"/>
<node index="3" text="Бло­ки­ровка" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[451,622][641,773]"/>
<node index="4" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[30,788][352,880]"/>
<node index="5" text="Действия" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[367,788][691,880]"/>
<node index="6" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,880][720,1439]">
<node index="0" text="Настройки" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[30,880][691,959]"/>
<node index="1" text="Новый ПИН-код" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,957][691,1072]"/>
<node index="2" text="Привязать платёжный аксессуар"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,1070][691,1184]"/>
<node index="3" text="Лимиты и ограничения по карте"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,1180][691,1295]"/>
<node index="4" text="Переименовать" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,1293][691,1409]"/>
<node index="5" text="Услуги" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[30,1405][691,1439]"/>
<node index="6" text='Оформить овердрафт "До зарплаты"'
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="7" text="Снятие наличных по QR-коду"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="8" text="Подключить автопополнение"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="9" text="Уведомления по счету"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="10" text="Выпустить карту" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="11" text="Ссылка для пополнения карты"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="12" text="Сформировать справку"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="13" text="Информация" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
<node index="14" text="Реквизиты карты" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="15" text="Выписка" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="16"
text="Подключенные программы страхования"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="17" text="Анализ финансов" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[1,1377][148,1439]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[144,1377][290,1439]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[286,1377][433,1439]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[429,1377][575,1439]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[571,1377][718,1439]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

View File

@ -1,898 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Мои продукты" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][350,173]"/>
<node index="2" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[699,89][712,157]"/>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="true" focused="false" scrollable="true"
long-clickable="false" password="false" selected="false"
bounds="[0,160][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,162][720,588]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,162][720,588]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,162][80,588]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,237][24,588]">
<node index="0" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,82][258,382]"/>
<node index="1" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]">
<node index="0" text=""
resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]">
<node index="0" text="160"
resource-id="aft-operationHistory-money"
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="1" text="точка 00"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="Рубль"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="3" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
</node>
<node index="1"
text="Классическая карта МИР Моментального выпуска (Своя карта)"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="дебетовая"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="3" text="** 5264"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node NAF="true" index="4" text=""
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
<node index="5" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
<node index="1" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,162][720,588]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[54,237][665,588]">
<node index="0" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[296,82][720,382]"/>
<node index="1" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,443][423,860]"/>
<node index="2" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[99,277][620,550]">
<node index="0" text=""
resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,312][620,368]">
<node index="0" text="280"
resource-id="aft-operationHistory-money"
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,312][178,367]"/>
<node index="1" text="точка 00"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[174,312][240,367]"/>
<node index="2" text="Рубль"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[249,312][277,367]"/>
<node index="3" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[275,312][333,368]"/>
</node>
<node index="1"
text="Классическая карта МИР"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,380][620,421]"/>
<node index="2" text="дебетовая"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,419][620,458]"/>
<node index="3" text="** 7183"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[99,517][620,550]"/>
<node NAF="true" index="4" text=""
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[571,277][620,322]"/>
<node index="5" text=""
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[541,524][639,550]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[54,172][665,211]"/>
</node>
</node>
<node index="1" text="Пополнить" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[78,622][268,773]"/>
<node index="2" text="Оплатить" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[264,622][455,773]"/>
<node index="3" text="Бло­ки­ровка" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[451,622][641,773]"/>
<node index="4" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[30,788][352,880]"/>
<node index="5" text="Действия" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[367,788][691,880]"/>
<node index="6" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,880][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,880][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,880][720,1439]">
<node index="0" text=""
resource-id="tab-content-12"
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="1" text=""
resource-id="tab-content-13"
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,880][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,880][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,880][720,1025]">
<node index="0"
text="27.04.25 29.04.25"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[277,910][423,995]"/>
<node index="1" text=""
resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="false"
enabled="true"
focusable="false"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[30,910][264,995]">
<node index="0"
text="Все операции "
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[50,937][241,968]"/>
</node>
</node>
<node index="1" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[0,1023][720,1439]">
<node index="0"
text="Сегодня, Вторник Перевод ВЛАДИСЛАВ НИКОЛАЕВИЧ К** в Т-Банк через СБП, по номеру телефона +7985553... Минус 10 рублей 0 копеек"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,1023][720,1349]"/>
<node index="1"
text="DBO TRANSFER RSHB INTERNET-BANK Минус 10 рублей 0 копеек"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,1343][720,1439]"/>
<node index="2"
text="Вчера, Понедельник P2P DBO RSHB INTERNET-BANK Плюс 300 рублей 0 копеек"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo"
content-desc=""
checkable="false"
checked="false"
clickable="true"
enabled="true"
focusable="true"
focused="false"
scrollable="false"
long-clickable="false"
password="false"
selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[1,1377][148,1439]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[144,1377][290,1439]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[286,1377][433,1439]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[429,1377][575,1439]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[571,1377][718,1439]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

View File

@ -1,111 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]"/>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,1126][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1126][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1186][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,1186][720,1439]">
<node index="0" text="РСХБ Онлайн" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,1186][720,1283]"/>
<node index="1" text="Зачисления" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,1278][720,1375]"/>
<node index="2" text="Все операции" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,1372][720,1439]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

View File

@ -1,89 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]"/>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="Ошибка" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="true" focused="true"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[95,627][624,965]">
<node index="0"
text="Невозможно зачислить сумму перевода на счет Получателя"
resource-id="" class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[140,751][579,830]"/>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[95,865][624,965]">
<node index="0" text="Ок" resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[485,880][609,950]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

View File

@ -1,307 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,112][251,202]">
<node index="0" text="Меню" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,112][88,202]"/>
</node>
<node index="1" text="Кю Ар сканер" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[545,112][605,202]"/>
<node index="2"
text="Уведомления. Новых уведомлений нет"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[631,112][691,202]"/>
<node index="3" text="Введите ПИН" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[90,408][630,451]"/>
<node index="4" text="1" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[108,547][253,689]"/>
<node index="5" text="2" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[288,547][431,689]"/>
<node index="6" text="3" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[466,547][611,689]"/>
<node index="7" text="4" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[108,727][253,869]"/>
<node index="8" text="5" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[288,727][431,869]"/>
<node index="9" text="6" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[466,727][611,869]"/>
<node index="10" text="7" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[108,905][253,1049]"/>
<node index="11" text="8" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[288,905][431,1049]"/>
<node index="12" text="9" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[466,905][611,1049]"/>
<node index="13" text="0" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[288,1083][431,1227]"/>
<node index="14" text="Стереть" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[466,1083][611,1227]"/>
<node index="15" text="Выйти" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[90,1263][630,1302]"/>
<node index="16" text=""
resource-id="loginEnterResults"
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[88,1297][93,1302]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]"/>
<node index="2" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="3" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="Внимание" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="true" focused="true"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[95,644][624,946]">
<node index="0" text="Сессия завершена" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[95,772][624,848]"/>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[95,847][624,946]">
<node index="0" text="Ок" resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[485,862][609,931]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@ -1,307 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Выписка" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][260,173]"/>
<node index="2" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[641,89][712,157]">
<node index="0"
text="Информирование о сроке отображения операций по счету"
resource-id="aft-rbtnClass-buttonIcon"
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[650,89][712,157]"/>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,160][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,160][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,162][720,571]">
<node index="0" text="по счету 40817 .... 2077"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[206,205][513,258]"/>
<node index="1"
text="Период с 02.06.2025 по 04.06.2025 More"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,295][720,391]"/>
<node index="2"
text="Подтвержденные Ожидающие обработки"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,383][720,477]"/>
<node index="3" text="" resource-id=""
class="android.widget.ListView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,475][720,475]"/>
<node index="4"
text="Операции с 02.06.2025 по 04.06.2025 отсутствуют"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,475][720,569]"/>
</node>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[575,1235][684,1343]">
<node index="0" text="Отправить" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[575,1235][684,1343]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[1,1377][148,1439]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[144,1377][290,1439]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[286,1377][433,1439]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[429,1377][575,1439]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[571,1377][718,1439]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 KiB

View File

@ -1,172 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]"/>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,284][720,1439]">
<node index="0" text="" resource-id="aft-popup-pushNotification"
class="android.view.View" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,284][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[15,299][706,803]">
<node index="0" text="Закрыть"
resource-id="aft-popup-pushNotification-iconClose"
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[615,329][676,393]"/>
</node>
<node index="1" text="Получайте новости с помощью push-уведомлений"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[45,742][676,893]"/>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[45,892][676,1028]">
<node index="0" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[75,940][120,987]"/>
<node index="1" text="Держите свои финансы под контролем"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[150,922][646,998]"/>
</node>
<node index="3" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[45,1028][676,1165]">
<node index="0" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[75,1077][120,1124]"/>
<node index="1"
text="Не пропускайте специальные предложения и рекомендации"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[150,1058][646,1135]"/>
</node>
<node index="4" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[45,1165][676,1302]">
<node index="0" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[75,1214][120,1261]"/>
<node index="1" text="Push-уведомления абсолютно бесплатны!"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[150,1195][646,1272]"/>
</node>
<node index="5" text="Позже"
resource-id="aft-popup-pushNotification-btnLater"
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[45,1330][354,1418]"/>
<node index="6" text="Включить"
resource-id="aft-popup-pushNotification-btnEnable"
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[365,1330][676,1418]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

View File

@ -1,333 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Перевод по телефону" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][461,173]"/>
<node index="2" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[699,89][712,157]"/>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,162][720,290]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[26,160][693,239]">
<node NAF="true" index="0" text="" resource-id=""
class="android.widget.EditText"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[58,179][663,220]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,284][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,284][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,286][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,286][720,1379]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[78,760][678,907]">
<node index="0"
text="Для перевода средств по номеру телефона предоставьте доступ к адресной книге в настройках смартфона"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[86,760][671,869]"/>
<node index="1" text="&#10;" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[667,832][667,869]"/>
<node index="2" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo"
content-desc="Перейти в настройки"
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="false" focused="false"
scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[226,867][530,905]">
<node index="0"
text="Перейти в настройки"
resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo"
content-desc="" checkable="false"
checked="false" clickable="false"
enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false"
password="false" selected="false"
bounds="[226,867][530,905]"/>
</node>
</node>
<node index="1" text=""
resource-id="phonebookSearchResult"
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[33,1373][39,1377]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1377][720,1439]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[1,1377][148,1439]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[144,1377][290,1439]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[286,1377][433,1439]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[429,1377][575,1439]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[571,1377][718,1439]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

View File

@ -1,305 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1031]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1031]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1031]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1031]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1032]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,166]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[7,89][78,157]">
<node index="0" text="Назад" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[7,89][69,157]"/>
</node>
<node index="1" text="Перевод по телефону" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[86,89][461,173]"/>
<node index="2" text="" resource-id=""
class="android.widget.TextView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[699,89][712,157]"/>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,162][720,290]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[26,160][693,239]">
<node index="0" text="+7 964 181 51 46" resource-id=""
class="android.widget.EditText"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="true"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[58,179][605,220]"/>
<node index="1" text="Очистить" resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[622,170][682,230]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,284][720,1032]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,284][720,1032]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,286][720,1032]">
<node index="0" text="" resource-id=""
class="android.view.View"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[0,286][720,1032]">
<node index="0" text=" Россельхозбанк"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[33,286][720,404]"/>
<node index="1" text=" Другой банк через СБП"
resource-id=""
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="true" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[33,398][720,517]"/>
<node index="2" text=""
resource-id="phonebookSearchResult"
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[33,509][39,515]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,1030][720,1030]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[575,1030][720,1030]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[31,989][112,1032]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[174,989][258,1032]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[290,987][429,1032]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[459,989][547,1032]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[624,989][671,1032]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

View File

@ -1,292 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.LinearLayout" package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][720,1439]">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="ru.rshb.dbo:id/action_bar_root" class="android.widget.LinearLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.webkit.WebView" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="true" focused="true" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1439]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,82][720,1377]">
<node index="0" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,82][720,796]">
<node index="0" text="Исполнен" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[230,329][489,397]"/>
<node index="1"
text="Перевод по номеру телефона в другой банк&#10;Владислав Николаевич К."
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[31,421][688,498]"/>
<node index="2" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[275,595][444,695]">
<node index="0" text="10"
resource-id="aft-operationHistory-money"
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[275,597][373,693]"/>
<node index="1" text="Рубль" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[393,597][444,693]"/>
<node index="2" text="" resource-id=""
class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false"
clickable="false" enabled="true"
focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[440,595][500,633]"/>
</node>
</node>
<node index="1" text="Детали операции" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,820][720,922]"/>
<node index="2"
text="Перевод через систему быстрых платежей"
resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="false"
enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[129,955][665,987]"/>
<node index="3" text="" resource-id=""
class="android.view.View" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[0,1027][720,1377]">
<node index="0" text="Добавить в избранное"
resource-id="saveTemplateButton"
class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,1057][691,1147]"/>
<node index="1" text="Сохранить или отправить чек"
resource-id="" class="android.widget.Button"
package="ru.rshb.dbo" content-desc=""
checkable="false" checked="false" clickable="true"
enabled="true" focusable="true" focused="false"
scrollable="false" long-clickable="false"
password="false" selected="false"
bounds="[30,1165][691,1257]"/>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false"
long-clickable="false" password="false" selected="false"
bounds="[0,1375][720,1439]">
<node index="0" text="Вернуться на главную" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="true"
focused="false" scrollable="false"
long-clickable="false" password="false"
selected="false" bounds="[30,1398][691,1439]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="Главная" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="История" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Своё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Платежи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Ещё" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
<node index="2" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="" resource-id="" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false"
checked="false" clickable="false" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]">
<node index="0" text="В банк" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="1" text="Кабинет" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="2" text="Продажи" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="3" text="Налоги" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
<node index="4" text="Профиль" resource-id=""
class="android.widget.Button" package="ru.rshb.dbo"
content-desc="" checkable="false" checked="false"
clickable="true" enabled="true" focusable="false"
focused="false" scrollable="false" long-clickable="false"
password="false" selected="false" bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="" class="android.widget.TextView"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false"
clickable="false" enabled="true" focusable="false" focused="false"
scrollable="false" long-clickable="false" password="false" selected="false"
bounds="[0,0][0,0]"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][720,82]"/>
<node index="2" text="" resource-id="android:id/navigationBarBackground" class="android.view.View"
package="ru.rshb.dbo" content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
selected="false" bounds="[0,0][0,0]"/>
</node>
</hierarchy>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

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