From 28960f0d4d13d0b6562fa0214ac20a96fde79922 Mon Sep 17 00:00:00 2001 From: Ingo Meyer Date: Thu, 10 Nov 2022 15:22:14 +0100 Subject: [PATCH 01/11] Switch back to central Docker images After applying the CI pipeline changes for C++17, the CI Docker images can be switched back to the central Docker image repository. --- .gitlab-ci.yml | 72 +++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a7802388d..f4b1fd3ff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ stages: tag-type-check: stage: prebuild - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/deploy + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/deploy only: - tags@Scientific-IT-Systems/gr script: @@ -16,7 +16,7 @@ tag-type-check: code-style-check: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - set +e - for file in $(git diff $(git describe --tags --abbrev=0) HEAD --name-only --diff-filter=ACMR); do @@ -50,7 +50,7 @@ code-style-check: ubuntu-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - wget https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz - tar xf cmake-3.23.0-linux-x86_64.tar.gz @@ -74,7 +74,7 @@ ubuntu-self-contained: ubuntu-cmake-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/ubuntu-self-contained + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/ubuntu-self-contained script: - wget https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz - tar xf cmake-3.23.0-linux-x86_64.tar.gz @@ -94,7 +94,7 @@ ubuntu-cmake-self-contained: ubuntu-cmake-self-contained-test: stage: test - image: iffregistry.fz-juelich.de/imeyer/gr-test/c-testing + image: iffregistry.fz-juelich.de/scientific-it-systems/gr-test/c-testing rules: - if: '$CI_MERGE_REQUEST_ID' when: never @@ -115,7 +115,7 @@ ubuntu-cmake-self-contained-test: ubuntu-cmake-self-contained-rebuild-images: stage: test - image: iffregistry.fz-juelich.de/imeyer/gr-test/c-testing:latest + image: iffregistry.fz-juelich.de/scientific-it-systems/gr-test/c-testing:latest rules: - if: '$CI_MERGE_REQUEST_ID' when: never @@ -158,13 +158,13 @@ ubuntu-cmake-self-contained-rebuild-images: ubuntu-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - make install GRDIR=/usr/local/gr ubuntu-cmake-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/ubuntu-system-dependencies + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/ubuntu-system-dependencies script: - apt-get update - apt-get install -y libqhull-dev libbz2-dev libjpeg-turbo8-dev libavdevice-dev libtheora-dev libogg-dev libvpx-dev libfreetype6-dev @@ -178,7 +178,7 @@ ubuntu-cmake-system-dependencies: debian-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - wget https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz - tar xf cmake-3.23.0-linux-x86_64.tar.gz @@ -270,7 +270,7 @@ debian-self-contained-armhf: debian-self-contained-aarch64: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/debian-self-contained-aarch64 + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/debian-self-contained-aarch64 script: - make -C 3rdparty default extras \ HOST=aarch64-linux-gnu \ @@ -317,7 +317,7 @@ debian-self-contained-aarch64: debian-cmake-self-contained-aarch64: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/debian-self-contained-aarch64 + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/debian-self-contained-aarch64 script: - make -C 3rdparty default extras \ HOST=aarch64-linux-gnu \ @@ -350,7 +350,7 @@ debian-cmake-self-contained-aarch64: debian-cmake-self-contained-armhf: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/debian-self-contained-armhf-cross + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/debian-self-contained-armhf-cross script: - make -C 3rdparty default extras \ HOST=arm-linux-gnueabihf \ @@ -383,13 +383,13 @@ debian-cmake-self-contained-armhf: debian-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - make install GRDIR=/usr/local/gr debian-system-dependencies-armhf: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME-cross + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME-cross script: - make install \ CC=arm-linux-gnueabihf-gcc \ @@ -404,7 +404,7 @@ debian-system-dependencies-armhf: debian-cmake-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/debian-system-dependencies + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/debian-system-dependencies script: - apt-get update - apt-get install -y libqhull-dev libbz2-dev libfreetype6-dev @@ -418,7 +418,7 @@ debian-cmake-system-dependencies: centos7-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - source /opt/rh/devtoolset-8/enable - curl -LO https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz @@ -443,7 +443,7 @@ centos7-self-contained: centos7-cmake-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/centos7-self-contained + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/centos7-self-contained script: - source /opt/rh/devtoolset-8/enable - curl -LO https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz @@ -465,14 +465,14 @@ centos7-cmake-self-contained: centos7-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - source /opt/rh/devtoolset-8/enable - make install GRDIR=/usr/local/gr centos7-cmake-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/centos7-system-dependencies + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/centos7-system-dependencies script: - source /opt/rh/devtoolset-8/enable - yum install -y libjpeg-turbo-devel libtiff-devel bzip2-devel @@ -487,7 +487,7 @@ centos7-cmake-system-dependencies: centos7-32bit-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - source /opt/gcc-8.5.0/enable - curl -LO https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-i386.tar.gz @@ -516,7 +516,7 @@ centos7-32bit-self-contained: centos7-32bit-cmake-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/centos7-32bit-self-contained + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/centos7-32bit-self-contained script: - source /opt/gcc-8.5.0/enable - curl -LO https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-i386.tar.gz @@ -540,7 +540,7 @@ centos7-32bit-cmake-self-contained: centos7-32bit-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - source /opt/gcc-8.5.0/enable - EXTRA_LDFLAGS="-static-libstdc++ -static-libgcc" @@ -548,7 +548,7 @@ centos7-32bit-system-dependencies: centos7-32bit-cmake-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/centos7-32bit-system-dependencies + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/centos7-32bit-system-dependencies script: - source /opt/gcc-8.5.0/enable - yum install -y libtiff-devel bzip2-devel @@ -564,7 +564,7 @@ centos7-32bit-cmake-system-dependencies: arch-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - make self GRDIR=/usr/local/gr - mkdir artifacts @@ -585,7 +585,7 @@ arch-self-contained: arch-cmake-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/arch-self-contained + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/arch-self-contained script: - make -C 3rdparty default extras - mkdir build @@ -602,13 +602,13 @@ arch-cmake-self-contained: arch-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - make install GRDIR=/usr/local/gr arch-cmake-system-dependencies: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/arch-system-dependencies + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/arch-system-dependencies script: - pacman -Sy - pacman -S --noconfirm --needed qhull @@ -646,7 +646,7 @@ freebsd-self-contained: windows-32bit-cross: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - wget https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz - tar xf cmake-3.23.0-linux-x86_64.tar.gz @@ -698,7 +698,7 @@ windows-32bit-cross: windows-32bit-cmake-cross: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/windows-32bit-cross + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/windows-32bit-cross script: - mkdir qt5-runtime-Windows-i686 - cd qt5-runtime-Windows-i686 @@ -742,7 +742,7 @@ windows-32bit-cmake-cross: windows-64bit-cross: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - wget https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz - tar xf cmake-3.23.0-linux-x86_64.tar.gz @@ -794,7 +794,7 @@ windows-64bit-cross: windows-64bit-cmake-cross: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/windows-64bit-cross + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/windows-64bit-cross script: - mkdir qt5-runtime-Windows-x86_64 - cd qt5-runtime-Windows-x86_64 @@ -838,7 +838,7 @@ windows-64bit-cmake-cross: windows-64bit-cmake-msvc: stage: build - image: windows_cpp17:10-gr-build + image: windows:10-gr-build tags: - libvirt script: @@ -992,7 +992,7 @@ darwin-self-contained-iff1605: emscripten: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME script: - source /emsdk/emsdk_env.sh - emmake make -C js @@ -1188,7 +1188,7 @@ packages-tar: sync: stage: sync - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/deploy + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/deploy variables: GIT_STRATEGY: none only: @@ -1212,7 +1212,7 @@ sync: deploy-to-obs: stage: deploy - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME only: - develop@Scientific-IT-Systems/gr - tags@Scientific-IT-Systems/gr @@ -1239,7 +1239,7 @@ deploy-to-obs: deploy-to-aur: stage: deploy - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME only: - develop@Scientific-IT-Systems/gr - tags@Scientific-IT-Systems/gr From 0e441901f432fe5c324f6d6da3bdcfc7c8724282 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Sat, 12 Nov 2022 15:10:07 -0500 Subject: [PATCH 02/11] Try LOAD_LIBRARY_SEARCH_DEFAULT_DIRS if fail --- lib/gks/plugin.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/gks/plugin.c b/lib/gks/plugin.c index e9c7d9c76..542e8b83f 100644 --- a/lib/gks/plugin.c +++ b/lib/gks/plugin.c @@ -51,6 +51,15 @@ static void *load_library(const char *name) GetEnvironmentVariableW(L"GRDIR", grdir, MAX_PATH); StringCbPrintfW(w_pathname, MAX_PATH, L"%ws\\bin\\%S.%S", grdir, name, EXTENSION); handle = LoadLibraryExW(w_pathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if (handle == NULL) + { + //Try loading with default search path if altered search path fails + // This value is a combination of LOAD_LIBRARY_SEARCH_APPLICATION_DIR, + // LOAD_LIBRARY_SEARCH_USER_DIRS, and LOAD_LIBRARY_SEARCH_SYSTEM32. + // They are searched in that order. + // Use AddDllDirectory to add additional user directories to the search. + handle = LoadLibraryExW(w_pathname, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + } } #else handle = dlopen(pathname, RTLD_LAZY); From 63a2580b4f80bf378895d21d593546b8bd5c9a28 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Sun, 13 Nov 2022 10:34:32 +0100 Subject: [PATCH 03/11] Fix comment --- lib/gks/plugin.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/gks/plugin.c b/lib/gks/plugin.c index 542e8b83f..7bbd96d95 100644 --- a/lib/gks/plugin.c +++ b/lib/gks/plugin.c @@ -53,11 +53,12 @@ static void *load_library(const char *name) handle = LoadLibraryExW(w_pathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (handle == NULL) { - //Try loading with default search path if altered search path fails - // This value is a combination of LOAD_LIBRARY_SEARCH_APPLICATION_DIR, - // LOAD_LIBRARY_SEARCH_USER_DIRS, and LOAD_LIBRARY_SEARCH_SYSTEM32. - // They are searched in that order. - // Use AddDllDirectory to add additional user directories to the search. + /* Try loading with default search path if altered search path fails + This value is a combination of LOAD_LIBRARY_SEARCH_APPLICATION_DIR, + LOAD_LIBRARY_SEARCH_USER_DIRS, and LOAD_LIBRARY_SEARCH_SYSTEM32. + They are searched in that order. + Use AddDllDirectory to add additional user directories to the search. + */ handle = LoadLibraryExW(w_pathname, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); } } From 67de71d0db462dbc104203b03c08f89d431270da Mon Sep 17 00:00:00 2001 From: Ingo Meyer Date: Mon, 14 Nov 2022 14:07:46 +0100 Subject: [PATCH 04/11] Make the `default` target the real default target in the gksqt Makefile --- lib/gks/qt/makefile.mak | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gks/qt/makefile.mak b/lib/gks/qt/makefile.mak index 1d0afc326..6ada2ca52 100644 --- a/lib/gks/qt/makefile.mak +++ b/lib/gks/qt/makefile.mak @@ -17,12 +17,12 @@ endif endif QMAKE ?= $(TMP_QMAKE) -QMakefile: - @if [ "$(QMAKE)" != "" ]; then $(QMAKE) -o QMakefile; fi - default: QMakefile @if [ "$(QMAKE)" != "" ]; then $(MAKE) -f QMakefile; fi +QMakefile: + @if [ "$(QMAKE)" != "" ]; then $(QMAKE) -o QMakefile; fi + install: default ifeq ($(UNAME), Darwin) @if [ ! -d $(DESTDIR)$(GRDIR)/Applications ]; then \ From db71cd7a20012cce8c7341f52228637b1ddd853e Mon Sep 17 00:00:00 2001 From: Ingo Meyer Date: Mon, 14 Nov 2022 13:19:43 +0100 Subject: [PATCH 05/11] Fix wrong references to `imeyer`'s repositories in the CI configuration --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4b1fd3ff..d02037976 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -134,7 +134,7 @@ ubuntu-cmake-self-contained-rebuild-images: - mv $SSH_KNOWN_HOSTS ~/.ssh/known_hosts - chmod 600 ~/.ssh/id_rsa - python3 -m venv env && source env/bin/activate - - git clone gitlab@iffgit.fz-juelich.de:imeyer/gr-test.git + - git clone gitlab@iffgit.fz-juelich.de:scientific-it-systems/gr-test.git - pip install -e gr-test/ - cd gr-test - git checkout -b update-files/job-$CI_JOB_ID @@ -202,7 +202,7 @@ debian-self-contained: debian-cmake-self-contained: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/debian-self-contained + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/debian-self-contained script: - wget https://gr-framework.org/downloads/3rdparty/cmake-3.23.0-linux-x86_64.tar.gz - tar xf cmake-3.23.0-linux-x86_64.tar.gz @@ -222,7 +222,7 @@ debian-cmake-self-contained: debian-self-contained-armhf: stage: build - image: iffregistry.fz-juelich.de/imeyer/gr-build-images/$CI_JOB_NAME-cross + image: iffregistry.fz-juelich.de/docker-images/gr-build-images/$CI_JOB_NAME-cross script: - make -C 3rdparty default extras \ HOST=arm-linux-gnueabihf \ From a67a12f5d070572af0983cad16b1ec89df7c1613 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 15 Nov 2022 10:21:09 +0100 Subject: [PATCH 06/11] GR: allow \(...\) for LaTeX math mode --- lib/gr/gr.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/gr/gr.c b/lib/gr/gr.c index a33c55a15..c05c3e123 100644 --- a/lib/gr/gr.c +++ b/lib/gr/gr.c @@ -11229,6 +11229,18 @@ static text_node_t *parse(double x, double y, char *string, int inline_math) math = !math; start = end; } + else if (inline_math && *end == '\\' && *(end + 1) == '(') + { + *end++ = '\0'; + append(x, y, start, line_number, 0); + start = ++end; + } + else if (inline_math && *end == '\\' && *(end + 1) == ')') + { + *end++ = '\0'; + append(x, y, start, line_number, 1); + start = ++end; + } else end++; } @@ -11460,7 +11472,7 @@ void gr_text(double x, double y, char *string) gks_inq_current_xformno(&errind, &tnr); if (tnr != NDC) gks_select_xform(NDC); - if (strchr(string, '\n') != NULL || strchr(string, '$') != NULL) + if (strchr(string, '\n') != NULL || strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) text_impl(x, y, string, 1, 0, NULL, NULL); else gks_text(x, y, string); @@ -11504,7 +11516,7 @@ void gr_textx(double x, double y, char *string, int opts) gks_select_xform(NDC); } - if (strchr(string, '\n') != NULL || (strchr(string, '$') != NULL && inline_math)) + if (strchr(string, '\n') != NULL || ((strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) && inline_math)) text_impl(xn, yn, string, inline_math, 0, NULL, NULL); else gks_text(xn, yn, string); @@ -11524,7 +11536,7 @@ void gr_inqtext(double x, double y, char *string, double *tbx, double *tby) gks_inq_current_xformno(&errind, &tnr); if (tnr != NDC) gks_select_xform(NDC); - if (strchr(string, '\n') != NULL || strchr(string, '$') != NULL) + if (strchr(string, '\n') != NULL || strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) text_impl(x, y, string, 1, 1, tbx, tby); else { @@ -11550,7 +11562,7 @@ void gr_inqtextx(double x, double y, char *string, int opts, double *tbx, double gks_select_xform(NDC); } - if (strchr(string, '\n') != NULL || (strchr(string, '$') != NULL && inline_math)) + if (strchr(string, '\n') != NULL || ((strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) && inline_math)) text_impl(xn, yn, string, inline_math, 1, tbx, tby); else { From f37dfaaf67ce7512a2ceb2d8d88c64465c4fca35 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 15 Nov 2022 15:19:13 +0100 Subject: [PATCH 07/11] Use "Python compatible" is_math_text() --- lib/gr/gr.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/gr/gr.c b/lib/gr/gr.c index c05c3e123..69b245504 100644 --- a/lib/gr/gr.c +++ b/lib/gr/gr.c @@ -11451,6 +11451,30 @@ static void text_impl(double x, double y, char *string, int inline_math, int inq gks_set_text_align(hAlign, vAlign); } +static int is_math_text(char *s) +{ + if (strchr(s, '$') != NULL) + { + int dollar_count = 0; + while (*s) + { + if (*s == '$') + { + if (*(s + 1) != '$') + dollar_count++; + else + s++; + } + s++; + } + return dollar_count > 0 && dollar_count % 2 == 0 ? 1 : 0; + } + else if (strstr(s, "\\(") != NULL) + return 1; + else + return 0; +} + /*! * Draw a text at position `x`, `y` using the current text attributes. * @@ -11472,7 +11496,7 @@ void gr_text(double x, double y, char *string) gks_inq_current_xformno(&errind, &tnr); if (tnr != NDC) gks_select_xform(NDC); - if (strchr(string, '\n') != NULL || strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) + if (strchr(string, '\n') != NULL || is_math_text(string)) text_impl(x, y, string, 1, 0, NULL, NULL); else gks_text(x, y, string); @@ -11516,7 +11540,7 @@ void gr_textx(double x, double y, char *string, int opts) gks_select_xform(NDC); } - if (strchr(string, '\n') != NULL || ((strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) && inline_math)) + if (strchr(string, '\n') != NULL || (is_math_text(string) && inline_math)) text_impl(xn, yn, string, inline_math, 0, NULL, NULL); else gks_text(xn, yn, string); @@ -11536,7 +11560,7 @@ void gr_inqtext(double x, double y, char *string, double *tbx, double *tby) gks_inq_current_xformno(&errind, &tnr); if (tnr != NDC) gks_select_xform(NDC); - if (strchr(string, '\n') != NULL || strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) + if (strchr(string, '\n') != NULL || is_math_text(string)) text_impl(x, y, string, 1, 1, tbx, tby); else { @@ -11562,7 +11586,7 @@ void gr_inqtextx(double x, double y, char *string, int opts, double *tbx, double gks_select_xform(NDC); } - if (strchr(string, '\n') != NULL || ((strchr(string, '$') != NULL || strstr(string, "\\(") != NULL) && inline_math)) + if (strchr(string, '\n') != NULL || (is_math_text(string) && inline_math)) text_impl(xn, yn, string, inline_math, 1, tbx, tby); else { From 978b2a786834c7c7cd48542e802e857cd8d9302d Mon Sep 17 00:00:00 2001 From: Thomas Verbovsek Date: Tue, 22 Nov 2022 13:35:37 +0000 Subject: [PATCH 08/11] Added a datafile reader for csv or similiar based files, which converts the... --- .gitlab-ci.yml | 35 + CMakeLists.txt | 86 ++ Makefile | 2 + lib/grm/Makefile | 35 +- lib/grm/grm-plots/README.md | 35 + lib/grm/grm-plots/data/covid19.csv | 924 ++++++++++++++++++++++ lib/grm/grm-plots/data/sans.dat | 132 ++++ lib/grm/grm-plots/data/test.dat | 9 + lib/grm/grm-plots/grm-plots.macos.sh | 5 + lib/grm/grm-plots/grm-plots.pro | 29 + lib/grm/grm-plots/grmplots.cxx | 32 + lib/grm/grm-plots/grmplots_mainwindow.cxx | 13 + lib/grm/grm-plots/grmplots_mainwindow.hxx | 18 + lib/grm/grm-plots/grmplots_widget.cxx | 407 ++++++++++ lib/grm/grm-plots/grmplots_widget.hxx | 78 ++ lib/grm/grm-plots/makefile.mak | 40 + lib/grm/grm-plots/makefile.mingw | 39 + lib/grm/grm-plots/util.hxx | 19 + lib/grm/include/grm.h | 1 + lib/grm/include/grm/import.h | 29 + lib/grm/makefile.mingw | 2 + lib/grm/src/grm/import.cxx | 424 ++++++++++ lib/grm/src/grm/import_int.hxx | 35 + lib/grm/src/grm/interaction.c | 29 +- lib/grm/src/grm/utilcpp.cxx | 47 ++ lib/grm/src/grm/utilcpp_int.hxx | 27 + 26 files changed, 2523 insertions(+), 9 deletions(-) create mode 100644 lib/grm/grm-plots/README.md create mode 100644 lib/grm/grm-plots/data/covid19.csv create mode 100644 lib/grm/grm-plots/data/sans.dat create mode 100644 lib/grm/grm-plots/data/test.dat create mode 100755 lib/grm/grm-plots/grm-plots.macos.sh create mode 100644 lib/grm/grm-plots/grm-plots.pro create mode 100644 lib/grm/grm-plots/grmplots.cxx create mode 100644 lib/grm/grm-plots/grmplots_mainwindow.cxx create mode 100644 lib/grm/grm-plots/grmplots_mainwindow.hxx create mode 100644 lib/grm/grm-plots/grmplots_widget.cxx create mode 100644 lib/grm/grm-plots/grmplots_widget.hxx create mode 100644 lib/grm/grm-plots/makefile.mak create mode 100644 lib/grm/grm-plots/makefile.mingw create mode 100644 lib/grm/grm-plots/util.hxx create mode 100644 lib/grm/include/grm/import.h create mode 100644 lib/grm/src/grm/import.cxx create mode 100644 lib/grm/src/grm/import_int.hxx create mode 100644 lib/grm/src/grm/utilcpp.cxx create mode 100644 lib/grm/src/grm/utilcpp_int.hxx diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d02037976..8a0ba74e8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,6 +59,7 @@ ubuntu-self-contained: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -187,6 +188,7 @@ debian-self-contained: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -255,6 +257,7 @@ debian-self-contained-armhf: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -302,6 +305,7 @@ debian-self-contained-aarch64: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -428,6 +432,7 @@ centos7-self-contained: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -500,6 +505,7 @@ centos7-32bit-self-contained: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -570,6 +576,7 @@ arch-self-contained: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -631,6 +638,7 @@ freebsd-self-contained: - mkdir artifacts - cp lib/gks/demo artifacts/gksdemo - cp lib/gks/qt/gksqt artifacts/gksqt + - cp lib/grm/grm-plots/grm-plots artifacts/grm-plots - cp lib/gr/demo artifacts/grdemo - cp lib/gks/libGKS.so lib/gks/libGKS.a lib/gks/plugin/*.so lib/gr/libGR.so lib/gr/libGR.a lib/gr3/libGR3.so lib/gr3/libGR3platform.so lib/grm/libGRM.a lib/grm/libGRM.so lib/gr/qtgr/*.so artifacts/ @@ -678,8 +686,15 @@ windows-32bit-cross: CXX=i686-w64-mingw32-g++ AR=i686-w64-mingw32-ar ARCHITECTURE=i686 + - MAKE="make -f makefile.mingw" make -f makefile.mingw -C lib/grm/grm-plots + GRDIR=./ + CC=i686-w64-mingw32-gcc + CXX=i686-w64-mingw32-g++ + AR=i686-w64-mingw32-ar + ARCHITECTURE=i686 - mkdir artifacts - cp lib/gks/qt/gksqt.exe artifacts/ + - cp lib/grm/grm-plots/grm-plots.exe artifacts/ - cp lib/gks/qt/*.dll artifacts/ - cp -r lib/gks/qt/platforms artifacts/ - cp lib/gks/libGKS.lib lib/gks/libGKS.dll lib/gks/libGKS.a lib/gks/plugin/*.dll lib/gks/plugin/*.a lib/gr/libGR.lib @@ -774,8 +789,15 @@ windows-64bit-cross: CXX=x86_64-w64-mingw32-g++ AR=x86_64-w64-mingw32-ar ARCHITECTURE=x86_64 + - MAKE="make -f makefile.mingw" make -f makefile.mingw -C lib/grm/grm-plots + GRDIR=./ + CC=x86_64-w64-mingw32-gcc + CXX=x86_64-w64-mingw32-g++ + AR=x86_64-w64-mingw32-ar + ARCHITECTURE=x86_64 - mkdir artifacts - cp lib/gks/qt/gksqt.exe artifacts/ + - cp lib/grm/grm-plots/grm-plots.exe artifacts/ - cp lib/gks/qt/*.dll artifacts/ - cp -r lib/gks/qt/platforms artifacts/ - cp lib/gks/libGKS.lib lib/gks/libGKS.dll lib/gks/libGKS.a lib/gks/plugin/*.dll lib/gks/plugin/*.a lib/gr/libGR.lib @@ -888,6 +910,7 @@ darwin-self-contained-iff1600: - cp -r lib/grm/include/grm artifacts/include/ - mkdir artifacts/Applications/ - cp -r lib/gks/quartz/build/Release/GKSTerm.app artifacts/Applications/GKSTerm.app + - cp -r lib/grm/grm-plots/grm-plots.app artifacts/Applications/grm-plots.app - cp -r lib/gks/qt/gksqt.app artifacts/Applications/gksqt.app - mkdir -p artifacts/Applications/gksqt.app/Contents/Frameworks - mkdir -p artifacts/Applications/gksqt.app/Contents/plugins/platforms @@ -929,6 +952,7 @@ darwin-self-contained: - cp -r lib/grm/include/grm artifacts/include/ - mkdir artifacts/Applications/ - cp -r lib/gks/quartz/build/Release/GKSTerm.app artifacts/Applications/GKSTerm.app + - cp -r lib/grm/grm-plots/grm-plots.app artifacts/Applications/grm-plots.app - cp -r lib/gks/qt/gksqt.app artifacts/Applications/gksqt.app - mkdir -p artifacts/Applications/gksqt.app/Contents/Frameworks - mkdir -p artifacts/Applications/gksqt.app/Contents/plugins/platforms @@ -970,6 +994,7 @@ darwin-self-contained-iff1605: - cp -r lib/grm/include/grm artifacts/include/ - mkdir artifacts/Applications/ - cp -r lib/gks/quartz/build/Release/GKSTerm.app artifacts/Applications/GKSTerm.app + - cp -r lib/grm/grm-plots/grm-plots.app artifacts/Applications/grm-plots.app - cp -r lib/gks/qt/gksqt.app artifacts/Applications/gksqt.app - mkdir -p artifacts/Applications/gksqt.app/Contents/Frameworks - mkdir -p artifacts/Applications/gksqt.app/Contents/plugins/platforms @@ -1015,6 +1040,7 @@ packages-tar: - mv artifacts-windows32/*.dll Windows-i686/gr/bin/ - mv artifacts-windows32/*.lib Windows-i686/gr/bin/ - mv artifacts-windows32/gksqt.exe Windows-i686/gr/bin/ + - mv artifacts-windows32/grm-plots.exe Windows-i686/gr/bin/ - mv artifacts-windows32/platforms Windows-i686/gr/bin/ - mv artifacts-windows32/fonts Windows-i686/gr/ - mv artifacts-windows32/include Windows-i686/gr/ @@ -1025,6 +1051,7 @@ packages-tar: - mv artifacts-windows64/*.dll Windows-x86_64/gr/bin/ - mv artifacts-windows64/*.lib Windows-x86_64/gr/bin/ - mv artifacts-windows64/gksqt.exe Windows-x86_64/gr/bin/ + - mv artifacts-windows64/grm-plots.exe Windows-x86_64/gr/bin/ - mv artifacts-windows64/platforms Windows-x86_64/gr/bin/ - mv artifacts-windows64/fonts Windows-x86_64/gr/ - mv artifacts-windows64/include Windows-x86_64/gr/ @@ -1036,6 +1063,7 @@ packages-tar: - mkdir -p Debian-x86_64/gr/lib - mv artifacts-debian10/*.so Debian-x86_64/gr/lib/ - mv artifacts-debian10/gksqt Debian-x86_64/gr/bin/ + - mv artifacts-debian10/grm-plots Debian-x86_64/gr/bin/ - mv artifacts-debian10/fonts Debian-x86_64/gr/ - mv artifacts-debian10/include Debian-x86_64/gr/ - cp artifacts-js/gr.js Debian-x86_64/gr/lib/ @@ -1044,6 +1072,7 @@ packages-tar: - mkdir -p Debian-armhf/gr/lib - mv artifacts-debian10-armhf/*.so Debian-armhf/gr/lib/ - mv artifacts-debian10-armhf/gksqt Debian-armhf/gr/bin/ + - mv artifacts-debian10-armhf/grm-plots Debian-armhf/gr/bin/ - mv artifacts-debian10-armhf/fonts Debian-armhf/gr/ - mv artifacts-debian10-armhf/include Debian-armhf/gr/ - cp artifacts-js/gr.js Debian-armhf/gr/lib/ @@ -1052,6 +1081,7 @@ packages-tar: - mkdir -p Debian-aarch64/gr/lib - mv artifacts-debian10-aarch64/*.so Debian-aarch64/gr/lib/ - mv artifacts-debian10-aarch64/gksqt Debian-aarch64/gr/bin/ + - mv artifacts-debian10-aarch64/grm-plots Debian-aarch64/gr/bin/ - mv artifacts-debian10-aarch64/fonts Debian-aarch64/gr/ - mv artifacts-debian10-aarch64/include Debian-aarch64/gr/ - cp artifacts-js/gr.js Debian-aarch64/gr/lib/ @@ -1060,6 +1090,7 @@ packages-tar: - mkdir -p Ubuntu-x86_64/gr/lib - mv artifacts-ubuntu2004/*.so Ubuntu-x86_64/gr/lib/ - mv artifacts-ubuntu2004/gksqt Ubuntu-x86_64/gr/bin/ + - mv artifacts-ubuntu2004/grm-plots Ubuntu-x86_64/gr/bin/ - mv artifacts-ubuntu2004/fonts Ubuntu-x86_64/gr/ - mv artifacts-ubuntu2004/include Ubuntu-x86_64/gr/ - cp artifacts-js/gr.js Ubuntu-x86_64/gr/lib/ @@ -1068,6 +1099,7 @@ packages-tar: - mkdir -p CentOS-x86_64/gr/lib - mv artifacts-centos7/*.so CentOS-x86_64/gr/lib/ - mv artifacts-centos7/gksqt CentOS-x86_64/gr/bin/ + - mv artifacts-centos7/grm-plots CentOS-x86_64/gr/bin/ - mv artifacts-centos7/fonts CentOS-x86_64/gr/ - mv artifacts-centos7/include CentOS-x86_64/gr/ - cp artifacts-js/gr.js CentOS-x86_64/gr/lib/ @@ -1077,6 +1109,7 @@ packages-tar: - mkdir -p Linux-i386/gr/lib - mv artifacts-centos7-32bit/*.so Linux-i386/gr/lib/ - mv artifacts-centos7-32bit/gksqt Linux-i386/gr/bin/ + - mv artifacts-centos7-32bit/grm-plots Linux-i386/gr/bin/ - mv artifacts-centos7-32bit/fonts Linux-i386/gr/ - mv artifacts-centos7-32bit/include Linux-i386/gr/ - cp artifacts-js/gr.js Linux-i386/gr/lib/ @@ -1085,6 +1118,7 @@ packages-tar: - mkdir -p ArchLinux-x86_64/gr/lib - mv artifacts-arch/*.so ArchLinux-x86_64/gr/lib/ - mv artifacts-arch/gksqt ArchLinux-x86_64/gr/bin/ + - mv artifacts-arch/grm-plots ArchLinux-x86_64/gr/bin/ - mv artifacts-arch/fonts ArchLinux-x86_64/gr/ - mv artifacts-arch/include ArchLinux-x86_64/gr/ - cp artifacts-js/gr.js ArchLinux-x86_64/gr/lib/ @@ -1093,6 +1127,7 @@ packages-tar: - mkdir -p FreeBSD-x86_64/gr/lib - mv artifacts-freebsd13/*.so FreeBSD-x86_64/gr/lib/ - mv artifacts-freebsd13/gksqt FreeBSD-x86_64/gr/bin/ + - mv artifacts-freebsd13/grm-plots FreeBSD-x86_64/gr/bin/ - mv artifacts-freebsd13/fonts FreeBSD-x86_64/gr/ - mv artifacts-freebsd13/include FreeBSD-x86_64/gr/ - cp artifacts-js/gr.js FreeBSD-x86_64/gr/lib/ diff --git a/CMakeLists.txt b/CMakeLists.txt index d1a7f2b3b..0351373c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -468,6 +468,8 @@ set(GRM_SOURCES lib/grm/src/grm/net.c lib/grm/src/grm/plot.cxx lib/grm/src/grm/util.c + lib/grm/src/grm/import.cxx + lib/grm/src/grm/utilcpp.cxx lib/grm/src/grm/datatype/double_map.c lib/grm/src/grm/datatype/string_array_map.c lib/grm/src/grm/datatype/string_list.c @@ -1084,6 +1086,76 @@ else() string(APPEND GR_REPORT "- gksqt: No (Qt4 / Qt5 / Qt6 not found)\n") endif() +if((Qt6Widgets_FOUND AND Qt6Core_FOUND) OR (Qt5Widgets_FOUND AND Qt5Core_FOUND)) + add_executable( + grm-plots WIN32 MACOSX_BUNDLE lib/grm/grm-plots/grmplots.cxx lib/grm/grm-plots/grmplots_mainwindow.cxx + lib/grm/grm-plots/grmplots_widget.cxx + ) + if(Qt6Widgets_FOUND AND Qt6Core_FOUND) + target_link_libraries(grm-plots PRIVATE Qt6::Widgets Qt6::Core grm_static) + if(NOT DEFINED Qt6_LIBRARY_DIR) + get_filename_component(Qt6_LIBRARY_DIR "${Qt6_DIR}/../.." ABSOLUTE) + endif() + set(grm-plots_INSTALL_RPATH "${INSTALL_RPATH};${Qt6_LIBRARY_DIR}") + else() + target_link_libraries(grm-plots PRIVATE Qt5::Widgets Qt5::Core grm_static) + if(NOT DEFINED Qt5_LIBRARY_DIR) + get_filename_component(Qt5_LIBRARY_DIR "${Qt5_DIR}/../.." ABSOLUTE) + endif() + set(grm-plots_INSTALL_RPATH "${INSTALL_RPATH};${Qt5_LIBRARY_DIR}") + endif() + set_target_properties( + grm-plots PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON INSTALL_RPATH + "${grm-plots_INSTALL_RPATH}" + ) + if(GR_MANUAL_MOC_AND_RCC) + set_target_properties(grm-plots PROPERTIES AUTOMOC OFF AUTORCC OFF) + if(Qt6Widgets_FOUND AND Qt6Core_FOUND) + set(MOC_INCLUDE_FLAGS ${QT6_MOC_INCLUDE_FLAGS}) + else() + set(MOC_INCLUDE_FLAGS ${QT5_MOC_INCLUDE_FLAGS}) + endif() + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/moc_grmplots_widget.cxx + COMMAND + ${QT_MOC_EXECUTABLE} -DGRDIR=\"$(GR_DIRECTORY)\" ${MOC_INCLUDE_FLAGS} + ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grm-plots/grmplots_widget.hxx -o + ${CMAKE_CURRENT_BINARY_DIR}/moc_grmplots_widget.cxx + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grm-plots/grmplots_widget.hxx + ) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/moc_grmplots_mainwindow.cxx + COMMAND + ${QT_MOC_EXECUTABLE} -DGRDIR=\"$(GR_DIRECTORY)\" ${MOC_INCLUDE_FLAGS} + ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grm-plots/grmplots_mainwindow.hxx -o + ${CMAKE_CURRENT_BINARY_DIR}/moc_grmplots_mainwindow.cxx + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grm-plots/grmplots_mainwindow.hxx + ) + target_sources( + grm-plots PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/moc_grmplots_mainwindow.cxx + ${CMAKE_CURRENT_BINARY_DIR}/moc_grmplots_widget.cxx + ) + else() + set_target_properties(grm-plots PROPERTIES AUTOMOC ON AUTORCC ON) + target_sources( + grm-plots PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grm-plots/grmplots_mainwindow.hxx + ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grm-plots/grmplots_widget.hxx + ) + endif() + if(APPLE) + set_target_properties(grm-plots PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "de.fz-juelich.grm-plots") + endif() + if(WIN32) + target_compile_definitions(grm-plots PRIVATE GR_STATIC_LIB) + endif() + if(MINGW) + target_compile_options(grm-plots PRIVATE -fno-exceptions ${COMPILER_OPTION_ERROR_IMPLICIT}) + endif() + string(APPEND GR_REPORT "- grm-plots: Yes\n") +else() + string(APPEND GR_REPORT "- grm-plots: No (Qt6 or Qt5 not found)\n") +endif() + if(GR_BUILD_DEMOS) add_executable(gksdemo lib/gks/demo.c) target_link_libraries(gksdemo PUBLIC gks_static) @@ -1229,6 +1301,20 @@ if(GR_INSTALL) BUNDLE DESTINATION Applications ) endif() + if(TARGET grm-plots) + install( + TARGETS grm-plots + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + BUNDLE DESTINATION Applications + ) + if(APPLE) + install( + PROGRAMS lib/grm/grm-plots/grm-plots.macos.sh + DESTINATION ${CMAKE_INSTALL_BINDIR} + RENAME grm-plots + ) + endif() + endif() install(FILES lib/gr/gr.h lib/gks/gks.h lib/gr3/gr3.h lib/grm/include/grm.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/) install(DIRECTORY lib/grm/include/grm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/) if(TARGET qt4gr diff --git a/Makefile b/Makefile index be9e1c871..31474dff4 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,8 @@ osxpkg: ln -s ../gr/bin/gr tmp/bin/gr ln -s ../gr/Applications/glgr.app/Contents/MacOS/glgr tmp/bin/glgr ln -s ../gr/Applications/gksqt.app/Contents/MacOS/gksqt tmp/bin/gksqt + @if [ -e ../gr/Applications/grm-plots.app/Contents/MacOS/grm-plots ]; then \ + ln -s ../gr/Applications/grm-plots.app/Contents/MacOS/grm-plots tmp/bin/grm-plots; fi sudo chown -R -h root:wheel tmp/ pkgbuild --identifier de.fz-juelich.gr --root tmp --install-location /usr/local --ownership preserve gr.pkg sudo rm -rf tmp diff --git a/lib/grm/Makefile b/lib/grm/Makefile index 4f50f8756..6a00f1917 100644 --- a/lib/grm/Makefile +++ b/lib/grm/Makefile @@ -21,6 +21,8 @@ UNAME := $(shell uname) src/grm/net.o \ src/grm/plot.o \ src/grm/util.o \ + src/grm/utilcpp.o \ + src/grm/import.o \ src/grm/datatype/double_map.o \ src/grm/datatype/string_list.o \ src/grm/datatype/string_array_map.o \ @@ -55,6 +57,18 @@ endif GR3LIBS = -L ../gr3/ -lGR3 LIBS = $(GRLIBS) $(GR3LIBS) -lm +grmplots_support = +ifneq ($(QT5_QMAKE),) +ifneq ($(QT5_QMAKE),false) + grmplots_support = yes +endif +endif +ifneq ($(QT6_QMAKE),) +ifneq ($(QT6_QMAKE),false) + grmplots_support = yes +endif +endif + .c.o: $(CC) -o $@ -c $(INCLUDES) $(CFLAGS) $< @@ -67,7 +81,11 @@ default: all: targets +ifdef grmplots_support +targets: prerequisites libGRM.a libGRM${GR_SHARED_LIBRARY_SUFFIX} grm-plots +else targets: prerequisites libGRM.a libGRM${GR_SHARED_LIBRARY_SUFFIX} +endif prerequisites: $(MAKE) -C ../../3rdparty/ PREFIX=$(THIRDPARTYDIR) @@ -85,6 +103,9 @@ libGRM.a: $(GRMOBJS) libGRM${GR_SHARED_LIBRARY_SUFFIX}: $(GRMOBJS) libGR libGR3 $(CXX) -o $@ $(SOFLAGS) $(GRMOBJS) $(LIBS) $(LDFLAGS) $(INSTALL_NAME) +grm-plots: + $(MAKE) -C grm-plots -f makefile.mak GRDIR=$(GRDIR) + install: @if [ ! -d $(DESTDIR)$(GRDIR) ]; then mkdir -m 755 $(DESTDIR)$(GRDIR); fi @if [ ! -d $(LIBDIR) ]; then mkdir -m 755 $(LIBDIR); fi @@ -92,14 +113,26 @@ install: @if [ ! -d $(INCDIR) ]; then mkdir -m 755 $(INCDIR); fi cp -p include/grm.h $(INCDIR) cp -rp include/grm $(INCDIR)/ +ifeq ($(UNAME), Darwin) + @if [ -d grm-plots/grm-plots.app ]; then \ + $(MAKE) -C grm-plots -f makefile.mak install; \ + fi +else + @if [ -f grm-plots/grm-plots ]; then \ + $(MAKE) -C grm-plots -f makefile.mak install; \ + fi +endif clean: + $(MAKE) -C grm-plots -f makefile.mak clean + rm -f grm-plots/.qmake.stash rm -f *.so \ *.a \ src/grm/*.o \ src/grm/datatype/*.o \ *${GR_SHARED_LIBRARY_SUFFIX} -.PHONY: all targets install clean prerequisites libGR libGR3 + +.PHONY: all targets install clean prerequisites libGR libGR3 grm-plots .SUFFIXES: # Delete the default suffixes .SUFFIXES: .c .cxx .o # List all suffixes for suffix rules explicitly diff --git a/lib/grm/grm-plots/README.md b/lib/grm/grm-plots/README.md new file mode 100644 index 000000000..ae3aa6384 --- /dev/null +++ b/lib/grm/grm-plots/README.md @@ -0,0 +1,35 @@ +# gr-plots + +## Introduction + +This small program allows to create plots from console line while using 1-3 parameters. + +## Console parameters + +1. file: contains the data which should be displayed. When no file is referred this results in an error message. +2. plot type: `line`, `heatmap` or `marginalheatmap` which is a heatmap with histograms on the side. The default is + line. +3. columns: define the columns of the file which should be respected in the plot. The default is all columns. When all + columns from x to y should be drawn use `x:y`. + +The three parameters are separated through 1 whitespace. To select more than 1 specific column use the ',' without +whitespace as separator. + +An example for the parameters on the commandline: + +```shell +covid19.csv line 1:3,5 +``` + +## CSV file + +First lines define parameters just like the title or the labels. For that the lines have to follow the pattern: + +```text +# key : value +``` + +Values are seperated through `,`. This means `3, 5` for example. + +The next line after the header is treated as a line full of labels. When the data has no labels use a blank line +instead. Now the data can be added with a tabulator (`\t`) as separator for the columns. diff --git a/lib/grm/grm-plots/data/covid19.csv b/lib/grm/grm-plots/data/covid19.csv new file mode 100644 index 000000000..3004c1fd2 --- /dev/null +++ b/lib/grm/grm-plots/data/covid19.csv @@ -0,0 +1,924 @@ +# title : Confirmed SARS–CoV–2 infections +# xlabel : Day +# ylabel : Confirmed +# xlim : 0.0, 917 + 1.0 +# ylog : 1 +# location : 4 +Germany Austria Belgium Netherlands France Italy Spain US +NAN NAN NAN NAN NAN NAN NAN 1.0 +NAN NAN NAN NAN NAN NAN NAN 1.0 +NAN NAN NAN NAN 2.0 NAN NAN 2.0 +NAN NAN NAN NAN 3.0 NAN NAN 2.0 +NAN NAN NAN NAN 3.0 NAN NAN 5.0 +1.0 NAN NAN NAN 3.0 NAN NAN 5.0 +4.0 NAN NAN NAN 4.0 NAN NAN 5.0 +4.0 NAN NAN NAN 5.0 NAN NAN 6.0 +4.0 NAN NAN NAN 5.0 NAN NAN 6.0 +5.0 NAN NAN NAN 5.0 2.0 NAN 8.0 +8.0 NAN NAN NAN 6.0 2.0 1.0 8.0 +10.0 NAN NAN NAN 6.0 2.0 1.0 8.0 +12.0 NAN NAN NAN 6.0 2.0 1.0 11.0 +12.0 NAN 1.0 NAN 6.0 2.0 1.0 11.0 +12.0 NAN 1.0 NAN 6.0 2.0 1.0 11.0 +12.0 NAN 1.0 NAN 6.0 2.0 1.0 12.0 +13.0 NAN 1.0 NAN 6.0 3.0 1.0 12.0 +13.0 NAN 1.0 NAN 11.0 3.0 1.0 12.0 +14.0 NAN 1.0 NAN 11.0 3.0 2.0 12.0 +14.0 NAN 1.0 NAN 11.0 3.0 2.0 12.0 +16.0 NAN 1.0 NAN 11.0 3.0 2.0 13.0 +16.0 NAN 1.0 NAN 11.0 3.0 2.0 13.0 +16.0 NAN 1.0 NAN 11.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 11.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 3.0 2.0 14.0 +16.0 NAN 1.0 NAN 12.0 20.0 2.0 16.0 +16.0 NAN 1.0 NAN 12.0 62.0 2.0 16.0 +16.0 NAN 1.0 NAN 12.0 155.0 2.0 16.0 +16.0 NAN 1.0 NAN 12.0 229.0 2.0 16.0 +16.0 2.0 1.0 NAN 14.0 322.0 6.0 16.0 +21.0 1.0 1.0 NAN 18.0 453.0 13.0 16.0 +26.0 1.0 1.0 1.0 38.0 655.0 15.0 17.0 +53.0 1.0 1.0 6.0 57.0 888.0 32.0 17.0 +66.0 3.0 1.0 10.0 100.0 1128.0 45.0 25.0 +117.0 7.0 2.0 18.0 130.0 1694.0 84.0 32.0 +150.0 8.0 8.0 24.0 191.0 2036.0 120.0 55.0 +188.0 12.0 13.0 38.0 212.0 2502.0 165.0 74.0 +240.0 17.0 23.0 82.0 288.0 3089.0 222.0 107.0 +349.0 23.0 50.0 128.0 426.0 3858.0 259.0 184.0 +534.0 37.0 109.0 188.0 616.0 4636.0 400.0 237.0 +684.0 46.0 169.0 265.0 948.0 5883.0 500.0 403.0 +847.0 75.0 200.0 321.0 1125.0 7375.0 673.0 519.0 +1112.0 98.0 239.0 382.0 1411.0 9172.0 1073.0 594.0 +1296.0 126.0 267.0 503.0 1783.0 10149.0 1695.0 782.0 +1567.0 148.0 314.0 603.0 2293.0 12462.0 2277.0 1147.0 +2369.0 203.0 314.0 804.0 2293.0 15113.0 2277.0 1586.0 +3062.0 312.0 559.0 961.0 3681.0 17660.0 5232.0 2219.0 +3795.0 409.0 689.0 1138.0 4496.0 21157.0 6391.0 2978.0 +4838.0 591.0 886.0 1416.0 4532.0 24747.0 7798.0 3212.0 +6012.0 801.0 1058.0 1708.0 6683.0 27980.0 9942.0 4679.0 +7156.0 999.0 1243.0 2057.0 7715.0 31506.0 11748.0 6512.0 +8198.0 1225.0 1486.0 2467.0 9124.0 35713.0 13910.0 9169.0 +10999.0 1571.0 1795.0 3001.0 10970.0 41035.0 17963.0 13663.0 +13957.0 1943.0 2257.0 3640.0 12758.0 47021.0 20410.0 20030.0 +16662.0 2398.0 2815.0 4213.0 14463.0 53578.0 25374.0 26025.0 +18610.0 2909.0 3401.0 4762.0 16761.0 59138.0 28768.0 34944.0 +22672.0 3455.0 3743.0 5575.0 20120.0 63927.0 35136.0 46096.0 +27436.0 4073.0 4269.0 6432.0 22372.0 69176.0 39885.0 56714.0 +31554.0 4760.0 4937.0 7457.0 25331.0 74386.0 49515.0 68841.0 +36508.0 5483.0 6235.0 8640.0 29252.0 80589.0 57786.0 86662.0 +42288.0 6237.0 7284.0 9806.0 33045.0 86498.0 65719.0 105253.0 +48582.0 7293.0 9134.0 10923.0 37693.0 92472.0 73235.0 127417.0 +52547.0 8100.0 10836.0 11814.0 40296.0 97689.0 80110.0 143544.0 +57298.0 8717.0 11899.0 12662.0 44645.0 101739.0 87956.0 165698.0 +61913.0 9264.0 12775.0 13686.0 52281.0 105792.0 95923.0 192079.0 +67366.0 9937.0 13964.0 14779.0 57125.0 110574.0 104118.0 223254.0 +73522.0 10486.0 15348.0 15814.0 59227.0 115242.0 112065.0 255530.0 +79696.0 11035.0 16770.0 16725.0 64452.0 119827.0 119199.0 287931.0 +85778.0 11473.0 18431.0 17951.0 47376.0 124632.0 126168.0 319776.0 +91714.0 11884.0 19691.0 18905.0 48225.0 128948.0 131646.0 349016.0 +95391.0 12137.0 20814.0 19703.0 50884.0 132547.0 136675.0 380798.0 +99225.0 12320.0 22194.0 20678.0 47395.0 135586.0 141942.0 410834.0 +103228.0 12626.0 23403.0 21895.0 51250.0 139422.0 148220.0 441897.0 +108202.0 12915.0 24983.0 23238.0 55034.0 143626.0 153222.0 477507.0 +113525.0 13205.0 26667.0 24565.0 56600.0 147577.0 158273.0 511790.0 +117658.0 13481.0 28018.0 25745.0 58045.0 152271.0 163027.0 540714.0 +120479.0 13838.0 29647.0 26710.0 108792.0 156363.0 166831.0 567022.0 +123016.0 14041.0 30589.0 27578.0 111933.0 159516.0 170099.0 594165.0 +125098.0 14152.0 31119.0 28314.0 129381.0 162488.0 172541.0 622493.0 +127584.0 14239.0 33573.0 29377.0 132588.0 165155.0 177644.0 648390.0 +130450.0 14389.0 34809.0 30618.0 145166.0 168941.0 184948.0 678028.0 +133830.0 14518.0 36138.0 31759.0 147057.0 172434.0 190839.0 711135.0 +137439.0 14629.0 37183.0 32832.0 150861.0 175925.0 191726.0 738464.0 +139897.0 14729.0 38496.0 33588.0 151955.0 178972.0 198674.0 763886.0 +141672.0 14789.0 39983.0 34317.0 154402.0 181228.0 200210.0 793970.0 +143457.0 14836.0 40956.0 35025.0 157068.0 183957.0 204178.0 820045.0 +145694.0 14904.0 41889.0 35919.0 158867.0 187327.0 208389.0 849926.0 +148046.0 14974.0 42797.0 36727.0 157158.0 189973.0 213024.0 881891.0 +150383.0 15047.0 44293.0 37384.0 159969.0 192994.0 202990.0 913856.0 +152438.0 15107.0 45325.0 38039.0 161647.0 195351.0 205905.0 944770.0 +154175.0 15186.0 46134.0 38440.0 162280.0 197675.0 207634.0 970741.0 +155193.0 15248.0 46687.0 38611.0 165966.0 199414.0 209465.0 995391.0 +156337.0 15283.0 47334.0 38998.0 169098.0 201505.0 210773.0 1.019964e6 +157641.0 15353.0 47859.0 39512.0 167643.0 203591.0 212917.0 1.046816e6 +159119.0 15402.0 48519.0 39987.0 168861.0 205463.0 213435.0 1.076518e6 +160758.0 15463.0 49032.0 40434.0 169387.0 207428.0 215216.0 1.11141e6 +161703.0 15517.0 49517.0 40769.0 170179.0 209328.0 216582.0 1.138174e6 +162496.0 15554.0 49906.0 40968.0 170540.0 210717.0 217466.0 1.161907e6 +163175.0 15582.0 50267.0 41285.0 171102.0 211938.0 218011.0 1.185709e6 +163860.0 15594.0 50509.0 41518.0 172219.0 213013.0 219329.0 1.209729e6 +164807.0 15624.0 50781.0 41973.0 176355.0 214457.0 220325.0 1.234211e6 +166091.0 15678.0 51420.0 42292.0 177096.0 215858.0 221447.0 1.26195e6 +167300.0 15724.0 52011.0 42581.0 177627.0 217185.0 222857.0 1.289133e6 +168551.0 15763.0 52596.0 42826.0 178155.0 218268.0 223578.0 1.313587e6 +169218.0 15812.0 53081.0 42987.0 178404.0 219070.0 224350.0 1.332334e6 +169575.0 15842.0 53449.0 43183.0 178719.0 219814.0 227436.0 1.351411e6 +170508.0 15857.0 53779.0 43410.0 179472.0 221216.0 228030.0 1.374792e6 +171306.0 15923.0 53981.0 43680.0 179993.0 222104.0 228691.0 1.394807e6 +172239.0 15961.0 54288.0 43880.0 180635.0 223096.0 229540.0 1.420697e6 +173152.0 16013.0 54644.0 44069.0 181148.0 223885.0 230183.0 1.445548e6 +173772.0 16067.0 54989.0 44195.0 181563.0 224760.0 230698.0 1.469598e6 +174355.0 16148.0 55280.0 44341.0 181703.0 225435.0 230698.0 1.488327e6 +174697.0 16163.0 55559.0 44449.0 182147.0 225886.0 231606.0 1.510635e6 +175210.0 16189.0 55791.0 44647.0 182648.0 226699.0 232037.0 1.531138e6 +176007.0 16247.0 55983.0 44900.0 183129.0 227364.0 232555.0 1.553966e6 +176752.0 16308.0 56235.0 45088.0 183396.0 228006.0 233037.0 1.579118e6 +177212.0 16338.0 56511.0 45264.0 184152.0 228658.0 234824.0 1.602947e6 +177850.0 16369.0 56810.0 45437.0 184698.0 229327.0 235290.0 1.623136e6 +178281.0 16397.0 57092.0 45646.0 184259.0 229858.0 235772.0 1.64331e6 +178570.0 16421.0 57342.0 45780.0 184584.0 230158.0 235400.0 1.662404e6 +179002.0 16452.0 57455.0 45970.0 184839.0 230555.0 236259.0 1.68113e6 +179364.0 16477.0 57592.0 46152.0 185012.0 231139.0 236259.0 1.699893e6 +179717.0 16499.0 57849.0 46328.0 188355.0 231732.0 237906.0 1.72116e6 +180458.0 16549.0 58061.0 46459.0 188949.0 232248.0 238564.0 1.746242e6 +181196.0 16568.0 58186.0 46645.0 190743.0 232664.0 239228.0 1.769322e6 +181482.0 16610.0 58381.0 46748.0 190975.0 232997.0 239479.0 1.788241e6 +181815.0 16642.0 58517.0 46851.0 191382.0 233197.0 239638.0 1.806081e6 +182028.0 16647.0 58615.0 46938.0 190735.0 233515.0 239932.0 1.826171e6 +182370.0 16666.0 58685.0 47148.0 187509.0 233836.0 240326.0 1.845327e6 +182764.0 16682.0 58767.0 47358.0 191869.0 234013.0 240660.0 1.873261e6 +183271.0 16735.0 58907.0 47541.0 192450.0 234531.0 240978.0 1.899701e6 +183678.0 16752.0 59072.0 47780.0 193022.0 234801.0 241310.0 1.91997e6 +183979.0 16819.0 59226.0 47945.0 193363.0 234998.0 241550.0 1.937796e6 +184193.0 16850.0 59348.0 48109.0 193637.0 235278.0 241717.0 1.954696e6 +184543.0 16875.0 59437.0 48293.0 194190.0 235561.0 241966.0 1.975017e6 +184861.0 16899.0 59569.0 48458.0 194815.0 235763.0 242280.0 1.996735e6 +185416.0 16914.0 59711.0 48668.0 195179.0 236142.0 242707.0 2.019013e6 +185674.0 16948.0 59819.0 48847.0 195980.0 236305.0 243209.0 2.044571e6 +186022.0 16970.0 59918.0 48990.0 196477.0 236651.0 243605.0 2.068728e6 +186269.0 17007.0 60029.0 49155.0 196867.0 236989.0 243928.0 2.087629e6 +186461.0 17029.0 60100.0 49294.0 197003.0 237290.0 244109.0 2.108628e6 +186839.0 17047.0 60155.0 49412.0 197666.0 237500.0 244328.0 2.133177e6 +187184.0 17100.0 60244.0 49527.0 198155.0 237828.0 244683.0 2.160227e6 +187764.0 17119.0 60348.0 49634.0 198741.0 238159.0 245268.0 2.188454e6 +188534.0 17150.0 60476.0 49710.0 199528.0 238011.0 245575.0 2.219508e6 +189135.0 17182.0 60550.0 49801.0 200147.0 238275.0 245938.0 2.251334e6 +189822.0 17234.0 60550.0 49866.0 200490.0 238499.0 246272.0 2.27717e6 +190359.0 17266.0 60550.0 49930.0 200632.0 238720.0 246504.0 2.306971e6 +190862.0 17295.0 60810.0 50012.0 201330.0 238833.0 246752.0 2.3457e6 +191449.0 17326.0 60898.0 50122.0 201598.0 239410.0 247086.0 2.381951e6 +192079.0 17369.0 61007.0 50213.0 201853.0 239706.0 247486.0 2.42125e6 +192556.0 17404.0 61106.0 50282.0 203116.0 239961.0 247905.0 2.470296e6 +193243.0 17448.0 61209.0 50355.0 203564.0 240136.0 248469.0 2.51105e6 +193499.0 17522.0 61295.0 50431.0 203157.0 240310.0 248770.0 2.553975e6 +193761.0 17567.0 61361.0 50483.0 203802.0 240436.0 248970.0 2.595272e6 +194259.0 17629.0 61427.0 50545.0 204244.0 240578.0 249271.0 2.645097e6 +194725.0 17678.0 61509.0 50622.0 205234.0 240760.0 249659.0 2.69422e6 +195228.0 17779.0 61598.0 50698.0 205773.0 240961.0 250103.0 2.749163e6 +195674.0 17874.0 61727.0 50759.0 206312.0 241184.0 250545.0 2.800668e6 +196096.0 17954.0 61838.0 50834.0 206670.0 241419.0 250545.0 2.846614e6 +196335.0 18088.0 62016.0 50870.0 206682.0 241611.0 250545.0 2.900342e6 +196554.0 18194.0 62058.0 50907.0 207700.0 241819.0 251789.0 2.943508e6 +196944.0 18270.0 62058.0 50959.0 208154.0 241956.0 252130.0 3.000739e6 +197341.0 18338.0 62123.0 51011.0 208976.0 242149.0 252513.0 3.061045e6 +197783.0 18429.0 62210.0 51055.0 209420.0 242363.0 253056.0 3.120701e6 +198178.0 18547.0 62357.0 51136.0 210135.0 242639.0 253908.0 3.189561e6 +198556.0 18619.0 62469.0 51237.0 210386.0 242827.0 253908.0 3.25e6 +198804.0 18724.0 62707.0 51308.0 210402.0 243061.0 253908.0 3.310132e6 +198963.0 18814.0 62707.0 51361.0 211825.0 243230.0 255953.0 3.369496e6 +199375.0 18866.0 62781.0 51468.0 211887.0 243344.0 256619.0 3.435158e6 +199726.0 18965.0 62872.0 51570.0 212614.0 243506.0 257494.0 3.501184e6 +200260.0 19087.0 63238.0 51675.0 213183.0 243736.0 258855.0 3.571998e6 +200843.0 19217.0 63499.0 51809.0 214009.0 243967.0 260255.0 3.63847e6 +201372.0 19358.0 63706.0 51953.0 214174.0 244216.0 260255.0 3.702792e6 +201574.0 19482.0 63706.0 52140.0 214178.0 244434.0 260255.0 3.761724e6 +201823.0 19563.0 64094.0 52305.0 216089.0 244624.0 264836.0 3.822387e6 +202345.0 19650.0 64258.0 52475.0 216684.0 244752.0 266194.0 3.890581e6 +202799.0 19740.0 64627.0 52638.0 217605.0 245032.0 267551.0 3.958126e6 +203368.0 19877.0 64847.0 52831.0 218841.0 245338.0 270166.0 4.026012e6 +204183.0 20039.0 65199.0 52974.0 219932.0 245590.0 272421.0 4.101159e6 +204964.0 20156.0 65727.0 53257.0 220016.0 245864.0 272421.0 4.165359e6 +205269.0 20309.0 66026.0 53424.0 220020.0 246118.0 272421.0 4.221198e6 +205609.0 20421.0 66428.0 53647.0 222508.0 246286.0 278782.0 4.280922e6 +206242.0 20522.0 66662.0 53894.0 223072.0 246488.0 280610.0 4.345753e6 +206926.0 20618.0 67335.0 54237.0 224542.0 246776.0 282641.0 4.409882e6 +207828.0 20771.0 68006.0 54587.0 225936.0 247158.0 285430.0 4.479123e6 +208698.0 20873.0 68751.0 55021.0 227239.0 247537.0 288522.0 4.543699e6 +209653.0 21063.0 69402.0 55387.0 227301.0 247832.0 288522.0 4.601277e6 +209893.0 21186.0 69849.0 55780.0 227304.0 248070.0 288522.0 4.648386e6 +210402.0 21248.0 70314.0 56271.0 230665.0 248229.0 297054.0 4.69007e6 +211281.0 21318.0 70648.0 56705.0 231636.0 248419.0 302814.0 4.751727e6 +212022.0 21411.0 71158.0 57351.0 233344.0 248803.0 305767.0 4.806075e6 +213067.0 21494.0 72016.0 57984.0 234945.0 249204.0 309855.0 4.866254e6 +214214.0 21653.0 72784.0 58603.0 237332.0 249756.0 314362.0 4.926841e6 +215336.0 21772.0 73401.0 59294.0 237402.0 250103.0 314362.0 4.990774e6 +215891.0 21862.0 74152.0 59990.0 237408.0 250566.0 314362.0 5.045041e6 +216327.0 21966.0 74620.0 60288.0 242168.0 250825.0 322980.0 5.096658e6 +217293.0 22038.0 75008.0 61594.0 243576.0 251237.0 326612.0 5.153612e6 +218519.0 22196.0 75647.0 62295.0 246180.0 251713.0 329784.0 5.208856e6 +219964.0 22383.0 76191.0 63042.0 248850.0 252235.0 337334.0 5.260512e6 +221413.0 22573.0 77113.0 63782.0 251764.0 252809.0 342813.0 5.330637e6 +222828.0 22824.0 77869.0 64396.0 254974.0 253438.0 342813.0 5.383031e6 +223453.0 23173.0 78323.0 64950.0 257994.0 253915.0 342813.0 5.417693e6 +224014.0 23329.0 78534.0 65469.0 258629.0 254235.0 359082.0 5.455542e6 +225404.0 23498.0 78897.0 66112.0 260748.0 254636.0 364196.0 5.500444e6 +226914.0 23757.0 79479.0 66747.0 264535.0 255278.0 370867.0 5.546328e6 +228621.0 24009.0 80178.0 67378.0 269335.0 256118.0 377906.0 5.591456e6 +230048.0 24356.0 80894.0 67964.0 274289.0 257065.0 386054.0 5.639047e6 +232082.0 24687.0 81468.0 68508.0 277763.0 258136.0 386054.0 5.684719e6 +232864.0 24989.0 81936.0 69144.0 282498.0 259345.0 386054.0 5.71663e6 +233575.0 25218.0 82092.0 69639.0 284474.0 260298.0 405436.0 5.750553e6 +234853.0 25411.0 82447.0 70254.0 288067.0 261174.0 412553.0 5.793226e6 +236429.0 25654.0 83030.0 70892.0 288354.0 262540.0 419849.0 5.835299e6 +237936.0 25955.0 83500.0 71491.0 299580.0 263949.0 429507.0 5.885817e6 +239507.0 26274.0 83952.0 72058.0 307205.0 265409.0 439286.0 5.932287e6 +240986.0 26500.0 84599.0 72636.0 312665.0 266853.0 439286.0 5.97539e6 +241771.0 26894.0 85042.0 73206.0 318047.0 268218.0 439286.0 6.009521e6 +242381.0 27131.0 85236.0 73694.0 321160.0 269214.0 462858.0 6.042883e6 +243599.0 27354.0 85487.0 74536.0 326264.0 270189.0 470973.0 6.084862e6 +244855.0 27575.0 85911.0 75261.0 333351.0 271515.0 479554.0 6.124823e6 +246166.0 27861.0 86544.0 76100.0 340473.0 272912.0 488513.0 6.169964e6 +247619.0 28290.0 87174.0 76827.0 349333.0 274644.0 498989.0 6.218298e6 +248997.0 28656.0 87825.0 77832.0 357927.0 276338.0 498989.0 6.261921e6 +249985.0 29036.0 88367.0 78654.0 364943.0 277634.0 498989.0 6.29104e6 +250799.0 29253.0 88769.0 79666.0 369209.0 278784.0 525549.0 6.315603e6 +252298.0 29620.0 89141.0 80932.0 375947.0 280153.0 534513.0 6.342347e6 +253474.0 30016.0 89691.0 81908.0 384546.0 281583.0 543379.0 6.375987e6 +255366.0 30568.0 90568.0 83286.0 394308.0 283180.0 554143.0 6.415435e6 +256850.0 31259.0 91537.0 84601.0 403837.0 284796.0 566326.0 6.460058e6 +258480.0 31857.0 92478.0 85796.0 415174.0 286297.0 566326.0 6.505641e6 +259428.0 32787.0 93455.0 87176.0 421519.0 287753.0 566326.0 6.545932e6 +260355.0 33202.0 94306.0 88573.0 427839.0 288761.0 593730.0 6.578496e6 +261762.0 33616.0 94795.0 90215.0 435665.0 289990.0 603167.0 6.615674e6 +263663.0 34436.0 95948.0 92178.0 445932.0 291442.0 614360.0 6.653966e6 +265857.0 35159.0 97976.0 94236.0 456171.0 293025.0 625651.0 6.699284e6 +267773.0 36013.0 99649.0 96232.0 469404.0 294932.0 640040.0 6.749468e6 +270070.0 36819.0 100748.0 98105.0 482964.0 296569.0 640040.0 6.795246e6 +271415.0 37693.0 102295.0 100434.0 493500.0 298156.0 640040.0 6.836856e6 +272337.0 38360.0 103392.0 102736.0 499039.0 299506.0 671468.0 6.868899e6 +274158.0 38831.0 105226.0 105201.0 509123.0 300897.0 682267.0 6.90717e6 +275927.0 39413.0 106887.0 107848.0 522355.0 302537.0 693556.0 6.94829e6 +278070.0 40132.0 108768.0 110676.0 538264.0 304323.0 704209.0 6.997173e6 +280223.0 40936.0 110976.0 113471.0 554368.0 306235.0 716481.0 7.044309e6 +282730.0 41593.0 112803.0 116513.0 568588.0 308104.0 716481.0 7.087856e6 +284140.0 42356.0 114179.0 119473.0 579223.0 309870.0 716481.0 7.121635e6 +285332.0 42947.0 115353.0 122520.0 583522.0 311364.0 748266.0 7.159375e6 +287421.0 43492.0 117115.0 125914.0 591527.0 313011.0 748266.0 7.201407e6 +289219.0 44231.0 118452.0 129240.0 605893.0 314861.0 769188.0 7.240039e6 +291722.0 44990.0 121059.0 133108.0 618918.0 317409.0 778607.0 7.286282e6 +294395.0 45844.0 124234.0 137133.0 631354.0 319908.0 789932.0 7.339725e6 +296958.0 46634.0 127623.0 141197.0 647868.0 322751.0 789932.0 7.389006e6 +299237.0 47648.0 130235.0 145805.0 660372.0 325329.0 789932.0 7.422136e6 +300619.0 48366.0 132203.0 150365.0 666011.0 327586.0 813412.0 7.459493e6 +303258.0 49103.0 134291.0 155402.0 677321.0 330263.0 825410.0 7.504039e6 +306086.0 50030.0 137868.0 161287.0 696274.0 333940.0 835901.0 7.553176e6 +310144.0 51108.0 143596.0 167303.0 713676.0 338398.0 848324.0 7.611066e6 +314660.0 52382.0 148981.0 173847.0 734707.0 343770.0 861112.0 7.666145e6 +319381.0 53492.0 156931.0 180267.0 761384.0 349494.0 861112.0 7.721512e6 +322864.0 54752.0 162258.0 187133.0 777378.0 354950.0 861112.0 7.768412e6 +325331.0 55766.0 165880.0 194516.0 786590.0 359569.0 888968.0 7.810492e6 +329453.0 56596.0 173240.0 201878.0 800216.0 365467.0 896086.0 7.860615e6 +334585.0 57739.0 181511.0 209733.0 823181.0 372799.0 908056.0 7.919057e6 +341223.0 59060.0 191959.0 217783.0 852938.0 381602.0 921374.0 7.982595e6 +348557.0 60495.0 202151.0 225935.0 878572.0 391611.0 936560.0 8.052769e6 +356387.0 62017.0 213115.0 234152.0 910711.0 402536.0 936560.0 8.107601e6 +361974.0 63812.0 222253.0 242195.0 940548.0 414241.0 936560.0 8.159771e6 +366299.0 65297.0 230480.0 250382.0 954838.0 423578.0 974449.0 8.227653e6 +373167.0 66496.0 240159.0 259154.0 975214.0 434449.0 988322.0 8.28939e6 +380762.0 68142.0 253386.0 268478.0 1.002624e6 449648.0 1.005295e6 8.350096e6 +392049.0 70120.0 270132.0 278513.0 1.043437e6 465726.0 1.026281e6 8.429717e6 +403291.0 72774.0 287700.0 287197.0 1.086286e6 484869.0 1.046132e6 8.511376e6 +418005.0 76005.0 305409.0 297431.0 1.131551e6 504509.0 1.046132e6 8.589751e6 +429181.0 79352.0 321031.0 307809.0 1.138167e6 525782.0 1.046132e6 8.650726e6 +437866.0 82322.0 333718.0 318123.0 1.211177e6 542789.0 1.09832e6 8.71529e6 +449275.0 84796.0 347289.0 326254.0 1.245635e6 564778.0 1.116738e6 8.792513e6 +464239.0 87578.0 368337.0 336572.0 1.283185e6 589766.0 1.136503e6 8.87899e6 +481013.0 91951.0 392258.0 347748.0 1.329821e6 616595.0 1.160083e6 8.970283e6 +499694.0 96420.0 412314.0 357605.0 1.379295e6 647674.0 1.185678e6 9.07013e6 +518753.0 101467.0 429229.0 366323.0 1.414396e6 679430.0 1.185678e6 9.157473e6 +532930.0 107182.0 441018.0 374637.0 1.460575e6 709335.0 1.185678e6 9.235303e6 +545027.0 111972.0 447355.0 382406.0 1.566666e6 731588.0 1.240697e6 9.317109e6 +560379.0 116451.0 452541.0 390073.0 1.639267e6 759829.0 1.259366e6 9.441875e6 +577593.0 121643.0 468213.0 397085.0 1.593146e6 790377.0 1.284408e6 9.542136e6 +597583.0 128005.0 479341.0 404354.0 1.650966e6 824879.0 1.306316e6 9.670217e6 +619089.0 135116.0 488044.0 411063.0 1.711918e6 862681.0 1.328832e6 9.797272e6 +642488.0 142069.0 494168.0 416771.0 1.798573e6 902490.0 1.328832e6 9.924336e6 +658505.0 150159.0 500789.0 421486.0 1.837135e6 935104.0 1.328832e6 1.0044009e7 +671868.0 155484.0 503182.0 426170.0 1.858559e6 960373.0 1.381218e6 1.0160964e7 +687200.0 161228.0 507475.0 431634.0 1.881172e6 995463.0 1.381218e6 1.0297518e7 +705687.0 167475.0 515391.0 437330.0 1.917578e6 1.028424e6 1.417709e6 1.04452e7 +727553.0 174910.0 520393.0 443467.0 1.950136e6 1.066401e6 1.43722e6 1.0603995e7 +751095.0 184087.0 525012.0 449447.0 1.974271e6 1.107303e6 1.458591e6 1.0783514e7 +773556.0 192344.0 531280.0 454914.0 2.006228e6 1.144552e6 1.458591e6 1.0947564e7 +790503.0 199362.0 535939.0 459791.0 2.03342e6 1.178529e6 1.458591e6 1.1087279e7 +801327.0 204460.0 537871.0 464139.0 2.04347e6 1.205881e6 1.496864e6 1.1240367e7 +815746.0 209072.0 540605.0 468814.0 2.089073e6 1.238072e6 1.510023e6 1.1405015e7 +833307.0 215147.0 545787.0 474545.0 2.117917e6 1.272352e6 1.525341e6 1.1576984e7 +855916.0 222669.0 550264.0 480574.0 2.138706e6 1.308528e6 1.541574e6 1.1769284e7 +879564.0 229103.0 553680.0 486719.0 2.16197e6 1.345767e6 1.55673e6 1.1970952e7 +902528.0 235710.0 556904.0 492208.0 2.17964e6 1.380531e6 1.55673e6 1.2150771e7 +918269.0 242175.0 558779.0 497463.0 2.19277e6 1.408868e6 1.55673e6 1.2297358e7 +929133.0 247329.0 559902.0 501427.0 2.197832e6 1.431795e6 1.582616e6 1.2478869e7 +942687.0 249765.0 561803.0 506412.0 2.207753e6 1.455022e6 1.594844e6 1.2652431e7 +961320.0 254373.0 564967.0 511027.0 2.224508e6 1.480874e6 1.605066e6 1.2832643e7 +983588.0 260116.0 567532.0 516905.0 2.237509e6 1.509875e6 1.617355e6 1.2949892e7 +1.006394e6 265507.0 570829.0 521504.0 2.250283e6 1.538217e6 1.628208e6 1.3164526e7 +1.028089e6 270525.0 574448.0 527224.0 2.26276e6 1.564532e6 1.628208e6 1.333275e7 +1.0427e6 274763.0 576599.0 531904.0 2.272523e6 1.585178e6 1.628208e6 1.3473101e7 +1.053869e6 278500.0 577345.0 535975.0 2.27683e6 1.601554e6 1.648187e6 1.3628015e7 +1.067473e6 280891.0 579212.0 541050.0 2.285273e6 1.620901e6 1.656444e6 1.3825131e7 +1.084743e6 284266.0 582252.0 546844.0 2.299501e6 1.64161e6 1.665775e6 1.4021291e7 +1.106789e6 288203.0 584857.0 552856.0 2.312288e6 1.664829e6 1.675902e6 1.424151e7 +1.130238e6 291771.0 587439.0 559561.0 2.323799e6 1.688939e6 1.684647e6 1.4476879e7 +1.153556e6 295427.0 589942.0 566495.0 2.336681e6 1.709991e6 1.684647e6 1.4698887e7 +1.171323e6 299018.0 591756.0 573695.0 2.34763e6 1.728878e6 1.684647e6 1.4878212e7 +1.183655e6 301883.0 592615.0 579896.0 2.351041e6 1.742557e6 1.702328e6 1.5073671e7 +1.197709e6 303950.0 594572.0 586525.0 2.365085e6 1.757394e6 1.702328e6 1.5300726e7 +1.218524e6 306462.0 597643.0 595363.0 2.37976e6 1.770149e6 1.712101e6 1.5516732e7 +1.242203e6 309094.0 600397.0 604311.0 2.393632e6 1.787147e6 1.720056e6 1.5753677e7 +1.272078e6 311574.0 600397.0 613532.0 2.407121e6 1.805873e6 1.730575e6 1.5992578e7 +1.300516e6 314664.0 603159.0 623514.0 2.421068e6 1.825775e6 1.730575e6 1.6217115e7 +1.320716e6 317499.0 608137.0 632024.0 2.432601e6 1.843712e6 1.730575e6 1.6408708e7 +1.337078e6 320135.0 609211.0 638718.0 2.435793e6 1.855737e6 1.751884e6 1.6618531e7 +1.35151e6 322641.0 611422.0 649970.0 2.447518e6 1.870576e6 1.762212e6 1.6844844e7 +1.379238e6 325384.0 615058.0 662851.0 2.465238e6 1.888144e6 1.77329e6 1.7079647e7 +1.406161e6 328142.0 618204.0 674874.0 2.483636e6 1.906377e6 1.785421e6 1.7319893e7 +1.439938e6 330531.0 621039.0 687184.0 2.499511e6 1.921778e6 1.797236e6 1.7567839e7 +1.471238e6 332481.0 623760.0 700282.0 2.516939e6 1.938083e6 1.797236e6 1.7773691e7 +1.494009e6 334632.0 625930.0 711490.0 2.529797e6 1.953185e6 1.797236e6 1.7960885e7 +1.510652e6 336137.0 626911.0 721350.0 2.535757e6 1.964054e6 1.819249e6 1.8157739e7 +1.53018e6 337490.0 629109.0 731817.0 2.547618e6 1.97737e6 1.829903e6 1.836367e7 +1.55492e6 339597.0 632321.0 743401.0 2.562604e6 1.991278e6 1.842289e6 1.8585107e7 +1.587115e6 342155.0 634904.0 754980.0 2.584322e6 2.009317e6 1.854951e6 1.8798055e7 +1.612648e6 345010.0 637246.0 764886.0 2.604584e6 2.028354e6 1.854951e6 1.8925234e7 +1.627103e6 346816.0 638030.0 773987.0 2.607677e6 2.038759e6 1.854951e6 1.9142672e7 +1.640858e6 348103.0 638877.0 781424.0 2.616544e6 2.047696e6 1.854951e6 1.9278635e7 +1.651834e6 349266.0 639734.0 788969.0 2.61965e6 2.056277e6 1.879413e6 1.9451935e7 +1.664726e6 350963.0 641411.0 798457.0 2.631144e6 2.067487e6 1.893502e6 1.9657909e7 +1.687185e6 353088.0 644242.0 808273.0 2.657658e6 2.083689e6 1.910218e6 1.9876203e7 +1.719737e6 356063.0 646496.0 816565.0 2.67766e6 2.107166e6 1.928265e6 2.0191291e7 +1.742661e6 358774.0 648289.0 825217.0 2.697018e6 2.129376e6 1.928265e6 2.0370188e7 +1.755351e6 360777.0 649169.0 832647.0 2.700484e6 2.141201e6 1.928265e6 2.0642467e7 +1.765666e6 362368.0 650011.0 839265.0 2.712975e6 2.155446e6 1.928265e6 2.0845869e7 +1.775513e6 364003.0 650887.0 845654.0 2.717059e6 2.166244e6 1.958844e6 2.1031371e7 +1.78741e6 365898.0 652735.0 852921.0 2.737892e6 2.181619e6 1.982544e6 2.1264231e7 +1.808647e6 368190.0 655732.0 862687.0 2.763078e6 2.201945e6 1.982544e6 2.1523991e7 +1.835038e6 371151.0 658655.0 870929.0 2.784845e6 2.220361e6 2.024904e6 2.1810234e7 +1.866887e6 373237.0 660703.0 878384.0 2.804705e6 2.23789e6 2.05036e6 2.2114297e7 +1.891581e6 375239.0 662694.0 885055.0 2.824882e6 2.257866e6 2.05036e6 2.2379028e7 +1.908527e6 377537.0 664263.0 890514.0 2.840826e6 2.276491e6 2.05036e6 2.258987e7 +1.921024e6 379083.0 665223.0 895438.0 2.844642e6 2.289021e6 2.111782e6 2.2793833e7 +1.933826e6 380470.0 667322.0 901629.0 2.864399e6 2.303263e6 2.13722e6 2.3015647e7 +1.953426e6 382176.0 670249.0 908206.0 2.888331e6 2.319036e6 2.176089e6 2.3244979e7 +1.97859e6 384337.0 672886.0 914315.0 2.909666e6 2.336279e6 2.211967e6 2.3480551e7 +2.000958e6 385993.0 675089.0 919648.0 2.930983e6 2.352423e6 2.252164e6 2.3725554e7 +2.019636e6 387529.0 677209.0 925310.0 2.952392e6 2.368733e6 2.252164e6 2.3943244e7 +2.033518e6 389086.0 678839.0 930109.0 2.969034e6 2.381277e6 2.252164e6 2.4119799e7 +2.040659e6 390406.0 679771.0 934419.0 2.972832e6 2.390102e6 2.336451e6 2.4260622e7 +2.052028e6 391416.0 681250.0 940033.0 2.996855e6 2.400598e6 2.370742e6 2.441751e7 +2.068002e6 393047.0 684256.0 945880.0 3.023613e6 2.414166e6 2.412318e6 2.460489e7 +2.0884e6 394704.0 686827.0 951692.0 3.046323e6 2.428221e6 2.456675e6 2.4797441e7 +2.106262e6 396446.0 689271.0 957161.0 3.069647e6 2.441854e6 2.49956e6 2.4989209e7 +2.122679e6 398234.0 691854.0 962104.0 3.09374e6 2.455185e6 2.49956e6 2.5167382e7 +2.134936e6 399687.0 693666.0 966170.0 3.112176e6 2.466813e6 2.49956e6 2.5307525e7 +2.141665e6 400949.0 694858.0 970111.0 3.116477e6 2.475372e6 2.593382e6 2.5437124e7 +2.148077e6 401896.0 696642.0 974882.0 3.138619e6 2.485956e6 2.629817e6 2.558813e7 +2.161275e6 403321.0 699662.0 979631.0 3.16557e6 2.501147e6 2.670102e6 2.5743586e7 +2.178828e6 404906.0 702437.0 984052.0 3.189378e6 2.515507e6 2.705001e6 2.5910345e7 +2.19285e6 406378.0 705120.0 988293.0 3.212613e6 2.52907e6 2.743119e6 2.6074086e7 +2.205171e6 407799.0 707837.0 992050.0 3.236658e6 2.541783e6 2.743119e6 2.6225025e7 +2.216363e6 409286.0 710153.0 995263.0 3.255994e6 2.553032e6 2.743119e6 2.6337882e7 +2.221971e6 410385.0 711417.0 998861.0 3.260382e6 2.560957e6 2.822805e6 2.6463196e7 +2.228085e6 411519.0 713271.0 1.002937e6 3.283719e6 2.570608e6 2.851869e6 2.6580226e7 +2.23779e6 412737.0 716395.0 1.007203e6 3.310125e6 2.58379e6 2.883465e6 2.6704596e7 +2.252001e6 414380.0 718847.0 1.011589e6 3.310145e6 2.597446e6 2.913425e6 2.6829625e7 +2.264909e6 415900.0 721432.0 1.015711e6 3.355752e6 2.611659e6 2.94199e6 2.6960734e7 +2.275394e6 417170.0 723870.0 1.019691e6 3.37634e6 2.625098e6 2.94199e6 2.7077591e7 +2.28401e6 418535.0 725610.0 1.021941e6 3.396055e6 2.636738e6 2.94199e6 2.7167019e7 +2.288545e6 419681.0 726483.0 1.02371e6 3.400398e6 2.644707e6 2.989085e6 2.7249817e7 +2.291924e6 420680.0 728334.0 1.026962e6 3.419418e6 2.655319e6 3.005487e6 2.7345198e7 +2.299996e6 421912.0 730951.0 1.031417e6 3.444827e6 2.668266e6 3.023601e6 2.7440479e7 +2.310233e6 423382.0 733100.0 1.035795e6 3.465903e6 2.683403e6 3.041454e6 2.754725e7 +2.320093e6 425050.0 735220.0 1.040035e6 3.486612e6 2.697296e6 3.056035e6 2.764783e7 +2.328447e6 426613.0 737115.0 1.043517e6 3.507843e6 2.710819e6 3.056035e6 2.7738586e7 +2.334561e6 427881.0 738631.0 1.046351e6 3.524518e6 2.721879e6 3.056035e6 2.7806894e7 +2.338987e6 429052.0 739488.0 1.049082e6 3.528924e6 2.729223e6 3.086286e6 2.7862342e7 +2.342843e6 430220.0 741205.0 1.052481e6 3.54852e6 2.739591e6 3.096343e6 2.7921563e7 +2.350399e6 431720.0 743882.0 1.057062e6 3.57356e6 2.751657e6 3.107172e6 2.7990409e7 +2.360606e6 433377.0 746302.0 1.061842e6 3.596078e6 2.765412e6 3.121687e6 2.8062989e7 +2.369719e6 435277.0 749739.0 1.066468e6 3.620205e6 2.780882e6 3.133122e6 2.8138147e7 +2.378883e6 436985.0 752379.0 1.071196e6 3.642576e6 2.795796e6 3.133122e6 2.8211929e7 +2.386559e6 439078.0 754473.0 1.075385e6 3.664622e6 2.809246e6 3.133122e6 2.8267194e7 +2.390928e6 440734.0 755594.0 1.079222e6 3.669276e6 2.818863e6 3.153971e6 2.8322676e7 +2.394811e6 441959.0 757696.0 1.083634e6 3.689469e6 2.832162e6 3.161432e6 2.8396535e7 +2.402818e6 443849.0 760809.0 1.088697e6 3.720996e6 2.848564e6 3.170644e6 2.847156e7 +2.414687e6 445816.0 763885.0 1.093843e6 3.74641e6 2.868435e6 3.180212e6 2.8548839e7 +2.424684e6 448261.0 766654.0 1.098836e6 3.771626e6 2.888923e6 3.188553e6 2.8624257e7 +2.434446e6 450150.0 769414.0 1.103544e6 3.795736e6 2.907825e6 3.188553e6 2.8695545e7 +2.442336e6 452646.0 771511.0 1.107326e6 3.815688e6 2.925265e6 3.188553e6 2.8747309e7 +2.447068e6 454870.0 772294.0 1.111328e6 3.820418e6 2.938371e6 3.204531e6 2.8797749e7 +2.451011e6 456271.0 774344.0 1.116361e6 3.84329e6 2.955434e6 3.130184e6 2.8856167e7 +2.46003e6 458463.0 777608.0 1.120518e6 3.870101e6 2.976274e6 3.136321e6 2.8923217e7 +2.471942e6 460915.0 780251.0 1.125235e6 3.895387e6 2.999119e6 3.142358e6 2.8992158e7 +2.482522e6 463314.0 783010.0 1.130635e6 3.918894e6 3.023129e6 3.149012e6 2.9060036e7 +2.492079e6 465664.0 785809.0 1.13522e6 3.942286e6 3.046762e6 3.149012e6 2.9121065e7 +2.500182e6 468427.0 787891.0 1.139092e6 3.964121e6 3.067486e6 3.149012e6 2.9162675e7 +2.505193e6 470672.0 789008.0 1.143395e6 3.969673e6 3.081368e6 3.16097e6 2.9206765e7 +2.509445e6 472620.0 791171.0 1.148753e6 3.992853e6 3.101093e6 3.164982e6 2.9262267e7 +2.518591e6 475142.0 794605.0 1.154158e6 4.022514e6 3.123368e6 3.172101e6 2.932004e7 +2.532947e6 477553.0 798108.0 1.160283e6 4.050606e6 3.149017e6 3.178356e6 2.9381828e7 +2.545781e6 480424.0 801723.0 1.166776e6 4.075681e6 3.175807e6 3.183704e6 2.9444429e7 +2.558455e6 483479.0 805321.0 1.172897e6 4.105444e6 3.201838e6 3.183704e6 2.9501249e7 +2.569245e6 486513.0 808283.0 1.178444e6 4.131895e6 3.223142e6 3.183704e6 2.9540523e7 +2.575849e6 489038.0 809861.0 1.183403e6 4.138369e6 3.238394e6 3.195062e6 2.9591555e7 +2.581329e6 490946.0 813026.0 1.189491e6 4.168396e6 3.25877e6 3.200024e6 2.9645622e7 +2.594764e6 493705.0 818142.0 1.195832e6 4.206916e6 3.28181e6 3.206116e6 2.9704896e7 +2.612268e6 496577.0 822801.0 1.20342e6 4.24199e6 3.306711e6 3.212332e6 2.9767286e7 +2.62975e6 500098.0 827941.0 1.211215e6 4.277108e6 3.332418e6 3.212332e6 2.9828918e7 +2.645783e6 503319.0 827941.0 1.218412e6 4.312451e6 3.356331e6 3.212332e6 2.9887785e7 +2.659516e6 506969.0 837006.0 1.224871e6 4.343115e6 3.376376e6 3.212332e6 2.9923163e7 +2.667225e6 509659.0 839238.0 1.230507e6 4.358924e6 3.400877e6 3.228803e6 2.9970587e7 +2.67471e6 512098.0 842775.0 1.238325e6 4.37362e6 3.419616e6 3.234319e6 3.0023445e7 +2.690523e6 515121.0 849090.0 1.246366e6 4.439011e6 3.440862e6 3.234319e6 3.0111203e7 +2.71318e6 518660.0 854608.0 1.254244e6 4.484672e6 3.464543e6 3.247738e6 3.0178829e7 +2.734753e6 522107.0 860731.0 1.26352e6 4.526554e6 3.488619e6 3.255324e6 3.0255199e7 +2.755225e6 525323.0 866063.0 1.271312e6 4.569179e6 3.512453e6 3.255324e6 3.0319254e7 +2.772401e6 528627.0 870757.0 1.278298e6 4.606307e6 3.532057e6 3.255324e6 3.0365574e7 +2.782273e6 531273.0 872936.0 1.284347e6 4.615413e6 3.544957e6 3.270825e6 3.0431446e7 +2.791822e6 534505.0 876842.0 1.292218e6 4.646136e6 3.561012e6 3.275819e6 3.0493135e7 +2.808873e6 537302.0 882453.0 1.300633e6 4.705186e6 3.584899e6 3.284353e6 3.0562665e7 +2.833173e6 540438.0 887920.0 1.30838e6 4.755862e6 3.607083e6 3.291394e6 3.0639521e7 +2.855061e6 543831.0 892585.0 1.316402e6 4.802545e6 3.629e6 3.291394e6 3.0713544e7 +2.87319e6 546926.0 897474.0 1.323735e6 4.802711e6 3.650247e6 3.300965e6 3.0778424e7 +2.885386e6 550234.0 900996.0 1.329341e6 4.883346e6 3.668264e6 3.300965e6 3.0816347e7 +2.893883e6 553053.0 902964.0 1.335101e6 4.894139e6 3.678944e6 3.311325e6 3.0883434e7 +2.900768e6 555386.0 904673.0 1.341658e6 4.902195e6 3.686707e6 3.317948e6 3.094626e7 +2.910445e6 557395.0 908212.0 1.349525e6 4.903122e6 3.700393e6 3.326736e6 3.1022036e7 +2.930852e6 560245.0 913057.0 1.357669e6 5.000155e6 3.717602e6 3.336637e6 3.1102102e7 +2.956316e6 563116.0 917917.0 1.365692e6 5.000319e6 3.736526e6 3.347512e6 3.1186855e7 +2.980413e6 565625.0 922487.0 1.374242e6 5.001723e6 3.754077e6 3.347512e6 3.125739e7 +2.998268e6 569084.0 925476.0 1.381126e6 5.119625e6 3.769814e6 3.347512e6 3.1304846e7 +3.011513e6 571051.0 927229.0 1.387867e6 5.128175e6 3.779594e6 3.370256e6 3.1367029e7 +3.022323e6 573108.0 930603.0 1.393347e6 5.167305e6 3.793033e6 3.376548e6 3.1447868e7 +3.044016e6 575350.0 935316.0 1.402277e6 5.210812e6 3.809193e6 3.387022e6 3.1523472e7 +3.073442e6 578529.0 939309.0 1.411331e6 5.248857e6 3.826156e6 3.396685e6 3.1597454e7 +3.099273e6 581266.0 943213.0 1.419759e6 5.285307e6 3.842079e6 3.407283e6 3.1680926e7 +3.123077e6 583622.0 947000.0 1.428376e6 5.32118e6 3.857443e6 3.407283e6 3.1736413e7 +3.142262e6 585988.0 949996.0 1.435557e6 5.350558e6 3.870131e6 3.407283e6 3.1780239e7 +3.153699e6 588021.0 951626.0 1.442423e6 5.357266e6 3.878994e6 3.428354e6 3.1838785e7 +3.163308e6 590036.0 955056.0 1.450952e6 5.401341e6 3.891063e6 3.428354e6 3.1901225e7 +3.188192e6 592128.0 960169.0 1.460682e6 5.436265e6 3.904899e6 3.446072e6 3.1965571e7 +3.21771e6 594659.0 964526.0 1.469963e6 5.469669e6 3.920945e6 3.456886e6 3.203229e7 +3.245253e6 597277.0 968107.0 1.478097e6 5.502009e6 3.935703e6 3.468617e6 3.2095185e7 +3.268645e6 599761.0 972041.0 1.486157e6 5.534651e6 3.949517e6 3.468617e6 3.2150156e7 +3.287418e6 601733.0 974418.0 1.492405e6 5.559156e6 3.962674e6 3.468617e6 3.2184924e7 +3.299325e6 603631.0 976088.0 1.497774e6 5.565113e6 3.971114e6 3.488469e6 3.2227211e7 +3.310301e6 605223.0 979034.0 1.506455e6 5.595437e6 3.981512e6 3.496134e6 3.2279492e7 +3.332532e6 607140.0 982959.0 1.513747e6 5.626979e6 3.994894e6 3.504799e6 3.2334678e7 +3.357268e6 609412.0 986622.0 1.522923e6 5.653526e6 4.009208e6 3.514942e6 3.2393504e7 +3.381597e6 611569.0 990229.0 1.528728e6 5.677829e6 4.022653e6 3.524077e6 3.2451606e7 +3.400532e6 613688.0 993434.0 1.534261e6 5.703499e6 4.035617e6 3.524077e6 3.2500382e7 +3.416822e6 615355.0 995562.0 1.543451e6 5.71342e6 4.044762e6 3.524077e6 3.2530938e7 +3.425982e6 616895.0 996896.0 1.551219e6 5.717187e6 4.050708e6 3.54043e6 3.257556e7 +3.433516e6 618004.0 999627.0 1.558521e6 5.741564e6 4.059821e6 3.544945e6 3.2618455e7 +3.45155e6 619452.0 1.003746e6 1.565338e6 5.767568e6 4.0704e6 3.551262e6 3.2664498e7 +3.473503e6 621178.0 1.007264e6 1.572833e6 5.789281e6 4.082198e6 3.559222e6 3.2710677e7 +3.491988e6 622573.0 1.010987e6 1.58026e6 5.80842e6 4.092747e6 3.567408e6 3.2759092e7 +3.507673e6 623958.0 1.014351e6 1.586853e6 5.829199e6 4.102921e6 3.567408e6 3.2794746e7 +3.520329e6 625114.0 1.016609e6 1.592726e6 5.838327e6 4.11121e6 3.567408e6 3.2817616e7 +3.527251e6 626174.0 1.017876e6 1.59826e6 5.841626e6 4.116287e6 3.581392e6 3.2849992e7 +3.533376e6 626919.0 1.020332e6 1.604636e6 5.861417e6 4.12323e6 3.586333e6 3.2885469e7 +3.548285e6 627847.0 1.023583e6 1.610672e6 5.882915e6 4.131078e6 3.592751e6 3.292162e7 +3.565704e6 629005.0 1.026473e6 1.616214e6 5.902376e6 4.13916e6 3.598452e6 3.2960356e7 +3.57704e6 630002.0 1.028104e6 1.62068e6 5.909419e6 4.146722e6 3.604799e6 3.3002573e7 +3.584934e6 630854.0 1.030071e6 1.625138e6 5.925104e6 4.153374e6 3.604799e6 3.303333e7 +3.593434e6 631491.0 1.031923e6 1.62798e6 5.93913e6 4.159122e6 3.604799e6 3.3051022e7 +3.598846e6 632174.0 1.032895e6 1.633323e6 5.942481e6 4.162576e6 3.61586e6 3.3076264e7 +3.603055e6 632695.0 1.034714e6 1.637905e6 5.959704e6 4.167025e6 3.619848e6 3.3105179e7 +3.614095e6 633334.0 1.038514e6 1.642572e6 5.978761e6 4.172525e6 3.625928e6 3.3134783e7 +3.626393e6 634179.0 1.041706e6 1.646758e6 5.629921e6 4.178261e6 3.631661e6 3.3164998e7 +3.635162e6 634789.0 1.044612e6 1.649943e6 5.642724e6 4.183476e6 3.636453e6 3.3193823e7 +3.642244e6 635450.0 1.047128e6 1.653382e6 5.655335e6 4.18819e6 3.636453e6 3.3215036e7 +3.648958e6 636019.0 1.048881e6 1.656085e6 5.665101e6 4.192183e6 3.636453e6 3.3228821e7 +3.65164e6 636528.0 1.049822e6 1.658552e6 5.667331e6 4.194672e6 3.64752e6 3.3250692e7 +3.653551e6 636877.0 1.050677e6 1.661341e6 5.670486e6 4.197892e6 3.652879e6 3.3275282e7 +3.656177e6 637284.0 1.052652e6 1.664692e6 5.683143e6 4.201827e6 3.657886e6 3.3299878e7 +3.66249e6 637769.0 1.055543e6 1.66856e6 5.697076e6 4.20597e6 3.663176e6 3.3326719e7 +3.66987e6 638376.0 1.057903e6 1.671962e6 5.70835e6 4.209707e6 3.668658e6 3.3348961e7 +3.675296e6 638913.0 1.059763e6 1.674686e6 5.719877e6 4.213055e6 3.668658e6 3.3362272e7 +3.679148e6 639337.0 1.0612e6 1.676736e6 5.728539e6 4.216003e6 3.668658e6 3.3369626e7 +3.681126e6 639722.0 1.062001e6 1.679064e6 5.728909e6 4.217821e6 3.67839e6 3.33759e7 +3.682911e6 640050.0 1.063499e6 1.681595e6 5.738762e6 4.220304e6 3.682778e6 3.3396753e7 +3.687828e6 640410.0 1.065358e6 1.684344e6 5.740116e6 4.2232e6 3.687762e6 3.3413465e7 +3.692468e6 640899.0 1.066957e6 1.686756e6 5.755675e6 4.225163e6 3.693012e6 3.3431861e7 +3.695633e6 641204.0 1.068406e6 1.688899e6 5.762633e6 4.227719e6 3.697981e6 3.3449726e7 +3.697927e6 641555.0 1.069874e6 1.690455e6 5.769287e6 4.230153e6 3.697981e6 3.346533e7 +3.700367e6 641839.0 1.070802e6 1.691858e6 5.774467e6 4.232428e6 3.697981e6 3.3471346e7 +3.701484e6 642165.0 1.071271e6 1.693285e6 5.775641e6 4.233698e6 3.707523e6 3.3485416e7 +3.702688e6 642476.0 1.072175e6 1.695016e6 5.781662e6 4.235592e6 3.711027e6 3.3498456e7 +3.705942e6 642783.0 1.073358e6 1.696595e6 5.787231e6 4.23779e6 3.715454e6 3.3517021e7 +3.709129e6 643139.0 1.074204e6 1.697986e6 5.791714e6 4.239868e6 3.729458e6 3.3531802e7 +3.711569e6 643426.0 1.074988e6 1.699204e6 5.795593e6 4.24176e6 3.7336e6 3.3556953e7 +3.71348e6 643653.0 1.075765e6 1.700254e6 5.799565e6 4.243482e6 3.7336e6 3.3566113e7 +3.714969e6 643851.0 1.076338e6 1.701112e6 5.802538e6 4.244872e6 3.7336e6 3.3571383e7 +3.715518e6 644058.0 1.076579e6 1.702156e6 5.803236e6 4.245779e6 3.741767e6 3.3583169e7 +3.71617e6 644161.0 1.077087e6 1.70319e6 5.806479e6 4.247032e6 3.745199e6 3.3593899e7 +3.717625e6 644308.0 1.077758e6 1.704282e6 5.809543e6 4.248432e6 3.749031e6 3.3605807e7 +3.718955e6 644488.0 1.078251e6 1.705193e6 5.811592e6 4.249755e6 3.753228e6 3.361757e7 +3.720031e6 644659.0 1.078251e6 1.705892e6 5.814779e6 4.250902e6 3.757442e6 3.3638752e7 +3.721139e6 644790.0 1.079084e6 1.706606e6 5.817403e6 4.252095e6 3.757442e6 3.3647804e7 +3.721981e6 644939.0 1.079415e6 1.70717e6 5.819313e6 4.252976e6 3.757442e6 3.3652761e7 +3.722327e6 645047.0 1.07964e6 1.707867e6 5.819809e6 4.25346e6 3.764651e6 3.3663316e7 +3.722782e6 645162.0 1.080035e6 1.708533e6 5.822022e6 4.254294e6 3.768691e6 3.3674112e7 +3.723798e6 645264.0 1.081061e6 1.709239e6 5.824352e6 4.255434e6 3.773032e6 3.3686777e7 +3.724806e6 645380.0 1.081908e6 1.709902e6 5.82636e6 4.2557e6 3.777539e6 3.3701253e7 +3.72558e6 645479.0 1.082476e6 1.710463e6 5.828348e6 4.256451e6 3.782463e6 3.3725855e7 +3.726172e6 645587.0 1.082476e6 1.710972e6 5.830476e6 4.257289e6 3.782463e6 3.3735224e7 +3.72671e6 645704.0 1.082476e6 1.71153e6 5.83211e6 4.258069e6 3.782463e6 3.3739848e7 +3.726929e6 645770.0 1.083478e6 1.712083e6 5.832628e6 4.258456e6 3.792642e6 3.3753431e7 +3.727333e6 645843.0 1.08455e6 1.712734e6 5.836023e6 4.259133e6 3.799733e6 3.3760908e7 +3.728141e6 645936.0 1.085131e6 1.713572e6 5.837403e6 4.259909e6 3.80896e6 3.377626e7 +3.729033e6 646042.0 1.085885e6 1.714517e6 5.840067e6 4.260788e6 3.821305e6 3.3791379e7 +3.729682e6 646122.0 1.086508e6 1.715649e6 5.842754e6 4.261582e6 3.833868e6 3.3821136e7 +3.730353e6 646230.0 1.086508e6 1.71687e6 5.84576e6 4.262511e6 3.833868e6 3.382655e7 +3.730912e6 646334.0 1.086508e6 1.718389e6 5.848365e6 4.263317e6 3.833868e6 3.3830834e7 +3.731124e6 646402.0 1.088363e6 1.720606e6 5.849167e6 4.263797e6 3.866475e6 3.3839736e7 +3.731564e6 646475.0 1.089105e6 1.724256e6 5.852755e6 4.264704e6 3.880612e6 3.3862018e7 +3.732549e6 646578.0 1.091095e6 1.729693e6 5.856838e6 4.265714e6 3.897996e6 3.3882196e7 +3.733519e6 646705.0 1.092477e6 1.736632e6 5.861284e6 4.267105e6 3.915313e6 3.3903061e7 +3.734468e6 646853.0 1.0937e6 1.746949e6 5.865864e6 4.268491e6 3.937192e6 3.3950654e7 +3.73542e6 647052.0 1.0937e6 1.756283e6 5.87056e6 4.269885e6 3.937192e6 3.3960773e7 +3.736165e6 647230.0 1.0937e6 1.764734e6 5.874874e6 4.271276e6 3.937192e6 3.397252e7 +3.736489e6 647384.0 1.097029e6 1.772565e6 5.876142e6 4.272163e6 3.971124e6 3.4001942e7 +3.737135e6 647568.0 1.098332e6 1.783035e6 5.8831e6 4.273693e6 4.015084e6 3.4028473e7 +3.738683e6 647813.0 1.100616e6 1.794058e6 5.88455e6 4.275846e6 4.041474e6 3.4059598e7 +3.740325e6 648086.0 1.102069e6 1.805455e6 5.895608e6 4.278319e6 4.069162e6 3.4091558e7 +3.741781e6 648388.0 1.103413e6 1.816562e6 5.906543e6 4.281214e6 4.100222e6 3.4169667e7 +3.743389e6 648740.0 1.103413e6 1.826824e6 5.917548e6 4.284332e6 4.100222e6 3.4183769e7 +3.744681e6 649171.0 1.103413e6 1.83579e6 5.93008e6 4.287458e6 4.100222e6 3.4204098e7 +3.745227e6 649507.0 1.107208e6 1.84254e6 5.934273e6 4.289528e6 4.16185e6 3.4252941e7 +3.74641e6 649772.0 1.108675e6 1.84955e6 5.95249e6 4.293083e6 4.189136e6 3.4292667e7 +3.748613e6 650108.0 1.108675e6 1.855885e6 5.974063e6 4.297337e6 4.219723e6 3.4340403e7 +3.750503e6 650471.0 1.112161e6 1.862387e6 5.996163e6 4.302393e6 4.249258e6 3.4396927e7 +3.752592e6 650890.0 1.112161e6 1.867786e6 6.015572e6 4.307535e6 4.280429e6 3.4517728e7 +3.754511e6 651311.0 1.113465e6 1.872491e6 6.041313e6 4.312673e6 4.280429e6 3.4546472e7 +3.755898e6 651653.0 1.113465e6 1.876406e6 6.056555e6 4.317415e6 4.280429e6 3.4574443e7 +3.756856e6 651978.0 1.117697e6 1.88045e6 6.061969e6 4.32053e6 4.342054e6 3.4653816e7 +3.758401e6 652294.0 1.11903e6 1.884048e6 6.089097e6 4.325046e6 4.368453e6 3.4718814e7 +3.761169e6 652659.0 1.121089e6 1.888613e6 6.11702e6 4.330739e6 4.395602e6 3.479239e7 +3.764311e6 653206.0 1.122951e6 1.892128e6 6.142449e6 4.336906e6 4.422291e6 3.4864933e7 +3.766765e6 653712.0 1.124715e6 1.895206e6 6.166759e6 4.343519e6 4.447044e6 3.5056375e7 +3.769165e6 654243.0 1.124715e6 1.897647e6 6.190621e6 4.350028e6 4.447044e6 3.5100267e7 +3.771262e6 654787.0 1.124715e6 1.899823e6 6.210335e6 4.355348e6 4.447044e6 3.5144834e7 +3.772109e6 655207.0 1.129018e6 1.902072e6 6.218927e6 4.358533e6 4.502983e6 3.5253193e7 +3.773875e6 655553.0 1.130758e6 1.905024e6 6.243225e6 4.363374e6 4.52331e6 3.5350945e7 +3.777446e6 655955.0 1.132934e6 1.908607e6 6.272466e6 4.369964e6 4.545184e6 3.545339e7 +3.780985e6 656550.0 1.134907e6 1.911632e6 6.299415e6 4.377188e6 4.566571e6 3.5563078e7 +3.784433e6 657047.0 1.136726e6 1.914402e6 6.325146e6 4.383787e6 4.588132e6 3.5814973e7 +3.787639e6 657648.0 1.136726e6 1.916901e6 6.351003e6 4.390684e6 4.588132e6 3.5877976e7 +3.790766e6 658219.0 1.136726e6 1.919082e6 6.371463e6 4.396417e6 4.588132e6 3.5912852e7 +3.791949e6 658782.0 1.141379e6 1.921333e6 6.378681e6 4.400617e6 4.62777e6 3.6072637e7 +3.794429e6 659218.0 1.143127e6 1.92368e6 6.407573e6 4.406241e6 4.64345e6 3.6190436e7 +3.799425e6 659836.0 1.145736e6 1.926573e6 6.440367e6 4.413162e6 4.660473e6 3.6344889e7 +3.805063e6 660710.0 1.147855e6 1.929495e6 6.470038e6 4.420429e6 4.677883e6 3.6488973e7 +3.810641e6 661569.0 1.149869e6 1.932083e6 6.497785e6 4.427827e6 4.69354e6 3.6715779e7 +3.816285e6 662537.0 1.149869e6 1.934614e6 6.522212e6 4.435008e6 4.69354e6 3.6788845e7 +3.821013e6 663488.0 1.149869e6 1.936987e6 6.543481e6 4.440669e6 4.69354e6 3.6835632e7 +3.823139e6 664321.0 1.154879e6 1.939383e6 6.556878e6 4.444338e6 4.719266e6 3.7029987e7 +3.827051e6 665118.0 1.15662e6 1.942391e6 6.582001e6 4.449606e6 4.733602e6 3.7180577e7 +3.835375e6 665993.0 1.159366e6 1.945033e6 6.612028e6 4.456765e6 4.745558e6 3.7348174e7 +3.843775e6 667207.0 1.161558e6 1.94756e6 6.637417e6 4.464005e6 4.758003e6 3.7503394e7 +3.853055e6 668498.0 1.163726e6 1.950237e6 6.660365e6 4.471225e6 4.770453e6 3.7742467e7 +3.861147e6 669811.0 1.163726e6 1.952768e6 6.683078e6 4.478691e6 4.770453e6 3.7834663e7 +3.868197e6 671097.0 1.163726e6 1.955267e6 6.700378e6 4.484613e6 4.770453e6 3.7878864e7 +3.871865e6 672203.0 1.168602e6 1.9578e6 6.708289e6 4.488779e6 4.794352e6 3.8087086e7 +3.877612e6 673186.0 1.170213e6 1.960873e6 6.734203e6 4.494857e6 4.804424e6 3.824155e7 +3.889173e6 674341.0 1.173108e6 1.963635e6 6.757909e6 4.502396e6 4.815205e6 3.8420531e7 +3.901799e6 675959.0 1.175575e6 1.966648e6 6.777592e6 4.509611e6 4.82232e6 3.8604297e7 +3.913828e6 677412.0 1.177909e6 1.969192e6 6.778049e6 4.517434e6 4.831809e6 3.884297e7 +3.924131e6 678816.0 1.177909e6 1.971619e6 6.81368e6 4.524292e6 4.831809e6 3.8921857e7 +3.932547e6 680191.0 1.177909e6 1.973884e6 6.82731e6 4.530246e6 4.831809e6 3.8973866e7 +3.937106e6 681537.0 1.18281e6 1.976296e6 6.834998e6 4.534499e6 4.847298e6 3.9203077e7 +3.942856e6 682620.0 1.184664e6 1.979267e6 6.835022e6 4.539991e6 4.855065e6 3.9383037e7 +3.956387e6 683900.0 1.187506e6 1.982194e6 6.868151e6 4.546487e6 4.861883e6 3.9573553e7 +3.970102e6 685752.0 1.18971e6 1.984868e6 6.882305e6 4.553241e6 4.871444e6 3.975269e7 +3.984353e6 687309.0 1.192008e6 1.987668e6 6.897529e6 4.55997e6 4.877755e6 3.998813e7 +3.995188e6 689001.0 1.192008e6 1.99014e6 6.910865e6 4.566126e6 4.877755e6 4.0074039e7 +4.005641e6 690933.0 1.192008e6 1.992291e6 6.921275e6 4.57144e6 4.877755e6 4.0137541e7 +4.01039e6 692509.0 1.196656e6 1.994847e6 6.924325e6 4.574787e6 4.887112e6 4.0231271e7 +4.017116e6 693900.0 1.198503e6 1.997755e6 6.938866e6 4.579502e6 4.89264e6 4.0440438e7 +4.030681e6 695701.0 1.201056e6 2.000258e6 6.944797e6 4.585423e6 4.898258e6 4.0617363e7 +4.046112e6 698001.0 1.203326e6 2.003063e6 6.962917e6 4.590941e6 4.903021e6 4.0783781e7 +4.059081e6 700170.0 1.205516e6 2.005351e6 6.972934e6 4.596558e6 4.907461e6 4.1025791e7 +4.070295e6 702509.0 1.205516e6 2.005482e6 6.982683e6 4.601749e6 4.907461e6 4.111492e7 +4.07764e6 704755.0 1.205516e6 2.009353e6 6.990662e6 4.606413e6 4.907461e6 4.1163271e7 +4.083151e6 706592.0 1.210381e6 2.011426e6 6.99298e6 4.609205e6 4.915265e6 4.1374047e7 +4.089476e6 707982.0 1.212106e6 2.013925e6 7.007436e6 4.613214e6 4.918526e6 4.1519448e7 +4.101931e6 709830.0 1.215114e6 2.016106e6 7.007819e6 4.61804e6 4.922249e6 4.1692698e7 +4.114856e6 712430.0 1.217473e6 2.018363e6 7.022203e6 4.623155e6 4.926324e6 4.1851474e7 +4.125878e6 714748.0 1.219814e6 2.020461e6 7.029959e6 4.627699e6 4.929546e6 4.2062333e7 +4.134779e6 716960.0 1.219814e6 2.022206e6 7.037931e6 4.632275e6 4.929546e6 4.2137303e7 +4.142116e6 718988.0 1.219814e6 2.023609e6 7.043875e6 4.636111e6 4.929546e6 4.2182173e7 +4.145852e6 720417.0 1.224885e6 2.025356e6 7.045422e6 4.638516e6 4.935534e6 4.2353973e7 +4.150516e6 721756.0 1.226682e6 2.027386e6 7.054198e6 4.64189e6 4.937984e6 4.2475709e7 +4.16097e6 723134.0 1.229236e6 2.029298e6 7.061323e6 4.645853e6 4.940824e6 4.260706e7 +4.171666e6 725243.0 1.231523e6 2.03109e6 7.06863e6 4.649906e6 4.943855e6 4.2736227e7 +4.181393e6 727082.0 1.233723e6 2.032774e6 7.075305e6 4.653696e6 4.946601e6 4.2910991e7 +4.188604e6 728899.0 1.233723e6 2.034465e6 7.080675e6 4.657215e6 4.946601e6 4.2971485e7 +4.196378e6 730728.0 1.233723e6 2.035906e6 7.085607e6 4.660314e6 4.946601e6 4.3025799e7 +4.1994e6 732114.0 1.238358e6 2.037687e6 7.08711e6 4.662087e6 4.95164e6 4.3181743e7 +4.203571e6 733499.0 1.240232e6 2.039554e6 7.094334e6 4.665049e6 4.95393e6 4.3294491e7 +4.215351e6 735088.0 1.242821e6 2.041333e6 7.100572e6 4.668261e6 4.956691e6 4.3415879e7 +4.227501e6 737702.0 1.244954e6 2.043142e6 7.106028e6 4.672355e6 4.959091e6 4.3526264e7 +4.237619e6 739627.0 1.247197e6 2.044898e6 7.111154e6 4.675758e6 4.961128e6 4.3681092e7 +4.246136e6 741366.0 1.247197e6 2.046582e6 7.116415e6 4.679067e6 4.961128e6 4.3729295e7 +4.2523e6 743174.0 1.247197e6 2.048255e6 7.120214e6 4.682034e6 4.961128e6 4.3774073e7 +4.255388e6 744732.0 1.251857e6 2.05019e6 7.121507e6 4.683646e6 4.965399e6 4.3916981e7 +4.260187e6 746104.0 1.253587e6 2.052145e6 7.127454e6 4.686109e6 4.9672e6 4.4012214e7 +4.271734e6 747562.0 1.256191e6 2.054972e6 7.137177e6 4.689341e6 4.969503e6 4.4124389e7 +4.283378e6 750242.0 1.258688e6 2.057813e6 7.142387e6 4.692274e6 4.97131e6 4.4225912e7 +4.293807e6 752280.0 1.261102e6 2.060392e6 7.147186e6 4.695291e6 4.973619e6 4.4357325e7 +4.302661e6 754134.0 1.261102e6 2.062706e6 7.152009e6 4.698038e6 4.973619e6 4.4396152e7 +4.310273e6 756011.0 1.261102e6 2.065453e6 7.156066e6 4.700316e6 4.973619e6 4.4435822e7 +4.313384e6 757595.0 1.266562e6 2.068398e6 7.157206e6 4.701832e6 4.977448e6 4.4531883e7 +4.318355e6 758894.0 1.269002e6 2.072199e6 7.163317e6 4.704318e6 4.977448e6 4.4642486e7 +4.330258e6 760490.0 1.272669e6 2.075878e6 7.164924e6 4.707087e6 4.980206e6 4.4750948e7 +4.34264e6 763211.0 1.276221e6 2.079658e6 7.17458e6 4.709753e6 4.982138e6 4.4837895e7 +4.354158e6 765326.0 1.279869e6 2.083391e6 7.180773e6 4.712482e6 4.984386e6 4.4947374e7 +4.365107e6 767720.0 1.279869e6 2.087116e6 7.185744e6 4.715464e6 4.984386e6 4.4987158e7 +4.373789e6 770102.0 1.279869e6 2.090498e6 7.189566e6 4.717899e6 4.984386e6 4.5018816e7 +4.377845e6 772251.0 1.289033e6 2.094417e6 7.190716e6 4.719493e6 4.988878e6 4.5117769e7 +4.384616e6 774247.0 1.292887e6 2.099044e6 7.196754e6 4.722188e6 4.990767e6 4.5199687e7 +4.401631e6 776974.0 1.299439e6 2.104298e6 7.20284e6 4.725887e6 4.993295e6 4.5291305e7 +4.417708e6 780956.0 1.305678e6 2.110201e6 7.209126e6 4.729678e6 4.995176e6 4.5369385e7 +4.43728e6 784574.0 1.31236e6 2.115912e6 7.215584e6 4.733557e6 4.997732e6 4.5465336e7 +4.452425e6 788060.0 1.31236e6 2.122226e6 7.221941e6 4.737462e6 4.997732e6 4.5497757e7 +4.466157e6 791769.0 1.31236e6 2.127543e6 7.226974e6 4.741185e6 4.997732e6 4.5516927e7 +4.47273e6 795302.0 1.328202e6 2.133303e6 7.228331e6 4.74372e6 5.002217e6 4.5629496e7 +4.483203e6 798099.0 1.333947e6 2.140627e6 7.2351e6 4.747773e6 5.004143e6 4.5696152e7 +4.506415e6 801545.0 1.342718e6 2.148354e6 7.24218e6 4.752368e6 5.006675e6 4.5798714e7 +4.534452e6 806032.0 1.351913e6 2.155772e6 7.248285e6 4.757231e6 5.008887e6 4.587381e7 +4.55912e6 810342.0 1.36065e6 2.163752e6 7.254779e6 4.762563e6 5.011148e6 4.5968914e7 +4.580663e6 816280.0 1.36065e6 2.171966e6 7.262178e6 4.76744e6 5.011148e6 4.6003209e7 +4.59755e6 822260.0 1.36065e6 2.179684e6 7.268527e6 4.771965e6 5.011148e6 4.6035532e7 +4.607208e6 827894.0 1.36065e6 2.187437e6 7.27041e6 4.774783e6 5.011148e6 4.6148787e7 +4.618021e6 832692.0 1.36065e6 2.196575e6 7.272516e6 4.777614e6 5.016968e6 4.6217534e7 +4.638419e6 837980.0 1.393358e6 2.206812e6 7.282823e6 4.782802e6 5.019255e6 4.6303127e7 +4.672368e6 844561.0 1.403548e6 2.217764e6 7.29222e6 4.788704e6 5.022546e6 4.6384563e7 +4.709488e6 853532.0 1.403548e6 2.22977e6 7.301303e6 4.795465e6 5.025639e6 4.6481422e7 +4.74349e6 863318.0 1.414463e6 2.241156e6 7.310967e6 4.802225e6 5.025639e6 4.6516283e7 +4.767033e6 873026.0 1.414463e6 2.252987e6 7.319526e6 4.808047e6 5.025639e6 4.655311e7 +4.782546e6 881145.0 1.43883e6 2.264297e6 7.321767e6 4.812594e6 5.032056e6 4.6663859e7 +4.804378e6 889169.0 1.43883e6 2.276956e6 7.334332e6 4.818705e6 5.032056e6 4.6742215e7 +4.844054e6 896928.0 1.463548e6 2.293318e6 7.346277e6 4.826738e6 5.038517e6 4.6837285e7 +4.89425e6 908903.0 1.463548e6 2.309589e6 7.35892e6 4.835435e6 5.042803e6 4.6894927e7 +4.94289e6 922128.0 1.484712e6 2.323474e6 7.362807e6 4.843957e6 5.047156e6 4.7038438e7 +4.987971e6 932719.0 1.484712e6 2.335547e6 7.377483e6 4.852496e6 5.047156e6 4.7082389e7 +5.021469e6 945373.0 1.484712e6 2.354772e6 7.389989e6 4.860061e6 5.047156e6 4.7114301e7 +5.045076e6 956813.0 1.512474e6 2.37497e6 7.393296e6 4.86526e6 5.056954e6 4.7248337e7 +5.077124e6 968012.0 1.524862e6 2.395772e6 7.41318e6 4.873075e6 5.061045e6 4.7335607e7 +5.12995e6 978997.0 1.543299e6 2.419406e6 7.433545e6 4.883242e6 5.067712e6 4.7448451e7 +5.195321e6 995468.0 1.559998e6 2.440482e6 7.453941e6 4.893887e6 5.074027e6 4.7558277e7 +5.248291e6 1.010492e6 1.5815e6 2.462333e6 7.475211e6 4.904441e6 5.080663e6 4.7685153e7 +5.312215e6 1.025373e6 1.5815e6 2.483042e6 7.497912e6 4.915981e6 5.080663e6 4.7730513e7 +5.354942e6 1.039442e6 1.5815e6 2.506086e6 7.517669e6 4.925688e6 5.080663e6 4.7770345e7 +5.385585e6 1.053541e6 1.62356e6 2.529064e6 7.523008e6 4.932091e6 5.096538e6 4.7914961e7 +5.430911e6 1.065176e6 1.635675e6 2.552859e6 7.553513e6 4.942135e6 5.103315e6 4.8006305e7 +5.497795e6 1.077153e6 1.659025e6 2.575117e6 7.586146e6 4.954585e6 5.111842e6 4.8117883e7 +5.573756e6 1.091668e6 1.679861e6 2.59645e6 7.619656e6 4.968341e6 5.1211e6 4.8157201e7 +5.65017e6 1.106126e6 1.701633e6 2.618552e6 7.654128e6 4.982022e6 5.131012e6 4.8210621e7 +5.717295e6 1.118256e6 1.701633e6 2.640725e6 7.691217e6 4.994891e6 5.131012e6 4.823716e7 +5.761696e6 1.130304e6 1.701633e6 2.662207e6 7.722804e6 5.007818e6 5.131012e6 4.8280309e7 +5.79106e6 1.139925e6 1.749469e6 2.684401e6 7.731351e6 5.01579e6 5.153923e6 4.8466603e7 +5.836813e6 1.147912e6 1.766035e6 2.702972e6 7.778575e6 5.028547e6 5.164184e6 4.8583712e7 +5.903999e6 1.156022e6 1.786444e6 2.726095e6 7.829045e6 5.04362e6 5.17472e6 4.8720826e7 +5.977208e6 1.166983e6 1.809557e6 2.747685e6 7.87749e6 5.06043e6 5.18922e6 4.8859679e7 +6.05156e6 1.175757e6 1.827467e6 2.770365e6 7.927361e6 5.077445e6 5.202958e6 4.9018289e7 +6.11607e6 1.183006e6 1.827467e6 2.79348e6 7.978825e6 5.094072e6 5.202958e6 4.9084631e7 +6.158125e6 1.189268e6 1.827467e6 2.814492e6 8.020978e6 5.109082e6 5.202958e6 4.9139815e7 +6.185961e6 1.194582e6 1.868906e6 2.832432e6 8.032613e6 5.118576e6 5.202958e6 4.9317501e7 +6.22202e6 1.198852e6 1.879784e6 2.850564e6 8.091667e6 5.134318e6 5.246766e6 4.9430762e7 +6.291621e6 1.203266e6 1.898498e6 2.870367e6 8.153025e6 5.152264e6 5.246766e6 4.958067e7 +6.362232e6 1.209334e6 1.914527e6 2.88793e6 8.209911e6 5.16478e6 5.273178e6 4.97052e7 +6.42352e6 1.213648e6 1.929772e6 2.905694e6 8.265076e6 5.18527e6 5.290273e6 4.9863412e7 +6.477217e6 1.216765e6 1.929772e6 2.92233e6 8.318995e6 5.206305e6 5.29019e6 4.9919999e7 +6.509863e6 1.221586e6 1.929772e6 2.936161e6 8.362843e6 5.225517e6 5.29019e6 4.9972308e7 +6.531606e6 1.224847e6 1.959193e6 2.94893e6 8.374944e6 5.238221e6 5.339992e6 5.0157794e7 +6.562429e6 1.228109e6 1.968269e6 2.962514e6 8.43836e6 5.258886e6 5.366128e6 5.0270614e7 +6.61373e6 1.231043e6 1.98012e6 2.978915e6 8.504074e6 5.282076e6 5.393268e6 5.0416463e7 +6.670407e6 1.235171e6 1.98012e6 2.994376e6 8.564979e6 5.30818e6 5.422168e6 5.0558193e7 +6.721375e6 1.2381e6 1.99016e6 3.009058e6 8.623131e6 5.336795e6 5.455527e6 5.0750844e7 +6.764188e6 1.240798e6 1.999764e6 3.022405e6 8.681667e6 5.364852e6 5.455527e6 5.0830602e7 +6.793536e6 1.243144e6 1.999764e6 3.034622e6 8.73014e6 5.389155e6 5.455527e6 5.0919802e7 +6.809622e6 1.245128e6 2.017154e6 3.044025e6 8.745272e6 5.40536e6 5.535231e6 5.1159843e7 +6.83305e6 1.247014e6 2.017447e6 3.057549e6 8.818154e6 5.436143e6 5.585054e6 5.1339257e7 +6.878709e6 1.248965e6 2.023285e6 3.071231e6 8.902466e6 5.472469e6 5.645095e6 5.1583e7 +6.923636e6 1.251779e6 2.030878e6 3.084017e6 8.994106e6 5.517054e6 5.718007e6 5.1852761e7 +6.959067e6 1.253941e6 2.038111e6 3.097098e6 9.088232e6 5.567644e6 5.718007e6 5.2101283e7 +6.981281e6 1.256207e6 2.038111e6 3.10944e6 9.192843e6 5.622431e6 5.718007e6 5.2187948e7 +6.991381e6 1.258323e6 2.038111e6 3.12119e6 9.22054e6 5.647313e6 5.718007e6 5.2366337e7 +7.005289e6 1.259951e6 2.052871e6 3.130822e6 9.251021e6 5.678112e6 5.932626e6 5.2866901e7 +7.026369e6 1.261687e6 2.062836e6 3.147507e6 9.430829e6 5.756412e6 6.032297e6 5.3228932e7 +7.066412e6 1.264288e6 2.075781e6 3.163542e6 9.639037e6 5.854428e6 6.133057e6 5.3731041e7 +7.109182e6 1.26763e6 2.089657e6 3.181596e6 9.845583e6 5.981428e6 6.294745e6 5.432174e7 +7.150422e6 1.270811e6 2.105343e6 3.198704e6 1.0077783e7 6.125683e6 6.294745e6 5.4835368e7 +7.176814e6 1.274628e6 2.105343e6 3.217646e6 1.0296909e7 6.266939e6 6.294745e6 5.502414e7 +7.189329e6 1.278327e6 2.105343e6 3.23314e6 1.0355341e7 6.328076e6 6.294745e6 5.531011e7 +7.207847e6 1.281328e6 2.133284e6 3.252649e6 1.042283e7 6.39611e6 6.667511e6 5.6355084e7 +7.238408e6 1.284811e6 2.151914e6 3.279437e6 1.0694804e7 6.566947e6 6.785286e6 5.716732e7 +7.29732e6 1.290817e6 2.17971e6 3.306721e6 1.1027112e7 6.756035e6 6.922466e6 5.7829956e7 +7.36166e6 1.300899e6 2.206992e6 3.34404e6 1.129001e7 6.975465e6 6.922466e6 5.8664969e7 +7.417995e6 1.309691e6 2.231686e6 3.374488e6 1.1618256e7 7.083762e6 7.164906e6 5.9534724e7 +7.473884e6 1.318582e6 2.231686e6 3.408735e6 1.1921925e7 7.281297e6 7.164906e6 5.9932416e7 +7.510436e6 1.325632e6 2.231686e6 3.438179e6 1.2218022e7 7.436939e6 7.164906e6 6.0417447e7 +7.535691e6 1.336348e6 2.286532e6 3.468379e6 1.2311963e7 7.554344e6 7.4573e6 6.1801347e7 +7.581381e6 1.347274e6 2.307843e6 3.502126e6 1.268078e7 7.774863e6 7.592242e6 6.2588733e7 +7.661811e6 1.359957e6 2.347164e6 3.537795e6 1.3042665e7 7.971068e6 7.771367e6 6.3437357e7 +7.743228e6 1.376504e6 2.347164e6 3.574787e6 1.3351053e7 8.155645e6 7.930528e6 6.4298689e7 +7.835451e6 1.393335e6 2.410731e6 3.60934e6 1.3680775e7 8.356514e6 8.093036e6 6.5178723e7 +7.913473e6 1.410269e6 2.410731e6 3.646279e6 1.4005385e7 8.54945e6 8.093036e6 6.5587031e7 +7.965977e6 1.427326e6 2.410731e6 3.689011e6 1.4283514e7 8.706915e6 8.093036e6 6.6066812e7 +8.000122e6 1.442182e6 2.484027e6 3.690448e6 1.4386178e7 8.790302e6 8.424503e6 6.6741937e7 +8.074527e6 1.458292e6 2.521462e6 3.760998e6 1.4851448e7 9.018425e6 8.518975e6 6.7871414e7 +8.18685e6 1.476626e6 2.575313e6 3.801409e6 1.5288014e7 9.219391e6 8.676916e6 6.877954e7 +8.320386e6 1.50472e6 2.642761e6 3.860272e6 1.5715329e7 9.418256e6 8.834363e6 6.9512111e7 +8.460546e6 1.52985e6 2.697239e6 3.907184e6 1.6116748e7 9.603856e6 8.975458e6 7.0353169e7 +8.596007e6 1.559478e6 2.697239e6 3.973076e6 1.650609e7 9.781191e6 8.975458e6 7.0655656e7 +8.681447e6 1.586146e6 2.697239e6 4.038129e6 1.6807733e7 9.923678e6 8.975458e6 7.10211e7 +8.74484e6 1.609498e6 2.830719e6 4.092539e6 1.691722e7 1.0001344e7 9.28089e6 7.1943238e7 +8.871795e6 1.634631e6 2.878212e6 4.151652e6 1.7420569e7 1.0212621e7 9.395767e6 7.2436314e7 +9.035795e6 1.661328e6 2.939439e6 4.216631e6 1.7848291e7 1.0383561e7 9.52932e6 7.3113429e7 +9.238931e6 1.699469e6 3.007724e6 4.291147e6 1.8241888e7 1.0539601e7 9.660208e6 7.3620615e7 +9.429079e6 1.73523e6 3.055925e6 4.330881e6 1.8596157e7 1.0683948e7 9.77913e6 7.4235504e7 +9.618245e6 1.773059e6 3.055925e6 4.406331e6 1.8928572e7 1.0821375e7 9.77913e6 7.4414116e7 +9.737215e6 1.80665e6 3.055925e6 4.518767e6 1.9178039e7 1.0925485e7 9.77913e6 7.4612072e7 +9.815533e6 1.835602e6 3.155239e6 4.624716e6 1.9266496e7 1.0983116e7 9.961253e6 7.5155562e7 +9.978146e6 1.861707e6 3.184201e6 4.692028e6 1.9681231e7 1.1116422e7 1.0039126e7 7.5481472e7 +1.0186644e7 1.889437e6 3.229629e6 4.775147e6 1.9998301e7 1.1235745e7 1.0125348e7 7.58116e7 +1.0422764e7 1.933415e6 3.267656e6 4.844257e6 2.027471e7 1.1348701e7 1.0199716e7 7.608707e7 +1.0671602e7 1.967057e6 3.296038e6 4.884578e6 2.0517059e7 1.1449601e7 1.0199716e7 7.6443015e7 +1.0889417e7 2.003905e6 3.296038e6 4.97965e6 2.0731613e7 1.1542793e7 1.0199716e7 7.6529437e7 +1.102259e7 2.037105e6 3.296038e6 5.057376e6 2.0887052e7 1.1621736e7 1.0199716e7 7.6612911e7 +1.1117857e7 2.067085e6 3.344833e6 5.437874e6 2.093591e7 1.1663338e7 1.0395471e7 7.6960254e7 +1.1287428e7 2.093012e6 3.36389e6 5.524628e6 2.11746e7 1.1765767e7 1.0439302e7 7.7174911e7 +1.1521678e7 2.122068e6 3.386223e6 5.611596e6 2.1177663e7 1.1847436e7 1.0502141e7 7.7363582e7 +1.176954e7 2.162487e6 3.405839e6 5.692388e6 2.1511997e7 1.1923631e7 1.0555196e7 7.7535345e7 +1.2009712e7 2.197838e6 3.421081e6 5.762879e6 2.1646561e7 1.1991109e7 1.06042e7 7.7745074e7 +1.2219501e7 2.231218e6 3.421081e6 5.823167e6 2.1765182e7 1.205333e7 1.06042e7 7.7796939e7 +1.2344661e7 2.261101e6 3.421081e6 5.878252e6 2.1851747e7 1.2105675e7 1.06042e7 7.7855262e7 +1.2421126e7 2.286139e6 3.447539e6 5.931816e6 2.188437e7 1.2134451e7 1.0672906e7 7.8025852e7 +1.2580343e7 2.310227e6 3.460301e6 5.995805e6 2.1886335e7 1.2205474e7 1.0707286e7 7.8137203e7 +1.2800315e7 2.336753e6 3.473015e6 6.052272e6 2.2130264e7 1.2265343e7 1.0744394e7 7.8252198e7 +1.3035941e7 2.375594e6 3.484518e6 6.10168e6 2.2223882e7 1.2323398e7 1.0778607e7 7.8354131e7 +1.3255989e7 2.406524e6 3.494223e6 6.135372e6 2.2310014e7 1.2377098e7 1.0809222e7 7.849945e7 +1.3445094e7 2.437153e6 3.494223e6 6.171884e6 2.2386566e7 1.2427773e7 1.0809222e7 7.8530855e7 +1.3563126e7 2.462981e6 3.494223e6 6.207905e6 2.244558e7 1.2469975e7 1.0809222e7 7.8553858e7 +1.3636993e7 2.484817e6 3.512212e6 6.242623e6 2.2466076e7 1.2494459e7 1.0858e7 7.8636971e7 +1.3762895e7 2.506243e6 3.520568e6 6.242693e6 2.2563594e7 1.2554596e7 1.0880193e7 7.8726501e7 +1.3971947e7 2.530015e6 3.529041e6 6.283336e6 2.2638153e7 1.2603758e7 1.0914105e7 7.8811759e7 +1.4188269e7 2.565399e6 3.537675e6 6.324585e6 2.270711e7 1.2651251e7 1.0949997e7 7.8878932e7 +1.4399012e7 2.594032e6 3.544034e6 6.362177e6 2.2765934e7 1.269332e7 1.0977524e7 7.8953391e7 +1.4574845e7 2.623952e6 3.544034e6 6.3951e6 2.2819557e7 1.273268e7 1.0977524e7 7.9000802e7 +1.4682758e7 2.649152e6 3.544034e6 6.422501e6 2.2862157e7 1.2764558e7 1.0977524e7 7.9019025e7 +1.4745107e7 2.671323e6 3.557314e6 6.451397e6 2.2877926e7 1.2782836e7 1.0977524e7 7.9117942e7 +1.4867218e7 2.692641e6 3.563841e6 6.48792e6 2.2959368e7 1.2829972e7 1.1036085e7 7.9164646e7 +1.5053624e7 2.720094e6 3.563841e6 6.536471e6 2.3017711e7 1.2867918e7 1.1054888e7 7.9218242e7 +1.5264297e7 2.761187e6 3.571579e6 6.594832e6 2.3079453e7 1.2910506e7 1.1078028e7 7.9266919e7 +1.548189e7 2.793028e6 3.586292e6 6.663249e6 2.3137902e7 1.2948859e7 1.1100428e7 7.9318236e7 +1.56741e7 2.825103e6 3.586292e6 6.730457e6 2.319158e7 1.2990223e7 1.1100428e7 7.9333155e7 +1.5790989e7 2.856781e6 3.586292e6 6.797256e6 2.3236908e7 1.3026112e7 1.1100428e7 7.9345552e7 +1.5869417e7 2.884518e6 3.601627e6 6.861716e6 2.3253235e7 1.3048774e7 1.1136425e7 7.9409702e7 +1.6026216e7 2.91118e6 3.609122e6 6.928013e6 2.3346927e7 1.3109527e7 1.1159574e7 7.943951e7 +1.624207e7 2.945417e6 3.609122e6 7.002259e6 2.3417253e7 1.3159342e7 1.118151e7 7.9477256e7 +1.6504822e7 2.996765e6 3.629671e6 7.076777e6 2.3492815e7 1.3214498e7 1.1204125e7 7.9523871e7 +1.6757658e7 3.047014e6 3.640052e6 7.146301e6 2.3565274e7 1.3268459e7 1.1223974e7 7.957359e7 +1.6994744e7 3.096646e6 3.640052e6 7.20635e6 2.3635798e7 1.3323179e7 1.1223974e7 7.9583808e7 +1.7141351e7 3.140407e6 3.640052e6 7.258692e6 2.3694834e7 1.3373207e7 1.1223974e7 7.9594859e7 +1.7233729e7 3.17804e6 3.658084e6 7.304612e6 2.371746e7 1.3402905e7 1.1223974e7 7.9630291e7 +1.7432617e7 3.212569e6 3.658084e6 7.357595e6 2.3834842e7 1.3489319e7 1.126004e7 7.9654683e7 +1.769521e7 3.252815e6 3.683784e6 7.417982e6 2.3943801e7 1.3563466e7 1.126004e7 7.9700834e7 +1.7990141e7 3.316853e6 3.696059e6 7.471677e6 2.4046195e7 1.3645834e7 1.126004e7 7.9754029e7 +1.8287986e7 3.368804e6 3.696059e6 7.52619e6 2.4143852e7 1.3724411e7 1.1324637e7 7.9785412e7 +1.8548225e7 3.419788e6 3.707561e6 7.56765e6 2.4241956e7 1.3800179e7 1.1324637e7 7.9796289e7 +1.8680017e7 3.46211e6 3.707561e6 7.602473e6 2.4323239e7 1.3861743e7 1.1324637e7 7.9807738e7 +1.8772331e7 3.499819e6 3.728945e6 7.634694e6 2.4347772e7 1.3895188e7 1.1324637e7 7.9850045e7 +1.8994411e7 3.531163e6 3.741614e6 7.675252e6 2.4528957e7 1.3992092e7 1.1378784e7 7.9874623e7 +1.9278143e7 3.568258e6 3.757776e6 7.71804e6 2.4683075e7 1.407045e7 1.1378784e7 7.9915649e7 +1.959653e7 3.623157e6 3.771233e6 7.757138e6 2.4823603e7 1.4153098e7 1.1378784e7 7.9958655e7 +1.9893028e7 3.664438e6 3.782085e6 7.792582e6 2.4967222e7 1.4229495e7 1.1451676e7 8.0005107e7 +2.0145054e7 3.70179e6 3.782085e6 7.820824e6 2.5106739e7 1.4304111e7 1.1451676e7 8.0014541e7 +2.0256278e7 3.73499e6 3.782085e6 7.845856e6 2.5216913e7 1.4364723e7 1.1451676e7 8.0026331e7 +2.0323779e7 3.760649e6 3.807447e6 7.867412e6 2.524672e7 1.4396283e7 1.1451676e7 8.0065331e7 +2.0561131e7 3.781719e6 3.807447e6 7.898395e6 2.5464389e7 1.4496579e7 1.1508309e7 8.008952e7 +2.0829608e7 3.807856e6 3.807447e6 7.926384e6 2.5633476e7 1.456799e7 1.1508309e7 8.0128718e7 +2.1357095e7 3.842048e6 3.851048e6 7.951853e6 2.5803173e7 1.4642354e7 1.1508309e7 8.0174387e7 +2.1357039e7 3.868236e6 3.851048e6 7.974049e6 2.5952226e7 1.4719394e7 1.1551574e7 8.0206622e7 +2.1553495e7 3.890531e6 3.851048e6 7.991e6 2.608434e7 1.4790806e7 1.1551574e7 8.0218423e7 +2.1668677e7 3.909523e6 3.851048e6 8.003377e6 2.6186606e7 1.4845815e7 1.1551574e7 8.0223178e7 +2.1668677e7 3.923533e6 3.881523e6 8.014427e6 2.6218724e7 1.4877144e7 1.1551574e7 8.0252129e7 +2.1849074e7 3.935083e6 3.881523e6 8.028475e6 2.6428476e7 1.4966058e7 1.1578653e7 8.0277798e7 +2.2265788e7 3.950434e6 3.881523e6 8.041708e6 2.6579448e7 1.5035943e7 1.1578653e7 8.0318778e7 +2.2441051e7 3.971481e6 3.915732e6 8.054589e6 2.6738483e7 1.5106066e7 1.1578653e7 8.0369434e7 +2.2591726e7 3.987872e6 3.915732e6 8.066022e6 2.688749e7 1.5173707e7 1.1627487e7 8.0444487e7 +2.2647197e7 4.001802e6 3.915732e6 8.07593e6 2.7029271e7 1.5238128e7 1.1627487e7 8.0457206e7 +2.2677986e7 4.014829e6 3.915732e6 8.083108e6 2.7136925e7 1.5292048e7 1.1627487e7 8.046674e7 +2.2878428e7 4.025499e6 3.943831e6 8.089752e6 2.7162463e7 1.5320753e7 1.1627487e7 8.0507126e7 +2.3017079e7 4.032839e6 3.943831e6 8.096401e6 2.7353225e7 1.5404809e7 1.1662214e7 8.0542904e7 +2.3182447e7 4.042363e6 3.943831e6 8.101578e6 2.7499728e7 1.5467395e7 1.1662214e7 8.0598345e7 +2.3339311e7 4.054989e6 3.972963e6 8.106357e6 2.7637292e7 1.5533012e7 1.1662214e7 8.0649077e7 +2.3376879e7 4.065438e6 3.972963e6 8.110496e6 2.7762686e7 1.5595302e7 1.1662214e7 8.0684528e7 +2.3416663e7 4.075415e6 3.972963e6 8.114337e6 2.7874269e7 1.5659835e7 1.1662214e7 8.0696872e7 +2.3437145e7 4.084222e6 3.972963e6 8.117175e6 2.7960919e7 1.5712088e7 1.1662214e7 8.0704379e7 +2.3459628e7 4.091716e6 3.972963e6 8.119285e6 2.7980729e7 1.5730676e7 1.1662214e7 8.0765876e7 +2.3658211e7 4.097345e6 3.998722e6 8.121967e6 2.8006219e7 1.5758002e7 1.1736893e7 8.0805187e7 +2.3844536e7 4.103119e6 3.998722e6 8.125697e6 2.8162002e7 1.5858442e7 1.1736893e7 8.0874174e7 +2.4006254e7 4.11172e6 4.015791e6 8.128733e6 2.8266009e7 1.5934437e7 1.1736893e7 8.0935931e7 +2.4141333e7 4.122722e6 4.015791e6 8.131494e6 2.8354529e7 1.6008181e7 1.1786036e7 8.1026026e7 +2.4180512e7 4.130862e6 4.015791e6 8.133776e6 2.84351e7 1.6079209e7 1.1786036e7 8.1045774e7 +2.4200596e7 4.137436e6 4.015791e6 8.135366e6 2.8494054e7 1.6136057e7 1.1786036e7 8.105928e7 +2.4337394e7 4.142983e6 4.015791e6 8.136891e6 2.8508116e7 1.6161339e7 1.1786036e7 8.1129586e7 +2.4337394e7 4.147453e6 4.036113e6 8.138755e6 2.8605614e7 1.6191323e7 1.1833457e7 8.1175007e7 +2.4609159e7 4.153702e6 4.036113e6 8.140717e6 2.8673411e7 1.6279754e7 1.1833457e7 8.1265097e7 +2.4710769e7 4.162015e6 4.056448e6 8.141965e6 2.8733434e7 1.6349788e7 1.1833457e7 8.1342523e7 +2.4798067e7 4.168617e6 4.056448e6 8.144e6 2.8786413e7 1.6409183e7 1.1896152e7 8.14038e7 +2.4809785e7 4.174744e6 4.056448e6 8.145596e6 2.8835895e7 1.64632e7 1.1896152e7 8.142781e7 +2.4813817e7 4.180075e6 4.056448e6 8.146887e6 2.8872621e7 1.6504791e7 1.1896152e7 8.1444531e7 +2.4927339e7 4.184588e6 4.071279e6 8.148198e6 2.8881384e7 1.6523859e7 1.1896152e7 8.1539357e7 +2.503397e7 4.188558e6 4.071279e6 8.150001e6 2.8948497e7 1.6586268e7 1.1953481e7 8.1589062e7 +2.5130137e7 4.194237e6 4.071279e6 8.151922e6 2.8996577e7 1.6633911e7 1.1953481e7 8.1701197e7 +2.521521e7 4.201452e6 4.088336e6 8.153591e6 2.9040934e7 1.6682626e7 1.1953481e7 8.178989e7 +2.5287462e7 4.207472e6 4.088336e6 8.155118e6 2.9081169e7 1.672699e7 1.2009059e7 8.1918791e7 +2.529595e7 4.213621e6 4.088336e6 8.156837e6 2.9119127e7 1.6767773e7 1.2009059e7 8.1946645e7 +2.52993e7 4.218785e6 4.088336e6 8.158071e6 2.9148451e7 1.6798998e7 1.2009059e7 8.1952437e7 +2.5406868e7 4.222306e6 4.102082e6 8.159227e6 2.9155815e7 1.6816419e7 1.2058888e7 8.2082675e7 +2.5503878e7 4.226263e6 4.102082e6 8.16081e6 2.9212276e7 1.6872618e7 1.2058888e7 8.215309e7 +2.5592839e7 4.23105e6 4.102082e6 8.162498e6 2.9252875e7 1.6915301e7 1.2058888e7 8.2313446e7 +2.5661838e7 4.236215e6 4.116397e6 8.163926e6 2.9289023e7 1.6954784e7 1.2058888e7 8.2427617e7 +2.5723697e7 4.241469e6 4.116397e6 8.165892e6 2.9321831e7 1.6993813e7 1.2127122e7 8.2515149e7 +2.5729848e7 4.246432e6 4.116397e6 8.167219e6 2.935229e7 1.7030147e7 1.2127122e7 8.2532252e7 +2.5732153e7 4.250291e6 4.116397e6 8.168227e6 2.9375134e7 1.7057873e7 1.2127122e7 8.2564392e7 +2.5818405e7 4.253741e6 4.127123e6 8.169091e6 2.9381085e7 1.7071649e7 1.2127122e7 8.2743325e7 +2.5890456e7 4.255897e6 4.127123e6 8.170403e6 2.9424812e7 1.711655e7 1.2179234e7 8.2828079e7 +2.5949175e7 4.258734e6 4.134293e6 8.171992e6 2.9489304e7 1.7147477e7 1.2179234e7 8.3032009e7 +2.5998085e7 4.26316e6 4.134293e6 8.173428e6 2.9517146e7 1.7178199e7 1.2179234e7 8.3167371e7 +2.604046e7 4.266462e6 4.134293e6 8.175239e6 2.9541498e7 1.7205017e7 1.2179234e7 8.3316621e7 +2.6044283e7 4.266462e6 4.134293e6 8.176417e6 2.9564005e7 1.7229263e7 1.2234806e7 8.3343563e7 +2.6045528e7 4.266462e6 4.134293e6 8.177181e6 2.958097e7 1.7247552e7 1.2234806e7 8.3363166e7 +2.6109965e7 4.273888e6 4.143408e6 8.177944e6 2.9551335e7 1.7257573e7 1.2234806e7 8.3505877e7 +2.6159106e7 4.274095e6 4.143408e6 8.179134e6 2.9583616e7 1.7288287e7 1.2238073e7 8.358909e7 +2.6198811e7 4.276334e6 4.147568e6 8.180573e6 2.9605758e7 1.7312432e7 1.2238073e7 8.3799362e7 +2.6200663e7 4.278954e6 4.147568e6 8.18163e6 2.9626992e7 1.7333299e7 1.2280345e7 8.394507e7 +2.6240639e7 4.281585e6 4.147568e6 8.183245e6 2.9631816e7 1.7355119e7 1.2326264e7 8.4053312e7 +2.6243352e7 4.281585e6 4.147568e6 8.184136e6 2.9655398e7 1.7373741e7 1.2326264e7 8.4066065e7 +2.6244107e7 4.281585e6 4.147568e6 8.184962e6 2.9671838e7 1.7388877e7 1.2326264e7 8.4071889e7 +2.6305996e7 4.286885e6 4.152558e6 8.185964e6 2.9676522e7 1.7396723e7 1.2326264e7 8.413282e7 +2.6360953e7 4.288153e6 4.152558e6 8.187211e6 2.971187e7 1.742141e7 1.2326264e7 8.4303393e7 +2.6409455e7 4.289988e6 4.152558e6 8.189023e6 2.973817e7 1.7440232e7 1.2360256e7 8.4531065e7 +2.6452148e7 4.293027e6 4.158754e6 8.190558e6 2.9763546e7 1.745795e7 1.2360256e7 8.4652992e7 +2.6493235e7 4.295818e6 4.158754e6 8.192641e6 2.9788676e7 1.7467642e7 1.2403245e7 8.48108e7 +2.6493235e7 4.295818e6 4.158754e6 8.194254e6 2.9813848e7 1.7490451e7 1.2403245e7 8.4837269e7 +2.6496611e7 4.295818e6 4.158754e6 8.195493e6 2.983439e7 1.7505973e7 1.2403245e7 8.4852164e7 +2.6498361e7 4.304326e6 4.158754e6 8.196517e6 2.9840626e7 1.7514589e7 1.2403245e7 8.501513e7 +2.6583016e7 4.306509e6 4.164698e6 8.198019e6 2.9852463e7 1.7543136e7 1.2436538e7 8.5101992e7 +2.6660652e7 4.308082e6 4.164698e6 8.200146e6 2.9906452e7 1.7566061e7 1.2436538e7 8.5301396e7 +2.673853e7 4.311116e6 4.170252e6 8.202575e6 2.9946603e7 1.7589595e7 1.2436538e7 8.5444526e7 +2.6803867e7 4.316435e6 4.170252e6 8.205566e6 2.9946697e7 1.7611607e7 1.2478994e7 8.5552295e7 +2.6803867e7 4.316435e6 4.170252e6 8.205566e6 2.9946603e7 1.7634065e7 1.2478994e7 8.5586297e7 +2.6809245e7 4.316435e6 4.170252e6 8.205566e6 2.9946603e7 1.7653375e7 1.2478994e7 8.5602873e7 +2.6915085e7 4.32784e6 4.17744e6 8.211768e6 2.9946647e7 1.7664043e7 1.2478994e7 8.5757502e7 +2.7007429e7 4.330667e6 4.17744e6 8.214642e6 3.0123426e7 1.7703887e7 1.2515127e7 8.5847627e7 +2.7096571e7 4.335007e6 4.17744e6 8.218556e6 3.0175534e7 1.7736696e7 1.2515127e7 8.6032558e7 +2.7124689e7 4.342311e6 4.18794e6 8.222722e6 3.0228615e7 1.7773764e7 1.2515127e7 8.6162743e7 +2.7204953e7 4.349916e6 4.18794e6 8.227221e6 3.027924e7 1.7809934e7 1.2563399e7 8.6302151e7 +2.7204955e7 4.349916e6 4.18794e6 8.227221e6 3.027924e7 1.7844905e7 1.2563399e7 8.631863e7 +2.7211896e7 4.349916e6 4.18794e6 8.227221e6 3.027924e7 1.787916e7 1.2563399e7 8.6335558e7 +2.7334993e7 4.36719e6 4.197345e6 8.237473e6 3.0381221e7 1.7896065e7 1.2563399e7 8.6432339e7 +2.7454225e7 4.372423e6 4.197345e6 8.242305e6 3.0476915e7 1.7959329e7 1.2613634e7 8.6544228e7 +2.7573585e7 4.379778e6 4.197345e6 8.247488e6 3.0555038e7 1.8014202e7 1.2613634e7 8.672973e7 +2.7681775e7 4.39115e6 4.211511e6 8.252995e6 3.063489e7 1.8071634e7 1.2613634e7 8.6879094e7 +2.7771111e7 4.400566e6 4.211511e6 8.258161e6 3.07142e7 1.8128044e7 1.268182e7 8.6996913e7 +2.7771112e7 4.400566e6 4.211511e6 8.258577e6 3.07142e7 1.8184917e7 1.268182e7 8.7036551e7 +2.7771911e7 4.400566e6 4.211511e6 8.258577e6 3.07142e7 1.8234242e7 1.268182e7 8.7057631e7 +2.791424e7 4.425837e6 4.225222e6 8.271456e6 3.0879062e7 1.8259261e7 1.268182e7 8.7221662e7 +2.804819e7 4.432922e6 4.225222e6 8.277287e6 3.1027099e7 1.8343422e7 1.2734038e7 8.7318916e7 +2.8180861e7 4.447278e6 4.225222e6 8.283818e6 3.1151971e7 1.8438877e7 1.2734038e7 8.7509265e7 +2.829396e7 4.459767e6 4.246078e6 8.29033e6 3.1285317e7 1.8523111e7 1.2734038e7 8.767695e7 +2.8392629e7 4.471152e6 4.246078e6 8.296406e6 3.1410383e7 1.8610011e7 1.2818184e7 8.783407e7 +2.839263e7 4.471152e6 4.246078e6 8.296406e6 3.1410383e7 1.8695954e7 1.2818184e7 8.7853068e7 +2.8394995e7 4.471152e6 4.246078e6 8.296406e6 3.1410383e7 1.8768871e7 1.2818184e7 8.786035e7 +2.8542484e7 4.49957e6 4.265296e6 8.310449e6 3.1653749e7 1.8805756e7 1.2818184e7 8.7940798e7 +2.8673212e7 4.506979e6 4.265296e6 8.317175e6 3.1861391e7 1.8938771e7 1.2890002e7 8.8080958e7 +2.8808614e7 4.517003e6 4.265296e6 8.323722e6 3.2016207e7 1.9048788e7 1.2890002e7 8.8281552e7 +2.8926346e7 4.529939e6 4.29488e6 8.331055e6 3.2177472e7 1.9157174e7 1.2890002e7 8.8423636e7 +2.9022265e7 4.542028e6 4.29488e6 8.338213e6 3.231867e7 1.9259037e7 1.2973615e7 8.8561988e7 +2.9022265e7 4.542028e6 4.29488e6 8.338213e6 3.231867e7 1.9357938e7 1.2973615e7 8.8589412e7 +2.902576e7 4.542028e6 4.29488e6 8.338213e6 3.231867e7 1.9439501e7 1.2973615e7 8.8612362e7 +2.9180489e7 4.573219e6 4.320107e6 8.353626e6 3.2570121e7 1.9523262e7 1.2973615e7 8.8814577e7 +2.93081e7 4.579384e6 4.320107e6 8.361159e6 3.2753754e7 1.966732e7 1.3032841e7 8.8961838e7 +2.9460249e7 4.591009e6 4.320107e6 8.367997e6 3.2881645e7 1.9778911e7 1.3032841e7 8.9165244e7 +2.9569943e7 4.606092e6 4.34905e6 8.375065e6 3.2881645e7 1.9887543e7 1.3032841e7 8.9339477e7 +2.9692989e7 4.618853e6 4.34905e6 8.38192e6 3.2881809e7 1.9985479e7 1.3090476e7 8.9489336e7 +2.9692989e7 4.618853e6 4.34905e6 8.38192e6 3.2881809e7 2.0076863e7 1.3090476e7 8.9528797e7 +2.9692989e7 4.618853e6 4.34905e6 8.38192e6 3.2881809e7 2.0145859e7 1.3090476e7 8.9547608e7 +2.985368e7 4.655677e6 4.368611e6 8.395102e6 3.3239622e7 2.017791e7 1.3090476e7 8.9712243e7 +2.9994679e7 4.663725e6 4.368611e6 8.400164e6 3.3375449e7 2.0299013e7 1.3132159e7 8.9830497e7 +3.0131303e7 4.675532e6 4.381331e6 8.404838e6 3.3465759e7 2.0385814e7 1.3132159e7 9.0046261e7 +3.0239122e7 4.691948e6 4.381331e6 8.409332e6 3.3546628e7 2.0467349e7 1.3132159e7 9.0200438e7 +3.0331131e7 4.704616e6 4.381331e6 8.413961e6 3.3621366e7 2.0539016e7 1.3204863e7 9.0367064e7 +3.0331133e7 4.704616e6 4.381331e6 8.413961e6 3.3621366e7 2.060819e7 1.3204863e7 9.0390185e7 +3.0331133e7 4.704616e6 4.381331e6 8.413961e6 3.3621366e7 2.0660065e7 1.3204863e7 9.0410386e7 +3.0476605e7 4.734005e6 4.398161e6 8.424253e6 3.3751295e7 2.0684182e7 1.3204863e7 9.056729e7 +3.0598385e7 4.74362e6 4.398161e6 8.428731e6 3.3840851e7 2.0772833e7 1.3203228e7 9.0733888e7 diff --git a/lib/grm/grm-plots/data/sans.dat b/lib/grm/grm-plots/data/sans.dat new file mode 100644 index 000000000..fe229e2f7 --- /dev/null +++ b/lib/grm/grm-plots/data/sans.dat @@ -0,0 +1,132 @@ +# title : Neutron scatter plot +# xlabel : $Q_x (Å^{-1})$ +# ylabel : $Q_y (Å^{-1})$ + +0 2 0 2 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 3 0 0 0 0 0 4 +0 1 2 2 1 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 2 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 2 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 2 0 0 0 1 1 0 1 0 4 0 1 4 1 +1 0 0 3 1 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 1 3 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 2 3 0 0 0 1 0 0 1 0 0 0 0 0 2 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 3 2 2 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 2 1 0 0 1 2 0 1 2 4 0 0 1 0 0 0 1 0 1 0 0 0 0 2 1 1 1 0 1 3 2 2 0 +0 0 0 1 1 2 1 1 0 2 0 1 1 0 0 2 0 1 1 0 1 0 0 2 1 1 1 1 2 2 7 1 3 3 2 2 1 1 1 0 1 1 1 0 3 5 5 1 6 5 2 1 1 1 2 2 0 2 3 5 3 1 4 5 7 6 3 3 3 1 0 3 2 1 2 0 2 2 5 3 4 4 2 5 1 0 1 2 1 1 0 3 4 1 3 2 5 2 4 1 3 0 1 1 2 1 2 0 1 1 2 2 0 1 0 1 1 3 0 2 1 0 2 0 0 0 0 0 +0 0 0 1 0 1 2 6 7 7 5 7 8 4 7 7 14 18 10 6 3 5 4 10 5 7 16 11 15 13 18 27 19 10 16 11 16 8 5 6 8 9 4 7 14 18 17 31 22 27 26 19 15 13 14 12 18 11 20 23 28 32 33 38 26 37 34 24 19 16 8 14 11 19 20 10 29 28 32 33 24 27 13 21 9 12 8 7 3 8 15 16 11 10 13 25 16 20 20 12 9 5 6 3 9 5 4 6 14 8 6 8 9 4 3 11 12 9 6 13 5 6 2 2 0 0 1 1 +0 0 0 1 1 5 21 28 18 27 19 30 22 25 29 35 38 37 29 31 35 28 24 32 39 41 44 60 43 55 42 50 58 50 47 32 43 47 39 27 27 40 47 51 60 71 71 93 110 82 93 97 89 78 78 79 73 90 99 108 159 166 179 131 161 170 155 142 122 120 83 106 78 93 109 95 105 136 123 138 109 105 73 89 65 55 59 43 37 46 69 48 50 58 43 66 72 70 60 44 43 40 39 25 26 29 23 30 36 34 39 22 34 21 25 20 23 21 23 34 19 9 12 2 1 1 1 1 +0 0 1 0 0 22 39 50 40 34 41 38 34 39 44 42 51 59 66 67 76 88 61 75 81 60 81 74 74 96 89 74 75 88 84 59 74 123 79 85 112 100 116 126 106 120 139 195 194 199 211 203 175 191 230 225 263 250 288 334 340 344 318 206 298 349 355 345 321 304 272 272 261 267 268 252 284 267 238 240 219 193 178 172 140 119 121 111 109 111 114 122 78 91 109 101 99 90 87 85 81 66 65 65 75 52 72 64 78 71 73 81 43 53 43 50 51 44 54 55 46 46 17 4 0 0 0 0 +0 0 0 0 3 14 55 70 55 49 47 36 38 33 39 45 70 61 67 68 70 82 69 89 78 88 86 97 101 90 93 90 98 87 77 64 96 119 120 125 135 139 146 153 194 172 191 210 234 253 272 318 293 287 342 431 399 439 414 472 496 465 397 263 342 482 485 466 481 441 412 433 408 368 378 372 376 357 315 325 278 271 235 205 191 175 176 162 171 149 137 144 110 102 124 121 96 106 102 91 96 101 97 80 92 88 97 94 78 89 82 58 44 49 52 48 48 43 74 64 82 43 25 6 0 0 0 0 +0 1 0 1 2 12 47 44 57 27 43 40 31 35 29 44 47 46 54 62 70 75 86 65 62 79 72 70 44 83 78 88 80 82 85 47 74 120 118 123 127 127 166 171 171 183 211 234 252 275 323 322 354 320 332 423 477 481 500 514 497 466 382 247 325 452 481 473 514 468 452 433 407 434 375 386 371 326 335 303 301 278 247 231 223 201 193 170 173 144 138 121 117 106 94 94 80 85 73 97 71 89 84 77 100 86 82 72 96 52 71 68 38 38 49 45 33 56 47 59 63 44 22 2 1 1 0 1 +1 1 1 0 1 14 38 45 54 38 33 39 18 34 21 27 32 49 49 59 56 61 70 75 75 64 56 53 72 75 72 94 68 74 80 60 66 115 109 122 155 134 176 179 179 215 221 253 268 288 328 377 375 362 381 457 449 480 445 432 477 422 306 215 291 376 407 437 432 434 422 426 375 396 382 363 378 347 316 334 336 304 305 230 215 239 219 194 165 163 118 120 108 104 97 105 85 80 89 73 65 93 93 87 80 71 71 64 62 63 64 46 42 36 40 32 35 39 42 45 62 41 26 4 2 0 0 1 +0 2 0 0 4 16 51 45 36 40 33 24 23 25 30 35 39 52 49 44 53 45 61 58 61 59 72 70 64 51 74 92 68 64 70 47 84 107 132 138 172 151 199 248 210 261 265 266 316 313 334 373 396 357 338 443 424 449 454 433 420 372 294 194 269 281 402 401 372 385 392 363 376 415 324 379 320 343 315 335 331 315 318 269 269 271 256 212 181 178 153 144 132 114 106 126 84 84 88 88 72 80 62 70 74 68 72 50 62 63 59 42 42 30 36 34 45 22 46 60 57 40 14 8 4 1 0 0 +0 0 1 0 1 16 43 43 47 34 27 24 30 28 23 27 44 40 43 55 62 54 53 52 45 49 62 64 61 54 52 71 66 82 67 65 78 135 126 136 183 170 216 249 263 308 308 304 324 326 385 362 366 326 305 332 371 343 410 372 379 303 258 171 200 297 308 346 300 372 303 345 345 313 310 356 348 336 331 314 334 344 346 300 298 309 259 253 222 198 177 154 125 115 129 88 74 92 76 77 65 60 85 61 67 65 54 66 43 68 53 44 32 33 37 36 33 41 28 55 56 40 18 4 0 0 0 1 +0 1 2 1 8 19 39 55 36 42 28 28 33 25 18 33 36 45 43 47 49 50 48 47 41 66 48 52 53 58 59 74 82 80 85 50 91 138 193 174 192 212 237 283 261 285 322 326 316 313 348 359 348 297 275 285 312 321 323 352 305 265 203 151 188 257 294 271 282 300 279 275 284 266 283 330 284 275 286 320 332 314 327 374 318 331 282 294 244 254 185 188 137 136 83 107 93 74 83 64 58 62 63 58 61 63 52 62 50 51 43 47 22 29 40 36 52 37 47 45 51 50 22 7 0 0 0 1 +0 0 0 0 3 22 33 34 21 36 33 31 21 25 26 32 23 37 45 45 44 53 39 54 51 57 53 59 70 61 56 98 80 83 96 54 100 156 164 192 222 247 264 270 298 331 333 322 347 341 347 313 311 282 243 254 301 297 297 283 290 244 176 112 144 200 225 210 218 245 242 223 238 252 285 261 265 276 284 290 299 315 335 377 332 347 317 281 278 251 239 208 162 160 143 125 80 80 72 69 70 73 66 61 68 59 64 64 52 42 54 57 33 29 30 25 35 27 41 42 45 54 22 11 0 0 0 0 +0 0 2 1 8 27 36 34 31 31 28 29 27 27 25 32 42 51 39 56 53 39 54 56 43 59 50 74 67 68 67 75 91 115 96 70 110 175 201 212 214 261 275 275 334 321 317 356 326 306 309 287 266 263 189 212 214 232 243 225 216 198 147 100 129 171 193 192 241 201 184 194 161 204 228 244 240 225 266 277 274 287 300 293 310 298 331 334 297 233 245 224 171 167 130 111 142 80 79 91 62 76 83 59 67 58 56 48 48 48 43 50 28 26 35 35 32 45 32 47 53 45 34 9 0 0 0 0 +0 0 0 0 13 26 46 47 43 25 37 30 33 32 33 38 48 46 64 60 52 57 72 55 62 59 72 79 92 82 103 126 156 127 118 122 191 231 254 310 275 331 357 394 377 350 397 386 338 321 306 287 287 233 221 171 219 221 229 192 169 183 152 93 130 177 210 186 182 179 163 173 159 184 171 221 211 242 228 250 279 303 304 379 374 378 361 355 358 301 331 309 241 229 211 193 140 139 122 96 85 92 65 58 73 62 58 64 73 57 66 58 66 40 22 36 26 32 51 49 63 57 23 12 1 0 0 0 +1 0 0 1 10 33 54 50 57 54 40 47 38 32 33 34 68 78 72 76 73 69 80 59 54 66 88 63 90 110 135 143 184 192 195 142 240 353 376 430 405 422 436 484 457 449 411 390 366 326 316 323 303 255 223 213 192 197 214 220 211 191 147 103 132 191 193 212 191 196 177 188 160 175 219 211 268 266 247 262 284 341 317 403 465 431 425 436 484 432 495 440 369 309 349 320 253 208 187 153 139 121 103 89 115 108 82 95 79 87 91 71 66 51 53 55 61 54 65 62 88 74 22 8 0 0 0 0 +0 0 0 2 6 34 48 46 45 54 48 43 41 43 35 45 52 52 44 59 63 68 63 74 68 81 91 104 107 129 117 183 181 200 221 135 240 369 429 436 420 427 448 406 380 329 340 266 245 241 273 208 225 192 158 128 141 203 168 183 198 145 119 77 78 157 149 151 183 158 143 134 146 131 170 188 193 172 201 234 210 255 285 334 365 377 447 415 457 508 498 479 384 397 395 345 313 244 223 198 162 142 120 133 123 84 116 91 103 98 83 77 51 47 50 36 67 48 59 73 84 56 21 4 1 2 1 0 +1 0 0 0 11 29 61 57 58 40 38 47 21 47 37 44 43 66 70 85 83 75 88 52 109 97 101 120 138 159 203 218 289 336 327 182 298 453 506 485 413 472 397 380 345 344 236 237 208 166 201 191 162 165 161 134 145 139 164 196 190 140 123 88 89 125 165 139 160 130 155 150 108 142 137 159 135 143 137 138 175 184 215 209 273 312 305 314 363 389 451 422 389 388 386 341 312 285 282 209 190 181 114 126 109 118 95 84 92 83 81 87 71 53 52 72 62 61 45 82 78 61 35 8 0 1 0 0 +0 0 0 1 4 41 64 80 73 56 54 50 42 46 49 57 54 90 106 93 86 87 101 101 111 119 119 140 186 246 267 301 392 396 394 239 366 522 550 563 499 459 407 335 350 299 250 226 200 195 198 170 208 197 172 166 155 182 189 223 200 167 147 94 135 178 186 218 195 183 201 192 160 184 169 181 178 155 175 196 175 186 193 209 297 279 318 337 363 450 442 523 470 528 553 524 476 446 402 368 306 233 190 177 149 136 118 117 114 126 95 97 63 53 65 69 72 86 67 96 96 74 30 7 2 0 0 0 +0 1 0 1 6 20 55 90 79 71 60 52 51 48 63 46 71 95 81 95 89 92 95 106 104 121 144 147 239 275 330 425 439 451 448 244 350 484 577 515 429 391 330 272 256 240 226 183 166 183 182 161 187 185 198 158 163 159 205 204 222 206 141 96 147 160 187 213 198 190 178 176 177 166 159 177 171 167 166 154 168 158 180 199 223 233 272 262 356 396 410 466 474 549 531 573 558 500 479 433 413 332 249 193 167 149 144 132 153 128 89 106 75 68 61 61 67 64 83 90 82 70 30 10 0 0 0 0 +0 0 0 0 4 33 64 73 77 62 51 49 46 47 47 58 76 97 98 86 100 108 123 104 130 139 189 222 278 322 360 441 449 475 382 252 285 428 477 426 354 284 235 196 160 174 179 166 171 162 192 172 162 152 174 183 167 158 182 224 218 200 149 98 132 192 192 151 177 180 174 159 168 176 189 185 163 156 165 142 149 130 168 177 168 175 186 213 252 290 324 365 385 456 508 505 489 562 572 481 499 414 317 269 226 191 152 165 149 129 133 114 87 57 60 65 66 46 89 77 83 78 26 5 0 0 0 0 +0 2 0 0 8 33 80 86 73 75 54 64 53 54 54 50 70 71 106 86 108 112 116 149 160 188 226 269 330 358 369 434 454 419 379 211 224 371 386 358 270 226 226 181 191 173 180 165 152 172 169 192 181 173 184 206 182 168 197 201 206 196 129 112 149 175 188 198 182 179 169 182 192 183 172 200 156 158 137 170 148 166 175 165 166 170 186 173 218 217 226 312 334 401 446 474 454 540 582 552 541 528 401 338 302 237 198 162 139 128 109 81 82 67 59 63 76 69 105 88 103 56 25 6 0 0 1 2 +0 1 0 1 3 28 67 91 62 67 55 57 51 43 40 56 68 97 88 92 111 110 148 154 194 244 257 326 369 384 438 389 409 396 334 204 180 291 293 260 235 176 166 188 178 185 161 176 151 155 183 193 183 191 192 217 218 191 184 214 235 221 177 126 150 186 222 210 193 221 194 200 202 188 167 194 172 182 143 159 136 154 162 155 185 175 159 183 184 202 217 280 258 310 337 407 381 504 520 563 575 584 490 434 371 304 217 161 161 145 132 111 68 69 63 76 65 70 97 104 104 82 27 3 0 0 0 1 +0 0 0 0 8 38 86 77 61 56 42 58 45 46 32 48 73 85 102 94 114 132 145 214 238 272 308 377 417 442 380 382 384 342 250 155 149 223 223 232 176 168 180 174 181 151 176 160 169 147 196 202 202 213 233 226 266 227 202 242 244 256 188 183 178 226 206 258 253 228 233 225 210 192 223 214 190 181 166 172 168 165 176 185 174 193 168 165 195 158 207 206 196 280 290 345 377 427 518 521 627 644 585 515 442 408 298 225 183 129 127 108 74 83 81 69 85 70 98 110 103 89 30 6 0 1 1 0 +0 0 0 1 6 37 71 87 64 70 57 63 58 66 46 58 87 97 119 114 126 149 152 222 268 382 328 414 437 441 402 374 375 303 230 126 127 168 199 226 179 155 171 189 164 173 168 186 167 182 218 222 229 233 247 256 273 300 239 305 339 329 288 255 281 328 331 353 297 323 300 272 255 265 245 212 209 185 188 189 190 200 183 170 183 204 173 175 199 179 175 186 180 217 250 276 321 361 472 501 583 578 625 532 498 505 340 288 208 168 130 118 98 79 86 80 69 65 96 105 108 71 23 9 0 1 0 1 +0 0 0 1 7 36 80 86 78 74 63 74 69 42 52 54 105 107 107 134 142 196 247 291 323 366 407 406 409 394 368 359 306 275 191 126 93 160 195 241 167 200 170 172 205 193 174 186 214 220 209 267 313 306 347 382 421 451 397 440 509 575 431 415 414 498 517 517 487 474 466 431 381 357 313 315 270 254 216 227 233 205 173 189 193 191 187 194 166 179 153 182 198 191 219 243 276 322 388 456 523 639 634 626 568 495 453 358 296 238 163 161 121 88 69 88 89 87 103 106 112 77 55 8 1 0 0 0 +0 0 0 2 14 36 78 79 73 65 74 61 62 51 60 81 89 118 132 163 174 215 280 300 396 432 430 429 458 410 370 312 260 224 167 74 83 172 177 186 200 188 188 202 187 208 212 228 241 269 287 352 409 447 485 595 659 706 636 642 725 777 715 554 701 682 725 697 708 659 660 591 577 528 479 422 367 351 323 277 285 240 222 213 201 195 192 180 191 189 168 176 176 174 173 216 219 294 326 433 510 513 611 631 656 607 517 452 328 270 185 145 110 96 104 91 94 86 91 102 99 98 46 4 1 0 0 0 +0 0 0 1 16 47 69 92 72 64 69 61 58 66 66 76 108 108 172 186 230 269 329 363 411 429 404 417 374 358 285 256 232 187 155 76 124 150 167 203 172 197 198 225 209 211 222 247 285 334 445 467 579 658 747 804 866 862 852 772 882 835 847 739 792 833 861 861 849 848 821 810 772 730 672 632 602 512 417 410 336 288 273 242 227 228 200 167 172 185 179 167 161 165 189 200 204 219 267 343 382 502 580 665 700 634 584 533 424 381 249 204 132 101 94 82 100 85 109 95 143 131 58 15 2 0 0 0 +0 0 0 1 3 37 99 102 78 77 72 60 57 76 56 74 112 140 174 211 283 316 351 394 419 408 434 390 323 296 251 215 198 191 135 82 108 152 194 228 162 167 199 206 215 288 296 349 384 447 610 712 818 849 878 881 954 912 869 787 824 904 860 692 739 752 831 852 795 825 823 815 807 813 824 817 818 678 629 554 563 413 351 303 260 263 238 198 206 180 207 211 165 161 176 197 175 203 224 274 343 429 493 515 615 652 654 572 531 475 327 224 157 93 84 91 94 94 125 105 130 138 64 24 2 0 0 0 +0 1 0 2 14 58 93 92 82 73 72 83 84 74 76 88 137 168 203 207 283 360 404 364 382 396 358 352 298 211 221 204 162 167 148 80 113 166 173 186 166 221 219 225 265 265 357 486 529 629 790 832 844 921 867 856 831 798 792 681 714 690 700 601 628 643 670 663 742 709 666 635 764 781 864 883 892 881 775 784 703 576 519 420 384 275 250 206 197 170 199 192 174 176 182 184 185 202 212 211 283 331 374 472 537 626 646 648 582 500 406 276 183 126 114 119 87 96 97 106 123 157 76 21 2 1 1 0 +0 0 0 1 17 63 96 88 83 78 77 65 61 68 73 93 152 176 228 304 314 348 436 361 406 346 320 302 290 232 186 192 181 167 149 85 119 162 192 189 183 187 241 265 336 414 515 642 796 836 866 895 896 870 764 694 633 703 598 554 560 577 497 537 556 509 488 524 537 529 564 530 580 638 738 778 850 851 880 995 922 741 696 580 476 405 299 248 196 222 207 195 184 177 175 199 214 172 191 231 231 278 331 408 499 524 668 733 667 585 459 406 266 189 166 138 109 124 92 127 134 121 93 36 6 1 0 0 +0 1 1 4 19 50 96 99 95 73 80 83 87 84 96 115 148 215 243 329 376 400 416 364 359 350 304 260 208 178 170 180 211 181 135 88 131 181 194 194 197 235 266 308 436 522 685 840 874 846 870 839 792 647 612 545 530 498 496 446 468 453 458 443 407 392 430 418 422 436 461 441 451 492 593 626 716 704 776 931 963 870 787 753 653 555 417 321 271 255 275 226 187 182 196 210 212 191 184 190 211 254 266 330 450 534 674 702 686 672 516 465 293 195 166 139 133 134 125 130 134 137 83 29 4 1 1 0 +0 0 0 0 18 50 93 90 104 84 70 98 65 79 69 124 164 250 313 397 399 427 441 370 327 325 252 207 183 170 165 181 172 175 173 75 124 206 233 215 247 283 357 501 615 696 797 818 808 755 734 662 572 543 469 428 405 420 412 401 348 392 407 375 391 349 374 376 403 364 367 358 370 400 451 468 511 534 628 680 828 800 837 854 847 680 544 425 350 296 258 211 200 187 195 174 206 165 185 169 201 225 256 295 360 486 597 701 679 601 519 427 321 218 176 194 135 129 115 120 139 131 71 27 4 0 0 0 +0 0 0 1 15 55 98 107 80 96 77 68 73 101 89 125 194 293 338 472 448 487 431 412 314 297 204 189 165 154 141 143 180 185 151 108 116 168 211 219 271 365 478 626 690 744 761 706 614 465 443 392 306 327 294 306 340 323 329 297 254 288 314 271 283 308 310 328 290 315 300 293 295 275 317 291 348 342 389 472 569 604 656 771 817 736 660 482 413 269 266 201 160 193 162 145 143 145 137 134 155 154 174 214 289 367 414 479 498 480 422 343 250 183 147 148 125 115 103 82 119 86 68 14 3 0 1 0 +0 1 0 1 9 43 87 105 101 92 91 92 87 97 106 161 236 311 380 423 474 421 407 371 303 226 196 151 140 149 150 150 166 144 137 111 165 201 259 306 378 511 624 761 759 735 694 570 439 390 330 260 250 277 243 272 310 320 308 285 235 274 296 205 160 272 284 274 255 236 204 181 172 208 199 181 199 199 206 220 253 300 373 453 504 537 480 434 327 236 162 113 113 105 107 101 100 95 90 95 97 95 102 132 155 196 269 306 328 334 333 289 192 167 133 133 87 78 81 100 86 89 46 19 1 1 0 0 +0 0 1 1 10 39 104 116 116 119 116 102 98 123 114 199 280 397 447 525 520 447 382 359 277 211 178 147 162 157 133 168 170 210 184 189 183 261 317 449 565 711 863 900 854 768 635 563 449 440 392 349 341 391 403 432 468 449 449 416 414 421 462 285 166 391 438 465 456 439 368 372 320 287 321 318 318 303 298 280 297 335 428 486 617 673 702 664 589 447 352 254 181 155 139 182 132 155 138 166 149 152 161 170 216 270 321 426 514 565 552 521 313 254 225 219 169 181 146 136 152 119 78 18 1 0 0 0 +0 0 0 0 6 43 92 152 141 117 110 121 125 145 167 221 335 400 487 534 549 468 423 315 263 188 184 149 162 190 181 162 160 179 170 216 223 314 417 576 789 898 904 850 743 638 523 459 423 407 419 428 429 476 511 527 547 565 547 543 525 528 483 324 177 402 598 669 626 567 562 596 527 528 553 448 505 464 443 403 392 456 533 552 640 827 924 879 865 767 588 474 324 269 260 248 214 206 214 216 205 203 199 215 291 343 439 547 701 731 701 681 454 386 324 286 248 236 217 193 210 149 67 16 1 0 0 0 +0 0 0 3 6 41 101 150 161 140 124 120 145 183 203 259 381 431 538 552 570 451 386 286 224 191 157 194 158 174 136 188 197 216 239 223 301 462 654 766 1038 911 828 743 584 507 435 368 404 418 445 490 554 577 579 582 640 639 675 658 603 584 538 312 148 408 641 740 730 702 700 674 605 622 612 622 608 553 510 466 451 442 478 594 615 785 833 975 1047 978 794 647 496 352 292 260 221 206 221 221 213 228 220 235 261 309 396 485 586 706 709 595 494 393 354 362 295 250 204 238 191 157 57 14 0 0 0 0 +1 2 1 2 12 38 95 131 164 139 148 169 187 169 225 291 396 510 545 573 534 360 305 241 241 164 183 180 161 173 165 181 191 249 232 283 376 561 762 893 932 901 744 640 471 393 350 363 393 431 488 496 547 539 553 591 615 634 663 610 586 528 456 281 127 352 596 686 665 633 628 639 633 674 614 606 565 564 504 433 411 397 459 486 499 575 747 818 945 935 869 694 546 425 331 307 218 212 235 192 181 196 217 181 214 263 313 421 499 605 693 552 454 395 384 366 337 298 250 258 200 130 56 6 1 1 0 0 +0 0 1 0 7 45 102 128 160 143 160 166 180 213 213 290 412 503 490 515 435 333 263 194 162 166 142 167 147 152 163 173 161 229 261 254 345 622 730 785 729 664 507 424 354 344 324 382 368 415 419 466 528 513 537 566 567 596 562 589 506 478 435 251 149 323 520 596 636 609 634 607 617 601 644 579 612 560 541 492 429 458 486 458 481 514 547 640 792 917 996 879 722 546 474 332 251 235 241 246 228 231 232 199 236 265 288 376 487 649 686 717 538 467 471 484 439 383 363 302 277 164 68 9 0 1 0 0 +0 0 0 0 6 48 79 143 120 129 149 158 179 212 247 275 394 497 496 419 369 315 226 183 153 161 159 157 152 196 159 186 208 288 386 298 434 803 887 864 753 580 496 407 463 381 430 466 444 490 568 577 598 590 630 667 671 624 678 634 595 489 509 344 164 408 559 664 663 682 675 711 684 745 680 666 674 650 624 570 517 561 572 517 496 507 505 585 655 888 985 971 960 732 612 476 328 285 289 213 262 223 229 231 253 250 246 319 451 589 642 711 505 491 522 541 472 382 408 331 271 214 78 11 1 0 0 0 +0 0 0 3 14 61 120 176 179 175 205 223 241 297 331 385 494 569 551 536 390 267 231 217 190 191 171 176 177 194 216 228 300 421 515 413 524 884 1039 882 703 523 434 424 449 471 478 527 568 571 603 618 634 680 599 583 593 620 585 615 554 519 478 329 222 398 580 606 626 601 616 698 678 672 656 666 682 654 624 640 607 623 584 565 565 475 475 518 553 695 846 958 898 843 760 602 464 326 278 265 248 242 231 193 214 222 232 271 358 526 620 637 533 549 524 550 487 431 421 375 346 205 68 13 0 0 0 0 +0 0 1 1 8 62 125 163 165 207 227 247 269 315 335 391 532 585 533 459 344 271 212 188 172 188 183 178 183 204 189 252 332 466 570 505 554 901 929 744 534 467 429 454 494 507 555 557 592 581 630 652 638 644 592 553 579 516 545 584 487 434 422 332 178 351 549 542 559 564 548 583 584 588 618 622 626 653 656 634 644 597 616 604 596 524 499 439 482 557 657 807 854 843 894 733 580 413 336 279 217 225 215 200 205 209 233 266 321 453 573 613 542 496 564 546 561 473 469 442 399 211 84 14 1 0 0 0 +0 0 0 2 17 78 161 188 193 212 239 265 326 307 369 408 538 572 489 438 327 240 212 171 171 160 207 175 184 182 207 325 442 590 695 567 563 811 791 645 510 443 407 457 517 511 534 570 581 601 617 601 620 599 569 533 501 526 486 487 487 379 393 308 158 340 488 547 489 540 511 504 506 549 545 578 583 594 646 580 577 609 646 655 625 559 522 440 501 485 592 674 755 881 959 864 714 524 375 292 244 244 202 208 216 180 196 250 273 350 453 588 513 535 585 569 559 582 518 473 408 319 125 22 2 0 0 0 +1 0 1 2 18 84 159 212 203 240 305 303 376 336 347 436 501 551 429 352 272 240 188 152 168 159 158 176 199 217 221 325 508 676 749 550 501 783 684 573 430 445 430 524 509 560 577 558 612 630 601 627 602 551 538 507 524 456 449 439 390 395 330 301 166 271 392 449 465 513 499 460 456 484 447 540 534 572 562 586 628 635 623 632 572 608 518 458 454 449 473 533 670 766 887 924 776 583 452 320 280 250 190 198 216 220 222 214 226 349 395 490 449 464 483 557 578 609 557 515 422 328 184 30 3 0 0 0 +0 0 0 3 32 87 162 206 212 275 307 321 349 373 383 415 532 483 456 329 265 170 192 138 154 163 137 180 179 221 273 436 626 804 831 529 456 672 562 467 433 416 512 521 509 558 579 593 567 567 558 588 500 479 461 451 431 433 445 415 417 385 305 273 173 295 383 456 388 399 453 425 426 377 412 467 483 511 505 566 614 631 586 621 630 582 580 504 472 413 415 472 504 700 822 997 902 685 519 393 257 226 195 189 183 174 171 204 249 254 327 451 402 464 490 549 593 636 561 602 561 387 185 58 6 0 0 0 +0 0 1 4 36 111 188 211 264 294 318 374 373 381 420 475 527 448 361 291 205 221 162 153 154 154 147 183 203 261 303 526 761 920 890 549 394 523 466 461 437 458 529 527 612 597 581 661 652 557 566 519 502 423 373 393 390 373 410 401 420 331 305 298 203 266 384 381 402 384 403 348 391 378 392 428 454 447 491 557 636 555 578 613 599 622 535 480 462 457 467 427 412 610 789 1061 991 794 599 437 292 237 201 157 177 179 186 194 228 228 280 372 412 420 526 486 619 647 666 599 551 436 219 63 8 1 0 0 +1 0 1 5 34 105 194 235 310 315 331 396 397 432 383 440 499 464 369 270 205 185 140 160 166 167 182 192 211 276 394 595 857 864 782 477 393 480 439 452 476 513 531 541 574 603 643 653 622 523 536 475 439 385 394 391 329 340 336 347 349 333 329 279 158 234 327 407 409 394 370 351 361 351 386 454 446 445 486 506 537 558 603 643 643 605 538 517 501 436 449 435 406 470 705 919 934 877 712 482 350 260 210 194 157 174 187 167 217 229 261 342 330 398 511 564 571 668 675 694 616 509 226 61 4 2 0 0 +0 1 0 1 17 105 209 272 326 346 382 422 457 397 406 394 527 466 383 239 178 167 184 152 161 162 177 216 247 302 406 688 933 933 748 424 291 409 427 473 491 479 563 603 622 588 557 610 517 531 453 463 465 394 395 382 361 354 373 359 355 312 271 221 133 200 348 381 367 391 389 328 342 397 389 371 390 358 431 490 501 506 537 577 610 671 587 566 541 516 466 453 370 460 620 794 849 840 770 602 413 250 216 203 220 191 210 214 214 221 270 289 301 377 403 525 568 714 731 761 719 515 209 40 8 1 0 0 +0 0 0 1 15 92 231 296 333 358 430 474 486 433 424 471 514 423 363 244 209 194 157 162 159 170 211 215 247 334 490 772 973 886 704 378 278 409 440 526 482 544 560 620 625 590 569 573 507 456 485 461 431 428 369 370 351 351 337 367 329 344 279 227 139 215 372 378 403 337 364 365 352 341 362 376 359 418 424 415 452 501 552 592 641 631 653 655 601 555 503 450 365 411 562 700 870 948 824 671 499 348 257 219 225 200 188 216 193 240 221 278 270 291 415 495 585 708 783 846 829 579 275 43 1 0 0 0 +0 0 1 1 6 85 212 315 361 457 483 487 487 490 452 451 508 403 332 259 210 198 171 191 184 198 217 209 295 424 629 821 956 911 651 369 245 398 409 557 587 526 635 606 640 604 592 535 475 449 419 419 363 394 359 366 339 337 335 361 346 321 270 222 151 207 319 389 380 407 368 357 344 361 352 363 377 347 425 390 478 462 534 577 596 649 659 659 604 571 511 466 417 386 545 595 848 938 975 781 595 340 272 231 225 205 205 161 221 227 237 252 233 333 412 491 566 710 802 892 901 661 273 61 2 1 0 0 +0 1 0 0 12 79 225 344 398 472 500 563 499 473 468 501 490 423 352 229 203 183 185 209 183 198 220 248 349 530 654 900 972 814 581 319 241 396 467 518 551 575 589 632 654 652 576 555 527 420 446 402 365 361 374 357 359 337 335 327 330 321 288 243 120 187 336 357 347 408 375 358 367 348 334 372 362 401 423 423 452 485 528 571 605 637 653 647 678 609 553 513 422 406 422 575 775 937 965 867 631 436 295 228 239 208 202 178 191 172 235 226 217 282 347 483 619 706 848 876 953 749 255 39 4 0 0 0 +0 0 0 0 10 83 237 337 452 517 539 546 546 524 469 462 502 440 274 247 232 170 192 194 183 234 212 273 402 551 719 846 869 824 568 279 246 355 468 619 645 628 664 681 589 591 543 505 434 432 401 387 360 380 344 356 336 305 312 350 338 351 280 232 124 192 356 393 429 334 334 353 358 331 356 379 366 381 407 448 404 446 512 533 547 599 611 677 615 611 580 532 433 400 406 517 675 863 988 913 773 471 323 262 248 225 182 184 202 202 224 213 221 279 320 421 603 636 874 948 991 762 323 44 1 0 0 0 +0 0 0 0 11 82 228 402 461 572 547 577 582 513 482 445 440 384 285 242 188 189 207 184 212 206 268 261 440 635 788 881 886 680 474 254 248 367 531 636 587 623 659 654 637 538 484 453 406 368 368 396 336 321 363 343 336 334 313 324 321 329 265 200 128 169 283 332 327 346 352 395 390 354 364 355 408 346 355 377 366 430 478 505 575 568 632 619 705 644 585 562 429 364 411 472 555 789 913 903 752 559 353 271 272 207 232 227 209 208 220 207 206 228 319 414 553 667 833 1024 1103 766 268 39 4 0 0 0 +0 0 0 2 8 94 251 414 524 545 573 590 582 511 428 435 447 376 265 214 187 199 179 202 199 223 268 357 476 636 794 854 836 614 434 249 232 410 504 602 618 655 627 642 579 548 457 425 425 397 361 354 384 334 349 316 339 330 269 291 282 282 246 143 114 177 269 305 352 326 400 347 363 356 322 324 348 367 363 340 364 371 452 452 540 596 628 643 647 679 636 601 418 395 403 417 551 693 906 968 915 615 428 303 261 222 228 225 218 212 219 175 197 215 313 372 503 641 864 965 1098 740 266 39 2 0 1 0 +0 0 0 0 9 84 261 447 575 646 618 647 609 543 479 454 413 316 243 232 179 194 220 222 240 252 269 362 485 765 929 843 805 579 440 258 243 424 512 616 662 651 687 607 593 538 482 440 386 368 413 336 388 309 313 349 345 287 282 271 314 298 229 186 103 168 292 306 346 325 326 330 343 373 370 331 342 360 382 371 369 438 462 451 511 571 653 648 706 688 635 533 475 410 447 423 489 664 902 990 830 677 443 296 235 212 213 196 195 211 191 185 180 237 276 389 496 696 805 1107 1097 754 268 48 3 1 0 0 +0 0 0 2 18 75 288 463 541 671 652 643 637 581 510 427 440 365 238 206 217 199 184 214 218 242 265 430 534 766 874 943 785 574 403 208 241 427 578 697 695 689 637 593 581 534 493 430 379 412 357 415 342 333 350 324 300 303 271 251 292 259 232 158 124 180 252 292 292 281 323 364 354 354 381 335 336 397 352 388 385 402 471 450 506 619 584 659 704 681 688 651 467 459 443 421 451 670 894 1016 892 691 492 327 266 244 203 225 217 229 195 187 207 225 277 413 532 655 883 1071 1083 759 300 39 1 0 0 0 +0 1 0 1 13 105 278 456 650 645 688 692 647 587 545 444 469 349 298 218 204 216 207 233 229 252 297 415 660 900 981 948 843 594 439 224 261 442 609 705 697 717 620 601 668 529 535 470 416 397 405 377 362 361 351 345 324 298 238 152 167 158 134 100 63 100 151 159 178 218 296 358 363 390 349 353 389 356 368 375 375 449 435 514 515 546 624 665 727 679 650 582 481 424 458 456 475 653 855 1011 978 745 510 353 310 220 215 210 234 222 210 217 226 238 304 364 490 619 811 1041 1104 863 354 54 4 1 0 0 +0 0 0 2 17 104 333 538 637 679 706 719 687 588 555 489 525 379 287 266 219 242 246 222 216 286 314 468 725 909 1070 1031 802 559 459 251 301 508 651 700 729 688 681 649 592 579 505 477 440 447 420 409 367 351 329 371 362 304 194 46 37 50 24 22 15 27 26 31 47 154 324 402 371 397 354 384 408 391 406 408 440 403 501 534 509 546 602 701 655 700 663 650 505 528 513 457 481 628 793 1031 978 778 562 342 265 245 236 212 207 217 228 225 226 213 279 379 520 654 789 1061 1180 932 381 63 4 1 0 0 +0 0 0 1 18 135 356 594 655 656 776 749 730 663 569 484 494 409 279 262 269 254 259 241 225 260 325 509 698 1008 1115 1057 843 548 452 267 305 511 632 667 618 635 604 620 549 528 460 442 361 411 382 357 376 370 326 337 324 294 157 25 5 3 3 3 2 4 8 4 28 126 296 351 351 321 377 385 379 380 377 397 397 419 475 500 570 604 640 636 696 713 733 690 585 488 528 518 545 649 876 1014 1011 851 584 432 334 234 256 235 231 232 264 246 190 240 307 405 473 657 836 989 1251 1066 484 98 7 0 0 0 +0 0 0 5 20 141 381 569 688 718 738 680 654 610 530 486 478 319 289 215 215 229 185 197 191 205 310 432 589 787 835 807 560 472 333 202 230 427 502 555 530 532 550 473 448 404 382 314 322 296 303 318 306 315 263 263 268 232 109 17 3 3 0 0 1 1 1 4 22 112 246 284 279 280 295 301 281 274 290 281 296 343 368 436 464 520 491 490 514 541 609 585 499 473 453 449 505 626 792 1044 1004 879 572 374 310 234 240 257 248 235 191 204 180 204 266 369 452 621 814 956 1132 1062 548 126 10 0 0 1 +0 1 0 2 19 131 305 441 531 531 522 494 466 389 344 327 326 278 200 157 138 168 155 165 176 190 226 357 546 733 765 764 615 423 375 219 235 400 473 597 537 550 556 514 483 429 393 384 366 355 313 289 340 301 253 262 293 217 126 24 1 3 3 2 0 1 1 7 32 102 251 284 248 263 265 267 277 232 257 292 253 251 282 306 355 339 404 378 392 410 431 435 359 356 343 334 368 439 538 737 743 633 452 304 233 194 164 180 153 133 170 157 143 158 206 249 306 407 557 737 839 805 441 105 10 0 0 0 +0 0 0 3 31 151 338 483 527 545 495 461 431 380 310 261 247 174 136 129 126 128 115 117 114 149 194 285 433 576 656 643 552 344 283 201 182 326 328 361 359 321 306 324 316 272 262 278 268 264 241 204 243 234 211 217 211 184 98 18 0 1 2 0 0 2 3 3 18 78 136 154 126 168 169 191 204 199 194 209 190 218 223 231 264 261 267 304 306 316 276 294 256 302 316 287 319 371 533 636 595 517 346 203 158 131 138 123 98 100 104 99 87 75 99 144 214 280 359 426 551 561 323 103 12 0 0 0 +0 1 0 6 48 256 405 571 594 615 562 553 415 381 340 280 282 175 141 129 131 97 100 134 113 117 152 234 346 436 507 559 425 291 226 119 169 275 300 340 348 303 296 303 268 261 244 247 238 229 166 191 182 191 156 165 147 164 83 11 3 3 0 1 0 0 0 1 11 74 116 134 140 119 155 155 196 172 149 162 182 168 167 160 187 201 208 233 225 252 220 240 223 257 276 306 300 347 433 511 529 413 288 209 139 114 103 92 101 83 93 92 93 89 93 124 182 264 334 463 632 591 436 127 22 0 0 0 +0 0 0 5 56 221 450 541 616 671 690 612 584 502 452 446 433 298 221 190 198 211 182 160 148 196 253 368 570 737 839 785 610 432 356 198 220 471 464 492 512 499 467 498 472 413 406 393 340 309 287 327 313 284 258 243 223 224 112 13 1 1 2 1 2 1 1 5 18 93 198 211 222 258 220 274 292 291 271 287 283 295 280 349 334 367 396 403 442 459 458 448 342 339 369 374 409 441 619 775 717 611 443 268 236 184 187 170 155 153 149 149 136 142 214 225 369 447 583 705 898 885 574 173 16 3 0 0 +1 0 0 8 36 208 408 579 630 666 720 716 659 569 501 470 460 345 257 222 230 231 222 212 211 239 307 471 668 897 961 928 779 588 385 243 293 532 616 653 654 599 589 605 534 479 452 435 403 363 321 365 350 337 335 272 310 283 122 24 1 0 3 4 1 0 5 3 27 147 273 318 285 289 352 314 321 330 301 322 345 371 396 399 495 487 518 575 596 586 591 522 480 470 458 391 481 546 769 904 934 747 534 387 229 247 209 207 215 205 215 191 180 187 254 333 449 544 678 920 1100 999 561 149 19 0 1 0 +1 0 0 3 40 142 354 547 580 636 694 705 695 575 507 487 525 419 301 281 244 231 224 218 260 285 297 480 689 946 1065 1022 851 608 427 245 319 548 687 677 740 669 691 590 588 500 485 454 410 373 383 356 356 353 379 339 340 293 118 31 6 4 2 1 3 3 4 5 32 142 302 333 310 345 334 333 334 331 340 357 380 387 458 457 536 592 625 623 691 714 640 595 484 447 449 406 483 561 766 910 913 779 561 393 291 275 244 203 227 193 229 216 196 192 303 341 458 592 748 930 1102 969 495 107 5 0 0 0 +0 2 0 3 14 122 324 540 620 657 710 717 680 597 531 458 497 406 280 227 218 228 215 234 239 271 288 456 725 950 1032 1057 886 566 439 250 280 581 656 723 730 709 648 594 611 523 457 456 433 362 394 396 395 377 360 317 348 274 137 23 14 25 20 15 14 13 20 18 46 134 296 339 351 346 313 342 338 364 349 344 383 387 455 457 529 619 656 631 719 660 614 579 493 459 430 446 453 594 792 972 942 788 563 329 277 271 226 212 244 223 234 230 199 202 268 413 510 650 738 957 1082 836 362 68 6 0 0 0 +0 0 0 1 10 93 260 483 577 645 663 670 678 599 545 484 491 443 300 272 205 265 221 233 244 247 292 422 694 872 1089 1007 832 660 440 247 297 476 599 671 719 714 650 635 564 531 487 450 393 373 371 375 358 341 316 320 328 320 189 111 115 128 116 96 51 91 102 108 123 167 293 355 364 318 324 321 335 326 366 384 334 438 452 477 535 596 616 701 636 700 659 575 437 438 437 424 497 685 807 962 913 761 476 357 263 241 249 230 219 213 218 190 196 248 277 374 442 561 783 902 1010 736 282 46 4 2 0 0 +0 0 1 2 13 73 259 442 606 590 687 620 600 579 489 439 485 423 302 228 218 217 235 246 229 286 287 403 607 850 957 947 847 614 498 245 295 422 597 631 699 627 674 559 556 546 482 430 409 381 377 370 325 332 300 292 328 325 261 264 264 289 259 195 129 198 290 284 281 293 349 307 299 296 330 333 325 374 345 368 377 454 430 460 539 592 629 694 684 664 629 569 456 407 374 428 518 693 841 950 899 704 518 300 268 243 240 213 235 223 238 205 187 211 287 414 500 600 759 955 994 630 204 26 1 0 0 0 +0 0 0 1 9 81 222 370 528 597 668 627 581 549 495 455 448 412 301 235 221 227 223 240 250 283 296 360 620 778 909 906 875 644 416 269 276 488 580 630 675 658 627 630 525 497 466 410 381 370 342 390 355 372 332 332 315 318 326 303 323 318 290 222 139 238 284 376 335 354 309 329 325 307 330 335 349 334 382 343 376 447 472 495 546 636 687 721 690 622 650 527 375 388 390 462 535 661 847 1020 829 656 455 349 294 206 217 230 188 197 179 210 148 201 255 371 502 586 745 879 826 532 175 17 2 1 1 0 +0 0 0 0 17 65 222 383 503 519 599 626 614 542 483 475 509 454 294 254 218 231 205 252 229 263 285 370 524 724 900 900 876 693 488 225 266 462 525 570 616 576 622 622 561 480 403 376 374 366 370 365 376 339 336 374 318 315 357 324 338 306 286 175 169 216 332 344 343 341 379 346 351 331 356 337 307 349 375 297 369 423 480 537 567 651 648 655 717 684 618 492 376 358 380 431 520 674 861 911 772 587 398 294 245 239 229 209 199 210 198 182 201 236 305 403 448 649 766 906 849 525 148 23 2 0 0 0 +1 0 0 1 5 49 214 370 496 521 605 577 598 626 482 492 531 448 339 275 227 231 204 245 240 235 259 331 494 695 855 914 908 705 494 290 292 418 537 544 571 625 638 601 572 515 505 416 369 377 394 365 370 343 335 335 300 303 319 339 302 343 290 191 116 231 288 325 362 346 298 313 349 334 353 327 373 336 357 337 429 463 540 504 592 616 689 644 726 636 562 463 366 341 440 530 653 815 888 919 710 514 396 279 219 220 216 217 216 179 223 182 188 229 274 388 473 577 696 785 760 485 175 28 3 0 0 0 +1 0 0 0 7 48 199 380 432 508 568 617 564 581 548 527 617 509 384 325 237 224 211 239 222 225 234 296 404 655 811 969 988 816 544 293 271 441 499 581 603 604 606 627 587 542 562 470 438 434 410 407 377 375 348 363 304 329 325 323 355 310 311 226 146 218 313 345 337 351 348 301 328 307 321 328 345 385 358 405 423 497 527 589 594 668 675 691 612 591 535 485 379 380 468 551 694 840 987 840 671 424 323 259 235 219 198 210 205 191 229 204 231 213 324 403 472 608 658 766 693 445 148 33 0 1 0 0 +0 0 0 1 15 66 214 336 463 468 549 557 560 590 570 532 648 558 420 305 224 226 242 222 213 211 261 289 353 574 812 981 1137 920 607 354 284 395 477 544 553 563 588 616 624 585 547 504 474 422 471 439 366 412 357 367 367 349 304 342 336 335 281 244 149 228 312 352 364 380 401 313 327 346 331 342 357 390 424 417 464 539 576 599 619 693 622 631 632 543 523 445 322 398 494 636 803 890 851 766 568 405 289 260 225 203 206 201 221 214 225 222 211 253 320 407 481 548 692 710 628 452 163 16 3 0 0 0 +0 0 0 3 14 56 183 330 449 426 511 550 576 551 544 533 667 587 432 321 260 242 210 204 189 201 242 274 346 451 694 910 1086 965 694 338 300 419 438 525 536 558 593 572 619 625 524 514 488 434 473 407 391 379 371 374 338 351 330 304 339 340 336 252 167 249 358 363 360 350 383 318 334 347 359 369 390 405 468 491 490 520 597 636 658 671 655 620 598 515 496 419 342 410 549 715 857 891 871 673 519 360 280 229 219 214 203 207 247 193 208 244 255 310 332 417 520 539 651 730 642 417 172 26 0 0 1 0 +0 0 0 1 29 80 228 322 382 403 515 564 582 577 507 552 701 617 480 387 261 229 221 160 202 223 233 278 306 382 603 828 960 913 677 380 306 417 433 441 478 581 585 574 609 596 577 535 464 476 491 410 407 402 400 396 335 338 380 353 375 342 309 242 185 260 337 344 375 351 378 340 331 348 389 423 449 427 416 497 535 513 534 596 655 662 668 584 536 464 507 397 383 412 566 785 858 850 773 592 426 290 241 211 183 203 218 193 203 202 209 250 279 299 366 426 475 538 522 626 578 413 191 24 4 0 0 0 +0 0 0 0 17 89 201 270 325 400 461 466 539 523 527 614 776 664 504 352 251 238 210 191 199 209 229 208 275 317 489 716 966 1003 826 421 364 442 474 425 436 513 529 598 574 596 579 572 541 476 472 456 422 412 387 408 348 338 376 356 392 360 321 253 197 276 329 334 361 407 351 398 333 366 395 422 415 431 470 533 532 494 587 601 641 661 578 586 527 488 472 376 365 452 637 792 897 854 680 509 343 232 235 213 197 183 188 184 211 199 244 285 291 297 314 435 475 478 499 598 518 378 175 29 4 0 0 0 +0 0 0 4 19 99 228 265 300 380 417 440 504 516 549 634 778 690 516 375 285 196 183 182 194 190 232 240 270 283 425 707 1046 1060 855 449 414 483 392 405 426 430 500 583 594 641 605 599 596 502 512 445 420 410 377 367 360 376 366 430 415 367 390 334 235 264 332 373 371 349 344 370 373 385 377 444 422 479 516 628 583 636 657 657 688 623 561 532 499 397 431 394 382 547 705 929 959 826 599 414 315 263 191 170 197 187 178 177 192 203 246 295 291 337 336 410 425 463 512 516 472 341 165 38 4 0 0 0 +0 0 0 7 32 103 188 259 287 304 423 450 477 526 562 655 765 686 576 420 288 222 187 211 197 191 200 237 215 286 377 585 886 1030 946 573 505 608 546 464 409 413 499 571 551 647 607 656 608 543 550 458 485 439 414 393 376 363 401 417 394 408 407 314 228 290 365 414 411 482 374 411 400 408 420 487 479 503 489 629 627 630 666 671 632 606 586 480 437 417 426 410 415 598 789 935 839 667 507 344 255 209 189 191 163 144 143 179 190 218 244 288 327 307 367 412 486 516 471 465 438 369 183 55 3 1 0 0 +0 1 1 0 13 92 186 226 249 294 369 425 461 466 513 594 814 746 652 469 350 265 193 213 176 197 196 213 222 292 290 445 701 834 886 599 590 720 615 444 462 433 514 559 579 612 629 622 599 616 548 538 558 537 493 469 450 435 450 480 463 436 430 335 195 266 388 414 451 507 480 458 425 411 496 512 487 525 517 578 594 556 626 665 635 578 485 480 413 414 449 482 512 691 836 827 704 546 404 284 216 207 182 179 172 151 180 217 188 227 273 365 308 343 401 408 462 465 440 424 381 326 170 34 2 1 0 1 +0 0 0 3 20 64 195 249 276 307 320 363 394 432 451 600 750 782 636 509 376 285 208 198 203 207 229 225 215 243 248 392 605 712 874 604 721 868 679 592 529 508 505 552 555 587 637 637 657 563 599 584 599 585 557 523 474 505 503 487 498 458 423 348 218 281 457 512 480 524 504 472 510 483 532 516 543 540 592 617 616 634 608 603 652 591 521 459 451 452 553 560 620 785 880 813 603 421 334 268 235 210 190 164 165 176 170 180 213 236 367 349 356 343 412 446 457 500 415 427 392 277 133 28 2 0 0 0 +0 0 2 0 16 60 153 183 251 255 283 334 363 423 434 562 769 826 771 556 448 311 241 205 196 229 211 217 225 206 274 328 440 610 780 568 718 953 947 685 549 474 467 495 555 563 590 644 608 609 640 616 644 598 627 531 554 520 557 564 529 518 494 390 245 335 517 585 552 536 549 537 531 581 578 559 585 546 628 713 673 599 645 646 551 497 521 483 475 481 639 651 675 855 845 697 554 354 296 218 207 187 203 169 188 176 185 212 236 319 367 407 382 360 419 433 448 426 418 415 345 266 122 25 0 0 1 0 +1 0 0 2 11 46 126 186 197 209 283 317 333 412 458 519 754 847 812 663 508 375 271 216 195 210 208 212 203 229 252 295 420 543 684 485 674 957 1002 861 678 556 457 515 508 515 565 587 638 648 634 669 662 608 613 632 602 635 604 583 611 597 545 402 284 367 532 615 633 652 631 640 686 621 664 679 657 668 681 644 649 631 639 582 520 503 429 484 475 572 771 775 705 867 831 641 403 324 274 238 197 201 195 169 169 210 204 195 262 323 419 440 420 441 417 458 437 435 347 351 330 216 80 21 1 0 0 0 +0 0 0 3 10 49 126 201 194 217 253 270 312 342 375 514 693 813 834 740 625 417 307 241 223 201 219 212 228 197 207 301 347 440 494 425 589 974 1188 1073 913 743 565 495 541 504 530 551 570 646 688 654 670 666 720 678 656 624 643 691 685 635 556 450 269 429 612 663 694 675 712 677 673 667 695 727 641 654 626 589 556 541 552 542 511 454 469 473 560 668 804 931 759 765 684 486 330 224 223 225 179 186 173 183 200 175 169 217 262 348 411 418 380 418 384 347 395 316 291 285 222 164 67 15 0 2 1 0 +0 0 0 0 3 42 112 178 208 180 217 230 278 343 345 477 633 794 779 730 637 492 391 272 230 216 193 236 211 206 219 213 268 322 390 351 451 774 1080 1105 954 803 633 490 484 439 444 506 457 492 534 593 617 678 600 655 621 646 642 647 602 610 528 414 260 336 472 618 648 668 636 649 610 640 611 628 636 523 502 453 438 433 436 438 391 426 442 509 582 729 821 739 565 549 458 363 233 216 185 182 169 160 162 164 171 169 179 214 281 279 378 408 335 327 313 309 325 276 305 244 229 147 69 10 1 1 0 0 +0 0 0 0 6 26 103 140 170 161 163 193 193 248 312 345 538 664 774 647 641 481 384 301 201 191 178 169 176 208 193 161 214 275 267 222 306 553 774 942 936 829 659 546 417 385 417 355 353 432 453 438 556 547 569 554 641 581 638 591 663 598 532 415 228 332 534 694 727 753 745 678 752 666 663 614 636 553 557 448 460 483 470 464 485 516 640 730 850 876 913 747 585 480 348 265 211 197 170 182 177 181 168 184 169 207 232 269 328 436 473 454 399 356 359 337 321 292 307 270 250 177 84 8 2 1 1 1 +1 0 0 1 4 40 104 130 151 130 137 162 168 204 232 320 478 624 723 726 674 594 445 354 250 208 221 201 185 201 178 188 223 261 242 206 255 477 774 1008 1120 1128 991 802 700 533 464 469 419 488 471 514 509 537 594 650 623 648 688 668 683 681 619 424 268 442 653 739 811 803 791 793 756 686 694 666 640 561 583 439 486 414 439 502 512 646 781 871 937 974 901 691 487 404 313 267 188 192 186 184 172 178 169 194 187 206 264 314 413 485 456 504 399 345 330 265 285 264 223 245 217 136 70 12 1 0 0 0 +0 0 1 0 9 49 106 154 149 156 159 166 171 186 235 315 479 694 801 825 783 679 583 434 327 232 223 192 174 205 216 205 265 254 260 168 202 409 603 834 981 1191 1042 980 887 671 589 477 477 448 496 516 496 513 526 559 623 583 585 594 612 597 523 431 258 349 596 711 736 710 687 608 614 615 606 546 515 514 511 460 419 412 453 566 696 797 890 979 979 831 709 504 394 283 234 217 203 171 160 164 175 161 168 200 207 240 282 354 451 514 524 475 361 310 310 258 225 243 202 189 177 138 61 19 0 0 1 0 +0 0 0 1 11 51 104 157 167 113 125 147 154 194 223 263 442 587 703 820 838 683 568 467 340 291 214 206 169 186 185 205 236 233 208 161 179 289 419 581 775 900 1011 1012 1044 856 657 626 492 462 450 479 448 430 471 463 443 496 501 521 611 581 484 346 280 349 568 603 588 568 552 592 536 530 471 440 441 390 419 415 430 498 534 685 736 866 956 926 787 629 478 344 245 221 209 207 164 186 174 180 178 169 175 173 222 224 295 376 495 497 491 453 320 265 279 188 201 152 144 139 167 116 66 20 1 0 0 0 +0 0 0 3 9 52 114 125 134 112 107 113 116 134 170 262 344 491 603 698 715 658 608 471 397 296 235 186 193 182 214 202 237 202 194 121 123 204 267 336 491 609 712 860 832 806 709 599 533 439 408 398 357 371 362 388 391 391 426 473 474 483 432 374 238 282 372 412 359 409 319 350 328 296 293 265 291 275 288 338 323 396 551 542 596 667 612 593 491 408 309 249 191 199 213 191 199 179 145 158 149 133 162 201 184 207 258 303 382 378 396 293 245 169 166 129 113 98 112 92 99 101 66 11 2 0 0 0 +0 0 0 0 10 28 94 105 104 87 110 107 113 108 124 153 235 337 426 557 585 612 524 469 390 294 236 176 159 166 149 164 196 217 191 95 110 184 197 252 282 379 483 662 760 764 718 704 593 525 488 469 407 381 331 361 335 375 393 421 425 448 412 334 206 182 268 224 240 179 179 177 157 143 160 150 192 154 189 192 228 282 320 348 348 280 260 261 194 150 120 117 90 143 153 138 140 137 132 130 134 135 113 112 129 162 194 212 214 231 204 180 147 71 69 53 44 46 42 41 57 50 27 13 2 0 0 0 +0 1 0 1 11 56 100 116 124 101 83 80 87 103 120 166 269 321 443 561 628 637 651 563 475 400 307 236 207 175 200 210 195 193 155 130 124 193 227 231 278 347 436 623 751 796 978 972 906 833 728 659 611 593 452 466 438 407 439 437 398 431 400 372 243 250 342 372 385 369 318 296 265 300 318 318 305 361 382 455 466 546 630 549 591 476 399 312 248 206 179 131 123 154 128 138 128 110 130 147 149 145 146 181 208 246 304 312 320 301 303 215 178 127 118 91 76 82 78 69 90 91 61 28 1 1 0 0 +0 0 1 1 16 63 101 118 96 81 90 81 91 98 101 147 219 330 388 528 634 679 669 635 591 483 409 346 245 204 203 190 218 233 164 128 123 201 212 242 240 285 332 475 560 719 826 989 910 787 872 846 752 710 602 583 504 493 503 502 484 471 419 381 208 330 413 475 467 484 459 438 474 468 487 582 560 611 705 748 757 845 932 938 808 705 498 369 311 244 243 195 161 147 171 152 134 161 144 145 157 173 174 245 314 358 393 442 451 431 356 325 179 164 122 119 106 96 100 125 116 112 92 36 2 0 0 0 +1 0 0 6 23 68 102 103 94 82 92 85 79 78 105 140 198 303 357 425 569 586 689 653 601 512 458 395 304 236 216 226 210 169 183 121 117 190 191 243 222 252 271 346 436 511 600 862 891 772 874 846 836 799 741 676 656 634 585 610 619 580 558 520 316 329 481 515 554 525 569 568 564 554 681 772 782 842 980 1033 1057 901 849 837 695 594 434 331 250 209 215 198 174 165 166 173 117 133 139 151 180 167 201 265 301 385 490 438 493 421 351 275 194 120 116 125 101 98 105 102 124 117 86 38 7 1 0 0 +0 0 0 4 35 55 95 111 108 86 80 68 83 85 91 106 165 224 320 362 471 490 557 581 573 534 500 453 385 297 269 222 170 203 167 93 110 177 191 208 185 218 242 248 275 278 408 524 655 623 687 766 797 777 778 702 716 731 726 758 778 721 646 669 369 356 583 674 696 749 679 696 721 734 778 869 983 971 961 987 935 787 695 587 535 406 293 249 231 209 196 170 139 152 133 144 148 149 145 152 220 221 260 290 335 432 446 450 455 408 330 248 148 125 102 94 84 97 89 103 117 107 58 26 6 0 0 0 +1 0 1 4 13 77 87 92 87 95 97 75 70 83 88 103 155 189 247 288 418 485 492 609 592 598 516 468 382 332 270 233 223 188 144 82 102 188 195 212 178 184 206 195 245 244 273 313 363 421 520 534 675 676 688 698 727 793 744 834 800 799 707 713 392 502 750 867 904 890 852 832 868 855 899 860 870 846 784 713 651 584 506 405 328 277 260 222 188 205 190 167 129 166 152 136 137 142 171 190 229 275 334 365 364 475 499 464 391 343 256 193 122 100 100 69 97 82 95 93 93 91 66 19 5 1 0 0 +0 0 0 3 21 61 83 102 114 84 70 78 94 57 86 87 152 137 184 260 329 403 474 548 555 592 586 561 493 413 344 265 257 210 162 97 112 157 175 213 172 198 187 210 208 224 214 250 306 315 375 412 461 518 584 590 640 635 715 727 818 766 768 758 421 480 808 949 1012 964 1030 943 905 911 857 870 761 658 590 502 412 401 363 314 281 273 208 196 214 184 169 197 163 138 138 157 151 174 196 255 250 294 362 406 407 478 464 403 356 294 229 143 111 99 79 82 73 79 83 102 96 110 51 15 1 0 1 0 +0 1 0 2 16 55 84 98 101 75 82 72 92 64 65 82 127 145 189 209 286 350 397 513 541 569 605 566 553 509 433 329 282 212 181 95 113 160 190 184 203 176 189 196 195 196 207 228 223 213 243 279 337 364 446 446 537 531 567 613 696 689 722 613 364 455 742 885 898 907 945 852 835 751 728 619 521 457 438 351 312 268 272 242 219 230 204 198 204 192 188 162 134 133 170 171 139 200 211 268 335 402 394 440 428 440 410 337 279 256 189 131 113 66 79 65 58 73 67 79 104 93 50 9 2 0 0 1 +0 0 0 2 11 55 99 88 89 77 60 76 67 83 72 84 100 132 145 185 245 291 353 405 489 572 565 597 546 511 498 433 321 326 196 113 118 182 183 201 188 189 169 201 170 204 189 187 199 179 214 227 218 268 288 327 321 331 419 458 495 471 477 472 258 302 531 650 677 686 660 605 564 539 493 419 390 332 284 228 245 250 179 210 186 192 201 190 193 177 165 157 126 152 184 174 223 219 300 328 378 414 427 431 421 395 357 262 219 200 165 126 89 95 67 69 75 60 72 82 92 76 35 3 2 0 1 0 +1 0 0 3 12 44 92 103 88 85 66 79 70 89 51 62 109 137 137 151 193 258 284 314 418 496 511 583 598 562 567 465 402 369 235 126 116 190 193 221 182 185 188 197 195 168 179 156 169 188 180 173 195 217 210 213 232 238 288 319 354 349 343 359 190 208 354 443 493 434 469 429 361 393 275 273 266 216 205 219 198 206 211 216 195 206 192 191 175 158 177 165 143 168 161 227 215 299 327 405 433 441 493 455 374 333 295 218 177 159 127 110 86 57 70 55 76 77 72 81 89 82 34 6 1 2 0 1 +0 0 1 1 9 36 82 92 80 69 68 76 67 63 55 86 106 102 136 143 154 181 217 315 344 450 467 533 558 582 532 485 472 386 256 181 144 223 204 191 190 188 196 183 169 200 171 164 157 168 170 162 197 206 190 190 193 200 215 209 234 242 215 198 106 132 201 345 340 359 291 315 282 277 234 243 234 193 196 145 186 193 189 186 176 194 181 175 165 186 193 169 140 190 222 265 303 340 381 448 451 434 443 403 324 304 224 204 150 141 120 89 79 58 55 67 86 74 86 95 100 81 29 3 0 0 1 0 +0 0 1 1 6 29 81 89 103 80 57 72 73 63 64 71 92 106 118 132 149 163 199 237 264 349 441 496 529 498 523 516 474 466 375 208 184 243 288 264 226 191 194 206 175 172 132 165 143 151 156 177 182 160 162 190 166 207 171 200 191 182 204 187 103 97 185 252 246 268 254 255 248 217 190 223 187 197 157 158 141 172 162 186 178 179 166 174 184 161 173 190 158 196 266 281 341 401 415 461 490 440 413 355 285 263 179 143 135 116 118 91 52 70 72 75 60 78 94 84 84 71 26 4 0 2 0 0 +0 0 0 1 5 28 45 95 93 82 78 51 55 51 63 58 102 84 110 148 148 140 162 176 218 286 353 425 478 538 512 514 542 526 416 251 227 349 333 336 221 190 194 192 172 158 169 132 129 142 160 166 203 138 175 163 181 159 159 168 172 167 165 150 91 96 168 203 238 224 222 237 208 210 197 180 198 169 156 145 186 127 176 167 195 212 165 188 204 209 219 224 235 261 341 401 374 405 459 486 457 401 347 286 256 187 170 160 112 109 85 75 61 67 54 76 72 65 74 104 74 70 25 4 0 2 1 0 +0 0 1 2 5 26 70 77 83 68 69 73 52 62 53 53 91 106 102 129 115 134 154 166 178 234 246 365 346 447 455 477 539 582 496 298 316 394 406 368 300 276 201 191 197 170 146 136 148 115 134 149 152 157 162 146 156 165 173 196 174 183 171 162 64 71 161 187 233 210 205 185 211 207 169 159 166 179 162 165 153 176 162 170 201 177 158 231 211 259 303 313 303 338 413 423 416 397 421 411 386 364 280 218 180 155 131 116 119 111 91 55 53 52 56 53 55 63 71 85 73 64 25 5 2 0 1 0 +0 0 0 3 7 24 60 81 70 82 53 46 66 55 51 61 77 94 91 115 91 132 133 151 154 158 196 257 327 388 421 469 525 592 495 297 311 472 462 457 359 280 257 206 197 180 165 130 155 151 165 136 152 127 149 163 135 141 165 140 170 176 155 157 85 75 159 204 169 171 198 192 196 155 170 152 186 165 165 166 155 163 203 183 171 215 242 265 279 317 349 375 333 410 429 454 451 437 447 387 339 251 201 189 145 135 117 114 88 103 85 70 52 64 71 66 50 61 63 78 72 47 18 3 0 3 1 0 +1 0 0 0 7 34 65 80 81 73 61 47 49 63 45 59 90 97 108 110 103 122 117 130 139 140 185 233 203 301 353 410 490 571 507 338 363 485 511 485 439 394 341 297 233 216 194 183 179 157 183 153 187 137 169 174 161 165 176 152 162 180 156 146 87 100 178 170 205 172 205 165 157 166 168 155 159 146 151 147 161 205 200 221 252 243 270 323 337 370 464 427 392 436 465 466 411 371 345 305 246 203 174 158 152 133 126 109 111 98 96 89 59 55 59 59 55 63 76 74 82 61 26 5 1 0 0 0 +0 0 0 1 9 27 60 76 68 64 63 66 66 57 50 67 87 75 108 99 105 104 118 132 102 151 146 179 204 233 237 339 459 443 486 262 341 521 549 558 537 444 420 380 287 267 222 201 192 182 167 182 168 163 167 162 172 153 153 139 160 190 167 143 93 91 149 199 195 187 181 175 162 192 181 168 155 175 182 204 168 190 232 258 286 321 375 400 427 481 487 453 392 422 428 416 330 324 271 233 177 183 150 118 126 115 137 102 87 78 104 85 57 43 50 61 65 45 55 83 82 82 25 6 0 0 1 0 +0 0 0 3 8 42 86 89 63 65 52 61 56 50 48 52 68 89 98 107 98 90 109 86 119 134 152 145 173 165 251 291 350 423 344 224 331 521 600 564 554 535 487 446 449 381 335 281 227 233 200 227 179 177 187 180 169 152 142 167 179 170 171 140 122 122 171 182 185 196 200 161 149 161 173 179 205 197 207 219 222 295 345 321 393 466 505 503 522 517 543 490 418 391 413 325 312 253 235 165 168 136 107 115 109 88 129 99 94 104 74 74 67 49 42 53 54 51 66 58 84 65 33 8 2 2 0 0 +0 0 1 2 8 31 60 77 73 70 50 50 73 57 54 55 79 91 102 92 98 86 88 104 104 121 130 119 140 169 198 235 267 320 314 197 248 431 546 591 562 535 488 499 524 423 425 355 318 288 281 275 229 214 229 183 148 156 165 168 191 191 169 139 107 116 172 215 193 159 188 194 183 163 213 183 203 207 246 265 290 340 334 386 416 462 458 467 477 464 467 367 359 296 324 287 198 174 169 130 115 101 82 88 89 74 79 86 68 73 67 54 57 45 37 62 40 54 53 49 61 43 20 2 0 1 0 0 +0 0 0 1 6 41 40 47 44 34 31 46 40 43 47 39 88 68 68 70 83 71 77 76 73 76 98 87 97 127 125 177 174 203 215 113 188 306 343 408 386 440 443 380 399 352 329 312 285 267 263 216 192 206 177 166 140 134 139 136 139 143 141 134 89 90 142 136 156 164 149 145 164 154 183 168 222 212 242 294 291 325 311 329 362 401 375 363 308 345 303 287 206 205 205 183 121 98 98 104 97 84 56 53 59 66 68 54 64 59 50 40 40 33 43 27 38 47 55 39 48 51 22 5 0 0 0 0 +0 2 0 1 5 15 38 40 34 31 32 28 31 22 28 36 33 42 50 38 46 43 47 52 47 63 53 60 57 50 80 95 112 109 111 72 102 186 215 247 221 298 302 317 291 287 261 291 252 219 218 208 217 214 174 174 160 164 156 140 129 150 131 138 104 107 142 154 190 198 173 173 170 199 163 193 197 239 248 240 316 283 334 311 324 358 317 280 297 285 238 216 161 139 142 130 104 94 78 86 80 59 65 63 63 50 72 61 50 69 45 52 27 50 31 37 32 44 45 41 52 37 20 7 2 3 0 0 +0 2 0 0 5 15 43 43 51 39 28 38 28 23 34 36 43 41 46 50 38 43 47 58 53 57 45 48 54 79 87 88 99 95 91 76 105 169 198 212 259 262 305 326 323 322 319 350 303 321 310 302 264 260 230 229 221 208 206 185 198 189 185 175 131 128 169 198 210 202 224 217 194 251 256 269 246 253 287 262 332 304 307 353 337 323 309 277 271 280 248 199 142 130 116 95 99 72 69 60 59 61 60 58 64 63 50 62 42 48 41 39 31 31 29 33 42 25 34 32 50 39 19 4 0 1 1 2 +0 0 0 1 4 24 45 47 37 26 33 30 32 35 31 29 56 52 55 55 69 58 62 67 48 63 66 68 74 83 64 83 96 105 89 80 106 176 195 223 274 262 354 335 364 339 366 359 313 335 316 319 350 299 329 277 265 280 264 256 225 238 243 211 166 177 205 262 261 237 267 255 276 267 269 273 292 280 295 286 343 300 309 321 351 360 332 293 235 210 195 144 134 102 112 80 70 58 50 57 45 48 48 50 53 61 50 53 40 50 55 42 21 25 32 27 27 24 22 40 39 40 26 6 1 0 1 2 +2 1 2 0 4 20 41 46 42 29 31 31 31 29 35 34 46 54 51 58 58 60 56 66 56 54 62 54 68 64 83 85 99 90 80 59 69 133 176 192 205 254 284 278 286 319 332 365 331 309 313 336 363 321 312 319 295 290 278 289 317 263 257 231 174 185 249 291 288 279 255 288 273 284 303 278 329 300 300 313 302 344 328 343 328 301 290 240 205 190 159 126 103 95 93 82 81 62 54 45 59 52 58 55 52 63 50 64 51 53 37 50 26 31 25 36 26 30 40 36 41 35 20 4 0 2 1 0 +1 0 0 0 2 24 31 64 45 34 27 31 28 30 32 37 47 56 59 56 55 62 69 55 66 57 75 64 66 84 74 73 96 75 79 37 83 130 147 155 185 202 237 226 264 263 293 325 308 295 357 314 358 355 368 322 358 326 338 311 341 348 317 267 192 218 313 326 336 362 323 337 337 303 308 331 336 301 335 329 347 305 319 298 306 267 260 235 183 154 148 129 83 78 82 61 68 65 53 58 64 60 60 54 63 61 70 69 58 48 49 42 35 34 34 23 36 25 29 52 40 51 27 6 0 0 0 3 +0 0 0 0 7 23 45 36 50 47 37 28 35 23 29 37 47 53 48 55 77 55 66 67 80 68 46 59 70 74 87 72 88 81 87 58 60 96 126 129 144 172 218 212 226 254 268 270 297 308 310 330 330 374 383 403 401 370 363 389 346 357 343 320 224 282 370 375 387 404 369 367 345 414 361 337 362 330 343 336 338 316 310 306 281 237 204 207 162 141 118 108 89 64 89 70 69 53 52 56 65 57 57 55 72 56 62 64 59 47 58 51 32 30 28 24 32 29 42 35 43 40 24 3 2 0 0 0 +0 0 1 1 6 21 50 54 48 35 39 42 32 29 38 41 48 55 66 64 63 68 74 66 74 87 75 62 83 77 63 79 84 71 99 73 44 102 114 141 147 145 165 197 197 243 252 254 259 275 321 352 352 339 395 376 410 402 420 408 414 440 396 305 261 262 360 400 451 424 396 401 395 430 375 347 363 328 333 308 318 281 283 270 251 204 193 156 164 159 113 99 60 93 99 83 71 71 67 60 76 64 75 67 68 65 60 82 55 54 56 47 37 39 30 32 33 36 55 43 45 63 24 7 0 0 0 0 +2 2 0 0 5 18 37 47 69 54 38 49 30 44 36 40 50 75 73 69 60 54 84 85 84 83 75 75 74 73 64 95 96 89 78 53 56 132 144 145 133 144 173 195 172 216 254 238 238 296 270 298 350 318 364 445 415 425 400 437 474 459 439 368 267 320 377 410 458 461 445 431 407 436 411 417 360 367 326 276 283 279 280 234 228 221 179 175 151 120 119 94 81 79 89 93 76 79 85 75 62 80 76 75 84 58 64 66 70 52 49 41 44 38 37 37 40 35 45 58 74 45 26 5 0 0 1 0 +0 1 0 0 6 21 50 63 56 48 50 45 34 40 33 47 52 63 80 74 77 85 76 105 77 77 77 90 104 81 82 98 115 116 104 67 69 126 126 149 143 138 154 186 163 193 199 214 190 192 228 296 276 296 301 337 381 364 370 389 392 447 432 401 289 300 383 413 403 440 464 443 391 435 374 389 366 356 292 266 254 256 248 248 210 174 176 133 124 121 119 102 102 109 80 77 85 92 81 92 84 87 86 86 68 80 74 80 90 60 72 49 43 45 34 43 45 43 65 71 67 38 25 3 0 0 0 0 +0 0 1 1 5 12 28 36 44 30 36 44 49 37 32 44 51 52 53 75 71 64 51 47 52 73 70 71 84 90 78 83 103 92 87 47 56 93 93 103 110 98 121 147 139 170 162 172 156 182 202 173 167 198 203 179 206 216 222 309 320 339 374 364 291 293 338 344 323 349 377 311 289 317 288 250 299 264 248 228 227 205 189 170 165 144 135 107 109 97 116 90 87 88 92 79 74 72 75 72 58 51 57 44 54 70 53 53 66 62 57 59 48 35 39 40 41 37 40 41 33 41 24 3 0 1 0 1 +1 0 0 1 6 4 11 12 20 17 24 5 15 16 11 22 36 20 29 19 24 14 20 14 26 25 28 46 33 63 56 55 57 64 43 37 43 53 38 43 51 30 32 59 66 72 100 81 56 62 63 74 53 60 44 47 49 57 76 89 125 147 168 213 198 177 223 227 195 196 163 152 149 134 162 165 157 150 174 164 145 135 123 100 89 72 59 63 54 37 42 42 54 67 77 64 63 49 44 23 30 27 19 18 14 23 23 28 33 43 35 33 20 21 21 17 12 27 16 17 12 19 7 0 0 0 0 3 +1 1 1 2 0 1 1 1 1 1 1 2 0 2 3 0 5 12 6 5 7 6 7 5 3 8 8 10 14 13 18 15 16 21 8 3 3 7 2 5 5 5 6 15 12 16 21 32 17 12 5 12 8 6 5 7 4 5 8 13 16 31 36 57 64 88 81 80 56 50 55 47 48 46 35 37 47 61 60 62 56 45 31 29 22 22 12 15 5 9 18 20 28 32 32 28 23 14 14 12 3 3 3 1 4 1 3 9 8 8 14 2 8 6 8 5 8 3 5 4 3 1 3 0 0 0 2 1 +1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 2 1 1 0 1 5 3 4 1 2 0 0 0 0 1 0 0 2 4 1 1 5 4 4 1 0 1 0 2 0 1 0 0 0 0 0 0 3 13 21 13 9 13 11 11 7 3 4 4 5 11 12 7 9 10 8 11 5 4 4 1 5 1 1 2 0 4 4 6 10 6 5 3 2 1 0 0 1 0 3 0 0 1 1 0 2 2 2 0 0 1 0 1 0 0 1 0 0 2 0 1 1 1 +1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 2 0 1 1 1 0 0 0 1 0 0 0 0 0 1 1 1 1 4 1 1 2 1 0 1 0 1 0 1 1 0 2 2 2 2 0 1 0 0 0 0 0 0 0 0 0 0 2 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 +1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 2 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 2 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 2 0 0 0 0 0 0 3 2 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 10 \ No newline at end of file diff --git a/lib/grm/grm-plots/data/test.dat b/lib/grm/grm-plots/data/test.dat new file mode 100644 index 000000000..5b7a46df6 --- /dev/null +++ b/lib/grm/grm-plots/data/test.dat @@ -0,0 +1,9 @@ +# title : Test +# xlabel : x +# ylabel : y + +1 2 3 4 +2 3 4 5 +3 4 5 6 +4 5 6 7 + diff --git a/lib/grm/grm-plots/grm-plots.macos.sh b/lib/grm/grm-plots/grm-plots.macos.sh new file mode 100755 index 000000000..ad8869b9e --- /dev/null +++ b/lib/grm/grm-plots/grm-plots.macos.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +SCRIPT_DIR="$(cd "$(dirname "$0")" >/dev/null 2>&1 && pwd)" + +"${SCRIPT_DIR}/../Applications/grm-plots.app/Contents/Macos/grm-plots" "$@" diff --git a/lib/grm/grm-plots/grm-plots.pro b/lib/grm/grm-plots/grm-plots.pro new file mode 100644 index 000000000..784b718da --- /dev/null +++ b/lib/grm/grm-plots/grm-plots.pro @@ -0,0 +1,29 @@ +GRDIR = $$(GRDIR) +isEmpty(GRDIR) { + GRDIR = /usr/local/gr +} +QT += widgets core +QMAKE_CXXLAGS += $$(EXTRA_CXXFLAGS) +QMAKE_LFLAGS += $$(EXTRA_LDFLAGS) +HEADERS += grmplots_widget.hxx grmplots_mainwindow.hxx util.hxx +SOURCES += grmplots_widget.cxx grmplots.cxx grmplots_mainwindow.cxx +INCLUDEPATH += ../include +if (macx) { + if (exists(../libGRM.dylib)) { + LIBS += -L.. -lGRM + } else { + LIBS += -L$(GRDIR)/lib -lGRM + } + # On macOS, the grm-plots executable is located in `$(GRDIR)/Applications/grm-plots.app/Contents/MacOS` + # and we need to resolve `libGRM.dylib` in `$(GRDIR)/lib` + QMAKE_RPATHDIR += ../../../../lib +} else { + if (exists(../libGRM.so)) { + LIBS += -L.. -lGRM -Wl,-rpath-link,../../gr -Wl,-rpath-link,../../gr3 + } else { + LIBS += -L$(GRDIR)/lib -lGRM -Wl,-rpath-link,$(GRDIR)/lib + } + # On every other system, the grm-plots executable is located in `$(GRDIR)/bin` + # and we need to resolve `libGRM.so` in `$(GRDIR)/lib` + QMAKE_RPATHDIR += ../lib +} \ No newline at end of file diff --git a/lib/grm/grm-plots/grmplots.cxx b/lib/grm/grm-plots/grmplots.cxx new file mode 100644 index 000000000..c03d5c0c5 --- /dev/null +++ b/lib/grm/grm-plots/grmplots.cxx @@ -0,0 +1,32 @@ +#include "grmplots_mainwindow.hxx" +#include + +int main(int argc, char **argv) +{ + const char *colms = "", *csv_file = "", *plot_type = "line"; + + if (argc > 1) + { + csv_file = argv[1]; + } + else + { + fprintf(stderr, "Please specify a file to run grm-plots.\n"); + exit(0); + } + if (argc > 2) + { + plot_type = argv[2]; + } + if (argc > 3) + { + colms = argv[3]; + } + + QApplication app(argc, argv); + MainWindow window(csv_file, plot_type, colms); + + window.show(); + + return app.exec(); +} diff --git a/lib/grm/grm-plots/grmplots_mainwindow.cxx b/lib/grm/grm-plots/grmplots_mainwindow.cxx new file mode 100644 index 000000000..7545f1914 --- /dev/null +++ b/lib/grm/grm-plots/grmplots_mainwindow.cxx @@ -0,0 +1,13 @@ +#include "grmplots_mainwindow.hxx" +#include +#include + +MainWindow::MainWindow(const char *csv_file, const char *plot_type, const char *colms) : QMainWindow() +{ + gr_widget_ = new GRWidget(this, csv_file, plot_type, colms); + setCentralWidget(gr_widget_); + setWindowTitle("GRM-plots"); + resize(600, 450); +} + +MainWindow::~MainWindow() = default; diff --git a/lib/grm/grm-plots/grmplots_mainwindow.hxx b/lib/grm/grm-plots/grmplots_mainwindow.hxx new file mode 100644 index 000000000..4d24177f0 --- /dev/null +++ b/lib/grm/grm-plots/grmplots_mainwindow.hxx @@ -0,0 +1,18 @@ +#ifndef MAIN_WINDOW_H_INCLUDED +#define MAIN_WINDOW_H_INCLUDED +#include "grmplots_widget.hxx" +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(const char *csv_file, const char *plot_type, const char *colms); + ~MainWindow() override; + +private: + GRWidget *gr_widget_; +}; + +#endif /* ifndef MAIN_WINDOW_H_INCLUDED */ diff --git a/lib/grm/grm-plots/grmplots_widget.cxx b/lib/grm/grm-plots/grmplots_widget.cxx new file mode 100644 index 000000000..764bb0ee5 --- /dev/null +++ b/lib/grm/grm-plots/grmplots_widget.cxx @@ -0,0 +1,407 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "grmplots_widget.hxx" +#include "util.hxx" + +void getMousePos(QMouseEvent *event, int *x, int *y) +{ +#if QT_VERSION >= 0x060000 + x[0] = (int)event->position().x(); + y[0] = (int)event->position().y(); +#else + x[0] = (int)event->pos().x(); + y[0] = (int)event->pos().y(); +#endif +} + +void getWheelPos(QWheelEvent *event, int *x, int *y) +{ +#if QT_VERSION >= 0x060000 + x[0] = (int)event->position().x(); + y[0] = (int)event->position().y(); +#else + x[0] = (int)event->pos().x(); + y[0] = (int)event->pos().y(); +#endif +} + +GRWidget::GRWidget(QMainWindow *parent, const char *csv_file, const char *plot_type, const char *colms) + : QWidget(parent), args_(nullptr), rubberBand(nullptr), pixmap(nullptr), tooltip(nullptr) +{ + csv_file_ = csv_file; + colms_ = colms; + plot_type_ = plot_type; + args_ = grm_args_new(); + +#ifdef _WIN32 + putenv("GKS_WSTYPE=381"); + putenv("GKS_DOUBLE_BUF=True"); +#else + setenv("GKS_WSTYPE", "381", 1); + setenv("GKS_DOUBLE_BUF", "True", 1); +#endif + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + rubberBand = new QRubberBand(QRubberBand::Rectangle, this); + setFocusPolicy(Qt::FocusPolicy::StrongFocus); // needed to receive key press events + setMouseTracking(true); + mouseState.mode = MouseState::Mode::normal; + mouseState.pressed = {0, 0}; + mouseState.anchor = {0, 0}; + + menu = parent->menuBar(); + type = new QMenu("&Plot type"); + algo = new QMenu("&Algorithm"); + if (strcmp(plot_type_, "heatmap") == 0 || strcmp(plot_type_, "marginalheatmap") == 0) + { + auto submenu = type->addMenu("&Marginalheatmap"); + + heatmapAct = new QAction(tr("&Heatmap"), this); + connect(heatmapAct, &QAction::triggered, this, &GRWidget::heatmap); + marginalheatmapAllAct = new QAction(tr("&Type 1 all"), this); + connect(marginalheatmapAllAct, &QAction::triggered, this, &GRWidget::marginalheatmapall); + marginalheatmapLineAct = new QAction(tr("&Type 2 line"), this); + connect(marginalheatmapLineAct, &QAction::triggered, this, &GRWidget::marginalheatmapline); + sumAct = new QAction(tr("&Sum"), this); + connect(sumAct, &QAction::triggered, this, &GRWidget::sumalgorithm); + maxAct = new QAction(tr("&Maximum"), this); + connect(maxAct, &QAction::triggered, this, &GRWidget::maxalgorithm); + + submenu->addAction(marginalheatmapAllAct); + submenu->addAction(marginalheatmapLineAct); + type->addAction(heatmapAct); + algo->addAction(sumAct); + algo->addAction(maxAct); + } + else if (strcmp(plot_type_, "line") == 0) + { + lineAct = new QAction(tr("&Line"), this); + connect(lineAct, &QAction::triggered, this, &GRWidget::line); + type->addAction(lineAct); + } + menu->addMenu(type); + menu->addMenu(algo); +} + +GRWidget::~GRWidget() +{ + grm_args_delete(args_); +} + +void GRWidget::draw() +{ + grm_plot(nullptr); +} + +void GRWidget::redraw() +{ + delete pixmap; + pixmap = nullptr; + repaint(); +} + +#define style \ + "\ + .gr-label {\n\ + color: #26aae1;\n\ + font-size: 11px;\n\ + line-height: 0.8;\n\ + }\n\ + .gr-value {\n\ + color: #3c3c3c;\n\ + font-size: 11px;\n\ + line-height: 0.8;\n\ + }" + +#define tooltipTemplate \ + "\ + %s
\n\ + %s: \n\ + %.14g
\n\ + %s: \n\ + %.14g" + +void GRWidget::paintEvent(QPaintEvent *event) +{ + util::unused(event); + QPainter painter; + std::stringstream addresses; + + if (!pixmap) + { + pixmap = new QPixmap((int)(geometry().width() * this->devicePixelRatioF()), + (int)(geometry().height() * this->devicePixelRatioF())); + pixmap->setDevicePixelRatio(this->devicePixelRatioF()); + + addresses << static_cast(this) << "!" << static_cast(&painter); +#ifdef _WIN32 + putenv(addresses.str().c_str()); +#else + setenv("GKS_CONID", addresses.str().c_str(), 1); +#endif + + painter.begin(pixmap); + + painter.fillRect(0, 0, width(), height(), QColor("white")); + draw(); + + painter.end(); + } + if (pixmap) + { + painter.begin(this); + painter.drawPixmap(0, 0, *pixmap); + if (tooltip != nullptr) + { + if (tooltip->x_px > 0 && tooltip->y_px > 0) + { + QColor background(224, 224, 224, 128); + char c_info[BUFSIZ]; + QPainterPath triangle; + std::string x_label = tooltip->xlabel, y_label = tooltip->ylabel; + + if (startsWith(x_label, "$") && endsWith(x_label, "$")) + { + x_label = "x"; + } + if (startsWith(y_label, "$") && endsWith(y_label, "$")) + { + y_label = "y"; + } + std::snprintf(c_info, BUFSIZ, tooltipTemplate, tooltip->label, x_label.c_str(), tooltip->x, + y_label.c_str(), tooltip->y); + std::string info(c_info); + label.setDefaultStyleSheet(style); + label.setHtml(info.c_str()); + if (strcmp(plot_type_, "heatmap") == 0 || strcmp(plot_type_, "marginalheatmap") == 0) + { + background.setAlpha(224); + } + painter.fillRect(tooltip->x_px + 8, (int)(tooltip->y_px - label.size().height() / 2), + (int)label.size().width(), (int)label.size().height(), + QBrush(background, Qt::SolidPattern)); + + triangle.moveTo(tooltip->x_px, tooltip->y_px); + triangle.lineTo(tooltip->x_px + 8, tooltip->y_px + 6); + triangle.lineTo(tooltip->x_px + 8, tooltip->y_px - 6); + triangle.closeSubpath(); + background.setRgb(128, 128, 128, 128); + painter.fillPath(triangle, QBrush(background, Qt::SolidPattern)); + + painter.save(); + painter.translate(tooltip->x_px + 8, tooltip->y_px - label.size().height() / 2); + label.drawContents(&painter); + painter.restore(); + } + } + painter.end(); + } +} + +void GRWidget::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_R) + { + grm_args_t *args = grm_args_new(); + QPoint widget_cursor_pos = mapFromGlobal(QCursor::pos()); + grm_args_push(args, "key", "s", "r"); + grm_args_push(args, "x", "i", widget_cursor_pos.x()); + grm_args_push(args, "y", "i", widget_cursor_pos.y()); + grm_input(args); + grm_args_delete(args); + redraw(); + } +} + +void GRWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (mouseState.mode == MouseState::Mode::boxzoom) + { + rubberBand->setGeometry(QRect(mouseState.pressed, event->pos()).normalized()); + } + else if (mouseState.mode == MouseState::Mode::pan) + { + int x, y; + getMousePos(event, &x, &y); + grm_args_t *args = grm_args_new(); + + grm_args_push(args, "x", "i", mouseState.anchor.x()); + grm_args_push(args, "y", "i", mouseState.anchor.y()); + grm_args_push(args, "xshift", "i", x - mouseState.anchor.x()); + grm_args_push(args, "yshift", "i", y - mouseState.anchor.y()); + + grm_input(args); + grm_args_delete(args); + + mouseState.anchor = event->pos(); + redraw(); + } + else + { + tooltip = grm_get_tooltip(event->pos().x(), event->pos().y()); + + if (strcmp(plot_type_, "marginalheatmap") == 0) + { + grm_args_t *input_args; + input_args = grm_args_new(); + + grm_args_push(input_args, "x", "i", event->pos().x()); + grm_args_push(input_args, "y", "i", event->pos().y()); + grm_input(input_args); + } + + redraw(); + } +} + +void GRWidget::mousePressEvent(QMouseEvent *event) +{ + mouseState.pressed = event->pos(); + if (event->button() == Qt::MouseButton::RightButton) + { + mouseState.mode = MouseState::Mode::boxzoom; + rubberBand->setGeometry(QRect(mouseState.pressed, QSize())); + rubberBand->show(); + } + else if (event->button() == Qt::MouseButton::LeftButton) + { + mouseState.mode = MouseState::Mode::pan; + mouseState.anchor = event->pos(); + } +} + +void GRWidget::mouseReleaseEvent(QMouseEvent *event) +{ + grm_args_t *args = grm_args_new(); + int x, y; + getMousePos(event, &x, &y); + + if (mouseState.mode == MouseState::Mode::boxzoom) + { + rubberBand->hide(); + if (std::abs(x - mouseState.pressed.x()) >= 5 && std::abs(y - mouseState.pressed.y()) >= 5) + { + grm_args_push(args, "keep_aspect_ratio", "i", event->modifiers() & Qt::ShiftModifier); + grm_args_push(args, "x1", "i", mouseState.pressed.x()); + grm_args_push(args, "y1", "i", mouseState.pressed.y()); + grm_args_push(args, "x2", "i", x); + grm_args_push(args, "y2", "i", y); + } + } + else if (mouseState.mode == MouseState::Mode::pan) + { + mouseState.mode = MouseState::Mode::normal; + } + + grm_input(args); + grm_args_delete(args); + + redraw(); +} + +void GRWidget::resizeEvent(QResizeEvent *event) +{ + grm_args_push(args_, "size", "dd", (double)event->size().width(), (double)event->size().height()); + grm_merge(args_); + + redraw(); +} + +void GRWidget::wheelEvent(QWheelEvent *event) +{ + int x, y; + getWheelPos(event, &x, &y); + + grm_args_t *args = grm_args_new(); + grm_args_push(args, "x", "i", x); + grm_args_push(args, "y", "i", y); + grm_args_push(args, "angle_delta", "d", (double)event->angleDelta().y()); + grm_input(args); + grm_args_delete(args); + + redraw(); +} + +void GRWidget::mouseDoubleClickEvent(QMouseEvent *event) +{ + grm_args_t *args = grm_args_new(); + QPoint pos = mapFromGlobal(QCursor::pos()); + grm_args_push(args, "key", "s", "r"); + grm_args_push(args, "x", "i", pos.x()); + grm_args_push(args, "y", "i", pos.y()); + grm_input(args); + grm_args_delete(args); + + redraw(); +} + +void GRWidget::heatmap() +{ + plot_type_ = "heatmap"; + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + redraw(); +} + +void GRWidget::marginalheatmapall() +{ + plot_type_ = "marginalheatmap"; + heatmap_type_ = "all"; + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + redraw(); +} + +void GRWidget::marginalheatmapline() +{ + plot_type_ = "marginalheatmap"; + heatmap_type_ = "line"; + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + redraw(); +} + +void GRWidget::line() +{ + plot_type_ = "line"; + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + redraw(); +} + +void GRWidget::sumalgorithm() +{ + heatmap_algorithm_ = "sum"; + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + redraw(); +} + +void GRWidget::maxalgorithm() +{ + heatmap_algorithm_ = "max"; + if (!grm_interactive_plot_from_file(args_, csv_file_, &plot_type_, colms_, heatmap_type_, heatmap_algorithm_)) + { + exit(0); + } + redraw(); +} diff --git a/lib/grm/grm-plots/grmplots_widget.hxx b/lib/grm/grm-plots/grmplots_widget.hxx new file mode 100644 index 000000000..4003523c0 --- /dev/null +++ b/lib/grm/grm-plots/grmplots_widget.hxx @@ -0,0 +1,78 @@ +#ifndef GR_WIDGET_H_INCLUDED +#define GR_WIDGET_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +#include + +class GRWidget : public QWidget +{ + Q_OBJECT + +public: + explicit GRWidget(QMainWindow *parent, const char *csv_file, const char *plot_type, const char *colms); + ~GRWidget() override; + +protected: + virtual void draw(); + void redraw(); + void keyPressEvent(QKeyEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void wheelEvent(QWheelEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + +private slots: + void heatmap(); + void marginalheatmapall(); + void marginalheatmapline(); + void line(); + void sumalgorithm(); + void maxalgorithm(); + +private: + struct MouseState + { + enum class Mode + { + normal, + pan, + boxzoom + }; + Mode mode; + QPoint pressed; + QPoint anchor; + }; + QPixmap *pixmap; + grm_args_t *args_; + MouseState mouseState; + QRubberBand *rubberBand; + grm_tooltip_info_t *tooltip; + QTextDocument label; + + QMenuBar *menu; + QMenu *type; + QMenu *algo; + QAction *heatmapAct; + QAction *marginalheatmapAllAct; + QAction *marginalheatmapLineAct; + QAction *lineAct; + QAction *sumAct; + QAction *maxAct; + + const char *csv_file_; + const char *plot_type_; + const char *heatmap_type_ = "all"; + const char *heatmap_algorithm_ = "sum"; + const char *colms_; +}; + +#endif /* ifndef GR_WIDGET_H_INCLUDED */ diff --git a/lib/grm/grm-plots/makefile.mak b/lib/grm/grm-plots/makefile.mak new file mode 100644 index 000000000..a6561d032 --- /dev/null +++ b/lib/grm/grm-plots/makefile.mak @@ -0,0 +1,40 @@ +UNAME := $(shell uname) +TMP_QMAKE ?= $(shell which qmake 2>/dev/null || which qmake6 2>/dev/null || which qmake-qt5 2>/dev/null || echo '') +ifneq ($(QT5_QMAKE),) +ifneq ($(QT5_QMAKE),false) + TMP_QMAKE := $(QT5_QMAKE) +endif +endif +ifneq ($(QT6_QMAKE),) +ifneq ($(QT6_QMAKE),false) + TMP_QMAKE := $(QT6_QMAKE) +endif +endif +QMAKE ?= $(TMP_QMAKE) + +default: QMakefile + @if [ "$(QMAKE)" != "" ]; then $(MAKE) -f QMakefile; fi + +QMakefile: + @if [ "$(QMAKE)" != "" ]; then $(QMAKE) -o QMakefile; fi + +install: default +ifeq ($(UNAME), Darwin) + @if [ ! -d $(DESTDIR)$(GRDIR)/Applications ]; then \ + mkdir -m 755 $(DESTDIR)$(GRDIR)/Applications; fi + @ditto grm-plots.app \ + $(DESTDIR)$(GRDIR)/Applications/grm-plots.app + @if [ ! -d $(DESTDIR)$(GRDIR)/bin ]; then \ + mkdir -m 755 $(DESTDIR)$(GRDIR)/bin; fi + @ditto grm-plots.macos.sh \ + $(DESTDIR)$(GRDIR)/bin/grm-plots +else + cp -p grm-plots $(DESTDIR)$(GRDIR)/bin/ +endif + +clean: + @if [ -f QMakefile ]; then make -f QMakefile distclean; \ + rm -f QMakefile; fi + @if [ -f Makefile ]; then make distclean; fi + +.PHONY: default install clean diff --git a/lib/grm/grm-plots/makefile.mingw b/lib/grm/grm-plots/makefile.mingw new file mode 100644 index 000000000..50c746778 --- /dev/null +++ b/lib/grm/grm-plots/makefile.mingw @@ -0,0 +1,39 @@ +ifeq ($(strip $(THIRDPARTYDIR)),) +override THIRDPARTYDIR = $(abspath $(CURDIR)/../../../3rdparty/build) +endif + + INCLUDES = -I../include \ + -I../../gks \ + -I../../gr \ + -I../../gr3 \ + -I$(THIRDPARTYDIR)/include + GRMLIB = ../libGRM.lib + GKSLIBS = -L ../../gks/ -lGKS + GRLIBS = -L ../../gr/ -lGR + GR3LIBS = -L ../../gr3/ -lGR3 + JPEGLIBS = $(THIRDPARTYDIR)/lib/libjpeg.a + PNGLIBS = $(THIRDPARTYDIR)/lib/libpng.a + ZLIBS = $(THIRDPARTYDIR)/lib/libz.a + QHLIBS = $(THIRDPARTYDIR)/lib/libqhull.a + FTLIBS = $(THIRDPARTYDIR)/lib/libfreetype.a + LIBS = $(GR3LIBS) $(GRLIBS) $(GKSLIBS) -lm -lws2_32 -lmsimg32 -lgdi32 -lpthread + +default: grm-plots.exe + +$(GRMLIB): + $(MAKE) -C .. libGRM.lib + +grm-plots.exe: grmplots.cxx grmplots_mainwindow.cxx grmplots_widget.cxx $(GRMLIB) + wget https://gr-framework.org/downloads/3rdparty/qt5-runtime-Windows-$(ARCHITECTURE)-mingw81.tar.gz + tar xzf qt5-runtime-Windows-$(ARCHITECTURE)-mingw81.tar.gz + moc -DGRDIR=\"$(GRDIR)\" -Iinclude grmplots_widget.hxx -o moc_grmplots_widget.cxx + moc -DGRDIR=\"$(GRDIR)\" -Iinclude grmplots_mainwindow.hxx -o moc_grmplots_mainwindow.cxx + $(CXX) -fno-exceptions -Wl,--subsystem,windows -mwindows -std=c++17 -DGRDIR=\"$(GRDIR)\" -DGR_STATIC_LIB $(INCLUDES) -Iinclude -Iinclude/QtGui -Iinclude/QtWidgets -Iinclude/QtCore -I../ -o $@ $^ moc_grmplots_widget.cxx moc_grmplots_mainwindow.cxx Qt5Gui.dll Qt5Widgets.dll Qt5Core.dll \ + $(JPEGLIBS) $(FTLIBS) $(PNGLIBS) $(ZLIBS) $(QHLIBS) $(LIBS) + + +clean: + $(RM) include + $(RM) *.dll + $(RM) moc_*.cxx + $(RM) grm-plots.exe diff --git a/lib/grm/grm-plots/util.hxx b/lib/grm/grm-plots/util.hxx new file mode 100644 index 000000000..9f8759414 --- /dev/null +++ b/lib/grm/grm-plots/util.hxx @@ -0,0 +1,19 @@ +#ifndef UTIL_HXX_INCLUDED +#define UTIL_HXX_INCLUDED + +namespace util +{ +template void unused(T &&...) {} +} // namespace util + +static bool endsWith(const std::string &str, const std::string &suffix) +{ + return str.size() >= suffix.size() && 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix); +} + +static bool startsWith(const std::string &str, const std::string &prefix) +{ + return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix); +} + +#endif /* ifndef UTIL_HXX_INCLUDED */ diff --git a/lib/grm/include/grm.h b/lib/grm/include/grm.h index d1f6ac7ae..a46f70649 100644 --- a/lib/grm/include/grm.h +++ b/lib/grm/include/grm.h @@ -11,5 +11,6 @@ #include #include #include +#include #endif /* ifndef GRM_H_INCLUDED */ diff --git a/lib/grm/include/grm/import.h b/lib/grm/include/grm/import.h new file mode 100644 index 000000000..39880ec13 --- /dev/null +++ b/lib/grm/include/grm/import.h @@ -0,0 +1,29 @@ +#ifndef GRM_IMPORT_H_INCLUDED +#define GRM_IMPORT_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/* ######################### includes ############################################################################### */ + +#include "args.h" +#include "util.h" +#include "net.h" +#include "plot.h" + + +/* ######################### public interface ####################################################################### */ + +/* ========================= functions ============================================================================== */ + +/* ------------------------- plot ----------------------------------------------------------------------------------- */ + +EXPORT int grm_interactive_plot_from_file(grm_args_t *args, const char *data_file, const char **plot_type, + const char *colms, const char *heatmap_type, const char *heatmap_algo); +EXPORT int grm_plot_from_file(const char *data_file, const char **plot_type, const char *colms); + +#ifdef __cplusplus +} +#endif +#endif // GRM_IMPORT_H_INCLUDED diff --git a/lib/grm/makefile.mingw b/lib/grm/makefile.mingw index aa9945c5f..68f0adc1d 100644 --- a/lib/grm/makefile.mingw +++ b/lib/grm/makefile.mingw @@ -30,6 +30,8 @@ endif src/grm/net.o \ src/grm/plot.o \ src/grm/util.o \ + src/grm/utilcpp.o \ + src/grm/import.o \ src/grm/datatype/double_map.o \ src/grm/datatype/string_array_map.o \ src/grm/datatype/string_list.o \ diff --git a/lib/grm/src/grm/import.cxx b/lib/grm/src/grm/import.cxx new file mode 100644 index 000000000..7b0b57ef2 --- /dev/null +++ b/lib/grm/src/grm/import.cxx @@ -0,0 +1,424 @@ +/* ######################### includes ############################################################################### */ +#include "import_int.hxx" +#include "util_int.h" +#include "utilcpp_int.hxx" +#include +#include +#include +#include +#include +#include + +/* ========================= functions ============================================================================== */ + +/* ------------------------- import --------------------------------------------------------------------------------- */ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~ filereader ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +std::string normalize_line(const std::string &str) +{ + std::string s; + std::string item; + std::istringstream ss(str); + + s = ""; + while (ss >> item) + { + if (item[0] == '#') break; + if (!s.empty()) + { + s += '\t'; + } + s += item; + } + return s; +} + +err_t read_data_file(const std::string &path, std::vector> &data, std::vector &labels, + grm_args_t *args, const char *colms, PlotRange *ranges) +{ + std::string line; + std::string token; + std::ifstream file(path); + std::list columns; + int linecount = 0; + + /* read the columns from the colms string also converts slicing into numbers */ + std::stringstream scol(colms); + for (size_t col = 0; std::getline(scol, token, ',') && token.length(); col++) + { + if (token.find(':') != std::string::npos) + { + std::stringstream stok(token); + int start = 0, end = 0; + if (starts_with(token, ":")) + { + try + { + end = std::stoi(token.erase(0, 1)); + } + catch (std::invalid_argument &e) + { + fprintf(stderr, + "Value error for column parameter. Use numbers in the " + "specified format. Entry '%s'\n", + token.c_str()); + return ERROR_PARSE_INT; + } + } + else + { + for (size_t coli = 0; std::getline(stok, token, ':') && token.length(); coli++) + { + try + { + if (coli == 0) + { + start = std::stoi(token); + } + else + { + end = std::stoi(token); + } + } + catch (std::invalid_argument &e) + { + fprintf(stderr, + "Value error for column parameter. Use numbers in the " + "specified format. Entry '%s'\n", + token.c_str()); + return ERROR_PARSE_INT; + } + } + } + for (int num = start; num <= end; num++) + { + columns.push_back(num); + } + } + else + { + try + { + columns.push_back(std::stoi(token)); + } + catch (std::invalid_argument &e) + { + fprintf(stderr, + "Value error for column parameter. Use numbers in the " + "specified format. Entry '%s'\n", + token.c_str()); + return ERROR_PARSE_INT; + } + } + } + if (!columns.empty()) + { + columns.sort(); + ranges->ymin = *columns.begin(); + } + + /* read the lines from the file */ + while (getline(file, line)) + { + std::istringstream iss(line, std::istringstream::in); + linecount += 1; + /* the line defines a grm container parameter */ + if (line[0] == '#') + { + std::string key; + std::string value; + std::stringstream ss(line); + + /* read the key-value pairs from the file and redirect them to grm if possible */ + for (size_t col = 0; std::getline(ss, token, ':') && token.length(); col++) + { + if (col == 0) + { + key = trim(token.substr(1, token.length() - 1)); + } + else + { + value = trim(token); + } + } + if (str_equals_any(key.c_str(), 4, "title", "xlabel", "ylabel", "resample_method")) + { + grm_args_push(args, key.c_str(), "s", value.c_str()); + } + else if (str_equals_any(key.c_str(), 5, "location", "xlog", "ylog", "xgrid", "ygrid")) + { + try + { + grm_args_push(args, key.c_str(), "i", std::stoi(value)); + } + catch (std::invalid_argument &e) + { + fprintf(stderr, + "Value error for plot parameter in argument '%s : %s'. Problem " + "appeared in line %i.\n", + key.c_str(), value.c_str(), linecount); + return ERROR_PARSE_INT; + } + } + else if (str_equals_any(key.c_str(), 4, "xlim", "ylim", "xrange", "yrange")) + { + std::stringstream sv(value); + std::string value1; + std::string value2; + for (size_t col = 0; std::getline(sv, token, ',') && token.length(); col++) + { + if (col == 0) + { + value1 = trim(token); + } + else + { + value2 = trim(token); + } + } + try + { + grm_args_push(args, key.c_str(), "dd", std::stod(value1), std::stod(value2)); + } + catch (std::invalid_argument &e) + { + fprintf(stderr, + "Value error for plot parameter in argument '%s : %s, %s'. " + "Problem appeared in line %i.\n", + key.c_str(), value1.c_str(), value2.c_str(), linecount); + return ERROR_PARSE_DOUBLE; + } + if (strcmp(key.c_str(), "xrange") == 0) + { + ranges->xmin = std::stod(value1); + ranges->xmax = std::stod(value2); + } + else if (strcmp(key.c_str(), "yrange") == 0) + { + ranges->ymin = std::stod(value1); + ranges->ymax = std::stod(value2); + } + } + else + { + fprintf(stderr, + "Key-value pair '%s : %s' in line %i unknown. Check if the key-value pair " + "exists in grm.\n", + key.c_str(), value.c_str(), + linecount); /* TODO: extend these ifs when more key values pairs are needed */ + } + continue; + } + else /* the line contains the labels for the plot */ + { + std::istringstream line_ss(normalize_line(line)); + for (size_t col = 0; std::getline(line_ss, token, '\t') && token.length(); col++) + { + if (std::find(columns.begin(), columns.end(), col) != columns.end() || columns.empty()) + { + labels.push_back(token); + } + } + break; + } + } + + /* read the numeric data for the plot */ + for (size_t row = 0; std::getline(file, line) && line.length(); row++) + { + std::istringstream line_ss(normalize_line(line)); + int cnt = 0; + for (size_t col = 0; std::getline(line_ss, token, '\t') && token.length(); col++) + { + if (std::find(columns.begin(), columns.end(), col) != columns.end() || (columns.empty() && labels.empty()) || + (columns.empty() && col < labels.size())) + { + if (row == 0) + { + data.emplace_back(std::vector()); + } + try + { + data[cnt].push_back(std::stod(token)); + } + catch (std::invalid_argument &e) + { + fprintf(stderr, + "Value error inside data. Check if '%s' in row %zu and column " + "%zu is correct.\n", + token.c_str(), row + linecount + 1, col + 1); + return ERROR_PARSE_DOUBLE; + } + cnt += 1; + } + } + } + return ERROR_NONE; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~ plot functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int grm_plot_from_file(const char *data_file, const char **plot_type, const char *colms) +/** + * Allows to create a plot from a file. The file is holding the data and the container arguments for the plot. + * + * @param data_file: Valid path the file which contains the data for the plot. + * @param plot_type: One of the arguments inside the brackets (line, heatmap, marginalheatmap). The default is line. + * @param colms: Defines which columns from the file should be used for the plot. The default is all. + * @return 1 when there was no error, 0 if there was an error. + */ +{ + grm_args_t *args; + int error = 1; + + args = grm_args_new(); + error = grm_interactive_plot_from_file(args, data_file, plot_type, colms, "all", "sum"); + grm_args_delete(args); + return error; +} + +int grm_interactive_plot_from_file(grm_args_t *args, const char *data_file, const char **plot_type, const char *colms, + const char *heatmap_type, const char *heatmap_algo) +/** + * Allows to create an interactive plot from a file. The file is holding the data and the container arguments for the + * plot. + * + * @param args: A grm container. Should be the container, which also defines the window. + * @param data_file: Valid path the file which contains the data for the plot. + * @param plot_type: One of the arguments inside the brackets (line, heatmap, marginalheatmap). The default is line. + * @param colms: Defines which columns from the file should be used for the plot. The default is all. + * @param heatmap_type: Valid types are 'all' and 'line'. The porameter defines if all or only one line and column is + * used for the sideplots of the marginalheatmap; + * @param heatmap_algo: Valid algorithms are 'sum' and 'max'. The parameter defines the way how the histograms are + * calculated. + * @return 1 when there was no error, 0 if there was an error. + */ +{ + std::string s; + size_t row, col, rows, cols; + std::vector> filedata; + std::vector labels; + std::vector labels_c; + std::vector series; + char *env; + void *handle = nullptr; + PlotRange ranges = {0.0, -1.0, 0.0, -1.0}; + + if (!file_exists(data_file)) + { + fprintf(stderr, + "Error! No file with the name %s was found. Please use a correct " + "filename and filepath.\n", + data_file); + return 0; + } + if (read_data_file(data_file, filedata, labels, args, colms, &ranges)) + { + return 0; + } + if (!filedata.empty()) + { + cols = filedata.size(); + rows = filedata[0].size(); + } + else + { + fprintf(stderr, "Error! No data or valid columns are specified.\n"); + return 0; + } + + series.resize(cols); + + if ((env = getenv("GR_DISPLAY")) != nullptr) + { + handle = grm_open(GRM_SENDER, env, 8002, nullptr, nullptr); + if (handle == nullptr) + { + fprintf(stderr, "GRM connection to '%s' could not be established\n", env); + } + } + + if (!str_equals_any(*plot_type, 3, "line", "heatmap", "marginalheatmap")) + { + *plot_type = "line"; + fprintf(stderr, "No correct plot type was specified. A normal line plot is " + "getting used.\n"); + } + if (strcmp("line", *plot_type) == 0 && (rows >= 100 && cols >= 100)) + { + *plot_type = "heatmap"; + fprintf(stderr, "File data is to big for line plot. A heatmap is being tried instead.\n"); + } + grm_args_push(args, "kind", "s", *plot_type); + + if (str_equals_any(*plot_type, 2, "heatmap", "marginalheatmap")) + { + std::vector xi(rows), yi(cols), zi(rows * cols); + + if (cols <= 1) + { + fprintf(stderr, "Error! For heatmap and marginalheatmap there must be " + "atleast two specified columns.\n"); + return 0; + } + ranges.xmax = (ranges.xmax == -1.0) ? ((double)rows - 1.0 + ranges.xmin) : ranges.xmax; + ranges.ymax = (ranges.ymax == -1.0) ? ((double)cols - 1.0 + ranges.ymin) : ranges.ymax; + ranges.ymax = (ranges.ymax <= ranges.ymin) ? ranges.ymax + ranges.ymin : ranges.ymax; + + for (row = 0; row < rows; ++row) + { + xi[row] = ranges.xmin + (ranges.xmax - ranges.xmin) * ((double)row / ((double)rows - 1)); + for (col = 0; col < cols; ++col) + { + if (row == 0) + { + yi[col] = ranges.ymin + (ranges.ymax - ranges.ymin) * ((double)col / ((double)cols - 1)); + } + zi[((cols - 1) - col) * rows + row] = filedata[col][row]; + } + } + + grm_args_push(args, "x", "nD", rows, xi.data()); + grm_args_push(args, "y", "nD", cols, yi.data()); + grm_args_push(args, "z", "nD", rows * cols, zi.data()); + grm_args_push(args, "type", "s", heatmap_type); + grm_args_push(args, "algorithm", "s", heatmap_algo); + } + else if (strcmp(*plot_type, "line") == 0) + { + std::vector x(rows); + for (row = 0; row < rows; row++) + { + x[row] = (double)row; + } + for (col = 0; col < cols; col++) + { + series[col] = grm_args_new(); + grm_args_push(series[col], "x", "nD", rows, x.data()); + grm_args_push(series[col], "y", "nD", rows, filedata[col].data()); + if (!labels.empty()) + { + labels_c.push_back(labels[col].c_str()); + } + } + grm_args_push(args, "series", "nA", cols, series.data()); + if (labels_c.empty()) + { + fprintf(stderr, "No labels specified. Continue with no labels for the lines.\n"); + } + else + { + grm_args_push(args, "labels", "nS", cols, labels_c.data()); + } + } + grm_merge(args); + + if (handle != nullptr) + { + grm_send_args(handle, args); + grm_close(handle); + } + + return 1; +} diff --git a/lib/grm/src/grm/import_int.hxx b/lib/grm/src/grm/import_int.hxx new file mode 100644 index 000000000..3969411ae --- /dev/null +++ b/lib/grm/src/grm/import_int.hxx @@ -0,0 +1,35 @@ +#ifndef GRM_IMPORT_INT_HXX_INCLUDED +#define GRM_IMPORT_INT_HXX_INCLUDED + +/* ######################### includes ############################################################################### */ + +#include +#include +#include +#include +#include "error_int.h" + + +/* ######################### internal interface ##################################################################### */ + +/* ========================= datatypes ============================================================================== */ + +/* ------------------------- plot ----------------------------------------------------------------------------------- */ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~ plot ranges ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +struct PlotRange +{ + double xmin, xmax; + double ymin, ymax; +}; + +/* ========================= functions ============================================================================== */ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~ import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +std::string normalize_line(const std::string &str); +err_t read_data_file(const std::string &path, std::vector> &data, std::vector &labels, + grm_args_t *args, const char *colms, PlotRange *ranges); + +#endif // GRM_IMPORT_INT_HXX_INCLUDED diff --git a/lib/grm/src/grm/interaction.c b/lib/grm/src/grm/interaction.c index 6c92f1ddb..521c3b7f3 100644 --- a/lib/grm/src/grm/interaction.c +++ b/lib/grm/src/grm/interaction.c @@ -104,6 +104,7 @@ int grm_input(const grm_args_t *input_args) double *x_series, *y_series; unsigned int x_length, y_length; double x_0, x_end, y_0, y_end, x_step, y_step; + double xind, yind; args_values(input_args, "x", "i", &x); args_values(input_args, "y", "i", &y); @@ -123,9 +124,16 @@ int grm_input(const grm_args_t *input_args) x_step = (x_end - x_0) / x_length; y_step = (y_end - y_0) / y_length; + xind = (x - x_0) / x_step; + yind = (y - y_0) / y_step; - grm_args_push(subplot_args, "xind", "i", (int)((x - x_0) / x_step)); - grm_args_push(subplot_args, "yind", "i", (int)((y - y_0) / y_step)); + if (xind < 0 || xind >= x_length || yind < 0 || yind >= y_length) + { + xind = -1; + yind = -1; + } + grm_args_push(subplot_args, "xind", "i", (int)xind); + grm_args_push(subplot_args, "yind", "i", (int)yind); } if (args_values(input_args, "angle_delta", "d", &angle_delta)) @@ -181,7 +189,6 @@ int grm_input(const grm_args_t *input_args) { double ndc_xshift, ndc_yshift, rotation, tilt; int shift_pressed; - const char *kind; if (str_equals_any(kind, 7, "wireframe", "surface", "plot3", "scatter3", "trisurf", "volume", "isosurface")) @@ -409,7 +416,7 @@ grm_tooltip_info_t *grm_get_tooltip(const int mouse_x, const int mouse_y) double num; double x_0 = x_series[0], x_end = x_series[x_length - 1], y_0 = y_series[0], y_end = y_series[y_length - 1]; - double x_step, y_step; + double x_step, y_step, x_series_idx, y_series_idx; gr_wctondc(&x_0, &y_0); gr_wctondc(&x_end, &y_end); @@ -422,13 +429,19 @@ grm_tooltip_info_t *grm_get_tooltip(const int mouse_x, const int mouse_y) y_step = (y_end - y_0) / y_length; mindiff = 0; - info->x = x_series[(int)((mouse_x - x_0) / x_step)]; - info->y = y_series[(int)((mouse_y - y_0) / y_step)]; + x_series_idx = (mouse_x - x_0) / x_step; + y_series_idx = (mouse_y - y_0) / y_step; + if (x_series_idx < 0 || x_series_idx >= x_length || y_series_idx < 0 || y_series_idx >= y_length) + { + mindiff = DBL_MAX; + break; + } + info->x = x_series[(int)x_series_idx]; + info->y = y_series[(int)y_series_idx]; info->x_px = mouse_x; info->y_px = mouse_y; - num = z_series[((y_length - 1) - (int)((mouse_y - y_0) / y_step)) * x_length + - (int)((mouse_x - x_0) / x_step)]; + num = z_series[((y_length - 1) - (int)y_series_idx) * x_length + (int)x_series_idx]; snprintf(output, 50, "%f", num); info->label = output; } diff --git a/lib/grm/src/grm/utilcpp.cxx b/lib/grm/src/grm/utilcpp.cxx new file mode 100644 index 000000000..890157d97 --- /dev/null +++ b/lib/grm/src/grm/utilcpp.cxx @@ -0,0 +1,47 @@ +#include "utilcpp_int.hxx" +#include +#include +#include + +#ifdef _WIN64 +#include +#include +#include +#include +#define F_OK 0 +#define access _access +#else +#include +#endif + +std::string ltrim(const std::string &s) +{ + size_t start = s.find_first_not_of(WHITESPACE); + return (start == std::string::npos) ? "" : s.substr(start); +} + +std::string rtrim(const std::string &s) +{ + size_t end = s.find_last_not_of(WHITESPACE); + return (end == std::string::npos) ? "" : s.substr(0, end + 1); +} + +std::string trim(const std::string &s) +{ + return rtrim(ltrim(s)); +} + +bool file_exists(const std::string &name) +{ + return (access(name.c_str(), F_OK) != -1); +} + +bool starts_with(const std::string &str, const std::string &prefix) +{ + return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix); +} + +bool ends_with(const std::string &str, const std::string &suffix) +{ + return str.size() >= suffix.size() && 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix); +} diff --git a/lib/grm/src/grm/utilcpp_int.hxx b/lib/grm/src/grm/utilcpp_int.hxx new file mode 100644 index 000000000..4bb691096 --- /dev/null +++ b/lib/grm/src/grm/utilcpp_int.hxx @@ -0,0 +1,27 @@ +#ifndef GRM_UTIL_INT_HXX_INCLUDED +#define GRM_UTIL_INT_HXX_INCLUDED + +/* ######################### includes ############################################################################### */ + +#include +#include + + +/* ######################### internal interface ##################################################################### */ + +/* ========================= macros ================================================================================= */ + +#define WHITESPACE " \n\r\t\f\v" + +/* ========================= functions ============================================================================== */ + +/* ------------------------- util ----------------------------------------------------------------------------------- */ + +std::string ltrim(const std::string &s); +std::string rtrim(const std::string &s); +std::string trim(const std::string &s); +bool file_exists(const std::string &name); +bool starts_with(const std::string &str, const std::string &prefix); +bool ends_with(const std::string &str, const std::string &suffix); + +#endif // GRM_UTIL_INT_HXX_INCLUDED From bda1931f05f1b4ed6b93b662ce65d35caf80666c Mon Sep 17 00:00:00 2001 From: Verbov Date: Tue, 22 Nov 2022 14:56:49 +0100 Subject: [PATCH 09/11] Added missing Qt-rpaths for gksqt in CMakeList.txt --- CMakeLists.txt | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0351373c9..df79790dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,6 +134,9 @@ if(Qt4_FOUND) foreach(DIR IN LISTS QT_INCLUDE_DIR) set(QT4_MOC_INCLUDE_FLAGS ${QT4_MOC_INCLUDE_FLAGS} -I${DIR}) endforeach() + if(NOT DEFINED Qt4_LIBRARY_DIR) + get_filename_component(Qt4_LIBRARY_DIR "${QT_LIBRARY_DIR}/../.." ABSOLUTE) + endif() endif() if(Qt5Widgets_FOUND AND Qt5Core_FOUND @@ -143,6 +146,9 @@ if(Qt5Widgets_FOUND foreach(DIR IN LISTS Qt5Core_INCLUDE_DIRS Qt5Gui_INCLUDE_DIRS Qt5Widgets_INCLUDE_DIRS) set(QT5_MOC_INCLUDE_FLAGS ${QT5_MOC_INCLUDE_FLAGS} -I${DIR}) endforeach() + if(NOT DEFINED Qt5_LIBRARY_DIR) + get_filename_component(Qt5_LIBRARY_DIR "${Qt5_DIR}/../.." ABSOLUTE) + endif() endif() if(Qt6Widgets_FOUND AND Qt6Core_FOUND @@ -152,6 +158,9 @@ if(Qt6Widgets_FOUND foreach(DIR IN LISTS Qt6Core_INCLUDE_DIRS Qt6Gui_INCLUDE_DIRS Qt6Widgets_INCLUDE_DIRS) set(QT6_MOC_INCLUDE_FLAGS ${QT6_MOC_INCLUDE_FLAGS} -I${DIR}) endforeach() + if(NOT DEFINED Qt6_LIBRARY_DIR) + get_filename_component(Qt6_LIBRARY_DIR "${Qt6_DIR}/../.." ABSOLUTE) + endif() endif() if(X11_FOUND) @@ -1003,22 +1012,27 @@ if(Qt4_FOUND ) ) add_executable(gksqt WIN32 MACOSX_BUNDLE lib/gks/qt/gksqt.cxx lib/gks/qt/gksserver.cxx lib/gks/qt/gkswidget.cxx) - set_target_properties(gksqt PROPERTIES CXX_STANDARD 11 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON) target_link_libraries(gksqt PUBLIC gks_static) if(Qt6Widgets_FOUND AND Qt6Core_FOUND AND Qt6Network_FOUND ) target_link_libraries(gksqt PUBLIC Qt6::Widgets Qt6::Core Qt6::Network) + set(gksqt_INSTALL_RPATH "${INSTALL_RPATH};${Qt6_LIBRARY_DIR}") elseif( Qt5Widgets_FOUND AND Qt5Core_FOUND AND Qt5Network_FOUND ) target_link_libraries(gksqt PUBLIC Qt5::Widgets Qt5::Core Qt5::Network) + set(gksqt_INSTALL_RPATH "${INSTALL_RPATH};${Qt5_LIBRARY_DIR}") elseif(Qt4_FOUND) target_link_libraries(gksqt PUBLIC Qt4::QtCore Qt4::QtGui Qt4::QtNetwork) + set(gksqt_INSTALL_RPATH "${INSTALL_RPATH};${Qt4_LIBRARY_DIR}") endif() + set_target_properties( + gksqt PROPERTIES CXX_STANDARD 11 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON INSTALL_RPATH "${gksqt_INSTALL_RPATH}" + ) if(MINGW) target_compile_options(gksqt PRIVATE -fno-exceptions ${COMPILER_OPTION_ERROR_IMPLICIT}) endif() @@ -1093,15 +1107,9 @@ if((Qt6Widgets_FOUND AND Qt6Core_FOUND) OR (Qt5Widgets_FOUND AND Qt5Core_FOUND)) ) if(Qt6Widgets_FOUND AND Qt6Core_FOUND) target_link_libraries(grm-plots PRIVATE Qt6::Widgets Qt6::Core grm_static) - if(NOT DEFINED Qt6_LIBRARY_DIR) - get_filename_component(Qt6_LIBRARY_DIR "${Qt6_DIR}/../.." ABSOLUTE) - endif() set(grm-plots_INSTALL_RPATH "${INSTALL_RPATH};${Qt6_LIBRARY_DIR}") else() target_link_libraries(grm-plots PRIVATE Qt5::Widgets Qt5::Core grm_static) - if(NOT DEFINED Qt5_LIBRARY_DIR) - get_filename_component(Qt5_LIBRARY_DIR "${Qt5_DIR}/../.." ABSOLUTE) - endif() set(grm-plots_INSTALL_RPATH "${INSTALL_RPATH};${Qt5_LIBRARY_DIR}") endif() set_target_properties( From f588e9625e8f1c636cf59fe01663cd26de52fb4f Mon Sep 17 00:00:00 2001 From: Daniel Kaiser Date: Tue, 15 Nov 2022 16:32:08 +0100 Subject: [PATCH 10/11] Use wchar_t to load fonts on Windows --- lib/gks/font.c | 21 +++- lib/gks/ft.c | 315 ++++++++++++++++++++++++++++++++++++----------- lib/gks/plugin.c | 1 + 3 files changed, 261 insertions(+), 76 deletions(-) diff --git a/lib/gks/font.c b/lib/gks/font.c index eada2a27e..096c31634 100644 --- a/lib/gks/font.c +++ b/lib/gks/font.c @@ -13,6 +13,14 @@ #include "gks.h" #include "gkscore.h" +#if defined(_WIN32) +#define STRSAFE_NO_DEPRECATE +#define _CRT_NON_CONFORMING_WCSTOK +#define __STRSAFE__NO_INLINE +#include +#include +#endif + #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif @@ -25,6 +33,7 @@ int gks_open_font(void) char fontdb[MAXPATHLEN]; int fd; +#ifndef _WIN32 path = gks_getenv("GKS_FONTPATH"); if (path == NULL) { @@ -32,10 +41,18 @@ int gks_open_font(void) if (path == NULL) path = GRDIR; } strcpy(fontdb, (char *)path); -#ifndef _WIN32 strcat(fontdb, "/fonts/gksfont.dat"); #else - strcat(fontdb, "\\FONTS\\GKSFONT.DAT"); + wchar_t wfontdb[MAXPATHLEN]; + if (!GetEnvironmentVariableW(L"GKS_FONTPATH", wfontdb, MAXPATHLEN)) + { + if (!GetEnvironmentVariableW(L"GRDIR", wfontdb, MAXPATHLEN)) + { + MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, GRDIR, -1, wfontdb, MAXPATHLEN); + } + } + StringCbCatW(wfontdb, MAXPATHLEN, L"\\FONTS\\GKSFONT.DAT"); + WideCharToMultiByte(CP_UTF8, 0, wfontdb, wcslen(wfontdb) + 1, fontdb, MAXPATHLEN, NULL, NULL); #endif fd = gks_open_file(fontdb, "r"); diff --git a/lib/gks/ft.c b/lib/gks/ft.c index 2fda59c29..34a566020 100644 --- a/lib/gks/ft.c +++ b/lib/gks/ft.c @@ -4,7 +4,11 @@ #include #include #if defined(_WIN32) +#define STRSAFE_NO_DEPRECATE +#define _CRT_NON_CONFORMING_WCSTOK +#define __STRSAFE__NO_INLINE #include +#include #else #include #include @@ -118,6 +122,9 @@ static const double caps[] = {0.662, 0.653, 0.676, 0.669, 0.718, 0.718, 0.718, 0 static FT_Bool init = 0; static FT_Library library; +static unsigned char **ft_font_file_pointer = NULL; +static int ft_num_font_files = 0; + double horiAdvance = 0, vertAdvance = 0; static unsigned int npoints = 0, maxpoints = 0; @@ -128,9 +135,15 @@ static int *opcodes = NULL; static long pen_x = 0; -static const char *system_font_directories[] = { #if defined(_WIN32) - "\\Fonts", NULL +typedef wchar_t ft_path_char_t; +#else +typedef char ft_path_char_t; +#endif + +static const ft_path_char_t *system_font_directories[] = { +#if defined(_WIN32) + L"\\Fonts", NULL #elif defined(__APPLE__) "/opt/local/share/fonts", "/Library/Fonts/", "/System/Library/Fonts/", NULL #else @@ -143,9 +156,47 @@ static const char *system_font_directories[] = { #endif }; -static const char *user_font_directories[] = { +static size_t ft_open_font(ft_path_char_t *fname) +{ + FILE *f; + size_t size; +#ifdef _WIN32 + f = _wfopen(fname, L"rb"); +#else + f = fopen(fname, "rb"); +#endif + if (!f) + { + return 0; + } + fseek(f, 0L, SEEK_END); + size = ftell(f); + rewind(f); + if (size) + { + ft_font_file_pointer = + (unsigned char **)gks_realloc(ft_font_file_pointer, (ft_num_font_files + 1) * (int)sizeof(char *)); + ft_font_file_pointer[ft_num_font_files] = (unsigned char *)gks_malloc((int)size); + fread(ft_font_file_pointer[ft_num_font_files], 1, size, f); + ft_num_font_files++; + } + fclose(f); + return size; +} + +static void ft_close_all_fonts() +{ + int i; + for (i = 0; i < ft_num_font_files; i++) + { + gks_free(ft_font_file_pointer[i]); + } + gks_free(ft_font_file_pointer); +} + +static const ft_path_char_t *user_font_directories[] = { #if defined(_WIN32) - "\\AppData\\Local\\Microsoft\\Windows\\Fonts", NULL + L"\\AppData\\Local\\Microsoft\\Windows\\Fonts", NULL #elif defined(__APPLE__) "Library/Fonts", NULL #else @@ -170,13 +221,19 @@ static FT_Long ft_max(FT_Long a, FT_Long b) return a > b ? a : b; } -static int ft_join_path(char *result, size_t size, const char *first, const char *second) +static int ft_join_path(ft_path_char_t *result, size_t size, const ft_path_char_t *first, const ft_path_char_t *second) { #if defined(_WIN32) const char delim = '\\'; + if (wcslen(first) + wcslen(second) + 1 >= MAXPATHLEN) + { + return 0; + } + + StringCbPrintfW(result, size, L"%ws%c%ws", first, delim, second); + return 1; #else const char delim = '/'; -#endif if (strlen(first) + strlen(second) + 1 >= MAXPATHLEN) { return 0; @@ -184,9 +241,10 @@ static int ft_join_path(char *result, size_t size, const char *first, const char snprintf(result, size, "%s%c%s", first, delim, second); return 1; +#endif } -static int ft_is_absolute_path(const char *path) +static int ft_is_absolute_path(const ft_path_char_t *path) { #ifndef _WIN32 return (path[0] == '/'); @@ -195,35 +253,23 @@ static int ft_is_absolute_path(const char *path) #endif } -static char *ft_user_home_path() -{ -#if defined(_WIN32) - return getenv("USERPROFILE"); -#else - char *env = getenv("HOME"); - if (env) - { - return env; - } - return getpwuid(getuid())->pw_dir; -#endif -} - -static int ft_search_file_in_dir(const char *base_dir, const char *filename, char *result, int recursive) +static int ft_search_file_in_dir(const ft_path_char_t *base_dir, const ft_path_char_t *filename, ft_path_char_t *result, + int recursive) { - char path[MAXPATHLEN]; + ft_path_char_t path[MAXPATHLEN]; #if defined(_WIN32) - WIN32_FIND_DATA file; + WIN32_FIND_DATAW file; HANDLE handle = NULL; - if (!ft_join_path(path, MAXPATHLEN, base_dir, "*.*") || (handle = FindFirstFile(path, &file)) == INVALID_HANDLE_VALUE) + if (!ft_join_path(path, MAXPATHLEN, base_dir, L"*.*") || + (handle = FindFirstFileW(path, &file)) == INVALID_HANDLE_VALUE) { return 0; } do { - if (strcmp(file.cFileName, ".") == 0 || strcmp(file.cFileName, "..") == 0 || + if (wcsncmp(file.cFileName, L".", MAXPATHLEN) == 0 || wcsncmp(file.cFileName, L"..", MAXPATHLEN) == 0 || !ft_join_path(path, MAXPATHLEN, base_dir, file.cFileName)) { continue; @@ -239,15 +285,15 @@ static int ft_search_file_in_dir(const char *base_dir, const char *filename, cha else if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (file.dwFileAttributes & (FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE))) { - if (strcmp(file.cFileName, filename) == 0) + if (wcsncmp(file.cFileName, filename, MAXPATHLEN) == 0) { - strcpy(result, path); + StringCbCopyW(result, MAXPATHLEN, path); FindClose(handle); return 1; } } } - while (FindNextFile(handle, &file)); + while (FindNextFileW(handle, &file)); FindClose(handle); #else @@ -291,39 +337,40 @@ static int ft_search_file_in_dir(const char *base_dir, const char *filename, cha return 0; } -static int ft_find_font(const char *filename, char *result) +static int ft_find_font(const ft_path_char_t *filename, ft_path_char_t *result) { - const char **font_directory; #if defined(_WIN32) - const char delim[2] = ";"; -#else - const char delim[2] = ":"; -#endif - char abspath[MAXPATHLEN]; - char *gks_font_dir, *user_home; + const ft_path_char_t **font_directory; + ft_path_char_t abspath[MAXPATHLEN]; + ft_path_char_t env[MAXPATHLEN]; + char reg_result_bytes[MAXPATHLEN]; + ft_path_char_t *gks_font_dir; + const ft_path_char_t delim[2] = L";"; + long size = MAXPATHLEN; + ft_path_char_t windir[MAXPATHLEN]; + HKEY registry_key; + LSTATUS lResult; /* search paths from `GKS_FONT_DIRS` environment variable */ - if ((gks_font_dir = getenv("GKS_FONT_DIRS")) != NULL) + if (GetEnvironmentVariableW(L"GKS_FONT_DIRS", env, MAXPATHLEN)) { - strncpy(abspath, gks_font_dir, MAXPATHLEN - 1); - gks_font_dir = strtok(abspath, delim); + gks_font_dir = wcstok(env, delim); while (gks_font_dir) { if (ft_search_file_in_dir(gks_font_dir, filename, result, 0)) { return 1; } - gks_font_dir = strtok(NULL, delim); + gks_font_dir = wcstok(NULL, delim); } } /* search OS's user font directories */ - user_home = ft_user_home_path(); - if (user_home) + if (GetEnvironmentVariableW(L"USERPROFILE", env, MAXPATHLEN)) { for (font_directory = user_font_directories; *font_directory; font_directory++) { - if (!ft_join_path(abspath, MAXPATHLEN, user_home, *font_directory)) + if (!ft_join_path(abspath, MAXPATHLEN, env, *font_directory)) { continue; } @@ -334,23 +381,21 @@ static int ft_find_font(const char *filename, char *result) } } - /* search OS's system font directories */ -#if defined(_WIN32) - long size = MAXPATHLEN; - char *windir = NULL; - HKEY registry_key; - - LSTATUS lResult = - RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, - KEY_QUERY_VALUE, ®istry_key); + /* search OS's system font directories */ + lResult = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, + KEY_QUERY_VALUE, ®istry_key); if (lResult == ERROR_SUCCESS) { - lResult = RegQueryValueExA(registry_key, "Fonts", NULL, NULL, abspath, &size); + lResult = RegQueryValueExA(registry_key, "Fonts", NULL, NULL, reg_result_bytes, &size); if (lResult != ERROR_SUCCESS) { size = 0; } + else + { + MultiByteToWideChar(CP_UTF8, 0, reg_result_bytes, -1, abspath, MAXPATHLEN); + } RegCloseKey(registry_key); } else @@ -360,9 +405,9 @@ static int ft_find_font(const char *filename, char *result) if (!size) { - if ((windir = getenv("WINDIR")) == NULL) + if (!GetEnvironmentVariableW(L"WINDIR", windir, MAXPATHLEN)) { - windir = "C:\\Windows"; + StringCbCopyW(windir, MAXPATHLEN, L"C:\\Windows"); } for (font_directory = system_font_directories; *font_directory; font_directory++) { @@ -380,8 +425,48 @@ static int ft_find_font(const char *filename, char *result) { return 1; } - #else + const ft_path_char_t **font_directory; + const ft_path_char_t delim[2] = ":"; + ft_path_char_t abspath[MAXPATHLEN]; + ft_path_char_t *gks_font_dir, *user_home; + + /* search paths from `GKS_FONT_DIRS` environment variable */ + if ((gks_font_dir = getenv("GKS_FONT_DIRS")) != NULL) + { + strncpy(abspath, gks_font_dir, MAXPATHLEN - 1); + gks_font_dir = strtok(abspath, delim); + while (gks_font_dir) + { + if (ft_search_file_in_dir(gks_font_dir, filename, result, 0)) + { + return 1; + } + gks_font_dir = strtok(NULL, delim); + } + } + + /* search OS's user font directories */ + user_home = getenv("HOME"); + if (!user_home) + { + user_home = getpwuid(getuid())->pw_dir; + } + if (user_home) + { + for (font_directory = user_font_directories; *font_directory; font_directory++) + { + if (!ft_join_path(abspath, MAXPATHLEN, user_home, *font_directory)) + { + continue; + } + if (ft_search_file_in_dir(abspath, filename, result, 1)) + { + return 1; + } + } + } + for (font_directory = system_font_directories; *font_directory; font_directory++) { if (ft_search_file_in_dir(*font_directory, filename, result, 1)) @@ -588,6 +673,7 @@ void gks_ft_terminate(void) { if (init) { + ft_close_all_fonts(); FT_Done_FreeType(library); } init = 0; @@ -621,8 +707,25 @@ static int gks_ft_convert_textfont(int textfont) return textfont; } -static char *gks_ft_get_font_path(const char *font_name, const char *font_file_extension) +static ft_path_char_t *gks_ft_get_font_path(const char *font_name, const char *font_file_extension) { +#ifdef _WIN32 + ft_path_char_t prefix[MAXPATHLEN]; + ft_path_char_t *font_path; + size_t len; + + if (!GetEnvironmentVariableW(L"GKS_FONTPATH", prefix, MAXPATHLEN)) + { + if (!GetEnvironmentVariableW(L"GRDIR", prefix, MAXPATHLEN)) + { + MultiByteToWideChar(CP_UTF8, 0, GRDIR, -1, prefix, MAXPATHLEN); + } + } + StringCbLengthW(prefix, MAXPATHLEN, &len); + len += 2 * (7 + strlen(font_name) + strlen(font_file_extension) + 1); + font_path = (ft_path_char_t *)gks_malloc(len * sizeof(ft_path_char_t)); + StringCbPrintfW(font_path, MAXPATHLEN, L"%lS\\FONTS\\%S%S", prefix, font_name, font_file_extension); +#else const char *prefix; char *font_path; @@ -638,13 +741,10 @@ static char *gks_ft_get_font_path(const char *font_name, const char *font_file_e font_path = (char *)gks_malloc(strlen(prefix) + 7 + strlen(font_name) + strlen(font_file_extension) + 1); strcpy(font_path, prefix); -#ifdef _WIN32 - strcat(font_path, "\\FONTS\\"); -#else strcat(font_path, "/fonts/"); -#endif strcat(font_path, font_name); strcat(font_path, font_file_extension); +#endif return font_path; } @@ -665,17 +765,35 @@ static void gks_ft_init_fallback_faces() } else { - char *file = gks_ft_get_font_path(fallback_font_list[i], ""); - error = FT_New_Face(library, file, 0, &fallback_font_faces[i]); + ft_path_char_t *file = gks_ft_get_font_path(fallback_font_list[i], ""); + size_t size = ft_open_font(file); + if (!size) + { +#ifdef _WIN32 + gks_perror("failed to open font file: %ls", file); +#else + gks_perror("failed to open font file: %s", file); +#endif + } + error = FT_New_Memory_Face(library, ft_font_file_pointer[ft_num_font_files - 1], size, 0, + &fallback_font_faces[i]); gks_free(file); if (error == FT_Err_Unknown_File_Format) { +#ifdef _WIN32 + gks_perror("unknown file format: %ls", file); +#else gks_perror("unknown file format: %s", file); +#endif fallback_font_faces[i] = NULL; } else if (error) { +#ifdef _WIN32 + gks_perror("could not open font file: %ls", file); +#else gks_perror("could not open font file: %s", file); +#endif fallback_font_faces[i] = NULL; } } @@ -686,10 +804,17 @@ static void gks_ft_init_fallback_faces() int gks_ft_load_user_font(char *font, int ignore_file_not_found) { static int user_font_index = 300; - char abspath[MAXPATHLEN] = {0}; + ft_path_char_t abspath[MAXPATHLEN] = {0}; FT_Error error; FT_Face face; int textfont; + size_t file_size; +#ifdef _WIN32 + ft_path_char_t _font[MAXPATHLEN]; + MultiByteToWideChar(CP_UTF8, MB_COMPOSITE, font, -1, _font, MAXPATHLEN); +#else + char *_font = font; +#endif if (!init) gks_ft_init(); if (strlen(font) > MAXPATHLEN - 1) @@ -698,11 +823,15 @@ int gks_ft_load_user_font(char *font, int ignore_file_not_found) return -1; } - if (!ft_is_absolute_path(font)) + if (!ft_is_absolute_path(_font)) { - if (ft_find_font(font, abspath)) + if (ft_find_font(_font, abspath)) { - font = abspath; +#ifdef _WIN32 + StringCbCopyW(_font, MAXPATHLEN, abspath); +#else + _font = abspath; +#endif } else { @@ -717,7 +846,13 @@ int gks_ft_load_user_font(char *font, int ignore_file_not_found) return -1; } - error = FT_New_Face(library, font, 0, &face); + file_size = ft_open_font(_font); + if (!file_size) + { + gks_perror("failed to open font file: %s", font); + return -1; + } + error = FT_New_Memory_Face(library, ft_font_file_pointer[ft_num_font_files - 1], file_size, 0, &face); if (error == FT_Err_Unknown_File_Format) { gks_perror("unknown file format: %s", font); @@ -771,23 +906,55 @@ void *gks_ft_get_face(int textfont) if (font_face_cache[textfont] == NULL) { - char *file = gks_ft_get_font_path(font, (use_ttf ? ".ttf" : ".pfb")); - error = FT_New_Face(library, file, 0, &face); - gks_free(file); + ft_path_char_t *file = gks_ft_get_font_path(font, (use_ttf ? ".ttf" : ".pfb")); + size_t size = ft_open_font(file); + if (!size) + { +#ifdef _WIN32 + gks_perror("failed to open font file: %ls", file); +#else + gks_perror("failed to open font file: %s", file); +#endif + return NULL; + } + error = FT_New_Memory_Face(library, ft_font_file_pointer[ft_num_font_files - 1], size, 0, &face); if (error == FT_Err_Unknown_File_Format) { +#ifdef _WIN32 + gks_perror("unknown file format: %ls", file); +#else gks_perror("unknown file format: %s", file); +#endif return NULL; } else if (error) { +#ifdef _WIN32 + gks_perror("could not open font file: %ls", file); +#else gks_perror("could not open font file: %s", file); +#endif return NULL; } + gks_free(file); if (strcmp(FT_Get_X11_Font_Format(face), "Type 1") == 0) { - char *file = gks_ft_get_font_path(font, ".afm"); - FT_Attach_File(face, file); + FT_Open_Args args; + file = gks_ft_get_font_path(font, ".afm"); + size = ft_open_font(file); + if (!size) + { +#ifdef _WIN32 + gks_perror("failed to open afm file: %ls", font); +#else + gks_perror("failed to open afm file: %s", font); +#endif + return NULL; + } + args.flags = FT_OPEN_MEMORY; + args.memory_base = ft_font_file_pointer[ft_num_font_files - 1]; + args.memory_size = size; + FT_Attach_Stream(face, &args); gks_free(file); } font_face_cache[textfont] = face; diff --git a/lib/gks/plugin.c b/lib/gks/plugin.c index 7bbd96d95..e435b1169 100644 --- a/lib/gks/plugin.c +++ b/lib/gks/plugin.c @@ -4,6 +4,7 @@ #include #ifdef _WIN32 +#define __STRSAFE__NO_INLINE #include #include #else From facf413820203a7f9066f61b98d809effbea7725 Mon Sep 17 00:00:00 2001 From: Daniel Kaiser Date: Wed, 23 Nov 2022 08:38:49 +0100 Subject: [PATCH 11/11] use wchar_t environment variables for gksqt binary on windows --- lib/gks/socket.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/lib/gks/socket.c b/lib/gks/socket.c index e29324032..4de539589 100644 --- a/lib/gks/socket.c +++ b/lib/gks/socket.c @@ -20,7 +20,9 @@ #include #include #else +#define __STRSAFE__NO_INLINE #include +#include #endif #include "gks.h" @@ -60,18 +62,12 @@ static int is_running = 0; static DWORD WINAPI gksqt_thread(LPVOID parm) { - char *cmd = (char *)parm; - wchar_t *w_cmd; - int len = strlen(cmd); - int w_len = MultiByteToWideChar(CP_UTF8, 0, cmd, len, NULL, 0) + 1; + wchar_t *cmd = (char *)parm; wchar_t w_cmd_line[CMD_LINE_LEN]; STARTUPINFOW startupInfo; PROCESS_INFORMATION processInformation; - w_cmd = (wchar_t *)gks_malloc(sizeof(wchar_t) * w_len); - MultiByteToWideChar(CP_UTF8, 0, cmd, len + 1, w_cmd, w_len); - - swprintf(w_cmd_line, CMD_LINE_LEN, L"cmd /c \"%ls\"", w_cmd); + StringCbPrintfW(w_cmd_line, CMD_LINE_LEN, L"cmd /c \"%ls\"", cmd); ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); @@ -86,8 +82,6 @@ static DWORD WINAPI gksqt_thread(LPVOID parm) CloseHandle(processInformation.hProcess); CloseHandle(processInformation.hThread); - free(w_cmd); - return 0; } @@ -160,16 +154,16 @@ static void *gksqt_thread(void *arg) #endif -static int start(const char *cmd) +static int start(void *cmd) { #ifdef _WIN32 DWORD thread; - if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)gksqt_thread, (void *)cmd, 0, &thread) == NULL) return -1; + if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)gksqt_thread, cmd, 0, &thread) == NULL) return -1; #else pthread_t thread; - if (pthread_create(&thread, NULL, gksqt_thread, (void *)cmd)) return -1; + if (pthread_create(&thread, NULL, gksqt_thread, cmd)) return -1; #endif return 0; } @@ -234,14 +228,31 @@ static int connect_socket(int quiet) static int open_socket(int wstype) { +#ifdef _WIN32 + wchar_t command[MAX_PATH], w_env[MAX_PATH]; +#else const char *command = NULL, *env; + char *cmd = NULL; +#endif int retry_count; int max_retry_count = 20; - char *cmd = NULL; int s; if (wstype >= 411 && wstype <= 413) { +#ifdef _WIN32 + if (!GetEnvironmentVariableW(L"GKS_QT", command, MAX_PATH)) + { + if (!GetEnvironmentVariableW(L"GRDIR", w_env, MAX_PATH)) + { + StringCbPrintfW(command, MAX_PATH, L"%wS\\bin\\gksqt.exe", GRDIR); + } + else + { + StringCbPrintfW(command, MAX_PATH, L"%ws\\bin\\gksqt.exe", w_env); + } + } +#else command = gks_getenv("GKS_QT"); if (command == NULL) { @@ -249,17 +260,14 @@ static int open_socket(int wstype) if (env == NULL) env = GRDIR; cmd = (char *)gks_malloc(MAXPATHLEN); -#ifndef _WIN32 #ifdef __APPLE__ snprintf(cmd, MAXPATHLEN, "%s/Applications/gksqt.app/Contents/MacOS/gksqt", env); #else snprintf(cmd, MAXPATHLEN, "%s/bin/gksqt", env); -#endif -#else - snprintf(cmd, MAXPATHLEN, "%s\\bin\\gksqt.exe", env); #endif command = cmd; } +#endif } for (retry_count = 1; retry_count <= max_retry_count; retry_count++) @@ -272,7 +280,7 @@ static int open_socket(int wstype) because in this case gksqt is started by the GR.jl wrapper script */ if (*command) { - if (start(command) != 0) gks_perror("could not auto-start GKS Qt application"); + if (start((void *)command) != 0) gks_perror("could not auto-start GKS Qt application"); } } #ifndef _WIN32 @@ -291,7 +299,9 @@ static int open_socket(int wstype) is_running = (retry_count <= max_retry_count); +#ifndef _WIN32 if (cmd != NULL) free(cmd); +#endif return s; }