Compare commits
17 Commits
test
...
90853294da
Author | SHA1 | Date | |
---|---|---|---|
90853294da | |||
96994dc37e | |||
c2328b69f0 | |||
4101823f6e | |||
a1d59c78b6 | |||
34fe915e38 | |||
4e13dda29d | |||
3c7b5d0958 | |||
590abe538d | |||
3568c8ecfb | |||
9d4775314c | |||
19719a2c1f | |||
b26ace2e11 | |||
9b9e77c830 | |||
e925e8b42f | |||
899f8ca02b | |||
6f338cc389 |
@@ -1,3 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
SUBDIRS = Calculator Utilities
|
||||
SUBDIRS = Calculator CalculatorCInterface
|
||||
|
@@ -0,0 +1,33 @@
|
||||
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
|
||||
|
58
Calculator/main.cpp
Normal file
58
Calculator/main.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#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();
|
||||
}
|
||||
#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();
|
||||
}
|
107
Calculator/message_handler.cpp
Normal file
107
Calculator/message_handler.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#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
|
||||
|
23
Calculator/message_handler.h
Normal file
23
Calculator/message_handler.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#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
|
42
CalculatorCInterface/CalculatorCInterface.pro
Normal file
42
CalculatorCInterface/CalculatorCInterface.pro
Normal file
@@ -0,0 +1,42 @@
|
||||
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 \
|
||||
tariff_calculator.cpp
|
||||
|
||||
HEADERS += \
|
||||
calculator_c_interface_lib.h \
|
||||
calculator_c_interface_lib_global.h \
|
||||
tariff_calculator.h
|
||||
|
||||
# Default rules for deployment.
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
}
|
||||
!isEmpty(target.path): INSTALLS += target
|
596
CalculatorCInterface/calculator_c_interface_lib.cpp
Normal file
596
CalculatorCInterface/calculator_c_interface_lib.cpp
Normal file
@@ -0,0 +1,596 @@
|
||||
#include "calculator_c_interface_lib.h"
|
||||
|
||||
//#include <git2/common.h>
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
#include <git2.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static QMap<QString, git_repository *> customerRepoMap;
|
||||
static std::mutex m;
|
||||
static char const *user = NULL;
|
||||
static char const *pass = NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// see https://libgit2.org/libgit2/ex/HEAD/checkout.html
|
||||
|
||||
/* Define t/he printf format specifier to use for size_t output */
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# define PRIuZ "Illu"
|
||||
# define PRIxZ "Illx"
|
||||
# define PRIdZ "Illd"
|
||||
#else
|
||||
# define PRIuZ "zu"
|
||||
# define PRIxZ "zx"
|
||||
# define PRIdZ "zd"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned int force : 1;
|
||||
unsigned int progress : 1;
|
||||
unsigned int perf : 1;
|
||||
} checkout_options;
|
||||
|
||||
int cred_acquire_cb(git_credential **out,
|
||||
const char *url,
|
||||
const char *username_from_url,
|
||||
unsigned int allowed_types,
|
||||
void *payload)
|
||||
{
|
||||
char const *username = user, *password = pass;
|
||||
|
||||
fprintf(stderr, "%s:%d: opened repository %s %s\n", __func__, __LINE__, username, password);
|
||||
|
||||
Q_UNUSED(url);
|
||||
Q_UNUSED(username_from_url);
|
||||
Q_UNUSED(payload);
|
||||
int error = -1;
|
||||
|
||||
if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT) {
|
||||
error = git_credential_userpass_plaintext_new(out, username, password);
|
||||
} else {
|
||||
fprintf(stderr, "GIT_CREDENTIAL_USERPASS_PLAINTEXT not supported by protocol (allowed_types=%08x)\n", allowed_types);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static bool check(int error, const char *message, const char *extra) {
|
||||
const git_error *lg2err;
|
||||
const char *lg2msg = "", *lg2spacer = "";
|
||||
|
||||
if (!error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((lg2err = git_error_last()) != NULL && lg2err->message != NULL) {
|
||||
lg2msg = lg2err->message;
|
||||
lg2spacer = " - ";
|
||||
}
|
||||
|
||||
if (extra)
|
||||
fprintf(stderr, "%s '%s' [%d]%s%s\n",
|
||||
message, extra, error, lg2spacer, lg2msg);
|
||||
else
|
||||
fprintf(stderr, "%s [%d]%s%s\n",
|
||||
message, error, lg2spacer, lg2msg);
|
||||
|
||||
// exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void print_checkout_progress(const char *path, size_t completed_steps, size_t total_steps, void *payload) {
|
||||
(void)payload;
|
||||
if (path == NULL) {
|
||||
printf("checkout started: %" PRIuZ " steps\n", total_steps);
|
||||
} else {
|
||||
printf("checkout: %s %" PRIuZ "/%" PRIuZ "\n", path, completed_steps, total_steps);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_perf_data(const git_checkout_perfdata *perfdata, void *payload) {
|
||||
(void)payload;
|
||||
printf("perf: stat: %" PRIuZ " mkdir: %" PRIuZ " chmod: %" PRIuZ "\n",
|
||||
perfdata->stat_calls, perfdata->mkdir_calls, perfdata->chmod_calls);
|
||||
}
|
||||
|
||||
static int resolve_refish(git_annotated_commit **commit, git_repository *repo, const char *refish)
|
||||
{
|
||||
git_reference *ref;
|
||||
git_object *obj;
|
||||
int err = 0;
|
||||
|
||||
assert(commit != NULL);
|
||||
|
||||
err = git_reference_dwim(&ref, repo, refish);
|
||||
if (err == GIT_OK) {
|
||||
git_annotated_commit_from_ref(commit, repo, ref);
|
||||
git_reference_free(ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = git_revparse_single(&obj, repo, refish);
|
||||
if (err == GIT_OK) {
|
||||
err = git_annotated_commit_lookup(commit, repo, git_object_id(obj));
|
||||
git_object_free(obj);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int perform_checkout_ref(git_repository *repo,
|
||||
git_annotated_commit *target,
|
||||
const char *target_ref, checkout_options *opts) {
|
||||
git_checkout_options checkout_opts;
|
||||
git_reference *ref = NULL, *branch = NULL;
|
||||
git_commit *target_commit = NULL;
|
||||
int err;
|
||||
|
||||
if ((err = git_checkout_options_init(&checkout_opts, GIT_CHECKOUT_OPTIONS_VERSION)) < 0) {
|
||||
fprintf(stderr, "error checkout options init %s\n", git_error_last()->message);
|
||||
return err;
|
||||
}
|
||||
|
||||
// Setup our checkout options from the parsed options
|
||||
|
||||
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
|
||||
|
||||
// if (opts->force)
|
||||
// checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
|
||||
|
||||
// if (opts->progress)
|
||||
// checkout_opts.progress_cb = print_checkout_progress;
|
||||
|
||||
// if (opts->perf)
|
||||
// checkout_opts.perfdata_cb = print_perf_data;
|
||||
|
||||
// Grab the commit we're interested to move to
|
||||
|
||||
err = git_commit_lookup(&target_commit, repo, git_annotated_commit_id(target));
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "failed to lookup commit: %s\n", git_error_last()->message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Perform the checkout so the workdir corresponds to what target_commit contains.
|
||||
// Note that it's okay to pass a git_commit here, because it will be peeled to a tree.
|
||||
|
||||
err = git_checkout_tree(repo, (const git_object *)target_commit, &checkout_opts);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "failed to checkout tree: %s\n", git_error_last()->message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Now that the checkout has completed, we have to update HEAD.
|
||||
// Depending on the "origin" of target (ie. it's an OID or a branch name), we might need to detach HEAD.
|
||||
|
||||
if (git_annotated_commit_ref(target)) {
|
||||
const char *target_head;
|
||||
|
||||
if ((err = git_reference_lookup(&ref, repo, git_annotated_commit_ref(target))) < 0)
|
||||
goto error;
|
||||
|
||||
if (git_reference_is_remote(ref)) {
|
||||
if ((err = git_branch_create_from_annotated(&branch, repo, target_ref, target, 0)) < 0)
|
||||
goto error;
|
||||
target_head = git_reference_name(branch);
|
||||
} else {
|
||||
target_head = git_annotated_commit_ref(target);
|
||||
}
|
||||
|
||||
err = git_repository_set_head(repo, target_head);
|
||||
} else {
|
||||
err = git_repository_set_head_detached_from_annotated(repo, target);
|
||||
}
|
||||
|
||||
error:
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "failed to update HEAD reference: %s\n", git_error_last()->message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_commit_free(target_commit);
|
||||
git_reference_free(branch);
|
||||
git_reference_free(ref);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int guess_refish(git_annotated_commit **out, git_repository *repo, const char *ref) {
|
||||
git_strarray remotes = { NULL, 0 };
|
||||
git_reference *remote_ref = NULL;
|
||||
int error;
|
||||
size_t i;
|
||||
|
||||
if ((error = git_remote_list(&remotes, repo)) < 0) {
|
||||
fprintf(stderr, "error git_remote_list %s\n", git_error_last()->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < remotes.count; i++) {
|
||||
char *refname = NULL;
|
||||
size_t reflen;
|
||||
|
||||
reflen = snprintf(refname, 0, "refs/remotes/%s/%s", remotes.strings[i], ref);
|
||||
if ((refname = (char *)malloc(reflen + 1)) == NULL) {
|
||||
error = -1;
|
||||
fprintf(stderr, "%s:%d malloc failed\n", __func__, __LINE__);
|
||||
goto next;
|
||||
}
|
||||
snprintf(refname, reflen + 1, "refs/remotes/%s/%s", remotes.strings[i], ref);
|
||||
|
||||
if ((error = git_reference_lookup(&remote_ref, repo, refname)) < 0) {
|
||||
fprintf(stderr, "git reference lookup %s\n", git_error_last()->message);
|
||||
goto next;
|
||||
}
|
||||
|
||||
break;
|
||||
next:
|
||||
free(refname);
|
||||
refname = NULL;
|
||||
if (error < 0 && error != GIT_ENOTFOUND) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!remote_ref) {
|
||||
error = GIT_ENOTFOUND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((error = git_annotated_commit_from_ref(out, repo, remote_ref)) < 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
git_reference_free(remote_ref);
|
||||
git_strarray_dispose(&remotes);
|
||||
return error;
|
||||
}
|
||||
|
||||
TariffCalculatorHandle NewTariffCalculator(void) {
|
||||
return new TariffCalculator();
|
||||
}
|
||||
|
||||
void DeleteTariffCalculator(TariffCalculatorHandle handle) {
|
||||
delete handle;
|
||||
}
|
||||
|
||||
int InitGitLibrary(void) {
|
||||
return git_libgit2_init();
|
||||
}
|
||||
|
||||
int ShutdownGitLibrary(void) {
|
||||
|
||||
for (auto key : customerRepoMap.keys()) {
|
||||
git_repository_free(customerRepoMap.value(key));
|
||||
}
|
||||
customerRepoMap.clear();
|
||||
return git_libgit2_shutdown();
|
||||
}
|
||||
|
||||
int CloneRepository(char const *url, char const *local_path) {
|
||||
|
||||
QString localRepoPath(QDir::cleanPath(QString(local_path) + QDir::separator() + ".git"));
|
||||
QDir localRepoDir(localRepoPath);
|
||||
|
||||
if (localRepoDir.exists()) {
|
||||
fprintf(stderr, "local repository path %s already exists\n",
|
||||
localRepoPath.toUtf8().constData());
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_repository *out;
|
||||
git_clone_options opts;
|
||||
int res = 0;
|
||||
|
||||
if ((res = git_clone_options_init(&opts, GIT_CLONE_OPTIONS_VERSION)) == 0) {
|
||||
opts.checkout_branch = "master";
|
||||
|
||||
fprintf(stderr, "%s:%d %s %s\n", __func__, __LINE__, url, local_path);
|
||||
|
||||
if ((res = git_clone(&out, url, local_path, &opts)) < 0) {
|
||||
git_error const *error = git_error_last();
|
||||
fprintf(stderr, "%s:%d error: %s\n", __func__, __LINE__, error->message);
|
||||
} else {
|
||||
QString localRepoPath = QDir::cleanPath(QString(local_path) + QDir::separator() + ".git");
|
||||
customerRepoMap.insert(localRepoPath, out);
|
||||
}
|
||||
} else {
|
||||
git_error const *error = git_error_last();
|
||||
fprintf(stderr, "%s:%d error: %s\n", __func__, __LINE__, error->message);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int CheckoutLocalBranch(char const *local_path, char const *branch_name) {
|
||||
int err = 0;
|
||||
checkout_options opts;
|
||||
git_repository_state_t state = GIT_REPOSITORY_STATE_NONE;
|
||||
git_annotated_commit *checkout_target = NULL;
|
||||
git_repository *repo = NULL;
|
||||
git_reference *branch_ref = NULL;
|
||||
|
||||
QString localRepoPath(QDir::cleanPath(QString(local_path) + QDir::separator() + ".git"));
|
||||
QDir localRepoDir(localRepoPath);
|
||||
|
||||
if (!localRepoDir.exists()) {
|
||||
fprintf(stderr, "local repository path %s does not exist\n",
|
||||
localRepoPath.toUtf8().constData());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!customerRepoMap.contains(localRepoPath)) {
|
||||
if ((err = git_repository_open(&repo, localRepoPath.toUtf8().constData())) != 0) {
|
||||
fprintf(stderr, "repository %s cannot be opened: %s\n",
|
||||
localRepoPath.toUtf8().constData(), git_error_last()->message);
|
||||
return -1;
|
||||
}
|
||||
customerRepoMap.insert(localRepoPath, repo);
|
||||
}
|
||||
|
||||
if (customerRepoMap.contains(localRepoPath)) {
|
||||
repo = customerRepoMap[localRepoPath];
|
||||
|
||||
// Make sure we're not about to checkout while something else is going on
|
||||
if ((state = (git_repository_state_t)git_repository_state(repo)) != GIT_REPOSITORY_STATE_NONE) {
|
||||
fprintf(stderr, "repository %s is in unexpected state %d\n",
|
||||
localRepoPath.toUtf8().constData(), state);
|
||||
err = -1;
|
||||
} else {
|
||||
fprintf(stderr, "repository %s is in state %d\n",
|
||||
localRepoPath.toUtf8().constData(), state);
|
||||
|
||||
if ((err = resolve_refish(&checkout_target, repo, branch_name)) < 0 &&
|
||||
(err = guess_refish(&checkout_target, repo, branch_name)) < 0) {
|
||||
fprintf(stderr, "failed to resolve %s: %s\n", branch_name, git_error_last()->message);
|
||||
} else {
|
||||
if ((err = perform_checkout_ref(repo, checkout_target, branch_name, &opts)) == 0) {
|
||||
fprintf(stderr, "%s:%d checkout ok\n", __func__, __LINE__);
|
||||
if ((err = git_branch_lookup(&branch_ref, repo, branch_name, GIT_BRANCH_LOCAL)) != 0) {
|
||||
if (err == GIT_ENOTFOUND) {
|
||||
fprintf(stderr, "local branch %s not found\n", branch_name);
|
||||
} else {
|
||||
fprintf(stderr, "local branch %s not found: %s\n",
|
||||
branch_name, git_error_last()->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (branch_ref) {
|
||||
git_reference_free(branch_ref);
|
||||
}
|
||||
|
||||
if (checkout_target) {
|
||||
git_annotated_commit_free(checkout_target);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int CommitFile(char const *local_path, char const *branch_name,
|
||||
char const *file_name, char const *comment) {
|
||||
assert(local_path != NULL);
|
||||
assert(branch_name != NULL);
|
||||
assert(file_name != NULL);
|
||||
assert(comment != NULL);
|
||||
|
||||
fprintf(stderr, "%s %s %s %s\n",
|
||||
local_path, branch_name, file_name, comment);
|
||||
|
||||
QString const currentWD = QDir::currentPath();
|
||||
|
||||
QString localPath(local_path);
|
||||
if (!QDir(localPath).exists()) {
|
||||
fprintf(stderr, "local path %s for file %s does not exist\n",
|
||||
localPath.toUtf8().constData(), file_name);
|
||||
QDir::setCurrent(currentWD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!QDir::setCurrent(localPath)) {
|
||||
fprintf(stderr, "can not set cwd path %s\n", localPath.toUtf8().constData());
|
||||
QDir::setCurrent(currentWD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "cwd %s\n", QDir::current().absolutePath().toUtf8().constData());
|
||||
|
||||
git_repository *repo = NULL;
|
||||
int error = 0;
|
||||
|
||||
QString localRepoPath(QDir::cleanPath(QString(local_path) + QDir::separator() + ".git"));
|
||||
QDir localRepoDir(localRepoPath);
|
||||
|
||||
if (!localRepoDir.exists()) {
|
||||
fprintf(stderr, "local repository path %s does not exist\n",
|
||||
localRepoPath.toUtf8().constData());
|
||||
QDir::setCurrent(currentWD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!customerRepoMap.contains(localRepoPath)) {
|
||||
if ((error = git_repository_open(&repo, localRepoPath.toUtf8().constData())) != 0) {
|
||||
fprintf(stderr, "repository %s cannot be opened: %s\n",
|
||||
localRepoPath.toUtf8().constData(), git_error_last()->message);
|
||||
QDir::setCurrent(currentWD);
|
||||
return -1;
|
||||
}
|
||||
customerRepoMap.insert(localRepoPath, repo);
|
||||
}
|
||||
|
||||
git_oid commit_oid,tree_oid;
|
||||
git_tree *tree = NULL;
|
||||
git_index *index = NULL;
|
||||
git_object *parent = NULL;
|
||||
git_reference *ref = NULL;
|
||||
git_signature *signature = NULL;
|
||||
git_repository_state_t state = GIT_REPOSITORY_STATE_NONE;
|
||||
|
||||
if (customerRepoMap.contains(localRepoPath)) {
|
||||
repo = customerRepoMap[localRepoPath];
|
||||
|
||||
if (git_repository_head_unborn(repo) == 1) {
|
||||
fprintf(stderr, "HEAD unborn. Create first commit\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we're not about to checkout while something else is going on
|
||||
if ((state = (git_repository_state_t)git_repository_state(repo)) != GIT_REPOSITORY_STATE_NONE) {
|
||||
fprintf(stderr, "repository %s is in unexpected state %d\n",
|
||||
localRepoPath.toUtf8().constData(), state);
|
||||
error = -1;
|
||||
} else {
|
||||
error = git_revparse_ext(&parent, &ref, repo, "HEAD");
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
fprintf(stderr, "HEAD not found. Creating first commit\n");
|
||||
error = 0;
|
||||
} else if (error != 0) {
|
||||
const git_error *err = git_error_last();
|
||||
if (err) {
|
||||
fprintf(stderr, "ERROR %d: %s\n", err->klass, err->message);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR %d: no detailed info\n", error);
|
||||
}
|
||||
}
|
||||
|
||||
if (error == 0) {
|
||||
if (check(git_repository_index(&index, repo), "Could not open repository index", NULL) &&
|
||||
check(git_index_write_tree(&tree_oid, index), "Could not write tree", NULL) &&
|
||||
check(git_index_write(index), "Could not write index", NULL) &&
|
||||
check(git_tree_lookup(&tree, repo, &tree_oid), "Error looking up tree", NULL) &&
|
||||
check(git_signature_default(&signature, repo), "Error creating signature", NULL) &&
|
||||
check(git_commit_create_v(&commit_oid, repo, "HEAD", signature, signature,
|
||||
NULL, comment, tree, parent ? 1 : 0, parent),
|
||||
"Error creating commit", NULL)) {
|
||||
fprintf(stderr, "%s %s %s %s\n",
|
||||
local_path, branch_name, file_name, comment);
|
||||
fprintf(stderr, "git commit ok\n");
|
||||
}
|
||||
|
||||
if (index) {
|
||||
git_index_free(index);
|
||||
}
|
||||
if (signature) {
|
||||
git_signature_free(signature);
|
||||
}
|
||||
if (tree) {
|
||||
git_tree_free(tree);
|
||||
}
|
||||
if (parent) {
|
||||
git_object_free(parent);
|
||||
}
|
||||
if (ref) {
|
||||
git_reference_free(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QDir::setCurrent(currentWD);
|
||||
return error;
|
||||
}
|
||||
|
||||
int PushLocalRepository(char const *local_path, char const *branch_name, char const *username, char const *password) {
|
||||
git_repository *repo = NULL;
|
||||
int error = -1;
|
||||
|
||||
fprintf(stderr, "%s:%d: %s %s\n", __func__, __LINE__, local_path, branch_name);
|
||||
|
||||
QString const currentWD = QDir::currentPath();
|
||||
|
||||
QString localRepoPath(QDir::cleanPath(QString(local_path) + QDir::separator() + ".git"));
|
||||
QDir localRepoDir(localRepoPath);
|
||||
|
||||
if (!localRepoDir.exists()) {
|
||||
fprintf(stderr, "local repository path %s does not exist\n",
|
||||
localRepoPath.toUtf8().constData());
|
||||
QDir::setCurrent(currentWD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!customerRepoMap.contains(localRepoPath)) {
|
||||
if ((error = git_repository_open(&repo, localRepoPath.toUtf8().constData())) != 0) {
|
||||
fprintf(stderr, "repository %s cannot be opened: %s\n",
|
||||
localRepoPath.toUtf8().constData(), git_error_last()->message);
|
||||
QDir::setCurrent(currentWD);
|
||||
return -1;
|
||||
}
|
||||
customerRepoMap.insert(localRepoPath, repo);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s:%d: opened repository\n", __func__, __LINE__);
|
||||
|
||||
git_repository_state_t state = GIT_REPOSITORY_STATE_NONE;
|
||||
git_push_options options;
|
||||
git_remote_callbacks callbacks;
|
||||
git_remote* remote = NULL;
|
||||
char refspec_[] = "refs/heads/master";
|
||||
char *refspec = refspec_;
|
||||
const git_strarray refspecs = {
|
||||
&refspec,
|
||||
1
|
||||
};
|
||||
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
|
||||
user = username;
|
||||
pass = password;
|
||||
|
||||
fprintf(stderr, "%s:%d: opened repository %s %s\n", __func__, __LINE__, user, pass);
|
||||
|
||||
if (customerRepoMap.contains(localRepoPath)) {
|
||||
repo = customerRepoMap[localRepoPath];
|
||||
|
||||
// Make sure we're not about to checkout while something else is going on
|
||||
if ((state = (git_repository_state_t)git_repository_state(repo)) != GIT_REPOSITORY_STATE_NONE) {
|
||||
fprintf(stderr, "repository %s is in unexpected state %d\n",
|
||||
localRepoPath.toUtf8().constData(), state);
|
||||
} else {
|
||||
if (check(git_remote_lookup(&remote, repo, "origin" ), "Unable to lookup remote", NULL)) {
|
||||
if (check(git_remote_init_callbacks(&callbacks, GIT_REMOTE_CALLBACKS_VERSION),
|
||||
"Error initializing remote callbacks", NULL)) {
|
||||
callbacks.credentials = cred_acquire_cb;
|
||||
if (check(git_push_options_init(&options, GIT_PUSH_OPTIONS_VERSION ),
|
||||
"Error initializing push", NULL)) {
|
||||
options.callbacks = callbacks;
|
||||
if (check(git_remote_push(remote, &refspecs, &options), "Error pushing", NULL)) {
|
||||
fprintf(stderr, "%s:%d: pushed %s (branch: %s)\n", __func__, __LINE__, local_path, branch_name);
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remote) {
|
||||
git_remote_free(remote);
|
||||
}
|
||||
|
||||
QDir::setCurrent(currentWD);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
28
CalculatorCInterface/calculator_c_interface_lib.h
Normal file
28
CalculatorCInterface/calculator_c_interface_lib.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#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
|
||||
|
||||
TariffCalculatorHandle NewTariffCalculator(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
void DeleteTariffCalculator(TariffCalculatorHandle handle) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
|
||||
// libgit2
|
||||
int InitGitLibrary(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
int ShutdownGitLibrary(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
int CloneRepository(char const *url, char const *local_path) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
int CheckoutLocalBranch(char const *local_path, char const *branch) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
int CommitFile(char const *local_path, char const *branch_name, char const *file_name, char const *commit_message) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
int PushLocalRepository(char const *local_path, char const *branch_name, char const *user, char const *password) CALCULATOR_C_INTERFACE_LIB_EXPORT;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CALCULATOR_C_INTERFACE_LIB_H_INCLUDED
|
23
CalculatorCInterface/calculator_c_interface_lib_global.h
Normal file
23
CalculatorCInterface/calculator_c_interface_lib_global.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#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
|
430
CalculatorCInterface/tariff_calculator.cpp
Normal file
430
CalculatorCInterface/tariff_calculator.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
#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
|
||||
|
||||
}
|
||||
|
24
CalculatorCInterface/tariff_calculator.h
Normal file
24
CalculatorCInterface/tariff_calculator.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#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
|
BIN
E52461.pdf
Normal file
BIN
E52461.pdf
Normal file
Binary file not shown.
BIN
Porting_Unix_to_the_386l.pdf
Normal file
BIN
Porting_Unix_to_the_386l.pdf
Normal file
Binary file not shown.
BIN
StartProgUsingPascal.pdf
Normal file
BIN
StartProgUsingPascal.pdf
Normal file
Binary file not shown.
@@ -1,82 +0,0 @@
|
||||
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
|
||||
}
|
||||
|
@@ -1,8 +1,5 @@
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QDebug>
|
||||
|
||||
#include "tariff_editor.h"
|
||||
@@ -12,39 +9,6 @@ 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;
|
||||
|
@@ -6,22 +6,6 @@ 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,
|
||||
@@ -34,6 +18,33 @@ 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,
|
||||
@@ -81,12 +92,10 @@ 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
@@ -1,181 +1,423 @@
|
||||
#include "tariff_editor.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDebug>
|
||||
#include <QPair>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDateTime>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
|
||||
#include <initializer_list>
|
||||
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";
|
||||
}
|
||||
|
||||
TariffEditor::TariffEditor() {
|
||||
m_doc = QJsonDocument();
|
||||
// m_doc.setObject(QJsonObject());
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QJsonObject TariffEditor::create(QString const &key) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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))}));
|
||||
} 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))}));
|
||||
} 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)),
|
||||
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;
|
||||
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"))}));
|
||||
a.push_back(o1);
|
||||
a.push_back(o2);
|
||||
|
||||
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
|
||||
} else
|
||||
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("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("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("price for dayticket as entered by customer"))
|
||||
}));
|
||||
} else
|
||||
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({
|
||||
if (key.compare("Config", Qt::CaseInsensitive) == 0) {
|
||||
QJsonObject o1({
|
||||
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("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("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"))})))}));
|
||||
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))}));
|
||||
} else
|
||||
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))})))}));
|
||||
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))}));
|
||||
} else
|
||||
if (key.compare("TimeRanges", Qt::CaseInsensitive) == 0) {
|
||||
// if prepaid, unrestricted
|
||||
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) {
|
||||
|
||||
QJsonValue v;
|
||||
QTime const &start = t.addSecs(i*60);
|
||||
QTime const &end = t.addSecs((i+1)*60);
|
||||
|
||||
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")))});
|
||||
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("Block-Start-0"), v)});
|
||||
b.append(v);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
a.push_back(QJsonObject({QPair(QString("OperationTimes"), b)}));
|
||||
b.push_back(o);
|
||||
}
|
||||
|
||||
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")))});
|
||||
|
||||
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_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))}));
|
||||
}
|
||||
|
||||
#if 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 ["
|
||||
|
||||
"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
|
||||
|
||||
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))});
|
||||
}
|
||||
|
@@ -1,22 +1,20 @@
|
||||
#ifndef TARIFF_EDITOR_H_INCLUDED
|
||||
#define TARIFF_EDITOR_H_INCLUDED
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
class TariffEditor {
|
||||
QJsonDocument m_doc;
|
||||
|
||||
QJsonArray m_a;
|
||||
QJsonDocument m_jsonDoc;
|
||||
void createJsonValue(QString const &key, QString const &value = "");
|
||||
public:
|
||||
explicit TariffEditor();
|
||||
|
||||
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);
|
||||
static QByteArray readJson(QString const &filename);
|
||||
};
|
||||
|
||||
#endif // TARIFF_EDITOR_H_INCLUDED
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include <QJsonValue>
|
||||
|
||||
|
||||
struct TariffTemplate : public QJsonObject {
|
||||
struct Tariff : public QJsonObject {
|
||||
QJsonValue m_project;
|
||||
QJsonValue m_version;
|
||||
QJsonValue m_date;
|
||||
|
BIN
[32] How to mix C and C++, C++ FAQ Lite.pdf
Normal file
BIN
[32] How to mix C and C++, C++ FAQ Lite.pdf
Normal file
Binary file not shown.
1693
au-porting2-pdf.pdf
Normal file
1693
au-porting2-pdf.pdf
Normal file
File diff suppressed because it is too large
Load Diff
BIN
compiling-c-and-c++-files-together-using-gcc.pdf
Normal file
BIN
compiling-c-and-c++-files-together-using-gcc.pdf
Normal file
Binary file not shown.
BIN
cppobjs.zip
Normal file
BIN
cppobjs.zip
Normal file
Binary file not shown.
BIN
delphi-addressing-pointers.pdf
Normal file
BIN
delphi-addressing-pointers.pdf
Normal file
Binary file not shown.
BIN
delpphi-a-tale-of-two-assemblers.pdf
Normal file
BIN
delpphi-a-tale-of-two-assemblers.pdf
Normal file
Binary file not shown.
BIN
delpphi-dLL-dos-and-donts.pdf
Normal file
BIN
delpphi-dLL-dos-and-donts.pdf
Normal file
Binary file not shown.
BIN
delpphi-pitfalls-of-converting.pdf
Normal file
BIN
delpphi-pitfalls-of-converting.pdf
Normal file
Binary file not shown.
985
l-solar-pdf.pdf
Normal file
985
l-solar-pdf.pdf
Normal file
@@ -0,0 +1,985 @@
|
||||
%PDF-1.3
|
||||
%<25><><EFBFBD><EFBFBD>
|
||||
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`+>>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>*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
|
97
message_handler.cpp
Executable file
97
message_handler.cpp
Executable file
@@ -0,0 +1,97 @@
|
||||
#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
|
||||
|
23
message_handler.h
Executable file
23
message_handler.h
Executable file
@@ -0,0 +1,23 @@
|
||||
#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
|
BIN
mixing-c and-c++-extern-c.pdf
Normal file
BIN
mixing-c and-c++-extern-c.pdf
Normal file
Binary file not shown.
Binary file not shown.
BIN
openarr.zip
Normal file
BIN
openarr.zip
Normal file
Binary file not shown.
BIN
pchars.zip
Normal file
BIN
pchars.zip
Normal file
Binary file not shown.
BIN
porting_unix_software-complete.pdf
Normal file
BIN
porting_unix_software-complete.pdf
Normal file
Binary file not shown.
BIN
poscomparisons.zip
Normal file
BIN
poscomparisons.zip
Normal file
Binary file not shown.
BIN
programmierung-mit-pascal_compress.pdf
Normal file
BIN
programmierung-mit-pascal_compress.pdf
Normal file
Binary file not shown.
BIN
shtrees.zip
Normal file
BIN
shtrees.zip
Normal file
Binary file not shown.
4433
tariff.json
Normal file
4433
tariff.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
using-c++-objects-in-deplphi.pdf
Normal file
BIN
using-c++-objects-in-deplphi.pdf
Normal file
Binary file not shown.
BIN
windows/git2.dll
Normal file
BIN
windows/git2.dll
Normal file
Binary file not shown.
BIN
windows/git2.exp
Normal file
BIN
windows/git2.exp
Normal file
Binary file not shown.
BIN
windows/git2.lib
Normal file
BIN
windows/git2.lib
Normal file
Binary file not shown.
BIN
windows/git2.pdb
Normal file
BIN
windows/git2.pdb
Normal file
Binary file not shown.
35
windows/helloworld.lpr
Normal file
35
windows/helloworld.lpr
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
{%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.
|
||||
|
35
windows/tariffcalculator.pas
Normal file
35
windows/tariffcalculator.pas
Normal file
@@ -0,0 +1,35 @@
|
||||
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.
|
||||
|
Reference in New Issue
Block a user