Compare commits

..

1 Commits
master ... test

Author SHA1 Message Date
dfb074e4ce Continued 2024-03-03 11:20:35 +01:00
55 changed files with 11756 additions and 10041 deletions

View File

@ -1,3 +1,3 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = Calculator CalculatorCInterface
SUBDIRS = Calculator Utilities

View File

@ -1,33 +0,0 @@
QT+=core
CONFIG+=c++20 console
INCLUDEPATH+="../CalculatorCInterface"
#LIBS += "C:\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\CalculatorCInterface\debug\libCalculatorCInterface.a"
#LIBS += "C:\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\CalculatorCInterface\debug\CalculatorCInterface.dll"
unix {
LIBS += -L/opt/ptu5/opt/build-ATBTariffCalculator-Desktop_Qt_5_12_12_GCC_64bit-Debug/CalculatorCInterface/ -lCalculatorCInterface
}
win32 {
INCLUDEPATH += C:\Users\G.Hoffmann\Downloads\libgit2-1.7.2\libgit2-1.7.2\include
LIBS += -LC:\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Release\CalculatorCInterface\release -lCalculatorCInterface
}
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
message_handler.cpp
HEADERS += message_handler.h
OTHER_FILES += ../tariff.json
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

View File

@ -1,60 +0,0 @@
#include <QCoreApplication>
#include <QString>
#include <QDebug>
#include <QLibrary>
#include <stdio.h>
#include <stdlib.h>
#include "message_handler.h"
#include "calculator_c_interface_lib.h"
//#include "tariff_calculator.h"
typedef TariffCalculator *TariffCalculatorHandle;
typedef TariffCalculatorHandle (*NewTariffCalculatorFunc)();
typedef void (*DeleteTariffCalculatorFunc)(TariffCalculatorHandle handle);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if (!messageHandlerInstalled()) {
atbInstallMessageHandler(atbDebugOutput);
//setDebugLevel(LOG_NOTICE);
}
#if 1
//TariffCalculatorHandle handle = NewTariffCalculator();
//DeleteTariffCalculator(handle);
//if (InitGitLibrary() > 0) {
// qCritical() << CloneRepository("https://git.mimbach49.de/GerhardHoffmann/customer_999.git", "C:\\tmp\\customer_999");
// qCritical() << CheckoutLocalBranch("C:\\tmp\\customer_999", "master");
// ShutdownGitLibrary();
// }
qCritical() << GetFileMenuSize("customer_999");
#else
QLibrary library("C:\\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Release\\CalculatorCInterface\\release\\CalculatorCInterface.dll");
if (library.load()) {
qCritical() << "loaded";
NewTariffCalculatorFunc f = (NewTariffCalculatorFunc) library.resolve("NewTariffCalculator");
TariffCalculatorHandle handle = 0;
if (f) {
qCritical() << "resolved";
handle = f();
}
DeleteTariffCalculatorFunc d = (DeleteTariffCalculatorFunc) library.resolve("DeleteTariffCalculator");
if (d) {
qCritical() << "resolved";
d(handle);
}
}
#endif
return 0; // a.exec();
}

View File

@ -1,107 +0,0 @@
#include "message_handler.h"
#include <QDateTime>
#include <cstring>
#include <QString>
#include <QFileInfo>
#include <QMessageLogContext>
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERR 3
#define LOG_WARNING 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
static char const *DBG_NAME[] = { "DBG ", "WARN ", "CRIT ", "FATAL", "INFO " };
static bool installedMsgHandler = false;
static int debugLevel = LOG_NOTICE;
int getDebugLevel() { return debugLevel; }
void setDebugLevel(int newDebugLevel) {
debugLevel = newDebugLevel;
}
bool messageHandlerInstalled() {
return installedMsgHandler;
}
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) {
installedMsgHandler = (handler != 0);
static QtMessageHandler prevHandler = nullptr;
if (handler) {
prevHandler = qInstallMessageHandler(handler);
return prevHandler;
} else {
return qInstallMessageHandler(prevHandler);
}
}
///
/// \brief Print message according to given debug level.
///
/// \note Install this function using qInstallMsgHandler().
///
/// int main(int argc, char **argv) {
/// installMsgHandler(atbDebugOutput);
/// QApplication app(argc, argv);
/// ...
/// return app.exec();
/// }
///
//#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
Q_UNUSED(context);
QString const localMsg = QString(DBG_NAME[type]) + msg.toLocal8Bit();
switch (debugLevel) {
case LOG_DEBUG: { // debug-level message
fprintf(stderr, "LOG_DEBUG %s\n", localMsg.toStdString().c_str());
} break;
case LOG_INFO: { // informational message
if (type != QtDebugMsg) {
fprintf(stderr, "LOG_INFO %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_NOTICE: { // normal, but significant, condition
if (type != QtDebugMsg) {
fprintf(stderr, "LOG_NOTICE %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_WARNING: { // warning conditions
if (type != QtInfoMsg && type != QtDebugMsg) {
fprintf(stderr, "LOG_WARN %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_ERR: { // error conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_ERR %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_CRIT: { // critical conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_CRIT %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_ALERT: { // action must be taken immediately
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_ALERT %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_EMERG: { // system is unusable
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_EMERG %s\n", localMsg.toStdString().c_str());
}
} break;
default: {
//fprintf(stderr, "%s No ErrorLevel defined! %s\n",
// datetime.toStdString().c_str(), msg.toStdString().c_str());
}
}
}
//#endif

View File

@ -1,23 +0,0 @@
#ifndef MESSAGE_HANDLER_H_INCLUDED
#define MESSAGE_HANDLER_H_INCLUDED
#include <QtGlobal>
#ifdef __linux__
#include <syslog.h>
#endif
int getDebugLevel();
void setDebugLevel(int newDebugLevel);
bool messageHandlerInstalled();
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler);
//#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const char *);
//void atbDebugOutput(QtMsgType type, const char *msg);
//#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
//#endif
#endif // MESSAGE_HANDLER_H_INCLUDED

View File

@ -1,47 +0,0 @@
QT+=core
TEMPLATE = lib
DEFINES += CALCULATOR_C_INTERFACE_LIBRARY
QMAKE_CXXFLAGS += -fPIC -std=c++20
unix {
LIBS += -L/usr/lib64 -lgit2
}
win32 {
INCLUDEPATH += C:\Users\G.Hoffmann\Downloads\libgit2-1.7.2\libgit2-1.7.2\include
LIBS += -LC:\Users\G.Hoffmann\Downloads\libgit2-1.7.2\libgit2-1.7.2\build\Debug -lgit2
}
# INCLUDEPATH+=$$_PRO_FILE_PWD_/../Utilities/
CONFIG += c++20 console
#QMAKE_CXX=C:\Qt\Tools\mingw1120_64\g++.exe
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
calculator_c_interface_lib.cpp \
git_library.cpp \
tariff_calculator.cpp \
local_git_repository.cpp
HEADERS += \
calculator_c_interface_lib.h \
calculator_c_interface_lib_global.h \
git_library.h \
tariff_calculator.h \
local_git_repository.h \
global_defines.h
# Default rules for deployment.
unix {
target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target

View File

@ -1,148 +0,0 @@
#include "calculator_c_interface_lib.h"
#include "local_git_repository.h"
#include "git_library.h"
//#include <git2/common.h>
#include <QMap>
#include <QString>
#include <QDir>
#include <QFile>
#include <QByteArray>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <mutex>
#include <git2.h>
#include <stdio.h>
#include <stdint.h>
#include <algorithm>
//static QMap<QString, git_repository *> customerRepoMap;
//static std::mutex m;
#ifndef _WIN32
# include <unistd.h>
#endif
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
TariffCalculatorHandle NewTariffCalculator(void) {
return new TariffCalculator();
}
void DeleteTariffCalculator(TariffCalculatorHandle handle) {
delete handle;
}
int InitGitLibraryInternal(void) {
return GitLibrary::Init();
}
int ShutdownGitLibraryInternal(void) {
LocalGitRepository::DestroyAllRepositories();
return GitLibrary::Shutdown();
}
int CloneRepositoryInternal(char const *url, char const *local_path) {
return GitLibrary::CloneRepository(url, local_path);
}
int CheckoutRepositoryInternal(char const *url, char const *localRepoName, char const *branchName) {
return GitLibrary::CheckoutRepository(url, localRepoName, branchName);
}
int CommitFileInternal(char const *localRepoName, char const *branchName,
char const *fName, char const *commitMessage) {
return GitLibrary::CommitFile(localRepoName, branchName, fName, commitMessage);
}
int PushRepositoryInternal(char const *localRepoName, char const *branchName,
char const *userName, char const *userPassword) {
return GitLibrary::PushRepository(localRepoName, branchName, userName, userPassword);
}
int PullRepositoryInternal(char const *localRepoName, char const *remoteRepoName) {
return GitLibrary::PullRepository(localRepoName, remoteRepoName);
}
#include <local_git_repository.h>
void SetReposRootDirectoryInternal(char const *p) {
LocalGitRepository::SetReposRootDirectory(QString::fromUtf8(p));
}
char const *GetReposRootDirectoryInternal() {
return (char const *)LocalGitRepository::GetReposRootDirectory().constData();
}
char const *GetLocalRepositoryPathInternal(char const *localGitRepo) {
return (char const *)LocalGitRepository::GetInstance(localGitRepo)->localRepositoryPath().constData();
}
int32_t GetFileMenuSizeInternal(char const *localGitRepo) {
return LocalGitRepository::GetInstance(localGitRepo)->GetFileMenuSizeInternal();
}
char const *GetFileMenuInternal(const char *localGitRepo) {
QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileMenuInternal().constData();
if (a.isValidUtf8()) {
int const len = GetFileMenuSizeInternal(localGitRepo);
if (len > 0) {
char *json = new char [len+1];
// fprintf(stderr, "allocate pointer %p\n", json);
memset(json, 0x00, len+1);
memcpy(json, a.constData(), std::min(len, (int)a.size()));
return json;
}
}
return nullptr;
}
char const *GetFileNameInternal(char const *localGitRepo, char const *fileId) {
QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileNameInternal(fileId);
if (a.isValidUtf8()) {
char *c = new char[a.size() + 1];
memset(c, 0x00, a.size() + 1);
memcpy(c, a.constData(), a.size());
return c;
}
return nullptr;
}
int32_t GetFileSize(char const *localGitRepo, char const *fileId) {
return LocalGitRepository::GetInstance(localGitRepo)->GetFileSize(fileId);
}
char const *GetFileInternal(char const *localGitRepo, char const *fileId) {
QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileInternal(fileId);
if (a.isValidUtf8()) {
char *c = new char[a.size() + 1];
memset(c, 0x00, a.size() + 1);
memcpy(c, a.constData(), a.size());
return c;
}
return nullptr;
}
bool SetFileInternal(char const *localGitRepo, char const *fileId, char const *json, int size) {
return LocalGitRepository::GetInstance(localGitRepo)->SetFileInternal(QString(fileId), QByteArray(json, size));
}
void DeleteMem(char *p) {
if (p) {
// fprintf(stderr, "delete pointer %p\n", p);
delete p;
}
}
#ifdef __cplusplus
}
#endif

View File

@ -1,42 +0,0 @@
#ifndef CALCULATOR_C_INTERFACE_LIB_H_INCLUDED
#define CALCULATOR_C_INTERFACE_LIB_H_INCLUDED
#include "calculator_c_interface_lib_global.h"
#include "tariff_calculator.h"
typedef TariffCalculator *TariffCalculatorHandle;
#ifdef __cplusplus
extern "C" {
#endif
void DeleteMem(char *p) CALCULATOR_C_INTERFACE_LIB_EXPORT;
void SetReposRootDirectoryInternal(char const *p) CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetReposRootDirectoryInternal() CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetLocalRepositoryPathInternal(char const *localRepo) CALCULATOR_C_INTERFACE_LIB_EXPORT;
// interface for menu of webpage
char const *GetFileMenuInternal(char const *localRepo) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int32_t GetFileMenuSizeInternal(char const *localRepo) CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetFileNameInternal(char const *localRepo, char const *fileId) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int32_t GetFileSize(char const *localRepo, char const *fileId) CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetFileInternal(char const *localRepo, char const *fileId) CALCULATOR_C_INTERFACE_LIB_EXPORT;
bool SetFileInternal(char const *localRepo, char const *fileId, char const *json, int size) CALCULATOR_C_INTERFACE_LIB_EXPORT;
TariffCalculatorHandle NewTariffCalculator(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
void DeleteTariffCalculator(TariffCalculatorHandle handle) CALCULATOR_C_INTERFACE_LIB_EXPORT;
// libgit2
int InitGitLibraryInternal(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int ShutdownGitLibraryInternal(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CloneRepositoryInternal(char const *url, char const *local_path) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CheckoutRepositoryInternal(char const *url, char const *localRepoName, char const *branchName) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CommitFileInternal(char const *local_path, char const *branch_name, char const *file_name, char const *commit_message) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int PushRepositoryInternal(char const *local_path, char const *branch_name, char const *user, char const *password) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int PullRepositoryInternal(char const *localRepoName, char const *remoteRepoName) CALCULATOR_C_INTERFACE_LIB_EXPORT;
#ifdef __cplusplus
}
#endif
#endif // CALCULATOR_C_INTERFACE_LIB_H_INCLUDED

View File

@ -1,23 +0,0 @@
#ifndef CALCULATOR_C_INTERFACE_GLOBAL_H
#define CALCULATOR_C_INTERFACE_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CALCULATOR_C_INTERFACE_LIBRARY)
#ifdef __linux__
#define CALCULATOR_C_INTERFACE_LIB_EXPORT
#else
#define CALCULATOR_C_INTERFACE_LIB_EXPORT Q_DECL_EXPORT __stdcall
#endif
#else
#ifdef __linux__
#define CALCULATOR_C_INTERFACE_LIB_EXPORT
#else
#define CALCULATOR_C_INTERFACE_LIB_EXPORT Q_DECL_IMPORT __stdcall
#endif
#endif
#endif // CALCULATOR_C_INTERFACE_GLOBAL_H

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +0,0 @@
#ifndef GIT_LIBRARY_H_INCLUDED
#define GIT_LIBRARY_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <git2.h>
class CWD {
QDir m_prev;
QDir m_localRepoDir;
QDir m_localRepoGitDir;
bool m_valid;
public:
CWD(QString const &localRepoName);
~CWD();
QDir const &localRepoDir() const { return m_localRepoDir; }
QDir &localRepoDir() { return m_localRepoDir; }
QDir const &localRepoGitDir() const { return m_localRepoGitDir; }
QDir &localRepoGitDir() { return m_localRepoGitDir; }
};
class GitLibrary {
static QString m_userName;
static QString m_userPassword;
public:
static QString &userName() { return m_userName; }
static QString &userPassword() { return m_userPassword; }
static int Init();
static int Shutdown();
static int CloneRepository(char const *url, char const *localRepoName);
static int CheckoutRepository(char const *url, char const *localRepoName, char const *branchName);
static int CommitRepository(char const *localRepoName, char const *branchName, char const *commitMessage);
static int CommitFile(char const *localRepoName, char const *branchName, char const *fName, char const *commitMessage);
static int PushRepository(char const *localRepoName, char const *branchName, char const *userName, char const *userPassword);
static int PullRepository(char const *localRepoName, char const *remoteRepoName);
// explicit GitLibrary();
// ~GitLibrary();
};
#endif // #define GIT_LIBRARY_H_INCLUDED

View File

@ -1,7 +0,0 @@
#ifndef GLOBAL_DEFINES_H_INCLUDED
#define GLOBAL_DEFINES_H_INCLUDED
#define HEADER __func__ << "(" << __LINE__ << ")"
#endif // GLOBAL_DEFINES_H_INCLUDED

View File

@ -1,212 +0,0 @@
#include "local_git_repository.h"
#include "git_library.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QJsonDocument>
#include <QByteArray>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QFile>
QString LocalGitRepository::repoRootDirectory = "";
QMap<QString, LocalGitRepository *> LocalGitRepository::localGitRepos;
QMap<QString, LocalGitRepository *> &LocalGitRepository::GetLocalGitRepos() {
return localGitRepos;
}
void LocalGitRepository::SetReposRootDirectory(QString s) {
if (repoRootDirectory.isEmpty()) {
repoRootDirectory = s;
return;
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory already set"
<< repoRootDirectory;
}
QString LocalGitRepository::GetReposRootDirectory() {
return repoRootDirectory;
}
LocalGitRepository::LocalGitRepository(QString const &localRepository)
: m_localRepository(localRepository)
, m_fileMenu("{}")
, m_fileMenuSize(-1)
, m_git_repository(nullptr) {
}
LocalGitRepository::~LocalGitRepository() {
}
void LocalGitRepository::SetGitRepository(git_repository *git_repo) {
m_git_repository = git_repo;
}
git_repository const *LocalGitRepository::GetGitRepository() const {
return m_git_repository;
}
git_repository *LocalGitRepository::GetGitRepository() {
return m_git_repository;
}
QString LocalGitRepository::localRepositoryName() const { // e.g. customer_999
return m_localRepository;
}
QString LocalGitRepository::localRepositoryPath() const {
if (!repoRootDirectory.isEmpty()) {
return QDir::cleanPath(repoRootDirectory + QDir::separator() + m_localRepository);
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory not set";
return "";
}
QString LocalGitRepository::localRepositoryPath(QString const &localRepository) {
if (!repoRootDirectory.isEmpty()) {
return QDir::cleanPath(repoRootDirectory + QDir::separator() + localRepository);
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory not set";
return "";
}
LocalGitRepository *LocalGitRepository::GetInstance(QString const& localRepository) {
LocalGitRepository *repo = nullptr;
if (GetLocalGitRepos().count(localRepository) > 0) {
repo = GetLocalGitRepos()[localRepository];
} else {
repo = new LocalGitRepository(localRepository);
qCritical() << "created local git-repository" << localRepository;
GetLocalGitRepos().insert(localRepository, repo);
}
if (repo == nullptr) {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR: could not find local git-repository" << localRepository;
}
return repo;
}
bool LocalGitRepository::DestroyInstance(QString const &localRepository) {
if (GetLocalGitRepos().count(localRepository) > 0) {
LocalGitRepository *repo = GetLocalGitRepos().take(localRepository);
delete repo;
qCritical() << "deleted local git-repository" << localRepository;
return true;
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR: could not find local git-repository" << localRepository;
return false;
}
void LocalGitRepository::DestroyAllRepositories() {
for (auto it = GetLocalGitRepos().keyValueBegin(); it != GetLocalGitRepos().keyValueEnd(); ++it) {
QString const &key = it->first;
LocalGitRepository *repo = GetLocalGitRepos()[key];
delete repo;
qCritical() << "deleted local git-repository" << key;
}
GetLocalGitRepos().clear();
}
int32_t LocalGitRepository::GetFileMenuSizeInternal() const {
return m_fileMenuSize;
}
QByteArray LocalGitRepository::GetFileMenuInternal() {
if (m_fileMenuSize == -1) {
QFile f(QDir::cleanPath(repoRootDirectory + QDir::separator()
+ m_localRepository + QDir::separator()
+ "etc/psa_webinterface/menu_config.json"));
if (f.exists()) {
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_fileMenu = QTextStream(&f).readAll().toUtf8();
if (m_fileMenu.isValidUtf8()) {
QString const &s = QString::fromUtf8(m_fileMenu);
m_fileMenuSize = s.toLocal8Bit().size();
}
}
}
}
return m_fileMenu;
}
QByteArray LocalGitRepository::GetFileNameInternal(QString const &fId) {
QRegularExpressionMatch match;
static const QRegularExpression re("(master|[0-9]+)");
if (fId.lastIndexOf(re, -1, &match) != -1) {
int idx = fId.indexOf("/");
if (idx != -1) {
QString path = fId.mid(idx);
idx = path.indexOf(":");
if (idx != -1) {
path = path.mid(0, idx);
QString s = match.captured(match.lastCapturedIndex());
if (s != "master") {
if (fId.contains("psa_tariff")) {
QString fn(QDir::cleanPath(
repoRootDirectory + QDir::separator() +
QString(m_localRepository) + QDir::separator()
+ path + QDir::separator()
+ QString("tariff%1.json").arg(s.toUInt(), 2, 10, QChar('0'))));
return fn.toUtf8();
}
}
}
}
}
return QByteArray();
}
QByteArray LocalGitRepository::GetFileInternal(QString const &fId) {
QByteArray a = GetFileNameInternal(fId);
if (a.isValidUtf8()) {
QFile fn(a);
if (fn.exists()) {
if (fn.open(QIODevice::ReadOnly)) {
return fn.readAll();
}
}
}
return QByteArray("{}");
}
int32_t LocalGitRepository::GetFileSize(QString const &fId) {
QByteArray a = GetFileNameInternal(fId);
if (a.isValidUtf8()) {
QFile fn(a);
if (fn.exists()) {
return fn.size();
}
}
return -1;
}
bool LocalGitRepository::SetFileInternal(QString const &fId, QByteArray const &json) {
QByteArray a = GetFileNameInternal(fId);
if (a.isValidUtf8()) {
QFile fn(a);
if (fn.exists()) {
if (fn.open(QIODevice::WriteOnly)) {
qint64 bytesWritten = 0;
qint64 bytesToWrite = json.size();
while (bytesToWrite > 0 &&
(bytesWritten = fn.write(json.constData(), bytesToWrite)) != -1) {
bytesToWrite -= bytesWritten;
}
fn.flush();
return (bytesToWrite == 0);
}
}
}
return false;
}

View File

@ -1,58 +0,0 @@
#ifndef LOCAL_GIT_REPOSITORY_H_INCLUDED
#define LOCAL_GIT_REPOSITORY_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <QMap>
#include <git2.h>
class GitLibrary;
class LocalGitRepository {
friend class GitLibrary;
QString m_localRepository;
mutable QByteArray m_fileMenu;
mutable int32_t m_fileMenuSize;
git_repository *m_git_repository;
static QString repoRootDirectory;
static QMap<QString, LocalGitRepository *> localGitRepos;
protected: // force heap-based objects
LocalGitRepository(QString const &localRepository);
~LocalGitRepository();
public:
static void SetReposRootDirectory(QString s);
static QString GetReposRootDirectory();
static LocalGitRepository *GetInstance(QString const &localRepository);
static bool DestroyInstance(QString const &localRepository);
static void DestroyAllRepositories();
static QMap<QString, LocalGitRepository *> &GetLocalGitRepos();
QString localRepositoryName() const;
QString localRepositoryPath() const;
void SetGitRepository(git_repository *git_repo);
git_repository const *GetGitRepository() const;
git_repository *GetGitRepository();
static QString localRepositoryPath(QString const &localRepository);
QByteArray GetFileMenuInternal();
int32_t GetFileMenuSizeInternal() const;
QByteArray GetFileNameInternal(QString const &fileId);
int32_t GetFileSize(QString const &fileId);
QByteArray GetFileInternal(QString const &fileId);
bool SetFileInternal(QString const &fileId, QByteArray const &json);
};
#endif // LOCAL_GIT_REPOSITORY_H_INCLUDED

View File

@ -1,430 +0,0 @@
#include "tariff_calculator.h"
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#if 0
QByteArray TariffCalculator::readJson(QString const &filename) {
QFile f(filename);
if (f.exists()) {
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&f);
return in.readAll().toUtf8();
} else {
qCritical() << filename << "not readable";
}
} else {
qCritical() << filename << "does not exist";
}
return QByteArray();
}
#endif
TariffCalculator::~TariffCalculator() {
qCritical() << __func__;
}
TariffCalculator::TariffCalculator() {
// QByteArray ba = readJson("/opt/ptu5/opt/ATBTariffCalculator/Utilities/tariff.template.json");
//QJsonParseError pe;
//m_jsonDoc = QJsonDocument::fromJson(ba, &pe);
//if (pe.error == QJsonParseError::NoError) {
// qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
//} else {
// qCritical() << __func__ << pe.errorString();
//
//}
m_o = QJsonObject();
createJsonValue("Tariffhead");
createJsonValue("Products");
createJsonValue("Accuracy");
createJsonValue("Type");
createJsonValue("Price");
createJsonValue("Config");
createJsonValue("TimeRanges");
//createJsonValue("Periods");
//createJsonValue("DayConfigs");
//createJsonValue("Days");
m_jsonDoc.setObject(m_o);
qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
}
void TariffCalculator::createJsonValue(QString const &key, QString const &value) {
if (key.compare("Tariffhead", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("Project"), QJsonValue(QString("Szeged"))),
QPair(QString("Version"), QJsonValue(QString("1.0.0"))),
QPair(QString("Date"), QJsonValue("01.01.1970")),
QPair(QString("Committer"), QJsonValue("")),
QPair(QString("Info"), QJsonValue(QString("")))});
m_o.insert(key, o);
} else
if (key.compare("Accuracy", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("accuracy_id"), QJsonValue(1)),
QPair(QString("accuracy_label"), QJsonValue(QString("computation-to-the-minute"))),
QPair(QString("accuracy_value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("accuracy of tariff computation is individual minutes")))});
m_o.insert(key, o);
} else
if (key.compare("Type", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("type_id"), QJsonValue(1)),
QPair(QString("type_label"), QJsonValue(QString("uniform-minutes"))),
QPair(QString("comment"), QJsonValue(QString("same price for all minutes")))});
m_o.insert(key, o);
} else
if (key.compare("Price", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("price_id"), QJsonValue(1)),
QPair(QString("price"), QJsonValue(165)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("price per hour as provided by customer")))});
QJsonObject o2({
QPair(QString("price_id"), QJsonValue(2)),
QPair(QString("price"), QJsonValue(990)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("price for dayticket as provided by customer")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_o.insert(key, a);
} else
if (key.compare("Config", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("minimal parking time in minutes (net)")))});
QJsonObject o2({
QPair(QString("value"), QJsonValue(360)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("maximal parking time in minutes (net)")))});
QJsonObject o3({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25")))});
QJsonObject o4({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in maximal time: 360*(165/60) = 990")))});
QJsonObject o5({
QPair(QString("comment"), QJsonValue(QString("general tariff config"))),
QPair(QString("config_id"), QJsonValue(1)),
QPair(QString("config_label"), QJsonValue("Tariff Config 1")),
QPair(QString("config_tariff_accuracy"), QJsonValue(1)),
QPair(QString("config_tariff_type"), QJsonValue(1)),
QPair(QString("config_carry_over"), QJsonValue(true)),
QPair(QString("config_prepaid"), QJsonValue(true)),
QPair(QString("MinimalTime"), QJsonValue(o1)),
QPair(QString("MaximalTime"), QJsonValue(o2)),
QPair(QString("MinimalPrice"), QJsonValue(o3)),
QPair(QString("MinimalPrice"), QJsonValue(o4))});
m_o.insert(key, o5);
} else
if (key.compare("Products", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("product_id"), QJsonValue(1)),
QPair(QString("product_price_id"), QJsonValue(1)),
QPair(QString("product_label"), QJsonValue(QString("SHORT_TIME_PARKING")))});
QJsonObject o2({
QPair(QString("product_id"), QJsonValue(2)),
QPair(QString("product_price_id"), QJsonValue(2)),
QPair(QString("product_time_ranges"), QJsonArray({QJsonValue(100001)})),
QPair(QString("product_label"), QJsonValue(QString("DAY_TICKET")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_o.insert(key, a);
} else
if (key.compare("TimeRanges", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-00:00 [ = [ 00:00-24:00 [")))});
QJsonObject o2({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(1)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("08:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-08:00 [")))});
QJsonObject o3({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(2)),
QPair(QString("range_start"), QJsonValue(QString("18:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 18:00-00:00 [")))});
QJsonObject o4({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(3)),
QPair(QString("range_start"), QJsonValue(QString("12:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 12:00-00:00 [")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
QTime const t(8,0,0);
QJsonArray b;
for (int i=0; i<600; ++i) {
QTime const &start = t.addSecs(i*60);
QTime const &end = t.addSecs((i+1)*60);
QJsonObject o({
QPair(QString("range_id"), QJsonValue(i)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(start.toString(Qt::ISODate))),
QPair(QString("range_end"), QJsonValue(end.toString(Qt::ISODate)))});
b.push_back(o);
}
a.push_back(b);
m_o.insert(key, a);
} else
if (key.compare("Periods", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("period_id"), QJsonValue(1)),
QPair(QString("period_label"), QJsonValue("1st quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-03-31")))});
QJsonObject o2({
QPair(QString("period_id"), QJsonValue(2)),
QPair(QString("period_label"), QJsonValue("2nd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-04-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
QJsonObject o3({
QPair(QString("period_id"), QJsonValue(3)),
QPair(QString("period_label"), QJsonValue("3rd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-09-30")))});
QJsonObject o4({
QPair(QString("period_id"), QJsonValue(4)),
QPair(QString("period_label"), QJsonValue("4th quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-10-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
QJsonObject o5({
QPair(QString("period_id"), QJsonValue(5)),
QPair(QString("period_label"), QJsonValue("1st half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
QJsonObject o6({
QPair(QString("period_id"), QJsonValue(6)),
QPair(QString("period_label"), QJsonValue("2nd half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
a.push_back(o5);
a.push_back(o6);
m_o.insert(key, a);
} else
if (key.compare("DayConfigs", Qt::CaseInsensitive) == 0) {
QJsonArray b;
b.push_back(QJsonValue(100002));
for (int i=0; i<600; ++i) {
b.push_back(QJsonValue(i));
}
b.push_back(QJsonValue(100003));
QJsonArray c;
c.push_back(QJsonValue(100001));
QJsonObject o1({
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(0), QJsonValue(1)})),
QPair(QString("day_config_short_time_parking"), b),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o2({QPair(QString("DayConfig_1"), QJsonValue(o1))});
QJsonObject o3({
QPair(QString("day_config_id"), QJsonValue(2)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(1)})),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o4({QPair(QString("DayConfig_2"), QJsonValue(o3))});
QJsonArray a;
a.push_back(o2);
a.push_back(o4);
m_o.insert(key, a);
} else
if (key.compare("Days", Qt::CaseInsensitive) == 0) {
QJsonArray b;
for (int i=1; i < 8; ++i) {
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(0))});
switch(i) {
case Qt::Monday: {
QJsonObject o2({QPair(QString("Mon"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Tuesday: {
QJsonObject o2({QPair(QString("Tue"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Wednesday: {
QJsonObject o2({QPair(QString("Wed"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Thursday: {
QJsonObject o2({QPair(QString("Thu"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Friday: {
QJsonObject o2({QPair(QString("Fri"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Saturday: {
QJsonObject o2({QPair(QString("Sat"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Sunday: {
QJsonObject o2({QPair(QString("Sun"), QJsonValue(o1))});
b.push_back(o2);
} break;
}
}
QJsonArray c;
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-25"))),
QPair(QString("day_movable"), QJsonValue(false))});
QJsonObject o2({
QPair(QString("day_id"), QJsonValue(2)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-26"))),
QPair(QString("day_movable"), QJsonValue(false))});
c.push_back(o1);
c.push_back(o2);
QJsonObject o3({QPair(QString("Weekdays"), b),
QPair(QString("Holidays"), c)});
//"Christmas_1st_day": {
// "day_id": 8,
// "day_config_id": 1,
// "day_date": "2024-12-25",
// "day_moveable": false
//},
//"Christmas_2nd_day": {
// "day_id": 9,
// "day_config_id": 1,
// "day_date": "2024-12-26",
// "day_moveable": false
//}
//m_a.push_back(QJsonObject({QPair(key, QJsonValue(o3))}));
m_o.insert(key, o3);
}
#if 0
"TariffDays": [
"Mon": {
"day_id": 1,
"day_config_id": 0
},
"Tue": {
"day_id": 2,
"day_config_id": 0
},
"Wed": {
"day_id": 3,
"day_config_id": 0
},
"Thu": {
"day_id": 4,
"day_config_id": 0
},
"Fri": {
"day_id": 5,
"day_config_id": 0
},
"Sat": {
"day_id": 6,
"day_config_id": 0
},
"Sun": {
"day_id": 7,
"day_config_id": 0
},
"Christmas_1st_day": {
"day_id": 8,
"day_config_id": 1,
"day_date": "2024-12-25",
"day_moveable": false
},
"Christmas_2nd_day": {
"day_id": 9,
"day_config_id": 1,
"day_date": "2024-12-26",
"day_moveable": false
}
// usw. die anderen Feiertage un
"DayConfig_1": {
"day_config_id": 0,
"day_config_date_range": 6,
"comment_1": "day config is valid for the whole year",
"day_config_product_ids": [0, 1],
"comment_2": "short-time-parking or day-ticket on this day",
#endif
}

View File

@ -1,24 +0,0 @@
#ifndef TARIFF_CALCULATOR_H_INCLUDED
#define TARIFF_CALCULATOR_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <git2.h>
class TariffCalculator {
QJsonObject m_o;
QJsonDocument m_jsonDoc;
void createJsonValue(QString const &key, QString const &value = "");
public:
explicit TariffCalculator();
~TariffCalculator();
static QByteArray readJson(QString const &filename);
};
#endif // TARIFF_CALCULATOR_H_INCLUDED

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,82 @@
QT += core
TARGET = util
VERSION="0.1.0"
win32 {
BUILD_DATE=$$system("date /t")
BUILD_TIME=$$system("time /t")
} else {
BUILD_DATE=$$system("date +%d-%m-%y")
BUILD_TIME=$$system("date +%H:%M:%S")
}
GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1")
EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}"
CONFIG += c++17
DEFINES+=APP_VERSION=\\\"$$VERSION\\\"
DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\"
DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\"
DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\"
# keep comments, as /* fall through */
QMAKE_CXXFLAGS += -C
QMAKE_CXXFLAGS += -g
QMAKE_CXXFLAGS += -Wno-deprecated-copy -O
contains( CONFIG, PTU5 ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
CONFIG += link_pkgconfig
lessThan(QT_MAJOR_VERSION, 5): PKGCONFIG += qextserialport
QMAKE_CXXFLAGS += -O2 -std=c++17 # for GCC >= 4.7
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
ARCH = PTU5
DEFINES+=PTU5
}
contains( CONFIG, PTU5_YOCTO ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
QMAKE_CXXFLAGS += -std=c++17 # for GCC >= 4.7
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5
DEFINES+=PTU5
# add qmqtt lib
#LIBS += -lQt5Qmqtt
}
contains( CONFIG, DesktopLinux ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
lessThan(QT_MAJOR_VERSION, 5): CONFIG += extserialport
# QMAKE_CC = ccache $$QMAKE_CC
# QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++17
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
ARCH = DesktopLinux
DEFINES+=DesktopLinux
}
SOURCES += \
main.cpp \
tariff_json_template.cpp \
tariff_editor.cpp
HEADERS += \
tariff_json_template.h \
tariff_editor.h
OTHER_FILES += \
tariff.json \
tariff.template.json
##########################################################################################
# for running program on target through QtCreator
contains( CONFIG, PTU5 ) {
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/app/tools/atbupdate/
!isEmpty(target.path): INSTALLS += target
}

View File

@ -1,5 +1,8 @@
#include <QtGlobal>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>
#include "tariff_editor.h"
@ -9,6 +12,39 @@ int main(int argc, char **argv) {
Q_UNUSED(argv);
TariffEditor editor;
editor.writeToDocument("Project", "Szeged");
editor.writeToDocument("Version", "1.0.0");
editor.writeToDocument("Date", "01.01.1970");
editor.writeToDocument("Commiter" , "");
editor.writeToDocument("Info", "");
editor.writeToDocument(editor.create("TariffType"));
editor.writeToDocument(editor.create("TariffAccuracy"));
editor.writeToDocument(editor.create("TariffPrice"));
editor.writeToDocument(editor.create("TariffProducts"));
editor.writeToDocument(editor.create("TariffConfig"));
editor.writeToDocument(editor.create("TimeRanges"));
qCritical().noquote() << editor.document().toJson();
return 0;
QFile currentFile("/home/linux/ATBTariffCalculator/Utilities/tariff.template.json");
if (currentFile.open(QIODevice::ReadOnly)) {
qCritical() << __LINE__;
QByteArray json = currentFile.readAll();
QJsonParseError e;
QJsonDocument doc = QJsonDocument::fromJson(json, &e);
if (e.error == QJsonParseError::NoError) {
qCritical().noquote() << doc.toJson(QJsonDocument::JsonFormat::Indented);
} else {
qCritical() << e.errorString();
}
}
return 0;

View File

@ -6,6 +6,22 @@ Tarif-Datei Szeged in Zone 1 (expandiert, Vorschlag):
"Commiter":"",
"Info":"",
"TariffType": [
{
"tariff_type_id": 1,
"tariff_type_label": "uniform-to-the-minute",
"comment": "same price for all computational units (minutes)"
}
],
"TariffAccuracy": [
{
"tariff_accuracy_id": 1,
"tariff_accuracy_label": "computation per minute",
"tariff_accuracy_value": 1,
"comment": "accuracy of tariff computation is individual minutes"
}
],
"Products" : [
{
"tariff_product_id": 0,
@ -18,44 +34,17 @@ Tarif-Datei Szeged in Zone 1 (expandiert, Vorschlag):
"tariff_product_time_ranges" : [100001]
}
],
"TariffAccuracy": [
{
"tariff_accuracy_id": 1,
"tariff_accuracy_label": "computation per minute",
"tariff_accuracy_value": 1,
"comment": "accuracy of tariff computation is individual minutes"
}
],
"TariffType": [
{
"tariff_type_id": 1,
"tariff_type_label": "linear",
"comment": "same price for all computational units, typically minutes"
}
],
"TariffTimeBase": [
{
"tariff_timebase_id": 1,
"tariff_timebase_label": "dynamic-timebase",
"comment": "computation starts at minute 0 (can be any minute during the day)"
},
{
"tariff_timebase_id": 2,
"tariff_timebase_label": "wall-clock-timebase",
"comment": "computation starts at fixed wall-clock time"
}
],
"TariffPriceCustomer": [
{
{
"tariff_price_customer_id": 1,
"tariff_price_customer": 165,
"editable": true,
"editable": true,
"comment": "price per hour as entered by customer"
},
{
{
"tariff_price_customer_id": 2,
"tariff_price_customer": 990,
"editable": true,
"editable": true,
"comment": "price for dayticket as entered by customer"
}
],
@ -92,10 +81,12 @@ Tarif-Datei Szeged in Zone 1 (expandiert, Vorschlag):
},
"MinimalPrice": {
"value" : 1,
"editable": true,
"comment": "price-id of customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25"
},
"MaximalPrice": {
"value" : 1,
"editable": true,
"comment": "price-id of customer entered price (for hour) expressed in maximal time: 360*(165/60) = 990"
},
"tariff_config_time_base": 1,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,423 +1,181 @@
#include "tariff_editor.h"
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
QByteArray TariffEditor::readJson(QString const &filename) {
QFile f(filename);
if (f.exists()) {
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&f);
return in.readAll().toUtf8();
} else {
qCritical() << filename << "not readable";
}
} else {
qCritical() << filename << "does not exist";
}
return QByteArray();
}
#include <QJsonArray>
#include <QDebug>
#include <QPair>
#include <initializer_list>
TariffEditor::TariffEditor() {
// QByteArray ba = readJson("/opt/ptu5/opt/ATBTariffCalculator/Utilities/tariff.template.json");
//QJsonParseError pe;
//m_jsonDoc = QJsonDocument::fromJson(ba, &pe);
//if (pe.error == QJsonParseError::NoError) {
// qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
//} else {
// qCritical() << __func__ << pe.errorString();
//
//}
m_a = QJsonArray();
createJsonValue("Project", "Szeged");
createJsonValue("Version", "1.0.0");
createJsonValue("Date", "01.01.1970");
createJsonValue("Committer", "");
createJsonValue("Info", "");
createJsonValue("Products");
createJsonValue("Accuracy");
createJsonValue("Type");
createJsonValue("Price");
createJsonValue("Config");
createJsonValue("TimeRanges");
createJsonValue("Periods");
createJsonValue("DayConfigs");
createJsonValue("Days");
m_jsonDoc.setArray(m_a);
qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
m_doc = QJsonDocument();
// m_doc.setObject(QJsonObject());
}
void TariffEditor::createJsonValue(QString const &key, QString const &value) {
if ((key.compare("Project", Qt::CaseInsensitive) == 0)
|| (key.compare("Version", Qt::CaseInsensitive) == 0)
|| (key.compare("Date", Qt::CaseInsensitive) == 0)
|| (key.compare("Committer", Qt::CaseInsensitive) == 0)
|| (key.compare("Info", Qt::CaseInsensitive) == 0)) {
m_a.push_back(QJsonValue({QPair(key, QJsonValue(value))}));
QJsonObject TariffEditor::create(QString const &key) {
QJsonArray a;
if (key.compare("TariffType", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_type_id"), QJsonValue(1)),
QPair(QString("tariff_type_label"), QJsonValue("uniform-to-the-minute")),
QPair(QString("comment"), QJsonValue("same price for all computational units, typically minutes"))}));
} else
if (key.compare("Accuracy", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("accuracy_id"), QJsonValue(1)),
QPair(QString("accuracy_label"), QJsonValue(QString("computation-to-the-minute"))),
QPair(QString("accuracy_value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("accuracy of tariff computation is individual minutes")))});
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o))}));
if (key.compare("TariffAccuracy", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_accuracy_id"), QJsonValue(1)),
QPair(QString("tariff_accuracy_label"), QJsonValue("computation per minute")),
QPair(QString("tariff_accuracy_value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue("accuracy of tariff computation is individual minutes"))
}));
} else
if (key.compare("Type", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("type_id"), QJsonValue(1)),
QPair(QString("type_label"), QJsonValue(QString("uniform-minutes"))),
QPair(QString("comment"), QJsonValue(QString("same price for all minutes")))});
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o))}));
} else
if (key.compare("Price", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("price_id"), QJsonValue(1)),
QPair(QString("price"), QJsonValue(165)),
if (key.compare("TariffPrice", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_price_id"), QJsonValue(1)),
QPair(QString("tariff_price"), QJsonValue(165)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("price per hour as provided by customer")))});
QJsonObject o2({
QPair(QString("price_id"), QJsonValue(2)),
QPair(QString("price"), QJsonValue(990)),
QPair(QString("comment"), QJsonValue("price per hour as entered by customer"))
}));
a.push_back(QJsonObject({
QPair(QString("tariff_price_id"), QJsonValue(2)),
QPair(QString("tariff_price"), QJsonValue(990)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("price for dayticket as provided by customer")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
QPair(QString("comment"), QJsonValue("price for dayticket as entered by customer"))
}));
} else
if (key.compare("Config", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("minimal parking time in minutes (net)")))});
QJsonObject o2({
QPair(QString("value"), QJsonValue(360)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("maximal parking time in minutes (net)")))});
QJsonObject o3({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25")))});
QJsonObject o4({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in maximal time: 360*(165/60) = 990")))});
QJsonObject o5({
QPair(QString("comment"), QJsonValue(QString("general tariff config"))),
QPair(QString("config_id"), QJsonValue(1)),
QPair(QString("config_label"), QJsonValue("Tariff Config 1")),
QPair(QString("config_tariff_accuracy"), QJsonValue(1)),
QPair(QString("config_tariff_type"), QJsonValue(1)),
QPair(QString("config_carry_over"), QJsonValue(true)),
QPair(QString("config_prepaid"), QJsonValue(true)),
QPair(QString("MinimalTime"), QJsonValue(o1)),
QPair(QString("MaximalTime"), QJsonValue(o2)),
QPair(QString("MinimalPrice"), QJsonValue(o3)),
QPair(QString("MinimalPrice"), QJsonValue(o4))});
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o5))}));
if (key.compare("TariffConfig", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_config_id"), QJsonValue(1)),
QPair(QString("tariff_config_label"), QJsonValue("Tariff-Config")),
QPair(QString("tariff_config_accuracy"), QJsonValue(1)),
QPair(QString("tariff_config_type"), QJsonValue(1)),
QPair(QString("tariff_config_carry_over"), QJsonValue(true)),
QPair(QString("tariff_config_prepaid"), QJsonValue(true))
}));
a.push_back(QJsonObject({
QPair(QString("MinimalTime"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("minimal parking time in minutes (net)"))})))}));
a.push_back(QJsonObject({
QPair(QString("MaximalTime"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(360)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("maximal parking time in minutes (net)"))})))}));
a.push_back(QJsonObject({
QPair(QString("MinimalPrice"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25"))})))}));
a.push_back(QJsonObject({
QPair(QString("MaximalPrice"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(990)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("customer entered price (for hour) expressed in maximal time: 15*(165/60) = 41.25"))})))}));
} else
if (key.compare("Products", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("product_id"), QJsonValue(1)),
QPair(QString("product_price_id"), QJsonValue(1)),
QPair(QString("product_label"), QJsonValue(QString("SHORT_TIME_PARKING")))});
QJsonObject o2({
QPair(QString("product_id"), QJsonValue(2)),
QPair(QString("product_price_id"), QJsonValue(2)),
QPair(QString("product_time_ranges"), QJsonArray({QJsonValue(100001)})),
QPair(QString("product_label"), QJsonValue(QString("DAY_TICKET")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
if (key.compare("TariffProducts", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("ShortTimeParking"),
QJsonValue(QJsonObject({
QPair(QString("tariff_product_id"), QJsonValue(1)),
QPair(QString("tariff_product_price_id"), QJsonValue(1))})))}));
a.push_back(QJsonObject({
QPair(QString("DayTicket"),
QJsonValue(QJsonObject({
QPair(QString("tariff_product_id"), QJsonValue(2)),
QPair(QString("tariff_product_price_id"), QJsonValue(2))})))}));
} else
if (key.compare("TimeRanges", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-00:00 [ = [ 00:00-24:00 [")))});
QJsonObject o2({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(1)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("08:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-08:00 [")))});
QJsonObject o3({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(2)),
QPair(QString("range_start"), QJsonValue(QString("18:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 18:00-00:00 [")))});
QJsonObject o4({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(3)),
QPair(QString("range_start"), QJsonValue(QString("12:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 12:00-00:00 [")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
QTime const t(8,0,0);
// if prepaid, unrestricted
QJsonArray b;
for (int i=0; i<600; ++i) {
QTime const &start = t.addSecs(i*60);
QTime const &end = t.addSecs((i+1)*60);
QJsonValue v;
QJsonObject o({
QPair(QString("range_id"), QJsonValue(i)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(start.toString(Qt::ISODate))),
QPair(QString("range_end"), QJsonValue(end.toString(Qt::ISODate)))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100001)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("start block is free of charge")))});
b.push_back(o);
}
v = QJsonObject({QPair(QString("Block-Start-0"), v)});
b.append(v);
a.push_back(b);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("Periods", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("period_id"), QJsonValue(1)),
QPair(QString("period_label"), QJsonValue("1st quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-03-31")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100002)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("end block is free of charge")))}),
v = QJsonObject({QPair(QString("Block-End-0"), v)});
b.append(v);
QJsonObject o2({
QPair(QString("period_id"), QJsonValue(2)),
QPair(QString("period_label"), QJsonValue("2nd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-04-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100003)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("08:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("start block is free of charge")))});
v = QJsonObject({QPair(QString("Block-Start-1"), v)});
b.append(v);
QJsonObject o3({
QPair(QString("period_id"), QJsonValue(3)),
QPair(QString("period_label"), QJsonValue("3rd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-09-30")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100004)),
QPair(QString("tariff_range_start"), QJsonValue("18:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("end block is free of charge")))});
v = QJsonObject({QPair(QString("Block-End-1"), v)});
b.append(v);
QJsonObject o4({
QPair(QString("period_id"), QJsonValue(4)),
QPair(QString("period_label"), QJsonValue("4th quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-10-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100005)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("08:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("start block is free of charge")))});
v = QJsonObject({QPair(QString("Block-Start-1"), v)});
b.append(v);
QJsonObject o5({
QPair(QString("period_id"), QJsonValue(5)),
QPair(QString("period_label"), QJsonValue("1st half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100006)),
QPair(QString("tariff_range_start"), QJsonValue("12:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("end block is free of charge")))});
v = QJsonObject({QPair(QString("Block-End-1"), v)});
b.append(v);
QJsonObject o6({
QPair(QString("period_id"), QJsonValue(6)),
QPair(QString("period_label"), QJsonValue("2nd half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
a.push_back(o5);
a.push_back(o6);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("DayConfigs", Qt::CaseInsensitive) == 0) {
QJsonArray b;
b.push_back(QJsonValue(100002));
for (int i=0; i<600; ++i) {
b.push_back(QJsonValue(i));
}
b.push_back(QJsonValue(100003));
QJsonArray c;
c.push_back(QJsonValue(100001));
QJsonObject o1({
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(0), QJsonValue(1)})),
QPair(QString("day_config_short_time_parking"), b),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o2({QPair(QString("DayConfig_1"), QJsonValue(o1))});
QJsonObject o3({
QPair(QString("day_config_id"), QJsonValue(2)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(1)})),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o4({QPair(QString("DayConfig_2"), QJsonValue(o3))});
QJsonArray a;
a.push_back(o2);
a.push_back(o4);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("Days", Qt::CaseInsensitive) == 0) {
QJsonArray b;
for (int i=1; i < 8; ++i) {
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(0))});
switch(i) {
case Qt::Monday: {
QJsonObject o2({QPair(QString("Mon"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Tuesday: {
QJsonObject o2({QPair(QString("Tue"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Wednesday: {
QJsonObject o2({QPair(QString("Wed"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Thursday: {
QJsonObject o2({QPair(QString("Thu"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Friday: {
QJsonObject o2({QPair(QString("Fri"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Saturday: {
QJsonObject o2({QPair(QString("Sat"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Sunday: {
QJsonObject o2({QPair(QString("Sun"), QJsonValue(o1))});
b.push_back(o2);
} break;
}
}
QJsonArray c;
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-25"))),
QPair(QString("day_movable"), QJsonValue(false))});
QJsonObject o2({
QPair(QString("day_id"), QJsonValue(2)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-26"))),
QPair(QString("day_movable"), QJsonValue(false))});
c.push_back(o1);
c.push_back(o2);
QJsonObject o3({QPair(QString("Weekdays"), b),
QPair(QString("Holidays"), c)});
//"Christmas_1st_day": {
// "day_id": 8,
// "day_config_id": 1,
// "day_date": "2024-12-25",
// "day_moveable": false
//},
//"Christmas_2nd_day": {
// "day_id": 9,
// "day_config_id": 1,
// "day_date": "2024-12-26",
// "day_moveable": false
//}
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o3))}));
a.push_back(QJsonObject({QPair(QString("OperationTimes"), b)}));
}
#if 0
"TariffDays": [
"Mon": {
"day_id": 1,
"day_config_id": 0
{
"time_range_id": 100001,
"time_range_start": "00:00:00",
"time_range_end": "00:00:00",
"time_range_start_minute": 0,
"time_range_end_minute": 1440,
"time_range_price_id": 2,
"comment": "[ 00:00-00:00 [ = [ 00:00-24:00 ["
},
"Tue": {
"day_id": 2,
"day_config_id": 0
},
"Wed": {
"day_id": 3,
"day_config_id": 0
},
"Thu": {
"day_id": 4,
"day_config_id": 0
},
"Fri": {
"day_id": 5,
"day_config_id": 0
},
"Sat": {
"day_id": 6,
"day_config_id": 0
},
"Sun": {
"day_id": 7,
"day_config_id": 0
},
"Christmas_1st_day": {
"day_id": 8,
"day_config_id": 1,
"day_date": "2024-12-25",
"day_moveable": false
},
"Christmas_2nd_day": {
"day_id": 9,
"day_config_id": 1,
"day_date": "2024-12-26",
"day_moveable": false
}
// usw. die anderen Feiertage un
"DayConfig_1": {
"day_config_id": 0,
"day_config_date_range": 6,
"comment_1": "day config is valid for the whole year",
"day_config_product_ids": [0, 1],
"comment_2": "short-time-parking or day-ticket on this day",
#endif
return QJsonObject({QPair(key, QJsonValue(a))});
}
QJsonDocument &TariffEditor::writeToDocument(QJsonObject const &object) {
QJsonArray a = m_doc.array();
a.push_back(object);
//a.push_back(object);
//a.push_back(QJsonObject(std::initializer_list{QPair(key, value)}));
m_doc.setArray(a);
return m_doc;
}
QJsonDocument &TariffEditor::writeToDocument(QString const &key, QString const &value) {
return writeToDocument(std::initializer_list{QPair(key, QJsonValue(value))});
}

View File

@ -1,20 +1,22 @@
#ifndef TARIFF_EDITOR_H_INCLUDED
#define TARIFF_EDITOR_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QString>
#include <QJsonObject>
class TariffEditor {
QJsonArray m_a;
QJsonDocument m_jsonDoc;
void createJsonValue(QString const &key, QString const &value = "");
QJsonDocument m_doc;
public:
explicit TariffEditor();
static QByteArray readJson(QString const &filename);
QJsonObject create(QString const &key);
QJsonDocument &document() { return m_doc; }
QJsonDocument const &document() const { return m_doc; }
QJsonDocument &writeToDocument(QString const &key, QString const &value);
QJsonDocument &writeToDocument(QJsonObject const &value);
};
#endif // TARIFF_EDITOR_H_INCLUDED

View File

@ -8,7 +8,7 @@
#include <QJsonValue>
struct Tariff : public QJsonObject {
struct TariffTemplate : public QJsonObject {
QJsonValue m_project;
QJsonValue m_version;
QJsonValue m_date;

File diff suppressed because it is too large Load Diff

BIN
cobjs.zip

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,985 +0,0 @@
%PDF-1.3
%ª«¬­
4 0 obj
<< /Type /Info
/Producer (FOP 0.20.5) >>
endobj
5 0 obj
<< /Length 1668 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gau`T92jk1&AI=/p]sm<=Rn7p>%!b$[W\P#8XPsHaW)!bE<N`3Q0\MNIbIAL>/l<@?FDh$.oLS@rV0R`bLu+W"*(:&HHp=agAX`8Ss,.ij1ugW@a@cCaGBuXH4spl38[Lq2Iad(SM?*;fRHdlo3=jeM_['r.jYSp2O-:$6MI,N>EmBrH'P4OIS->5kD(kjCMPMYG1Lh2,X2.(3u^D@9X,L=q(*J=lr<PIVmS_B:i)+ea63aR2%%>2;'RO!(LO=]YZhYZ_o#&Z$pWSV[+>[o(q[]sG/C*e,0uC,q1e(IRJ32Vk,R?4Z1ZUInkPLG1?Xp113''*_&)k4)1,"/&*H[P&=U,N,dC.j:PL_=T>H/p5+m]9n\:"1'oTq'gF0b`7/_r]GAWkB%_18OOG@SZ>%&\WqN34k2qMUf9$UGOXC+AS_OJ_Ek1n!^/f=0XPcKd7\NVfBQ`SD5/epUg+b=;8kR)]I2k?<l(DY(Yl?V@(GqV"_^.NABSB=_sM(?<YM27ZGOj!#IqB=+[jr0N#.VB^"FT9b#cSsbD1lU;LK/rT2EmLJrZ>o7HgO^5Y^%?mM+]&F,<K4"^43oGl39hq[FgjV#/B)?-4%kAThG?FW?4Qb+IRKjIcn7jM2W1Ha(K*C,i.<P9TGFW/J:0"O+EhJ&@BYrtDA5jp*-/>n))=lE<QjZ>@;\N5A-L\7hr*EK'J'/B5BY6JClK+rco-1n7\L,oB(qljCiCMIjH9.I>B'O?=olpsDH,7?<b-%=Y;5_iBGl)^Q)JBI4Kl?Yog0(DM.0CMl06n7A/WmdK7f#gCe7u7"YUGp?>bFZV7gPVA1ClC)L>qh\3"*+n!Usr'GA%,1>uLO5lUXl@_r/^Q23Bl]a>u>5nEU%+"eUi-nRDh$nda4FfmoE."s@$!/ld&XqX[l"k+;2'Ql%V4guGA^P,on]]I,KipooEdEfDd`H]KT%QT>D,F,e(E(D`jJq?*Tf7?Pi%i@Q1]lVFb]PtR#4K9]ZAYjes(7LoaD_ZL;"P\DO$.isII'@Zb5G*%nR*n:o^X2c7SQ5LlWpW:oUFV:hR"9D!;m?u"+K/O-i9f9\A'unr.<M[Qq=`^7`W1#*cng6Y4$d(=Bl9'(:)g=G'c*t0UI0s_hWb_mTrcu?!+tK!Y"m"TjDaCZM`1c;2VHeFepghJZS9UTC-)<n1Q\-A1OJ&Mli?DV6[]WAc:IN'.8StLlIUoNqub6A4k(YSg;i+A'm<9+/Fg0Pcpk-YaT,FpqO!O-3=JAlaRD-&\'OE+KI&f9<-D'h9#,">=D>l89]U#P%pWjm^@+E[-E)"%ljKYaV<TrW%3l4i$k8$A]BM0SI.R1%)kuV@HE:ppSSgl`G;Q-uNr=S&reXbn9C7FrTSD"=b_mnW^>D^m?\8AW+tttu91l2=43A1(M!t13#]jol9Uo#go@Q%mM<cIlG]N])=3n"3le1LZ;%gLt<gb&F_qslBnD#.\:0NV%D[PM%+\2Qk/n_d0T(?sor<Jip*k'OS)[):%30@jWj:6/3&j)0"'M0FP[oZ1+m=E%Pg+nN@n=Z$f['lSR-Ed#Q+pdoj>S>NcrtA;VLPO5L>X(n5'5*1SH,7utpU7>^'*?<!IL1$cN2eC24Y)Ys;-$nn#-K51T3_FdF$'B,&]2o_e'QNdCUI?A(gegc?kVWMC(&@B~>
endstream
endobj
6 0 obj
<</Type /XObject
/Subtype /Image
/Name /Im1
/Length 654
/Width 87
/Height 34
/BitsPerComponent 8
/ColorSpace /DeviceRGB
/Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gb"/(m?*&E%,FZ0_%J04&hLj3.)?NI_%J04&hLj3]JmkN_\!2p=Zg;Vp[=Js)0e_2GFf6Q%32b+0**1"@AT2V)!JO@_UC@/qgQ`E\uqB>cL]71)ImMT!nA$s)i!<,:1TVkbXhkRap;B.FPA^10SS:&>[5::FE&;@gIZq,(;PC?Z7HVs`e)."+a49R,dd^1h1@7T#E-=bL$mkF#VsMU<urB$\OljX5o>;N+rl6jSKB!\,#O3eW8S3T2o5s_OX.%4Qc6V<E?#iXN73/NU</+'`i-;<Ft'l:fSlLLhPqXm?s6c4Qr5\RNGl>8jmaq16lj??65$Yd-`7HQn,ao!O@'6oQZF9F#6:"O"\R,bV_Bkk"tmqV=r8D32d<472OkMp"Ged%kgWR9Mr`jkI0W2U!Y-qja"3kr5#;pl]K;YRSqqIA/8As_+.3dOMUqPY8][S-I@8SgEajuu>;hm>kYO;H_./9I!P^HE'q\(7^I;0"";d?S3cKME((79/\C)Nr6<0L$s(^>_q`7=S+6KK33;M4dR_mR]@rtT,2X)AKOO:I9f6Wk"iVlNFWbjO$bb$N_+-fmT)K@#XZ6\Z)FRY&ihOPaU?)RI'eHkAH]U+/U#R?3,8Po0]!u8bOIWn%K&l*ArC9,s@L5$tf!2YnGc2~>
endstream
endobj
7 0 obj
<</Type /XObject
/Subtype /Image
/Name /Im2
/Length 1455
/Width 170
/Height 27
/BitsPerComponent 8
/ColorSpace /DeviceRGB
/Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gb"/)4)Q#m$nZLR]g@b;2Plm+5]Ql-BjIT-+63KSqc)ug#OhoVhT_A@DR$V$P=Ic.6V3dY`p8UK+pNT],Df3D,Xol?\gC.?1hkC68WtLi>ompe%[Z@>pNLOFOX&V?W;cajK_5!LhW(SJ*56pBZU!("f/IoiQRT/\_l"$L_jaNab/9R,G`%hq$BPD@m</,2]>;[ElsH>omUD\6Q?U4FiTF8cA\YQ)i=DUV@D.73f_9=hJQh/m=c-NLqthC9?kW0)iIIaul.k(D^7t",6BQg[piUh-^Wi7K1<)\3"-ki2Sed\,XA[TSh=ta%0"Be!m(;sON<fpX'f2GOHJE3ii-r^#d:^-b(1TbB@?OsN`Ja47fnUc=h,Dfl)e*asp#7OoJRP(=/l*H0TD#ku4Ri\sF:>K8F<uEu%@S<ZE=c7dG[ZXQJ6?0s4u(u&SH<)?[G7.q/P6d0H$bN@[Rp?a;@">B`'<:4A6;-(KLsge9d?m'/<5<3OIJ7b<>8KRFAW11i*80t#_P-?#)'Nfof,_Fb&+ut)3l"N,Y5tKY2c_%0mZ?dT*2lA0'EI*fb(3BMi`A4'h(&_SRk$sG>EW(YGe1DQCT\P7#\cbof37=%B`6"SF[3m9YFuIech7%ctI^8b7-48>4rhORHGe*)qS!aU>>\1_8=Y\R6'nBN`e"%h#\/.Lra`/TLd=='#(58_ME#?>0&n+O7$:k_.GoR,%7HL#YS<QVi(ZiP$8j(dE!G/7ri4*p76gn\"qi,m6t=K.S?<R@),Rt9GD#FR&I-Z7j@R>#ijBji)]i-e7SukT4dVWG+?,8H,MlTEq2R^SQ"379+(9mpEW*tKH_CfW99PTn';F]CIKP^W<"HW9]@$A]qdar@)Q()0"T-'I_sm%6X4\8)"%B^X[ih*o\3>3e:Gr@8tKNO7l/h"mJ2sOT;K>)8+kCE%t0u.olPrCZ.U583Q/Y%ojJ$tHJ.;V1&*1.m:GWW.mZPQ=%r@4ngW'K7=L?`!Y>$W+,X9Y-]4DhR=oG>+6mVcG\*;B5420q*BqFXA:BG)onG:bM0"K$`P>$jTdDknTB9^6Q[S[dV+B,sg82/YN<:"HrH%=W:t1J(I<@9amKjcTS5ZMC/6O1(<M&Npg*i>hfUl=>3=TI(LIn"g9m7kiFrmboEj(s2oaS36Q%_-CZIMYE_9RX\jjDb*3^1H1QPqRu8aN8DY0CFY\`We'UPZa_XZ;9Y4$KP9f^[XL@N=RPPm\>W-aFe(H!`S0iu;DkfgI>4G)1,q]dU+%//q\TlrB)up;187[`?"B@.s1&[J[I'pe#`T?GFr>JkbObSe0r\q.T*T;4JltCB/[89m6k1k0fc,h=f?V=I_;LQ`CjNp;3]b!";Q:Gdb=om/"(F2lMW79\bP0iD"6E`1EQ190EaIHo\?qEVmNis5u&/01K9ahb'>"Rl'irZb3I@,LN;YP9s"m1hlLnj<(iH9@a~>
endstream
endobj
8 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 5 0 R
/Annots 9 0 R
>>
endobj
9 0 obj
[
10 0 R
12 0 R
13 0 R
14 0 R
]
endobj
10 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 70.866 528.25 125.562 516.25 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 11 0 R
/H /I
>>
endobj
12 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 132.894 528.25 239.766 516.25 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (mailto:r1sood@in.ibm.com)
/S /URI >>
/H /I
>>
endobj
13 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
14 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
15 0 obj
<< /Length 1358 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
GatU39lK&M&A@7.kZ.pj.j?:^Ec9Vf.CSH76"=:59b4TfQAJ/.5Y>qlmn:VA*6OGRM^!q4Pkb%9lco4rlK7Mk"GDM,YhIl#6$YhLaSsjU&r1JHJjj5MP@^tuK>2$%Pd9%OT#Dt6Z8`/&^VC=/e^P^G]2'62"e("t$*C#<q)Z]!h1uEFq;c^7rW[8j[A";9!;m"eKj,DUSs=]:]aarN<khpZ:,<MpPFV)a^(i6\D5Ug&n2.^hDd'+&"Z.>0c\t2,2P<@u@#gS'3&!KTn3ge!KisiKBu7_8=WDZK='S?@98Bpk=12>oLdpVE_p`UMP.Ar@[U9Yu&asD\6=US<<]a0OO1BW(K2b-p?>@H;RPtne9p]'cQq^YUTScY=<[`gMBN;[pMlO9&Ae;Y><Dhb-LG<,,n,Ic#%R[er]9(i1:(?sqSu&,bIG)-n^$:(#+[^)rCHhrP;NEb2-1VSQb`lC*+un+<mtEs`@qN"mEPX`tgUM**.[qCRPF!b*W%XmWk3HcCX/<d'[,JDE1Tl3K&6gbS8nc"Bm/0Y*h[r>aOJJ37lrc]n:Ve&79i4[6_<Jup@IOW:f7T%t$'^NU/k[&Db3??j3j/#2[YLX7+Nqb$'N25=38VaWBa(C,.bE]c^q)&>b<V\])%n/PoI"<V:,TM,K&YP,Bf)8>T'6fGkAS#G_Gln'MfjflGP;eIa\*78NqeN,1'^3D8KC\1^+WRXJpDCu+PpKjT)1F4)m:Z0qOKNu)*_rkY1S)$1Ekdk+9ZG%D2Z'*JYNad):m*4o>JbYcLWe>o:/n40H\V31qM+ZT57sI7Dj3Vl5N)Q]$.<2qoWbOPVC\YE`Kmh-8(_pbgk9jXglU9o4c4I0nNSC'L(9'VHcRMj9gkgEOr9V/!M)d+`%[um;?1W$'t4%>>N98aEWF'V'B_-8E\T,j?!h2Bb#1QDTgdkCG]"pj3i9+F>:6^ea=f$Z6;DYV"r@R>V[;Vb]d;k[e8Q*-mtt#>aKts1_jqU,t,W@K]e;]cI\d2oba89F1\fS%6>n6a2\0Yis/.Q1.g\b)m1RLkqM<p`!$TMC#Y>cK8-YLOfeAC;94[tEc45?B.L2+jVOHs?eh&b!>r54+f52LOnlneYNBV<n>J12`_HLn:1^#X$[ChX@F=brkN%3`qe_9ge9:aJ7ZgFFIl?OqhpSE1kPq-jJu'VrdK>3_n<41N2l5EU.qRrf.#At[iad"#XR"4OIHR6:3-gmaQQ]KOci)RCM<$PGTd3>@ks%@N+))`d"hG,f$s@,]6^E!3=.0q%o1=#Udf#!-mNV)!#M&1K.(:U6?TrtYn$P#n0J:^#@V:9=@V4)B1@MYa.sC,!Z58?)8WIJFX.+S>'8j1m~>
endstream
endobj
16 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 15 0 R
/Annots 17 0 R
>>
endobj
17 0 obj
[
18 0 R
19 0 R
]
endobj
18 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
19 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
20 0 obj
<< /Length 2078 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm=?#SIU'Re<2n68ha;(Pl@#PKjY7D!,E[\30;LLh"'7+jsR;BmJLrqE1(a#_fr*=j"XON81jmlC..OSL`J])<NW_C-62k5!PHYe1;J6i.N,-Gs4P*Y0T+(lZ>b?sX?B]"XBs#<1%@C>Zb.=2K&TVWQEamW#:rG=;O>o=B9^.^[()LQ&E^TrO8KGalmacq:_g_?QKp86=WBOD3*Qgn:cKA3qo\:R$#$n%nq2;hX2a,ac:iK\a5)CSh8>'\n3@-$puidhS'>FJ)[qAY'9EJB=m>W4:-</r<"D\)=nF8pgK.`a+7";00usTd7,lH-2+THL(9b_uL&K\kbQAhU_d^b5LS@QCR(BI(<-L!G3,&"18%*$<2)4H19J22#+[r6pWWFm]M-(W[^EJj"0\9*%)cEo3U9`SA?Mrs(R,jY)H(nc(HP>,?>1i'7gg(hr4/Egne3G$R..t9C9PU$9NiDA?UC9IN9GU`9E`L\Du_6YVC_4qQ.i^(4[e2G9K$8(&IVrVN:d7,qi$%NPN8mM\df#]oS6n>\g1@BF>uUcb;YP&_[W_b^kj7e&W8sA3B+trdXKs!WI[,faGsM(`96Zb*nQ-(Z\(!6Vc&,Lli0bC(H4??Soq6Os>WJr0Z(Q-5$T_G;hS3Ui!ljS"eP53cG/N`+&gt>CrPT)d/)^T;E#^IoQ2#ZNYe57@]c"N&k,MV4O@g2a1U8d)6Q5&^ZAeM3/Rjc@B-:obsg:78c&7^`UpcZ'sM<Qi.aHqj4C%/&[,cT$Fp7m4>%_6Q_Q"Ri@g4D'?GrJPEO%+e0;m_Hq%o::I3iIr[J:/R3(^E$e-mPb$2XoA0aWoVaN=XgDAT5u#>?d+<=P8?@T[W*hC"T\JDH$d'oYiXX0#C?$b?9'MdW(_.f,X3)30m--7&9fp(UW#)LdeL_>_G-@^?0srMZ<_r8(W+ie!%HdV=J9TW[5[s!KQ\q\aohW@.#UHCRS%/E8-t@jB3hCI'p]TMg$Agb"5X$id_?$K4!B0O.).esG>D%BdT&Io'4)%kBco.kW59@1H`N]rs,jKu(klu;rXT^]q^mlX)&Y`DW*S:Uu1#'b?m2PuUII0#q1I?=]*M[0!L$7q"KR\IbZ?_"1pe'82eL-N4#`+'eReb;XhOS&m-dsV`2^>0GP')pK:7S8RX5/LUVo^i6Gm0Nqa9i"M@V[<Jp5nE.kO607q1aL]l2$OW[dh&K"2,Zo]cYMY?oFKPpV1cZ:C_*.<ekhREB-dW?p'G4!ocMVdp5_/:j3;XT:+R*>K.(98_W+erS(gljHo.A*#gGWB$6C5.-`NK\?o?pHOo#&,8"\a+%1Ji?+sd^_om$a?^''rZr<E``^udlCV,5+q&-aK1]X:IdBkh<g`;%G$.9R3#UOfIVm>CV9)8=,KOT4.k3#oO:[`5Sf$hA,NposINg9bM=<.fO/BlpDmBBp$U@8H$.%5<q(gc8^6JCI&6$n,bEH53HC/Nr/,^'$(+-<B.]%6u]NG[8?(VSQX>MI`%I;UUVL$/4GKqO8@KAH$%Ist?#e**<-MMJ1o--Jn(h,K<dS-e3sOnPSLM"5l+U92hO(s`n<;:eQFOnZkYV63g2BXth=,#Ig"^HDf@s6akRN!CSBmS)\%f-J*&/3nuZ`C(`]`,CfZ2`G,K1MJBX,deX5^tIZ?DE7fY63"Ij7bcuJX9T=0q#:-*,E\FK/Q8]pYeBP]3f^\$Ii:?oY`\)@L.K3ll8gZ>+GT+UN^W5Oh`Mr]K&bAa)70))/9j<5!4o)o]>sf(G#!3JJm:Ck\ei&T0#e0+kl`_maknIrV-4bLLp<-L$F&5ieW?rDlV&-;SAL`(2__tG[;dD!HD13=);Q,oV?dB(b9%d=>rqXtKl9I4n;+PG%;H^A-i7.gSl0imFoZi!7cfGkA\3G),i^#970fg"-j.*MmEt/?8jAsAR<Ub"U2WG#dM5PT1-T!/*<*DYKTj<B?Q.l:-,"QNY17<B\Fr<;+GVW!Z!ZH:6T^a#.<0@1=iO+s+CPd.Z)#C'rOWhefPU:a<Eh&@/*OWiTC25rD*aa=9/IV8%OmqWD';=Sg$O?L]odY^L%3"5Qhf1Hi&%KS~>
endstream
endobj
21 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 20 0 R
/Annots 22 0 R
>>
endobj
22 0 obj
[
23 0 R
25 0 R
26 0 R
]
endobj
23 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 394.998 353.935 452.346 341.935 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
25 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
26 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
27 0 obj
<< /Length 1773 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
GatU4D/\/e&H;*)+eTpCTWo\<U0dPqERu=#)e?"-%9W<i[V/m'/@q'V-i^n.>8E8Tohl2a!7B4XGC8g=o#SH=jS"dSfUcdpo@:c7ee?fBi6O</b7$MZn3VB_qSmnur,_Onm9.SU>F$#U`g$6!QsHt5T*V#g5N^S;^W-3G'.,_J[dh#WFR8LMpW*jX-Y:7M3>ur;,"E5cR.Dnn,JK>e`<O#3PLYNsQ7Wt@9sUq*LSq$@pm%b>8C$gEc]qBa36sJ)@VPNrai`3S*7cksj!7iQ7(;/iaq+"@f9Rf=G"a9VL.@&qopH?u[XhqX<oCL-eX,KRXcepVj(teK9*T]N4lb9;(^lQ;4I7nH?LUV%.h\Fr\Y=Q*'Bfi5PF.3*L<uc6bP)?@/&A]8j:F^&Qd;6RT,.f3WmdeD8ps:RrSohN?dU;mHRA;=f187,I&J`tK/34P,kf5N3@Jr,k\3lZ3A8>aNH])9XLQp>F?%M^MtO/h3E4\$@YU,OX_"DbUoP2E#EijT@]UsD:RQZ-:,n^=Z.;T/So(3-JK8tuMb0HsEfi6"Klf=ii#a$>QKIhGI"((L:c*N+K$&EsiR5M`6<Akj^<5-^kk(8df#@lY(6prWPFZ`b2eI)]\"W(8<PJbRTIO#Yr:sNVf?#);W\H"JaE*:R>m]du`qlbF0@^G2*#Rus.1Y,QY$i,IRte]X[>soZY"N'Bi!2)kC>T!sbR9=sRP8`VAU/P=i#[-&(9+SSLmGLB"MY.3f6EESb3".26`'>;]ZoZ@e90.sJKYc)jCeY7olL2UVeE2_>)rLBhXI_>\KZd3h]C1<J=RCV)7/)NqtIcL@hm(bDblu"1<]$2RI$\JBbl.A?;1b2Q#,-:qme0_)l9dq';br*[`"kt\VKif5ekPkh^=^-3^07AFO[QTTl8Wp2$f-a7/.SB=AAd^gs+Rhd-XgK@;t$"X%u;(RQg,IE*V^A9mjoh6r`>p^m"r*#VQXIj_hI]iLHtNC5/s3*]'KiSrPkd)t_f7baugO>;CLXKT>amW5d"NQ7k\44"]38$@idWV19Wb1L"0n'!$bZ^)J2-(q(SX_;,XK0oXl6JT2d;]Fa0;2uf616Xr\N8`XGkiAO00*HVEi3%d)eEs1Os;*Bs"RdN2-S`";"nr?XB%g[/#*N)ILK/%`75s3ck`lS=oO!_s4]6=>Y)$/LuA/t/C+sW0g:,)6D6qZ(Z9dL*O/X9V6#=Q`!O;&X?U4k\NpAF#mUMc$=>A>S/hMMbi4-26XTT(Jdb"39"oI_e))U!]E%>1;EVP<g92lR`#Dg9+VZNs`rG3X$*fL7F"rXHCh:(#iTk3<Zcc`6D'NsMk4UF;sUW))g*8M&Rr9p6WO=AiL?Z?S7%rf#T,3&]e46+(eN^Hii,.3F,tU`@9:_^;aJb-\+m)guEBiLlkK46Tkt7qCHdD+X9mbTAX@#DD\?UITa8AQY&AS9G"M[Y5&pD.p6k9%4#2I7_mRZ)\@^>t;0l[0t=R,[I=fZ<raQ@+S9adO"u-jF+cULJcAa<+5Am,arK6&E,<d6O(PZ&j.e3I01L`'YbG<[Z<CRr5Y+:<tGrh7QGQY?/(9STsbIlYA63lS&MCBKgW1h4`SF0U#R:>3FUDRW(d-.`Cp2(W7UV,JnN,@=XB!.$%(X5C40Mn?U^Hm?ea*I.(\-e[4bb6$c7fp1Mf-pT'j1:Tba.]BV:"aSO(K.;<N%7-nj/&/fU?`q<gs&lOD#'_qc.,?GIgj9d-bmWk%4O?LNDTZ+$WENOV=lUUV\Y?)d`D@?Q[W~>
endstream
endobj
28 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 27 0 R
/Annots 29 0 R
>>
endobj
29 0 obj
[
30 0 R
31 0 R
32 0 R
]
endobj
30 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 70.866 513.935 128.214 501.935 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
31 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
32 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
33 0 obj
<< /Length 2041 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
GatU59lo&I&A@C2nE=sFKE):,>j\>$icL^1R`V8k!L=i7;gtYjQ*L5P$VDVQO9boVNlN3iikBhcG[0U`GDk.p`U'4"LbbD1(2RSSLse6m&eZB^=[:JZ(h!#BMdS^F@s3&.&SHk)Oti2ulu6l2(fHu/6YI0?*Kuj6*lRoOK_Q+@3<O5JD$4:mM"e[D!-`p!XCkt.,RDp:%LAi-ckL&M"cFT"o-TgchdZ72R$/dq+ZJC\/GC`GaTZu,r"Ucs=On>L(r^SRJ"JASVMd6h89d`cIk=()F1Ea?d<e/Ai,Ll6IfuC1]\V1%^E(YKMs-;"(X:%lZkH*CQD,7=CU`;flQS++#.Y-@.Z8^`]/<>\dO4!JZS17f.-7K*bneG7'_PT=)AJo^LL=Gk]Z<S4YfmogjZd<V%tW9b(.TUR8D+t"5k6G^Ea()g@+EGsBH#8l]8q*.j6f-U?cWF\o@HK[4)e)a`4VnTB,j\q/;j^ilFt=JA(,&`@&qOgd!^R]9WjFug=dT.[JhlCj0"Z$r"iO`=fhf\;JXrT6R*)X\!:2*dmO*&\bIWE`WhgY_:#B4/^"SK<U=8A>?R64(7u0-aB"".[futbWV4o^W3%!q+k(=f<,KEW[?*fke>e:BTC8\Kj+5uIa+Rc'TmME:5\i(soI!LnR^^/FCD7<%mA`X!>;V].9'h6-;-F]9kJ+HdBt6)P62Lk6,"ikYQjqnd[_.@&.$lSEYGH@J;3h^XID3gK]`C,$`@ZRgkHG(\&bRVM;&Tp<k79YbFBHD>gfqXK?<a,2-/?jN+pdSA7&1_ZXlgFbLt%iiXn9@[&ZMO")sh<4:c>ELq5.#+7Xh0[BUX6JM$PKeZmj^C6[7O(6Q!VNG$>?gReDC>]%..]h]M,>4@Y8>Uh`&o>)2X@[B\,u5&]PF[9-S+WG:#kX<Wa2TtYq+9gFIkrsi3O=m*)1m?0P,^Ir15+#uIWlQ'oQ\":/'*kHE.ojI4"^!'Pc#?Pgi06@f:#`V.9G^Q+>L=eubHFY'!]62bV)!E8WfiDaFlfG'S",]?R\X'C\L1IQ%c)/Em.ZZ*Lg3jKF^&&"WZ/"a*rYP95rGHuCdK76i<t.#$K4_=S%S/Qp.#tSJ9/V<(j$V2Jag,XHrN\L"TOHQ']++op3=`EB-VfRoe/4^p8"@QG$U"QB<nZS>V6N!o-.cp0MfO)dNh!SXUSj0(FFW/@MV9S`B)kn9kPSsmT,5Uuh+Sj>rOQE-rDf0\f0MB2'oip=E+o%FK9iD)dftsQ=(CM-<#l7\jGK9h3)i@H&`(-f7*+C/ckR^\)<(T&#cF\_`^I3gPHSWEl3^B9BLk]ZM02PC@:C)n8QD`Y8U@tWH#$S\=DACZ/kW\ZiUi;RK;_G*T97KE65BeV9G^#;'(LbpTC20o)8ma\9JG\uo41,'&K*d3,OOLS$a3L&0@;s'fU*$-hGR,Y"tut\[*h!:@l:2@lG5CM="G:fm)t0>EsC<?HM%f4HIf^KDh>dhTtj5^!'bo1plme1#rcnnF9@u)f\pl^i-9o27I&')?oN2rb;7FeB]dQCS&g7`H=ikg7NUL@#]GYG7"1O^#fA'[G%be*Q44&srnGJs(.GSrgrS1l&=T95@1Wt-G_@kA`+]cAZo3`^=b/XCiW7:n==]"lDM*1aB-Y&"#+>/iN=KfZLHcuA8.,9'gW&(lDIi,F#jj5e*l.:OB@U$ErS`L^r\->_n@?^c*oLjfpT]CM?58U5lAhs_CU89Ha[R');b`KOSo,]n3(]aBSCd>+?U*AGg@0ZGj[%7jEYHfsE\l(OH;TL32:2&L'^.po$,'E<m0B?,7-.oRei"ImONBu5^m`_0oU4CY7n<3)`JA'&&G]3H2$L[#Fo>(3Ren1,IIRdu8sOib0dFr!B>W["W+.l2^uD/.(&&?T082&VG#d?:rs2cZ<A@`m(QHBT`_/#PJO/c_m:dS4"na4h%%5gHb#3lOU?3t'n.?8bkoWMGN0;X?=2HYY/$%K1/N6lf/UtM3*I_=q7<8!R!XV5k$#T`!L8aYGbk@%6(]J5u\Ab+-r<G83/62~>
endstream
endobj
34 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 33 0 R
/Annots 35 0 R
>>
endobj
35 0 obj
[
36 0 R
37 0 R
]
endobj
36 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
37 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
38 0 obj
<< /Length 2040 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm=bBDVu&Dd46\8+u4N;/R7mUFd^SN:I[U3#%[\dO=I,h+*UJu!5_I>>+=>YosPKo\0iVuc%#kKZF2o<\05,;0?$Yr?$]NP3kFi/QtSn>9\[SP6\1&GT*VoB)nDpR<hAjipS>]mm]j-P?iZ"nt=aI639p;sMCB;0<E@[Gi`UhKkr9RZc/>!WQ6,eIPAUf2B"=f,rh,G-.Cj2:iA&GdJ#)^#>t'ZI0i9V*jhMij4+/o^d"t+n/u+gmL1la(.+$e%K<cWO1%'9"5X9GXs3rIep`-*ZZ_Yq)Z91S(;I_.&rR3W"9?UPi1ImVYF"q)G5Kg)s045SVB1[+,WP%K@k`N+(_>l(7cjoiuMBJH%$6<eo`,kel&Rf]@XdS>^`5q5QqDU]Ip#E`R94X[pQ=VicbKIXnF*@NpOG-$@jKo#I[P1h_j1$b"S*YCPS#RQ"u]AYn\>()M_pEU*K2MmYHm=g,qG]+%=R*ngRP5Gj7f5L^7dr/cfn^25])(079\mJ"9E7dXl,UYjij*X9qIKG%E:l9<NMn^>Kr:f['J7EBVfO/4:Z87oZM%kPR`DCuZ&_pgYl_mM&sLU6,,P3!?4@K+[I>mha%d&L:aWg+\dNmfk7Em^1up31B'^EjYkjaO(#5mo3(pToR2?V4>W;)CD)m%&M_r9X@\21+WbU*25m`+Zh%@n6=2\Z.F%PeLmFdLJNF^>RE79eYH&KD1n'PBg<<]AnZ`oG/u-0LGdg/-eq?VR$&`C&Re,O<CI+/FFD[s2=dM!nWIjm?#ps>$!i]lU5`)$\8OR;4!Ru`qs0odaFYP^qo!f/49Kml\GkcEpfOn@'o'2/XCg5"2JSSb<jtc)3/H/iCC./?h7)ng;"RV`#(slF[O>C^D+>B(`G+7LO:g:PkI+J&&:j]#RkM;"CAA!/oh%DkoET@=Cj<?B$sUnmj_EG&l"Fu<._:u^fI3^/6R"!29%?N'Gqs=EKgX'fXUSc2f,%;)&i?ibMR)^"(qr24]o=S(<FT7QWP0E#o%jpoc.fX&q5@m4bA44jhIXdmAiE,#7tI,7hGt9]U,YIqV9BO2M[nV*&cmM-_-5>A^r^2(K['@20Q:ZVJG:.,CNAqu-_EA=+i7Q2cs`/J2>#5\'cV@0Re)JQ4N%A]h+\%_m%3WOm$LS@]6<tdkfU%^RSIZ"/+QudF(jO8iT,^2aj>=r@IOM5>+4&Ic,DU=H*DnAYeH/SLeYup$.e*)!d!#`qpRf<!6$K1]]ikcJm^:]_0DesHn6tkE><u=Gd\TtPqAuE0j%/9L183g=Yu]M>O=HcJAPZ\$q#.n)MONK;+0i_E#'ddpT-q2R=c^YWD9i=&n1r\p\'1P*0BT8Sorr1+1TH]_]<t-NDA3+o<K."h*_WPfuru+)Aq.+km4%E2F3b,<:)]jC(p<b"?B4u$r)lr?`ZB.$jaMW>?D<EV+f/7&IdN%Y$#UL2mRd)2\#4?L'No:PQq+tR[VBK\GfFM-a<4<.L.^.V;'Gn97p.[_fS_2``W'/?J-Ch,iYeg#Q6eC2JHhGn;TB4;]0MFjn*"9TNW.$k4`fOqP`DlWa[ZOq+3^)3C%.kd8ER''F4+EK\&>L)<IfrWK\tHZMTo=<q(oXH@8`*_7U#i/pR6q`4M-%%TIH@hsAlmf9nj.BZPcSiE/GMa\7'<\FoV(')-TM<cmINEP\m0bZP=58c)V2>[TD$m6U#@*Sf$nMu+O[03QCGPPR):(/\Ynbr*'kk;BG`UMC&E)QeB>=B4n2cuU-0/-n[Q]GIW+)5#RK[d"idN[PlOe,&K#gn.4S00L`pC%tF9oD>h;%IShQlXF!ir!.5`ei^S1\\^dNArMl)ZeYrp.]_7qk0g=Ti/<$kK=%2;=kc<;s4nidpf'%n/&ZmDfZtFb89NP>L<3s;PF/j;M?d$g;>SdX]JlYt,^4$PT6T?eDTB7FZg/brRs"3\D/HT!PLGMLA5%&fOr>gq(!CmESE:AMN;$"=mL#Vaanek3%g4UGIL!EJMMrO6[c)J$=:gjYW?D`bj0l.-KcQ9r=[B\^m:q+D5HS^LNW~>
endstream
endobj
39 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 38 0 R
/Annots 40 0 R
>>
endobj
40 0 obj
[
41 0 R
42 0 R
43 0 R
44 0 R
]
endobj
41 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 114.882 248.935 172.23 236.935 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
42 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 70.866 115.435 128.214 103.435 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
43 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
44 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
45 0 obj
<< /Length 2128 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gat=nD/\/e&BE]*;s7eN/uhI"PdGX+p4*PhOKA``@MoBhVJW$4j@OC?m*h$(7-Z0ni[$"1<]9Em]DM+i4Pq\+T78"*TmkoO2iGK+/r1=B5K&H]58M+o#k8d(]]J#IlbfEtR]P.joWDjA/!CM7]<#%9/cCaehqmo_-,tnr5Y/iKO1!>/>0C5`SMk3^e@Zj<GA4;d%sbT8p9J@*G@\!@&bLN*GHughn=b+VJLB,_URIc8cl]C\['!urIo(%F49l>Ek;:B2V]9eZ(?"NX^\)BuaSh1u#>^BXe6N-16&22\Z'Dl-XKlKLT%30Nd`JRg0H+1-lPW;_iLrB@"YD?@Sg3j>QCFt+Ys#dP[QC.-4#*mU5CMf=o!I$jdk*8S%s!qPZ;oUhA`6F\5)B'b05]t_N2CWF:gqpn6EM=gA^s$#B>sE<prN:QMhs^6P^-GDosi\AL[.0C&Moiq'MPVpW'8;f3EBq/(cX\I)g2kl]NkBH#lK?EPcFs]HPo8d@,.OB=ZN\b<mo_Rr`Ir,LDD'o>HiXL/P^.s,j$X[(qeBEZ7QW*ks3,<-d%#K2.Pc##`X3uk"X.-0c8,((:86Op`\fPf`A.oe$+/r31b1(1S;A*=3;._3.09Ud?(eRTmp[e=OYYSjkQb"fCZ<ggJcsQM%6<-kt/fs-7nF&Z.Hg8q\i1,7gIM(+Taa:]7441&?fe="cTq9rfcH`"FSUcKRUd4l`>VpB-V1.B2f/ABZC5aiVl,r6_AH^3s'3&]=Sj;eW_)5jg8X$V]#c`O)tWoQ<R^.W,!A"[.el-T=T/=T^V)ll:HNJV]"0j+^l:`L4j:>c65IeDU"c7?`\%?X!GEL4X22g[)3'?>@.Rgh@:$Jg!KB&TW#(3[4[,aooZA"C#rG'&B]=A>11>D4YaNokTY,n0Lb3jnV#?@A#IdEN#dkYk/QEP<f>q6HL@,SSU/P#J3ujHE)<#b^gV=B3/"F8LX7p:0Y/0-Vi(S2OO`9fqA20N'G*(bmg9jhKWr8sPsYd7N3:0Tco'Ge\cs*C=(CQ<1"[&C)Ojo4OlrW=SNtHB^<+RJ"V)\m^d2fR3/k!ELX7p:&@r&c7TY6.F>;\bZML+;k1C-'_.->KT&/ks\7(UZ2bVl@%Ahg!ZZP5QDAZ[(%HFYSVKEL+0^`[n,/S5:9V'JQl?aqcU61JB#tE^CKBb(2(gW+2lFP=cF:C9a^BRuAMa<,;=/--:lk[W@S&Cn=k,QQe!>58IMQii^pC0QMY,7$%2&$Y6L*B)g;s\T\'G7X>,,<d2O/W-(EkF#ck?G8qEX6ML%Z7m>@<=@eKWZJRco'l<\scm%M]mk;2:lg2ZO3I<FNYU]KDR5-n/KY0Q4Lq(&qL\HKIpWk5l?@8%8L"]`ZK!9F_;%IVkm:EU,D_WPMfd-U7@Ji%XE9C&+?3'o-,cu4Dcuf[>4M?eP(<ZYF`%3in@Uip6YYs/aFLuM[WR(TBKB`b@>Hj86>k+5Y8"J^Ob-2[IJn<dab?[_IAj3/^_PAQ(1JOW6(HRM/5q4*A<,+`l1Nq#i7\'q?)&,`H,(FkO.[+nC-PU>=7IoSQQ\c[G4gIqTKqV$(/g!"?TV/QpB;i-:S)9n&GXbWiW5\@A\cIeIXWQ(_g";OPX:=;GZ@eKZ8)%+!JIYS%X"\Qk4Ba&k@B>_f.l3kh>Fq`-p^Y$=bm(!f>I\>L5=YN"WPY&:/44LSn/"=Ydiu7$[kf?pm!I',<rVBeWTcl1QbC&YI(MV=i;.7=K@%&^E$+MXO)#"'0Wt=-j(#D5XrP(tI6MkDSfN4)'^uMfP%dQZpr,e?.2:[c9DOD00E`1JVX0C+hG.h3;L=JD_2$ab7f8Qa7Y`CQa71eQF$BH)`$n5XV10%,Xh;W=-);aT>FbA\fs6Z@J&(kB;Lt$A%[kS_9?.A`98\.l2aA2JI]q;fBPnX(npoVKuEq&psE\gEU*J3`IG3oB^2[YKHh,[="9cWA`\<AbBnBkmc0_Q]fFuZn3=J(IP73410I"W3c<mR'#KFl/CWT\>dXLbYK"I/SZABSare_B0>6@ln]\e/hYZd7IJWe,dcNLQ..MQ(*RghJj7+3]N3^/#<(2GS)<3!PmVPNr1QElNItHn)>BO;%^<DIl^'BSps5`A(fgS<\2@2L~>
endstream
endobj
46 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 45 0 R
/Annots 47 0 R
>>
endobj
47 0 obj
[
48 0 R
49 0 R
]
endobj
48 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
49 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
50 0 obj
<< /Length 2245 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm>?'Ca9'RekG_;m'0e-%$B+E,rqA(!s&mAsssd-Yq^7^e]bU4BT9r;$a>`"`J%B0)G$)k21rm^Yh#]$B^>k5G/=h]'n$EJTFW]*UVZU=9L3kPCQ*87$Y'0E3NiCiB<_\\3flnL9(.JK%&=FK^b(/&.P__1?fQ9W3_K&F39br)6"2)=[KTn+c:jlg9ZZ,CIOqs*Q34?"E$9KK/;Qq<MTq1p<FaSb92H@=2f0VoSJp"E6%(Mhj5A,5/73-o;9+oj'iM7%ggR,-M*^hi#W"K*?9KK*I=$A[$^PA[$aQAY@PlbMr4NaOd*:2A='TTRn%`W;r%iB!?ec.R;X"=bRu=WLXn4EC3N#@>2QhL=g0K*_'iFa-e*S1bllt9e9\!9sA9!G.f4^*+n#^9JFou0dA1d+LK6/Alp@3"`,iEO)<JT\RVR@pJ)\L1N(RU%'=W%fHqW_YY#-+]5.]b'AJ5X6fWlpT-B,G.M`+8<T$Ea:Wp%Gi$qkPY"q.7f,q6PUX+:`9"DiW?XnBlpe<UCNJd6Z@XLshi"YEADmOOejLj;XPut][78aX<1j_DkCd_U,)6\cjlDM#Blo>>rj=+(.;"MUG0%]Z#^(e9n78o&E94aVK$!l>mf9k+QGAnk:1C:^]ZGm8ko<I@;gYj?q&KS#V=_?oQ25quhmV0M;,7#_:?>\@"&hWo+h55QNnRT33*f?e,fEeGNn33_29iM'#7Ma,gnYJGom)k)GIE5D0;[KaE79aKTBZad$@5l+c69=;*KQ#NeCS4YEH]2!Gf\nk-$*;8cH!(k<P0*B!3J:D%IG40bF/Ybg%kmCIkL2d.W`^Ub7DYU@p$c_ki(4nDn9nI0/Xuo4;pEgL[F:0adl0%T8$n^Veu+/M!\j30lLEMWTcV1H8>J+oMP%ZaXK'nb-j6g?VE0YNP`p2>Wa)%WOM"WZ\$quYL0m5BN0Gn^UJ!J4[>0MMQ_LW].5sfa*Y:?X[\H<V/PH9-al?409YrMb\W<I8joK1o;P[ebV-,^Vr/V_O9oBWPnR.((nq0`RqiW7^?HR&L9Y#cDVet2*[d,.?R?+9>G?tU-][m<D(ppq?ed]r,EY1jW_<I/fL?V?V]hkRI)+S(%KF="V*@tO)<Zhi=D@tdaehf7lVKXZlSCW[#Qq%?>cS!*aA0FTJbr>lh6->*::RFL8d,d_?TDN+/kqN-578Ou6nkY%t5Y(2ZPVPh>EZN^P?Zb&3>@n>fd6?<\lG,4l`qR;a>0KYFSsPj)c6q<5<P\&6(QO8^U-\YsghO3U8/lg"WoT"&YETo?g1=C:CQsp.?5[iiZdYr)`tG&n?9A7RC6@758_MWt_#QJ[Vo@U4U,&C%QJb/^\!>$CXJfcT$2G]-?-R_YYpuk-(*+BJoD4"IkM6YAd;bR'Ij`a_q$75H%=N=e^CY\]&1TWK;st7?F1F`Sn=#_@&$bR>@MH>'N!RKn!:1M^NdVcA0#?aVU>PEP%XC5m%A?f]5J"ehV9(rVmXbm)SY4c@(3A.!N,4E3]F!<R4RN,mC'.0WBHJ"_@sces"R@F\At$X*bpA-!5kk!AjcLhROO[mjQ](9,H2:P]5(1/_BUFS.ZE5\A-sJu$k16(417cMY:t4=C6;(>7$ZhkOdJM7AL%:jAI_G\rONBn>$coS9kP-OP^%Wq_oH&kk9CF&"Wp9-MNm>#cPi'\!HG=/6N'F/k!7Qec%!L+JRjFc`AgYp;bq;(h2@EnJOki-=CsP)TL2h,h*84SuD6Wc=n>TiD?P$HnEf3[K1Jgi!']ohOh[=.c?"lTV:?Z)+V%j<u8i$e88k?hc8df$9T:NRF0"]b"]@ajCl<YtRlA77$FZZ=@DO2uiAm$u):^2X_9P0&2b\"=,5pp1sRGEaR1:rs-1-6ai2S0,HZ-Q2$CR8=CT3Z8?B6EZ"M1su$gN&?BI#`IObjmO<cACK?S[6R)/bnVd_9`\1)gR#hGI`)FPO?KfE^h!,7O7?cN&K5;.QC5^))p(b,d8r0@5Y7G>g*G#qBa@Pk5pqA"%$iL,*E020>`;3nfr(Aq,V%^Yg$7rrt)*c=$ZJaSpYL[GY"ck@aoV7^@=m]]_YQ+?g@qbk_Nmp?%mo.<;Muo)j.ndUG!h'rs7T[@2JZ8Ss3i9[4+P@VlI3a/m8?2G18j0/VWAd:ZtKpWHO;28>Pu7M):+UMBtAtZfr#MC(U+3,5s:G0;:R0l#%$eq!%J[r4\=cNd`0>SjsL2*FM?A/E\H%m>gRaG1#s3nA2F0+6OYDpA~>
endstream
endobj
51 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 50 0 R
/Annots 52 0 R
>>
endobj
52 0 obj
[
53 0 R
54 0 R
]
endobj
53 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
54 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
55 0 obj
<< /Length 1831 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gau0DD3(/G&H88._*qNb]?5FS`WgbSLUOdr>4q9#,Me-PMF^&H</=Hq]:1n<J%l!m*XJRpdrk7jZ10WA):-K9?;1V_\(%&d0oa:i?lJ>32,*e]*+af6gi,s^:H`2#)dc'5bMnl.[EBsQ?"P%NQ^NfM"\`'Z$Sk26>^QpglV$9=0mQjDE_PI"@0i24[hA?\aKf8d"jJrV*i,4=pnig.)/cc'd1^Q$TAPFYrT!RG/+h?.8+5V3DA_i:+:^Zh;G[/RF/ABN/ZYGi<h9]dL\G62<1Xa$r)5-seGF)<pc^Bga5@JgWd8tIW-'qR@,0\;$1M_s(UH\@bQkln?;395YrLZ';/ig$@b$;H?@h$d&P%)b>1]`3l%X/bb>U)H8=*dE\";Qd%a#q9[g^)H@[4t:Xp&Hq!^9cmfrT/lFEB1RV1*E,FdGmRcB@F'4)gHUM\9WY;X!#?26KTBHk"#Rc.0hA7(pbOrFl2a/V8=-ED3tY0q7uQ4I^'7Cj%HV57=4dcV@!J=PcPoio2.QG@NHfLX5X,p`^bg0XeWc]fa^R8jKPO,JY>B%7uZKPO3I&*\UT$irXhb<?Ct6c7mt=@@VV]EQdI9:_qi;fh%QkEC,@.as]JMC6\X:M+2q.aTo3L+SSEgeB\[J:J0:rC'LRoZ.tq6@JuFRTq$7;_;M1`\0n;.61Yq:h&f[V-L@7[_)tJkkn\%`GX_"?\n!o0eA@_Y1FQclKieN+KF1m('hO$H()C5a/X87?$QcW_/'r(=j2!`;$LL@B3lb-PFaHt4YpiVMFX6-6b2`7N;s3!H(6h)$-ua@^jmb[n-?a3JB-u+W+p9R8e`,b?45!Ga4lr,>["<N$I@s)1N2iS3;)OJQ'"M@foE7lcD;P)F*sVtB>6eaRO"(AN5ZX./.!ArMV"qD/BaJ8&lq%$*1>_CSCd@b3)Te7n?KJc_@CXk6AJ)l@F<>(=gnmEG?IXOVoBKKtorWjGZTNA0l$f4nDCX+:]5_^P=Pj3mSk!UtNp>'0.P0m.R?#@225iUpM)rm$OBsZ8:Mm\;LVR+jc#2%e#!^k?\6S&T*^a2jG?[JhdKb8W9&M<mI$M#Y[CrGc8=3kh>ssrtLPX)>7;5W,^6PYl#*24M)0_OrDG@M[/R;F[ifi^ml2DaiCg3N=02lb1TU!a5.!X^0VT5X9STiTV)"Q_Qs4bmB[6"RBH^Z$Ta!S\$0gT]oc=qKe3C"ESZ:fa+WEi9.]-i/5R&<elbHm!S.<?r5)6-d\%Pr5Y0=T+d3.gDYm71FZd+YO+Q6<'X]1ti=F-^ZqLHYcW!<X'b"MCaXQ@Sj-73M?Z'Y876B`;K$UOE=l[nU(B3AtgWeM1sE1utFMr?C"k8G=rSoTC=iouPaGcfU!6G_SnX)4$(H4NIY4;/Z5PL!'t,3;2$,L:/dE(]<+kTg8!;@7/None*pQDNF!WKnK:7bWa#uin`X(Zc9HfCOAEDM)+ZQhm&uSIkT"Z+t26@>Z]$\>^a=FY!*Bte&sIphn0lhd<u^iod2<<$>LT"Ou-\`+cZ6[g&f%`)t+qiqDEfQTZfRM+:_kK*/;McZ79H7pB^B[/ad.QW"c$c-,MkG2HP8jZ?pM2B]AX,5@3CDg%qModFoQ,ZMrqW?U+OsH<tGjX*34Yf+`uJ+Cs"-L3ZIc?/I2cq]O#rrDP'#dZsuP-sd[Nf*8O;Qs./YXOVL@:oL-CDtY?gfj]Q>P=`+,XqDVEE&u"Ig*q3PDQTa57^=pe%J*dHj).6'8`DCUf^EcGBb#ffBfjkc6r#HSfH$,o]g3A"mAgcmI0)mH!Wf;'Y8(:ebrBf6hUq5%^IGs/OM*1C9Pr$"rWV3Ud#n~>
endstream
endobj
56 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 55 0 R
/Annots 57 0 R
>>
endobj
57 0 obj
[
58 0 R
59 0 R
]
endobj
58 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
59 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
60 0 obj
<< /Length 1888 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gau`TD/\/e&H;*)TbSE+?nj0(U0d[J.FP@dJnD-9%VprQQ=u&0/@lO\`;B5&??q^1f`&5l8OZ4s4hTs&GGMAWZaV$\KcO].Mq-%[eh_-qqB*-I)hl"E"W/I#8(M-ZI6Uqm1_n>!>JE8/ITVLm1t_32"/$_K'XkdrSgt73\)pEslIX?EA?ISNf^ROP;\;7f?5As>r[LeqH/A$t04mF]2Mtc<UZ^K?I@PGDYRu&87;Q1\kLas?O$-,kCH;95G-s".!f(FkUG/d!2.AG#n=p=V!eQ5\X*:gC>*a.:BkU6C%5;9jHi"tlU4+f#K+TGjjc]rRFY$A7@`9il4f>T+p')u>U>@`$mUJ,^j#:Y?no]f.%5s_CGo0!Hru/:?`KI)EAQZifGQ6GD\LNnDE7[O%&2nL8gG063m/d"!)8Llt,4ure3OW"a]=6ZlEFFIkWi9<"Rn:k]=*&fi<S0MgoH/&@Q[19t`S6>M5nc'Nc!9C):!q]ZnjoNoSsCi0NOYGN_XSQ<<]\%q2j;+;<kJJm,D=DH+c-7g_Bq+&W=jl:IGZL^m6Iti8/3,JF]("U`=[hQYabFLneA!JZntDuVio^I@A#F(p"D:KruGH#pLe0rNUG+'f.fTG,&SXVeP7hqQXmsDY>X2KYq4ijb?1><j*9"^j!2/nrfq+NYl==`o#lA9/8JR=^#\L)9k<\B68aC^clYcT>cErFi!XUU-OMZN(^%420\<SNEh;V$^%FjAfh#b.J2>:TQ4K<nKD*0tBQ61l"tHiZCk,o@ZP?Bc9UT,2%h)!.544+t4TP8CZP],IX,.YWG+8&i2DqjgK+@Lbodb!@.[$VB/tnlH.;*Vjg:L(Am4jHq;ZCVik44)fF;/MV0i@!cRd+%s7hG#=PBiS.O=[)_:<_V)9jD]b,[J;-a<jkYGi%JF+t6tdW$I?-\\f-jp8`bHjbC2DFX_mk1+2,2C_CO5=3ih1=u-=/YnD(E<R5>0Ut!(7h2V$i,eQ>H'(dqYBX'f>lZE6";or\_2G":TmAJ.<n!W,Dc\`MpHt5!Bl%F\#>AYB3E]-o95aDH>'"4OG#lpT`"UG2^GDCUgVK,Dl3F?f$$+0jA=6.'&0ime0<@o87&k=:+<KTb+lb"0^TG6j:H>GjB[;5TsEpidt+msNRXc\"dkkL=lYo-:,KWeEMp/3iERpK"pN-_No<?^&7piF-iJ/JATq*]L#Qg#XAa4,8=0u?p`nR@(n/W1*@j*[kMZoc[(a-(5][/5Y%*"H(8(:krS(Y-3f^QJZ:?nY%^43/q>gNT:)?%;*NBhhAD$'F[9rTV!5k4,C/*nY+I#Hab&cQJIu#=I0NJ,0'>`nT5c@i)[!Z!9@IDVR;`l#Ip#b5ptn>pTgSQuA3>T"L4H/X$j"b'PC4%s(gN9tifGaX8J5eAH)1[69\qF&-ue@Qq)-ST:7LSUq^7m!;E$f#_qGhp(V<+U:/@.B2)CY*:m_(6&nN?-3pcF^dM6[DZ!B)U4L+'fkWu0`<XhrRIsoqd1L3?@NM"Rpt`:]Oig=ZV=jg*q:iDO6j:DkmCOahKjojP!$bqYNYD!%`11FTI/uS?>Rg-3E<2^L`r]%CdB:0%B@qZ(L-,d:e<Q@n\_rm@uoc(54n`\dtaLDiqTPt^+Ds2%iu6jOn;+3$:L-FB>N\SCR=BjEd0RB:G8K$b4SFBHY9fCC9M6hHuH(=TCAiYnVF:^[NcHI"d9ms<SrD^h<\bceA:l0O47M[M3"1*Z&l1;Q3r%rq5031q7T/nJOgj07F<'Ipi;#ZM<\q"]n`](s$[1us4cD)3kS8UIu*NqXtJRMM@2uh[\8oQ&1smu[(V#u6hOc%GET-O^lnM8FUOg7mH!1*W]L1ug%pq?,i/%7,[e7MSJACmSj(d_T6(#7^0aZ7~>
endstream
endobj
61 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 60 0 R
/Annots 62 0 R
>>
endobj
62 0 obj
[
63 0 R
64 0 R
65 0 R
]
endobj
63 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 187.59 363.648 458.622 351.648 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/linux/library/l-pow-portsolaris)
/S /URI >>
/H /I
>>
endobj
64 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
65 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
66 0 obj
<< /Length 1987 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gat=->Ar7S'RnB30_/&9J0XB/=gnEKeeB"U-"oDW__Mq57+jsS;'7;LhQJ#446E4fb0#e^;psY#c?F.gb_Q#5m+.RaY%:Dkq1Ut7?8rU&r]-1`[c0!27#kc&:,86(PJ=<`/,XR2m7+AYr(:?t&usMfYU1(o".tZIrI1OG@YBB#i-.Z]*&Ch+odFI["Njb9o^D[F<6_bGemgH61R\9s2)\,P.t03rK`FA59<^!s((:5B";_ptJ>\\P,$&*Z+t6W3BqlFm!kX\[)F>sqLIQ@@!-V2(W<I.WmU`T4Z*/PuCQ(&e)86Mg7?#6*L3$6)*?<=2'dYkO7_X\0elfoDN)XN=A9bO*K$X.J\@%bDR+SD&29l^H%B!Va?AXDT!LOZeB=H_PbIZu06udQtIl%+PP]9AP5ls/m?aoY0BP<ArJJNrriu0_a/kNGRk0R'A?jl1kT'RH@ClS.+IbmC:p_f?>JZ&I,$"@*n,<uelYqVsT_jiV9"]$%sQ5IPn3QZ$S\RA]GlOj+=rUg!IqbJ<MpXC>?@9/,<^nnm*0N)d_;,R71%#)V:$GN9+qMJj!<Sp]C[/`PJDDhEhIdXF&?!Y`j7ap%O29C<]S>t12ZbWn+M^HcBhPphL7YIZQ.Qd(0e^3B9ZJbk2&nON[(O1qHAjHb4I+Ra+5SdH3".\=L:q#b8k@qI!3mVu7,>KCo=NIT)VWuYMDFWNq?=\b]XqJ[Kd6F3C=A]kb9\kTC7e0GI5l*fc/gtOJ.H6^j#=/0[/9HHH/!l85_!B0)(F>tuqtTpG6j9,NBBsRHF.9rLR2_ZX2GC<"-emQlS2N\aU\YJ-/>\O>4k1'+A^l&ur!K&s`r=i$=^g4m/VuAhd#BQE-\e`WWaW$U.6M"ODU2Y<"'`>$<7tZK)-+fuNX`L==ql''I5[h,qQ<&s[,1J@ei"lt*q+Qi]q<$<H#$Vg8^EYt01l#`Vc^b`=MU[<%-&,`:a.r/Cq2j5le0/p!9ZC[0)E-n`1pnl[`1]-.h"!Wkj5]A)Ce3lFr$8Xq5=,&)c5n/7gc^mn\[YT<O6V6r/4'i-k93e/BJg"%M!,LX4:f1%piq1l_0c]W[SagN'O#bnfVI&^hW[3c5\.<jpJtR<atQ-fA1`^o0^J;'^#N(dic-;^2qOiP`)YpTpPA;WZ+A]'JOPQZlNLD/^'^eA8Y^NBXqDGPIE\NH2C65#Z;ICF(Z((:aFYkBV8k=YQ%ZdR#`Jij?jYLiIC3f]f*dE8)N4VPhYgJ0iPW%55Kqd4A_SEC,Z8_mb*OT='%&[Jgf3Z>Fraj`3LT0@*teDZ)P2b'@dWfO*?)*0Gi00Lr!j5=qr//Ll#SGXU1b&C%Rl6J9cDlHh'Alb_.tQ4OE/4E'OBqmH4E6f8hl^Tt]PV<Y4KC0_m^EL88iq3*D<J=67q7ZWnl^JgApTN&Sq$6S%\S?+a\!']pOu>!:e!TO@J.QW8!*7GWdaV$]t63FQk>X(ZY3*IoFU<+5l$bL71EI'6o9AJCWR%N2hd/G1MLT]>V>E]9?Y1k_AWH8S'\>F]"0i09oG6L]#r_ZXGlVMuTpk@1qhUs`Ll,R=/V?FXZ_:Fc0Oc/eV%^JghUqWr7\@&.n*.&.7l;1:O\!i9"g7#3as<,;>9&(;8J`pf4T>4D.&f^WEir%[;Nn*\o7VDn9se(IK>l)Z>rc'cH0aUH`G%Q!"L2e#_-<b=b7+`Oi>B%CWoiCjV6D%aW7ZmM[I9a?\5YI\j@*P(7l#m9i/V1C2q>l_d,b4E8_]=Pq3dW)[iAZD*o$?%uL>6%4B3P#CkIt"a/,jp5o7;5=AZOF$W6#4^DT^7$7Pk_L2HX3F?l4QmUQEF2+q"KF&6jK,U%ETa?i4N,iVI)CV3iubtF1i%kflR&mCCb0sQBNQ1^m6]-7n*c(c;5jG>7V%ViKDp#rFl551tkg,DJ6^pA@Vc%]DM($^1YkbU_d4d[Y#g?,sWg?,hLGN4id`+&p/Y9Gd);f_fd-b(]OLd06^L~>
endstream
endobj
67 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 66 0 R
/Annots 68 0 R
>>
endobj
68 0 obj
[
69 0 R
70 0 R
]
endobj
69 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
70 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
71 0 obj
<< /Length 2197 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm=>Ar7S'Roe[&C?ajBP<OX[<l*/bHc8+\%((FAM=gVG)45&.S<9k@K1aGZ7^p<kW%4`#-_X0g\77[Gf[O#bi\An72`A4`Hl-#Ri/VMpn=!lPJHc@T2NO?BJ$[DT._kLB@[7X"'GMBQW:qU<2pSK@sNtR<nVX8V=BuHQaQShb_<a@c4m$3$+XqGe_31@Xu0Gm+,_[#HVO-/P91EalueU(c?tjjp%Z\fBi^LE<MJ[L&Z6Y=''_NhWE^H`cCk7F6=$5hVmH1AP@So1ZL"aE39%mbI1gX*&p^CK0@fAhlJ5qCF]P7Fs+&nmdt_)(-@dMSCUjne(Ru(u0rkl:c0UeMS&HN=1Df+"V'u7n`-P=u$hk9o:L)&3[G:#*9T-EOQ"S0s7&Cs)8IT`2I%Q'EZTQP\rZ4XKLR\k=QBu@SeAs]JBA7mkr#\thH)gJbl?"H]R+H)L[d?1Il^bUMP"8l_N"_O<D/#kn!oWp5"j6Tm_S1%"`K3TD85V,&7CEg9X^5Xo8T_VPM4Y4&J)K1gQ((ugk;Kol\XXPc+'OET`P0T+\_[c^.bc-^C/mei*;^Y>(nN3Coll$6U\.fl8qFb5R8>M(&sY4FeZI%ecQ+rak6B5Ih-4kP<rtaN`edAJW"Z#[d`q;/fU6]r!M]<W[N/?FqYe$e%bCUj'sU(sd^7-T;/GhLgR0g.Q)-!nO8<H19311H[CK,aNS:@0+>9`sgnU[T/>oIj*I!#@;X7Z/ieT+#\Z(JM-:)S1>oISA$GC*Q^Sp%!PZ="3=]$B8(0GiEU8^(Po5=%<)J[S!:7%GB-4$k+5O^R'P213]LjN"c`q_k.%bTV<hKrM4i\:L8EG(B1h0g7$m3NZ7VW%XP/ISMC%(eD&aQBb=1MsY^N#8r(>`2T#6';R<aeg8*6B32/FY=d^R"JX4mV$sNk1`9`qVE2b($2u^MJ8B&>5DLHOP0M)RLQ`PUU8=TaV\I1kul!UVCCfWT8;a^$04kO.E^2RC=G/LTLS"2d2XsULN5..cPuZ.]!5;bAVQm2,FKH$b7lk7D-NcIU.eE(JuE=5k2C_6'AZB]<FdR_Q_H0emBV;kBHiG-g//jP&%MQdMGt]O@5EtQ!fS4j:HM!!fM7GA='6.N;ONF<mYK-%AObo@F@qdb14tFk`7R!$\5+ZgNBB)c:SH*e?i]X["gWa)H\4hC8i:sSq=#%qi]0\V!MWb_aUt[8%g_i\""C@nl93(mR8!jm+,hQ:n^4jeHL+hQSu<,moXpb6CHCX*r5StT"H^5ZnS0JVO0u:ddDHe0Ul7@G<'((&#IOm,CBZ:E2B_).JV[np2ED820mb29,iOtdif'^Q'7@lY]+`m$k@g<qP++:#:?W!(O5"S!bf*#aOfE+F<MNS6X^o"8@,irkFgNX=BfPB=GWNhlMdU@%NUk(CdT/u=BdQu=7OClkDJr").3)IK@&iGmrufTq<h-h<YSlE9a9bi^eZ,\XN42hkEQ\V/2kCr]:25tkTli$mB[/Xb1s4c>@^D2)(YW91^@OU@RdW.pA3#:6d)5Si`]bsl?(rW>kB[*md&-uQ::snAodt^Ch6'Sp,9]05FhOM@ST;>/D,(/aCXuB2k_pLr??qj`8EP3l/$.u@/nY#t\3Lq.%dK4+/^%NSicHjNpLm8,@rT,9EoOXs%F4m!d(Smd_fKn'(.Cq^Ac#QloBH,k#5a#pn@d*`EZL)2TP(h5EqO>Gq:!mUmkbH`*DZK#6^NILHUh/6LG;\?X1VaU_!K(sko_FU0,e72U`]9n@?b+uZfebm')?hGmIKQ5_r]555G@Prn2\`I&Y_Ap9^`33*=H&XQV68?Klr6;7EbDl2b#Y_E@CiO_`9^YW%XLH]X0&k<lOaTF)\h=am1b\Pt[ZW_N;;#f`FZlNkX*;SmS*1!7?qt0]I@0q>V9eM0%[3'Oe`McNJ9X`0<8-Ub,S"#&bWPALaS0Jp6#<P5N*(_$_V";E2<Lr"Odnn^??o8Q1Q2N7pH07SDnPOXPd(Ti"=#h#1S;>`Z+Nm7#rd-^$"s`G[FsWGCXB,<Lq/$$Sj:nn(NqfljMk+%Wi,oe<JVEZZbK)pY_]m&=i$C[K^@?kU>^U[\QWB9,=pd,$4PfN>hBXrTbC#+CI.,)X>t158_7/37WK!F4hHq7A38(&B6%jdVn3pB:[[3fHG:]"N_8j;HGPURJU:d0=#L)%%5:Jl$+4T)St![oQT~>
endstream
endobj
72 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 71 0 R
/Annots 73 0 R
>>
endobj
73 0 obj
[
74 0 R
75 0 R
]
endobj
74 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
75 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
76 0 obj
<< /Length 2007 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gat%$HZ.Xs&HCX[6Gn<t#o[!36p3GM^m_)gL,AE=%kUToL+L_1&Qs/I8/&*'mQ9aRP:X^KJfkcH]DLF]W417'j`L-3U_D(-+)TQ2hN&YI\@/M"L/+\h1oBS,f?Pg&Lul3Ob-f4PT@$l]^bHZ[(aPmG#8G?I$JR'[Cu$GHjcjC,[2LL31oqJa,,-.'&@Csh:\.t,\fBs"5rB[3WTJJZ0gg#(QS?J.VAnpGaaB\:e_6)%Lo9kB<'.Q^IOCOJYBPI\e\5eI^KW=N6Tj:9"#m.;nLKYfZ0WL3L"S(1O-^*lB2ZO;@46/Y`.!AmEeGQ<U).8B#;`oQ-ZZoYBH8D84V%kc:nu`*)_7"1-IEhMR/t8#9X+&nqnE%=3F`19Ceq7H/IqtbC)QiJlmP,b9e9mX/4J>_;K>W#0jFcTh8f)KB6fXao@,BU$4V]>2X;c:844l:bYHF`;-G\MB;bOLmc<`A&(Cc5,u4g,>/?iURINA=5rt=Zg;[50j30B:c"b5#@ZY(ZDJA/Wnl([aQ94o2b6RO5+7+ReD<5IDj@+r$77hNlTgs+K0gCg!eflr9#an%nKCE&T\VO=MM+q<68aIs1K/cih(o,$$XDTMXCI/n!=Q$bi`tUM^[Ya0M<NU:E/`ca(p(Ef8aas$6.n\$=PGVElUG?bcLpS5%\,P^4.5`N`'DNCKTf.6`.^kSk,_ef>as):8=p%r`MGK^F.[D5bUAUP-K5FRu]>)'NgEIuk>95$51)652Pk!GkCo>C(DUp3e(]'!U2&/9s\4R_P3$(.JS6D6G'$m5sFH?,<n?o'+UaRp[Lj:r^qcnTA?JaICh;6r3kI;B-pjnRp:>S_F\sUh*m^ZTfEr"i,g;XP.]g<-?M?'k'USq+<iti#CEdN$'H%%K_]D_Ka`MJGD,5?OI\\)X;.hu"BYRCfUg7N`_-%eGCdSL69TI0-0H$O9e2GC&1L,([@%'5*OFXK1<]M*;E4[ZEb][##hAQ[<mSr9]$5*QZ6WC,u!n@"d=>8D4_c1g@lQ4O6R=0EWlo[H^t1HkMOG\o^d<O15`oBV6M.E%Z-PWYfk8^NA;^)13W6=#sfh':@mF=8kdB<OUJWqL(/0LP*+[70+BARhVbBV?A._PRj<DX?Dd#_87(je^Dueq+-UO`_R#HAIL(JuA1MS0aZ->AUc?Re*c4S*TSW9CH&_<nMreW57<,6>_1_k"kOsn7)l0Y*V]l,657@O,GP0M`?NMOH12%cc-\^ZGtrr\SDcnNsL*)nXprQQM0c<baqFX4&7=PerpD#4<GH40'tN%Vq_eE'2n3+"o>:A`ShufYaJI%MPFQ`/0Y]$h4Y4[GG70<Q>*X%)AZ7HDEhEU<1n-l[PeJU#G,Ob:i1e4i;NZ3kQ_Qn2;s/Mh`2bs&gd.?OY[0LZ3rd9)!fgQIs/+lP6V]Z`*#2O[(;Z!Y8->iY&m_j(9*oibta,T0_i<2r<!\P+1F?I40-K:[>u#)FKC_1I2$1#WBfih\,-2YNU'(rHQa@teqp#/bWDUJofQrQ".,L:=J\0:j_]7pCH[20^RQtT$p-3$:J7d1as.Jl^nW7\Fr9E\.cnBHX`Gm,hu,B"L%-2XHR6CQiI^!>'ZeS+2&'DNDH#Wo;:uh[C*VR5#@Bmu,2umdG>.U3TnQuI%s1\r?Pf`t*Q[l7pFOq$1r<GI[T5s@^t^KH9r@R<[W5<m0Z]\SE8T"<5t.1lh%_2TobBq/5(H+.'.TJRd0ZR29-;P&W/8NERpCQ/?VVN)r-26:.t"U?g;Tb_5]m>+*NjG1(>(.[?i0sbcX,L5L\X``FrV?;\rA+F-gc%mVf_CuCU*/7-*q%>Y<TFO`J+N;AfPj4g]WMrV^/tEG8SMWb:;:04-X$.RDJ5R<@,rai1<lr]IsDr.ZX*&4a+SiWG<CFcD0.0W^(:_8o#"oh1b0NgOV=YrK(sq!@(S/0MgO^6"qf;>pS1&FB?sgo"P'Qhl!,XY9_"sK!bS[#anF]\G9TJP>4eKF*MMtc,JU]3r0pU5BGl~>
endstream
endobj
77 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 76 0 R
/Annots 78 0 R
>>
endobj
78 0 obj
[
79 0 R
80 0 R
]
endobj
79 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
80 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
81 0 obj
<< /Length 1122 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm:9lnc;&A@7.pfM.,l]:fca#5M+$o#mN$tXsA@`u1u9/;[#2ZFgY8Y_Pd#7aE[QD32`qqga52lk'N45]Q1f5k!3`,j(Xms+]l4,N-tEU4sbmtUhc=]+A&"^u>>b90CLl&1UU[Eid9RLA_h._IR<N43qIQB/.IB!oY@Rj![*_422C(7;(IkF14&*1HK9MJ<nacVTUtfg%*DOE,<K6"P92Qa?P8:HtEsDE=$]P1N59i4hT_%&95/r4=7Z%>Fo=kEo3`Dp-9d!nurR+8"fMM\=X2-3nL2cEb$HKJR9Y$laqm&Tn7kCUd2oPlQ2/kUj+n"K,m7:qW,2O:%f]SArHO:eTUQ8LP`j>@)7,Na5:k6pj]+8OJ%b:)d)`S71MW_Vd2M&1_T'Y_`"5`)TOa"p6CO6r[2qksD*mA@Y0%dn29)K/6DeC]q6a)O\l;Yt?)EN5.I+,.]9_>$b$A'N6VLZVo:DWtr+LgbuDu8b-;D.0<7A%?GW`5Ep&McCdqDCBVo`LYm@bi`>bPOfHZM,D<]<P&,4]BL0YjCom2_orZWL)'1M2":F"R%AoZ67c>t_eb/07o1"2mc@#Y"F1p_<)QSKk:D33lBeW7k2i<Y=Xrj?V9@!-mKCG-.5>2S/')fj8G^'Z@n2,kVYWWOj-K#7f!kWNq$h^<rh<`q%Ot[;k&HR%j2kPiZk=2orWk#p<aqlTVaR.)m8iTEPAbQ0i"ZpX^0aOM/68a@kYXT0?<`)-er6Ti[0G8E-/^NA=:WZO1e&Y(Aj"7EZ".=hu/_^]pdKm!;!>'[dVUh$10EO2RiEh(%KC@Qa?jpT0)rbdu6MckuN3][6=COS#]UUY;9/&s*@>3\'VE8<a#LZnTn;ZqU`PsO%@=2A0^>Mok0o7YS+Ea,(*D,t%0Zio)GI9OoB6R6^C:PbsU=?cU@@XNn(Ct!u]r<1FjXu^8oZZYSeWmCh$V%B?b^s/TI+-<\T0X1cU.lk\HVJifA5-?XDdM,JY:P`Q0@s![G4/XupZC`(PN>"m;>.4(TH$fi-\RVK\m^h,&6AqpR%huMU7$;.BtA[*C<i<>+D!DgWodRM,`uA&H?)J&J0dGr\7lLXdD"i=/XR^1iO;+^^NXn2Rf!1KjQ^p~>
endstream
endobj
82 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 81 0 R
/Annots 83 0 R
>>
endobj
83 0 obj
[
84 0 R
85 0 R
]
endobj
84 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
85 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
88 0 obj
<<
/Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163)
/Parent 86 0 R
/Next 90 0 R
/A 87 0 R
>> endobj
90 0 obj
<<
/Title (\376\377\0\120\0\154\0\141\0\156\0\156\0\151\0\156\0\147\0\40\0\146\0\157\0\162\0\40\0\164\0\150\0\145\0\40\0\160\0\157\0\162\0\164)
/Parent 86 0 R
/Prev 88 0 R
/Next 92 0 R
/A 89 0 R
>> endobj
92 0 obj
<<
/Title (\376\377\0\104\0\145\0\166\0\145\0\154\0\157\0\160\0\155\0\145\0\156\0\164\0\40\0\145\0\156\0\166\0\151\0\162\0\157\0\156\0\155\0\145\0\156\0\164\0\163)
/Parent 86 0 R
/Prev 90 0 R
/Next 94 0 R
/A 91 0 R
>> endobj
94 0 obj
<<
/Title (\376\377\0\101\0\162\0\143\0\150\0\151\0\164\0\145\0\143\0\164\0\165\0\162\0\145\0\55\0\40\0\141\0\156\0\144\0\40\0\163\0\171\0\163\0\164\0\145\0\155\0\55\0\163\0\160\0\145\0\143\0\151\0\146\0\151\0\143\0\40\0\144\0\151\0\146\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\163)
/Parent 86 0 R
/Prev 92 0 R
/Next 96 0 R
/A 93 0 R
>> endobj
96 0 obj
<<
/Title (\376\377\0\103\0\157\0\156\0\143\0\154\0\165\0\163\0\151\0\157\0\156)
/Parent 86 0 R
/Prev 94 0 R
/Next 97 0 R
/A 95 0 R
>> endobj
97 0 obj
<<
/Title (\376\377\0\101\0\142\0\157\0\165\0\164\0\40\0\164\0\150\0\145\0\40\0\141\0\165\0\164\0\150\0\157\0\162)
/Parent 86 0 R
/Prev 96 0 R
/A 11 0 R
>> endobj
98 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F9
/BaseFont /Courier
/Encoding /WinAnsiEncoding >>
endobj
99 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding >>
endobj
100 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F2
/BaseFont /Helvetica-Oblique
/Encoding /WinAnsiEncoding >>
endobj
101 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F3
/BaseFont /Helvetica-Bold
/Encoding /WinAnsiEncoding >>
endobj
1 0 obj
<< /Type /Pages
/Count 14
/Kids [8 0 R 16 0 R 21 0 R 28 0 R 34 0 R 39 0 R 46 0 R 51 0 R 56 0 R 61 0 R 67 0 R 72 0 R 77 0 R 82 0 R ] >>
endobj
2 0 obj
<< /Type /Catalog
/Pages 1 0 R
/Outlines 86 0 R
/PageMode /UseOutlines
>>
endobj
3 0 obj
<<
/Font << /F9 98 0 R /F1 99 0 R /F2 100 0 R /F3 101 0 R >>
/ProcSet [ /PDF /ImageC /Text ] /XObject <</Im1 6 0 R
/Im2 7 0 R
>>
>>
endobj
11 0 obj
<<
/S /GoTo
/D [82 0 R /XYZ 65.866 533.635 null]
>>
endobj
24 0 obj
<<
/S /GoTo
/D [null /XYZ 0.0 0.0 null]
>>
endobj
86 0 obj
<<
/First 88 0 R
/Last 97 0 R
>> endobj
87 0 obj
<<
/S /GoTo
/D [null /XYZ 0.0 0.0 null]
>>
endobj
89 0 obj
<<
/S /GoTo
/D [16 0 R /XYZ 65.866 663.135 null]
>>
endobj
91 0 obj
<<
/S /GoTo
/D [28 0 R /XYZ 65.866 714.135 null]
>>
endobj
93 0 obj
<<
/S /GoTo
/D [39 0 R /XYZ 65.866 217.635 null]
>>
endobj
95 0 obj
<<
/S /GoTo
/D [82 0 R /XYZ 65.866 675.135 null]
>>
endobj
xref
0 102
0000000000 65535 f
0000040830 00000 n
0000040980 00000 n
0000041072 00000 n
0000000015 00000 n
0000000071 00000 n
0000001831 00000 n
0000002681 00000 n
0000004334 00000 n
0000004454 00000 n
0000004501 00000 n
0000041225 00000 n
0000004637 00000 n
0000004813 00000 n
0000005014 00000 n
0000005205 00000 n
0000006656 00000 n
0000006779 00000 n
0000006813 00000 n
0000007014 00000 n
0000007205 00000 n
0000009376 00000 n
0000009499 00000 n
0000009540 00000 n
0000041293 00000 n
0000009679 00000 n
0000009880 00000 n
0000010071 00000 n
0000011937 00000 n
0000012060 00000 n
0000012101 00000 n
0000012239 00000 n
0000012440 00000 n
0000012631 00000 n
0000014765 00000 n
0000014888 00000 n
0000014922 00000 n
0000015123 00000 n
0000015314 00000 n
0000017447 00000 n
0000017570 00000 n
0000017618 00000 n
0000017756 00000 n
0000017894 00000 n
0000018095 00000 n
0000018286 00000 n
0000020507 00000 n
0000020630 00000 n
0000020664 00000 n
0000020865 00000 n
0000021056 00000 n
0000023394 00000 n
0000023517 00000 n
0000023551 00000 n
0000023752 00000 n
0000023943 00000 n
0000025867 00000 n
0000025990 00000 n
0000026024 00000 n
0000026225 00000 n
0000026416 00000 n
0000028397 00000 n
0000028520 00000 n
0000028561 00000 n
0000028779 00000 n
0000028980 00000 n
0000029171 00000 n
0000031251 00000 n
0000031374 00000 n
0000031408 00000 n
0000031609 00000 n
0000031800 00000 n
0000034090 00000 n
0000034213 00000 n
0000034247 00000 n
0000034448 00000 n
0000034639 00000 n
0000036739 00000 n
0000036862 00000 n
0000036896 00000 n
0000037097 00000 n
0000037288 00000 n
0000038503 00000 n
0000038626 00000 n
0000038660 00000 n
0000038861 00000 n
0000041352 00000 n
0000041403 00000 n
0000039052 00000 n
0000041462 00000 n
0000039234 00000 n
0000041530 00000 n
0000039453 00000 n
0000041598 00000 n
0000039692 00000 n
0000041666 00000 n
0000040053 00000 n
0000040209 00000 n
0000040385 00000 n
0000040491 00000 n
0000040599 00000 n
0000040716 00000 n
trailer
<<
/Size 102
/Root 2 0 R
/Info 4 0 R
>>
startxref
41734
%%EOF

View File

@ -1,97 +0,0 @@
#include "message_handler.h"
#include <QDateTime>
#include <cstring>
#include <QString>
#include <QFileInfo>
#include <QMessageLogContext>
static char const *DBG_NAME[] = { "DBG ", "WARN ", "CRIT ", "FATAL", "INFO " };
static bool installedMsgHandler = false;
static int debugLevel = LOG_NOTICE;
int getDebugLevel() { return debugLevel; }
void setDebugLevel(int newDebugLevel) {
debugLevel = newDebugLevel;
}
bool messageHandlerInstalled() {
return installedMsgHandler;
}
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) {
installedMsgHandler = (handler != 0);
static QtMessageHandler prevHandler = nullptr;
if (handler) {
prevHandler = qInstallMessageHandler(handler);
return prevHandler;
} else {
return qInstallMessageHandler(prevHandler);
}
}
///
/// \brief Print message according to given debug level.
///
/// \note Install this function using qInstallMsgHandler().
///
/// int main(int argc, char **argv) {
/// installMsgHandler(atbDebugOutput);
/// QApplication app(argc, argv);
/// ...
/// return app.exec();
/// }
///
#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
Q_UNUSED(context);
QString const localMsg = QString(DBG_NAME[type]) + msg.toLocal8Bit();
switch (debugLevel) {
case LOG_DEBUG: { // debug-level message
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
} break;
case LOG_INFO: { // informational message
if (type != QtDebugMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_NOTICE: { // normal, but significant, condition
if (type != QtDebugMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_WARNING: { // warning conditions
if (type != QtInfoMsg && type != QtDebugMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_ERR: { // error conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_CRIT: { // critical conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_ALERT: { // action must be taken immediately
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_EMERG: { // system is unusable
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
default: {
//fprintf(stderr, "%s No ErrorLevel defined! %s\n",
// datetime.toStdString().c_str(), msg.toStdString().c_str());
}
}
}
#endif

View File

@ -1,23 +0,0 @@
#ifndef MESSAGE_HANDLER_H_INCLUDED
#define MESSAGE_HANDLER_H_INCLUDED
#include <QtGlobal>
#ifdef __linux__
#include <syslog.h>
#endif
int getDebugLevel();
void setDebugLevel(int newDebugLevel);
bool messageHandlerInstalled();
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const char *);
void atbDebugOutput(QtMsgType type, const char *msg);
#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
#endif
#endif // MESSAGE_HANDLER_H_INCLUDED

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,35 +0,0 @@
{%RunFlags MESSAGES+}
{$mode ObjFPC}{$H-}
program helloworld(output);
uses
TariffCalculator, CTypes;
var
TariffCalc: TariffCalculatorHandle;
CustomerRepo: array[0..100] of char;
LocalCustomerRepo: array[0..100] of char;
begin
writeLn('Hello, World!') ;
// TariffCalc := NewTariffCalculator;
// DeleteTariffCalculator(TariffCalc);
if InitGitLibrary() > 0 then
begin
writeLn('init OK!') ;
CustomerRepo := 'https://git.mimbach49.de/GerhardHoffmann/customer_999.git';
LocalCustomerRepo := 'C:\\tmp\\customer_999';
CloneRepository(CustomerRepo, LocalCustomerRepo);
ShutdownGitLibrary();
end
else
begin
writeLn('init NOT OK!') ;
Readln;
end;
end.

View File

@ -1,35 +0,0 @@
unit TariffCalculator;
{$mode ObjFPC}{$H-}
interface
uses
SysUtils, CTypes;
type
// Can't use the class directly, so it is treated as an opaque handle.
// THandle is guaranteed to have the right size, even on other platforms.
TariffCalculatorHandle = THandle;
function NewTariffCalculator: TariffCalculatorHandle; stdcall;
procedure DeleteTariffCalculator(handle: TariffCalculatorHandle); stdcall;
function InitGitLibrary: cint32; stdcall;
function ShutdownGitLibrary: cint32; stdcall;
function CloneRepository(var url; var local_path) : cint32; stdcall;
implementation
const
DLLName = 'CalculatorCInterface.dll';
function NewTariffCalculator: TariffCalculatorHandle; stdcall; external DLLName;
procedure DeleteTariffCalculator(handle: TariffCalculatorHandle); stdcall; external DLLName;
function InitGitLibrary: cint32; stdcall; external DLLName;
function ShutdownGitLibrary: cint32; stdcall; external DLLName;
function CloneRepository(var url; var local_path) : cint32; stdcall; external DLLName;
end.