Imported Upstream version 2.3.3+svn1216
authorDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sat, 5 Dec 2015 13:50:17 +0000 (15:50 +0200)
committerDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sat, 5 Dec 2015 13:50:17 +0000 (15:50 +0200)
87 files changed:
CMakeLists.txt
ChangeLog.txt
FindMathGL2.cmake
clean-svn [new file with mode: 0755]
cmake-qt4.txt
cmake-qt5.txt
examples/CMakeLists.txt
examples/full_test.cpp
include/config.h.in
include/mgl2/Fl_MathGL.h [new file with mode: 0644]
include/mgl2/abstract.h
include/mgl2/base.h
include/mgl2/canvas.h
include/mgl2/canvas_cf.h
include/mgl2/canvas_wnd.h
include/mgl2/data.h
include/mgl2/data_cf.h
include/mgl2/datac.h
include/mgl2/datac_cf.h
include/mgl2/define.h
include/mgl2/fltk.h
include/mgl2/mgl.h
include/mgl2/mgl_cf.h
include/mgl2/mpi.h
include/mgl2/pde.h
include/mgl2/plot.h
include/mgl2/prim.h
include/mgl2/qmathgl.h
include/mgl2/qt.h
include/mgl2/type.h
include/mgl2/wnd.h
json/CMakeLists.txt
mgltex/Recompilation_decision.eps [new file with mode: 0644]
mgltex/Recompilation_decision.pdf [new file with mode: 0644]
mgltex/Recompilation_decision.svg [new file with mode: 0644]
mgltex/mgltex.dtx
mgltex/mgltex.ins
mgltex/mgltex.pdf
mgltex/mgltex.sty
mgltex/sample.tex
src/CMakeLists.txt
src/addon.cpp
src/axis.cpp
src/base.cpp
src/canvas.cpp
src/canvas_cf.cpp
src/complex.cpp
src/complex_io.cpp
src/crust.cpp
src/data.cpp
src/data_ex.cpp
src/data_io.cpp
src/evalc.cpp
src/evalp.cpp
src/exec.cpp
src/export_2d.cpp
src/fft.cpp
src/fit.cpp
src/interp.hpp
src/opengl.cpp
src/parser.cpp
src/pixel.cpp
src/plot.cpp
src/prim.cpp
src/s_hull/s_hull_pro.cpp
src/s_hull/s_hull_pro.h
src/vect.cpp
src/volume.cpp
todo.txt
udav/CMakeLists.txt
udav/prop_dlg.cpp
udav/prop_dlg.h
udav/qmglsyntax.cpp
udav/text_pnl.cpp
udav/textedit.cpp
udav/textedit.h
udav/udav.desktop
udav/udav_wnd.cpp
utils/CMakeLists.txt
utils/make_bin.cpp
utils/mglconv.cpp
utils/mglview.cpp
widgets/CMakeLists.txt
widgets/fltk.cpp
widgets/qt.cpp
widgets/qt4/CMakeLists.txt
widgets/qt5/CMakeLists.txt

index 2aae3347299e56337f7769cdc679643bf2f60880..e2f5e464b384a2e29f5bf444e8d6fb6a9dd84f83 100644 (file)
@@ -15,6 +15,38 @@ set(MathGL_VERSION_MAJOR 2)
 set(MathGL_VERSION_MINOR 3.3)
 set(MathGL_SOVERSION 7.4.0)
 
+function(mgl_add_lib mgl_tmp_lib)
+       if(${mgl_tmp_lib} MATCHES mgl)
+               set(mgllib mgl)
+               set(mgllib2 mgl2)
+       else(${mgl_tmp_lib} MATCHES mgl)
+               set(mgllib mgl-${mgl_tmp_lib})
+               set(mgllib2 mgl2-${mgl_tmp_lib})
+       endif(${mgl_tmp_lib} MATCHES mgl)
+       set(mgl_src_lst ${ARGV})
+       list(REMOVE_AT mgl_src_lst 0)
+       add_library(${mgllib} SHARED ${mgl_src_lst})
+       add_library(${mgllib}-static STATIC ${mgl_src_lst})
+       set_target_properties(${mgllib} PROPERTIES SOVERSION ${MathGL_SOVERSION})
+       set_target_properties(${mgllib} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
+       set_target_properties(${mgllib} PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
+       set_target_properties(${mgllib}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
+       target_compile_definitions(${mgllib}-static PUBLIC MGL_STATIC_DEFINE)
+
+       if(enable-mgl2)
+               set_target_properties(${mgllib} PROPERTIES OUTPUT_NAME "${mgllib2}")
+               set_target_properties(${mgllib}-static PROPERTIES OUTPUT_NAME "${mgllib2}")
+       else(enable-mgl2)
+               set_target_properties(${mgllib}-static PROPERTIES OUTPUT_NAME "${mgllib}")
+       endif(enable-mgl2)
+
+       install(
+               TARGETS ${mgllib} ${mgllib}-static
+               RUNTIME DESTINATION bin
+               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
+               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
+       )
+endfunction(mgl_add_lib mgl_tmp_lib)
 
 MACRO(MGL_DEPENDENT_OPTION option doc default depends1 force1 depends2 force2)
   IF(${option}_ISSET MATCHES "^${option}_ISSET$")
@@ -72,6 +104,7 @@ option(enable-all-widgets "Enable all Widgets")
 option(enable-all-swig "Enable all SWIG based interfaces")
 option(enable-rvalue "Enable move constructor support (need C++11)" OFF)
 option(enable-pthread "Enable POSIX threads support" OFF)
+option(enable-pthr_fltk "Enable POSIX threads for widgets" ON)
 option(enable-openmp "Enable OpenMP support" ON)
 
 if(enable-pthread AND enable-openmp)
@@ -174,6 +207,7 @@ CHECK_CXX_SOURCE_COMPILES(
 #include <complex.h>
 int main(int argc, char *args[])
 {std::complex<double> c(2.0, 1.0);
+double _Complex i=1.0i;
 double _Complex *a = reinterpret_cast<double _Complex *>(&c);
 std::complex<double> b(*a);return 0;}" MGL_HAVE_C99_COMPLEX)
 if(NOT MGL_HAVE_C99_COMPLEX)
@@ -259,6 +293,13 @@ endif(enable-pthread)
 
 if(enable-gsl)
        set(MGL_HAVE_GSL 1)
+       FIND_PACKAGE(PkgConfig)
+       pkg_check_modules(GSL2 REQUIRED gsl)
+       if(GSL2_FOUND)
+               if ( NOT ${GSL2_VERSION} LESS 2.0)
+                       SET(MGL_HAVE_GSL2 1)
+               endif ( NOT ${GSL2_VERSION} LESS 2.0)
+       endif ( GSL2_FOUND )
        find_library(GSL_LIB gsl)
        find_library(GSL_CBLAS_LIB gslcblas)
        find_path(GSL_INCLUDE_DIR gsl/gsl_fft_complex.h)
index 3add6371b8971b13e36ecf61b7bd0148cd657317..f58b86c0f083036837a9494002bf392dc935cf5b 100644 (file)
@@ -1,3 +1,24 @@
+2.3.4 Released ?? December 2015
+
+* Add mglData::Pulse() for determining pulse parameters
+* Add Pmap() plot for Poincare map
+* Add Lamerey() plot for Lamerey diagram
+* Add Bifurcation() plot for Bifurcation diagram
+* Add mglGraph::SetPenDelta() for changing size of semi-transparent area around lines, marks, glyphs, ...
+
+* Add MGL command 'fscanf' for getting formated data from textual file
+* Add MGL command 'echo' for printing the content of data
+* Add MGL command 'print' -- like 'info' but print immediately in stdout
+* Add option to rewrite file in 'savehdf'
+
+* Force set focus for editor in UDAV
+* Add line numbers to UDAV editor. Cyan number denote current line, red numbers denote lines with errors.
+* Disable mouse wheel for zooming in UDAV by default
+
+* Update mgltex (thanks to Diego Sejas Viscarra)
+
+* Bugfixes
+
 2.3.3 Released 01 June 2015
 
 * Add SurfCA() and Surf3CA() plots
index ec5ba2dfa5287476054b3c6384a40401a0ada1f1..772b5055c8d5833ff7cf6a9d06dbaf00f9ce68ec 100644 (file)
@@ -113,12 +113,12 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(MathGL2
                REQUIRED_VARS MATHGL2_LIBRARY MATHGL2_INCLUDE_DIR
                VERSION_VAR MATHGL2_VERSION_STRING)
 
-FOREACH(_Component ${MathGL2_FIND_COMPONENTS})
+FOREACH(_Component ${MATHGL2_FIND_COMPONENTS})
        STRING(TOLOWER ${_Component} _component)
        STRING(TOUPPER ${_Component} _COMPONENT)
 
-       SET(MathGL2_${_Component}_FIND_REQUIRED ${MathGL2_FIND_REQUIRED})
-       SET(MathGL2_${_Component}_FIND_QUIETLY true)
+       SET(MATHGL2_${_Component}_FIND_REQUIRED ${MATHGL2_FIND_REQUIRED})
+       SET(MATHGL2_${_Component}_FIND_QUIETLY true)
        # TODO find qt.h for qt4 and qt5 !!!
        FIND_PATH(MATHGL2_${_COMPONENT}_INCLUDE_DIR
                                NAMES mgl2/${_component}.h
@@ -127,7 +127,7 @@ FOREACH(_Component ${MathGL2_FIND_COMPONENTS})
                                NAMES mgl-${_component}
                                PATHS ${MATHGL2_LIBRARY_DIR} NO_DEFAULT_PATH)
 
-       FIND_PACKAGE_HANDLE_STANDARD_ARGS(MathGL2_${_Component} DEFAULT_MSG
+       FIND_PACKAGE_HANDLE_STANDARD_ARGS(MATHGL2_${_Component} DEFAULT_MSG
                                                                                MATHGL2_${_COMPONENT}_LIBRARY
                                                                                MATHGL2_${_COMPONENT}_INCLUDE_DIR)
 
diff --git a/clean-svn b/clean-svn
new file mode 100755 (executable)
index 0000000..f0ba47a
--- /dev/null
+++ b/clean-svn
@@ -0,0 +1,3 @@
+find . -name '.svn' -print0 | xargs -0 rm -rf
+find . -name '*~' -print0 | xargs -0 rm -f
+rm ./clean-svn
index a5d389eb796b1a7eaff3943d37e51848f483196d..4208b52932853fce2ccba97595cf7cace28c2886 100644 (file)
@@ -1,10 +1,14 @@
 set(MGL_HAVE_QT4 1)
 if(enable-json-sample)
+set(MGL_QT4_LIBS Core Gui Network WebKit OpenGL)
 FIND_PACKAGE(Qt4 4.8 REQUIRED QtCore QtGui QtNetwork QtWebKit QtOpenGL)
 else(enable-json-sample)
+set(MGL_QT4_LIBS Core Gui OpenGL)
 FIND_PACKAGE(Qt4 4.8 REQUIRED QtCore QtGui QtOpenGL)
 endif(enable-json-sample)
 if(NOT QT4_FOUND)
        message(SEND_ERROR "Couldn't find Qt4 library.")
 endif(NOT QT4_FOUND)
-include(${QT_USE_FILE})
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
index c4b5bbf2824ee58b71f3acee345c15d13d1da01b..ff447f7cd850e08fe3b413a6c2b560d27f616ad7 100644 (file)
@@ -16,15 +16,22 @@ endif(NOT Qt5Gui_FOUND)
 if(NOT Qt5PrintSupport_FOUND)
        message(SEND_ERROR "Couldn't find Qt5 PrintSupport library.")
 endif(NOT Qt5PrintSupport_FOUND)
+set(MGL_QT5_LIBS Core Gui Widgets PrintSupport OpenGL)
 if(enable-json-sample)
 find_package(Qt5Network REQUIRED)
 find_package(Qt5WebKit REQUIRED)
+find_package(Qt5WebKitWidgets REQUIRED)
 if(NOT Qt5Network_FOUND)
        message(SEND_ERROR "Couldn't find Qt5 Network library.")
 endif(NOT Qt5Network_FOUND)
 if(NOT Qt5WebKit_FOUND)
        message(SEND_ERROR "Couldn't find Qt5 WebKit library.")
 endif(NOT Qt5WebKit_FOUND)
+if(NOT Qt5WebKitWidgets_FOUND)
+       message(SEND_ERROR "Couldn't find Qt5 WebKitWidgets library.")
+endif(NOT Qt5WebKitWidgets_FOUND)
+set(MGL_QT5_LIBS ${MGL_QT5_LIBS} Network WebKit WebKitWidgets)
 endif(enable-json-sample)
 
+set(CMAKE_AUTOMOC ON)
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
index 517162dc12eacbc7c122f6944e9004142ce82bf3..4f713402feb1f1553aca0a3836e401aab45ff8f8 100644 (file)
@@ -23,23 +23,21 @@ if(MGL_HAVE_WX)
 endif(MGL_HAVE_WX)
 
 if(enable-qt)
-       add_executable(mgl_qt_example wnd_samples.cpp qt_example.cpp ${MGL_MOC_EX_FILES})
+       add_executable(mgl_qt_example wnd_samples.cpp qt_example.cpp)
        if(enable-qt5)
                include(../cmake-qt5.txt)
                target_link_libraries(mgl_qt_example mgl-qt5)
-               qt5_wrap_cpp(qgl_moc_src qgl_example.h )
        else(enable-qt5)
                include(../cmake-qt4.txt)
                target_link_libraries(mgl_qt_example mgl-qt4)
-               qt4_wrap_cpp(qgl_moc_src qgl_example.h )
        endif(enable-qt5)
-       add_executable(mgl_qgl_example wnd_samples.cpp qgl_example.cpp ${qgl_moc_src} ${MGL_MOC_EX_FILES})
+       add_executable(mgl_qgl_example wnd_samples.cpp qgl_example.cpp)
        if(enable-qt5)
                target_link_libraries(mgl_qgl_example mgl)
-               qt5_use_modules(mgl_qgl_example Core Widgets Gui OpenGL)
+               qt5_use_modules(mgl_qgl_example ${MGL_QT5_LIBS})
        else(enable-qt5)
                target_link_libraries(mgl_qgl_example mgl)
-               target_link_libraries(mgl_qgl_example ${QT_LIBRARIES})
+               qt4_use_modules(mgl_qgl_example ${MGL_QT4_LIBS})
        endif(enable-qt5)
 
 endif(enable-qt)
index d34f80a416244f398880b3ed2e870c2d842c8df6..154b4eb6bd3dd807c9ed228bf5c423e4241b60bb 100644 (file)
@@ -65,14 +65,9 @@ void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez);
 void save(mglGraph *gr,const char *name,const char *suf);\r
 void test(mglGraph *gr)\r
 {\r
-       gr->Line(mglPoint(-1,-1),mglPoint(1,1));\r
-       gr->Axis();\r
-       gr->WriteEPS("1.eps");\r
-       gr->WriteTEX("1.tex");\r
-       gr->WriteSVG("1.svg");\r
-       return;\r
        mglParse par;\r
-       par.Execute(gr,"load '/home/balakin/mathgl-code/mathgl-2x/build/examples/libmgl_module.so':baxis\n");\r
+       par.Execute(gr,"call 'test' -1\n func 'test' 1\nline $1 0 1 1 'b'\nreturn\n");\r
+//     par.Execute(gr,"load '/home/balakin/mathgl-code/mathgl-2x/build/examples/libmgl_module.so':baxis\n");\r
 //     par.Execute(gr,"subplot 1 1 0:#rotate 40 60\nperspective 1.22:box:axis\n");\r
        return;\r
 }\r
index 483e6b6508959a50bcfed440665e304c79033a78..053824c3a0ecaaf339bfbf3173370d52dcf7c8c3 100644 (file)
 #define MGL_SYS_NAN            0
 #define MGL_HAVE_TYPEOF        0
 #define MGL_HAVE_PTHREAD       0
+#define MGL_HAVE_PTHREAD_FLTK  0
 #define MGL_HAVE_ATTRIBUTE     0
 #define MGL_HAVE_C99_COMPLEX   0
 #else
 #define MGL_HAVE_TYPEOF        ${MGL_HAVE_TYPEOF}
 #define MGL_SYS_NAN            ${MGL_HAVE_NAN_INF}
 #define MGL_HAVE_PTHREAD       ${MGL_HAVE_PTHREAD}
+#define MGL_HAVE_PTHREAD_FLTK  ${MGL_HAVE_PTHR_FLTK}
 #define MGL_HAVE_ATTRIBUTE     ${MGL_HAVE_ATTRIBUTE}
 #define MGL_HAVE_C99_COMPLEX   ${MGL_HAVE_C99_COMPLEX}
 #endif
diff --git a/include/mgl2/Fl_MathGL.h b/include/mgl2/Fl_MathGL.h
new file mode 100644 (file)
index 0000000..6929500
--- /dev/null
@@ -0,0 +1,144 @@
+/***************************************************************************\r
+ * Fl_MathGL.h is part of Math Graphic Library\r
+ * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU Library General Public License as       *\r
+ *   published by the Free Software Foundation; either version 3 of the    *\r
+ *   License, or (at your option) any later version.                       *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU Library General Public     *\r
+ *   License along with this program; if not, write to the                 *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+//-----------------------------------------------------------------------------\r
+#ifndef _MGL_FL_MATHGL_H_\r
+#define _MGL_FL_MATHGL_H_\r
+\r
+#ifdef __MWERKS__\r
+# define FL_DLL\r
+#endif\r
+\r
+#include <FL/Fl.H>\r
+#include <FL/Fl_Window.H>\r
+#include <FL/Fl_Scroll.H>\r
+#include <FL/Fl_Button.H>\r
+#include <FL/Fl_Counter.H>\r
+#include <FL/Fl_Menu_Bar.H>\r
+#include <mgl2/fltk.h>\r
+class mglCanvas;\r
+//-----------------------------------------------------------------------------\r
+/// Class is FLTK widget which display MathGL graphics\r
+class MGL_EXPORT Fl_MathGL : public Fl_Widget\r
+{\r
+public:\r
+       Fl_Valuator     *tet_val;       ///< pointer to external tet-angle validator\r
+       Fl_Valuator     *phi_val;       ///< pointer to external phi-angle validator\r
+       mglCanvas *gr;                  ///< Built-in mglCanvas instance (mglCanvasFLTK is used by default)\r
+\r
+       Fl_MathGL(int x, int y, int w, int h, const char *label=0);\r
+       virtual ~Fl_MathGL();\r
+\r
+       /// Update (redraw) plot\r
+       virtual void update();\r
+       /// Set angles for additional plot rotation\r
+       inline void set_angle(mreal t, mreal p){        tet = t;        phi = p;        }\r
+       /// Set bitwise flags for general state (1-Alpha, 2-Light)\r
+       inline void set_flag(int f)     {       flag = f;       }\r
+       /// Set flags for handling mouse\r
+       void set_graph(HMGL gr);        ///< Set grapher object\r
+       inline void set_graph(mglGraph *Gr)\r
+       {       set_graph(Gr->Self());  }\r
+       /// Get pointer to grapher\r
+       inline HMGL get_graph() {       return (HMGL)gr;        }\r
+       /// Set drawing functions and its parameter\r
+       inline void set_draw(int (*func)(mglBase *gr, void *par), void *par)\r
+       {       if(draw_cl)     delete draw_cl; draw_cl=0;      draw_func=func; draw_par=par;   }\r
+       inline void set_draw(mglDraw *dr)       {       if(draw_cl)     delete draw_cl; draw_cl=dr;     draw_func=0;    }\r
+       inline void set_draw(int (*dr)(mglGraph *gr))\r
+       {       set_draw(dr?mgl_draw_graph:0,(void*)dr);        }\r
+       void set_state(bool z, bool r)  {       zoom = z;       rotate = r;     }\r
+       /// Set zoom in/out region\r
+       inline void set_zoom(mreal X1, mreal Y1, mreal X2, mreal Y2)\r
+       {       x1 = X1;        x2 = X2;        y1 = Y1;        y2 = Y2;        update();       }\r
+       /// Get zoom region\r
+       inline void get_zoom(mreal *X1, mreal *Y1, mreal *X2, mreal *Y2)\r
+       {       *X1 = x1;       *X2 = x2;       *Y1 = y1;       *Y2 = y2;       }\r
+       /// Set popup menu pointer\r
+       inline void set_popup(const Fl_Menu_Item *pmenu, Fl_Widget *wdg, void *v)\r
+       {       popup = pmenu;  wpar = wdg;     vpar = v;       }\r
+       inline void zoom_region(mreal xx1,mreal xx2,mreal yy1, mreal yy2)\r
+       {       x1=xx1; y1=yy1; x2=xx2; y2=yy2; }\r
+       void stop(bool stop=true);\r
+\r
+protected:\r
+       void *draw_par;         ///< Parameters for drawing function mglCanvasWnd::DrawFunc.\r
+       /// Drawing function for window procedure. It should return the number of frames.\r
+       int (*draw_func)(mglBase *gr, void *par);\r
+       mglDraw *draw_cl;\r
+\r
+       const Fl_Menu_Item *popup;      ///< pointer to popup menu items\r
+       Fl_Widget *wpar;                        ///< widget for popup menu\r
+       void *vpar;                                     ///< parameter for popup menu\r
+       mreal tet,phi;                          ///< rotation angles\r
+       bool rotate;                            ///< flag for handle mouse\r
+       bool zoom;                                      ///< flag for zoom by mouse\r
+       bool wire;\r
+       mreal x1,x2,y1,y2;                      ///< zoom region\r
+       int flag;                                       ///< bitwise flag for general state (1-Alpha, 2-Light)\r
+       int x0,y0,xe,ye;                        ///< mouse position\r
+       char pos[128];\r
+\r
+       virtual void draw();            ///< quick drawing function\r
+       int handle(int code);           ///< handle mouse events\r
+       void resize(int x, int y, int w, int h);        ///< resize control\r
+};\r
+//-----------------------------------------------------------------------------\r
+class MGL_EXPORT Fl_MGLView : public Fl_Window\r
+{\r
+public:\r
+       Fl_MathGL *FMGL;                ///< Control which draw graphics\r
+       Fl_Scroll *scroll;\r
+       Fl_Menu_Bar     *menu;\r
+\r
+       void *par;                              ///< Parameter for handling animation\r
+       void (*next)(void*);    ///< Callback function for next frame\r
+       void (*prev)(void*);    ///< Callback function for prev frame\r
+       mreal (*delay)(void*);  ///< Callback function for delay\r
+       void (*reload)(void*);  ///< Callback function for reloading\r
+\r
+       void toggle_alpha()     {       toggle(alpha, alpha_bt, "Graphics/Alpha");      }\r
+       void toggle_light()     {       toggle(light, light_bt, "Graphics/Light");      }\r
+       void toggle_sshow()     {       toggle(sshow, anim_bt, "Graphics/Slideshow");   }\r
+       void toggle_grid()      {       toggle(grid, grid_bt, "Graphics/Grid"); }\r
+       void toggle_zoom()      {       toggle(zoom, zoom_bt);  }\r
+       void toggle_rotate(){   toggle(rotate, rotate_bt);      }\r
+       void setoff_zoom()      {       setoff(zoom, zoom_bt);  }\r
+       void setoff_rotate(){   setoff(rotate, rotate_bt);      }\r
+       bool is_sshow()         {       return sshow;   }\r
+       void adjust()\r
+       {       mgl_set_size(FMGL->get_graph(),scroll->w(),scroll->h());        FMGL->size(scroll->w(),scroll->h());    update();       }\r
+\r
+       Fl_MGLView(int x, int y, int w, int h, const char *label=0);\r
+       virtual ~Fl_MGLView();\r
+       void update();                  ///< Update picture by calling user drawing function\r
+protected:\r
+       Fl_Button *alpha_bt, *light_bt, *rotate_bt, *anim_bt, *zoom_bt, *grid_bt;\r
+//     Fl_Counter *tet, *phi;\r
+\r
+       int grid, alpha, light; ///< Current states of wire, alpha, light switches (toggle buttons)\r
+       int sshow, rotate, zoom;///< Current states of slideshow, rotate, zoom switches (toggle buttons)\r
+\r
+       void toggle(int &val, Fl_Button *b, const char *txt=NULL);\r
+       void setoff(int &val, Fl_Button *b, const char *txt=NULL);\r
+};\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w);\r
+//-----------------------------------------------------------------------------\r
+#endif\r
index d6eb49480f64c3e26134739857b23b3a72dad341..19c222ed26c669759e0d153c8c7bf9891c1fa2f0 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- * thread.h is part of Math Graphic Library
+ * abstract.h is part of Math Graphic Library
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -43,6 +43,8 @@ typedef mglFormula* HMEX;
 typedef mglFormulaC* HAEX;
 typedef const mglDataA* HCDT;
 #ifdef __cplusplus
+std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns);
+std::string MGL_EXPORT mgl_datac_to_string(HCDT d, long ns);
 extern "C" {
 #endif
 /// Set seed for random numbers
@@ -134,6 +136,10 @@ public:
        mglDataA()      {       temp=false;     func=0; o=0;    }
        virtual ~mglDataA()     {       if(func)        func(o);        }
        virtual void set_v(mreal val, long i,long j=0,long k=0) {}
+       /// Get the interpolated value and its derivatives in given data cell without border checking
+       virtual mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const =0;
+       /// Get the interpolated value in given data cell without border checking
+       virtual mreal value(mreal x,mreal y=0,mreal z=0) const =0;
        virtual mreal v(long i,long j=0,long k=0) const = 0;
        virtual mreal vthr(long i) const = 0;
        virtual long GetNx() const = 0;
@@ -151,6 +157,9 @@ public:
        /// Save whole data array (for ns=-1) or only ns-th slice to text file
        virtual void Save(const char *fname,long ns=-1) const
        {       mgl_data_save(this,fname,ns);   }
+       /// Get whole data array (for ns=-1) or only ns-th slice to string
+       virtual std::string Get(long ns=-1)
+       {       return mgl_data_to_string(this,ns);     }
        /// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme
        inline void Export(const char *fname,const char *scheme,mreal v1=0,mreal v2=0,long ns=-1) const
        {       mgl_data_export(this,fname,scheme,v1,v2,ns);    }
index 9526e7fb9c96e808d38be2eeea9821f19ae7e0c6..9aa0c41db65927419325db14a9efb3c4e9569752 100644 (file)
@@ -32,6 +32,9 @@
 #else\r
 #define MGL_PUSH(a,v,m)        a.push_back(v);\r
 #endif\r
+#if MGL_HAVE_OMP\r
+#include <omp.h>\r
+#endif\r
 //-----------------------------------------------------------------------------\r
 inline mreal mgl_d(mreal v,mreal v1,mreal v2) { return v2!=v1?(v-v1)/(v2-v1):NAN; }\r
 //-----------------------------------------------------------------------------\r
@@ -51,12 +54,10 @@ template <class T> class mglStack
        void *mutex;\r
 public:\r
        mglStack(const mglStack<T> &st)\r
-       {\r
-               np=st.np;       dat = (T**)malloc(np*sizeof(T*));\r
+       {       np=st.np;       dat = (T**)malloc(np*sizeof(T*));\r
                pb=st.pb;       m=n=0;  reserve(st.n);\r
                for(size_t i=0;i<m;i++) memcpy(dat[i],st.dat[i],(1L<<pb)*sizeof(T));\r
-               n=st.n;         mutex = 0;\r
-       }\r
+               n=st.n;         mutex = 0;      }\r
        mglStack(size_t Pbuf=10)\r
        {       np=16;  pb=Pbuf;        dat = (T**)malloc(np*sizeof(T*));\r
                dat[0] = new T[1L<<pb]; n=0;    m=1;    mutex = 0;      }\r
@@ -432,6 +433,8 @@ public:
        inline void SetMarkSize(mreal val)      {       MarkSize=0.02*val;      }\r
        /// Set size of arrows\r
        inline void SetArrowSize(mreal val)     {       ArrowSize=0.03*val;     }\r
+       /// Get unscaled arrow size\r
+       inline mreal GetArrowSize() const       {       return ArrowSize/0.03;  }\r
 \r
        /// Set warning code ant fill Message\r
        void SetWarn(int code, const char *who);\r
index efcee953f1370c500ed5819a9d07ff462115ec93..924147ce0bb6c6748da354a13791b552555b2d29 100644 (file)
@@ -32,9 +32,9 @@ struct MGL_EXPORT mglAxis
        mglAxis(mglAxis &&aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns),  t(aa.t),fact(aa.fact),stl(aa.stl),      dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt),    ch(aa.ch),      pos(aa.pos),sh(aa.sh),inv(aa.inv)       {}\r
 #endif\r
        inline void AddLabel(const wchar_t *lbl, mreal v)\r
-       {       txt.push_back(mglText(lbl,"",v));       }\r
+       {       if(mgl_isfin(v))        txt.push_back(mglText(lbl,"",v));       }\r
        inline void AddLabel(const std::wstring &lbl, mreal v)\r
-       {       txt.push_back(mglText(lbl,v));  }\r
+       {       if(mgl_isfin(v))        txt.push_back(mglText(lbl,v));  }\r
        inline void Clear()\r
        {       dv=ds=d=v0=v1=v2=sh=0;  o=NAN;  ns=f=0; pos = 't';      inv=false;\r
                fact.clear();   stl.clear();    t.clear();      txt.clear();    }\r
@@ -198,7 +198,7 @@ using mglBase::Light;
        /// Set object/subplot id\r
        inline void SetObjId(long id)   {       ObjId = id;     }\r
        /// Get object id\r
-       inline int GetObjId(long xs,long ys) const      \r
+       inline int GetObjId(long xs,long ys) const\r
        {       register long i=xs+Width*ys;    return (i>=0 && i<Width*Height)?OI[i]:-1;       }\r
        /// Get subplot id\r
        int GetSplId(long xs,long ys) const MGL_FUNC_PURE;\r
@@ -331,6 +331,8 @@ using mglBase::Light;
        void PreparePrim(int fast);\r
        inline uint32_t GetPntCol(long i) const {       return pnt_col[i];      }\r
        inline uint32_t GetPrmCol(long i, bool sort=true) const {       return GetColor(GetPrm(i, sort));       }\r
+       /// Set the size of semi-transparent area around lines, marks, ...\r
+       inline void SetPenDelta(float d)        {       pen_delta = 1.5*fabs(d);        }\r
 \r
 protected:\r
        mreal Delay;            ///< Delay for animation in seconds\r
@@ -438,9 +440,10 @@ private:
        std::vector<mglMatrix> stack;   ///< stack for transformation matrices\r
        GifFileType *gif;\r
        mreal fscl,ftet;        ///< last scale and rotation for glyphs\r
-       long forg;              ///< original point (for directions)\r
+       long forg;                      ///< original point (for directions)\r
        size_t grp_counter;     ///< Counter for StartGroup(); EndGroup();\r
-       mglMatrix Bt;   ///< temporary matrix for text\r
+       mglMatrix Bt;           ///< temporary matrix for text\r
+       float pen_delta;        ///< delta pen width (dpw) -- the size of semi-transparent region for lines, marks, ...\r
 \r
        /// Draw generic colorbar\r
        void colorbar(HCDT v, const mreal *s, int where, mreal x, mreal y, mreal w, mreal h, bool text);\r
@@ -481,8 +484,6 @@ private:
        void glyph_fpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d);\r
        void glyph_wpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d);\r
        void glyph_lpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, bool solid, const mglDrawReg *d);\r
-\r
-\r
 };\r
 //-----------------------------------------------------------------------------\r
 struct mglThreadG\r
index 4bbd1c86799e908d65664d4542ce5f26c46b4829..a13c46e117df0210f9ef5dcb42398f66e86d756b 100644 (file)
@@ -50,6 +50,10 @@ void MGL_EXPORT mgl_finish_(uintptr_t *gr);
 void MGL_EXPORT mgl_rasterize(HMGL gr);\r
 void MGL_EXPORT mgl_rasterize_(uintptr_t *gr);\r
 \r
+/// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1.\r
+void MGL_EXPORT mgl_pen_delta(HMGL gr, double d);\r
+void MGL_EXPORT mgl_pen_delta_(uintptr_t *gr, double *d);\r
+\r
 /// Set tick length\r
 void MGL_EXPORT mgl_set_tick_len(HMGL gr, double len, double stt);\r
 void MGL_EXPORT mgl_set_tick_len_(uintptr_t *gr, mreal *len, mreal *stt);\r
index cadfba5fdf21a1dc0f990c98b0e246c934bbce39..c98cb558f20a890dd8550912b7e7b7d145c7314b 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * window.h is part of Math Graphic Library\r
+ * canvas_wnd.h is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
index 6ca9f62fbf53138358e8bcdd798f7ee16c58880c..44f99c6bd834dc51496cd7bc638d7929ac336416 100644 (file)
 \r
 #include "mgl2/data_cf.h"\r
 #include "mgl2/pde.h"\r
-#ifdef __cplusplus\r
 //-----------------------------------------------------------------------------\r
 #include <vector>\r
 #include <string>\r
 //-----------------------------------------------------------------------------\r
+mreal MGL_EXPORT mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
+mreal MGL_EXPORT mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0);\r
+mreal MGL_EXPORT mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
+std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns);\r
+//-----------------------------------------------------------------------------\r
 /// Class for working with data array\r
 class MGL_EXPORT mglData : public mglDataA\r
 {\r
@@ -62,6 +66,10 @@ using mglDataA::Momentum;
        mglData(const double *d, int rows, int cols)    {       a=0;    Set(d,cols,rows);       }\r
        mglData(const float *d, int size)       {       a=0;    Set(d,size);    }\r
        mglData(const float *d, int rows, int cols)     {       a=0;    Set(d,cols,rows);       }\r
+       /// Allocate memory and copy data from std::vector<T>\r
+       mglData(const std::vector<int> &d)              {       a=0;    Set(d); }\r
+       mglData(const std::vector<float> &d)    {       a=0;    Set(d); }\r
+       mglData(const std::vector<double> &d)   {       a=0;    Set(d); }\r
        /// Read data from file\r
        mglData(const char *fname)                      {       a=0;    Read(fname);    }\r
        /// Allocate the memory for data array and initialize it zero\r
@@ -123,14 +131,12 @@ using mglDataA::Momentum;
        inline void Set(const mglDataA &dat)    {       mgl_data_set(this, &dat);       }\r
        /// Allocate memory and copy data from std::vector<T>\r
        inline void Set(const std::vector<int> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+       {       if(d.size()>0)  {       Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+               else    Create(1);      }\r
        inline void Set(const std::vector<float> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+       {       if(d.size()>0)  Set(&(a[0]),d.size());  else    Create(1);      }\r
        inline void Set(const std::vector<double> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+       {       if(d.size()>0)  Set(&(a[0]),d.size());  else    Create(1);      }\r
 \r
        /// Create or recreate the array with specified size and fill it by zero\r
        inline void Create(long mx,long my=1,long mz=1)\r
@@ -247,6 +253,9 @@ using mglDataA::Momentum;
        /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
        inline mglData Momentum(char dir, const char *how) const\r
        {       return mglData(true,mgl_data_momentum(this,dir,how));   }\r
+       /// Get pulse properties: pulse maximum and its position, pulse duration near maximum and by half height, energy in first pulse.\r
+       inline mglData Pulse(char dir) const\r
+       {       return mglData(true,mgl_data_pulse(this,dir));  }\r
        /// Get sub-array of the data with given fixed indexes\r
        inline mglData SubData(long xx,long yy=-1,long zz=-1) const\r
        {       return mglData(true,mgl_data_subdata(this,xx,yy,zz));   }\r
@@ -438,6 +447,12 @@ using mglDataA::Momentum;
        /// Set the value in given cell of the data\r
        void set_v(mreal val, long i,long j=0,long k=0) {       mgl_data_set_value(this,val,i,j,k);     }\r
 #endif\r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       return mglSpline3(a,nx,ny,nz,x,y,z,dx,dy,dz);   }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const\r
+       {       return mglSpline3s(a,nx,ny,nz,x,y,z);   }\r
        mreal vthr(long i) const {      return a[i];    }\r
        // add for speeding up !!!\r
        mreal dvx(long i,long j=0,long k=0) const\r
@@ -482,11 +497,6 @@ inline bool operator<(const mglDataA &b, const mglDataA &d)
 inline bool operator>(const mglDataA &b, const mglDataA &d)\r
 {      return b.Minimal()>d.Minimal(); }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
-mreal MGL_EXPORT mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0);\r
-mreal MGL_EXPORT mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
-#endif\r
-//-----------------------------------------------------------------------------\r
 /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase\r
 inline mglData mglTransformA(const mglDataA &am, const mglDataA &ph, const char *tr)\r
 {      return mglData(true,mgl_transform_a(&am,&ph,tr));       }\r
@@ -626,15 +636,15 @@ public:
                di=d.di;        dj=d.dj;        dk=d.dk;        return d;       }\r
        inline mreal operator=(mreal val)\r
        {       di=dj=dk=0;     a0=val; return val;     }\r
-       /// Get the value in given cell of the data without border checking\r
-       mreal value(mreal x,mreal y,mreal z,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
        {       if(dx)  *dx=di; if(dy)  *dy=dj; if(dz)  *dz=dk;\r
                return a0+di*x+dj*y+dk*z;       }\r
-       mreal v(long i,long j=0,long k=0) const\r
-       {       return a0+di*i+dj*j+dk*k;       }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const  {       return a0+di*x+dj*y+dk*z;       }\r
+       mreal v(long i,long j=0,long k=0) const         {       return a0+di*i+dj*j+dk*k;       }\r
        mreal vthr(long ii) const\r
-       {       register long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);\r
-               return a0+di*i+dj*j+dk*k;       }\r
+       {       register long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);      return a0+di*i+dj*j+dk*k;       }\r
        // add for speeding up !!!\r
        mreal dvx(long ,long =0,long =0) const  {       return di;      }\r
        mreal dvy(long ,long =0,long =0) const  {       return dj;      }\r
@@ -685,10 +695,13 @@ public:
        /// Copy data from other mglDataV variable\r
        inline const mglDataW &operator=(const mglDataW &d)\r
        {       nx=d.nx;        ny=d.ny;        nz=d.nz;        di=d.di;        dj=d.dj;        dk=d.dk;        return d;       }\r
-       /// Get the value in given cell of the data without border checking\r
-       mreal value(mreal x,mreal y,mreal z,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
        {       if(dx)  *dx=di; if(dy)  *dy=dj; if(dz)  *dz=dk;\r
                return di*(x<nx/2?x:nx-x)+dj*(y<ny/2?y:ny-y)+dk*(z<nz/2?z:nz-z);        }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const\r
+       {       return di*(x<nx/2?x:nx-x)+dj*(y<ny/2?y:ny-y)+dk*(z<nz/2?z:nz-z);        }\r
        mreal v(long i,long j=0,long k=0) const\r
        {       return di*(i<nx/2?i:nx-i)+dj*(j<ny/2?j:ny-j)+dk*(k<nz/2?k:nz-k);        }\r
        mreal vthr(long ii) const\r
@@ -745,11 +758,12 @@ public:
                if(eq && *eq)   {       ex = mgl_create_expr(eq);       str=eq; }\r
                else    {       ex=0;   str=""; }\r
        }\r
-       /// Set dfunction and coordinates range [r1,r2]\r
+       /// Set function and coordinates range [r1,r2]\r
        inline void SetFunc(mreal (*f)(mreal,mreal,mreal,void*), void *p=NULL)\r
        {       mgl_delete_expr(ex);    ex=0;   dfunc=f;        par=p;  }\r
 \r
-       mreal value(mreal i,mreal j=0,mreal k=0, mreal *di=0,mreal *dj=0,mreal *dk=0) const\r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal i,mreal j=0,mreal k=0, mreal *di=0,mreal *dj=0,mreal *dk=0) const\r
        {\r
                mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
                if(di)  *di = 0;        if(dj)  *dj = 0;        if(dk)  *dk = 0;\r
@@ -769,6 +783,14 @@ public:
                }\r
                return res;\r
        }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal i,mreal j=0,mreal k=0) const\r
+       {\r
+               mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
+               if(dfunc)       res = dfunc(x,y,z, par);\r
+               else if(ex)     res = mgl_expr_eval(ex,x,y,z);\r
+               return res;\r
+       }\r
        /// Copy data from other mglDataV variable\r
        inline const mglDataF &operator=(const mglDataF &d)\r
        {       nx=d.nx;        ny=d.ny;        nz=d.nz;        v1=d.v1;        v2=d.v2;        setD();\r
@@ -840,6 +862,12 @@ public:
        inline void SetInd(long i, wchar_t name)\r
        {       ind = i;        s = name;       }\r
 \r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       if(dz)  *dz=0;  return dat.valueD(ind,x,y,0,dx,dy);     }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const\r
+       {       return dat.value(ind,x,y);      }\r
        /// Get the value in given cell of the data without border checking\r
        mreal v(long i,long j=0,long =0) const\r
        {       return dat.v(ind,i,j);  }\r
@@ -881,6 +909,12 @@ public:
        inline void SetInd(long i, wchar_t name)\r
        {       ind = i;        s = name;       }\r
 \r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       if(dy)  *dy=0;  if(dz)  *dz=0;  return dat.valueD(x,ind,0,dx);  }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const\r
+       {       return dat.value(x,ind,0);      }\r
        /// Get the value in given cell of the data without border checking\r
        mreal v(long i,long =0,long =0) const\r
        {       return dat.v(i,ind,0);  }\r
@@ -913,6 +947,13 @@ public:
        const mglDataS &operator=(const mglDataS &st)   {       dat = st.dat;   return st;      }\r
        const std::vector<mreal> &operator=(const std::vector<mreal> &st)       {       dat = st;       return st;      }\r
 \r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       return mglSpline3(dat.data(),dat.size(),1,1,x,0,0,dx,dy,dz);    }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const\r
+       {       return mglSpline3s(dat.data(),dat.size(),1,1,x,0,0);    }\r
+\r
        mreal v(long i,long j=0,long k=0) const         {       return dat[i];  }\r
        mreal vthr(long i) const        {       return dat[i];  };\r
        long GetNx() const      {       return dat.size();      }\r
index 913017c55a34ed90ed773885708f9fb5e46dbf48..44cbfeb8ff561d158548d4cc0a66f0a9cc8c60bf 100644 (file)
@@ -346,6 +346,9 @@ uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *dat, uintptr_t *weight, int *n,
 /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
 HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how);\r
 uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *dat, char *dir, const char *how, int,int);\r
+/// Get pulse properties: pulse maximum and its position, pulse duration near maximum and by half height.\r
+HMDT MGL_EXPORT mgl_data_pulse(HCDT dat, char dir);\r
+uintptr_t MGL_EXPORT mgl_data_pulse_(uintptr_t *dat, char *dir,int);\r
 /// Get array which values is result of interpolation this for coordinates from other arrays\r
 HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm);\r
 uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *dat, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm);\r
index 70d71d80e7fc499223fadc2ff2d5e822da630451..4cf7dcd8ad43a51f690ebd5ea47c078f766d8ceb 100644 (file)
 \r
 #include "mgl2/data.h"\r
 #include "mgl2/datac_cf.h"\r
-#ifdef __cplusplus\r
 //-----------------------------------------------------------------------------\r
 #include <vector>\r
 #include <string>\r
-#define mgl2   mreal(2)\r
-#define mgl3   mreal(3)\r
-#define mgl4   mreal(4)\r
+//-----------------------------------------------------------------------------\r
+#ifndef SWIG\r
+dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
+dual MGL_EXPORT mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx=0, dual *dy=0, dual *dz=0);\r
+dual MGL_EXPORT mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
 //-----------------------------------------------------------------------------\r
 /// Class for working with complex data array\r
 class MGL_EXPORT mglDataC : public mglDataA\r
@@ -71,6 +72,12 @@ using mglDataA::Momentum;
        mglDataC(const double *d, int rows, int cols)   {       a=0;    Set(d,cols,rows);       }\r
        mglDataC(const float *d, int size)      {       a=0;    Set(d,size);    }\r
        mglDataC(const float *d, int rows, int cols)    {       a=0;    Set(d,cols,rows);       }\r
+       /// Allocate memory and copy data from std::vector<T>\r
+       mglDataC(const std::vector<int> &d)             {       a=0;    Set(d); }\r
+       mglDataC(const std::vector<float> &d)   {       a=0;    Set(d); }\r
+       mglDataC(const std::vector<double> &d)  {       a=0;    Set(d); }\r
+       mglDataC(const std::vector<std::complex<double> > &d)   {       a=0;    Set(d); }\r
+       mglDataC(const std::vector<std::complex<float> > &d)    {       a=0;    Set(d); }\r
        /// Read data from file\r
        mglDataC(const char *fname)                     {       a=0;    Read(fname);    }\r
        /// Allocate the memory for data array and initialize it zero\r
@@ -127,17 +134,18 @@ using mglDataA::Momentum;
        {       mgl_datac_set_ap(this, &ampl, &phase);  }\r
        /// Allocate memory and copy data from std::vector<T>\r
        inline void Set(const std::vector<int> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+       {       if(d.size()>0)  {       Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+               else    Create(1);      }\r
        inline void Set(const std::vector<float> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+       {       if(d.size()>0)  Set(&(a[0]),d.size());  else    Create(1);      }\r
        inline void Set(const std::vector<double> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
-       inline void Set(const std::vector<dual> &d)\r
-       {       if(d.size()<1)  return;\r
-               Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+       {       if(d.size()>0)  Set(&(a[0]),d.size());  else    Create(1);      }\r
+       inline void Set(const std::vector<std::complex<double> > &d)\r
+       {       if(d.size()>0)  {       Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+               else    Create(1);      }\r
+       inline void Set(const std::vector<std::complex<float> > &d)\r
+       {       if(d.size()>0)  {       Create(d.size());       for(long i=0;i<nx;i++)  a[i] = d[i];    }\r
+               else    Create(1);      }\r
 \r
        /// Create or recreate the array with specified size and fill it by zero\r
        inline void Create(long mx,long my=1,long mz=1)\r
@@ -186,7 +194,7 @@ using mglDataA::Momentum;
        /// Equidistantly fill the data to range [x1,x2] in direction dir\r
        inline void Fill(dual x1,dual x2=mglNaN,char dir='x')\r
        {       mgl_datac_fill(this,x1,x2,dir); }\r
-       \r
+\r
                /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2] using global spline\r
        inline void RefillGS(const mglDataA &xdat, const mglDataA &vdat, mreal x1, mreal x2,long sl=-1)\r
        {       mgl_datac_refill_gs(this,&xdat,&vdat,x1,x2,sl); }\r
@@ -230,6 +238,10 @@ using mglDataA::Momentum;
        /// Save whole data array (for ns=-1) or only ns-th slice to text file\r
        void Save(const char *fname,long ns=-1) const\r
        {       mgl_datac_save(this,fname,ns);  }\r
+       /// Get whole data array (for ns=-1) or only ns-th slice to string\r
+       std::string Get(long ns=-1) const\r
+       {       return mgl_datac_to_string(this,ns);    }\r
+\r
        /// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to\r
        inline bool ReadRange(const char *templ, double from, double to, double step=1, bool as_slice=false)\r
        {       return mgl_datac_read_range(this,templ,from,to,step,as_slice);  }\r
@@ -253,9 +265,12 @@ using mglDataA::Momentum;
        /// Get imaginary part of data values\r
        inline mglData Imag() const\r
        {       return mglData(true,mgl_datac_imag(this));      }\r
-       /// Get absolute value of data values\r
+       /// Get absolute value of data values, i.e. |u|\r
        inline mglData Abs() const\r
        {       return mglData(true,mgl_datac_abs(this));       }\r
+       /// Get square of absolute value of data values, i.e. |u|^2\r
+       inline mglData Norm() const\r
+       {       return mglData(true,mgl_datac_norm(this));      }\r
        /// Get argument of data values\r
        inline mglData Arg() const\r
        {       return mglData(true,mgl_datac_arg(this));       }\r
@@ -430,25 +445,29 @@ using mglDataA::Momentum;
        /// Set the value in given cell of the data\r
        void set_v(mreal val, long i,long j=0,long k=0) {       mgl_datac_set_value(this,val,i,j,k);    }\r
 #endif\r
+       /// Get the interpolated value and its derivatives in given data cell without border checking\r
+       mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       dual aa,ax,ay,az;       mreal res;\r
+               aa = mglSpline3C(a,nx,ny,nz,x,y,z,&ax,&ay,&az); res = abs(aa);\r
+               if(dx)  *dx = res?(real(aa)*real(ax)+imag(aa)*imag(ax))/res:0;\r
+               if(dy)  *dy = res?(real(aa)*real(ay)+imag(aa)*imag(ay))/res:0;\r
+               if(dz)  *dz = res?(real(aa)*real(az)+imag(aa)*imag(az))/res:0;  return res;     }\r
+       /// Get the interpolated value in given data cell without border checking\r
+       mreal value(mreal x,mreal y=0,mreal z=0) const\r
+       {       return abs(mglSpline3Cs(a,nx,ny,nz,x,y,z));     }\r
        mreal vthr(long i) const {      return abs(a[i]);       }\r
        // add for speeding up !!!\r
        mreal dvx(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k);\r
-               return i>0? abs(i<nx-1? (a[i0+1]-a[i0-1])/mgl2:a[i0]-a[i0-1]) : abs(a[i0+1]-a[i0]);     }\r
+               return i>0? abs(i<nx-1? (a[i0+1]-a[i0-1])/mreal(2):a[i0]-a[i0-1]) : abs(a[i0+1]-a[i0]); }\r
        mreal dvy(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k);\r
-               return j>0? abs(j<ny-1? (a[i0+nx]-a[i0-nx])/mgl2:a[i0]-a[i0-nx]) : abs(a[i0+nx]-a[i0]);}\r
+               return j>0? abs(j<ny-1? (a[i0+nx]-a[i0-nx])/mreal(2):a[i0]-a[i0-nx]) : abs(a[i0+nx]-a[i0]);}\r
        mreal dvz(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k), n=nx*ny;\r
-               return k>0? abs(k<nz-1? (a[i0+n]-a[i0-n])/mgl2:a[i0]-a[i0-n]) : abs(a[i0+n]-a[i0]);     }\r
+               return k>0? abs(k<nz-1? (a[i0+n]-a[i0-n])/mreal(2):a[i0]-a[i0-n]) : abs(a[i0+n]-a[i0]); }\r
 };\r
 //-----------------------------------------------------------------------------\r
-#ifndef SWIG\r
-dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
-dual MGL_EXPORT mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx=0, dual *dy=0, dual *dz=0);\r
-dual MGL_EXPORT mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
-#endif\r
-//-----------------------------------------------------------------------------\r
 /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini\r
 inline mglDataC mglPDEc(mglBase *gr, const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="")\r
 {      return mglDataC(true, mgl_pde_solve_c(gr,ham, &ini_re, &ini_im, dz, k0,opt));   }\r
index 9f4e21ea4c4e66dfec62a87ccc743ca346ac3571..1383e84e21979777a3a8b1c3d1d5e4a06e34c873 100644 (file)
@@ -291,14 +291,21 @@ uintptr_t MGL_EXPORT mgl_datac_correl_(uintptr_t *dat1, uintptr_t *dat2, const c
 void MGL_EXPORT mgl_datac_diffr(HADT dat, const char *how, mreal q);\r
 void MGL_EXPORT mgl_datac_diffr_(uintptr_t *d, const char *how, double q,int l);\r
 \r
+/// Get real part of data values\r
 HMDT MGL_EXPORT mgl_datac_real(HCDT dat);\r
 uintptr_t MGL_EXPORT mgl_datac_real_(uintptr_t *dat);\r
+/// Get imaginary part of data values\r
 HMDT MGL_EXPORT mgl_datac_imag(HCDT dat);\r
 uintptr_t MGL_EXPORT mgl_datac_imag_(uintptr_t *dat);\r
+/// Get absolute value of data values, i.e. |u|\r
 HMDT MGL_EXPORT mgl_datac_abs(HCDT dat);\r
 uintptr_t MGL_EXPORT mgl_datac_abs_(uintptr_t *dat);\r
+/// Get argument of data values\r
 HMDT MGL_EXPORT mgl_datac_arg(HCDT dat);\r
 uintptr_t MGL_EXPORT mgl_datac_arg_(uintptr_t *dat);\r
+/// Get square of absolute value of data values, i.e. |u|^2\r
+HMDT MGL_EXPORT mgl_datac_norm(HCDT dat);\r
+uintptr_t MGL_EXPORT mgl_datac_norm_(uintptr_t *dat);\r
 \r
 /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
 mdual MGL_EXPORT mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z);\r
index a87d414b771b4e3fd95279736c44964e19f2cdae..edf2837f04cecfd4bde6d196b577da6fc56031dc 100644 (file)
 #endif\r
 #endif\r
 \r
-#if MGL_HAVE_OMP\r
-#include <omp.h>\r
-#endif\r
-\r
 #endif\r
 //-----------------------------------------------------------------------------\r
 #ifdef WIN32 //_MSC_VER needs this before math.h\r
@@ -146,9 +142,11 @@ const unsigned long long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};
 #if MGL_USE_DOUBLE\r
 typedef double mreal;\r
 #define MGL_EPSILON    (1.+1e-10)\r
+#define MGL_MIN_VAL 1e-307\r
 #else\r
 typedef float mreal;\r
 #define MGL_EPSILON    (1.+1e-5)\r
+#define MGL_MIN_VAL 1e-37\r
 #endif\r
 #define MGL_FEPSILON   (1.+1e-5)\r
 //-----------------------------------------------------------------------------\r
@@ -161,6 +159,7 @@ typedef float mreal;
 #endif\r
 //-----------------------------------------------------------------------------\r
 #if MGL_HAVE_TYPEOF\r
+#define mgl_isrange(a,b)       ({typeof (a) _a = (a); typeof (b) _b = (b); fabs(_a-_b)>MGL_MIN_VAL && _a-_a==mreal(0.) && _b-_b==mreal(0.);})\r
 #define mgl_isbad(a)   ({typeof (a) _a = (a); _a-_a!=mreal(0.);})\r
 #define mgl_isfin(a)   ({typeof (a) _a = (a); _a-_a==mreal(0.);})\r
 #define mgl_isnum(a)   ({typeof (a) _a = (a); _a==_a;})\r
@@ -170,6 +169,7 @@ typedef float mreal;
 #define mgl_sign(a)            ({typeof (a) _a = (a); _a<0 ? -1:1;})\r
 #define mgl_int(a)             ({typeof (a) _a = (a); long(_a+(_a>=0 ? 0.5:-0.5));})\r
 #else\r
+#define mgl_isrange(a,b)       (fabs((a)-(b))>MGL_EPSILON && (a)-(a)==mreal(0.) && (b)-(b)==mreal(0.))\r
 #define mgl_min(a,b)   (((a)>(b)) ? (b) : (a))\r
 #define mgl_max(a,b)   (((a)>(b)) ? (a) : (b))\r
 #define mgl_isnan(a)   ((a)!=(a))\r
@@ -208,7 +208,7 @@ enum{       // types of predefined curvelinear coordinate systems
 enum{  // Codes for warnings/messages\r
        mglWarnNone = 0,// Everything OK\r
        mglWarnDim,             // Data dimension(s) is incompatible\r
-       mglWarnLow,             // Data dimension(s) is too small\r
+       mglWarnLow,             // Data dimension(s) is too small\r
        mglWarnNeg,             // Minimal data value is negative\r
        mglWarnFile,    // No file or wrong data dimensions\r
        mglWarnMem,             // Not enough memory\r
index df70be48841066daa3c23e02ee17a00b8dd1a4b0..343059ba815062393d01463aec7e0f9d397be252 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * window.h is part of Math Graphic Library\r
+ * fltk.h is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
@@ -34,6 +34,8 @@ int MGL_EXPORT mgl_fltk_run();
 int MGL_EXPORT mgl_fltk_run_();\r
 /// Run main FLTK loop for event handling in separate thread.\r
 int MGL_EXPORT mgl_fltk_thr();\r
+/// Callback function for asking user.\r
+void MGL_EXPORT mgl_ask_fltk(const wchar_t *quest, wchar_t *res);\r
 #ifdef __cplusplus\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -59,125 +61,5 @@ public:
        int RunThr()    {       return mgl_fltk_thr();  }       ///< Run main loop for event handling in separate thread\r
 };\r
 //-----------------------------------------------------------------------------\r
-#ifdef __MWERKS__\r
-# define FL_DLL\r
-#endif\r
-\r
-#include <FL/Fl.H>\r
-#include <FL/Fl_Window.H>\r
-#include <FL/Fl_Scroll.H>\r
-#include <FL/Fl_Button.H>\r
-#include <FL/Fl_Counter.H>\r
-#include <FL/Fl_Menu_Bar.H>\r
-class mglCanvas;\r
-//-----------------------------------------------------------------------------\r
-/// Class is FLTK widget which display MathGL graphics\r
-class MGL_EXPORT Fl_MathGL : public Fl_Widget\r
-{\r
-public:\r
-       Fl_Valuator     *tet_val;       ///< pointer to external tet-angle validator\r
-       Fl_Valuator     *phi_val;       ///< pointer to external phi-angle validator\r
-\r
-       Fl_MathGL(int x, int y, int w, int h, const char *label=0);\r
-       virtual ~Fl_MathGL();\r
-\r
-       /// Update (redraw) plot\r
-       virtual void update();\r
-       /// Set angles for additional plot rotation\r
-       inline void set_angle(mreal t, mreal p){        tet = t;        phi = p;        }\r
-       /// Set bitwise flags for general state (1-Alpha, 2-Light)\r
-       inline void set_flag(int f)     {       flag = f;       }\r
-       /// Set flags for handling mouse\r
-       void set_graph(HMGL gr);        ///< Set grapher object\r
-       inline void set_graph(mglGraph *Gr)\r
-       {       set_graph(Gr->Self());  }\r
-       /// Get pointer to grapher\r
-       inline HMGL get_graph() {       return (HMGL)gr;        }\r
-       /// Set drawing functions and its parameter\r
-       inline void set_draw(int (*func)(mglBase *gr, void *par), void *par)\r
-       {       if(draw_cl)     delete draw_cl; draw_cl=0;      draw_func=func; draw_par=par;   }\r
-       inline void set_draw(mglDraw *dr)       {       if(draw_cl)     delete draw_cl; draw_cl=dr;     draw_func=0;    }\r
-       inline void set_draw(int (*dr)(mglGraph *gr))\r
-       {       set_draw(dr?mgl_draw_graph:0,(void*)dr);        }\r
-       void set_state(bool z, bool r)  {       zoom = z;       rotate = r;     }\r
-       /// Set zoom in/out region\r
-       inline void set_zoom(mreal X1, mreal Y1, mreal X2, mreal Y2)\r
-       {       x1 = X1;        x2 = X2;        y1 = Y1;        y2 = Y2;        update();       }\r
-       /// Get zoom region\r
-       inline void get_zoom(mreal *X1, mreal *Y1, mreal *X2, mreal *Y2)\r
-       {       *X1 = x1;       *X2 = x2;       *Y1 = y1;       *Y2 = y2;       }\r
-       /// Set popup menu pointer\r
-       inline void set_popup(const Fl_Menu_Item *pmenu, Fl_Widget *wdg, void *v)\r
-       {       popup = pmenu;  wpar = wdg;     vpar = v;       }\r
-       inline void zoom_region(mreal xx1,mreal xx2,mreal yy1, mreal yy2)\r
-       {       x1=xx1; y1=yy1; x2=xx2; y2=yy2; }\r
-       void stop(bool stop=true);\r
-\r
-protected:\r
-       mglCanvas *gr;          ///< pointer to grapher\r
-       void *draw_par;         ///< Parameters for drawing function mglCanvasWnd::DrawFunc.\r
-       /// Drawing function for window procedure. It should return the number of frames.\r
-       int (*draw_func)(mglBase *gr, void *par);\r
-       mglDraw *draw_cl;\r
-\r
-       const Fl_Menu_Item *popup;      ///< pointer to popup menu items\r
-       Fl_Widget *wpar;                        ///< widget for popup menu\r
-       void *vpar;                                     ///< parameter for popup menu\r
-       mreal tet,phi;                          ///< rotation angles\r
-       bool rotate;                            ///< flag for handle mouse\r
-       bool zoom;                                      ///< flag for zoom by mouse\r
-       bool wire;\r
-       mreal x1,x2,y1,y2;                      ///< zoom region\r
-       int flag;                                       ///< bitwise flag for general state (1-Alpha, 2-Light)\r
-       int x0,y0,xe,ye;                        ///< mouse position\r
-       char pos[128];\r
-\r
-       virtual void draw();            ///< quick drawing function\r
-       int handle(int code);           ///< handle mouse events\r
-       void resize(int x, int y, int w, int h);        ///< resize control\r
-};\r
-//-----------------------------------------------------------------------------\r
-class MGL_EXPORT Fl_MGLView : public Fl_Window\r
-{\r
-public:\r
-       Fl_MathGL *FMGL;                ///< Control which draw graphics\r
-       Fl_Scroll *scroll;\r
-       Fl_Menu_Bar     *menu;\r
-\r
-       void *par;                              ///< Parameter for handling animation\r
-       void (*next)(void*);    ///< Callback function for next frame\r
-       void (*prev)(void*);    ///< Callback function for prev frame\r
-       mreal (*delay)(void*);  ///< Callback function for delay\r
-       void (*reload)(void*);  ///< Callback function for reloading\r
-\r
-       void toggle_alpha()     {       toggle(alpha, alpha_bt, "Graphics/Alpha");      }\r
-       void toggle_light()     {       toggle(light, light_bt, "Graphics/Light");      }\r
-       void toggle_sshow()     {       toggle(sshow, anim_bt, "Graphics/Slideshow");   }\r
-       void toggle_grid()      {       toggle(grid, grid_bt, "Graphics/Grid"); }\r
-       void toggle_zoom()      {       toggle(zoom, zoom_bt);  }\r
-       void toggle_rotate(){   toggle(rotate, rotate_bt);      }\r
-       void setoff_zoom()      {       setoff(zoom, zoom_bt);  }\r
-       void setoff_rotate(){   setoff(rotate, rotate_bt);      }\r
-       bool is_sshow()         {       return sshow;   }\r
-       void adjust()\r
-       {       mgl_set_size(FMGL->get_graph(),scroll->w(),scroll->h());        FMGL->size(scroll->w(),scroll->h());    update();       }\r
-\r
-       Fl_MGLView(int x, int y, int w, int h, const char *label=0);\r
-       virtual ~Fl_MGLView();\r
-       void update();                  ///< Update picture by calling user drawing function\r
-protected:\r
-       Fl_Button *alpha_bt, *light_bt, *rotate_bt, *anim_bt, *zoom_bt, *grid_bt;\r
-//     Fl_Counter *tet, *phi;\r
-\r
-       int grid, alpha, light; ///< Current states of wire, alpha, light switches (toggle buttons)\r
-       int sshow, rotate, zoom;///< Current states of slideshow, rotate, zoom switches (toggle buttons)\r
-\r
-       void toggle(int &val, Fl_Button *b, const char *txt=NULL);\r
-       void setoff(int &val, Fl_Button *b, const char *txt=NULL);\r
-};\r
-//-----------------------------------------------------------------------------\r
-void MGL_EXPORT mgl_ask_fltk(const wchar_t *quest, wchar_t *res);\r
-void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w);\r
-//-----------------------------------------------------------------------------\r
 #endif\r
 #endif\r
index 286a3bbd6f324c2b233419739ea766e62061126d..7fdfb54f1ac244b8279f5b3e1d4b81521d2cf50b 100644 (file)
@@ -73,6 +73,8 @@ public:
        inline void SetAlphaDef(double alpha)   {       mgl_set_alpha_default(gr, alpha);       }\r
        /// Set the transparency type (0 - usual, 1 - glass, 2 - lamp)\r
        inline void SetTranspType(int type)             {       mgl_set_transp_type(gr, type);  }\r
+       /// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1.\r
+       inline void SetPenDelta(double d)       {       mgl_pen_delta(gr,d);    }\r
 \r
        /// Set the using of light on/off.\r
        inline void Light(bool enable)                  {       mgl_set_light(gr, enable);      }\r
@@ -114,11 +116,11 @@ public:
        inline void CutOff(const char *EqC)             {       mgl_set_cutoff(gr, EqC);        }\r
 \r
        /// Set default font size\r
-       inline void SetFontSize(double size)            {       mgl_set_font_size(gr, size);    }\r
+       inline void SetFontSize(double size)    {       mgl_set_font_size(gr, size);}\r
        /// Set default font style and color\r
-       inline void SetFontDef(const char *fnt)         {       mgl_set_font_def(gr, fnt);      }\r
+       inline void SetFontDef(const char *fnt) {       mgl_set_font_def(gr, fnt);      }\r
        /// Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72)\r
-       virtual void SetFontSizePT(double pt, int dpi=72){      SetFontSize(pt*27.f/dpi);       }\r
+       virtual void SetFontSizePT(double pt, int dpi=72)       {       SetFontSize(pt*27.f/dpi);       }\r
        /// Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt)\r
        inline void SetFontSizeCM(double cm, int dpi=72)        {       SetFontSizePT(cm*28.45f,dpi);   }\r
        /// Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt)\r
@@ -570,6 +572,20 @@ public:
        inline void Error(mglPoint p, mglPoint e, const char *pen="k")\r
        {       mgl_error_box(gr, p.x, p.y, p.z, e.x, e.y, e.z, pen);   }\r
 \r
+       /// Draws Lamerey diagram for mapping x_new = f(x_old)\r
+       /** String \a stl may contain: â€˜v’ for drawing arrows; â€˜~’ for disable 1st segment.\r
+        *      Option value set the number of iterations (default is 20).*/\r
+       inline void Lamerey(double x0, const mglDataA &f, const char *stl="", const char *opt="")\r
+       {       mgl_lamerey_dat(gr,x0,&f,stl,opt);      }\r
+       inline void Lamerey(double x0, const char *func, const char *stl="", const char *opt="")\r
+       {       mgl_lamerey_str(gr,x0,func,stl,opt);    }\r
+       /// Draws Bifurcation diagram for mapping x_new = f(x_old) in x-axis range\r
+       /** Option value set the number of stationary points (default is 1024).*/\r
+       inline void Bifurcation(double dx, const mglDataA &f, const char *stl="", const char *opt="")\r
+       {       mgl_bifurcation_dat(gr,dx,&f,stl,opt);  }\r
+       inline void Bifurcation(double dx, const char *func, const char *stl="", const char *opt="")\r
+       {       mgl_bifurcation_str(gr,dx,func,stl,opt);        }\r
+\r
        /// Draws the face between points with color stl (include interpolation up to 4 colors).\r
        inline void Face(mglPoint p1, mglPoint p2, mglPoint p3, mglPoint p4, const char *stl="r")\r
        {       mgl_face(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, stl);      }\r
@@ -1029,6 +1045,16 @@ public:
        inline void Mark(const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")\r
        {       mgl_mark_y(gr, &y, &r, pen, opt);       }\r
 \r
+       /// Draw Poincare map at condition r==0 for curve {x,y,z}\r
+       inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *pen, const char *opt="")\r
+       {       mgl_pmap_xyz(gr, &x, &y, &z, &r, pen, opt);     }\r
+       /// Draw Poincare map at condition r==0 for curve {x,y}\r
+       inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")\r
+       {       mgl_pmap_xy(gr, &x, &y, &r, pen, opt);  }\r
+       /// Draw Poincare map at condition r==0 for curve {x,y} with x in x-axis range\r
+       inline void Pmap(const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")\r
+       {       mgl_pmap(gr, &y, &r, pen, opt); }\r
+\r
        /// Draw textual marks with size r at points {x,y,z}\r
        inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *text, const char *fnt="", const char *opt="")\r
        {       mgl_textmark_xyzr(gr, &x, &y, &z, &r, text, fnt, opt);  }\r
index bc1096e3daaec9e40da3f256b21a02c2912d0e2a..a0d0080f5d25cc1cdabf55c8d9ace9edbaffd67f 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * MGL_EXPORT mgl_cf.cpp is part of Math Graphic Library\r
+ * mgl_cf.cpp is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
index aab7a4def7c0fbb3cee890a6fcf29e211f646760..79aacb0796a34f00c56f452943853f361f725762 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * mgl.h is part of Math Graphic Library\r
+ * mpi.h is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
@@ -50,7 +50,7 @@ public:
        inline void MPI_Send(int id)    {       mgl_mpi_send(gr,id);    }\r
        /// Receive graphical information from node id using MPI\r
        inline void MPI_Recv(int id)    {       mgl_mpi_recv(gr,id);    }\r
-       \r
+\r
 };\r
 #endif\r
 //-----------------------------------------------------------------------------\r
index c7568866bbbc30038bacdc394479af6f15e998a0..3bee32d7e77ec10f5ce02d1541068b492038899c 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- * data_cf.h is part of Math Graphic Library
+ * pde.h is part of Math Graphic Library
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
index cd7d708aa266daf10fe1693f809257108e1de550..e1ed4f01cd6c8ac8478826e27f45e8ed85f9180e 100644 (file)
@@ -208,6 +208,16 @@ void MGL_EXPORT mgl_mark_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintp
 void MGL_EXPORT mgl_mark_y(HMGL graph, HCDT y, HCDT r, const char *pen, const char *opt);\r
 void MGL_EXPORT mgl_mark_y_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int);\r
 \r
+/// Draw Poincare map at condition r==0 for curve {x,y,z}\r
+void MGL_EXPORT mgl_pmap_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt);\r
+void MGL_EXPORT mgl_pmap_xyz_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int,int);\r
+/// Draw Poincare map at condition r==0 for curve {x,y}\r
+void MGL_EXPORT mgl_pmap_xy(HMGL graph, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt);\r
+void MGL_EXPORT mgl_pmap_xy_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int);\r
+/// Draw Poincare map at condition r==0 for curve {x,y} with x in x-axis range\r
+void MGL_EXPORT mgl_pmap(HMGL graph, HCDT y, HCDT r, const char *pen, const char *opt);\r
+void MGL_EXPORT mgl_pmap_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int);\r
+\r
 /// Draw tube with variable radius r around curve {x,y,z}\r
 void MGL_EXPORT mgl_tube_xyzr(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt);\r
 void MGL_EXPORT mgl_tube_xyzr_(uintptr_t *graph, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int,int);\r
index 18f7e556c1d21ddbb4bd8443f08614cb0c73a1f1..b27c3c07a2bd764dec985a47f16b26675387ebc2 100644 (file)
@@ -202,7 +202,7 @@ void MGL_EXPORT mgl_label_y_(uintptr_t *graph, uintptr_t *y, const char *text, c
 /// Draw table for values val along given direction with row labels text at position {x,y}\r
 /** String \a fnt may contain:\r
  *      â€˜#’ for drawing cell borders;\r
- *      â€˜|’ for limiting table widh by subplot one (equal to option â€˜value 1’);\r
+ *      â€˜|’ for limiting table width by subplot one (equal to option â€˜value 1’);\r
  *      â€˜=’ for equal width of all cells;\r
  *      â€˜f’ for fixed format of printed numbers;\r
  *      â€˜E’ for using â€˜E’ instead of â€˜e’;\r
@@ -220,6 +220,23 @@ void MGL_EXPORT mgl_logo(HMGL gr, long w, long h, const unsigned char *rgba, int
 void MGL_EXPORT mgl_logo_file(HMGL gr, const char *fname, int smooth, const char *opt);\r
 void MGL_EXPORT mgl_logo_file_(uintptr_t *gr, const char *fname, int *smooth, const char *opt,int l,int n);\r
 \r
+/// Draws Lamerey diagram for mapping x_new = f(x_old)\r
+/** String \a stl may contain: â€˜v’ for drawing arrows; â€˜~’ for disable 1st segment.\r
+ *     Option value set the number of iterations (default is 20).*/\r
+void MGL_EXPORT mgl_lamerey(HMGL gr, double x0, double (*f)(double,void *), void *par, const char *stl, const char *opt);\r
+void MGL_EXPORT mgl_lamerey_dat(HMGL gr, double x0, HCDT f, const char *stl, const char *opt);\r
+void MGL_EXPORT mgl_lamerey_str(HMGL gr, double x0, const char *f, const char *stl, const char *opt);\r
+void MGL_EXPORT mgl_lamerey_dat_(uintptr_t *gr, double *x0, uintptr_t *f, const char *stl, const char *opt, int,int);\r
+void MGL_EXPORT mgl_lamerey_str_(uintptr_t *gr, double *x0, const char *f, const char *stl, const char *opt, int,int,int);\r
+\r
+/// Draws Bifurcation diagram for mapping x_new = f(x_old) in x-axis range\r
+/** Option value set the number of stationary points (default is 1024).*/\r
+void MGL_EXPORT mgl_bifurcation(HMGL gr, double dx, double (*f)(double,double,void *), void *par, const char *stl, const char *opt);\r
+void MGL_EXPORT mgl_bifurcation_dat(HMGL gr, double dx, HCDT f, const char *stl, const char *opt);\r
+void MGL_EXPORT mgl_bifurcation_str(HMGL gr, double dx, const char *f, const char *stl, const char *opt);\r
+void MGL_EXPORT mgl_bifurcation_dat_(uintptr_t *gr, double *dx, uintptr_t *f, const char *stl, const char *opt, int,int);\r
+void MGL_EXPORT mgl_bifurcation_str_(uintptr_t *gr, double *dx, const char *f, const char *stl, const char *opt, int,int,int);\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
index 0e6334cfea0c0fcf45d1a444cde4547897af90ff..504875fde91f128fccfd906ebb615e49e02ec095 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * window.h is part of Math Graphic Library\r
+ * qmathgl.h is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
@@ -44,6 +44,7 @@ public:
        bool enableMouse;       ///< Enable mouse handlers\r
        bool enableWheel;       ///< Enable mouse wheel handlers\r
        QString primitives;     ///< Manual primitives, defined by user\r
+       mglCanvas *gr;          ///< Built-in mglCanvas instance (mglCanvasQT is used by default)\r
 \r
        QMathGL(QWidget *parent = 0, Qt::WindowFlags f = 0);\r
        virtual ~QMathGL();\r
@@ -176,7 +177,6 @@ protected:
        void wheelEvent(QWheelEvent *);\r
        void mouseDoubleClickEvent(QMouseEvent *);\r
 \r
-       mglCanvas *gr;          ///< Built-in mglCanvasQT-er instance (used by default)\r
        void *draw_par;         ///< Parameters for drawing function mglCanvasWnd::DrawFunc.\r
        /// Drawing function for window procedure. It should return the number of frames.\r
        int (*draw_func)(mglBase *gr, void *par);\r
index ab877bdb638281d92b03d2b93bb2728652a8e8ce..58ef70d1768de575886bb5b9990c4d0d381cd42c 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * window.h is part of Math Graphic Library\r
+ * qt.h is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
index 8450f76d1a2f3fefacbba1b1fccddea9f14e106f..d441ec13bd4f87afd8789cfe7ea851f4bedd5c73 100644 (file)
@@ -93,6 +93,8 @@ inline bool operator>(const mglPoint &a, const mglPoint &b)
 {      return a.x>=b.x && a.y>=b.y && a.z>=b.z;        }
 inline mreal mgl_norm(const mglPoint &p)
 {      return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);   }
+inline mreal mgl_anorm(const mglPoint &p)
+{      return fabs(p.x)+fabs(p.y)+fabs(p.z);   }
 #endif
 //-----------------------------------------------------------------------------
 /// Class for RGBA color
index a1aa0c3211ca3a5734532f3fcfa4fdd3748a377b..885e5a85cff507d0d52228cf1aa50b016b6c9941 100644 (file)
@@ -58,7 +58,7 @@ class MGL_EXPORT mglWnd : public mglGraph
        const mglWnd &operator=(const mglWnd &t)        {       return t;       }\r
 public:\r
        mglWnd() : mglGraph(-1) {}\r
-       virtual ~mglWnd() {}\r
+       virtual ~mglWnd() {     mgl_use_graph(gr,-255); }\r
        virtual int Run()=0;            ///< Run main loop for event handling\r
 \r
        inline void ToggleAlpha()       ///< Switch on/off transparency (do not overwrite user settings)\r
index 1c860d7d97c3f03311b7c49729c4a529bcc09a02..5979d6ca14c7ffbc71d3d3a8223fc5ef693c1260 100644 (file)
@@ -7,19 +7,18 @@ include_directories(${MathGL_BINARY_DIR}/json)
 if(enable-qt5)
        include(../cmake-qt5.txt)
        qt5_wrap_ui(json_ui_src MainWindow.ui)
-       qt5_wrap_cpp(json_moc_src ${json_moc_hdr} )
 else(enable-qt5)
        include(../cmake-qt4.txt)
        qt4_wrap_ui(json_ui_src MainWindow.ui)
-       qt4_wrap_cpp(json_moc_src ${json_moc_hdr} )
 endif(enable-qt5)
-add_executable(MglForJsTestBench ${json_src} ${json_moc_src} ${json_ui_src})
+add_executable(MglForJsTestBench ${json_src} ${json_moc_hdr} ${json_ui_src})
 if(enable-qt5)
        target_compile_definitions(MglForJsTestBench PUBLIC MGL_USE_QT5)
        target_link_libraries(MglForJsTestBench mgl-qt5)
-       qt5_use_modules(MglForJsTestBench Core Widgets Gui Network WebKit WebKitWidgets PrintSupport)
+       qt5_use_modules(MglForJsTestBench ${MGL_QT5_LIBS})
 else(enable-qt5)
-       target_link_libraries(MglForJsTestBench mgl-qt ${QT_LIBRARIES})
+       target_link_libraries(MglForJsTestBench mgl-qt)
+       qt4_use_modules(MglForJsTestBench ${MGL_QT4_LIBS})
 endif(enable-qt5)
 
 endif(enable-json-sample)
diff --git a/mgltex/Recompilation_decision.eps b/mgltex/Recompilation_decision.eps
new file mode 100644 (file)
index 0000000..b087058
--- /dev/null
@@ -0,0 +1,1851 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: cairo 1.13.1 (http://cairographics.org)
+%%CreationDate: Sat Nov  7 08:28:35 2015
+%%Pages: 1
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 3
+%%BoundingBox: 0 -1 631 791
+%%EndComments
+%%BeginProlog
+save
+50 dict begin
+/q { gsave } bind def
+/Q { grestore } bind def
+/cm { 6 array astore concat } bind def
+/w { setlinewidth } bind def
+/J { setlinecap } bind def
+/j { setlinejoin } bind def
+/M { setmiterlimit } bind def
+/d { setdash } bind def
+/m { moveto } bind def
+/l { lineto } bind def
+/c { curveto } bind def
+/h { closepath } bind def
+/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
+      0 exch rlineto 0 rlineto closepath } bind def
+/S { stroke } bind def
+/f { fill } bind def
+/f* { eofill } bind def
+/n { newpath } bind def
+/W { clip } bind def
+/W* { eoclip } bind def
+/BT { } bind def
+/ET { } bind def
+/pdfmark where { pop globaldict /?pdfmark /exec load put }
+    { globaldict begin /?pdfmark /pop load def /pdfmark
+    /cleartomark load def end } ifelse
+/BDC { mark 3 1 roll /BDC pdfmark } bind def
+/EMC { mark /EMC pdfmark } bind def
+/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
+/Tj { show currentpoint cairo_store_point } bind def
+/TJ {
+  {
+    dup
+    type /stringtype eq
+    { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
+  } forall
+  currentpoint cairo_store_point
+} bind def
+/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
+    cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
+/Tf { pop /cairo_font exch def /cairo_font_matrix where
+      { pop cairo_selectfont } if } bind def
+/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
+      /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
+      /cairo_font where { pop cairo_selectfont } if } bind def
+/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
+      cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
+/g { setgray } bind def
+/rg { setrgbcolor } bind def
+/d1 { setcachedevice } bind def
+%%EndProlog
+%%BeginSetup
+%%BeginResource: font DejaVuSans
+11 dict begin
+/FontType 42 def
+/FontName /DejaVuSans def
+/PaintType 0 def
+/FontMatrix [ 1 0 0 1 0 0 ] def
+/FontBBox [ 0 0 0 0 ] def
+/Encoding 256 array def
+0 1 255 { Encoding exch /.notdef put } for
+Encoding 32 /space put
+Encoding 46 /period put
+Encoding 47 /slash put
+Encoding 60 /less put
+Encoding 62 /greater put
+Encoding 63 /question put
+Encoding 64 /at put
+Encoding 65 /A put
+Encoding 67 /C put
+Encoding 68 /D put
+Encoding 69 /E put
+Encoding 70 /F put
+Encoding 71 /G put
+Encoding 73 /I put
+Encoding 76 /L put
+Encoding 77 /M put
+Encoding 78 /N put
+Encoding 82 /R put
+Encoding 83 /S put
+Encoding 85 /U put
+Encoding 89 /Y put
+Encoding 92 /backslash put
+Encoding 97 /a put
+Encoding 99 /c put
+Encoding 100 /d put
+Encoding 101 /e put
+Encoding 104 /h put
+Encoding 105 /i put
+Encoding 108 /l put
+Encoding 109 /m put
+Encoding 110 /n put
+Encoding 111 /o put
+Encoding 112 /p put
+Encoding 113 /q put
+Encoding 114 /r put
+Encoding 115 /s put
+Encoding 116 /t put
+Encoding 117 /u put
+Encoding 118 /v put
+Encoding 119 /w put
+Encoding 121 /y put
+/CharStrings 42 dict dup begin
+/.notdef 0 def
+/S 1 def
+/t 2 def
+/a 3 def
+/r 4 def
+/F 5 def
+/i 6 def
+/n 7 def
+/d 8 def
+/backslash 9 def
+/M 10 def
+/G 11 def
+/L 12 def
+/at 13 def
+/less 14 def
+/s 15 def
+/c 16 def
+/p 17 def
+/greater 18 def
+/I 19 def
+/space 20 def
+/e 21 def
+/question 22 def
+/C 23 def
+/o 24 def
+/m 25 def
+/v 26 def
+/period 27 def
+/R 28 def
+/w 29 def
+/slash 30 def
+/l 31 def
+/U 32 def
+/D 33 def
+/E 34 def
+/A 35 def
+/h 36 def
+/y 37 def
+/q 38 def
+/u 39 def
+/Y 40 def
+/N 41 def
+end readonly def
+/sfnts [
+<0001000000090080000300106376742000691d3900001d14000001fe6670676d7134766a0000
+1f14000000ab676c796600c0787b0000009c00001c7868656164026638f700001fc000000036
+686865610cb8067b00001ff800000024686d7478cb7f16780000201c000000a86c6f63610002
+4608000020c4000000ac6d617870049706710000217000000020707265703b07f10000002190
+0000056800020066fe96046605a400030007001a400c04fb0006fb0108057f0204002fc4d4ec
+310010d4ecd4ec301311211125211121660400fc73031bfce5fe96070ef8f272062900010087
+ffe304a205f00027007e403c0d0c020e0b021e1f1e080902070a021f1f1e420a0b1e1f041501
+0015a11494189511049500942591118c281e0a0b1f1b0700221b190e2d071914222810dcc4ec
+fcece4111239393939310010e4f4e4ec10eef6ee10c6111739304b535807100eed1117390710
+0eed1117395922b20f2901015db61f292f294f29035d01152e012322061514161f011e011514
+0421222627351e013332363534262f012e01353424333216044873cc5fa5b377a67ae2d7fedd
+fee76aef807bec72adbc879a7be2ca0117f569da05a4c53736807663651f192bd9b6d9e0302f
+d04546887e6e7c1f182dc0abc6e4260000010037000002f2059e0013003840190e05080f03a9
+001101bc08870a0b08090204000810120e461410fc3cc4fc3cc432393931002fecf43cc4ec32
+11393930b2af1501015d01112115211114163b01152322263511233533110177017bfe854b73
+bdbdd5a28787059efec28ffda0894e9a9fd202608f013e0000000002007bffe3042d047b000a
+002500bc4027191f0b17090e00a91706b90e1120861fba1cb923b8118c170c001703180d0908
+0b1f030814452610fcecccd4ec323211393931002fc4e4f4fcf4ec10c6ee10ee113911391239
+30406e301d301e301f3020302130223f27401d401e401f402040214022501d501e501f502050
+21502250277027851d871e871f8720872185229027a027f0271e301e301f30203021401e401f
+40204021501e501f50205021601e601f60206021701e701f70207021801e801f80208021185d
+015d0122061514163332363d01371123350e01232226353436332135342623220607353e0133
+321602bedfac816f99b9b8b83fbc88accbfdfb0102a79760b65465be5af3f00233667b6273d9
+b4294cfd81aa6661c1a2bdc0127f8b2e2eaa2727fc00000100ba0000034a047b001100304014
+060b0700110b03870eb809bc070a06080008461210fcc4ec3231002fe4f4ecc4d4cc11123930
+b450139f1302015d012e012322061511231133153e0133321617034a1f492c9ca7b9b93aba85
+132e1c03b41211cbbefdb20460ae666305050000000100c90000042305d50009002940120695
+040295008104ad08050107031c00040a10fcec32d4c431002fecf4ec10ee30b20f0b01015d13
+211521112115211123c9035afd700250fdb0ca05d5aafe48aafd3700000200c1000001790614
+00030007002b400e06be04b100bc020501080400460810fc3cec3231002fe4fcec30400b1009
+400950096009700905015d1333112311331523c1b8b8b8b80460fba00614e900000100ba0000
+0464047b001300364019030900030e0106870e11b80cbc0a010208004e0d09080b461410fcec
+32f4ec31002f3ce4f4c4ec1112173930b46015cf1502015d0111231134262322061511231133
+153e013332160464b87c7c95acb9b942b375c1c602a4fd5c029e9f9ebea4fd870460ae6564ef
+00020071ffe3045a06140010001c003840191ab9000e14b905088c0eb8019703170400080247
+11120b451d10fcecf4ec323231002fece4f4c4ec10c4ee30b6601e801ea01e03015d01113311
+23350e0123220211100033321601141633323635342623220603a2b8b83ab17ccbff00ffcb7c
+b1fdc7a79292a8a89292a703b6025ef9eca86461014401080108014461fe15cbe7e7cbcbe7e7
+00010000ff4202b205d50003002d4014021a010100001a03030242019f008104020001032fc4
+3939310010f4ec304b5358071005ed071005ed592213012301aa0208aafdf805d5f96d069300
+000100c90000061f05d5000c00bf403403110708070211010208080702110302090a0901110a
+0a09420a070203080300af080b050908030201050a061c043e0a1c00040d10fcecfcec111739
+31002f3cc4ec32111739304b5358071005ed071008ed071008ed071005ed5922b2700e01015d
+405603070f080f09020a15021407130a260226072007260a200a3407350a69027c027b07790a
+80028207820a90021604010b0313011b0323012c032708280934013c035608590965086a0976
+08790981018d0395019b03145d005d13210901211123110123011123c9012d017d017f012dc5
+fe7fcbfe7fc405d5fc0803f8fa2b051ffc000400fae1000000010073ffe3058b05f0001d0039
+402000051b0195031b950812a111ae15950e91088c1e02001c1134043318190b101e10fcecfc
+e4fcc4310010e4f4ecf4ec10fed4ee1139393025112135211106042320001110002132041715
+2e0123200011100021323604c3feb6021275fee6a0fea2fe75018b015e9201076f70fc8bfeee
+feed011301126ba8d50191a6fd7f53550199016d016e01994846d75f60fecefed1fed2fece25
+0000000100c90000046a05d500050025400c0295008104011c033a00040610fcecec31002fe4
+ec304009300750078003800404015d133311211521c9ca02d7fc5f05d5fad5aa00020087fe9c
+077105a2000b004c00954032180c0309a919151b03a94c0f34330fac30a93715ac24a937434d
+33341e1a00281206180c281a2b1e2849122b2a28492c3d4d10dcecfcec10fefdfe3cc610ee11
+123939310010d4c4fcec10feedd4c610c5ee3210c4ee11393930004bb009544bb00c545b4bb0
+10545b4bb013545b4bb014545b58bd004dffc00001004d004d0040381137385940090f4e1f4e
+2f4e3f4e04015d011416333236353426232206010e01232226353436333216173533113e0135
+3426272624232206070602151412171604333236371706042322242726023534123736243332
+04171e011510000502fa8e7c7b8d907a798f02213c9b67acd7d8ab679c3b8f92a53f4068fed5
+b07be2609db1736d6901149d81f9685a7dfed998b9feb8808086887e810152bdd4016b7b4b4f
+fec2fee802198fa3a48e8ca5a4fe484d49f9c8c8fa4b4c83fd2016dfb16bbc50838b414066fe
+b5c19ffeea6a686d57516f6167837d7d0149bdb6014a7d7f87aea062e67bfef9fed006000001
+00d9005e05db04a60006004d402a029c030403019c0001040403019c0201050605009c060542
+05040201000503a806a7070102002404230710fcec3239310010f4ec1739304b53580704ed07
+1008ed071008ed071004ed592209021501350105dbfbf80408fafe050203f0fe91fe93b601d1
+a601d1000001006fffe303c7047b002700e7403c0d0c020e0b531f1e080902070a531f1f1e42
+0a0b1e1f041500860189041486158918b91104b925b8118c281e0a0b1f1b0700521b080e0708
+1422452810fcc4ecd4ece4111239393939310010e4f4ec10fef5ee10f5ee121739304b535807
+100eed111739070eed1117395922b2002701015d406d1c0a1c0b1c0c2e092c0a2c0b2c0c3b09
+3b0a3b0b3b0c0b200020012402280a280b2a132f142f152a16281e281f292029212427860a86
+0b860c860d12000000010202060a060b030c030d030e030f03100319031a031b031c041d0927
+2f293f295f297f2980299029a029f029185d005d7101152e012322061514161f011e01151406
+23222627351e013332363534262f012e01353436333216038b4ea85a898962943fc4a5f7d85a
+c36c66c661828c65ab40ab98e0ce66b4043fae282854544049210e2a99899cb62323be353559
+514b50250f2495829eac1e00000000010071ffe303e7047b0019003f401b00860188040e860d
+880ab91104b917b8118c1a07120d004814451a10fce432ec310010e4f4ec10fef4ee10f5ee30
+400b0f1b101b801b901ba01b05015d01152e0123220615141633323637150e01232200111000
+21321603e74e9d50b3c6c6b3509d4e4da55dfdfed6012d010655a20435ac2b2be3cdcde32b2b
+aa2424013e010e0112013a230000000200bafe5604a4047b0010001c003e401b1ab9000e14b9
+0508b80e8c01bd03bc1d11120b471704000802461d10fcec3232f4ec310010e4e4e4f4c4ec10
+c4ee304009601e801ea01ee01e04015d2511231133153e013332001110022322260134262322
+061514163332360173b9b93ab17bcc00ffffcc7bb10238a79292a7a79292a7a8fdae060aaa64
+61febcfef8fef8febc6101ebcbe7e7cbcbe7e7000000000100d9005e05db04a60006004f402b
+069c0006030403059c040403009c010201069c05060202014206050302000504a801a7070602
+240400230710fc3cec39310010f4ec1739304b5358071008ed071004ed071004ed071008ed59
+2213350115013501d90502fafe040603f0b6fe2fa6fe2fb6016d0000000100c90000019305d5
+0003002eb700af02011c00040410fc4bb0105458b9000000403859ec31002fec3001400d3005
+4005500560058f059f05065d13331123c9caca05d5fa2b0000020071ffe3047f047b0014001b
+00704024001501098608880515a90105b90c01bb18b912b80c8c1c1b1502081508004b02120f
+451c10fcecf4ecc4111239310010e4f4ece410ee10ee10f4ee1112393040293f1d701da01dd0
+1df01d053f003f013f023f153f1b052c072f082f092c0a6f006f016f026f156f1b095d71015d
+0115211e0133323637150e01232000111000333200072e0123220607047ffcb20ccdb76ac762
+63d06bfef4fec70129fce20107b802a5889ab90e025e5abec73434ae2a2c0138010a01130143
+feddc497b4ae9e0000020093000003b005f0000300240065402b241e0906040a1d1304001486
+1388109517910083021d1a0d0905040a1e010d1c1a041c05010300261a132510dc4bb00c5458
+b90013ffc03859c4fcecd4ec10ee11393911123911123931002feef6fef4ee10cd1139391739
+3001b679097a0a7a20035d2533152313233534363f013e0135342623220607353e0133321615
+14060f010e01070e01150187cbcbc5bf385a5a3933836c4fb3615ec167b8df485a582f270806
+06fefe01919a65825659355e31596e4643bc3938c29f4c8956562f3519153c34000000010073
+ffe3052705f000190036401a0da10eae0a951101a100ae04951791118c1a07190d003014101a
+10fcec32ec310010e4f4ecf4ec10eef6ee30b40f1b1f1b02015d01152e012320001110002132
+3637150e01232000111000213216052766e782ff00fef00110010082e7666aed84feadfe7a01
+86015386ed0562d55f5efec7fed8fed9fec75e5fd34848019f01670168019f47000000020071
+ffe30475047b000b0017004a401306b91200b90cb8128c1809120f51031215451810fcecf4ec
+310010e4f4ec10ee3040233f197b007b067f077f087f097f0a7f0b7b0c7f0d7f0e7f0f7f107f
+117b12a019f01911015d012206151416333236353426273200111000232200111000027394ac
+ab9593acac93f00112feeef0f1feef011103dfe7c9c9e7e8c8c7e99cfec8feecfeedfec70139
+0113011401380000000100ba0000071d047b0022005a4026061209180f00061d07150c871d20
+03b81bbc19100700110f0808065011080f501c18081a462310fcec32fcfcfcec11123931002f
+3c3ce4f43cc4ec32111217393040133024502470249024a024a024bf24df24ff2409015d013e
+013332161511231134262322061511231134262322061511231133153e01333216042945c082
+afbeb972758fa6b972778da6b9b93fb0797aab03897c76f5e2fd5c029ea19cbea4fd87029ea2
+9bbfa3fd870460ae67627c0000000001003d0000047f0460000600fb40270311040504021101
+0205050402110302060006011100000642020300bf0506050302010504000710d44bb00a5458
+b90000004038594bb014544bb015545b58b90000ffc03859c4173931002fec3239304b535807
+1005ed071008ed071008ed071005ed592201408e48026a027b027f02860280029102a4020806
+00060109030904150015011a031a0426002601290329042008350035013a033a043008460046
+0149034904460548064008560056015903590450086600660169036904670568066008750074
+017b037b0475057a068500850189038904890586069600960197029a03980498059706a805a7
+06b008c008df08ff083e5d005d133309013301233dc3015e015ec3fe5cfa0460fc5403acfba0
+0000000100db000001ae00fe00030011b7008302011900180410fcec31002fec3037331523db
+d3d3fefe000200c90000055405d50013001c00b14035090807030a0611030403051104040342
+06040015030415950914950d810b040506031109001c160e050a191904113f140a1c0c041d10
+fcec32fcc4ec1117391139393931002f3cf4ecd4ec123912391239304b5358071005ed071005
+ed1117395922b2401e01015d40427a1301050005010502060307041500150114021603170425
+002501250226032706260726082609201e360136024601460268057504750577138806880798
+0698071f5d005d011e01171323032e012b01112311212016151406011133323635342623038d
+417b3ecdd9bf4a8b78dcca01c80100fc83fd89fe9295959202bc16907efe68017f9662fd8905
+d5d6d88dba024ffdee878383850000010056000006350460000c01eb404905550605090a0904
+550a0903550a0b0a025501020b0b0a061107080705110405080807021103020c000c01110000
+0c420a050203060300bf0b080c0b0a09080605040302010b07000d10d44bb00a544bb011545b
+4bb012545b4bb013545b4bb00b545b58b9000000403859014bb00c544bb00d545b4bb010545b
+58b90000ffc03859cc173931002f3cec32321739304b5358071005ed071008ed071008ed0710
+05ed071008ed071005ed0705ed071008ed59220140ff050216021605220a350a49024905460a
+400a5b025b05550a500a6e026e05660a79027f0279057f05870299029805940abc02bc05ce02
+c703cf051d0502090306040b050a080b09040b050c1502190316041a051b081b09140b150c25
+00250123022703210425052206220725082709240a210b230c390336043608390c300e460248
+034604400442054006400740084409440a440b400e400e560056015602500451055206520750
+085309540a550b6300640165026a0365046a056a066a076e09610b670c6f0e7500750179027d
+0378047d057a067f067a077f07780879097f097b0a760b7d0c870288058f0e97009701940293
+039c049b05980698079908402f960c9f0ea600a601a402a403ab04ab05a906a907ab08a40caf
+0eb502b103bd04bb05b809bf0ec402c303cc04ca05795d005d13331b01331b013301230b0123
+56b8e6e5d9e6e5b8fedbd9f1f2d90460fc96036afc96036afba00396fc6a00010000ff4202b2
+05d50003002d4014001a010201021a03000342029f008104020001032fc43939310010f4ec30
+4b5358071005ed071005ed5922013301230208aafdf8aa05d5f96d000000000100c100000179
+061400030022b7009702010800460410fcec31002fec30400d10054005500560057005f00506
+015d13331123c1b8b80614f9ec00000100b2ffe3052905d50011004040160802110b0005950e
+8c09008112081c0a38011c00411210fc4bb0105458b90000ffc03859ecfcec310010e432f4ec
+11393939393001b61f138f139f13035d133311141633323635113311100021200011b2cbaec3
+c2aecbfedffee6fee5fedf05d5fc75f0d3d3f0038bfc5cfedcfed6012a012400000200c90000
+05b005d500080011002e4015009509810195100802100a0005190d32001c09041210fcecf4ec
+113939393931002fecf4ec30b2601301015d0111332000111000212521200011100029010193
+f40135011ffee1fecbfe42019f01b20196fe68fe50fe61052ffb770118012e012c0117a6fe97
+fe80fe7efe960000000100c90000048b05d5000b002e401506950402950081089504ad0a0501
+0907031c00040c10fcec32d4c4c431002fececf4ec10ee30b21f0d01015d1321152111211521
+11211521c903b0fd1a02c7fd3902f8fc3e05d5aafe46aafde3aa0000000200100000056805d5
+0002000a00c2404100110100040504021105050401110a030a0011020003030a071105040611
+0505040911030a08110a030a4200030795010381090509080706040302010009050a0b10d4c4
+173931002f3ce4d4ec1239304b5358071005ed0705ed071005ed0705ed071008ed071005ed07
+1005ed071008ed5922b2200c01015d40420f010f020f070f080f005800760070008c00090701
+0802060309041601190256015802500c67016802780176027c0372047707780887018802800c
+980299039604175d005d090121013301230321032302bcfeee0225fe7be50239d288fd5f88d5
+050efd1903aefa2b017ffe810000000100ba000004640614001300344019030900030e010687
+0e11b80c970a010208004e0d09080b461410fcec32f4ec31002f3cecf4c4ec1112173930b260
+1501015d0111231134262322061511231133113e013332160464b87c7c95acb9b942b375c1c6
+02a4fd5c029e9f9ebea4fd870614fd9e6564ef000001003dfe56047f0460000f018b40430708
+020911000f0a110b0a00000f0e110f000f0d110c0d00000f0d110e0d0a0b0a0c110b0b0a420d
+0b0910000b058703bd0e0bbc100e0d0c0a09060300080f040f0b1010d44bb00a544bb008545b
+58b9000b004038594bb0145458b9000bffc03859c4c4111739310010e432f4ec113911391239
+304b5358071005ed071008ed071008ed071005ed071008ed0705ed173259220140f006000508
+0609030d160a170d100d230d350d490a4f0a4e0d5a095a0a6a0a870d800d930d120a000a0906
+0b050c0b0e0b0f1701150210041005170a140b140c1a0e1a0f27002401240220042005290828
+09250a240b240c270d2a0e2a0f201137003501350230043005380a360b360c380d390e390f30
+114100400140024003400440054006400740084209450a470d490e490f401154005101510255
+03500450055606550756085709570a550b550c590e590f501166016602680a690e690f60117b
+08780e780f89008a09850b850c890d890e890f9909950b950c9a0e9a0fa40ba40cab0eab0fb0
+11cf11df11ff11655d005d050e012b01353332363f01013309013302934e947c936c4c543321
+fe3bc3015e015ec368c87a9a488654044efc94036c00000000020071fe56045a047b000b001c
+003e401b03b90c0f09b91815b80f8c1bbd19bc1d180c06081a47001212451d10fcecf4ec3232
+310010e4e4e4f4c4ec10c6ee304009601e801ea01ee01e04015d011416333236353426232206
+010e012322021110003332161735331123012fa79292a8a89292a702733ab17ccbff00ffcb7c
+b13ab8b8022fcbe7e7cbcbe7e7fdae646101440108010801446164aaf9f60000000200aeffe3
+0458047b00130014003b401c030900030e0106870e118c0a01bc14b80c0d0908140b4e020800
+461510fcecf439ec3231002fe4e432f4c4ec1112173930b46f15c01502015d13113311141633
+32363511331123350e0123222601aeb87c7c95adb8b843b175c1c801cf01ba02a6fd619f9fbe
+a4027bfba0ac6663f003a8000001fffc000004e705d500080094402803110405040211010205
+050402110302080008011100000842020300af0602070440051c0040070910d4e4fce4123931
+002fec3239304b5358071005ed071008ed071008ed071005ed5922b2000a01015d403c050214
+02350230023005300846024002400540085102510551086502840293021016011a031f0a2601
+290337013803400a670168037803700a9f0a0d5d005d03330901330111231104d9019e019bd9
+fdf0cb05d5fd9a0266fcf2fd3902c7000000000100c90000053305d500090079401e07110102
+0102110607064207020300af0805060107021c0436071c00040a10fcecfcec11393931002f3c
+ec323939304b5358071004ed071004ed5922b21f0b01015d4030360238074802470769026607
+8002070601090615011a06460149065701580665016906790685018a0695019a069f0b105d00
+5d13210111331121011123c901100296c4fef0fd6ac405d5fb1f04e1fa2b04e1fb1f013500b8
+00cb00cb00c100aa009c01a600b800660000007100cb00a002b20085007500b800c301cb0189
+022d00cb00a600f000d300aa008700cb03aa0400014a003300cb000000d9050200f4015400b4
+009c01390114013907060400044e04b4045204b804e704cd0037047304cd04600473013303a2
+055605a60556053903c5021200c9001f00b801df007300ba03e9033303bc0444040e00df03cd
+03aa00e503aa0404000000cb008f00a4007b00b80014016f007f027b0252008f00c705cd009a
+009a006f00cb00cd019e01d300f000ba018300d5009803040248009e01d500c100cb00f60083
+0354027f00000333026600d300c700a400cd008f009a0073040005d5010a00fe022b00a400b4
+009c00000062009c0000001d032d05d505d505d505f0007f007b005400a406b80614072301d3
+00b800cb00a601c301ec069300a000d3035c037103db0185042304a80448008f013901140139
+0360008f05d5019a0614072306660179046004600460047b009c00000277046001aa00e90460
+0762007b00c5007f027b000000b4025205cd006600bc00660077061000cd013b01850389008f
+007b0000001d00cd074a042f009c009c0000077d006f0000006f0335006a006f007b00ae00b2
+002d0396008f027b00f600830354063705f6008f009c04e10266008f018d02f600cd03440029
+006604ee00730000140000960000b707060504030201002c2010b002254964b040515820c859
+212d2cb002254964b040515820c859212d2c20100720b00050b00d7920b8ffff5058041b0559
+b0051cb0032508b0042523e120b00050b00d7920b8ffff5058041b0559b0051cb0032508e12d
+2c4b505820b0fd454459212d2cb002254560442d2c4b5358b00225b0022545445921212d2c45
+442d2cb00225b0022549b00525b005254960b0206368208a108a233a8a10653a2d0000010000
+0002570ae39778045f0f3cf5001f080000000000cef5cb7600000000cef5cb76f7d6fcae0d72
+095500000008000000010000000000010000076dfe1d00000de2f7d6fa510d72000100000000
+00000000000000000000002a04cd0066051400870323003704e7007b034a00ba049a00c90239
+00c1051200ba0514007102b2000006e700c906330073047500c90800008706b400d9042b006f
+04660071051400ba06b400d9025c00c9028b000004ec0071043f00930596007304e5007107cb
+00ba04bc003d028b00db058f00c9068b005602b20000023900c105db00b2062900c9050e00c9
+05790010051200ba04bc003d05140071051200ae04e3fffc05fc00c900000000000000440000
+013c000001b8000002e400000354000003a8000003f800000470000005080000055400000650
+000006f80000073c000008bc0000093400000a9400000b2c00000bcc00000c4400000c8c0000
+0c8c00000d6000000e3800000ed000000f74000010380000115c0000118400001298000014bc
+0000150800001544000015c800001648000016a8000017a40000181c000019e800001a880000
+1b0c00001bd000001c7800010000002a0354002b0068000c0002001000990008000004150216
+00080004b8028040fffbfe03fa1403f92503f83203f79603f60e03f5fe03f4fe03f32503f20e
+03f19603f02503ef8a4105effe03ee9603ed9603ecfa03ebfa03eafe03e93a03e84203e7fe03
+e63203e5e45305e59603e48a4105e45303e3e22f05e3fa03e22f03e1fe03e0fe03df3203de14
+03dd9603dcfe03db1203da7d03d9bb03d8fe03d68a4105d67d03d5d44705d57d03d44703d3d2
+1b05d3fe03d21b03d1fe03d0fe03cffe03cefe03cd9603cccb1e05ccfe03cb1e03ca3203c9fe
+03c6851105c61c03c51603c4fe03c3fe03c2fe03c1fe03c0fe03bffe03befe03bdfe03bcfe03
+bbfe03ba1103b9862505b9fe03b8b7bb05b8fe03b7b65d05b7bb03b78004b6b52505b65d40ff
+03b64004b52503b4fe03b39603b2fe03b1fe03b0fe03affe03ae6403ad0e03acab2505ac6403
+abaa1205ab2503aa1203a98a4105a9fa03a8fe03a7fe03a6fe03a51203a4fe03a3a20e05a332
+03a20e03a16403a08a4105a096039ffe039e9d0c059efe039d0c039c9b19059c64039b9a1005
+9b19039a1003990a0398fe0397960d0597fe03960d03958a410595960394930e05942803930e
+0392fa039190bb0591fe03908f5d0590bb039080048f8e25058f5d038f40048e25038dfe038c
+8b2e058cfe038b2e038a8625058a410389880b05891403880b03878625058764038685110586
+250385110384fe038382110583fe0382110381fe0380fe037ffe0340ff7e7d7d057efe037d7d
+037c64037b5415057b25037afe0379fe03780e03770c03760a0375fe0374fa0373fa0372fa03
+71fa0370fe036ffe036efe036c21036bfe036a1142056a530369fe03687d036711420566fe03
+65fe0364fe0363fe0362fe03613a0360fa035e0c035dfe035bfe035afe0359580a0559fa0358
+0a035716190557320356fe035554150555420354150353011005531803521403514a130551fe
+03500b034ffe034e4d10054efe034d10034cfe034b4a13054bfe034a4910054a1303491d0d05
+491003480d0347fe0346960345960344fe0343022d0543fa0342bb03414b0340fe033ffe033e
+3d12053e14033d3c0f053d12033c3b0d053c40ff0f033b0d033afe0339fe033837140538fa03
+3736100537140336350b05361003350b03341e03330d0332310b0532fe03310b03302f0b0530
+0d032f0b032e2d09052e10032d09032c32032b2a25052b64032a2912052a2503291203282725
+0528410327250326250b05260f03250b0324fe0323fe03220f03210110052112032064031ffa
+031e1d0d051e64031d0d031c1142051cfe031bfa031a42031911420519fe0318640317161905
+17fe031601100516190315fe0314fe0313fe031211420512fe0311022d05114203107d030f64
+030efe030d0c16050dfe030c0110050c16030bfe030a100309fe0308022d0508fe0307140306
+64030401100504fe03401503022d0503fe0302011005022d0301100300fe0301b80164858d01
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b002b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b1d00>
+] def
+/f-0-0 currentdict end definefont pop
+%%EndResource
+%%BeginResource: font DejaVuSans
+11 dict begin
+/FontType 42 def
+/FontName /DejaVuSans def
+/PaintType 0 def
+/FontMatrix [ 1 0 0 1 0 0 ] def
+/FontBBox [ 0 0 0 0 ] def
+/Encoding 256 array def
+0 1 255 { Encoding exch /.notdef put } for
+Encoding 1 /uniFB01 put
+/CharStrings 2 dict dup begin
+/.notdef 0 def
+/uniFB01 1 def
+end readonly def
+/sfnts [
+<0001000000090080000300106376742000691d3900000184000001fe6670676d7134766a0000
+0384000000ab676c7966aa72abf90000009c000000e868656164026638f70000043000000036
+686865610cb806530000046800000024686d747809d700950000048c000000086c6f63610000
+012c000004940000000c6d617870046f0671000004a000000020707265703b07f100000004c0
+0000056800020066fe96046605a400030007001a400c04fb0006fb0108057f0204002fc4d4ec
+310010d4ecd4ec301311211125211121660400fc73031bfce5fe96070ef8f27206290002002f
+0000044a061400150019005240111b46001708160f1404080803160a064c1a10fc3cc432c4fc
+3cc410fe3cec310040120803a90010870e18be16b10e970900bc05012f3ce632eefeee10ee10
+ee3230400bff1ba01b901b801b101b05015d01112311211123112335333534363b0115232206
+1d0101331523044ab9fe07b9b0b0adb3b9b0634d01f9b9b90460fba003d1fc2f03d18f4eb7af
+9950686301b2e900013500b800cb00cb00c100aa009c01a600b800660000007100cb00a002b2
+0085007500b800c301cb0189022d00cb00a600f000d300aa008700cb03aa0400014a003300cb
+000000d9050200f4015400b4009c01390114013907060400044e04b4045204b804e704cd0037
+047304cd04600473013303a2055605a60556053903c5021200c9001f00b801df007300ba03e9
+033303bc0444040e00df03cd03aa00e503aa0404000000cb008f00a4007b00b80014016f007f
+027b0252008f00c705cd009a009a006f00cb00cd019e01d300f000ba018300d5009803040248
+009e01d500c100cb00f600830354027f00000333026600d300c700a400cd008f009a00730400
+05d5010a00fe022b00a400b4009c00000062009c0000001d032d05d505d505d505f0007f007b
+005400a406b80614072301d300b800cb00a601c301ec069300a000d3035c037103db01850423
+04a80448008f0139011401390360008f05d5019a0614072306660179046004600460047b009c
+00000277046001aa00e904600762007b00c5007f027b000000b4025205cd006600bc00660077
+061000cd013b01850389008f007b0000001d00cd074a042f009c009c0000077d006f0000006f
+0335006a006f007b00ae00b2002d0396008f027b00f600830354063705f6008f009c04e10266
+008f018d02f600cd03440029006604ee00730000140000960000b707060504030201002c2010
+b002254964b040515820c859212d2cb002254964b040515820c859212d2c20100720b00050b0
+0d7920b8ffff5058041b0559b0051cb0032508b0042523e120b00050b00d7920b8ffff505804
+1b0559b0051cb0032508e12d2c4b505820b0fd454459212d2cb002254560442d2c4b5358b002
+25b0022545445921212d2c45442d2cb00225b0022549b00525b005254960b0206368208a108a
+233a8a10653a2d00000100000002570a13d8c3465f0f3cf5001f080000000000cef5cb760000
+0000cef5cb76f7d6fcae0d72095500000008000000010000000000010000076dfe1d00000de2
+f7d6fa510d7200010000000000000000000000000000000204cd0066050a002f000000000000
+0044000000e80001000000020354002b0068000c000200100099000800000415021600080004
+b8028040fffbfe03fa1403f92503f83203f79603f60e03f5fe03f4fe03f32503f20e03f19603
+f02503ef8a4105effe03ee9603ed9603ecfa03ebfa03eafe03e93a03e84203e7fe03e63203e5
+e45305e59603e48a4105e45303e3e22f05e3fa03e22f03e1fe03e0fe03df3203de1403dd9603
+dcfe03db1203da7d03d9bb03d8fe03d68a4105d67d03d5d44705d57d03d44703d3d21b05d3fe
+03d21b03d1fe03d0fe03cffe03cefe03cd9603cccb1e05ccfe03cb1e03ca3203c9fe03c68511
+05c61c03c51603c4fe03c3fe03c2fe03c1fe03c0fe03bffe03befe03bdfe03bcfe03bbfe03ba
+1103b9862505b9fe03b8b7bb05b8fe03b7b65d05b7bb03b78004b6b52505b65d40ff03b64004
+b52503b4fe03b39603b2fe03b1fe03b0fe03affe03ae6403ad0e03acab2505ac6403abaa1205
+ab2503aa1203a98a4105a9fa03a8fe03a7fe03a6fe03a51203a4fe03a3a20e05a33203a20e03
+a16403a08a4105a096039ffe039e9d0c059efe039d0c039c9b19059c64039b9a10059b19039a
+1003990a0398fe0397960d0597fe03960d03958a410595960394930e05942803930e0392fa03
+9190bb0591fe03908f5d0590bb039080048f8e25058f5d038f40048e25038dfe038c8b2e058c
+fe038b2e038a8625058a410389880b05891403880b0387862505876403868511058625038511
+0384fe038382110583fe0382110381fe0380fe037ffe0340ff7e7d7d057efe037d7d037c6403
+7b5415057b25037afe0379fe03780e03770c03760a0375fe0374fa0373fa0372fa0371fa0370
+fe036ffe036efe036c21036bfe036a1142056a530369fe03687d036711420566fe0365fe0364
+fe0363fe0362fe03613a0360fa035e0c035dfe035bfe035afe0359580a0559fa03580a035716
+190557320356fe035554150555420354150353011005531803521403514a130551fe03500b03
+4ffe034e4d10054efe034d10034cfe034b4a13054bfe034a4910054a1303491d0d0549100348
+0d0347fe0346960345960344fe0343022d0543fa0342bb03414b0340fe033ffe033e3d12053e
+14033d3c0f053d12033c3b0d053c40ff0f033b0d033afe0339fe033837140538fa0337361005
+37140336350b05361003350b03341e03330d0332310b0532fe03310b03302f0b05300d032f0b
+032e2d09052e10032d09032c32032b2a25052b64032a2912052a250329120328272505284103
+27250326250b05260f03250b0324fe0323fe03220f03210110052112032064031ffa031e1d0d
+051e64031d0d031c1142051cfe031bfa031a42031911420519fe031864031716190517fe0316
+01100516190315fe0314fe0313fe031211420512fe0311022d05114203107d030f64030efe03
+0d0c16050dfe030c0110050c16030bfe030a100309fe0308022d0508fe030714030664030401
+100504fe03401503022d0503fe0302011005022d0301100300fe0301b80164858d012b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b002b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
+2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b1d00>
+] def
+/f-0-1 currentdict end definefont pop
+%%EndResource
+%%EndSetup
+%%Page: 1 1
+%%BeginPageSetup
+%%PageBoundingBox: 0 -1 631 791
+%%EndPageSetup
+q 0 -1 631 792 rectclip q
+Q q
+268.801 790.4 96 -38.398 re W n
+q
+268 790.4 97 -39 re W n
+[ 0.793388 0 0 0.8 268.8 752.000008 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 121 def
+  /Height 48 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 48 ] def
+end
+image
+Gb"/kM-!XM[`AE!Q8p)k#T4-r#lt*Y"Mu-$K[C@n60;;Q"=FBgZ&5L<KG04MMF1D/J=q]X<%
+ HR3lVqkK/t_f_;*3Ri::IX?qsBT"PU`fL%_#Qbg<8Su-0a9Ym!SPOTCY\VT(D`<iUPH"?Ti
+ f3nA@ncNZ:'lVR`t5X<9/PXeI(jriEE%o4PH^Y1p=";>]XucIEA`2,gQ51+KSn$54U2L\W<
+ QHDbFV8K(SqYbs\#rAR3)^\mh`340qb`![6roMWSS1Elma1d6bi^3T5\'tFY$Kk^5/M\jSc
+ /'h!%<lmaQFLdSh3F5co?aY+@[WCWg]mJqfUIUBZq;rWLo/q[ZoYC4sp=jN#pu75/p[>kDn
+ mqWP[8g5g7;6HNV>6%LVlq9N^U7p$j+bRBb,kB.8O4*U]"6>6jY]stQIP>-3U`M]%>VDDa6
+ 5BKcfX?r'i\45L@'t#95!>0.nH8&)crODSf[<`TN8u8H6e5kQ"@lM--(8BM?R$m9"?2l2Kn
+ WMq$6Z]^AS!-%j!jK-@GadnS\P*EW5n-cYq[QM9W]?^:l!CXh6>,+_)I$&+<W8Cg';E7:t>
+ hFcF(OX,jZl3OrYe\NLnWmqoa_T^D<$/QWIlJ(W5$1"=ZlUSm-un$WN;2[kO?).KV50W'iO
+ @gQ8YJTXVd1DB=+"i^cr_j$1<@D;9*^2aI=]sU;-T3#/mG'e#ji8At"_o'6O2T>L@:Hq:qf
+ X#5BS2iA\'4^3*:0G;McBb>^*UB2-k9_dK=kp>t`JJGI#5>P9oka[*M;;h!)V16%25CH%Mc
+ &%na_RVUX!;1U&MCDtd[;"F<N+A_NHBcjb[="RO96@Din<;9ph.-@<8pC^q$M.B7%USL6',
+ $Uc=_QBnZq`P_J"(L7MVV=N::s!Eci'uRsR3eEmbS)>?;=Do\[E-n$gZ`=(+<<kH5gGQ'K>
+ 10i8=Y.b?N&8%GQKc!F7OEFeC8;`iTZGd-5eRJgbWbhl]iZ)&j`CTb6)05+-Y89_',BOsS-
+ WMZRuF*(ULdA\9PL$GF36Ma;20-9od5;%8?K"COU]!>>JZ]naLIU2bugEq9S-+Y^i&haY*b
+ Z/`-<U>*/<i.r/;9k#>itkG\cO0?*<(Jn7U&^TX_Ic=ub_2qaVPZe[qN'FDHP^Dr$Inh`eE
+ <O!TcH3U$4AYRFHMJrB;-rP@ap`WGAgc<h_0Z\g"?J`Mb;m+8j1dfp[A'=!JZ'BB0*jMhnk
+ _X^YLU*_K>1J"QrdI7(o$Nc.ajDDAss77QK2f4[hCR8Z7Ds``"AI1'q`b5$W`IqtlH43;`a
+ (VYnH)4*UDbff=1iDH'0b>IDp=2_Wn?>h:fJ8mfW=^[9eNO&Pq9YFK`]E=!%k#Pd_JX8L:k
+ r9s(B>I*-<nCed4C^f9&W7^?PbXmh\iQeM-5NbRk,Y2f+A^Lh=&_\U.%cES!EDJnm2#=f?h
+ Et:Ce,32ef[%Wa=`qi<WB&#Q='n)>rq1u:rH5Z[2pDR%rYOJY0u2^lEULR\B4!WE!3SN-r3
+ kQWH3UORJ(tT^@^=0hZGYA7SuanaAr,)3lcdu%KRQh-f\0S@CRH"[Z#O9sq=B62IJ+N[HkG
+ *-*#sZbB?r3/Y1<aOf$CKah,o9!bArWPYJJn9VR=-^:)7)\Hb<FPJHr77<]plA_GE,fD(;'
+ ts-<+lhObA`E1n8Se\GQQS=Kj#kJ=88nE!udZ3n#Th(ABedM'e\>\rjC))KdY1.5ppj<@D+
+ RJ)rd:'+I>7`tG5[d2PJiJ`+9C.^Oi%h3A^f+K)A1*pQg3=".mc7M`-IR_VplLGJ9,f:-gC
+ %<Y@l$Bj'#MptarY.=1%nC`gB8D""o]aI^-[8HZ;E87XLL]75!Z]O:JQt0g%5T#N.UYoh_b
+ rp!S8bTr44B7Uk!mc/&2F>.3UT3Q%fK*T=%R[?iR.)l3$Nj_Z,]I,77FJ:UUY$s*:t1M"f\
+ HHQOgL-aH,1aXG,!HrUb5Zi*n"&9S[-JA=`mL33@rlH?bL.3&1[cHr,)d3M/$j0OQ$\CLH!
+ \)7hW_:_C&]I6LAN,$E^$jWeX/m1?O6J;EIU`0#$W!c,-H!2&E9#"h@6_>@*4"5VeqFmHop
+ ^=2X.g6O\A/^<^#?]K2Hop"*?H3NrDr5i_<?3P!58B;KRbk?E(>VO)$#sZG+#p3Z`V=HihJ
+ 57mIJL<`j2XHh?91-HF<ub"XB[Mu8''IIE[&9lL/0>2Q_917r^rjbm4h,FfS_LW'@6RR@h:
+ L7W;,Q?4^rCf,D>Ae&1CMOq>5q>reXQosA!Ko$Sph?UerZL`Ie9#RTHQ7Ol4ke37cM=P,Xr
+ HEnu)8T2t[#^6\cc5_4FbBO+F-9%glQfi^hnF.2a^Gq?nkQ`>gfhP@nUjlQp=[W#KU?T2Y!
+ T(GBrJ>Se7l&0KnmHZr>7)"&hc\#h7nQ>B+c!4Y5hoF]CI3qDV1,@j0e6[srci/[r[1A_Nf
+ pVoKh*7P/Ib*9Q@,<Z>o5Rg$R+W*BeQ@lTEP[g8JSqMu\NBOFR,Cdj\e4uVgj`;6`.P")O.
+ nU5fI;iq_9<FYm3^<G\B4%,eda&V?b\*10NPA;K1;EI72V$Q#a$GV!b%62sU.sVEEYV5#@J
+ C1C.\Vh0ccVhf*9QRnZ)-RIjic[f&O_W%:06&=m&UmMQap_e]PLkmc_a^CatjDg\SGXoiHE
+ ho;su8gT(+f?l"'cQi(qbWYCfPQW)Yt(PoS9eMh9WMDDk[Mm`i*/'\Wh+`X4F2XiS:Ch^>%
+ Dns"l*l>c4VeK%l':=<gg>fDV5Q4t["TB][Jm3en*jW)G6HLfi)E'+AOFE$g$i;>-Ce86bO
+ 1CTQS6CH#N'Hu#Z3XO9%7oS,GMjPj$5GlKe&+82#pWf>-1^(p1X+,*I_MZ?&05#!H6r7;io
+ W5.H`i5q?*d73kmcDS&_\<%R=6GYsh/=td*uMrl0@+p.2AV2sj-8mh1j5o(B"NJU,OX"OlN
+ 5/(-@g$n-*VLQ=RrRf-k3_4rVBGo71f.4++K5"I!'RcKZ>W891[J,1m[67X(?tlf#f\_GH3
+ J"rXOuI_NAs21HdmuV>kWCs0[*OZ+#D%!p+XFP(=leF"fQ)S^\2cQ_>Oh"Pq"#/mbcTRdqU
+ tTcP6rmdAq=OI&8cQtOHnli#W$jX%sYg6R$;Fm)54TEa<u>c<CK,]^/9eQSE!dDj2s&],#0
+ 1jMHVdg'T_L6R"i,"2nn%SacP&9K.b^"p#89eD4rn(g(0GAgB,4NGSQ>C)IICIOCe04W;u\
+ *HYJ^raRbpb85=KVOC"V&t*X>+,euZ*A\0ckQk&eM+o6<i0P#1q>a6U^S?ZKnmH9Ch;tSZc
+ Pg85MFrlkeVo![1WFjH?/o6XaRg)V8Pb6CjKi\^WoW@&L("oZ*"OD+&3NfY#6+<LZ8Qb)uJ
+ Y\I&1"m/8?^X+WQpRlN3d&omX?J9?0P!$-l4/_Eu(M8=2jj*\Am&*nNmJiR,c'W,WpZT:7c
+ `G')rc2>4Jc8V-HN5^AklR,Z,e;mVO]3l0)jcp&N\:PNb>:ugDYjcr4sACr1](uuT4XS%3\
+ fuLWI[!W.:S;[S2)5Skt8$5jt/df3,9uuOQ:3H63)`P3CfFSc;J>fk*=e+2?kKZkEA%i]%4
+ YbUr3fDq[2!E1,a2+1qW!rqM;61:YC:A]T95mHm:l#KV/,42mbJJg!8(?;Jg;ZS;hV&k_&k
+ LYW7/4p"IA@H-Fqj5U,S@+LIZ=2J6&bqtW8I%09Sa&=>+(*n`=X.$@4o"`NPP!OGFT3[KgS
+ YXCB8\m!E&E$Njcsf$4-WfJ&d%)#Ek[OkLu="]*bnPOk,qS3fe%U:5n+dfm^.eMqn7A7(jY
+ ",@b_#(p*@a=Y<L275eFfp#`boETE.qn8Rj4K9K53pt"U,::stYU"5X6F(V)#5pu8$JI=#i
+ JBf#&@`rPn8"%'HTs2`SVE'X)4h\2<lu?\_L=*MCO4'+[Numug+"8]lORfO0#b+(,?AKgR;
+ Sk\3NrJrS\d7R'TJI>n`k>\e7TPmn+g=cQ-'B?O(^\*DD5L]Ff[Gi8J*)V%1<4m\/[E+)b0
+ />O_91P'_H)TI@:Dmb2k)\['?L_\.>N$XYUAT+@SW5=+9L-j5`Nt%$UqRm0@Q#@\OJtgEbI
+ 5:L%+7AF6ZfXokW/;[^9^r]\/Uj*qm$nNco.\4UicK!4tnMs$rY*eGDL8.-uq@V(Xd@B=Qa
+ (,8c^pT[N'W$FQIm)_a#\h77-Xeu$qk`c3Xj;3UOqmFsT<dpcgt9G9?Ke),iqBQ'`21<W[n
+ L0R7]6FdMnr*`\!.t&!E$h&q,NW(WX"k@,T,&4K<l,0ojgR/Ee7eSD0cWrpZ/(^^RmLC3[_
+ b=c_mDERM$$rJ<c/N,S\"7i3.tLk-Cc!tlhbRhE0228BMq(pSB.,T_5e.$2a2k@`GFMt`h1
+ K5*bVCF,-9a'UZY#G^HYWVQ*/;+Pq(fC,R'.#d2jW4QqE!@+$>=_lUVbC1K=K)u5oEP8H8T
+ uQAaGDD.t?@o?<;T%$O2S\P7jmc^+U00)Hn'<kbN=m*c>d%OcA%mH6>nGj_&LVNG?P^meo0
+ 18WIU6^<2XIWq^ZF5u2]7euRJNFi4`r,%XNR:^O6.g99"CggcO=cHDJLl\s8C./#j8N>kR<
+ 'jNPoNLA/9`0F_-[rKGgO&6A&EJ[&h\[fQ.9?+:pEote5KhQ=LBIU:?PD*$?2pdV+`),\"M
+ `jRD5PK-6b88JE:,isj8&oR$Q/9[u+c>DiDQs7CRZ8lbC5XQY@W-+\p/?o5Fn7.s(d3Cqq_
+ mk%3LQj%!=N9#+g=iNkr;o-S5Dc./R!%AJoE\R"Q`O[GD?qUkR<%1kiWqrH+@DNOW/t$4GL
+ 4d>6CP?")=?f1J0Jj(ccU]AKVs'4&]%RBdV-DaH;ssqtR\"a#5g_%Uiij[Ph+s$uZ.u=@>Y
+ DK0)qG3$8/fBQ@L\,Lj4iZO/SoOInK6+6Od"PI"dQ60Nf=OR0KNP7_hJ&8@gWj=na`FlTWU
+ oB8Iqo[9=91DeJa]Re)_"V6d4QmEcL#-E]j>UhGKLpt(*(WTd52VX3OgQ/aCb=+d=,@1):+
+ u*%V6bOEqH'.o=<Ki/YT)niQ$-AOqGi\)A8AtCK0M/e!+''j_aE*oG6AfjR7]$`>A+Y!kad
+ I#):/4.i5/S4W;9'mni/=-&V5srKn*Ot/Ul<s4q6W*A*-3FPb*tmggA"P)(C,)0Y7<^P&AL
+ q9/3u'&eM:7b!KB]Rkln-$8b-OYZ/IXV,_;q4n:`aVAH&OLM\T(O7Wrg+'T,=]-5MLc2a9=
+ pWtj#^.+*5#@d>u?/WC;Ui^.=7DHu5lb;-AC@nX*[b)L%$=M3U%BBm=<o]"6E5b`/VPf2O=
+ <X4WGq%Q_&^+L*cM%lgI_$h]Yj[,,#PQ,Y,G&NWRR66dc_l,t\HT.7FHO?'q`RY:#9?<mp%
+ "s00N2+bIqFuQZjM\Aj:l+Gs`V5uT*RDmLK*Mo^SN;>E',r"X`+'-*hJfhZ<cI;04EDJF3-
+ N^1PcNGpK"779Q];nR&7.m@h9$GfcP?C/?hAKTkkei:&&m2mp^p3p0VjR4J"87gB0KH"(4t
+ WV,RL_4/.g"#I\;7GA,3(LW#K1JB/,I(L_(9[6>/%IPC^!GEIaeG]K=KlcqnAJD*u[/,V1`
+ q5$]Tk8&pX%;C?&6U4d=Hg]7%'%2UDS%NVf]:S=BR`t9\_KVqb%B9Ip\;C6c.;T4=di^brp
+ dM#^gQ@hV7BilLDM8bXu+ScdF*pGU[T*\/rT./'q)\*Ahs10<8Nhq_RKjPCU,;e-b<lV9^R
+ QI"A[!MjZ_FTeDEntU%bD#P^/qEn$0R&A.]1gCbeoFgpF'!$&Hj#Y4@`"Kj-BBH\+]o3iKr
+ #r'1gjFeJn9\2JXd_t7Q:Y/`<*u0E"LF7?cs=YLc.<]qtKO;<s+/T+>_PT/p:XM$(<TW[u<
+ tHF(cU#S84fF/9"9N8f2ke7Y3E0VfTG]9r:!.gYF3C$H3,X6\a9KKJ@=;*_X:8YT,2$9>^h
+ e&[It<eBlE+RL);G'F4iH+<6:1Du;mR^)Z#5^D]'XEP0RF/(B7UipMYm5/AocgR=k5FQ8N#
+ &!\,5:UV-ioI+9c6_I^&$.4Ee-`L"3@gQ7niB"`1S7=$YRlT/jP)ue>Y])-8+WuYj]6<-QU
+ jbT']DTmC;A+ApX-YK7Bl%,0:lq.2X-B;OOhg3.-n.,1;,plgBM+km#ES#`0ujG)P=5Bk01
+ fQOQnYE)c8P9uUS.^MYq0F?fdC;Ii?h)]`ko!.KRbJtf8]cOmW\U/-Qm8R>MM0`SiG-N[UD
+ qUoX*7B._4&kD_81O[UU6/>F@P+REKkV?4OF#@QQ6JS[Z;7MQlUdf_X=V:%7Wq=Iso;QbXN
+ g<Y6l6_3m_E-3?hMNjUTMD'B_I@'Nfh(67K$"@Ve>5>e3trs,o^6`^~>
+Q
+0 g
+BT
+22 0 0 22 289.473926 763.771396 Tm
+/f-0-0 1 Tf
+[(Start)]TJ
+ET
+Q q
+177.602 708.002 278.457 -71.371 re W n
+q
+177 708.4 280 -72 re W n
+[ 0.797873 0 0 0.793023 177.6 636.627923 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 349 def
+  /Height 90 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 90 ] def
+end
+image
+Gb"0TGuU"%T#^@ckDgbuA(X,(+bY@PCBuXGEfl$'$R(2-(',"9X!e_WPtT(*[>Lo]["*M2;l
+ Q^gUM.J!?5G);)6K664<Ai!3_mk@4J'i:^*10rleG7_@X_,2qjc914bnfahrgQnM%DENf8k
+ R9^qdbGa,bRoHb6l#g=tB.1cKp\l/@7")aJ9-NgcE*h).'4B!`*I2LBZ75ekG7mDEE-%b%h
+ fZ14$t`fH0#3H4hQ002-T?t_7'rr.A6SnWhpZ0(#U9_\/WpYS2[n,VkiC/DTTbGn"-`RFG9
+ bL.bR@cCltn^.q'.TL#(87ZtD3\5s+,,S%'_[QOJ=pR*[9G9.*-KCiMa`5^s\;8Y!K`&L,H
+ #mT">I1&Ac^n&_:Ngr+5CE6f;.Y"*"K5@*>8m^=D"`h#S;^SSH)7iZXsfc<^3JMgV5<LD0;
+ nlO(Ta`@L_+kW($3I&/1[,C/Nl*['ccErd:7e",]?Ia;I'$\KnoEkn*KCO<#JBu%a]m8B?s
+ UZ<_U]_H,$RkETt-Y'h^`j>dL?n_gP`=)n)oMhnHgRHY)72aoa^;6>m'_;fB#aVR1R=>*r=
+ ?RMAa&"1[C3.=Jl:$`<@K^#SD.X&+O`c^n"[JgjET+$XX]D_EbNR@9R$^UX'V'kLV$QLEO4
+ ;-K?NRi%_1)kIujQDY%]Pnh&IHJ5YBl&2F8RE*/G4Y:7@WM@Uf4<6!q9MM4T1fnH6-.rS\%
+ FNYRU'c%*ku!"'PPmA4ZG\G.JgsU]/`F"UpkZobq)JlnFgl;HIe)RAoB4HaQJpr#_C'^)Au
+ ;A7l#k@+D<ocuc;)]A%Biqjs7l#^PBC*U2XWQ6^ZOOLSX5B)!pp8e+Z$5)joZi[.387uc17
+ 8_8Ws7.V6101:r;DKZi38Tk?V+H\##q3YHO#`!sAJn7un^>e^:Y,HrY]hf;_7cgGaR@4Y:5
+ _T&Ic9NFs/E/q6pRdrO[?RJk\-ZIWPVXiaV.B18sq=8`0uJoX4<e#Z-1Jpu6bIFu09>T^CR
+ (V3E^<19bUQ`-Dp(RQ<+T;,HN6=hkP':!%@9Y_<$Y[-U3U/[iZ[5HcIIglns'XId(qSe@/%
+ j!iHBfT0k;XDEd<NTU_HYTQ->l!WUWj\\1GL%:Vf)76L.SFL`i]$+el]Z]SBtQA,XnPkLck
+ *upWfk'H-V,b^4dN+e-'R/^:7@:2AZp-\%2,r],!3?&-P8<tg5H@-Q7cCMi8V]`rVc[K9Nl
+ "XT*oQlnBc4Nn:@)\]fY,#n_BkK@/isEkI)Gep#h85r9l3BaH(ftj=qh(WSHIZY5]A?57X_
+ 1_sR9(H8_l(1>I<q<o4FgVaL1=-i_TL^N4jFER]_fn(Enp%Gk?tQkM/^S<(j<T*b5:[T6:-
+ DI.5#n`*+\5(#oklNR'on.p*.:=$1T#?$cG`<(fGNEQuB5?tP_KC$*NOg:I'b6du_.eeZ6?
+ 6f(,3HAnH`l9FY\I+qbdih]3p2_9&(NDkR/:f#r9q-7g:d\Ss0?(+29Rj57br9k?mAl)#S0
+ AP*UrH*ZWg31^',(55$\S6;(2$IS0tcuoU":=UeWqR5iXT]k'k)\<"ZKIkV\$'H69>]!9Aj
+ =q+/Q!@YJ#/KmaJ(0Bk7>%?Np]=]";nIgpo:G($t&IPVg?dY?#7)q!3=<V4iLiZQoJGhqfZ
+ gere,`ajnA+CGEB1R,!!$h2<i%c%VIWCOlZ!nUY8]?M_rQ/L?`V8_Z@JH4JVrqRg@e`AG&0
+ Z,4p#^>@Hb7)YB!3DsK/2^c$p9Y"e3Fa*T3n9I__$h2X(*boGu7"m,ggmn&rnsn?o"@&5HJ
+ #=#[>V6df+ljS/DNHA!abahS.Z9hC+W%K,Qg^&s&ZRu!=fO-])<sO83L`US81-n:A6Ul>Q1
+ nh$+4Z0KLC8.`gi+u<+^k1,Nu'h/`.TS?X/d)#"aF4,#aPWfFOl-?_P9Gl00`O`>H8NGb#=
+ B0+-Oq"jEN"3RRg1ga>khddum?bdf-\h9L4/L8W-'Po,?&W+\dgSE'2eh:6s'"Vb'\K4>s-
+ lGm[lRfPZkqG[CJAm)2d*b;O:AA53nLJn=q!NcBWu%(.Y.caclggCu)Qch/TVjH2*mPN-AQ
+ 8OLd=NP"W.P:Ls"p!*Fi(&c>k*?#YRFiHC+)*UhA]2`C<r'dm_P/1XD['3*CO-\E%]%@4sg
+ :BAN@MkMep`RoT#epKaVa;\JCTQ_lJW/sA,H#/kT79UMN=Q=,K^/ijAKWqh`7J_eB=d_K'S
+ 4Ru-j)SD_t3T9#Z<9&Z_a31P+$(39I2o(@Md8`/7_6F-2BM8"nB(@Mlml=aMG\D1oHO<*P"
+ ;bKUWk?<X/BKd+hAd5BG"u7NM7@KegH-p),IX(p]eWF1eYf8SV^'Z[s_W$T!G1ea]@d;\iP
+ KOONITgu.K#r.:dmr7eF>8Ol#:-Nb9`i.:^8Sm9j/<\:;3+;G5]icRCWZ>3ENJbfA7LAJ/C
+ FM4,s`mL+Vl2tQ8l3@qV_5PT[o`6fWoqR>1@h`O+q>cq<qB87#1TI`GI=P!YrV.OJHC9JQj
+ :Rsel5O7Pl=UV^(1cB-.d9JAa][gKr:bF#1Lq!\V[bH7mD2"p)gPRG;tO!(^.K\1dP)%G">
+ hA8"HsFfKsN4q"UkGNP*\JM/;t4kNuVW7f7G\SZZ';%Ac[O7L?.e]!OFIX;*SuTiI33]R"Z
+ -/qKYF:p\tI!ZS96m5AuA:L(XX5_MCMV]HN"KH4Vb<,6RT`LR@F&K7I+/FOZ?k@^rm_!bT8
+ 8;*SuTiSHU$Qj$,NrOa;.qi*lYfi^:G(hm-GIbkXR%8.6d$^QD@Gs`!!N'Y610H]uZL)=g\
+ K7I*41@"$31#G'-!bR"7W#mq9I.&ZnQj'@\Ib55'^$?eK(79aN@7/7OSfhDV(kVU06O[VQ+
+ CGt`UOM&2_jN^pQj!m"@Ot\K^ark)&2V^N!bMIcJ/Eud&24J/"N2;0;h/#d+<]g>*e=oiKt
+ 'As6aK&VYT`/(5(CcX"p$F`p#0Brba&FtLCGs[ouU\Zba&FtLCIAhl?gQ&Qn8]q%i\tAl:W
+ 41=iaG:;Tf.7_hOP>qSk5tVC\7/rm%i8rNII-UV:WiK%[FprNII-UV:NfK%[FprNII-UV:E
+ c_V`VTrnQJY!qjHcR#h*00ahU:!qjHc/->Jf@i!:P"mRHE=Tn"'`[mK)$e.rjZ3\t#Mch`0
+ (9!i^A.bcd(:.D?/5SQFa<FG&/7u^\=eL5lO@>g+<Qp&?Z9\Aa+cAU6UmM>WA:aSK6^E?#6
+ 88l1aTD.!L+EE!D.4:)P6L5!%9Wi!X/'WtADn<kPD1UiofY(K8BF1q&:[oskdi2Nc-sd+")
+ 1=M*NA,"Sobjk9nT\Z#lTqS2"W`r@J\#DE_/o!Bh3XT.5tktC6k[8d]u]JjDBkk>q(ktL;>
+ Dt)2u=-S!J0]N+KM:0ZF-es6E,mHJK;V\Z@+?25D[`Hjj/>P<%(:$qX1#BVs2ZZB,XaV%<0
+ XpZ<5@Gafn2*Uifc\m08b)EFZBT-oeC)Ir:ilU[qF>gXMfJC$sYJV[V760K;)6CW_:-Bc^7
+ a_hhr.K?YTHHG*M/Qu75R"[f&AjI._o5_*q<Ch5*T!=mB>WH_.Up/D-8cB8gp?KbK/NFeH:
+ *u-)%6:UL4uPYJg(>7qAMSSf--]4.#k4@'-BU.(PCp,NCFE?HpRd/&1O>)kC12[F(Fce^j>
+ ,TL`E)?D;DB^1ET'2m/piJ:>F`H4[)=+\`a'H730NXb=!T"@6cm=s`l]<Z,G2ejV]dEF`ch
+ cC5][Qa*INCOWbLr_TeVF@s#jL:-guE=b7u,JMTaP%*'#r_bY\Yu50i1omB)e?L"j)Kp["k
+ SL^=`7fophh<'IJD*Y)@lLXHb5c8aG!=e5`7I\b3FpcZaq5Z/=f[KMeTK#r1hd*TR7?oVp:
+ A>P7/o6ag$d;BNG`X<T9o(B^,Td$p=^m7%9\2ghE@7h@]h(6@f*>fX'GOKEZj5,IA88%gL$
+ M8B7]oQrbL]d*-71*p$\DTW8gV7@3I@!0\ba+Ff?DPdM*eB99+G>IRp&`-_q95!a.e's2+Z
+ c\:D?q$m.<t@q4/IJhb@?C>ecI5"paB-jI4\-UDAJg,HNs4`il&+'ZkR/"CRLQj&9Hq7:8j
+ PTpNDq)jKDJip*YaCl,?pgik@O97tm-+.eNY4aR_&@&OO8#LRF_f)&Nk-k@T_kVK=LhZp?:
+ 2VrSf0\R?\BN5q)BO)qS6EoE$Odj?(reBlh!$cAd-L$-dS5CE71WTgb+r#D[d(Z$CLKatg`
+ Nh"ErHZ1`f\aM%nX2>(jOhui@iA%I58LH]spLr)M&4/_ePC_].Hp1+9<_!PV+WN[bZ[B<G*
+ ZP?U/TnGkE*t]4a2.iJZ87L_56@%%@8b=dM\e%\qsM))[e":c/60i?\=A%jGII15@.32fUC
+ aZ[@ZK$g+]$C15DTR56-I.Lj_@)8>.@<Z63n#49Vu&HK_`E>k(`A5:bXC:QVtWmjB?o_Z%O
+ *4B9nh">?Y&cp\aj<Dnl5dL.Nm'VD:8^qR#GZmJ>O?D,QOTSW2*C)[VQMFW:p'ORq+u6?]/
+ lP:3\gGDZfs6^F73CW&RG%2ft:"7sq;3[B%*_*^PVL^hZ:ciePs)cqA*T(Q3Zj1$M&Wk,4q
+ `jKSXSii_!"S1/_*W,^0>$@Ag<.Y%_Ni]K\j/h$Qa%:Nqg\0a7'RWr;J/'Ohr\!/=%_Q$hK
+ \ctC#Nc[Hie3+iE]skC-+12p4'7Enei_OPSCgjChU7RMRICF.gIq-rKpPqm[hu'mSXuE?%<
+ Y+gEoBTE`u41Gq;R>F40UiX/2-1+r\!6mI!1%@X]!5+#e^E;i)b(WG]DZH,[>+d>:TaOGE+
+ RkS_.HM,jos2)>1BpVFLg$D\0+<!FBEsQJfcU%)F\`.A+dr>>8L0$#IWhN-uNN,Woj<,F0]
+ >80ETB!"7p6);L>^B+2uk`W[#sGHuk3jlIDMn5Vs`h(K^SbC\tc.SXJfBW,.AFAZY=/ki6p
+ Lj=oL-bA$DoBdg+No$q!;SJ]gck.Gn7US20*uGS`#mLR>JoRcT$A0rKjp%T5l.s+(ht6(=9
+ ZR9\V%!>$rB3;,k?D.0lKU9/<\.I\?rh85IWe1uAm0Xq>#&ff6KkPfLl>9Tc@B'6\6rbNlK
+ Vbp0KPRB%$1e!&$K<:175dgJB*E$hVN&"Y$J\ZTr"U]eB-$@:4D&Ar&@%,2hEIr#M%62j+8
+ W](`LU-7V@$k?rRe5Qg(ZG=&?#MJH<8\-lBV`g`O0MgqVaugPZVhCCfk5FMY%d>VIlLg<58
+ )iGHI3!mChlir~>
+Q
+0 g
+BT
+22 0 0 22 295.43584 676.569568 Tm
+/f-0-0 1 Tf
+[(F)71(ind)]TJ
+-3.973633 -1 Td
+[(\\MGL@@@<sc)-3(ript>)]TJ
+ET
+Q q
+243.199 600.798 147.57 -135.715 re W n
+q
+243 601.4 148 -137 re W n
+[ 0.797682 0 0 0.798319 243.2 465.085823 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 185 def
+  /Height 170 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 170 ] def
+end
+image
+Gb"0WLK>0kqZlWji0Qio%`6*"0"W[J08kVl.%mdYks\F+'EJSB:de8,9sMWo22N6`,1V8K:b
+ 3HIBVJA>p_l5/<:p1Xm+i[oqhcmT0[H/NPES@SGb*0-kIKJsmgK2,O[U$gA<B:r=_*X`eki
+ DCT0<_VY<\E=egFdPq!d8@qtE6:4n,ZEmlu:!#lgK\6P_08!==&Ai^J'8pT'W6+$Y5Pr;#q
+ cY?o&[^4#nPh7IkBbWu2sA.<Lo&Ha5&oB&b;8&tT*p[A+SfB#YlIVj!fGNMTj`JaKYhLuak
+ "Mqkq6R0oBs2nj]5f)snNYl&mS\P."l_Ot*[Vsj+Dt!+"gG^ck0R$H,jn;D5XC#1Xp.XMSX
+ )5WOqC<P&hRn;3C)Ma0Sc&6>J+rBeD/6b(lGW3]\[,nF-7)&M\2dYenoAr^@tb-`-:WbdT,
+ Le=ATROlUTG=crqknVpT%Bahn:8B%%fj]rjm0_q*NQE+*XQX,R!pgqi5f=?rCjc$uO2skQV
+ q^6Obib;=4qFgkf>D;,_Z,fQ"(.rdPG#P$3T95pt!M4Se=:mIR4poB4Ad)B%o)a^1>h/L`e
+ 9da,hW`I_T2l=ad;78[^]HtTT@_U`h9Viu7j^X)%blPce(DdC+QC)IM83I1Jnp2@]'SiS_^
+ .l01D+u4,sZIu4Xk+tl:H3JZJqmiqYm-/"2$omBqY&nMb_bo![eZ:0fY*LoIO2ni[P*8BGh
+ md]\e2"B=3Vh^dXkFF9EmdiaiZdu8VO-H.PUsnG)]LI]H?+3(`&M[*5?mDtQCb^VL)Wis/5
+ :b6XR9a]b"D,,(G!s+j5";o,of-kOOQ%=$T9BR#ojhg;Nar<UW\tcDD#8&G"L8:WSCc0Et>
+ BU;OSAmk$o'CY9.5I`O4%uZ./E?X*`2_\P^nJNCR+hI-\X)%eSi?>.QaU81d31`1<t]>-tu
+ UTHHCD=_d`XWu'?*/D+$c\ghI]*-^Gu0pGq'5o*ZheQFQ^5rZSGF!=!-Mlu;ZU1$\4iG'N=
+ $OLDNP_bO9=m=;TNq-aM=g99ZVB0'UZu0a;J\:4d'?4sOF?#Z'4qd%g2itK(T3CSu[+N98V
+ X*GB95T05Q8`*mQ*+P21t'Z;'5=FJ[?B#p1^Zs7Tp+3ja$lN"b_e!EST)6Ii51es@g0uhUl
+ <($3:s])F*gXr^=X"sGOF,7(e-kPm8,M(HQT$YmKUdnq>oa44q'"Q:#4Z>KY<4sL_eXSOBM
+ j&8TV1_74rW/ZDY?HqsoL11MZKu+8f%+Y4^sR+'sJYm@\W2:T<f<q$rt;k.enl:.NY]IB!#
+ `P]R`?5aM*HL=UT*9a=S>:alu(YW3:TR>[T*YPS7bL;ii)l*^?GSM_]VpZfQ7*q6-6FR03+
+ Zb]Gr?j.K#[X0sVl9V.iF#7C?T?379P]X>tQ_chWBe^Z;DlUXY0Lf5RlU#>(FG65mPN#mr)
+ 3mXK2D1V#0I*<.f$pR6`AJsP]99j&bi:lHYS;1D`/oKjnE'lK],7&4!C-C2D4[EQ)(`2aag
+ M+\](tG)`fXXIdLpDp1P)7aD6E7k*@Xhn3@u-`-.,:a=lG+P3K'*!*%oQi:27u7m7EmgZ68
+ </Z'F6Y#<&/=-Ts?Fhf@'\#u1YT'9g6c'>Y_C;!J)hm6An*q;6;FPo(iFb=&4n2bSKK;j5]
+ d(lRS\9o>X.*>M!^$Zkp'_[fc.2f2o]3D#W@?'Oj:nnuhG%".mW55YlHT)_Y;^ptl?(_#[2
+ _!+,2&."<kJY0Wk<d1e'rmLq<%p;qMU0=q;=ZT(]RRAAPA3d'PeJlL@SWjq-=>hfc3W*hbr
+ qRQ\8+NPE:%a38HJ[N`i"Z6a5kc@nCBs'.!A6ckF!9Hm(L6$Q93cFe$dJp-@t%gX2l<EB8B
+ V3%';Pdi\kn;H;q$cV1.Y$makEK.<H(''5(@-5bb6oi9i\6Tj<aemk')^HjON_WmM=/1*F+
+ O)9d-0t$X/1elUh_u*/&lWie%$K@%Rt^-<3]h5`7dJ,cO5O$[72XZ'@b9G?,Dp=J!,K,O3A
+ (,o?<?*EtRQDjp-o'`obT5(H^a?r!/gKC]-lO@NLd\/l']nZFcT9)r<lKaZ?"GWJK&$[`T'
+ 7[G>Gc5l+5,dJ\Mp5=,o/DjD`De2DfiAGnIGH<j=3br*RjGp9fKq-rQ.d@-\Bnoaq\B2@E(
+ AQ3eC4WJpdP?BQ/R&ShAcN3_;H^;o&B6>00f';7MN=oCd^!^Y_lAZ&Z3*-k[e@B6UY!Vq3I
+ E4;\\1aU"CjcIj]rM,SF@?G@SYF)74nWnYgFc)W(nK`291^`46[4AgNF>k(2*']oRB\Ef(5
+ sH5,g4`h7(4CGto(#!aD!%=dDlW>7<m-(,F/U^r!ukBhhk*Pda[.SLr*h>nP\.H;2`'F4d9
+ *oRMu5^u'j=2$oc@+=C4ocQ*TF6nL>#=tYYI_4F'!dG7'HF.(`G/0.X3J<r)?ieom@bG%(e
+ 2tqE$`PrS88M,1q#2IG@RM2D/naT!Z/[0A[WPt?\`OQJ3J<&.-T7r&:a9c9pL[V$aG8]:05
+ u_K6.JW@]]hY0&!Oo@'SKJ6eS.NMmCY@%c!a?J:"V9gA>-tO'h\^+U,id[/0%j![="_1:/H
+ Y)5SDd\a,bhWJ'YOC"^UPNJ"Q&RmE^J7W>8KDBJQ`NhZn/S0SBMV*EuA.f$nV_L#^[I*d#h
+ N.V^+:EJ<M#/8^mCmRaTts8`&)Di5)8J2-L.Lj?'mdrC'K"[D6bgrn"/q>#7I3?-=(r#1A)
+ .F:UGp8M+;En;n)?+b]R9ab#d\EL7EH#ad[3jKb/E-^V&+5e`F#n@V*;8UI)".&Q)n[V21h
+ D-C=\\^<;$BNhPS<2AX:Oi+rC\!(![>;D_5cbUsId)j-"EG,pq$e[_<7DSfYrQ/@nblT7O^
+ ;(%P$bWVLZnqnnI>`2!!A&(`L),QIBh-WA=uMV3eQ8@g:DG=``1::E/FI%s!UO<W/=P;Y"G
+ L[E,2b(mD$IMKCaTk'Lr?jP[CDW=3`+?e(0'^H\*T>njAM,G8gK?1GLF(3r9W^:#BRBqf8b
+ `Cp8pp"Mh%.*L*qE#Jd6DW91956EGgqQq!Vds4dN(ddmAfh8h3J.:rjE-S6W3H3jUm=k\P.
+ gomK!l])[*1l_J*<Doa7WN)d"rWStV1V'7L3WCU/<AT=V,Zq!lObR3^:/+%V0&_g._S\4n7
+ $gkp(.!IdN=:61s&[_ba%0&mNMO3,F*]e#;.QY7(ZXHuNk+qSW5<OMgSbn,6/Yt\O'6,T_j
+ Cf-dF318Q0.B=VHfV!:+KAA]8J`/rhoZQ@A&$lF,"%:*iBOkPe@-'1+r]1]&TpDGA*^r%[1
+ Yh'rc',Z9/CJj:!eKIs3e99k<p"8\ViPjae>4i7@bi<;VVL2`.5!fZ5/S9gbQ6uPA$)A(YT
+ ZJ-\l=<eh;po>MNA^SC%6cBfXLD.ba'Fn'72qKfg_,[tmd)K_F^>>4s-f>hI)+bmE9!QSKA
+ $^8_rb@F;8[$QdZK8C^&pjVBL0M`\S5%5oShB8\jNP;&RV.u[K&Q8ZT8oKJu<s(X+V==EPA
+ 6(A<e(K-0uOrN-H_H8@"CFBm<!h0jc`LSYb"RI3^_JsH(e.RONfdN^$&*QP9JD`h-B[7&rl
+ c]&uJ93/G4$<=R>5h6.ajr5kc\]_KgppZiUo9K+SeUobMi;^$]I+;g,m8Q-/J[$`4j:fnBd
+ YZlM`[)mTLn[M(iTMaMa<!2M$tuS31$Q)BJ;?QOQT%$Oql[aS2;!NnX\THX@+G9q:t5(QDE
+ AfDO@%0OgDPR-NQr!:FkG#s2.rMBd(fZa=I([]td3lL_Dn04WfPABaFjm#1[rB6OScmWsO-
+ `V1eldkF@?ud%9H3GuSF)R=rr$f1E2=KPY!$7]I5ZiI"Bg@V?;848dGH%qB6n)jX"cS32u$
+ j9fhVWB)3WQYV0((#cj]'l6PO@H[Yg8NZs-U_^M7IB*Ju*sl@lbRek?>K\o8U6_QPcA<)7\
+ pq<&#.kX>6@1]L3QcEkdre]O'C9!?T`]e&qb[_:kJf3:"_3ZfL(l6*8k\HM:CcZ2,'$Fh&A
+ m'h),=?<:2UP%-R)a`F!@i2+e1%YQu-t?=:8qNpfaU@TGHs?\+Sio%>.[hs'$t9_q;m@d)h
+ @1B1moK#_fP#:>gBfCFJWikW@PF>'P$>;%*@)3`"TM1o)F:]\BNpjM@bu2CD:m4Fp8YQ'@(
+ aWT\I[oB>P6Y530!:2Z`M,S]#PU/#YZ#`NjW:Qel$#]Xa4,VA4a7=uo37H)@ZhgX<^;*HK^
+ F[gb;+LI2":9Nqc_/mK\WitXN3[_`MRM6tom/eZEL6ED*\ssR1U4p"2S.kGO4c.PUq8!gFj
+ !!03o!5eDC&,(kegt01<F12;\_QMH$l`!hlZ#>0=RkolBHpAJ$Z'+q1:67*O^9Vlj*Mt`;@
+ K0Z-p5UH8VTt+R_f6T8Ps)Ag$G]jF(`ON1F4hcF!AZH2+cg7WC=$joJfDncK/gZAP^cUnaI
+ WE_L#@0Bf9mL#<LPN,.AsVVDK[7H$<uGp>rq@((3n`3$F$],3-f7E?\6fMK;SiKDjZ4QAYG
+ jEl#,%/?$&o'Y1/uQJR_jq!n#gV<NhV9BKal6@3NI61^\RMd)Ou(T0,)&jnQ+TtNiA_hnd2
+ 7S(^5U)#kaPG'9aAK$G2cj,%*>`2-d&"?\bUiJo\jq[K]'A/qmaUW^d*1@Vp:`(M%#sX@Xi
+ D5>d\J(\Q4J7=1d*@.:08Y9a[,A:scA>BY1>nd[QFI2K#\2mjTJ1Q0$F.sl7nRGJ`Q>?\6I
+ ^UZ'05L<qp'[Rr"#&6rX/e=!Rr<7E@2f]-ZEC>F;D?j:k?ubF<XosnXPE>(4><FdW(K[_:N
+ >4QkHb783hrcZ.QMrP*8f(U>`ae`!MkHbAndJ`eli$[1Kb(Hb"j<8-o5I[8fL#EcU@;h]&S
+ rB4oH(6FQ!6,_`Ld(3d\aqjXCF5&%jI-c4=V(B05*E>YA<+$'/gO$C'P<mJt685"bCZ[>W8
+ ,U`NZKHJ2tPdS"G%1,Tp7#U8%U-uD^n6\]o6a@K[\pRL0.#dP91,Z5/E+)aliMN>pV)e(_T
+ tQ8GH>kB)<Z"Ijq-5NL^"cMnnBZqnhuTAeS3]ftU3&(5:?Kih<kN\.p<nO=WF;j6@ujYCC#
+ 2l=fu`j.4usjdaOP;`&CaDYa8M)8fXaW#_N/aqq/Ph(eq,o-o&NJ]/Td/FRB\_!D0>jEXek
+ h$VK%OB_[irmCYG.W^G<3:H'E8]0?&blcQ1GjCb7U,BS!:DCb;m=79Yojd.'L#Vb\t:4'VB
+ q`n\f1r7Pe"QS5G?-s2]J>`]qG@HVChUh4lbs$VUO'1Kc?;G3XiZuWuO3Ee3-cU0Lqm&?cH
+ BUVaj:0R2mj_99@hS":1r;#s-bnkl`=d;!qC>Q&AMIgif']ps;&I-:>M`XSWD9T%59Yt,Z7
+ W\^$'8]Hu*)B*QMJKc>(",F)F"o7dHnFT!rhnpB)-V4',OMFuY#_F+do/3-?$#2[Xa_EUHM
+ ci!T=$p3n)(nKlKG`uV02gP]if'uk+j7:j^tSsR_:[@F@AZ0bF\:eXb@"c-J'o/m]8&hKX"
+ FFaIX*0:ASq;o8^Ce%?dO+!GT(_f,NlW=D7Rc[6/,+[K[sn.%2+`qV80rbo8TJ3o:&Z;>Bq
+ Ml07GbP7Ja!4QUF?XZLf;DGJoubbUL3ZRbUQk9U?$.pIE"i9#A6[iNd(_nMrkl==2('=hO&
+ 8``UJS%Ku3f7SCW^t&[(g#%-OjPOM!Q!!1B?s9-,-.Q.JMNuJ3]&jhCF[s?3G",YFm?gQ<(
+ *;-.A)!:"="dpt_;TG?(ARLWh;&S`5!4;hQds9FbXkS^cHBL_5:8ZYG0fHdQ@0_@S_@4R33
+ @136>'Ra+_9UnBi[4#-_5XY'6Fho>RCU.J`%eLM]g;nQY"\e_q6&!bB5a;E6nuucl,8OF#I
+ (*0cXn=Wp@X/ccJjDgX'p6c5kPU^emF</at.HORfup]CjUkS_H'a0:9(fDKb-a,sN+,Qfk5
+ HDcqM'@8GXDr8oU&HCeCCmiM4XZ-U?(GN=L`,aC$\6IaF1cuP*>l1lo@^bYeY>jH$:(A6YY
+ m?=N-4Uf60[3dTWSTn,$qBK6^(pOYrX&lF9F8HLC*.bTuZ`(Zjkb!A(Bl.Reg9u"Hb`osJZ
+ c_l\k9bp"B#OXF^%57Yn^k6b5JI"&oK:0aI-LbTC;IY"i-[@pqOGp(FJ:<9\<^n3/S>/Nbp
+ 9N+4P7FMMf&L;[d6[Gs,h(plqPTFeXsq0E&/Bn?o6#*k8Tl(g/o`'ig%\^SN?K2feYIh-qF
+ O@jQkF$s7ba):O@<J/Xi/o3k]QFrn>6b$^.:MG-&5QoAf013mdI(JH'jYrXO=g"57@=dug:
+ H(gQ-RbHTAl?kJKrU-p@Q@geeBSI`NE\/b5J>K29Fc61I,d<&uA,^kTSEL+f3#V-q(OdaPY
+ &PV#!9Q`id=jj%^\Fju%GQ7O*`JYOi;h:\NV"Np<gU/DhQE2W>OI]]]YV:9I`58=+"-nR9R
+ ZDX$=24^3*IFnO:DW0L"tl^';^((@!4WRGY(lH:PKu`c3r))l8.1kP2[=p=J#pWfaW%=g#P
+ 0P)VOO3L6JLp@>VO_OaBZp+7,<DLdS0E8W1)VR45.oG*kudnVMAG_YXaDn+N:=mIJXe?.TM
+ rsbXe<D*]0j4fttDGBc5lnl?62bm4:CuP]:R+P%T!A@no5e%\E\+C;RfDak1.+REKsRK_/h
+ <+gl]k'E5eagGfF.Q.(p^2(t:HE<M3%Sg6%n7a\^B)p`]XO1*V_2,^b:(r=YtQEE<t_;$:e
+ BN"5s'7]t+#IZ.T26&oC*??0`cCA3>r]PJbpn[,8U:KM[6/I=[EU.XS(/D.gSn*+hA`E:h5
+ CbtBJu_O0rA8IK%&7i$&@;XM"3YiXl-o*#n<g$u&0'IF-@u,%?o..LXF"t=Su"-%"drEf(s
+ h4Z9O_bJ;b&hdW\LlqV<a)ufJ&UBS9OapI?,I7Ie2]]iopebCL=c$Fo$3tg,12Hd1Hrk'2g
+ $,@f=>!S//[eAP.hAI=XIk]t\:YU5:PT9`]V#^o;%@2?qZbJ]9rk?XHH5[1)h9;#O$!-Wh?
+ I#oo?5G/F'\/QcER51BF%[+R*;dpc*FXKD1AVM5IIbuT;s9BSBP'8&k_@i+:Q^4,J7UIUA/
+ X0%(Ti"&1)p[6l9l)1)YZ=\?n3JREWKR'nVgoTX+qkd&k94Ut%GT#oXUn3EO]O'\%[YKIGB
+ qQUbe;&rsBd]I!I4G#5LZi9848@YB/@#12a5V7dZQYjQglmocU).OGj^C3-D6.?OruK9JK4
+ @KB)A.A`n1Q`TDns?p%On$8_P+=P)Ja9+EV.>gW)0X\"jNXA(HU,bMRuTqVbJ_3Rd?bUl9d
+ QC9P]YEIpMCCWht<AM4c"%do%:;(G,`<(KCE4grXkTbfNcKm[:/'8^+&FZa'm,\Se1?g?D9
+ bdi</'mUS0&dVu!69eS(A[^*QU^@'M"^1R93?\-5bhS":+ijmmW[Y7EGEATV[UZqu%X@"u`
+ @;N80-\F8-d?VGc#=I`-n`Fc(T)bn.,\Va7Xs.$Rr%8DD988XOPJs*jS]n_\@g6l#+qK<FC
+ MeQB9i&?T]tm5YI5P6/:*eG@ao'p=#Cc+-m!/?sj_*[nGbO9.]DL-R7h<q9WSd?cg;uNg*6
+ em4W4H58b>:)QJk_m&CmaI!R.!U,(hs8_4NMO'CT3A[T]N&`en)YcK'H_&:=-7$ktV_CR]c
+ 6<c5UC-BraCbV<MQgiCm+TLR58HA:XE+SFi\u`k-H_4FdA.F!!P5.VKL4M\j\]4Lfn+e?P!
+ K9<s`?SBWIB<8@khoPfh9oGBC:Zq/Pa,QZCh(Y*PYghs5n.cO32F2E"hBq>LU8\V)gN1DlY
+ ;U`Z[_j-tY85\u_V1n_k/BF6!VS;3dDmu<#ILISZMKcDT[.'BKTA722YNFon9pMP8amlMBM
+ @3G)hj,$<#1F4F8sQ15FJ'cD&!<l'_!cm??P8o7PiF$[XVYKJc*bpj1`b[I;.EPS^#8q8I6
+ H_i:Tlj&r7@Fis*<6##D>:J-k`pQE_+B]X-]NG=Xd90;REOs2aLWOecfc%$jR5-i/C>]"+D
+ $j`J$Ca0#pP)N#D%/)EM;@HCA5:>Uesp[YtLLEEh"\6ROhIYJ#>Z!k#=+fj61'9CR09dLt]
+ bP,dVG!bd*f@R6b_/H^G<<<&-D"AOcIPGQh3-Of'H#$Wb'<]a.9KL=:TkbN.!XGfJL?GCq@
+ U4l=los^dX>%$ZJZs8VMmsnSBMeT^E8H.@8-_F1g(pZ_S&jh4F/93M^9OjSd-_Ie.V9`=Ql
+ QW3[:=K>L(VZ3+@=0X9_HQFuGJJ-Ml<iq!SA=9?kCgS%__BV002fBFLCZJ]WY=&hg_`LO9B
+ 6qe4=t!/QLd3j=*\2.`[ct^Y*0D'Tfi`m0di9:-_!bN!h3<Q"?*O`kl_`)+bEm*lQTO@CgD
+ _$^hFB=-]/*#@G%(UIH\*K%5.g303%bY)'UrFa.-6T-^B--a@QA);mm@lSFhFIBj+p1,$W6
+ %4O/Z0,,D%i!1XQF[E*Ons(%obiD#1a-gU\(niVkC89Y-)PQ#bM<srhMOHsQ=3`/P.\<]0.
+ [L8>L,2W].=r>G(6I#*U9QSVAZF$8<'V7Q;YW3S?-b'r![8ISgGX*XPV2h2Pqe?u$[g5(+-
+ 9+4</[Q%^,:=m%n`;cNQ/i'BMSCEt<MC6kc@rBY$n^*W3nk6_T>D!"VMT&u6#%!U&jUO?S!
+ 39.E5#fl-cNB^TLlC<3)N'OCgE,<4J4d[e+/$f"[7e.\_+W$;N$X#?u4jdEmboHi_F`VJ0"
+ pB]Ytm*g>cVC$9CI!''Bn8\57>HChODu%&+MdS1?tMeNru83FuJT#Ypfi5eVDUcfbi*OV8D
+ M:;0UCqh6=Hr&<3s[5&?GJt>AKML>V2@R[]3&&7'lRM4X6(-5#slU=Bco!Li3AX,)(Ch"JF
+ [Y21p+>#q=^I0Ym&e27U"V7el&TWID-KS]3N_TSd`LY@+rM[$>=OhVI8pmTd-TOB3e()u:G
+ Hs@V_TbtH$Pq*GCM=3m)I9.M35i?djZ$,FcsBj$*r]e"`Bc'q1WguM<$\8nH8(T'f)f.m^6
+ UJ"0Pn*eF2AGtjZ=?AcsBk/#B[Hk34;A8Et'q]7^)DBQCt'LTEPkiL85UGUeTdCI^3c;.#d
+ g9kf"S(Q=<KU`eeL6>RM>HpM,PITOiqu\V`Cuc&%5i(Q,d[<S'kI6@3:/,2p:mQ53`KOf<^
+ [6T+e.kX6u/(O+l_EtYW2TtRa(Z1+B?[,cQP#]#8%FYTV1ma0=4LMX**k!Y)jFZ_%U3C-Ee
+ if:']-Nee+^U,9+\MCS>"T_mW3%S@Yi,)a6E'dgb#p_K-g!F&.V-*MRCD#q27rdtUWM!:r<
+ 7DI5kd?4.fe'Y]Sen!VM`VRU:/j?_='!EKs!994ak&9b"1m>C<nrNXd0XVaU*T-5(O%WZRh
+ HYc/c6F5156jn0bIP<_HIai=p>QR3DM+n_H>H_N#S:\]i%JB;A%=icEW0Gb91P6`P[2>Q5E
+ :'*p4$!KgcS$dR3mL_G1;LBWnM#EDD0'k?:8F>:RLt&=89W#-7Bd87#uUG7lGk[/\i-1/tT
+ UmJM1*lMB5]6=#t@**P1'dS^Zn?(dL<6)*J!(O(U!)#ND@9ac_bjC`<jKl%mi-?`,eC"Y3E
+ H_2.P-&f#2[Os&.7Dt%qclP1b@\LK@8lk_*6^tr)iECo[M1!Wrm194g,c4"!>*lsXp<L=4D
+ .$.MW+O-Ws8=W'k2KQjj':6JW2:>u:8EU;kX:/a0QoE;5p^<GaB/[]O`4&`6jmg:cE"rkDP
+ @g/TtQ6q'g.VPRO'K^(XiFiQUBsF)Gs/`'N$FaZJSQbd(WE+if4A;aAC-E(&gkSEgV)H"Ih
+ e,MJDDUn6`a?'XI7Pg.QTE9L=);Pr((3:?65mj(iL(grmB!L6fi1#lehc#\29A%X)lJkQFV
+ ;8LJp:BlU;V)+Ce$T1RP<?4bHiC$GYo,$CVQi&++Mr7BuMFu$/9fIncniP-mC#>V!^()FmK
+ gdJ5dWU32-d[USsZ*\Yfr7<?ZTtPJ>>RT9/m:rB=J#/ONnGdhWD#52L9@Hs+-_a^V?g5a@"
+ SCZ,-QLQk;G5`hJ"@El@?I5%OM@,$"a#NrBMn2(DRlHh&lW=\a4j;**=GZmS>j*[#OR?VeL
+ YE<i3[1'SXJCE)R_^dhp\6BkPm"RYUu*C"h$$j6]9_5),cta;Uc_d\fPBqrtS0(S-XSDaM0
+ [Z(#$h_X<kGZMmCWba:7NjSP3X0P"tkO'FOln@cp/S=qW)rl1<W'gsDYU"?%WP(b<u?)9.-
+ %Oq[i,Qq+AL[:%tn.W;OC(`\P<[6-%K?[PU:_%R^#6D6O]HWN5i,`E0!qk[hn'6,bX$#sED
+ E#955M6-9bZlFr<e^B4o,)Vr4&.)k*AB0CumNgW15l\A)c&s".RSi"q''`pYnPmngC^2t('
+ PUi`L%Z:f(O,Af@PWo0c]Y4Q-TQVa_h_fs#H(!G[D[Wb"MU2J3[^ZkM%"EE8#8i;3>"5&Jn
+ ']hs!:Od(jE;g%Ws*o$Z')O>!g#uGYjSPW^V(r-SMhST#a`IEJJ@*qQ4;!'/A).\"uTUAas
+ sCMeM'DU-D;/,,)\D-Y+&Ui$J,f8=1n8N@hdjO^[^X,$YLl?"A`jMO_a1K_Eb!);;--8NeH
+ <H_o@/[Q3da&]Vc&giBcpJF<#)A9d\]G?j*SLHL]mW[7>.Lp;uuS;:l9>EY:hToufg%E;__
+ r;!&"$Ur=&W]Q4L@o^%7BlR]$q-'7S/_HXCTi4C%;([$_HSH'FEg_j!X'C5&Sm:%gF=$=E#
+ Y-<@V^AuO1-#R&"`u>@plB3A0[B0jVTHJpQ2=3rJqpUO(O*qS<]*ODV'7:%U6B"4LD^$^Zl
+ Fr*[8ESD'NFs^RRu.SdN9J"#4%cn>hgJiqnZ;'Q\mcHBNJB3P6"P(lW%8!CG7^b$Vj*AUI!
+ g.+0^4rf]r^`SA7`YO>#8n$LMCd)<a9qZ=K6-F!>9N[tke^cFoQU%t4ccHQkb@+8EYcXEOo
+ gNhF0'/?jGcah!t[g`K3W:@KsgPo$%%LcHWrfKiKbQAT(:l\$i@1*YATbG?LE).[\U0-4bF
+ +II=9L2eTsp>^1SO3>RkRV)j@fm]B.okpZ&o2OioM9MTE:"T.Y0Cge>6i3QY1<t`d(i)pS1
+ 5TBp,MD];-f[&/kQPH*FpFDaK[JQ6=V"F_T;5XQ9el+(`jhST\/]"e/'t)6U<s#QK*Xfb7Y
+ ^V(W?fKo3Q^f/$jrK(lXrkKFCW;"0r*DK8^@1=3Vl19L3j"rNs='/L!o:bd&KHIHNHml:Gd
+ h+I%$gJR'lW5F3Ut'B.W`WFRhi>O=G6%5HHF[mcBHK@i=ED(?/_di2E"-UcZWI@$RWeM&3#
+ 4S$KnpP4*9JgN@UsXU`rLbKjGBbsWQ_fttkXIOLKj/JDu7J^2I>>N8:U"p($9&QUs_[^t..
+ rTX$%M>"MPNr";XXbgYYmNrjT`p+%gd#"'D/No%$m>#RNg\L;3ea[#bqcK?_>#TfNqVDW$D
+ n:[aRJI%BFYB3[3)arqdnqaI;3$l<G,%R];Dd12Bjn^sA/ID893_kk>=*_W\1f@J]&":$_0
+ D7HLSi=n_?!'LaUl(S.3i\"O0frk_K*#PNKKO=NEP\njK0@N81-d=7*^Y=<Zdg#RDbZSiFm
+ +>:XulnX_qpMiFo$$B;fEP0[`RCKSAj'(-:?Xo[RbPFiW,i(Z]++D-Y[p=&"FS_kDm+mZ$O
+ Lol\g>[VUa+iVKc!bk3hf[7ATN^,+C<c:$u&;lt!%>2NF!l+!sr4rh22MrsE\](u'%>EAc/
+ 83.V8Ks\L<oB+`4V`/O#5MpSF^e];5PGZ<P"T")s_kQAK1+?gi>)q0GA"9V`fljp41Fc!tm
+ +]/Dm[`*.*^B(Aor=pfLNG:F$;I8P^3pCXqqXL*>eSp=k"J.apI3%O$5UmU'f(&$H:gNLbg
+ [NPnXJ.64`oWFRStU%huET<P:(<'5u%X\IfW^N=%E_3oao?*(GG4Up#hsVJ%sBSq;At/CJG
+ kMg:VFONboT$c8M4Th::'Ko]]<L1Cslh[g)\Q-`b#J'<`O/GOOBS0[H>"p%\(;5O[BQq!d7
+ ;7uo\P4F$\mATr>W3R],Z'`nIl5SDEPPQUehfZ_,c#Bht8#>:@RTna"^BZpL/_.TEj40lpO
+ M_)0T,)\"Xa<HNnZMM!.+/n.L,Q~>
+Q
+0 g
+BT
+22 0 0 22 297.143848 542.838269 Tm
+/f-0-0 1 Tf
+(Is it)Tj
+-1.246094 -1 Td
+(de)Tj
+/f-0-1 1 Tf
+<01>Tj
+/f-0-0 1 Tf
+[(ned?)]TJ
+ET
+Q q
+36 428.798 206.23 -67.715 re W n
+q
+36 429.4 207 -69 re W n
+[ 0.799336 0 0 0.796639 36 361.085705 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 258 def
+  /Height 85 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 85 ] def
+end
+image
+Gb"/gqchP4q1/Ks<JH5q3#Y-m8I-J)KFe1h#QZ*=6APn<;3Xuo&>_f]Ob8OK;%Q#Z/PrQ>`&
+ UXn6rX:Y"[uCt1;D>L.^b3ib4p:nB5aI!\QdHWpa"sLYPUhn,a[B^q`M%^dlVL*^7CXY(`a
+ WFp$1)&7uqPq[Pg'%T)61/k0TgU_\Iq;m]3GA>BOoBc^W't2+AN-J,UgNb4eq:m&`9ii+RE
+ 3g#Fqa9atC!SHArr8BC>knMbCC+@W1Wos>AL)]S\JgMcs24_hNR[H:<]Nl%n9CK@Qn;FL]l
+ aF2!",d)Ua:4@)@rZ\6dmTRF;o+TL!?iKqQP^#ui\3'Qo*G$EBRHL;0DfLGXablppX:8t=m
+ jkQE4+4$5o>QV(_o'Aq%:NuYT].$J]8&$=K&#_Rp_Bd/i\mu90$%@s0$GdubW2mZ]4sk0V`
+ XL1m)[.R#R@>_"@JUmDou0&*TH$kkHrUacVp)-;+bEqroW@?a,_<X08-fu#>G5`^kq?VFmG
+ 2g<lX95Y2*<DI:Q.1B-fW7Qg^q=[-,;7Fjn`dLs%Y%(_!\IqU"ZVMmq3$CcbKlE+I]mUti6
+ 'UA1R9>\g>Yf-Y*DGY-#[QBp[L_*PH59GpKJ"mD-TT058clLT[^j[jGHgG`uJfU;KeJXrVt
+ km=&H'W!W:2L*Cp`Qkm=HdY+5]f(1`P3Q\q[_rI".83QI&=Ylmb))6n`<7FkHGoUeUO<o3]
+ /qDdJj=NM4"Fe^__N\cXK&;%Vru@Pck(LJBVPVc#hn%fG4*TK(+hiZ*%ij+Z%$tFLei>]r(
+ ;*Ga/K0sonOTY5Q%>Ia?WZ]@M"/8'I;5hL84^,7saL%]$;?ZXj0KJnWLMg]^0Ljf^is=kIB
+ 1s9M8-p:fmC-@"@_RV?Xm*^A@,(IJoV1,\L=bH-t4!)qW((M]7`D]lg@75st=lmCG74^\X[
+ >o@^4Ddi0KlY77L,np`S^:%Z?9)b1QP]$-;e^@+F7XQTTE?DXoiiY^!n#`lAdS3QYOO)VT"
+ [@cnrCZ.7F_D%Gui#u.%G<EOm4Ylgo+M<=*^:qpoX2>&<Ke1ePF^^M.Zo^(Xj%S!)f?_7MC
+ X@4tNd=E(Np=X\_"J6.NqIk9=mrD\FCn):SW7hVZ]3^R51`#&Htg"/RH:T,<W!k1fGU9fjj
+ "W^%b8VF6Gg,GZ-7'DIj&uCI?KoGEk-2Rji`L;#m/-JqP_fhdAKd4<`E$$G^=W*(l8iUOkt
+ \uPNBQmHD:Ar(AR;]^^*eELCZR5IXVMH=.u=lH'PU-cHPjT`B'D?@2hjA-Cu2uY.9*.dsT-
+ ?L^P$a"p^b4]+gs\1Aq"ArLP(<>4(Efn)_?FObsbR4[(Aeb7&Jl.pW,r'(oQ*i:E/XroKK4
+ fp)`f1W2*rTB]p%/E)sX>#BOqPfSB*j2[/h%M"MXN"B71nF2'WpPQCro5\A7q2C-Kp)?uZ<
+ 4O-rA,cHM>Bj=Ae9Bk-bKaIlamT7J_a$6K$$d/%IpU5JP0m=AQj9jS]\')J\qu'9OXe/UVP
+ [s5@"@_RL5(Gs\:&^:DQ_'K/TYAL`1.OP0NLa!kV^+U_1[G\5Q'2-0XMYm18-oGSpUT8onP
+ 1belSGRl6VKM9TM[_i'@Qh,XZ>KS;DtEa`hNFD)&+a3?qg?*Qk-Ld8IoU3h&u54GC1C<IK:
+ DBT4CJK%E@Wh&RM)H+@Ah-E9>mao*X/ots4!q,1Dp;VS[k^@;"q@6b:2&tqSl%<Ark%*bKm
+ K)$"]Kj^cDF0NZ_MfQ=X#_cahYgXWD4$6ik3Mp2%P+\Ym7)gsD0MDTbo)cnV'l(/M.`gM3K
+ duS5?F\L;Sa>OP@Za*AN.,U])n((1jYUXGJ;[%0(^r"4E&/3^6_P1bDfgY?VEoRupTt)k/%
+ T"`"T_FMKjl3AFEiq`4f;b+OjKit<'Rgr2q,^aatQ6M>cHfl(/Iu(&ogrto2iP-WFb^+d;1
+ 4q5uS+qNJAjWAd#J8rc<94i/Rkb0L*o)L7&6i6N9g4Uf$NC+Z.="U^Ya>aEIL!)I>cV/)Qg
+ ;,I$gH1\PG*BEcT7mEdCTFL0]acY/Bu5b8KCY(l94E&AV=-\&A?IjNlK_L7@UHG_Jdi1Aq8
+ l']1];%%%]T^CsE$qc5Xg$qk;]V[)PTp-T[=b.+<P`uMI!uRT6*%:<-9<7#@4C!epRgRCSR
+ .C9nXJ[]k1C`b&IMC;KS]M6TmG$f7:aUd!k<Gm8Y!d9<lUV36I]21N"LLm8M^oq+./i/?q#
+ =\OBZ:eN-DVTW?i3_"E<Z1BksjnR5LFs$Xrp<uKIak;c\2>.!o8WRU\'Ign/k`)bE-V+Idt
+ __isKlAdZ)[.hU?sZJZ_;M;>LG>ro4?-#L\U[0*q1l=.fq_DNoT9\Gs&?m(XU8-3&+qJk-L
+ :B3kW'7d1^mocI7crRZ%$^jfSip0VI#1&q9eJi[6ZXl/1g4g'<WU\'H^p)d@drRWJhnK1h_
+ rRVWPoH..br?iW6rPoX\s0;U6!\?S0+'4!ka8Y*+YlE@*>QOO?qi<8CraYtJ"k\=k5HY"`O
+ 8[*6@/mM3\,u"]p)d@drQ"ot$F'Q_Ip<$J+8\:G.j/+F]n:E.B6+61h?6nF\k[PVl'C<9#c
+ rPuSb*E?rPTHK@g/tbhl?h,Fj`?B2\T7X?j3@lUj%pg,d)[5$:rc?mi^FU>QI\:ORA8q6Fq
+ r^!hq.eh'IK&F9?Z:T19'\];1LLm[ij>mhLrPP!24DFh3>,<^=5hq?Z?"kpH7/_;0(o-!Mb
+ 1K65Ra)*P!m71$H?i/99o!VRU:J1JG7isK`/fRI-,XoS>`)_5T\`t`"^E<WiRlp%WQ=+L7i
+ 'kf(1<l0hMp^OA+q`js-aIfQ,AL1SY_Y#VH#_VR7mmEJ5gf%SdVFLYmU!Ohfc,"A]q[1&1j
+ ]s%5!nCfbX50lNq(p`630</,k@1-1,r@(/=pWmnd>W^W&7uY?$B2F'UX0F$S&'%i(f'lnW<
+ bCDr\9\i'ZDMknI!2EbQ&I1;@e+R6+j6eZ&INX`IU]a35,e>US0sSQ\43#$=Rs.qI8$+Xso
+ <15man%CY#2;E]EIpC*@EQJ!7`2+3D\"VT/t@Id@rPTHJTV#N&S)Vh_l9N0A3^/@*n\UGo/
+ Shkds#@3qFE6%'UJ3_0ncRL#jG>I+<O4(2`OemN0W6^&M8#JaaSCj1GkH%QFYZRT"9KGNgJ
+ WBe<SEODHQ]7Qci>d$S>@]$]kKb<@eMKUo$nYVjX1B0#T!V5#3m0s<6iMZlSH>>DtoRs4DB
+ ?j('R!7Vm'M_<[QisGETi_<J%ZniH+31>jAUNiYXl>g@R785U`W@Z#KpT$DXGlWUcpnP[Ib
+ iK+\LTmo1#H<9WIPlS\o=X$=bbS?;U/s6@f7a0#?ag+<<,Gh-ujqCDK&D\Po'oq+J$Z.TGB
+ ed'5ViB%*kmV:3.\%?N<5XBGo#OnR`[GBgrSu7NnA?g8ZW><%p'igu$jjZ=hJr=%>agMN=<
+ ^T=n6dSQUQ[Z:ISLVdT5:ErMHEJIF/AnR)_H[\+h7+<Q4Z#c&,s.Yk2>/=lZ4!iIi/FY&ob
+ <C2TY:h;1&O+e8KD4\G/TuturVP[s5@"@_R`lH)jp@hWh<egI,m>U4aR?gaRV2T,_i_e/ne
+ nT[q$3<kS03</nOM^tr2*=Du5EuHk(^r^+CS^gu)W!DEgrCp*2ksJ&K:1p-Sf._E`]OjNLh
+ CV@[PWjO%6ALgpu()gq"QhR'o\-34W>4t;-b1Y&]V,R3*@1l=QU6nO[%#;MQ[<er>r<aSQ.
+ GK7'^]"ES=n^S["\;%#,md:.VD9-ruOhF]-=@-td@_dS`NbkT6$Fk.*+;#d!4BRXX29YY:"
+ 8^/.o*lKbW$-70"i"lnWM^Ne.Rku)+sR_Y6/U`-bi:#$PRH7Y_^&6+$lJr=2pVtCgD>*4cH
+ Q8)#1).eU(%#,o&2,Y14OSn_jM06D^HBl9NJJ)A9F.jI(RSU1GS&6p;n8dW-ceHruj#VM.^
+ 3T=)^^=K?^PU=di'C/">-/;*n6fBq=B#AM\riJAZ+J7coK8I]WCf?37UR8b0LnPW#VD6nek
+ %%oL*20#81LDN&hM$oj*q'L"DoA^$1KJTl)#Q,D5e,@5rCNb:\oCX#^mC\*R+\3A-=JQB\&
+ hri9ng#RMshIc>g4[lY9qrAjc*mTqFoeN+M"p0p-OU_-C_'%tc#<,aFm0K&fF?@4B)".He-
+ IY-ZY`Ha@'59]r&bJX7=*F7t?SbDe0H5:?/%n@&bOa1d$$]!&:R[2'i#]@`NgCM@<Pq1)sm
+ i&Lb'6FrkHBscOD(a3=UGdC)>(_!)\WK::%a)!.j\rhMTa>5bc;a7L_c=&:Y71#b9-_@9=I
+ F@";4?Q=43qSIV]R9O\X/cnfOI<O881JdkgMdsrg05Kd/I\03)`Ut<3miF+TMo)4(_"g=.7
+ c$6_[pP%ZU2ePZHWf?IU\(d6,$Zp1/h$OGItJLU;Xd(s.t=^KlHd(pP$1WCA!UGjM^9O+N4
+ t5TU>3.cBYt],VEnd(C$W<OBPO`#GdcK.lU;kN:,Y,Q/\"7[:LY2/iT<hlg7.,b1&&>V$a(
+ d5_EZ`2&^l9XK/Z@IJ'#g[7@:?.b)(S(DIR"cHcA6'8+[RaK]"SH+OCj9%CPSWlgEPkTPIG
+ !"onr6>-^>Bc$W,+cMGAU)'=bIm3A`QOit>+5ZDQ\o@h)R2NRt3r88fUK8qn%nVTT*uc/g>
+ (k`UJ\M9]9O7G~>
+Q
+0 g
+BT
+22 0 0 22 88.727771 400.323962 Tm
+/f-0-0 1 Tf
+[(Compar)19(e)]TJ
+-1.365234 -1 Td
+[(script )-3(vs. code)]TJ
+ET
+Q q
+365.602 426.4 250.668 -62.098 re W n
+q
+365 426.4 252 -63 re W n
+[ 0.798306 0 0 0.796111 365.6 364.303344 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 314 def
+  /Height 78 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 78 ] def
+end
+image
+Gb"0Tq,>adrkS&RTSjQ+_%f9B8IR<i7nA/LT/hE5_PK'j`e[fL>/6%r.4S4-Bgkl/.hiMoBL
+ P3T7B,kNWoDF.eT(C?:)A#Oj#C>"]%tuP$#=2Jqq]rVD9XH#jSbLepldN0351u0^#'4us8D
+ QLO$A*nrV,2tpYG&sk`nf-%X3$%2K#^)^UBrVCgN3-0JD`46i&kK^!Vor:S27GWq>Re,X\?
+ DIWKgX')('Y-2qNpWoT\WPWXR>=cdJSjlI6m^/M\GY\N"Z`k!c!g\21b]Qio%]dHUI]Qiu+
+ ji`u=R9pQ]Y=`qPC?k?La'[Z6FnkI"RLO%*MAIqfb:>Fd<gFN'.5c#n0DV8MC%]W3D,mVkb
+ V!a9rE`W(^*uR]e<mWt>GI%=`@Ae]JT$@#UP`*@$KfmhDX'E+kk<*=`5Dd^D1pD"P:G:d.+
+ NtI>0>$TRI]oL^UI`pAOXN!F_t?`3uU$Ghc\FY<84gep2JL3m\]@gB"tcLchX0drCo._nit
+ f6?"#VqbiK1[kjdX&pI^blgt.F8S_:5J%MjI4g?HqU5JQscf-o1DUASJAiPm`*G19L!eo*R
+ Q]5E="Dph*.8<P4@ZP/X;,V7A3/@IUG>%sHAWPYpl@S.-:AHbZ!$WFnM<2%uB!LZdcH&7F&
+ 3-gNF3^tIeU,^7@6?MQVIcSkh5Q'L)e#-51&'ra_cG4)=p9.d!I^E"eZ*Ih?h8YcJeOFCtO
+ Zp<me&oLeO,#pTH0N]DCS*J6H)18u;%0dDB[/8TmJ3KOER4LCmq&Q,$=SO>)^4be0^0#"mp
+ ZtSeQ$B[SN8J`2J2(DMEYg%Z/31Kg")IhdEKp-Br\.=[5:)m7eTF@g;2'?f8d:'kjS;q:tO
+ 0Sh=nO*%Q@As2QRg5r9p32Z1<l8qf0RoFloIi2eo"ZN7@^i=-2'i.unOOIUJ.LcgojsV=Sk
+ qj]<1m/P_3rOo'oS]`NRp>drC&:MQaZV7jS<mbQXDSisDlX_=t7:/5-1I^PlC<\=uK0.H[p
+ HDNe\\>*rt(Pd1k5LVJIEdI*D`fk1sD$;XU1M&/+6*4:@HZOe$[d5-\EM3>U]@Uj)ghi-2U
+ l&qfrp(2B/##$-Ec7N$1R:NAkB\P$$n7+WU,g36`Fupp%@p#V=R@g?dkUX7Ku'$)913#STg
+ >0ONEr'GFQ(U75G%1mYKt)/qZ'Cl*Wu<PSdiMT':c(Re%\0JAnsK9akD'AmGH"rXR/E@[2i
+ WS&'*%h<RA/Ii<DYfJS\uQSDQj4'F&o]$E-gNP]3d0#fiK/Rh`_I/7*#Vmd:u8+.o!jZ<FB
+ oi&s*rjNO%+jbjrF]kE,rjKqb2VNM+r9q*UAar<Fb!FAme:%3cWRsT%\I^LACD^oC*//&2f
+ k0oT3WgrD;ml"D6l^"SE3I%c<Ci%U9=4`jD^]!k':J\HF_)iX693.cB2,(7"Ub@Pp08]0;.
+ +MM[2=P*GcemTT^V39(r0(an,B.)/&!aDP3W*JH]-<E#-)S`RW8UubJ2]pTiM&u$6!)Zn%j
+ +p@l8nP69Bc93jN1nW3GD_&2)A"!)&5u>RueH1=<$?`?j_8RGFu`ZO2/[D\5N]89AoXsf8<
+ /al>lI+nh)@s?:H9ZbM_A8(g7.,QU?*P</-AJ$@3,Nc1*?l?BYPq&T_V@+.A!ONK"?\Bkb5
+ ,p\+4Ac`L@9UISfANdXqf0:hRnOqA:j*?eUN'N?4HfTO;oba62;>l^5LIP%'I6!kCtc@e",
+ E8D`IAiZB&R>tjo!<!*]WJ=t$d&)Aod&A=c9Cqqj[-V6*,?79oiR5TqFHIqN'<,Y]gdXi:]
+ uQ2pASD"T.-]]RH')!H$n_nWCf%Gj0+^FI#mST2A0)`<_Jp<\d_H_0S56s@h4W=/SQ/%l)G
+ [<k82<"l_o?)/?Z[Z&YYW:g;_n#4H9@6,l:26UVJ28\p%:11e[ckj,@XKtjE#Ad`='PnkaM
+ ^'TA7X,6?<Y/RGiB;FK=?,V:1>OE&eAKB`F92T.Xj:!btaD4_eYkJJoD*L`[B>%d5keO\Bk
+ >NT3n\r+Jt]=2J_fH;X?DinT@#H"$&K-)4Vd\RQ7>ZXLGrhFoo&Jo_hI:4]H[E$HBE:g`MS
+ felF/.+g^8Hl<5oA[#A/X]]ne^fqJsb)s7_bb80SV:\bLV3-_f<6j*-0sm[=]GXIU6a$]K/
+ 6hdn3fII,kGHQ(TjY("_AB2uYD)ppYY>=;-'*t;T,W$?Q<KJg[FW#UeN.)me(N2/er-^IlY
+ Xk.gsS3?S!N_n.2<&oE%hd1:Y5GU<,37f>r6>g/_)=[cu?,>^E>W\>UurlqcST-K58H6@_W
+ ')e_jVNXk:rD]GFg'Xqgh:KU6-UaBiXT#-QM%&`/?2^pRW0MsrcD%B^GP6%jGjRrGKs9d..
+ T>D?q4C^8oZfJkskp%0G5/*RWe!\)@CMWXiD#1n_EJFE\4j@1%m9u45H"<`*e8Rs)`)Qjg]
+ 5/N)I6tSL![:7]Wq!aKg5Bi!#`N4pci?sulT.6uYZOXj-T1&ZqVmodO$4%`&')<'/i``TGM
+ X]RPOe;"Tf8AN^$24fh`O00b;mLM&CW17j,YAg'MW%<%d4)45_juse;d:i-;^G)7\5j#^8s
+ W4lXVgJj/=kd(1#+47;T6%Q\5Q:IMJL1MVe#&ASndZ=_R8AumC?/#.u$,39;f:#%&Z^`:3!
+ BQmZ^,=P-*=-:_BiFGNt!TP-`^ZV#],)4*A&.ENK_/nB!$o_B[%-3[V]kT3MZJ'A)N:#bQK
+ b+ZrG'X(*?$o#ZUT,]TprMt#[Q(W(O;[5oYO-_FWL0@:AHD:[`NEMrNf.B_5#&3fpN6?mng
+ =DPYXf1Pu%P7-@*r?epi,=elT8k*SGk:;`5G3bjJ"FUL<<P`qi>Y]k9Q=*3&`_@KI)K)@5e
+ TFNbBYoN]e%9=D*,LnVC<<tgGgsO0N+V0Bh%OV%<hVIsTTj&Dqp1W+(+U6H>4tM'>hGm.*Y
+ \/_i4'->=OueLbD*^u!3W/-Y5sVDWM.-L7MDqUEuI$3JkomL<X';u7jd2-#2Ye^<gMB$Nb]
+ <9(1a9J]NioP72^.GS.O9"&4WF`IDmUb9lY,k4ri+j@28E<rZOXpUVa6@];3DPcUA<-Tp9r
+ \1?#-1E%D<aQ*;tSb(S[5$T`F#Z:LiY8rr"16>`CHL%Fs=:MQVgT.]la%.Z90Gh+1HcK*:H
+ TemVOiaGUaZmS,JCAL!s*>6YnfW>0+p3P(#cYf8Y9K5Z;dl;"HJP%B(/%fTW2etFM8u>ogO
+ 6'28X`M2?8OV1QolrQ)b"2p!V?Q`3"5Q1tAKKBCrcaJ1b%7e#(d8@Z*MLgm%f7HD,MF'iUG
+ 0ol5)GYun=B.7T.d=5_#'ijRfrmsr;'rIOb08Ad\F=:&/JQinBaQQ)B6-t;JTXsnV)8Ar]]
+ rkM-kkQ7lAoA+EfCG@lCC@6eQN%RflP;L6WtX]`^M)K[#(P"UW1&H\5qB3WR_9^fh&G&H8M
+ ^s(*8OJ<$rZQC/QQT#bm\oqb3,./k8eSN<XEV=FQ`He,:k`JYOrP>BJq4]P[m=?=K.k3!K$
+ B>jAseU2[OYU<VX*Er.Q3P:-$r4`pPTNI#1n`\g=X"_amU%'`Mrp="M\64>[4eh,h-aJUE%
+ %WK_A@p!4.0<<.3=KYW3iTHlD/=%<R^KkWq=<e2jR@j2)cj-PS]g-BSV)=F'PqNC+%7iY/l
+ aS``\R:'ff]PrV0VuC7_q$;Jl._NbUe-p@<Q;-,^a8<grU@;bN&>0n^(==MeA</0lj)XnJl
+ 9Lo50?YC`_EShiD3ic0X]Z7^\t=B?aU--RWihr,UQ#c*<BS51E^J+1Ddk?,:PM(M\SaD@U9
+ [MI^O[B/Q^BHW)qq3mIa.muW+pR=UE-Fp8D!Vk1@na4[TVe0VHQ`A6=N9W+?#V^pE&'!KtT
+ G:+GSQ;YRO/L``/\p&OLHtmE=3jli*X6YBCh]+c20gA;a@(N\D:(hJK0T.RTFbsY@U*FZDe
+ /b*;d@Mp!A!SR3'p6sG@@2JBGbnB]/.Q0W69L6YmQ0>!<`LhZK=kh'h46RU\,<leZ&4Y>qO
+ 3P/)c*(i7JkB![A$\#A7FQXi';G8)J,"pmG['f2G<+"$1OY1]P!"&Q>A>6<@a`;2`HQKZXu
+ `_beC`YD4T<B<TpS#:_S+RFB8o`3MW]+noA0fhsto5$M=)92]@%S],s4]J2WtK;Osd%4jT]
+ _]79;+_2]#s_M*":f@Rp.jm'eY6qc)WR-bg[7o?R_,IisTMmtbaB")5Uc$=sq-.LO8k2R*4
+ m5!;RG:`Sp50co4%O4o=db)(sg9iHp$>Iapn5$l(IPO$2mE1^fk2la*r"uu3j$hq:^!3B7n
+ `Xlt4e74QAu!tDq,$..+,8H%bE/K57l)glFQV'0T&V_e9lomuU^$\mU/YoC2P;#Tkih6S@^
+ UZe1Vlg[9T7c:dFks@AU/9u:7WLD#B1MH?T4Yh<T)g[AN3=#<"*gVcMe5b&VGu'J$,t&3cM
+ )C6HomtN?<!V*#q5C>5?27ItC*24VR2<gUI&TIbrqiCNJ$pOsQ"oE\llkUnk&$ZICW*Gbn`
+ #@J2<[M5G]Ik0oK6FX[]Xo?mQ;hn&>kG8E;icD54R1[r-g(;1$#+4TY2_1A3GY5N3S9hc)<
+ cAt.W5-D**0`*aal8)r-\ZZHBJG.UViSb"P*fQ/@UBC"(Z;po7<mcl0~>
+Q
+0 g
+BT
+22 0 0 22 392.355518 400.130603 Tm
+/f-0-0 1 Tf
+[(R)44(ewrite/r)18(ecompile)]TJ
+3.138672 -1 Td
+[(script)]TJ
+ET
+Q q
+352 154.4 278.457 -71.371 re W n
+q
+352 154.4 279 -72 re W n
+[ 0.797873 0 0 0.793023 352 83.027923 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 349 def
+  /Height 90 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 90 ] def
+end
+image
+Gb"0WHVi1(^;ob.cYf(B'(-or,_Q.(KFgJ+J:Jnu,_U+KJKc9^+H)RYFg1OF[8[k$+sJL='Y
+ Js@B9`fP?E1.#Lg,r#0Qo"&AJhMXD67q$Nq5D08D!C5FUq[G(Wc>00E6,&'0gE--TD4D>Bl
+ `&HhR*rdmoH?rU@]8[r1$5HM)#S=4b9SQJK1=lftoqhHXAa;-$h&=[RXTgpjJfN'^`-DFE!
+ S/M0Dd='\j->?st#;cQh(=]np,Zald'r^^g?GB`ehCY*I]^4#bDh8bQu%hB27)8;(f^RaP5
+ '*\[H^]!l\[\H@7r'+KW;;qF;(X/;4SsD2j0fE@9d41Ed)Pon<To5H=12URc4/Ri?ZO#M5n
+ (Kl')IpWO-EsGjPG4t.`^EPK.]:5NU1:T.BrQpm\_6:M0E8\fY5Q:qRl>9B\T>fmb4'6.+\
+ h1dlT9=Y*!sKFq1$]89V7Z8]m*l"W[/ag>Pd=Tjbl(!/1N!t'Wj%faJ9LnoPZl79CY('G0#
+ J?0:nMq@Yb<`(NMNVZ"RmbDV^2H/UR4u\T27pBS_nhZq%-s@*A[t0r,-:ekf7BS3&fR6!hj
+ b`?1DI>.1tPD124mT3%=8<GcF)ZE\CBadt(1qmMbHeJ,bjj-EK]_X?]3@q"!O[:>o(C<]lU
+ ]^h8kYd7g3=K!l[2&>I8XW1\kPc^l:/ui3lSBQbILeMMq`Hj;?ih]'U_1>9A\jGDCQSWEtN
+ ihC):<j8DSii]/$`5aDGjsYN`J_^ST1klK]P-`gcW2Ws>/+s%7IeSiD.5n@ioHc3&V8Dq5o
+ KO'3Ra]1;UkNaDo\BId:ORU8VLK:S#A_.b=RM9/_PmJ$sgsOg.?!n79lcuFJ)EOTN@B%2bG
+ 6ZHLkG+J+ON_B$\b=C2+m#M2)T`OrHQlAU&Z'fMu:NSt)=9Sjo/F]jZ>X7MQj\=HoA*GXqR
+ dL8qC>>>O^i4l<p>6L/gS,!otm9WK?.+X810W`d#S6+S4#:aG)-,TN,#l0N6`+,U'gOsLJt
+ 3_oDCpJZNK(`ja4GOOBIQS+Q*q]mT*DqUkq>KT-&<^gU;<!TjsSSG2'l:=9\8+YW`*o+5JI
+ RQPCBqD#G:1@@DI-"!NEXW_$;mtQ"Q-G1TV-1AGXj>E1B50VuY$@P2\MPUQ;.@J6f\i1F_$
+ M:E.=PMNa4\ehM=!jo3nhS%_].oVDd:%P%La%`_=S1m_83rdVqMLdkBaF:`G:@fO.2jP&fn
+ &,5M'*5h<@:&DOgOg^@M5\1UbT!;E6>-.Tor=,-+;!eY5".2)T?iX%AGJkGhIVS#6Eh,Y9o
+ XI94D_/;ir><cF5?c:Ulf8R/icBCF/h'!U_.BR^@%McQo-3e..qrVQ=<r0E!b$NgJ5c-:TI
+ Au#^b%XAr6OV7,W]X5u_gV5t&'RINIBAWeR!-h,X/&V[bM=^Xcq&`<]]*dT@ir%sE];:@P.
+ Y3#045J5R/on@@F0HF*0XJ+6%j*th1c.VZ`s^tS-+B7G[sAQ*g,CT\n)<C?2^Kk5aJWM/_S
+ Z%W(2.6,/JS9cT]EN>K?qJ`H?NS$O]ndI/X3S>I%A0#MuYfJK]C-p[,Ee)WCcX)bt\08I2%
+ .C@/@NuA>,]*RoU9g`H?tCoiEYko+E8-!o3?5fUX+\rSQN&GCZ<7bE$0%iRkb,p?msG+3*0
+ afGbfW"(U\9^ZE5hQZb@&Cp5=&IfdAEP*7P3l@b1<%P?&`cHFb(j(b]W;)U>`h7ijDUIUBD
+ ao],gO?`^+c0KLp>;XK!+id_'jJ>fM-AVIF9:1XT3GnSS!4MuXL7\rAk<_-l)nsCIY$<rM$
+ YRM:m[T-lbj:2EFS8,L2=%Ymb_!URK#9BQD[)G?+3tH[TB`sma'0P':6@MknJP476ccS'FC
+ hBp(%q5W2f;lu0FOc,!dP70[T.#d'n0C(S_Q:U>bVn<e"t8g;n-K&9SNf>0XqpZc[dDFZl%
+ _'!h;f3p*;VOroo>/oW.ZgoGcKmE5VbRorq@")^D"0TQc,lCP#qg'IQi!N#MMF6-NdD>\IZ
+ &2)XLXPD/3sBn3*S9V>HrW)&qu>F(5U?H"uf1D!_*_NB5u'aM?Nd&MgY%CBp/PR]apZOSQR
+ n'9#l3$&/,U1'B$b!P(IJGZmOp13Vi'e`e:;@=Is\T[u?G+PinAZ2u1U;VGbTFI/YG`KoHO
+ +\'_K7oL;B5LQ</nBj5.LDPA@(-VLe8R`agf1a(cKX<)piJ\8Tm,m?X>(3\%*d2(AMU?O%a
+ Pkq8Fs"4nF@<1NR2YXf--5kkN,=bRV`hW]_,`GSq9t=j'U)t5YVmX:G\Sl%ZMG@8.[Bli%"
+ n7*cJcQ6\lXf`YlthKbb0<^pXMN,DGrfbNZlI%DP0Eed3?abruM,@GV2C1I$OuXlj'9O[/;
+ )(0^?L9F%IcRW(7fXsCg5n`)jo&Yd_*n]!>+`PPJ(ll]Gm_$>Ej1PE.srk+?_P_F]#G)`)C
+ c'3pJ1hbE,gW9&=S.eRj\2GE#`$7[`DrT_R*1Vk>j'&CBJ9<UqoXgD4gl>OQ+<ZU84:B1dn
+ 2Y(]K7M<>(,"n2ZjsEm5sWNTlGt@0Qj!m"69QPZ0Yo;J&.j./"O$oO!MQ*ORXePV+<X>NEY
+ 'o4(^+BS?53Ue!X8[.TRS$dbQ7tL=d7;:!OI;B5Sdi$6,5$Z&C?+)\j=+_?kCZfp1?V+/79
+ %9K_0VC0N#-;)!XOU(+=[u&c,5:^Bp82$j)kOhF\>5$Q'"'0tbIJ?ktF%BY8]X6,5$Z&CC2
+ 07R=g@?kC\01o<RS/79%9q!noHJ6BZ1T^h$4"Tbr[5sXT$*<uVOJ3cG4Nfkae9,;]*:QR+a
+ ViE57PeZGg]a@b*YiI?3rh^q4.b"[=1:'7ARuYjr:gO53bQ?mE3^U#:Gm>lS$f?p@&73N:H
+ A#ToGl]HM$YNq.5@G53JBSSdgUGBX*7nX8O?'%_op>p,!\tj^miA`b=[;,%ntfh30FPsL:q
+ gqn!bMJ$(!6cA=hlR2o0N2Z0aj?PA3MC`2.clqJBS8[F2fb=(6J?bI)qZYbQ9OAPYW.&J6>
+ /"KC\PA(.OpMXbiDK1q"g)/S5$iJBS8[K>fBL(6J?bI&`P;bQ9OAP`HNbJ6>-LL%9q,(,--
+ ;Hr.OObeb<1_4U%D=[6mIjf>0sAc\Ug.,Uef^apVXK0d:(+S5`X2e[q"$cldS^-8lW=[3aY
+ o%f_EELR-fA/St[]f+"L2_Idg/EDSjX7cCkVC_(,KbcfkeO!=gHl3/ra8]<IABCtkctIi=J
+ .$\eeA2_+e:kdY@hu4Z#]%Ib(@i0@.NSP0[KO$tA7<4o%`c@$=u\TAL.h'V3$?E:Pl\Q>dY
+ )KYZtl=7%GOGiV!rs!Ek8JU__4iFK.Nssr4$.\=?i-73GXhIpZ2fJW(_laBs:eHc-c$I)!D
+ gI8t:lno5Vc6+H&ScHDB)7DPRT:1si+Sr@4`UK9amb.1ffVo<-[6njfu>a]u.`4]s+P[u1m
+ joQ%ZHjH:g!D,Bgb;FRf@!\-%2>n+E1E%i2ja1t9Kn^p,'d"O#BVZsg@&d35M32VF2'f8<E
+ W</C\s#j/&.`K#!`QOCMe,mZuY$HRiSYmu4BkCM(N=,2tTndm!U]&tXI%2sfbgfR\",U@Ak
+ PE*:_,)+\X;q&1p-llM(cW@B]Mfp\ECc(<Qe%:?6@B!$:P)RI0OJo`95l:NYYN0ZPVJp9p-
+ J+g0oP#LA7If+\9[[8I=4h[2U]Ks0)&sQp2QS]jch$6?6$tfeaY8h$\-;8_dWqRQGR9#:b%
+ 5p$E-cd'gcSUaBlr,4q311&h"GWaRR!3`imk_MSe$q''F3t,J]j&AD)4=1/sAC1.H?+_X6+
+ 8mFeg%:8_\a]dFOK-i(9+HJ"AW:;36$*6$THi.!Q=oBpE:OuQS)8'X?gEIcFlK[AqE]o_3#
+ kR7!8pN!pMV"7e'Gbn9-HoXhQFB!3mriW]$0%M"DCOM/IZ*B<_P1hHLH1HX$L?$;bAY`(44
+ 59UPliXa-JaR^?!rE\:o0NV-K?@;Ndj]le1Bma1hY6So5NV_?SF?>J!CH#MpN(m=R1'rCRE
+ p@o$HSJ*)u-6ZcA)aMR[=u7\!OC665GPjDoH;9;j641S"'9OqoCH?behi,:[d)Le(/[fDg&
+ !"hj*@u'=.$(h!$RP6fi0W/n$AoZdqNbC=KmC"7K&!^F`T-.`K"U7>MKn,r->n*&=/B#%!:
+ D7h4M=+5@82;seETB/>4d<aJP0DK]&)%qbNooYZFp$k3Z.@8`JHiSib-GOM+bf=c@pEeW$#
+ ec&?l-H!mScHk$Ac=*XSp.<!DfeV-1&/Me]Xc28@;fR[p]F?>S6>2V)ACd`)A3ONl$c?(W:
+ h3U;>RCtYQYGLA@*>saG,&3``M+YO(3XnGP(0IQ0WE3HW=2#jpg`d;RuMQ58b)=5-Q81Wj5
+ iW%EMAXPaB4C?*^_N`2[CGGSK_A)S0;BS)6j`>UW+Rs+nJ9f3#d5caWVgjcQMBR;\OD92Jt
+ ER4;W=&;HZq)rn!a5LCYJ)fED!4ViL`Sr>cn+8Z=$?8mH%1Y&nGT4'QVM:#ob8@FF4Q=r<#
+ 1c8U2(;$))b\NgG6(,?jbT1H\E(nW-be&\VDN`M`HefJpK(@;X8%-o%@W3ELVg`ZIiW;L&^
+ Go"IQL=GHgDf9\q6[ing3Q\MlXdHOt>e<4H3n]BqCjfGC.>JN!7[NZ3K=Q.2Tf3NR\BtE6l
+ "!UWVN$@`22C],(Rg=6j1PGd=8%UF`k#@&;1[F?`/A1Lf,=.Ba9s5(#aGUMfM"3@g7;ZsEN
+ nHV^F+!/,(qKd?R)!mMh)Fc*AfMniQ.&#TX^"?A6`YS?ET<!DV814-@C7+'"&f>r_"##hl/
+ GtTrG#"mIH=9V^=n`j<S2DJX_^UP8DtNki!`ZE"T>qrHKq#U";Vc6fpa*7&E?V7:o!.V,GC
+ `OqYsmaQU_;"pP9*s'<G\Z2cPBiVrfQ]tM,8SXiIa%2C2./!^ppS!u3\7XEYXeCi;L1T)NC
+ K\dO`O`<uLd`JT3\B)V^2)LE*OjT<UOTCogp#3m1<!Lh7%-6'ff@SX'drYNTfoD)Vm3dp:S
+ 2f)Cpb5%uG9Ts@%]\P7)&G:VOJ.fIOjTTb%VF5odpm](UfX?qNupS509m61>]p<@T##u/rk
+ :RLcl3oDq"5f:,3'j\,=?g,89ha@pg::LqLA~>
+Q
+0 g
+BT
+22 0 0 22 442.893213 123.332434 Tm
+/f-0-0 1 Tf
+[(Unde)]TJ
+/f-0-1 1 Tf
+[<01>]TJ
+/f-0-0 1 Tf
+[(n)-3(e)]TJ
+-2.75 -1 Td
+[(\\MGL@@@<sc)-3(ript>)]TJ
+ET
+Q q
+0 154.4 278.457 -71.371 re W n
+q
+0 154.4 279 -72 re W n
+[ 0.797873 0 0 0.793023 0 83.027923 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 349 def
+  /Height 90 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 90 ] def
+end
+image
+Gb"0VHVfoM^;ob.c^l11+iFAk&OHbb&?[/Z&-NV:84!B6J06BE,(fR#U/gNf=qlm8&J,YA'j
+ S]ce4R-+Gf*1NX]g&ka.phO/E=!XeRQ34O39N?rIqVLmV\qs7A#A)IHL4;NtX`rJ%snI0F#
+ k0B@!/5IJVcDhgP+@2n*\\\pX<o:J]<QIJ\3Tg:hE.@srcJ:!KR#lKTt/[5A[6%3%2J6r.#
+ :/*Wq6ZEdp1jr2EA=^><9?XLEdB6388rMND]\pF$aIt.L3HhYVRL51Q+%*)i%A+TWNKKFDG
+ >e>0]ld2>[R[WtO/R(&M:<DjjGrZ`[e'+d_#%Ktd;I[:9X#?uQa-Il$b2t"i:4E-MZ-bI*+
+ $99UHdOcO7n4oE7Hrglo]iqsK1<&&bFE/s.erE-eLR,YRQg0)\pjVSh7IkQ5CQ:u1-?M$8.
+ u13#0rf'97ftuDbbb!f%e.?-$)^[QRu>:f&H?QQY^nnBfY_Ode2_FX==fK^Z`_CPcqK2LQ%
+ $_BjO*6G"S-,/.2'6,oa7-<\A=J]t:JOcWUP=*iZ;o,n&dF8/'(HTq\9/<^H0OU;FC*/?W*
+ g@WTMWm8`Iqel9$,DJ6/%^U:dbGC@H%-A9_RBWZcF%&_Y8I57W>ea(>Y2Qp>[O,N/)S3uDD
+ U;E<m:%dT0:<N(eaV2h'?qo+&#7iFl\?L/DlEiCsS#)tI<gV@>?b<_WHrbuIRQ;uO7[9YWS
+ $!3mR1_S7gTW(RBmuA1.eBMVk[SM-*rW1gN'phu8_6gQp/L]Yo9<KYoF1]ZPUSmZV-d]!9H
+ ,%KMcQeSV-N3`OF)6f']c^1[G893j5In2j@2p^)6?>^YJ0ku%m+rF:RdYbe<;6/D-3EoP\?
+ X$[VF+3c>?QO>&&D-D`RX6`npEdEsK,d(D&p.AmGk6%iGtId[lnOQ5+#s<InT8m_L)u0;%R
+ Ipbu37Ip(IAmd?j&K7fC1(l!g$a\h$'^:m>'mtM"f9+/&k2m1?RC%>/EqjTJbDeo:3K9i"_
+ m=.<@nBf1\/W6q#k,3-#0YM@AHK2N`:m*`Qe^'Y@lAAMI^Zsh.NO-jpoCZm>[.!'h=(^\4V
+ Ss7=@PZu.g(81VL_IRJ'=oq^fT'-XFDGsXoe4'*#6kOA@/U,ESND%AHB'R`4Pu@K?2hGrfk
+ ,ASR/Gn9Wj;r!DkHB@ErFLq^"!@Rj_ZN(YKKnqV(8"3LG`XuD*pP?R\dB::")JWbLnX6Zlr
+ @FRhf7Cnp`#ap:FGa_?eQ=!&q=;U^.Q2.:rg1](lWaDN8XgqTDpA>2%_Xk5P>V'`LXTr4:t
+ !1,Lh0i5"4IhbG!ZS7cH$@tT0PAktXrGO+p3Hg[Cf!71W`huUVl9&:+$Hu/!aJtk1>=(KgX
+ .d!c7RJn1cKGEe?j=b&dq31T;lt)cYr4K,VcM_tUhPK`-"`"nQoVYn6*UW*j8KM,L_j$5cV
+ =a`JV6eEDZX`*FF`.<Y5:,cQ%mIGth!5j1:q0Bg\PUC@pN)<00n]6r5oqYM/ri7W7RjDg]t
+ J9%E.Gg/(TdXAiV)[=C2%D1a2`M:4)6&C[,LSDL.FZ3G?-^'d(CVr?47p'7e&TfonLL$3HB
+ TZk:.RV2XF-RQcBAiPoRK%XV<N)6C&.C+lq>r[Hc>ok5PA7NugHY.LY>:6F(Rj`g=rpp%nG
+ 3El$-OI15**PXo/%pN\R;]d#`Ci%i*Wn@'Xh>6`.1^o:5q/VWemE:K4(:gtZpc`n)FMUAVJ
+ [MVaR_iZ/,."ok--OW7f1VC0]78"s8dK<c&MjY_0c8*,/(RM+X;/P4IE;fX"A=+(&(*5\hI
+ ,i6>VP`(c(mW>$`=V1$)BG1nk@Xs>hMr0hcW@rT&&SA5JYT'G2\ch"^dh>^fMq(+#!EXGM)
+ 9m7?MDrVE\mq0Vnda;lnUkl)Vtn5RH&]<=n6I#0NZ)IPH^9<AcU^km-7,Rf[*G`P:VgEJiY
+ YH^sb^ki_>F?#!"V<_-=)TSX^8tD'e[[$+-.p/HInSE't5Wol.bR-c_8h"%#sJQ3\QY_Efc
+ \`^<`?X9c@$9D3@o:SgOFYN.!#fO5iH!Ue5G/q_BP]"3JW=jTYfr.Q\EOCrTeO3sRuUuZAb
+ &G>2,To&sr*HigH!?HQh\#eqt$-nss_K^#`#pJU,-<]=nb-54\>Gf4$OPs*j\P/W!SZ#X:c
+ q2pL*g79^Q8b.m8BWPtK#QkCDhHiI8B%X[M_E<`+BK`=RqXn_Hn]S3+@5cJ)>]NT1OArJN"
+ B9"1gA,LD1Ko"fG4j16=?Cd02(#t':5X#H7:q=p/sqCoM1R]'h8PpN8i.k!hauf$O=r'AVA
+ MW:&$7S/uQQd]"4&V&A<I[@O]3o,WKUjm3E(5YX!Y_L9sf2Sf9DUZ;;/WBJ>=I=L54b'0=B
+ WAE<SPc3`&K>bd]?;@oS%cVrbb),;-E9+O*oiOr&i,elB-\eVQ%5sQ)!\^c.<qE>::^ark)
+ d):)bf`JL15sXXl++f#G^`Xcl`BOP-Z[b>,'A:.O!4.2A5SM^%"9GiZ5sQ+.F+]!G^`&l&A
+ !B9p/79%97.<N/^ark)ODT?$+CGs=#fp&[F:^,6(^+ArIUs'E$Q'"W9?&4_Qj!m"Z41:\"P
+ _3gL[!E&Jb%,*U$!?c+CGs=#\a-^77"^??kC\0oLaad=hl/Qn`;V2!OI;B5i]h!$Napko$8
+ 5JkBbB=R)iF'r3JlV\L7d$"O$r/+#H<Z6"(<O<#2W5rBVYb)O(J8Jn3i'g%(cl@hoX#;4`@
+ GP(er*E$bmtJ7sr5!alcTU(>DU5KYOa`*a>lHK?P^4_=`$JEVXV]jhg3$]$tp?TMd"Z[h7l
+ nr7,p0FN\#-snoF!OI=?KCW;X(,-,P4t'bpAc]5gk_&FX@hpa+Ld!4o0kLHmJEVXVrF-Ok/
+ dpqe:Wrm7!9MDC/795)I8IX\bQ;AWd0JcK`@PC4&5>tb;To2S!RV/6o>E1f((bmj5"s0%Ac
+ ^9ajccJBbQ:+3P`Lqj0FJ.`5!uot/>.iYnc@/PAcYV"PY[@c0FMQgTmUtSLKQkU#N^"G0/*
+ cI,+s<sisTH"ff$u#2BH9BOA2Hs=lUE4!SJ=42e<(F$clpV^*]=X.p49\&C_T:T3JY+2\Q[
+ gi335W-,E#+I%'VS)3Cu3S;bHc?SYk?_+>l!W.uBJYf;i[b;5rRj"1X-.UK5`Htd0mC`^^8
+ 4qeo.KPgnaNg/L#MBrbRp@KZ+Yt(7%ed0=hd%Q)(P(aHL+R@462X84,Wc=,Sp^jX)0JC,3C
+ QXdh.7&&>7h/O2BM4+=,OF%!d7!19\OuL_iOmjl#@oX3+'nLgS/Z1Z#sB9U_7g%cLkaG'cU
+ qd314AG0U>h:dK[VddnPKXmJ/RN'1+L8"1:K@LDaT-?Ge+TT7mTin2!^el*]g^u;'Hu9=H3
+ id&#YL`32oEO&.&Cu-ZnUG,6;t%?rI1Z$iJm+l1&kf8r]cGa\.`"_`XHAKe*OsTr(s.$ulk
+ g=%9!hHbA,s_1t/uR.L27iVjP[r^)*:*X:pS/X7QqWHKj59SC\ZbFJ]oG9?%qld.A,:=pEl
+ eIh<J@$i>-c]`IH9%Ia1\I)*%KGEe?'YnqdFE*sR(3]+^2!JL=Xph-;-d%btlg9l#n%*&8T
+ M[ARO<sk6fH6C^_E/pF/eg3u5ufnoKYqEo.b1P\mAO&OV%Uocn9,p*p3TX"F!4K;C_SI\(8
+ M2H7Z3[#mS6ZOK,9lRM,A-IhEZiI$k2dshS$gCeF?i2JgHq+?[efK1V)rg.ll^2_EXL-T4W
+ H+/+=jAK/_mg(')O1/63mH7Yg>a%#<&>Y4OB$5+cDCpEb_Ij+PBDSl*X2#oNbK7kZfJ+kPS
+ L<O]Cpp\3RB2@E<P4<[ieI(3ZU``0[1K:e5?/7OCE4%DqGl2Ign<ItYu9,UL%9<RAK#4m9B
+ ;C)4LaR?=OIfEK$&:2(*QM?TaOPu;sr+E0c9PL\%>cA;f<XCP[3AFuD0TRC;3sf&5*ZV):<
+ -*D5gYgui)((&?Gl%'sf3a$`eb)4*6*=J:-2.\EJ0fD`;@&X.+')DbB>0Q'DN(eC6.BKZFe
+ jo,dNll^I86S2&ON6\-:<MTk-N5VC=%gY+e8Ia4!TiNi58G"Qr7!ID\kpXZ^o=(PFn&hft%
+ .Nh7I3b'P:cuGkg./HY:Zr?F+7?.QG5gq$f'6.HRhq>XtWPWKFD_rESq/]_N.%EY!IX::O=
+ L/D#\9BZ(1M;'M3,WtCKiO:a(7bTh`aZQeF-$(65^#9PkA_qCX-YZL\Eb/tKk5(/%\9hg@6
+ <>MZIGkC4Ibo8TFS"!@$As!IR_fYD,0R[5s8/W+(B!dA^+CU\6CiZGp$?hu6i8e&1&43/3+
+ i>Jp8Ioo#q6A$b+\'[$k6039mn&N`[KGF':?:Q5<N@(=WkPu`jl++4'K,u@pssG(E3QtO-n
+ //@8>$p>NpC4/@53-h%%3T5+GZX)0I@/Fd:1;f,u2<$QOAJn$R*D2o8+'c-Ar`K!JATgb-m
+ MD3d<^=o,,7$1@7I-AW%=hO;l-R!0pnBr0RY.M]m5SFn93l>>+Lf4E?VDZ0XH1Frns/mcEF
+ VF*%!60nP,'&AF>p`);Fo@33]"TbeG1n=@XbaIo=K#L?!86KW4A(_0g5)aRBjr1'k>k!nZ6
+ J_D']:Wl#+1ZXhBMifb_"p`6Q*!+OFSS9aIAEUdT6fL_\Agc\#pfT<KGYEe;MdVYB84Rhk#
+ 3E[E+QFXZoB*@#h"(%f9t5<8,.1c9r_jT65H2#UTrkG.c-#/$)/1fT-&J#(K^\6ki[nP24l
+ -$!h.-Sq>i^VNH6HfYA3ONlA4gB/A6*5G)O3'6/VVE.N/gSMBP>K`cP>Z*"o(Y,mbbd/oB+
+ <H-Vh%VZrC+kY?J2QDJ<NF:0(\E7R;2em^*[]cq>T.Z:l\pMp.';MbIq_9+..,)',+d)'Bs
+ &%mPKDA[$X05`Q9U!s;W->j4CmVRu`ha%&>[54W,`B.$%0=!CSK%''1Q)&G:VOJ.fIOjR>#
+ %^]u&os)4GknU2Kj2[5&X-/'sbKeJUF(]0"E*rYho[<.9IK,C3O`?M?OeM_u8/U).r#MrbO
+ M(~>
+Q
+0 g
+BT
+22 0 0 22 104.449866 123.332434 Tm
+/f-0-0 1 Tf
+(De)Tj
+/f-0-1 1 Tf
+<01>Tj
+/f-0-0 1 Tf
+[(ne)]TJ
+-3.366211 -1 Td
+[(\\MGL@@@<sc)-3(ript>)]TJ
+ET
+Q q
+268.801 38.4 96 -38.398 re W n
+q
+268 38.4 97 -39 re W n
+[ 0.793388 0 0 0.799999 268.8 0.0000473848 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 121 def
+  /Height 48 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 48 ] def
+end
+image
+Gb"/kM-!XM[`AE!(7?q5&2KH&O?b/45_(O<&-7nbN5-)pMMN$9d8E5\MJ*a0%`fb]'GOE&W!
+ M,BeQU#I3k[^aT@`7F45F4)gpVFAI<%$<MTT[P?a6'-(Q68T8bW.RID1'sht\8mT(;aBVk:
+ ^'rqin6rqc'=]B@J0g"kJlZ>sYFIeK:71J3PqX-P;=?*eWID0]SmJ3bL2\[-BEL/u7bEH__
+ PEXad*UOjHQbn!bC,LiGi5?XMkI"L!]+*Wp8!$*<?$heNI&A.-PCc&8EmOb7!V&Z76*bOo%
+ O#6WWb9T2NCq+K$r4-%$efGhmoZ?dlp[6kLJ,__'GoFP>]kj3Wgpln2dA(OtS'&m2EmrJR(
+ ?O)4Q`R<kBPj]M/";k:Wh&.QN:l_2*hpi81X8dg]IY_<IUUOUnq+<=ZHe29SSOPYCL0$J^1
+ RDrqVPcW+oa/^QWiZHhd4"'UV=BPH"kP$=f!q7M_jA`&jiK7<7*c$E0WE,>9'XY-(4[0,=@
+ E9V3j^A;@$n^,h1=Cm+o)0_O33hDVZLNs$kolkHDVrlIrX]!sA"nXK7qUSPbW<[:8[C`nH<
+ YF`kl#k9^CKV?Uh9?C?)3A_iKWF[nN_:3LP<[sQ<o^?1?%/XP=.ql%7Mm;d^Rec,7m#I[>T
+ ]4uJIoFP:sLXBs\*^d_.3bfJW9oMaPe].A6N(UosK6Nh_mk&\tZ^`7mrT;AHC>HDie>^4<^
+ 3pr7s7!o:^R@(&q=Doss6.=Rmd@6XW[2^;)6YWZ]6a;$Q;ofsf!!;T$_9LlCB'SW_qWb7lI
+ g9i^Z2N842*]%HYgUc?0,4KZ_tHu&R(MB>a&nfX%^lAR'kHN^/\*[ITNR,lc3]SESBt4?>*
+ !l2-&-'nE6M_YL7)aEJ.e=LrV%)Wd0eNAZ=W?<V'u611u@=`VD%%<5L>[/D/EWaE$j6nZpT
+ +2f2_W1c0ICk0;dM)iqj`7aAV-gIk-GZI>^QPq?*Fp\M=@Fh,tq(Kut,>1XhM^>Yj#m<=W[
+ \UUpZCeN<PlF_]=[))=?A$;_YY^GSgof4*ni@jF3C,=2MSpIt1q<Vmrk:4o/=2V3YVkH>)=
+ d1UB'\-Q()D6pi/rf=j'=*$e5Z<hID3Uj5,Ua/`jncN"l+(MS_/u5-0.nY1=CY6dJeYit&&
+ -8Q-?WlFa2Y2a[Gois^s,Y>rH5]2LS-h<^3mJtZ[M8sCeICKMXlo^p!p0[=6(Ytm;H9_f,$
+ dQi^D[h*H.P,\E(!a3k0G@i4E?9:++oaDp\CX[F_>D9%Po>8ZKZ&o)i61Bj?f8bW#dHXHu?
+ @KLR7@fNYH<dR>]Z6;.O1*ZQ0(l1Xne$/^\s?leV%hHj$?SN&X8\pWJfL)&eRRDg'+6g\[H
+ hmN90O6udS:XdRkHMH_3^d!=`YlDer<sPG,n5M\M]3/;Rc7enSAu_9h*jcb1a6Y<6.0Y80Y
+ (mBRj>'(!kg?(cGOBkUmC2,O9hI89FTVaCQRnPC%.M)\7aCU;`9/Me*,\u)IUChgBDPE;<W
+ 9nPo`.3?k$r90g]]Y<IrBbf^2!K(mE;VAgT<s?IM]e"J9(^8OUf5eqr'lj^YVM1f:m/>'j$
+ -1o6iVj8nPSl&Y\,#jZGbOQ92uMl9^s]2gP#W`m^h]IIY8m#]Mo5nNBt]:RsIB[<Q[ZW1e6
+ /1$V4o7U1C_b`T@,=So8hDL-g*!r0g(7h5JN\@3&F/qDnc(s7CSZf%BRkY$;hCekZPAAF=D
+ fUi1m1Z7123*$C<f"plkBUsRXfXO"/<$/rooM5!e7_7'cgg+l<:^a42g*BH;-Ym<t7s"9eO
+ $CW&pJfY<FBlM,\TL8LguRtXR425CQPJW+2OcCmOn8SKihNof!Ug!Y\:44GPeami$$K*qSg
+ `5+%_Yp/MhKqXio^G'dRhl"FFIj*m#6Of39WqahK7C[JaM.;P^Kr:hk)0.MW0m(EAH#Hm9h
+ Xn:r;oA1>JgOIbsXiH$KYhn%fY4jMW)k*Q?"n>.Jb*ntjuW=Q2YET.fVJCWoT<Sf\J^IFLR
+ ?_:<9E'DBA\mO5ruI?AIk&e7CJ@FCkV4#5cSoTSqCTJ_CN<q8BcclER$EU`[$kX^?6jtDYb
+ _l9q9;$*PQ\K*;t"\Ipl;RV`]'s\gSNI_NJ25H0nU%]eDNfQC%YiW!r-AMg(7quN)lC.(Xa
+ I]8DXFoj$-E]u5J]$eD*H<,q(W3sT!]!=a]cE,f@odqpo$;Jg_V8aB8cORJn4DaJHtNlSQj
+ PED@<orGo5mL"]/N1k8s6!GLPRBF&uL_W-)'(oKUcjOqVGMiDLD#s'C$g6"\e05#N&[oYWs
+ XW`HcEBJYaK+b42XD[P+8fCl3OX@GK2trh]c%/AtPCV]Pds@eG_VHBPYf&UXNq0q6(Vs!7V
+ QCX+$+ApC3[[RNM\"B:05a]8!]&\<s%1/?+'&lANqCm?N1:U;kPH/[Cn9C0]uoYh1Sg,<f(
+ 2&Tp%[2\C;RhhaQ;I.__C?`Abfu?u3I!>G'gP86XpOs9IgWtt`5(E("0G;)/3/6+!V;2aj)
+ ks#gn@D'&dk&A-"?XC)&N)gEo+<`'9RDI4.m#Nj(&QH!2o\g5jT!nGT=oa6`3PO=V,38GOY
+ eZ<ODN>eDL6G"YX`u;kj4JN#Of>1LN5lTRH0>+fEe,J':FjUM$LE0ghr.*<?Y2;4I%,H&gJ
+ gqk9S.5"sF.IHb.TM%/X^*i9&&!9,B7Afnpne*-V2TH?6AIjBPl.<^sa<HhFF\.kTmg+1HC
+ _1-"-$IH,gpn6G/qMt8#ck4\uW&FBr@1`E&]F!k2#2aOgf`3lPs;'N#)O005E"jV:;)'<(F
+ TqOi@]anf_W?*-g]!S6Gh&I<s-0=5`O%hCo>H:CPr?]F6gtio0JD4,QX'qnD]#3KtkC`B$Z
+ r+:er%1C:$c'\EP9qFdgFQtUp_6+JA_Q2BQoQa,n#d[lC']tm%6o(!bhA=4rDcIR^H+*ncO
+ po$@!]=ObGbp3]g(*Kn0.^N%h)t\.G\WR2Vtcto:MV\NA_!!+_-f(ZR5C8"t9$<T5<3K"@7
+ a((i#!2B0FRDj[p+Id#`$EXus'@JuJ.o]D(a*8!bc0i$i\<1'L,DGSDLDV"mZ)FY7I("EuB
+ @E4653HPJT>&Ei]$W0I;!+oK+.6]&Lm!#=5VkK&BU,Rl),NgA$'5<#$c:D6Um"#R<`Wl8Kj
+ 1)`#1\b,Xbc-*MN=AH-;\o;S-DJ[Bn'l0D5CMTFChTCHMg]2aY@='gc=?URO9q!Z=%pL26#
+ =FI\$5M_Z#Rr6Tj\1fbrS/e>2i<E+k9Y;"<3F=dn^bsSfQa;@-ZeO9U@e"1NHf'FDQ8SF1J
+ r@j41+.dknV-m]$i^B*-qN]RPZe)0mnZ$&IPQ@@%l1pMmP:#(`pp/HD&%kZWbA9jM>KTb02
+ uXJ,d2DGALb6rdo2#:,fjJG@i,?$XB3rr"\0/EK\'n<Q-FHEq^nPTHOVbAAaEq@WB1a&>-"
+ f*fV)U7gNBI=Q9pgW`rWSh.?\>8ld^"7*\sg<Q98db,<HUSVGgU3GbaTL`5Gr'_!+`*JlM5
+ !iD_i/W.qJ@Pr%;C1]m_G9B<aWtV0a"ZiNr%]`Fdgj8P%7/_[ZQ98cECIGGI(Wo^,bE68WL
+ S0IG.!#%?;`n;3H12ZMk1EsF?.ah_-?O:mj8.<,XW'4=L5579%Y75LUeVo),SmS`9t\BC10
+ B7js)dI`,Kdj=(T=GF2PO=>%u\*7S1Vc)*C1i$7'5KJA1gXF*%I]NBPr85odA@pDqhQD4u,
+ gIE!Z#tKR*/6j@g3Z5dCMB,@7#a-Yb6Zq$F")pI!FngUAQN`pd[8INGYc$?!?Y"0W!C0(pT
+ K@8S.(-b^.R0a)$Lnf\%Mf(o[SK"p>QqKdI":/Ag6W0afB4l&eP-L*^n4_js\$FR*U12Met
+ cHmA=EMP./(nk7H--D"cU<]#JV8"j!=X9J"lq%]Rh.rE5K?nSfMjT&&DO?Ao<mn7._+s,^N
+ WL\_?pbd9f^bci,FcBt+K3i-Hr!tQQ_:]DH`g+A]%rauSo%XN*#t>IR-Q23/%APC1!:tR:Q
+ a,21WTLmr![cto785%F@<bY@7E_R/O<4t"U4Ih7i48BQg:SkFV7X?[#\@06K\%ZS0Ds=o^d
+ 5Bdi<HrL-`n<P#?;VCl%$.m.mhO-+jfm>>6aTF!COb:fsKJ`QIZ?U^3k^Jf)]VUf8EpMN[!
+ JH2M&F2Bc-crciKo@oQid)g.;[NufEUKSV&p=;au='*Ng0QGI#^X:9ikOQUr#l*,<@WPnip
+ )CSX6MF*jV>%SbRM&J;X3RaS4aZ/F''3Q2m?pkmYS2QAQFRXCKpgS4Wd``&1O[#N_B@8'pM
+ C0tLJ`a3"H4^komgb!CI]uM&l=!mbNKZ.#H-U.uBtBk&6[d`6WpMDIC'uMM:<F5ImF=>!5E
+ ?^/U0?(5=qc+0K'3[kG,[F*G_h44qb%h&'@VDDYo3^_%Yb^5.$A*/0lh%pb;Mqj>-=WuMZ]
+ []</F7T/KFB5!'JmBH0O<W9`&KjTTEc`jO&B%9S8Fi+K$#['DkadoVX])=R&W)rnBbgE?jW
+ ,TD+)la^<nVBa]YV%?u/;QmY%.9kf8j<`$'qnAa=;m:]E/KSd#4kRB2Nj[0J;\:7:tAr=Hb
+ -"5MCGuS.BF+f@<WFf1cEdQ$)X-lj6<'Z/+(mL-Uo6)&h3NprJ&l4`%7+(Va2QfV>eajbD=
+ :Psu]sighjP.2QHSJVZ)]EH"IU3*P,S*s(Xal:c*N*<-qf8nU_$Le`!B--<V&?!*eBJ<GSi
+ p\,JrOiFihf/%-lPdlHp+Jd'iiuB`CWD*(UG)KKCkp_h)ri*o[nu=1#%lZ-00krPJ#^"5!g
+ WuX[u-L&T2(mD_P=7)emXiJ7W'6TSI+]lngk:bK[A)O)DMEeo$[9]V-Z4UI6>[OY&L!3jHW
+ al9M:)`Eju3flAlp*Zl'gkeos,Ogn6C)3`Q4B7GK=8P6sN#%sZ)0`q7s,.CqLJ2.khl%jA=
+ UD!\N@jBZZ]k#H>7?4X8$m@P7^mdNlg`&ilh>#LBfs["OHYHiY,PKRRoTufP)!=@DRpt9gI
+ 2f!e>EJoF6=c>n+$RrqbpbtGbtp24"`^!*GhA*_c'2UM+N3=u'euFl9><1][K]'R't\=<jK
+ l-Td^D(In[8Z8JSah."t]k$W@,.$)!k7\"EhVj4d+aI[8,^tHdl9<7;e/SJE,>W9=?%sHZq
+ ;*'/Cco&pMJXp0'*BIa1J':F0=,W7sIIlq&II2*nqr(3m\?,uH:]CS5!,#Rb5GAin_$B>i0
+ I7UI?J<p9laY#Z2C=\:r6Hmsf,_.(Ip%lXCG.#gKJY(QP5QtD,H&/RZ#FCR3M:R7-fRi>;N
+ Z"cI,m/3$Eb9RPB2-ad1+AoVQ8n.>0<X0SedqOK,I"N;CTR\3i]]og".RI>n)4iiU[nDsic
+ l,H+!p=G0%HeE6'8*DDE=7T)lu[o2.'OD3Y[/)Blob)["GOA2T0N3Pl$-/smbG?om+=!A:L
+ ["n-_Di\]Hh.El.d[89iq\*lsc/WjNh+?ih6mpc(^nBadES%Fc5lmNqDeHV;KL_rg5A;=$G
+ b/Sq78e<`d]-De@2-S5"ZeJRCH).2!$u"2ln8#;e,R$m-X+XSIgFAUGgK6;WIGToJZ+J^Lj
+ 0J>22=2fu!qVSYrp9mj%#K=@>6NphK=4#W:7"W[go*(uV9\b-OsXI,Pjd@LIQ$JJmNk\,k7
+ h)*7D'ZomP$#`jGdG[GaKGs;S&7H[u%L.W\@=T1A#)a]q+L/,i*r?DrB+^-EB9G'rL:;*Y*
+ rgjHO/%[VKbk$;&W/fupaT>m294CjeS,/rS=\k3cdB&gikg"=@H:IYG]-">lD&S5;7nb5hO
+ :ALD^N>$F;Wh'k:m)J"N/'K0JnHA%2],6j64H/VJg[5*MUp'KSTfj+JQK_Q8:W7mJHYHhn"
+ (H0+AVi>YBCI7cr!i8gsD#hOY"CM_1b=2XmCaB.O]pjR`R$4]tA3Pg%X_/QubPQCUC3IKH"
+ h_^qk+kVbJ_+^cE0%L.W\@=VOA,?@&?CGNM#lk';n5TkjdiK0RZircjQ/eP`QYY&AMI<Akf
+ 3BRFW:Rq'rF@&d-V=`b.C>9g$>^Kh\,G'4GZ;@T1]/!jD$#^>Z,sB9[0G"WtK>Pu7ed2L'j
+ 4oWFA,$<1;=*T5_E(4O5keJBgLudCJff7%i^IZ%)ckPNVPbA\]MPKpHZ;G?8\p:@WhONR_R
+ c`.@B8XcjUb2`\2id.*4/uJ$#Vf)X6;7r[]>&#`C\6q<jIS87)jNj"-cVP+Cj=H5!hLKf[n
+ dtSbkAFrrf-W+,faQM;dF&Rl;s*Z7mLXhI!&I&?nPRHS3328=P:q?-.*;$L$RNWR18#3]EM
+ !9D@O&-]%T.0cjse32!`!+[bG4d-tbfg(De/5dfXWlpPXpKoh;1@`TBGL5ulW`V:NP,[^QV
+ R><1P~>
+Q
+0 g
+BT
+22 0 0 22 295.822559 11.771399 Tm
+/f-0-0 1 Tf
+[(End)]TJ
+ET
+Q q
+243.199 325.599 147.57 -135.715 re W n
+q
+243 326.4 148 -137 re W n
+[ 0.797682 0 0 0.798319 243.2 189.885823 ] concat
+/DeviceRGB setcolorspace
+8 dict dup begin
+  /ImageType 1 def
+  /Width 185 def
+  /Height 170 def
+  /Interpolate true def
+  /BitsPerComponent 8 def
+  /Decode [ 0 1 0 1 0 1 ] def
+  /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def
+  /ImageMatrix [ 1 0 0 -1 0 170 ] def
+end
+image
+Gb"0WLK>0kqZlWji0Qio?C/+D/laq`779Bi/i<o4`'R<(722#)"A;&d)i6^HeAMUu#Un>jB(
+ $WW;.$q#<:p1Xbj6rdAnG+4G(FqaS/b=bk2jj8Ep(!jHg_@C<)H(!<E)ga'ie417Fc(P:S0
+ hmqF@2NId7YN+$P'ss8IFrIm<i]r:S*k+5sCP3E0Dj4^^V5]RJ\ce+<;#gF#dg]R9PGc'pZ
+ ]YC1hIn(ta1?tB4G;C1@T,6gQagY7&cXZO"0SNCuZdY/(L>$B4A3d(2B*I,8Doa6;%^C;--
+ AGm`O-%gg0#ok\2+$I2]q=:MK-[spbC!Z4<4+GqRZXW0bo($X%2K'uoCi)2\e_+s0nmsfCo
+ _.oR>/jr9-ia/>hjlj<45/$2f2f(WZ=m\%gf`U0:0(u@;d@t@`Zb?<ZY,$<Mi$<iF(O1DK5
+ e3nhrDaqhn477mN&-8lkJUCp<=PS:E8-\gWfum0nJ1&!M6I&`Wh`&RO(mfTqb<5<\i*"FLA
+ @ZR-$,Mk4cK3lo<SGoVB*gdP>tQ3dL8nq5ru7:E2N\ZZ=`hLgY]cQ]._cM,>En*"O,];eHJ
+ *>9dtmRNbE'4(F7iQA/T2Fr$dc?Bl6?c#n/1cC_#AN.ljYSj.RFj6G0l]"7!]OqM4JB$]tm
+ >IIqqo#,hQ*^O\p55$=0edN?nD'rg&2FH"mB7bi'JiQPnD+5'*EiUT>3:urr$gm>GQI/uC-
+ WdH-e5W?iO.SWe@VpEhaf;0@/!EjUVD!MP9]+OP*.4jsVO2&,16nCJb*2$]Nd?R@g'VF1h`
+ @,DqFts)Nh'JIf:S:n;-^=c_44I='J,-&9pdfEjG+Jb'P*Ql/6X+>fsN`?An0];V(p(U2RB
+ JBK2#>I9U14SPW]k@DY+7\qMKI-'?ml!FYM57GB`%^H1^"qV.GmV\<F5rN,?P7EYjD48dMQ
+ q.K/W$UAElVin78Z-5iVid*eGk(HH4WfPA^:;<O;r:Lbl#^u7^hd?6DJD2PNN!](0U`(>.;
+ _XdV`*Q>)MOs5BLR<>/Rp[koe%6p_+TC9BBg@=VkfBPAV^BH="q<G0XeBN*a8S2alR&Tp;<
+ BM*JCke+LmW^5aAP>b=]![cgd8APl(cjZ^;^:9I5:NmO8PDkSWXF:j[hblB0ClfH+*D5:Wr
+ D.D='K2'X`QcD`GD,3s!rp)UR1BU=7%tO9ocKY(K8;0Y%Xq!cItNT6jmg:-nQ[NLn%GI=b\
+ s$gf&Z5DooOa/">/14D6A7^K(a=HbmbWi(.a8O\c!LgP9dgQY/%6L,$iaos<IfM%6!R-E:"
+ 4.T;:jD(%!2V*pihjofb2-(jK+2CIlRf:Ca-ilJ^aO3VV0IrPsGq?T:XK6t5GYuL3_-s5L8
+ 19KCb0u#rnpe1g3K9&=DA6P_&Aq5a'1e`ha3,:l--W<0%$Z')s/L.DP-a5TCEj@$%e*>GQK
+ [@T#=f6HZ*oE2dQ/l/A)tor("FPFurt#2/i6=Q,4!,H%"i#>8?RCDJp)qtu5L&3FH,a]`be
+ JeoR$J".[AcX<*\8$FrUIC$W+jY8-sS.SMcOb$SXL-0EhGB"3]XbHLV6:Y%;Xtk[r)9I4[I
+ ($kiD[cn@/HTL4Vc4;!eYa:'J8-J3jLFgA9ieM,39%Zq%D)[7k)0GabR+@OY5Z7UcZb_'[.
+ Jac;P^9rlaK@RL/FaZd&CpuI__p*Br#Y$:[oWt'YD!'Yu.G<oRnGZkAV_a.3DB^c,Kdm<#9
+ E*sUZ_ZThr!qNEWXdo/pOa2_\(0+-D2,"B9M8lo!!M,_s5E$>!ZFr5I_lC)ff['^Hfk5ddD
+ -jtjs5H<-V#UC7!'VN#hHU0W[t/n,_=;Kk&dXM<^^1K1aT9FBTOg/DkRI6Y>4RBSD"KHt[(
+ o-IC2mf6>>\Qn8;TDW?^%l<),HR]-V"#6MMrq-l]_?B#nh1Y_!>doFsT+2#946VXb#CE#Ft
+ <SY&jU#X?Qc`PlhNnJLXIbM^so*%Sr"jrch%nS/:&h5E%2?c\0W8NN8E--\hS*QIAl7I^Ce
+ ?InF,/HCg<r+1P'@blPk0:*>TUJ']&53map%9M:3EVWI&)'6,Vn8H]u<-\=<Zf)Lo3_?oTA
+ -cLA#o9QR_&9a^'lh^Sim@,p3:Ab$!=/,mG&BT3B"bI-GKkZ*fT2Z27>qdj/=fUOd-nmD-K
+ $Z\75:Hq7M@Z$8>cB27[p`jmMU7.As6>+6CqrV4$J3BSc@D+]!(=msoYT-Vj!1YE=ATA<\a
+ ZuA7[MOI5:&%k^[^KA[LMKOb<d8YDsr1"'5:pLP;h)>4-;i;CgB4U14rak,+7LqW&Rk5-#m
+ q&Z`<$M^9Z&,X<Ro?+*R#9n%6XMffn0n[rT9P\O[g#3GIY>G=7r,C?a_l3@V*7GnRq_GGAQ
+ 9b>S!g;5:M>]Hf/u<)m2V>M?MGrFeL`UC6trhuA=f-d]uUHLS!AS6pe'-\>+3`tN0o^t+3=
+ Ml2C]e7'X6cr!u$Zg^>/!@Jn;P]NDn2"+;r2Xp7uJ<T08i,Z-%'2/Ii'1"=j>%$ZJC#K;=W
+ "p*nr7?R)Pc6WdR#B`k9mQ0[h8LDHf)<9=kfET\W08%Qk>&dr'6q,RbDDl-fXgPs(T:mu:J
+ :Q&Vf=&XE@t2/K;i=T5L,^X"E]loi@/"ZE3dB*EdAP-#e4N@?[ZheK4`sai26h<"+9MNK9P
+ 9PfG?LZf)iu=peNu)C>%lEY/Q*gKPBBMFPRHL;Hge(iJ.')P8/%C>Z6r8H=mhq#aju9YVrZ
+ !pBGgR&91SQSe[tpK"uAUY*8I0E^Hqj(Ts&7MacZ2ACCTY`L3E179<oel=4!-rI*VX`J]tH
+ Te1hdp7b=/8MT5#+`I@oA:Ip!O"CG4"9,>=E,pj!V!ADY#\nol4&8ME5kpD<Kk$kBc;\dm-
+ sP)!0eF?&Mjio@;5];+YQULJ7[ukS@4^$PL/f7@b+$s7'QEVo)kK1E!BT5N:/7S-3^_m0=,
+ TV>9<?+c8D-I>dE,?P@#FR8ppnmPd86*9(qVakDSDL%Y.YR@RkkPV%"EBuKP5%KAe$d4`cD
+ bX(7kq<$U:9t?ReZ<j4mbanDD,cFV:u-8s'J\LTp9<AF(`D!B)<mPAC%f4#a&Zc4'0UGbk@
+ f0/njO0,?o&YW9OiF@cg8^0D%SplE$dUd?XJ%986E&J+94@SS\q\i[@ppK^5e%!9pE'++'F
+ SX^dZLX,'ui<OIV>5Ut0InGXk`=HGtcq,spP:LuQgGc%>(=#:;oUP*!-ZHe@-Ps//$9JRlM
+ G=;^F@jh'*p6Eo7:/q\:..EqkbP%_??a#3'CZP>m4Tc*-cOG(#LCND6UIS;lL:EL.N2QK3.
+ ]<\\W_RuQ64h=3'db4T])OfXp%RYRde4E+t_;)&LiV[`f`@8='D4;-ERpa8J&Bg>ZCK+"9U
+ [d/L#PP8[M<XBT^/SJkh3Pd*R4V2P)$d$:UK7J`fH(@I1N)=ZXCLEXZ5'WZ'O59r*J(-R,e
+ uSR@XjU!S8+Wm8:?-O'+'k(N']+mPkbb_]#lLhf9l(;3Qs_JsHITb_Ar[s/47YrGLip/\uk
+ Ucq0$8Nk@DEaB6GLhLK9=G@S$s#ZuXeKOS0]Jp_9/sI-G&pH)B`hq%ajbC$2GQR'IU/#*;1
+ (`072s#Xq'A6:"eKQ!rp-UFZLmCbE>5/+=V$.-sa<5]D%8RN_rIdqMn`5kg30@Cfs5H_n[>
+ aWs,%QTnW0;"K@4\r&rhT=Pr)(!Ql'r%U,XSj@,>Y%=Z+\q&4T$Q4mISmS7rt6f-ZFZ3MP1
+ ^"0NOd9OD#5bF&=LoK93?l3[_ctU<n?`EYQhk=m)+C@j7U0OV@9JNZ:rZ;G6@A5W?^/M3':
+ V?r#XUq!.jaN\+^u45s!rLrU2)UiMSWr81,;'+l^WcsG'jqj-ji&LTtT/CA\dT2'@5?u^(d
+ ^g:o1n:0ep'-R\LELhJHBKrf$nA0oo3Q0NY1R?@D&3.e5>a#A_e=pA&FAe_K-G^"+(d$`I#
+ \nqB3PiDa?D,4Kd3>gd58S8$s/=F6'&(8!%MkYo3I/\g66=jA>Uh"&[S@IbEff4LLgWLBn"
+ WAt>mj5;cZaDXIp#-N=DLcMJ+!OI:;k'&Om>Cr/P)BNaf5h;,+!ud=t0jeRd(BBk]7pn:'S
+ Sf/a8$H_i@#1I2B\sQT.`26MjWWKmui#[P!@OmS_HQ`TCIC>%$[5eY58<C'g9e]V2j6H,OI
+ 6S6WgL"e$eImC-U34-:62O$4q%>!0&]["oLs$g?Bn1ME-ks!c5d(;u2#/[.6\JNDI\</<Mj
+ -?:lJ]5rb3P6P_gqp@gnU;/%C=Ne$1PA5Y.Q\21>qc;*8M0#rkjQ<jcRnAQ:',)/*N[dDen
+ 3d*=BG_,tPO?_%rI($NSBR3IN#bVf`3mD3"k-B8/YY\pS;8!X,f5SfO0%iC+0o`7/m>\;&N
+ 2#5H0O)&6@72g3hGiYfG>hn:<(.q,./3=\mW_.U?=oK[#Bt4M-uP,(];WD+cc":DrJpWPZc
+ ?>(:(cuNW^^B_q<@/71(Ug(*b1B7H7XUQ3l,a<B1Ti"^e%3Tb-HaZ;M=/PKGc+nrb1(;PMq
+ ?P[3-MK']ilEe:pPI]PQGeT-PFV94F,WJLEq(IX1FWBOYs(:hMC(;\UoCb.&>3-SEKdNjCj
+ 5,P*Tr8O<BZQ#4>'ZP<?m,1TqqiU#O8=YVo.XWqg>5/+=M3c-NF0Wdiqr"[%[>9S20p/Du9
+ Jg9!=PTn!R*eeg%ur#j:8AD1a+=sj/c:,/3@BEm`Ei%-U7`8:3%]`'+tRbsq<+Gk(3c&MLT
+ sjlclRW'LcU+3ad5(,,?jm*7&mM9rX6Cbl<jm;ps0?3A>hqAE@7&#Zq#=:MhJ@"PL%i)GYU
+ Y/$\.>hmUY$<hUcC&=?'Jp'$qdD5_&Lok1-MfCMQl2a!X8FjJ4,Z38oVc,YeOU`f<>7Jm.q
+ r\V7HLK`>Yant6/-EpMGe,B\..M=Zjk/MBK&`>r:+2Rp_sZ0?p4b@*W<(:!@97#R%`_LK:`
+ b4;iL8Vmi<7[N7KC_q9CKeDd)K_BZNal&8>*@H4di\--$eq/VU6<]cO>%$[e<OH3X)qW3K"
+ c7;p:a`;&k:J>h*0#[G?'Q:e=lG$/"s(]]<(++_pMpp\iLU];jTfl7E!D<&A]V]D3.Xe?=a
+ iDROrYXUISn&"nsmmMMVr`2j5eBNH\r0@(>-4fG5gN8iPrFNgc5$YCVcOJ2E(Oci+,@B%kH
+ f;k:Hs&:n#qBHi;WTA]H'Np4HHMUo<3dl&q\C[P$WE@&&Wo)6/4I)qmN+Ieq^%*EtET:JT&
+ (9e=J?:0+4;$d=S>3qli5FE4C'$)*P9%q@%9jB>;Nd'Ac5H"a(4[Jg:Z\h_cuZ64&FctS&+
+ hS":1o&\&9B28H2F8Otl\_3qg-*,KQrfE;,n9s0kd'hh(3d7bl;6m"*:tQ(OBKoJVaV^pBU
+ .$3M7C5I([3ReR5<\J\<3ajjDl'Y]2E+<(9\<6DHLo:Es#khdf@rB#/^VW:p[91eGgOieDV
+ s=.(X8S9St&W=[Bqc7ECO2(IUZDleV;7I`AK/4Ntt9q\FV#1@`euh(r7jnE4,2\M4e$5UBf
+ d`NiB$+94a9[njMkb'5>TaVMo)EOt&D-3dp#_Ms&FFj.jB(Ih5@=I/!]644gZ@BrjD'I-JN
+ 0a`6Xp(RJYc?8ala:Jp9M5:c1]ltjn+7_Y_I^'">"b"sbZ:fIXm"UjOU=,M"DM>T$PUcjV.
+ <tIO<NL!tUq7X>-4'frs?dVne]ToYB,V)o5<]V3-i.1=ZokQNHI."cOJ,e94DnEWnCC]_2B
+ m!0Snq%siQ^;9[B$QJ4or$$?<L`D7ltfgkE3+.)lK#oLaS(!P6[QttkA%i!MJ?!?fIOqh-b
+ `eqIO:5g2isWnW\`C!,LBE/7:3l;:LU!CG]Q5p%k$\-UkI=]juYM?_L;TI'%1QH^Cq)+4`B
+ 5L4+1l,eh,Q*Qf]o)>eW+/e%2W4e@<*4+7C<IrT^TP\phj&pu+.+oEtP_b!Y$p<+^UQM%#9
+ a&8L1mc9:A#rg3b9Foag0pSV0,=CBi>K<]:)I\rT0W.iAnVP5)'Kr$ei4cpTs(AuXm[5W#/
+ LX-QWlT^:7*/OUmpYU%)cYVLMBk_VclBP#"ZI>,XK]FbA]O&)59ikWXc'FFhcN$4;=8q_5p
+ ob/i/jqol4*7/Zj^\p+3dFn4VLs2%YhL17F97krs"--U(h`bnJAHP-g1%MQ1o?GB_#t^GJt
+ ^mWFA7H\G38,Br_Qs/rSkd(Cg`Bg$N-GX4ZuR^5Q9^;?!/&g(+%0T?^k?t_t%A[6P")c^=i
+ "&cc&B#rrdjrk\onlrDu6g,%q;eN<.r?#FpK4m2%DW;H*k&"UjOS:C#.KbOkn$Y2C[SOCe6
+ 4*pZKZj(E;D71NL0k%]pf$59heZ.-NCe/3+:7ZRfaBPM@nF8P[3=0JEt!_3trldh%7LMIG"
+ [!(!B`JK;LdSjYi:R`B1V^2#iR=h]TC3q"m8&#?9OB2(I:#K,)3#%2HD"&fg%n-#QTgh@GO
+ \uSbNtbJPblNef8;mBB'X5RaX>&s51d:b!I@H;SW_(oq`[Yj1MDhj37dC"dT^mT8[MJJtc.
+ ]^F9D>2OYXaDn+R,ltp%:Isr-2H-`WbleT`I=\\LU_!8&kj/D:hn=ZL,]G3H8[jY'>-'"8s
+ cY#C*Nh*!u_s^7`:Y)>]Gm:Z0T\-^58nWPJO/gB*K:Arl_=6f(@T>@7goc(Ds14(g=Wq<Ff
+ ^2'XYOft%Mkg>bj`^1F7([kTcH%J2_e?[M\$:"ZUreu/XU4h-"1Gfu5TP+R+b>bcoLZ5:L*
+ p7%Qe(UcL[E7n4^2;Z>iX.ruX(4a\.E&%mP7>'kJKZ_^,i/BlUY]Nc=*uR(i&"k]uU_@G4"
+ ]au`Ops/uqGU'p`3ZHG%ElHWQ9/gXZ'8Pe-eRW20NGl!W/YkeaNR4_IUIZUe#,ugH[DSb=0
+ MqVRl>7h>E;aJ(WAdr#C&t#nt-i_jd[7RQQGNQQ`\$><N!^Si'Nn0lTu*V,nq>X"LU$NI5#
+ ?'NjR]A^Q'(th[=_D"J$ZTS1ck["a7]WZ6`Uer]\H64i1l^JDkfu>*Pk`+%s^^8&8)ES;Gs
+ D('`KA*g>%$;U9Q0_FM^\[C))'FS5M'laqB0mb+pnBhG+dMk0lYLB(CkNh]0DYkoDae(OFU
+ CHQ]^qWkUY(qj5B"u]3]23FOq$oEcS3DVXQ/gkMQ:3O4!+0@eg`M]Q02s.?5B/&o3Bh8dQi
+ >*n\L(bR"'J))U1XT6D18DmC"]ZYsJ*GqrfQb29s&gcjQI\6Fo&S5q$ahjA7t_*#S'iZ&Wq
+ s'HK@jcl>tcI/BX.9"KjM."6&);4=Zq%J?o&$eblm^uLmA8F+k@k/HQg]OY*0<<Lm))%\&f
+ t@@p-hsN/FLtVE&G2=K,"P;K=Wk[*p%6VDI(lY-DAX<-e$1VT/JqK?a,K++_H"hS"",o^Q:
+ 4D[Z:3Zt@]:FB(<oVL]6$@!fd^)m'9[c#Ra9r?:g>LmH.jZTjHcjL]tMX@;9\6Z+PC-`qjW
+ :B$)[SW5OY[jf3hH\R6SYHbAp6ciMIr'\g"QMP@T!PUQEdf/+4kMa;`n2^&Bq&@)Q+:`QGO
+ !"DVdaD+*V;-Rc,[2K6.m5aS4'&!prHgVY=a!t?:>4ChZp-npB;:IT-!QRI\NoQ(rsDM_'S
+ XcQT-8q(5'g@q[DQF2@\P]5Tk$qtY_JL98iXk4AP1tP,=h1W]_V-[bKkV/#ZAJsX2'5+K*V
+ ,h)JV0s(T,-k33[M,Fk&Uu%72$O@;Ngu#9BBO,9\YH;5.7*W9r/Cfa2Ii:a_m$RgM3uG1Vb
+ ];Y;tKnmj/SBaV:*"ZK)#W41O(Pkcn*%6(FrH1pkZ*#>@=Ar3mf9?b`Mh7ME\khqct_Bn_,
+ Ca5C$Y1b]grD9q"388DLK.`RX_u?<S3\Tk2*/kZ$h\8)`peFRVE0BF`&S\3_@%oL2@"L1/_
+ 3(VY@EFnqmC"Qc?=SE.j\+e:m=#1N4bIEFE4%rOR$Oo#2GB#BJX-XM"&)?`Si^#siF($r%u
+ u$g(7F%rH+UX53&qXd`-2iF3RL?eY\AudQHV&OaZj\lL/'@,m!AX,("UM;anAm^/O<=*0J,
+ S6pf`!;Q@1R*+ZQo`%:4t:mu+ha,#5@60m&Ro_/mK3SBQ3,Qt`PBiAko+=3#G=\5nok0J,F
+ N4lfdSl[ih2(N"OAC0;dYjZ"phQZ>hHo33G@QXIm(j<U*&Rommk(IQSEItA?=PL%sR12&8D
+ FWo?<>F55F:b@t3pf\q$\h_#XnoJ)uhukqcW"VXtRneQf7Q@Z:md>j;eVTrbhVMQN/[0B6[
+ (t6]P*TKDb:us(H2'&a]-BNVDJ5)bZ%s("J)ZE,S\QQfErqi`iH0Yd[[>_!fD":DF)ik:FW
+ &PhmuC)"C8/5sJ$X7U^Wc//4Bs/*4lXC"F&MF9J2r2*$+U^oqhDonOVZT\ODBEL$e"-GPNY
+ 'lQAT4%O6#7DFb3AG&LS;W#$GiTo80$Rk%+7XODAhoU,hM=@TpWo!?J$@:5aEd[#cpUao"'
+ =r/r828"JjV\`kYad-rtkL/+8cn,te'c&'Z8n?p(3>q*2N"$/b#,&sd0Dj/BuBgV])#3H$r
+ :Soi\SI(foPN"7;@u!n(rVQWaj'33KfHcodV+*$659Ii"OXp#b-*L'OF7M4,c?G6+UfcCY>
+ JLP'.@(2ddV'5RF8nS7g_8(UQno<#ER-M'iJT7ok;tsG!St+-XAf;G\=l&MN0QaX=Rh`8Lp
+ \pUj'3QUV`;c.VtPYGX$q&BcQ!5XTbC?k-XS<]rPB2p+qWqCm<)FA9Qe=^E8t2>WMh-VBjI
+ BtB"n?ukJuHK6KCNoN.k"B3,6Z*(Q1_PI-o:0W!ZU!Y_NlM[KP>@n\]ir/]X_5>2%!K_apf
+ SSl+pN57k+<%-uouck`J^[P#F#S/q:PHmTbd3#IR-rsTl!9n&b#Vkml3BGkNXrD8c8(4Me>
+ bgc;D2[H]&)-cb5%&%aM+E9$6V*5/ANYsE:::O`6A1',=m>%_:!M-/)d5Y2Xa[rhU=-$#_C
+ gBN8(($\JW"Y#]rQ'#2("#pAYSN\#Q?1,RDSDDS3*Nn(I:m-M"?%VO:)mr)pA4%qEY-q8<C
+ ml'MeG,oe\V>e@9bDWSC+<)dYSAV-haL&)0-DE%ol1;rYo6KZJDo7BS!;/kg1MBBTFb55UY
+ OS:,`+2%\)+-XRGkL(2fWm;%";hO_PcEXiolYm`ZAg,.F9E:mH.]5GgkBGiq;H4,Lta2#<2
+ V/^g015f497im(Mp'0-TjLT7-Us%1OnLhdlb!?G<VD^OZNRhUeLZkmpAEgm`*+q"@(ZoAZa
+ r$ToJJuD4Z@O`#1_WQpul%tAHl3&WsV4rP1J#5#3VLorC;Gk+mS3'Ua(8X$RJNB2Pi.PX=r
+ TJFA0AQ%=e)G4^&8]Z"@iL0W9>+<S*[''U,"\Ikf1D(bd/IgQaH4^l$ND,g<Mu;M#MLqF3#
+ W';62#=,`jtae7*?B"mYl`Op</@bMj"`iWi7'=3>"s.(4T/=^%Nh0Ws,paEi;FDM$u]uUFE
+ PlWff"4(Hs40Cu(;9C;HK0i`bE=FW#"/Di]WhZ9=<nT1'Cl'58'5b:S3I,bN-hEMCZ!:Ir@
+ TZ0VUo_4;8(("!(eQXdZf=12<%:Lr+A314NW,_ma&jKkWirs*`Hs+PLu9h^I=p06O3p@]](
+ IJL\<%cTlo:LqOZ8T@LY+fOKfLf'Yg3KZj0/]/\0'0F#s2KYi[^6:8ag(.0qBgH,'K1r!Cp
+ N#GYBPEVupb.(?A!\^l$+@?rSD4]u_LIOXj^\ok'^%M3C#V5STp?/#J54*W7H1#SYS6(T9#
+ 9<7j,c>?;do#/(6KC3c@>@cMW'?j_kr./M,5$^YOL\h7Z$GAN/.*o<<QKeSc8gGM.1I3&ga
+ 9KodcXJ&J&AkS1r+!GpbA+PhZ\G`LS/)gc-,!if1SXPpN(lLV&n"&ZM(ih91csg']n9-^H'
+ a\DrFYL3eFr9u1.CIEI@/OWg>cUrA%alXN6DBgHq*B"Mj=m/0()j(k2!+`bF1@gS[XdM-Qk
+ e_R1Nr[S]Q3>(UW&^F_N!A2j#QF`bR-\<;W&j)M!U.dQbSrtT$\&UWZ_?&1!i(th^Q9h]+O
+ ublU`MaI&SFFEu>UNJfqiscopi"IidDGcI`,oNC2l<F#qNks55ER*)g3X3]p5[5+aq6"p<+
+ nKI7=7iua$Ecad"W.taM9kbieFXJ&EcHW#jqGG48^cJ:3IUjMKZp5AGtt>F;A<[c_NSbWkb
+ lNL(iu8&M"/kUhO,U6@2Z%`?"qe0bq\<B+\it@Ht]k!iJI"[(t5re+-Z)7)YXPLA$9qW6ek
+ *7=7iuf9,f]LmcP13%`"S^t+4;K`e?lO_Kr6(@luN;J7_(,"%g<*ND+;[N[p`![lB(c:kAV
+ B.X-9]^L\JY=4o,T%"&]`lbs8c\ZUJjFWmOU7iqMF[Wu.K1.D[(8C;*r'Ua'BFgY1TtT4sa
+ Z0t$;NVV.k76k?QCnBhkTklUi[6KDdD[+aSF99%1?>hgSJ*`HiM[i9O/HP&#@C,N!9bCrB^
+ \2bYglgI9SK`l>XVcJkW+b*)ohW4%,k,R$iqpl6K.s$l%kG-*,o)]d%4Fr)0$tQpI(YiH^u
+ Fj2YI25mYb=.$&&<i`Y%iXo`Zq]TYVT!#sXB6\@=n[Z1;$q/JZt&`n5#PZ%ZNt"h!]b!GY!
+ <T`@pT%I/>&$iXVM#H4kjEcHjAm712K?7KtP$?Im4e)CQiq17F9J--tQ:Cd0M'3'7/?en#1
+ /QcclZLOJnTfoq"=o\AlMQDWZM-t\@K5?N6*>i5Y>V4XsgA=8$B;/OQP,ppZ+4q>;IeEg^-
+ \2U@Yhg.sZ32]&h^"WFM.Q&`U16sn@4W?,:E7<C:gr\r.\cF)D5:[FX,;#0G4[IM6q\_.1N
+ Tkq^*(<,Oj':&/3`2WIpD+-.ErK99`29Qr*?Vub66Dh3NPA0L8EaQ)/e/-BKu?Nn=0cqYio
+ Yu(LkDj[5/)pU!74cXdl3#Rq'eVb%QhomZ'5SQ=08GhY=olk)J'<[Rd0!rW\)*FB?%fLC&W
+ M<+nLbMC?bm@Hoo=W?J0s*1>cGn6r+OcX%jH8Mf70k;SF[_'"&P#efJLH<ggT=,t+OBmT:;
+ ca?a`[8?NP<h>!3N(#p\:7]HC<CM:1"PrllD@js&"kst#>3WuXW[HGu04eq&F4W#5TG;b#f
+ !s27?$0&u>*5+c!N%>1`lcR2MYrQQ"r5jQ`ZigiAZ"p/c1&'doeG!cDQ4aiXu=I$IBfR04D
+ Tp:f'9NKRf4W`du9Ms%@#LkMDdNBM2IcK,ErQ&7rK",r3t-TFZ$$j1"Dh0Y2d>rpFoM8A12
+ ^@.8D`uoUm^02H4cWSD^&)_3R!q8o)'c:!(q;*pW,^Ks@DbnAB`O(OHqBc;;cBTeVt3aYm+
+ Ad";FVJt:233uut;N47:TDkT&69M8fgY);O5UU9*l?T+3H:.BYgS.dnf=1p.62K7A\4&\:8
+ ?"Hro#nq$12Dc^QD1m\Tju?<4Db\cr1XT1+1fS\(A?AO.\:%;pOiBF3N#`9P)!>3bhpL4Y^
+ \-cLOhh')N]&F_,t$5OkUPJqeA!k;rl.4b)huKoVRgLP-Mh%D<k0*kGPtEbj3!Y-s)q=9`^
+ oX-]R9P7o&U6,:UKQej0ti:\WO`-5*K8GB^1m7RLr95Fs>DScGJDb.P5dO8\pjqhfdkeH/m
+ T,Vf1J*l0n)=S;`Ti#BW+Ihql%pX0_1u91s?BO88+nXNFYZ,^B18`;&"7aU.S!AlW^sqeP)
+ \LAKVNp\oI;lkqX73Ka"7"0.*ZplPpeoBOl,41B.a\oI+(8)'Y9^GjYCDm.sgl]/(pO1-/p
+ G4a1W8'delLVF'<_>]\#Is.iH]0;nl!PEdR%d@;k,PC]ndp"bLG'A-pIf/uWrVNd*^OH(R/
+ N)"N$7cMn_uN@o1JghB:JYnI0-#&i^OK%%YZ-Gnp2Jt,2Wb"ri$7Q[N[h'-U5CG#W1o/!Wi
+ 2YLWaW%0#A*92"o~>
+Q
+0 g
+BT
+22 0 0 22 298.411426 279.754358 Tm
+/f-0-0 1 Tf
+[(Ar)21(e)]TJ
+-0.272461 -1 Td
+[(they)]TJ
+-0.536133 -1 Td
+[(equal?)]TJ
+ET
+Q q
+0 g
+2.4 w
+0 J
+0 j
+[] 0.0 d
+4 M q 1 0 0 -1 0 790.399963 cm
+316.762 33.48 m 316.762 86.008 l S Q
+q 1 0 0 -1 0 790.399963 cm
+316.762 147.812 m 316.762 199.551 l S Q
+q 1 0 0 -1 0 790.399963 cm
+256.559 257.719 m 139.379 257.719 l 139.379 365.215 l S Q
+q 1 0 0 -1 0 790.399963 cm
+378.305 257.715 m 495.484 257.715 l 495.484 365.211 l S Q
+q 1 0 0 -1 0 790.399963 cm
+225.398 398.059 m 316.828 397.484 l 316.828 474.172 l S Q
+q 1 0 0 -1 0 790.399963 cm
+377.992 533.152 m 495.168 533.152 l 495.168 640.648 l S Q
+q 1 0 0 -1 0 790.399963 cm
+255.668 532.582 m 138.488 532.582 l 138.488 640.078 l S Q
+q 1 0 0 -1 0 790.399963 cm
+255.688 674.629 m 373.973 674.629 l S Q
+q 1 0 0 -1 0 790.399963 cm
+316.828 674.629 m 316.828 752.344 l S Q
+q 1 0 0 -1 0 790.399963 cm
+495.113 422.059 m 495.113 451.77 l 332.828 451.199 l 332.828 451.199 317.516
+ 429.449 301.457 451.18 c 138.828 451.484 l 138.543 532.629 l S Q
+1 0.890196 0.815686 rg
+187.742 549.427 m 212.887 549.427 l 221.75 549.427 228.887 542.291 228.887
+ 533.427 c 228.887 524.564 221.75 517.427 212.887 517.427 c 187.742 517.427
+ l 178.879 517.427 171.742 524.564 171.742 533.427 c 171.742 542.291 178.879
+ 549.427 187.742 549.427 c h
+187.742 549.427 m f
+0 g
+BT
+22 0 0 22 182.028894 526.571399 Tm
+/f-0-0 1 Tf
+(Y)Tj
+ET
+0.8 w
+q 1 0 0 -1 0 790.399963 cm
+181.98 247.797 m 184.309 247.797 l 188.762 254.391 l 193.184 247.797 l 
+195.512 247.797 l 189.84 256.188 l 189.84 263.828 l 187.652 263.828 l 187.652
+ 256.188 l h
+181.98 247.797 m S Q
+BT
+22 0 0 22 192.556238 526.571399 Tm
+/f-0-0 1 Tf
+(e)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+204.914 257.312 m 204.914 258.281 l 195.836 258.281 l 195.918 259.648 196.324
+ 260.691 197.055 261.406 c 197.793 262.117 198.82 262.469 200.133 262.469
+ c 200.891 262.469 201.625 262.375 202.336 262.188 c 203.043 262.004 203.75
+ 261.719 204.461 261.344 c 204.461 263.219 l 203.75 263.523 203.02 263.754
+ 202.273 263.906 c 201.531 264.059 200.777 264.141 200.008 264.141 c 198.09
+ 264.141 196.566 263.586 195.445 262.469 c 194.328 261.348 193.773 259.836
+ 193.773 257.938 c 193.773 255.961 194.305 254.391 195.367 253.234 c 196.426
+ 252.082 197.859 251.5 199.664 251.5 c 201.285 251.5 202.57 252.023 203.508
+ 253.062 c 204.441 254.105 204.914 255.523 204.914 257.312 c h
+202.945 256.734 m 202.922 255.652 202.613 254.793 202.023 254.156 c 201.438
+ 253.512 200.66 253.188 199.695 253.188 c 198.59 253.188 197.703 253.504
+ 197.039 254.125 c 196.371 254.742 195.988 255.617 195.898 256.75 c h
+202.945 256.734 m S Q
+BT
+22 0 0 22 206.091394 526.571399 Tm
+/f-0-0 1 Tf
+(s)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+215.84 252.156 m 215.84 254.016 l 215.277 253.738 214.691 253.523 214.09
+ 253.375 c 213.484 253.23 212.863 253.156 212.23 253.156 c 211.238 253.156
+ 210.5 253.309 210.012 253.609 c 209.52 253.914 209.277 254.367 209.277 
+254.969 c 209.277 255.43 209.453 255.789 209.809 256.047 c 210.16 256.309
+ 210.863 256.559 211.918 256.797 c 212.605 256.938 l 214 257.242 214.996
+ 257.668 215.59 258.219 c 216.18 258.762 216.48 259.527 216.48 260.516 c
+ 216.48 261.633 216.035 262.52 215.152 263.172 c 214.266 263.82 213.051 
+264.141 211.512 264.141 c 210.863 264.141 210.191 264.074 209.496 263.953
+ c 208.797 263.828 208.055 263.641 207.277 263.391 c 207.277 261.344 l 208.004
+ 261.73 208.723 262.02 209.434 262.203 c 210.148 262.391 210.855 262.484
+ 211.543 262.484 c 212.477 262.484 213.199 262.328 213.699 262.016 c 214.195
+ 261.695 214.449 261.242 214.449 260.656 c 214.449 260.129 214.266 259.719
+ 213.902 259.438 c 213.535 259.148 212.742 258.867 211.527 258.594 c 210.84
+ 258.438 l 209.609 258.18 208.723 257.781 208.184 257.25 c 207.641 256.723
+ 207.371 255.984 207.371 255.047 c 207.371 253.926 207.77 253.055 208.574
+ 252.438 c 209.375 251.816 210.512 251.5 211.98 251.5 c 212.719 251.5 213.406
+ 251.559 214.043 251.672 c 214.688 251.777 215.285 251.941 215.84 252.156
+ c h
+215.84 252.156 m S Q
+1 0.890196 0.815686 rg
+186.602 274.685 m 211.742 274.685 l 220.605 274.685 227.742 267.548 227.742
+ 258.685 c 227.742 249.822 220.605 242.685 211.742 242.685 c 186.602 242.685
+ l 177.734 242.685 170.602 249.822 170.602 258.685 c 170.602 267.548 177.734
+ 274.685 186.602 274.685 c h
+186.602 274.685 m f
+0 g
+BT
+22 0 0 22 180.886035 251.828577 Tm
+/f-0-0 1 Tf
+(Y)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+180.84 522.539 m 183.168 522.539 l 187.621 529.133 l 192.043 522.539 l 
+194.371 522.539 l 188.699 530.93 l 188.699 538.57 l 186.512 538.57 l 186.512
+ 530.93 l h
+180.84 522.539 m S Q
+BT
+22 0 0 22 191.413379 251.828577 Tm
+/f-0-0 1 Tf
+(e)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+203.773 532.055 m 203.773 533.023 l 194.695 533.023 l 194.777 534.391 195.184
+ 535.434 195.914 536.148 c 196.652 536.859 197.68 537.211 198.992 537.211
+ c 199.75 537.211 200.484 537.117 201.195 536.93 c 201.902 536.746 202.609
+ 536.461 203.32 536.086 c 203.32 537.961 l 202.609 538.266 201.879 538.496
+ 201.133 538.648 c 200.391 538.801 199.637 538.883 198.867 538.883 c 196.949
+ 538.883 195.426 538.328 194.305 537.211 c 193.188 536.09 192.633 534.578
+ 192.633 532.68 c 192.633 530.703 193.164 529.133 194.227 527.977 c 195.285
+ 526.824 196.719 526.242 198.523 526.242 c 200.145 526.242 201.43 526.766
+ 202.367 527.805 c 203.301 528.848 203.773 530.266 203.773 532.055 c h
+201.805 531.477 m 201.781 530.395 201.473 529.535 200.883 528.898 c 200.297
+ 528.254 199.52 527.93 198.555 527.93 c 197.449 527.93 196.562 528.246 195.898
+ 528.867 c 195.23 529.484 194.848 530.359 194.758 531.492 c h
+201.805 531.477 m S Q
+BT
+22 0 0 22 204.948535 251.828577 Tm
+/f-0-0 1 Tf
+(s)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+214.699 526.898 m 214.699 528.758 l 214.137 528.48 213.551 528.266 212.949
+ 528.117 c 212.344 527.973 211.723 527.898 211.09 527.898 c 210.098 527.898
+ 209.359 528.051 208.871 528.352 c 208.379 528.656 208.137 529.109 208.137
+ 529.711 c 208.137 530.172 208.312 530.531 208.668 530.789 c 209.02 531.051
+ 209.723 531.301 210.777 531.539 c 211.465 531.68 l 212.859 531.984 213.855
+ 532.41 214.449 532.961 c 215.039 533.504 215.34 534.27 215.34 535.258 c
+ 215.34 536.375 214.895 537.262 214.012 537.914 c 213.125 538.562 211.91
+ 538.883 210.371 538.883 c 209.723 538.883 209.051 538.816 208.355 538.695
+ c 207.656 538.57 206.914 538.383 206.137 538.133 c 206.137 536.086 l 206.863
+ 536.473 207.582 536.762 208.293 536.945 c 209.008 537.133 209.715 537.227
+ 210.402 537.227 c 211.336 537.227 212.059 537.07 212.559 536.758 c 213.055
+ 536.438 213.309 535.984 213.309 535.398 c 213.309 534.871 213.125 534.461
+ 212.762 534.18 c 212.395 533.891 211.602 533.609 210.387 533.336 c 209.699
+ 533.18 l 208.469 532.922 207.582 532.523 207.043 531.992 c 206.5 531.465
+ 206.23 530.727 206.23 529.789 c 206.23 528.668 206.629 527.797 207.434 
+527.18 c 208.234 526.559 209.371 526.242 210.84 526.242 c 211.578 526.242
+ 212.266 526.301 212.902 526.414 c 213.547 526.52 214.145 526.684 214.699
+ 526.898 c h
+214.699 526.898 m S Q
+1 0.890196 0.815686 rg
+422.027 275.142 m 447.172 275.142 l 456.035 275.142 463.172 268.005 463.172
+ 259.142 c 463.172 250.279 456.035 243.142 447.172 243.142 c 422.027 243.142
+ l 413.164 243.142 406.027 250.279 406.027 259.142 c 406.027 268.005 413.164
+ 275.142 422.027 275.142 c h
+422.027 275.142 m f
+0 g
+BT
+22 0 0 22 419.743164 251.142834 Tm
+/f-0-0 1 Tf
+(N)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+421.898 523.227 m 424.82 523.227 l 431.93 536.633 l 431.93 523.227 l 434.039
+ 523.227 l 434.039 539.258 l 431.117 539.258 l 424.008 525.836 l 424.008
+ 539.258 l 421.898 539.258 l h
+421.898 523.227 m S Q
+BT
+22 0 0 22 436.200195 251.142834 Tm
+/f-0-0 1 Tf
+(o)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+442.934 528.617 m 441.871 528.617 441.031 529.031 440.418 529.852 c 439.801
+ 530.676 439.496 531.812 439.496 533.258 c 439.496 534.695 439.801 535.832
+ 440.418 536.664 c 441.031 537.488 441.871 537.898 442.934 537.898 c 443.984
+ 537.898 444.816 537.484 445.434 536.648 c 446.047 535.816 446.355 534.688
+ 446.355 533.258 c 446.355 531.832 446.047 530.703 445.434 529.867 c 444.816
+ 529.035 443.984 528.617 442.934 528.617 c h
+442.934 526.93 m 444.648 526.93 446 527.496 446.98 528.617 c 447.957 529.734
+ 448.449 531.281 448.449 533.258 c 448.449 535.227 447.957 536.777 446.98
+ 537.898 c 446 539.016 444.648 539.57 442.934 539.57 c 441.203 539.57 439.848
+ 539.016 438.871 537.898 c 437.902 536.777 437.418 535.227 437.418 533.258
+ c 437.418 531.281 437.902 529.734 438.871 528.617 c 439.848 527.496 441.203
+ 526.93 442.934 526.93 c h
+442.934 526.93 m S Q
+1 0.890196 0.815686 rg
+420.887 549.427 m 446.027 549.427 l 454.895 549.427 462.027 542.294 462.027
+ 533.427 c 462.027 524.564 454.895 517.427 446.027 517.427 c 420.887 517.427
+ l 412.023 517.427 404.887 524.564 404.887 533.427 c 404.887 542.294 412.023
+ 549.427 420.887 549.427 c h
+420.887 549.427 m f
+0 g
+BT
+22 0 0 22 418.600293 525.428577 Tm
+/f-0-0 1 Tf
+(N)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+420.758 248.941 m 423.68 248.941 l 430.789 262.348 l 430.789 248.941 l 
+432.898 248.941 l 432.898 264.973 l 429.977 264.973 l 422.867 251.551 l 
+422.867 264.973 l 420.758 264.973 l h
+420.758 248.941 m S Q
+BT
+22 0 0 22 435.057324 525.428577 Tm
+/f-0-0 1 Tf
+(o)Tj
+ET
+q 1 0 0 -1 0 790.399963 cm
+441.793 254.332 m 440.73 254.332 439.891 254.746 439.277 255.566 c 438.66
+ 256.391 438.355 257.527 438.355 258.973 c 438.355 260.41 438.66 261.547
+ 439.277 262.379 c 439.891 263.203 440.73 263.613 441.793 263.613 c 442.844
+ 263.613 443.676 263.199 444.293 262.363 c 444.906 261.531 445.215 260.402
+ 445.215 258.973 c 445.215 257.547 444.906 256.418 444.293 255.582 c 443.676
+ 254.75 442.844 254.332 441.793 254.332 c h
+441.793 252.645 m 443.508 252.645 444.859 253.211 445.84 254.332 c 446.816
+ 255.449 447.309 256.996 447.309 258.973 c 447.309 260.941 446.816 262.492
+ 445.84 263.613 c 444.859 264.73 443.508 265.285 441.793 265.285 c 440.062
+ 265.285 438.707 264.73 437.73 263.613 c 436.762 262.492 436.277 260.941
+ 436.277 258.973 c 436.277 256.996 436.762 255.449 437.73 254.332 c 438.707
+ 253.211 440.062 252.645 441.793 252.645 c h
+441.793 252.645 m S Q
+Q Q
+showpage
+%%Trailer
+end restore
+%%EOF
diff --git a/mgltex/Recompilation_decision.pdf b/mgltex/Recompilation_decision.pdf
new file mode 100644 (file)
index 0000000..cff8a13
Binary files /dev/null and b/mgltex/Recompilation_decision.pdf differ
diff --git a/mgltex/Recompilation_decision.svg b/mgltex/Recompilation_decision.svg
new file mode 100644 (file)
index 0000000..deabd7d
--- /dev/null
@@ -0,0 +1,1560 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   inkscape:version="0.91 r"
+   version="1.1"
+   id="svg2"
+   viewBox="0 0 788.07224 987.99994"
+   height="278.83554mm"
+   width="222.4115mm"
+   sodipodi:docname="Recompilation_decision.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker5662"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5664"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <inkscape:path-effect
+       effect="bend_path"
+       id="path-effect4543"
+       is_visible="true"
+       bendpath="m 118.00024,456.39849 222,0"
+       prop_scale="1"
+       scale_y_rel="false"
+       vertical="false" />
+    <inkscape:path-effect
+       effect="sketch"
+       id="path-effect4541"
+       is_visible="true"
+       nbiter_approxstrokes="5"
+       strokelength="100"
+       strokelength_rdm="0.3;1"
+       strokeoverlap="0.3"
+       strokeoverlap_rdm="0.3;1"
+       ends_tolerance="0.1;1"
+       parallel_offset="5;1"
+       tremble_size="5;1"
+       tremble_frequency="1"
+       nbtangents="5"
+       tgt_places_rdmness="1;1"
+       tgtscale="10"
+       tgtlength="100"
+       tgtlength_rdm="0.3;1" />
+    <inkscape:path-effect
+       effect="envelope"
+       id="path-effect4539"
+       is_visible="true"
+       yy="true"
+       xx="true"
+       bendpath1="m 225.41095,441.11923 114.58929,0"
+       bendpath2="m 340.00024,441.11923 0,101.24298"
+       bendpath3="m 225.41095,542.36221 114.58929,0"
+       bendpath4="m 225.41095,441.11923 0,101.24298" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="-6.0542683 : 531.67714 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="718.04023 : 477.85825 : 1"
+       inkscape:persp3d-origin="345.99297 : 302.46455 : 1"
+       id="perspective8810" />
+    <marker
+       inkscape:stockid="TriangleOutS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="TriangleOutS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4367"
+         d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="StopS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="StopS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4394"
+         d="M 0,5.65 0,-5.65"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.2,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker7593"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path7595"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker7373"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path7375"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker7159"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path7161"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6951"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path6953"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6743"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path6745"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6541"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path6543"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker6167"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path6169"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker6007"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow2Mend">
+      <path
+         transform="scale(-0.6,-0.6)"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         id="path6009"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lstart"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4219"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker5593"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow2Mend">
+      <path
+         transform="scale(-0.6,-0.6)"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         id="path5595"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker5451"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow2Mend">
+      <path
+         transform="scale(-0.6,-0.6)"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         id="path5453"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker5315"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow2Mend">
+      <path
+         transform="scale(-0.6,-0.6)"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         id="path5317"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker5197"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow2Mend">
+      <path
+         transform="scale(-0.6,-0.6)"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         id="path5199"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Sstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Sstart"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4249"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(0.3,0,0,0.3,-0.69,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Send"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Send"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4252"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-0.3,0,0,-0.3,0.69,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker4979"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4981"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="TriangleOutL"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4361"
+         d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="scale(0.8,0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4240"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lstart"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4237"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(1.1,0,0,1.1,1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4222"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Mend"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path13789"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+         transform="matrix(-0.4,0,0,-0.4,-4,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <symbol
+       id="Terminal">
+      <title
+         id="title7859">Terminal/Interrupt</title>
+      <desc
+         id="desc7861">A terminal point in a flowchart: start, stop, halt, etc.</desc>
+      <path
+         d="m 35,95 a 20,20 0 0 1 0,-40 l 80,0 a 20,20 0 0 1 0,40 z"
+         style="stroke-width:2"
+         id="path7863"
+         inkscape:connector-curvature="0" />
+    </symbol>
+    <symbol
+       id="AuxillaryOp">
+      <title
+         id="title7838">Auxiliary Operation</title>
+      <desc
+         id="desc7840">Offline operation.</desc>
+      <rect
+         x="35"
+         y="35"
+         width="80"
+         height="80"
+         style="stroke-width:2"
+         id="rect7842" />
+    </symbol>
+    <symbol
+       id="Decision">
+      <title
+         id="title7815">Decision</title>
+      <desc
+         id="desc7817">A decision or switching type operation.</desc>
+      <path
+         d="M 15,75 75,35 135,75 75,115 Z"
+         style="stroke-width:2"
+         id="path7819"
+         inkscape:connector-curvature="0" />
+    </symbol>
+    <symbol
+       id="InputOutput">
+      <title
+         id="title7780">Input/Output</title>
+      <desc
+         id="desc7782">General input/output functions.</desc>
+      <path
+         d="m 35,35 100,0 -20,80 -100,0 z"
+         style="stroke-width:2"
+         id="path7784"
+         inkscape:connector-curvature="0" />
+    </symbol>
+    <symbol
+       id="Buffer_Small">
+      <title
+         id="title7212">Buffer Small</title>
+      <path
+         d="m 37.711573,40 25,10 -25,10 z"
+         id="path7214"
+         inkscape:connector-curvature="0" />
+    </symbol>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5206">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5208" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5210" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5212" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5214" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5216" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5218">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5220" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5222" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5224"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5226" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5228" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5230">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5232" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5234" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5236" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5238" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5240" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5242">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5244" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5246" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5248"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5250" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5252" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5254">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5256" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5258" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5260" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5262" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5264" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5266">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5268" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5270" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5272"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5274" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5276" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5278">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5280" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5282" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5284" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5286" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5288" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5290">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5292" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5294" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5296"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5298" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5300" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5302">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5304" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5306" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5308" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5310" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5312" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5314">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5316" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5318" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5320"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5322" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5324" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5326">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5328" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5330" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5332" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5334" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5336" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5338">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5340" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5342" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5344"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5346" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5348" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5350">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5352" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5354" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5356" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5358" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5360" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5362">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5364" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5366" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5368"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5370" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5372" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5374">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5376" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5378" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5380" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5382" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5384" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5386">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5388" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5390" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5392"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5394" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5396" />
+    </filter>
+    <filter
+       inkscape:menu-tooltip="Pressed metal with a rolled edge"
+       inkscape:menu="Bevels"
+       inkscape:label="Pressed Steel"
+       style="color-interpolation-filters:sRGB"
+       id="filter5398">
+      <feGaussianBlur
+         result="result1"
+         stdDeviation="3"
+         id="feGaussianBlur5400" />
+      <feBlend
+         in2="result1"
+         result="result5"
+         mode="multiply"
+         in="result1"
+         id="feBlend5402" />
+      <feGaussianBlur
+         in="result5"
+         result="result6"
+         stdDeviation="1"
+         id="feGaussianBlur5404" />
+      <feComposite
+         result="result8"
+         in2="result5"
+         in="result6"
+         operator="xor"
+         id="feComposite5406" />
+      <feComposite
+         in="result6"
+         result="fbSourceGraphic"
+         operator="xor"
+         in2="result8"
+         id="feComposite5408" />
+      <feSpecularLighting
+         in="fbSourceGraphic"
+         result="result1"
+         lighting-color="#ffffff"
+         surfaceScale="2"
+         specularConstant="2.20000005"
+         specularExponent="55"
+         id="feSpecularLighting5410">
+        <fePointLight
+           x="-5000"
+           y="-10000"
+           z="20000"
+           id="fePointLight5412" />
+      </feSpecularLighting>
+      <feComposite
+         in2="fbSourceGraphic"
+         in="result1"
+         result="result2"
+         operator="in"
+         id="feComposite5414" />
+      <feComposite
+         in="fbSourceGraphic"
+         result="result4"
+         operator="arithmetic"
+         k2="2"
+         k3="1"
+         in2="result2"
+         id="feComposite5416"
+         k1="0"
+         k4="0" />
+      <feComposite
+         in2="result4"
+         in="result4"
+         operator="in"
+         result="result91"
+         id="feComposite5418" />
+      <feBlend
+         mode="darken"
+         in2="result91"
+         id="feBlend5420" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-maximized="1"
+     inkscape:window-y="24"
+     inkscape:window-x="65"
+     inkscape:window-height="876"
+     inkscape:window-width="1535"
+     inkscape:snap-grids="false"
+     showguides="true"
+     inkscape:snap-bbox="false"
+     showgrid="true"
+     inkscape:current-layer="svg2"
+     inkscape:document-units="px"
+     inkscape:cy="496.39986"
+     inkscape:cx="327.57307"
+     inkscape:zoom="0.70000001"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     borderlayer="false"
+     inkscape:snap-to-guides="false"
+     inkscape:snap-intersection-paths="false"
+     inkscape:snap-page="false"
+     inkscape:snap-perpendicular="true"
+     inkscape:object-paths="false"
+     inkscape:object-nodes="false"
+     inkscape:snap-object-midpoints="false"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-center="true"
+     inkscape:snap-global="false"
+     inkscape:connector-spacing="26"
+     inkscape:snap-others="true"
+     inkscape:snap-nodes="false"
+     inkscape:snap-bbox-midpoints="false"
+     inkscape:bbox-paths="false"
+     inkscape:bbox-nodes="false"
+     inkscape:snap-bbox-edge-midpoints="false"
+     inkscape:snap-text-baseline="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid15208"
+       spacingx="20"
+       spacingy="20"
+       dotted="false"
+       empspacing="0"
+       originx="84.535615"
+       originy="-34.500034" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(56.035869,-48.362179)" />
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5398)"
+     id="rect15298"
+     width="100"
+     height="39.999996"
+     x="346.03613"
+     y="3.9999998"
+     ry="19.999998" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="395.46545"
+     y="33.285709"
+     id="text15304"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15306"
+       x="395.46545"
+       y="33.285709">Start</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.93979216;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5374)"
+     id="rect15308"
+     width="290.06018"
+     height="74.345917"
+     x="251.006"
+     y="110.82932"
+     ry="3.7605369e-06" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="397.49304"
+     y="142.28799"
+     id="text15310"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15312"
+       x="397.49304"
+       y="142.28799">Find</tspan><tspan
+       sodipodi:role="line"
+       x="397.49304"
+       y="169.78799"
+       id="tspan15314">\MGL@@@&lt;script&gt;</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.61052561;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5350)"
+     id="rect15316"
+     width="104.42103"
+     height="104.421"
+     x="-37.940403"
+     y="434.159"
+     ry="0"
+     transform="matrix(0.73605839,-0.67691805,0.73605839,0.67691805,27.536121,2.4999998)" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="396.24426"
+     y="309.45212"
+     id="text15372"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15374"
+       x="396.24426"
+       y="309.45212">Is it</tspan><tspan
+       sodipodi:role="line"
+       x="396.24426"
+       y="336.95212"
+       id="tspan15376">defined?</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.46426511;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5326)"
+     id="rect15308-5"
+     width="214.82143"
+     height="70.535728"
+     x="66.625397"
+     y="458.73218"
+     ry="3.5678115e-06" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="173.32182"
+     y="487.595"
+     id="text15310-7"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15402"
+       x="173.32182"
+       y="487.595">Compare</tspan><tspan
+       sodipodi:role="line"
+       id="tspan15404"
+       x="173.32182"
+       y="515.09497">script vs. code</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.6016953;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5302)"
+     id="rect15308-5-1"
+     width="261.11255"
+     height="64.684021"
+     x="483.47986"
+     y="461.65802"
+     ry="3.2718219e-06" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="615.10748"
+     y="487.8367"
+     id="text15310-7-8"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15430"
+       x="615.10748"
+       y="487.8367">Rewrite/recompile</tspan><tspan
+       sodipodi:role="line"
+       id="tspan15432"
+       x="615.10748"
+       y="515.33667">script</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.93979216;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5230)"
+     id="rect15308-58"
+     width="290.06018"
+     height="74.345917"
+     x="469.00604"
+     y="802.82477"
+     ry="3.7605369e-06" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="615.46466"
+     y="833.83441"
+     id="text15310-2"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15538"
+       x="615.46466"
+       y="833.83441">Undefine</tspan><tspan
+       sodipodi:role="line"
+       id="tspan15540"
+       x="615.46466"
+       y="861.33441">\MGL@@@&lt;script&gt;</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.93979216;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5254)"
+     id="rect15308-7"
+     width="290.06018"
+     height="74.345917"
+     x="29.006018"
+     y="802.82477"
+     ry="3.7605369e-06" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="175.46468"
+     y="833.83441"
+     id="text15310-4"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15534"
+       x="175.46468"
+       y="833.83441">Define</tspan><tspan
+       sodipodi:role="line"
+       id="tspan15536"
+       x="175.46468"
+       y="861.33441">\MGL@@@&lt;script&gt;</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5206)"
+     id="rect15298-0"
+     width="100"
+     height="39.999996"
+     x="346.03613"
+     y="944"
+     ry="19.999998" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="395.93542"
+     y="973.28571"
+     id="text15304-3"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan15563"
+       x="395.93542"
+       y="973.28571">End</tspan></text>
+  <rect
+     style="fill:#ff9b58;fill-opacity:1;stroke:#000000;stroke-width:2.61052561;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5278)"
+     id="rect15316-5"
+     width="104.42103"
+     height="104.421"
+     x="-291.92599"
+     y="688.14459"
+     ry="0"
+     transform="matrix(0.73605839,-0.67691805,0.73605839,0.67691805,27.536121,2.4999998)" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="396.24426"
+     y="638.30701"
+     id="text15372-1"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan4665"
+       x="396.24426"
+       y="638.30701">Are</tspan><tspan
+       sodipodi:role="line"
+       id="tspan4667"
+       x="396.24426"
+       y="665.80701">they</tspan><tspan
+       sodipodi:role="line"
+       id="tspan4669"
+       x="396.24426"
+       y="693.30701">equal?</tspan></text>
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 395.9522,41.850038 0,65.659912"
+     id="path9635"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 395.9522,184.76632 0,64.67006"
+     id="path9668"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 320.69584,322.14706 -146.47212,0 0,134.37059"
+     id="path9880"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 472.88165,322.14453 146.47212,0 0,134.37059"
+     id="path9880-8"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 281.75015,497.57146 114.28572,-0.71429 0,95.85714"
+     id="path11097"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 472.48848,666.43983 146.47212,0 0,134.37059"
+     id="path9880-87"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 319.58325,665.72555 -146.47211,0 0,134.37059"
+     id="path9880-4"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 319.6073,843.28574 147.85714,0"
+     id="path12272"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 396.03587,843.28574 0,97.14286"
+     id="path12293"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
+     d="m 618.89301,527.57146 0,37.14285 -202.85714,-0.71428 c 0,0 -19.14012,-27.19021 -39.21292,-0.0237 l -203.28708,0.38084 -0.35715,101.42857"
+     id="path12941"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccc" />
+  <rect
+     style="fill:#ffe3d0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect5520"
+     width="71.428574"
+     height="40"
+     x="214.67897"
+     y="301.21429"
+     ry="20" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
+     x="227.53612"
+     y="329.78571"
+     id="text5522"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan5524"
+       x="227.53612"
+       y="329.78571">Yes</tspan></text>
+  <rect
+     style="fill:#ffe3d0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect5520-4"
+     width="71.428574"
+     height="40"
+     x="213.2504"
+     y="644.64282"
+     ry="20" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
+     x="226.10754"
+     y="673.21423"
+     id="text5522-9"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan5524-4"
+       x="226.10754"
+       y="673.21423">Yes</tspan></text>
+  <rect
+     style="fill:#ffe3d0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect5520-7"
+     width="71.428574"
+     height="40"
+     x="507.5361"
+     y="644.07141"
+     ry="20" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
+     x="524.67896"
+     y="674.07141"
+     id="text5522-6"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan5586"
+       x="524.67896"
+       y="674.07141">No</tspan></text>
+  <rect
+     style="fill:#ffe3d0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect5520-7-3"
+     width="71.428574"
+     height="40"
+     x="506.10754"
+     y="301.21426"
+     ry="20" />
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:100%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
+     x="523.25037"
+     y="331.21423"
+     id="text5522-6-9"
+     sodipodi:linespacing="100%"><tspan
+       sodipodi:role="line"
+       id="tspan5586-2"
+       x="523.25037"
+       y="331.21423">No</tspan></text>
+</svg>
index 34dedaecfef747222d65bbc018073d439f9827c3..ecdd628e00d8d5e8820a8917d3912473c3eaca4e 100644 (file)
@@ -1,42 +1,48 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
-% 
+% Copyright (C) 2014--2015 by Diego Sejas Viscarra <diego.mathematician@gmail.com>
+% Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin@gmail.com>
+%
 % This program is free software: you can redistribute it and/or modify it
 % under the terms of the GNU General Public License as published by the
 % Free Software Foundation, either version 3 of the License, or (at your
 % option) any later version.
-% 
+%
 % This program is distributed in the hope that it will be useful, but
 % WITHOUT ANY WARRANTY; without even the implied warranty of
 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 % Public License for more details.
 % 
 % You should have received a copy of the GNU General Public License along
-% with this program.  If not, see <http://www.gnu.org/licenses/>.
-% 
+% with this program. If not, see <http://www.gnu.org/licenses/>.
+%
 % \fi
-% 
+%
 % \iffalse
 %
+%<package>
 %<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{mgltex}[/2014/11/22 v2.0 Embed MGL scripts in LaTeX documents]
-% 
+%<package>\ProvidesPackage{mgltex}[2015/11/07 v4.0 Embed MGL scripts into LaTeX documents]
+%<package>
+%
 %<*driver>
-\documentclass{ltxdoc}
+\documentclass[10pt]{ltxdoc}
 \usepackage{color}
-\usepackage[comments]{mgltex}
+\IfFileExists{hyperref.sty}{\usepackage{hyperref}}{}
+\usepackage{mgltex}
 \EnableCrossrefs
 \CodelineIndex
 \RecordChanges
+\widowpenalty=10000
+\clubpenalty=10000
 \begin{document}
   \DocInput{mgltex.dtx}
 \end{document}
 %</driver>
 % \fi
-% 
-% \CheckSum{1297}
-% 
+%
+% \CheckSum{1520}
+%
 % \CharacterTable
 %  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
 %   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
 %   Right bracket \]     Circumflex    \^     Underscore    \_
 %   Grave accent  \`     Left brace    \{     Vertical bar  \|
 %   Right brace   \}     Tilde         \~}
-% 
+%
+% \bgroup%
+%   \makeatletter%
+%   \gdef\MGL@set@pseudo@verb@env{%
+%     \if@minipage\else\vskip\parskip\fi%
+%     \setlength{\labelsep}{1em}%
+%     \@beginparpenalty\predisplaypenalty%
+%     \leftskip\@totalleftmargin\rightskip\z@%
+%     \parindent\z@\parfillskip\@flushglue\parskip\z@%
+%     \itemsep\z@%
+%     \@@par%
+%     \def\par{%
+%       \if@tempswa%
+%         \leavevmode\null\@@par\penalty\interlinepenalty%
+%       \else%
+%         \@tempswatrue%
+%         \ifhmode\@@par\penalty\interlinepenalty\fi%
+%       \fi%
+%     }%
+%     \ttfamily%
+%     \frenchspacing%
+%   }%
+%   \makeatother
+% \egroup
+%
 % \changes{v1.0}{2014/09/27}{Initial version}
-% \changes{v.2.0}{2014/11/15}{Possible bugfix by adding \texttt{\textbackslash expandafter} to commands to ignore/write lines of MGL code}
-% \changes{v.2.0}{2014/11/15}{Add environment \texttt{mglsignature} that adds a commentary every MGL script}
-% \changes{v.2.0}{2014/11/15}{Eliminate line ignoring commands to create more elegant scripts, due to the a new command that adds comments to the scripts}
-% 
+% \changes{v2.0}{2014/11/23}{Possible bugfix by adding \texttt{\textbackslash expandafter} to commands to ignore/write lines of MGL code}
+% \changes{v2.0}{2014/11/23}{Add environment \texttt{mglsignature} that adds a commentary every MGL script}
+% \changes{v2.0}{2014/11/23}{Eliminate line ignoring commands to create more elegant scripts, due to the a new command that adds comments to the scripts}
+% \changes{v2.0}{2014/11/23}{Move the MGL \emph{stop} command from the \texttt{\textbackslash{}AtEndDocument} command to the \texttt{\textbackslash{}mgl@func} buffer}
+% \changes{v3.0}{/2015/03/29}{Add detection of changes in MGL scripts to speed up compilation time (only changed scripts are recompiled)}
+% \changes{v3.0}{/2015/03/29}{Add command \texttt{\textbackslash mgldir}, \texttt{\textbackslash mglscriptsdir}, \texttt{\textbackslash mglgraphicsdir} and \texttt{\textbackslash mglbackupsdir} to specify a main directory for \textsf{\mglTeX} and directories for the creation of scripts, graphics and backups}
+% \changes{v3.0}{/2015/03/29}{Add the \texttt{\textbackslash mglquality} command to specify a default quality}
+% \changes{v3.0}{/2015/03/29}{Add the \texttt{\textbackslash mglwidth} and \texttt{\textbackslash mglheight} commands to specify the default size of the images produced}
+% \changes{v3.0}{/2015/03/29}{Add the \texttt{\textbackslash mglsettings} command to configure behavior of the package}
+% \changes{v3.0}{/2015/03/29}{Improve environment \texttt{mglsignature} by adding the possibility of using \LaTeX{} commands inside it}
+% \changes{v4.0}{/2015/08/17}{Completely rewrite of \textsf{\mglTeX}}
+% \changes{v4.0}{/2015/08/17}{\textsf{\mglTeX} now depends of the \textsf{verbatim} package}
+% \changes{v4.0}{/2015/08/17}{All environments write their contents \emph{verbatim}}
+% \changes{v4.0}{/2015/08/17}{Remove \texttt{\textbackslash mglquality} command. Instead, add package options \texttt{0q}, \ldots, \texttt{8q} to specify quality}
+% \changes{v4.0}{/2015/08/17}{Add the \texttt{\textbackslash mglpaths} command to add directories to the search paths for MGL scripts}
+% \changes{v4.0}{/2015/08/17}{Add the \texttt{\textbackslash mglname} command to force clousure of the current main script, its compilation, and the opening of a new main script}
+% \changes{v4.0}{/2015/08/17}{Add the option \texttt{label} to the \texttt{mgl} environment in order to override the automatic naming of the script and corresponding image}
+% \changes{v4.0}{/2015/08/17}{Add the option \texttt{label} to the \texttt{mglverbatim} environment to name the verbatim code}
+% \changes{v4.0}{/2015/08/17}{Add the option \texttt{separator} to the command \texttt{\textbackslash mglplot} to brake the code into different physical text lines}
+% \changes{v4.0}{/2015/08/17}{Add the option \texttt{path} to the commands \texttt{\textbackslash mglgraphics} and \texttt{\textbackslash mglinclude} to force a path to search MGL scripts}
+% \changes{v4.0}{/2015/08/17}{Make verbatim-like environments and \texttt{\textbackslash mglinclude} command more visually elegant}
+% \changes{v4.0}{/2015/08/17}{Numbering in verbatim-like environments is optional now}
+% \changes{v4.0}{/2015/08/17}{Add the command \texttt{\textbackslash listofmglscripts} to create a list of all MGL scripts included verbatim in the document}
+% \changes{v4.0}{/2015/08/17}{Add the command \texttt{\textbackslash mglTeXwVer} that prints the name of the package with its version in a coherent manner, and separated by an unbreakable space}
+% \changes{v4.0}{/2015/08/17}{Verbatim-like environments and the \texttt{\textbackslash mglinclude} command have starred versions wich prevent the command \texttt{\textbackslash listofmglscripts} to list them}
+% \changes{v4.0}{/2015/08/17}{Remove \texttt{mglsignature} environment for being considered useless, and to avoid interference with the detection of changes in MGL scripts, to speed up script writing and to make the package less resource-consuming}
+% \changes{v4.0}{/2015/08/17}{Remove the \texttt{\textbackslash mglwidth} and \texttt{\textbackslash mglheight} commands for being considered useless}
+% \changes{v4.0}{/2015/08/17}{Remove the \texttt{\textbackslash MGL@setkeys} command since it isn't needed as first thought}
+% \changes{v4.0}{/2015/08/17}{\textsf{\mglTeX} is more customizable now}
+% \changes{v4.0}{/2015/08/17}{Many improvements, including, but not limited to, speed up, increased coherence and cleanness of the code, less resource consumption}
+% \changes{v4.0}{/2015/08/17}{Many bugfixes}
+%
 % \GetFileInfo{mgltex.sty}
-% 
+%
 % \DoNotIndex{\def,\bgroup,\egroup,\newcommand,\newenvironment,\\,\@onlypreamble,\@undefined,\@vobeyspaces,\list}
 % \DoNotIndex{\if,\else,\fi,\begingroup,\endgroup,\end,\edef,\xdef,\gdef,\scapechar,\active,\arabic,\catcode,\bfseries}
 % \DoNotIndex{\@flushglue,\@for,\@ifnextchar,\@makeother,\{,\},\^,\ ,\AtBeginDocument,\AtEndDocument,\centering}
 % \DoNotIndex{\PassOptionsToPackage,\ProcessOptions,\read,\relax,\RequirePackage,\rightskip,\setcounter,\setkeys,\setlength}
 % \DoNotIndex{\space,\stepcounter,\string,\TeX,\the,\vbox,\verbatim@font,\write,\z@,\z@skip,\newif,\PackageInfo,\today}
 % \DoNotIndex{\obeylines,\or\ifcase,\small}
-% 
+%
 % \title{The \textsf{\mglTeX} package\thanks{This document corresponds to \textsf{\mglTeX}~\fileversion, dated \filedate.}}
 % \author{Diego Sejas Viscarra\\\texttt{diego.mathematician@gmail.com}}
-% 
+%
 % \maketitle
-% 
+%
 % \begin{abstract}
-%   \noindent MathGL is a fast and efficient library by Alexey Balakin for the creation of high-quality publication-ready scientific graphics. Although it defines interfaces for many programming languages, it also implements its own programming language, called \emph{MGL}, which can be used independently. With the package \textsf{\mglTeX}, MGL scripts can be embedded within any \LaTeX{} document, and the corresponding images are automatically created and included.
-
-% This manual documents the use of the commands and environments of~\mglTeX.
+% \noindent MathGL is a fast and efficient library by Alexey Balakin for the creation of high-quality publication-ready scientific graphics. Although it defines interfaces for many programming languages, it also implements its own scripting language, called \emph{MGL}, which can be used independently. With the package \textsf{\mglTeX}, MGL scripts can be embedded within any \LaTeX{} document, and the corresponding images are automatically created and included.
+%
+% This manual documents the use of the commands and environments of~\textsf{\mglTeX}.
 % \end{abstract}
-% 
+%
+% \tableofcontents
+%
 % \section{Introduction}
-% MathGL is a fast and efficient library by Alexey Balakin for the creation of high-quality publication-ready scientific graphics. It implements more than $50$ different types of graphics for 1d, 2d and 3d large sets of data. It supports exporting images to bitmap formats (PNG, JPEG, BMP, etc.), or vector formats (EPS, \TeX, SVG, etc.), or 3d image formats (STL, OBJ, XYZ, etc.), and even its own 3d format, MGLD. MathGL also defines its own vector font specification format, and supports UTF-16 encoding with \TeX-like symbol parsing. It supports various kinds of transparency and lighting, textual formula evaluation, arbitrary curvilinear coordinate systems, loading of subroutines from .dll or .so libraries, and many other useful features.
-% 
+% MathGL is a fast and efficient library by Alexey Balakin for the creation of high-quality publication-ready scientific graphics. It implements more than $50$ different types of graphics for 1d, 2d and 3d large sets of data. It supports exporting images to bitmap formats (PNG, JPEG, BMP, etc.), or vector formats (EPS, \TeX, SVG, etc.), or 3d image formats (STL, OBJ, XYZ, etc.), and even its own native 3d format, MGLD. MathGL also defines its own vector font specification format, and supports UTF-16 encoding with \TeX-like symbol parsing. It supports various kinds of transparency and lighting, textual formula evaluation, arbitrary curvilinear coordinate systems, loading of subroutines from .dll or .so libraries, and many other useful features.
+%
 % MathGL has interfaces for a wide variety of programming languages, such as C/C++, Fortran, Python, Octave, Pascal, Forth, and many others, but it also defines its own scripting language, called \emph{MGL}, which can be used to generate graphics independently of any programming language. The \textsf{\mglTeX} package adds support to embed MGL code inside \LaTeX{} documents, which is automatically extracted and executed, and the resulting images are included in the document.
-% 
+%
 % Besides the obvious advantage of having available all the useful features of MathGL, \textsf{\mglTeX} facilitates the maintenance of your document, since both code for text and code for graphics are contained in a single file.
-% 
+%
 % \section{Usage}
 % \noindent The simplest way to load \textsf{\mglTeX} to a \LaTeX{} document is to write the command
 % \begin{center}
 % \begin{center}
 % |\usepackage|\oarg{options list}|{mgltex}|,  
 % \end{center}
-% where \meta{options list} is a comma-separated list that can contains one or more of the following options:
+% where \meta{options list} is a comma-separated list that can contain one or more of the following options:
 % \begin{itemize}
 %   \item |draft|: The generated images won't be included in the document. This option is useful when fast compilation of the document is needed.
-%   \item |final|: This overrides the |draft| option.
-%   \item |on|: To create the MGL scripts and corresponding images of the document every time \LaTeX{} is run.
-%   \item |off|: To avoid creating the MGL scripts and corresponding images of the document, but still try to include the images.
+%   \item |final|: Overrides the |draft| option.
+%   \item |on|: To rewrite, recompile and include the changed MGL scripts and/or corresponding graphics.
+%   \item |off|: To avoid creation, compilation and/or inclusion of the MGL scripts and corresponding images.
 %   \item |comments|: To allow the contents of the |mglcomment| environments to be shown in the \LaTeX{} document.
-%   \item |nocomments|: To not show the contents of the |mglcomment| environments in the \LaTeX{} document.
-%   \item |png|, |jpg|, |jpeg|: To export images to the corresponding bitmap format.
-%   \item |eps|, |epsz|: To export to uncompressed/compressed EPS format as primitives.
-%   \item |bps|, |bpsz|: To export to uncompressed/compressed EPS format as bitmap.
+%   \item |nocomments|: To avoid showing the contents of the |mglcomment| environments in the \LaTeX{} document.
+%   \item |1x|, \ldots, |9x|: To specify the scale for the creation of graphics (|1x| is normal scaling, |2x| is twice as bigger, etc).
+%   \item |0q|, \ldots, |8q|: To specify the quality for the creation of graphics. An info message indicating the characteristics of the chosen quality is printed in the .log file according to the following table:
+% \begin{center}
+%   \DeleteShortVerb{\|}
+%   \begin{tabular}{|c|l|}
+%     \hline
+%     Quality & Description\\
+%     \hline
+%     \hline
+%     $0$ & No face drawing (fastest)\\
+%     \hline
+%     $1$ & No color interpolation (fast)\\
+%     \hline
+%     $2$ & High quality (normal)\\
+%     \hline
+%     $3$ & High quality with 3d primitives (not implemented yet)\\
+%     \hline
+%     $4$ & No face drawing, direct bitmap drawing (low memory usage)\\
+%     \hline
+%     $5$ & No color interpolation, direct bitmap drawing (low memory usage)\\
+%     \hline
+%     $6$ & High quality, direct bitmap drawing (low memory usage)\\
+%     \hline
+%     $7$ & High quality with 3d primitives, direct bitmap drawing\\
+%     & (not implemented yet)\\
+%     \hline
+%     $8$ & Draw dots instead of primitives (extremely fast)\\
+%     \hline
+%   \end{tabular}
+%   \MakeShortVerb{\|}
+% \end{center}
+%   \item |png|, |jpg|, |jpeg|: To export images to a bitmap format.
+%   \item |eps|, |epsz|: To export to uncompressed/compressed vectorial EPS format.
+%   \item |bps|, |bpsz|: To export to uncompressed/compressed bitmap EPS format.
 %   \item |pdf|: To export to 3D PDF format.
 %   \item |tex|: To export to \LaTeX{}/\emph{tikz} document.
 % \end{itemize}
-% It must be noted that the options |on| and |off| are exclusive, in the sense that if one specifies both of them, only the last one will be used. Likewise, the options that specify the format to save the graphics are exclusive.
-% 
-% Observe the option |off| is useful to save compilation time of a document. For example, if the graphics of an article are in final version, instead of compilling them over and over again every time \LaTeX{} runs, they can be created only once with the |on| option, and then only included (but not recompiled) with the |off| option.
-% 
-% The are two ways to compile a document with \textsf{\mglTeX}: The first way is to run
+% If two or more mutually exclusive options are specified, only the last one will be used by \textsf{\mglTeX}. For example, if one specifies the options |0q|, |3q| and |8q|---in that order---, then the quality will be set to $8$.
+%
+% Observe the |off| option is similar to the |draft| option, with the exception that |draft| deactivates inclusion of graphics for the \textsf{\mglTeX} and \textsf{graphicx} packages, while the |off| option only deactivates \textsf{\mglTeX} functionalities (creation and/or inclusion of scripts and graphics), not affecting \textsf{graphicx}. This could be useful to recognize which images are created with MGL, and which are only included. Another possible use for this option is to avoid recompilation of scripts when they must be constantly changed until their final version.\footnote{\textsf{\mglTeX} has a convinient recompilation-decision algorithm that enables recompilation for changed scripts only (see subsection \ref{subsection: recompilation decision}).}
+%
+% There are two ways to compile a document with \textsf{\mglTeX}: The first way is to run
 % \begin{center}
-%   |latex --shell-escape |\meta{document}
+%   |latex --shell-escape |\meta{document}|.tex|
 % \end{center}
-% twice, since the first run will extract the MGL code, execute it and include some of the resulting graphics, while the second run will include the remaining graphics; the second way is to run |latex |\meta{document} to extract the MGL code, then execute the generated scripts with the program |mglconv| (which comes with MathGL), and execute |latex |\meta{document} once more to include the graphics.
-% 
-% \subsection{Environments for MGL code embedding}
-% \DescribeEnv{mgl}\noindent The main environment defined by \textsf{\mglTeX} is |mgl|. It extracts its contents to a general script, called \meta{document}.mgl, where \meta{document} stands for the name of the \LaTeX{} file being compiled; this script is compiled, and the corresponding image is included. Its syntax is:
+% three times, since the first run will detect changes in the scripts; the second run will extract the MGL code, execute it and include some of the resulting graphics, while the third run will include the remaining graphics. The second way is to run
+% \begin{center}
+%   |latex |\meta{document}|.tex|
+% \end{center}
+% twice to detect changes in MGL code and to extract it, then compile the generated scripts with the program |mglconv| (part of MathGL bundle), and execute |latex |\meta{document}|.tex| once more to include the graphics.\footnote{If no changes were made to scripts intended to create graphics, only one \LaTeX{} run is needed.} (More on the recompilation-decision mechanism of \textsf{\mglTeX} can be found in subsection~\ref{subsection: recompilation decision}.)
+%
+% \subsection{Warning for the user}\label{subsection: warning}
+% Before we continue the description of the package, it must be pointed out that \textsf{\mglTeX} assummes that the command |\end{|\meta{MGL environment}|}|, that ends the corresponding \meta{MGL environment}, occupies its own physical line of \LaTeX{} code. So the correct forms of use of environments are the following:
+% \begin{quote}
+%|\begin{|\meta{MGL environment}|}|\\
+%\meta{contents of the environment}\\
+%|\end{|\meta{environment}|}|
+% \end{quote}
+% and
+% \begin{quote}
+%|\begin{|\meta{MGL environment}|}|\meta{contents of the environment}\\
+%|\end{|\meta{environment}|}|
+% \end{quote}
+% The following form will cause problems:
+% \begin{quote}
+%|\begin{|\meta{MGL environment}|}|\meta{contents of the environment}|\end{|\meta{MGL environment}|}|
+% \end{quote}
+%
+% \textsf{\mglTeX} depends on the \textsf{verbatim} package to define its environments. One of the characteristics of \textsf{verbatim} is that it transcripts everything contained between the begining and the end of an environment, including spaces before an |\end{|\meta{MGL environment}|}| command. This should not be a problem, except for the fact that \textsf{\mglTeX} has a mechanism to detect changes in MGL scripts in order to recompile them (see subsection \ref{subsection: recompilation decision}), and the mentioned spaces in the scripts and their counterparts in the \LaTeX{} document can't be recognized properly as identical when compared, causing the package to recompile the scripts even when they haven't changed, rendering the mechanism useless.\footnote{It is currently unknown for the author why this spaces aren't detected properly. Help would be appreciated.} In order to avoid this glitch, the facilities provided by \textsf{verbatim} have been adapted to ignore everything before |\end{|\meta{MGL environment}|}|, including spaces and, unfortunately, MGL code.
+%
+% It should also be pointed out that the default behavior of the |verbatim| package makes the following form to ignore the \meta{text} after the |\end|\meta{MGL environment}, issuing a warning.
+% \begin{quote}
+%|\begin{|\meta{MGL environment}|}|\\
+%\meta{contents of the environment}\\
+%|\end{|\meta{MGL environment}|}|\meta{text}
+% \end{quote}
+%
+% \subsection{Setting up \textsf{\mglTeX} for use}
+% \noindent Although \textsf{\mglTeX} is completely functional without any further set up, there are some parameters of its behavior that could be useful to modify. The following commands must be used in the preamble of the document only, since the first MGL script is created at the moment of the |\begin{document}| command, and otherwise they could create weird errors during compilation; trying to use them somewhere else will produce an error. 
+%
+% \DescribeMacro{\mgldir} This command can be used to specify the main working directory for \textsf{\mglTeX}. Inside it, the scripts, backup files and graphics will be created, or can be separated inside subdirectories. This is useful, for example, to avoid many scripts and graphics from polluting the directory where the \LaTeX{} document is.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mgl}|\oarg{key-val list}\\[0.5em]
-%       \hss\meta{MGL code}\hss\\[0.5em]
-%     |\end{mgl}|\\[0.25em]
+%     |\mgldir|\marg{\mglTeX{} main directory}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% Here, \meta{key-val list} accepts the same optional arguments as the |\includegraphics| command from the \textsf{graphicx} package, plus an additional one, |imgext|, which can be used to specify the extension to save the graphic. The \meta{MGL code} doesn't need to contain any specific instruction to create the image, since \textsf{\mglTeX} takes care of that.
-% 
-% \DescribeEnv{mgladdon} This environment adds its contents to the general script \meta{document}.mgl, but it doesn't produce any image. It doesn't require any kind of arguments.
+% \meta{\mglTeX{} main directory} can be in the form of an absolute path or a relative path, and should be an existing location, since it won't be created automatically.
+%
+% \DescribeMacro{\mglscriptsdir} It specifies the subdirectory inside \meta{\mglTeX{} main directory} where the MGL scripts will be created.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mgladdon}|\\[0.5em]
-%       \hss\meta{MGL code}\hss\\[0.5em]
-%     |\end{mgladdon}|\\[0.25em]
+%     |\mglscriptsdir|\marg{MGL scripts subdirectory}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeEnv{mglcode} This is the same as the |mgl| environment, but the corresponding code is written \emph{verbatim} to a separate script, whose name is specified as mandatory argument. It accepts the same optional arguments as |mgl|.
+%
+% \DescribeMacro{\mglgraphicsdir} It specifies the subdirectory inside \meta{\mglTeX{} main directory} where the MGL graphics will be created, including the ones from external scripts (not embedded inside the \LaTeX{} document).
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglcode}|\oarg{key-val list}\marg{script\_name}\\[0.5em]
+%     |\mglgraphicsdir|\marg{MGL graphics subdirectory}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+%
+% \DescribeMacro{\mglbackupsdir} It specifies the subdirectory inside \meta{\mglTeX{} main directory} where backups for the MGL scripts will be created.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglbackupsdir|\marg{MGL backups subdirectory}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+%
+% The above commands can be used in various combinations. For example, if none of them is used, the scripts, graphics and backups will be created inside the same path where the \LaTeX{} document is being compiled; if only |\mgldir| is used, they will be created inside \meta{\mglTeX{} main directory}; if only |\mgldir| and |\mglscriptsdir| are used, the scripts will be created inside \meta{\mglTeX{} main directory}\meta{MGL scripts directory}, while the graphics and backups will be inside \meta{\mglTeX{} main directory} only; if |\mgldir| isn't used, but the other commands are, the \meta{MGL scripts subdirectory}, \meta{MGL graphics subdirectory} and \meta{MGL backups subdirectory} paths will be inside the the folder where the \LaTeX{} document is being compiled.
+%
+% \DescribeMacro{\mglpaths} In case of having external MGL scripts, it is not recommended to place them inside the same location as where the embedded scripts are extracted, since they could be accidentally overwritten or deleted by the user; they should be separated in a folder which can be specified in the form of an absolute or relative path using this command.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglpaths|\marg{List of external MGL scripts paths/}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% This command can be used many times or can be used to specify many paths at once. In the case of using it many times, each call will add the new directory to the list of searching paths; if it is used to specify many paths at once, they must be separated by commas.
+%
+% \subsection{Environments for MGL code embedding}
+% \DescribeEnv{mgl}\noindent The main environment defined by \textsf{\mglTeX} is |mgl|. It extracts its contents to a main script, called \meta{name}.mgl, where \meta{name} stands for a name specified by the user with the |\mglname| command (see below), or the name of the \LaTeX{} document being executed otherwise; this script is compiled, and the corresponding image is included.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\begin{mgl}|\oarg{key-val list}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
-%     |\end{mglcode}|\\[0.25em]
+%     |\end{mgl}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeEnv{mglscript} The code within |mglscript| is written verbatim to a script whose name is specified as mandatory argument, but no image is produced. It is useful for creation of MGL scripts which can be later post-processed by another package, like \textsf{listings}.
+% Here, \meta{key-val list} can have the same optional arguments as the |\includegraphics| command from the \textsf{graphicx} package, plus two additional ones, |imgext|, which can be used to specify the extension to save the graphic, and |label|, which can be used to indicate a name for the corresponding graphic (otherwise, an automatic naming will be applied). The \meta{MGL code} doesn't need to contain any specific instruction to create the image since \textsf{\mglTeX} takes care of that.
+%
+% \DescribeEnv{mgladdon} This environment adds its contents to the document's main script, but it doesn't produce any image. It doesn't require any kind of arguments. It is useful to add ``complementary code'', like loading of dynamic libraries, set default size for the graphics, etc.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglscript}|\marg{script\_name}\\[0.5em]
+%     |\begin{mgladdon}|\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
-%     |\end{mglscript}|\\[0.25em]
+%     |\end{mgladdon}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeEnv{mglfunc} This is used to define MGL functions within the general script \meta{document}.mgl. It takes one mandatory argument, which is the name of the function, plus one optional argument, which specifies the number of arguments of the function. The environment needs to contain only the body of the function, since the lines ``func \meta{function\_name} \meta{number of arguments}'' and ``return'' are appended automatically at the beginning and the end, respectively. The resulting code is written at the end of the general script, after the |stop| command, which is also written automatically.
+%
+% \DescribeEnv{mglfunc} Is used to define MGL functions within the document's main script. It takes one mandatory argument, which is the name of the function, plus one optional argument, which specifies the number of arguments of the function (the default is $0$). The environment needs to contain only the body of the function, since the lines ``func \meta{function\_name} \meta{number of arguments}'' and ``return'' are appended automatically at the beginning and the end, respectively. The resulting code is written at the end of the document's main script, after the |stop| command, which is also written automatically.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeEnv{mglcommon} This is used to create a common ``setup'' script that will be executed together with each of the other scripts. It is useful to define constants, parameters, etc. that will be available to every script. 
+%
+% \DescribeEnv{mglcode} It has the same function as the |mgl| environment, but the corresponding code is written to a separate script, whose name is specified as mandatory argument. It accepts the same optional arguments as |mgl|, except, of course, the |label| option.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglcommon}|\\[0.5em]
+%     |\begin{mglcode}|\oarg{key-val list}\marg{script\_name}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
-%     |\end{mglcommon}|\\[0.25em]
+%     |\end{mglcode}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% For example, one could make
-% \begin{verbatim}
-% \begin{mglcommon}
-% define gravity 9.81 # [m/s^2]
-% \end{mglcommon}
-% \end{verbatim}
-% to make the constant \emph{gravity} available to every script.
-% 
-% Observe this environment should be used only to define constants, parameters and things like that, but not graphical objects like axis or grids, because every image created with the |mgl| environment clears every graphical object before creating the image.\footnote{This problem occurs only with the \texttt{mgl} environment, so you could use \texttt{mglcommon} to create many graphics with the same axis, grid, etc., with environments like \texttt{mglcode}, but in that case the best option is to use the \texttt{mglsetup} environment together with the \texttt{\textbackslash{}mglplot} command.}
-% 
-% \DescribeEnv{mglsignature} This environment is used to declare a signature (or commentary) that will be included at the beginning of every script generated by \mglTeX. It is verbatim-like environment, so no \LaTeX{} cammand will be executed, but copied literally. However, the default signature is ``This script was generated from \meta{document}.mgl on date \meta{today}''.
+%
+% \DescribeEnv{mglscript} The code within |mglscript| is written to a script whose name is specified as mandatory argument, but no image is produced. It is useful for creation of MGL scripts which can be later post-processed by another package, like \textsf{listings} or \textsf{pygments}.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglsignature}|\\[0.5em]
-%       \hss\meta{Signature for MGL scripts}\hss\\[0.5em]
-%     |\end{mglsignature}|\\[0.25em]
+%     |\begin{mglscript}|\marg{script\_name}\\[0.5em]
+%       \hss\meta{MGL code}\hss\\[0.5em]
+%     |\end{mglscript}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeEnv{mglcomment} This environment is used to embed commentaries in the \LaTeX{} document. The commentary won't appear in the case of the user passing the option |nocomments| to the package, but it will be written \emph{verbatim} is the user passes the option |comments|.
+%
+% \DescribeEnv{mglcommon} This is used to create a common ``setup'' script to define constants, parameters, etc. that will be available to the others.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglcomment}|\\[0.5em]
-%       \hss\meta{Commentary}\hss\\[0.5em]
-%     |\end{mglcomment}|\\[0.25em]
+%     |\begin{mglcommon}|\\[0.5em]
+%       \hss\meta{MGL code}\hss\\[0.5em]
+%     |\end{mglcommon}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% In the case of the user allowing commentaries, this will result in the appearance of the following commentary in the \LaTeX{} document:
-% \begin{center}
-% \makeatletter
-% \verbatim@font
-% \makeatother
-% <------------------ MGL comment ------------------>\\
-% \meta{Commentary}\\
-% <------------------ MGL comment ------------------>\\
-% \end{center}
-% 
+% If called more than once, it will overwrite the setup code. Also note that it should be used only to define constants, parameters and things like that, but not graphical objects like axis or grids, because the |mgl| environment clears every graphical object before creating the image.\footnote{This problem occurs only with the \texttt{mgl} environment, so you could use \texttt{mglcommon} to create many graphics with the same axis, grid, etc., with environments like \texttt{mglcode}, but in that case the best option is to use the \texttt{mglsetup} environment together with the \texttt{\textbackslash{}mglplot} command.}
+%
+% For example, one could write
+% \begin{quote}
+%   |\begin{mglcommon}|\\
+%   |define gravity 9.81 # [m/s^2]|\\
+%   |\end{mglcommon}|
+% \end{quote}
+% to make the constant \emph{gravity} available to every script.
+%
 % \subsection{Fast creation of graphics}
-% \noindent\textsf{\mglTeX} defines a convenient way to work with many graphics that have exactly the same settings (for example, same angles of rotation, same type of grid, etc.): instead of writing repetitive code every time it's needed, it can be stored in memory with the |mglsetup| environment, and then can be used when needed with the |\mglplot| command.
-% 
-% \DescribeEnv{mglsetup} This environment stores its contents in memory for later use. It accepts one optional argument, which is a keyword (name) to be associated to the corresponding block of code, so different blocks of code can be stored with different names.
+% \noindent\textsf{\mglTeX} defines a convenient way to work with many graphics that have exactly the same settings (same rotation angles, same type of grid, same lighting, etc.): instead of writing repetitive code every time it's needed, it can be stored inside a |mglsetup| environment, and then can be used when needed with the |\mglplot| command.
+%
+% \DescribeEnv{mglsetup} This environment is defined as a special case of the |mglfunc| environment. It accepts one mandatory argument, which is a keyword (name) associated to the corresponding block of code (MGL function body).
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglsetup}|\oarg{keyword}\\[0.5em]
+%     |\begin{mglsetup}|\marg{keyword}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
 %     |\end{mglsetup}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeMacro{\mglplot} This command is used for fast generation of graphics with default settings, and can be used in parallel with the |mglsetup| environment. It accepts one mandatory argument which consists of MGL instructions, separated by the symbol ``:'', which can span through various text lines. It also accepts the same optional arguments as the |mgl| environment, plus an additional one, called |settings|, which can be used to specify a keyword used in a |mglsetup| environment. If the |settings| option is specified, the code in the mandatory argument will be appended to the block of code of the corresponding |mglsetup| environment.
+%
+% \DescribeMacro{\mglplot} This command is used for fast generation of graphics with default settings, and can be used in parallel with the |mglsetup| environment. It accepts one mandatory argument which consists of MGL instructions, separated by the symbol ``:'', and can span through various text lines. It accepts the same optional arguments as the |mgl| environment, plus two additional ones, called |setup| and |separator|. The |setup| option specifies a keyword associated to a |mglsetup| block, which will be executed before the code in the mandatory argument. The |separator| option specifies a text symbol that will break the code in the mandatory argument into a new physical line in the main script every time is encountered.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
+%
 % \subsection{Verbatim-like environments}
-% \DescribeEnv{mglblock}\noindent It writes its contents \emph{verbatim} to a file, whose name is given as mandatory argument, and then it also typesets its contents on the \LaTeX{} document, numbering each line of code.
+% \noindent The main purpose of these environments is to typeset their contents to the \LaTeX{} document, elegantly separated from the rest of the text. They have two versions: an unstarred version which can be listed later with the |\listofmglscripts| command (see below), and a starred version which won't be listed.
+%
+% Although these environments are intended to mimic the behavior of the |verbatim| environment from \LaTeX{}, there is an important difference, namely, long lines will be broken when the page margin is reached. This intended behavior is set because a language like MGL can easily have very long lines of code, like textual formulas, vectors input as lists of values, etc. Of course, no hyphenation will be performed, but the code will be indented in the second, third, etc. continuation lines by an amount specified by |\mglbreakindent| (see below).
+%
+% \DescribeEnv{mglblock}\DescribeEnv{mglblock*} Besides typesetting its contents to the document, |mglblock| creates a script whose name is specified as mandatory argument. It also accepts one optional argument, called |lineno|, whose default value is |true|, used to activate (|lineno=true|) or deactivate (|lineno=false|) line numbering inside the environment. The default behavior is to number each line of code.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglblock}|\marg{script\_name}\\[0.5em]
+%     |\begin{mglblock}|\oarg{lineno value}\marg{script\_name}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
 %     |\end{mglblock}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeEnv{mglverbatim} It typesets its contents to the \LaTeX{} document, numbering each line of code.
+% The ouput looks like this:
+% \begin{quote}
+%   \makeatletter
+%   \MGL@set@script@name{example_script}%
+%   \refstepcounter{MGL@verb@script@no}%
+%   \addcontentsline{lms}{MGL@script}{\protect\numberline{\theMGL@verb@script@no.}{\ttfamily\protect\detokenize{\MGL@script@name.mgl}}}%
+%   \setcounter{MGL@line@no}{0}%
+%   \list{\mgllinenostyle\arabic{MGL@line@no}.}{}%
+%   \MGL@set@pseudo@verb@env
+%   \fboxrule=\mgllinethickness%
+%   \item[\MGL@line@sep]\fbox{\bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}}\hskip\labelsep\MGL@line@sep\par\par%
+%   \stepcounter{MGL@line@no}%
+%   \item new x 50 40 '0.8*sin(pi*x)*sin(pi*(y+1)/2)'
+%   \stepcounter{MGL@line@no}%
+%   \item new y 50 40 '0.8*cos(pi*x)*sin(pi*(y+1)/2)'
+%   \stepcounter{MGL@line@no}%
+%   \item new z 50 40 '0.8*cos(pi*(y+1)/2)'
+%   \stepcounter{MGL@line@no}%
+%   \item title 'Parametric surface' : rotate 50 60 : box
+%   \stepcounter{MGL@line@no}%
+%   \item surf x y z 'BbwrR'
+%   \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+%   \endlist%
+% \end{quote}
+%
+% \DescribeEnv{mglverbatim}\DescribeEnv{mglverbatim*} This environment only typesets its contents to the \LaTeX{} document without creating any script. It accepts the |lineno| option, with default value |true|, plus an one called |label|, intended to specify a name associated to the corresponding code. The default behavior is to number each line of code.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglverbatim}|\\[0.5em]
+%     |\begin{mglverbatim}|\oarg{key-val list}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
 %     |\end{mglverbatim}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \subsection{Working with external scripts}
-% \noindent In case of having MGL scripts in their own files, \textsf{\mglTeX} can work with them without needing to transcript them to the \LaTeX{} document.
-% 
-% \DescribeMacro{\mglgraphics} This command takes one mandatory argument, which is the name of an external MGL script, which will be automatically executed, and the resulting image will be included. The same optional arguments as the |mgl| environment are accepted.
+% The output looks like this without |label|:
+% \begin{quote}
+%   \makeatletter
+%   \setcounter{MGL@line@no}{0}%
+%   \list{\mgllinenostyle\arabic{MGL@line@no}.}{}%
+%   \MGL@set@pseudo@verb@env
+%   \fboxrule=\mgllinethickness%
+%   \MGL@set@script@name{\mglverbatimname}%
+%   \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+%   \refstepcounter{MGL@verb@script@no}%
+%   \addcontentsline{lms}{MGL@script}{\protect\numberline{\theMGL@verb@script@no.}{\ttfamily\protect\detokenize{\MGL@script@name}}}%
+%   \stepcounter{MGL@line@no}%
+%   \item new x 50 40 '0.8*sin(pi*x)*sin(pi*(y+1)/2)'
+%   \stepcounter{MGL@line@no}%
+%   \item new y 50 40 '0.8*cos(pi*x)*sin(pi*(y+1)/2)'
+%   \stepcounter{MGL@line@no}%
+%   \item new z 50 40 '0.8*cos(pi*(y+1)/2)'
+%   \stepcounter{MGL@line@no}%
+%   \item title 'Parametric surface' : rotate 50 60 : box
+%   \stepcounter{MGL@line@no}%
+%   \item surf x y z 'BbwrR'
+%   \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+%   \endlist%
+% \end{quote}
+% \noindent If a |label| is specified, the output will look exactly as that of the |mglblock| environment.
+%
+% \DescribeEnv{mglcomment} This environment is used to embed commentaries in the \LaTeX{} document. The commentary won't be visible in the case of the user passing the option |nocomments| to the package, but it will be typeset \emph{verbatim} to the document if the user passes the option |comments|.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglgraphics|\oarg{key-val list}\marg{script\_name}\\[0.25em]
+%     |\begin{mglcomment}|\\[0.5em]
+%       \hss\meta{Commentary}\hss\\[0.5em]
+%     |\end{mglcomment}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeMacro{\mglinclude} This command takes one mandatory argument, which is the name of an external MGL script, which will be automatically transcript \emph{verbatim} on the \LaTeX{} document, and each line of code will be numerated.
+% If the user requests visible commentaries, this will result in the appearance of something like the following in the \LaTeX{} document:
+% \begin{quote}
+%   \makeatletter
+%   \list{}{}%
+%   \MGL@set@pseudo@verb@env
+%   \item\hskip-\labelsep<\MGL@dash@sep\mglcommentname\MGL@dash@sep>%
+%   \item This is a MGL commentary
+%   \item\hskip-\labelsep<\MGL@dash@sep\mglcommentname\MGL@dash@sep>%
+%   \endlist%
+% \end{quote}
+%
+% \subsection{Working with external scripts}
+% \noindent External scripts exist in their own files, independently of the \LaTeX{} document ---for example, a script sent by a colleague, a script created before the actual writing of the \LaTeX{} document, etc. \textsf{\mglTeX} provides convenient ways to deal with external scripts, as if they were embedded. It must be noted, however, that the package works on the suposition that these scripts are in their final version, so no change detection is performed on them. If a external script is changed, the corresponding graphic must be manually deleted in oreder to force recompilation.
+%
+% \DescribeMacro{\mglinclude}\DescribeMacro{\mglinclude*} This command is the equivalent of the |mglverbatim| environment for external scripts. It takes one mandatory argument, which is the name of a MGL script, which will be automatically transcript \emph{verbatim} on the \LaTeX{} document. It accepts the same optional arguments as the |\mglgraphics| command, plus the |lineno| option to activate/deactivate line numbering. There are unstarred version of this command will be listed if |\listofmglscripts| is used, while the starred version won't.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglinclude|\marg{script\_name}\\[0.25em]
+%     |\mglinclude|\marg{script\_name}\oarg{lineno boolean value}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \subsection{Additional commands}
-% \DescribeMacro{\mgldir}\noindent This command can be used to specify where \textsf{\mglTeX} should create the MGL scripts and corresponding images. This is useful, for example, to avoid a lot of scripts and images from polluting the current directory.
+%
+% \DescribeMacro{\mglgraphics} This takes one mandatory argument, which is the name of an external MGL script, which will be automatically executed, and the resulting image will be included. The same optional arguments as the |\includegraphics| command are accepted, plus the |imgext| option to specify the extension of the resulting graphic, and an additional option, |path|, which can be used to specify the location of the script.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mgldir|\marg{directory}\\[0.25em]
+%     |\mglgraphics|\oarg{key-val list}\marg{script\_name}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% This command must be used in the preamble of the document, since the first MGL script is created at the moment of the |\begin{document}| command; trying to use it somewhere else will issue an error. On the other hand, it is the responsibility of the user to create the \meta{directory}, since \textsf{\mglTeX} won't do it automatically.
-% 
-% \DescribeMacro{\mglquality} This command can be used to specify the quality for the graphics created with \mglTeX. An info message specifying the characteristics of the chosen quality is printed in the .log file.
+%
+% \subsection{Additional commands}
+% \DescribeMacro{\mglname}\noindent This command can be used in the preamble of the document to indicate the name of the main script, passed as mandatory argument. If used after the |\begin{document}| command, it will force the closure of the current main script, create the corresponding graphics, and start a new script with the specified name.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglquality|\marg{quality}\\[0.25em]
+%     |\mglname|\marg{main\_script\_name}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% The available qualities are described below:
+%
+% The use of this command is encourage when writing large documents, like books or thesis, to create a main script per document block (section, chapter, part, etc.). Since the |mgl| environment and the |\mglplot| command use an internal counter to automatically name scripts, unless the |label| option is used; if a new script is added this way to the document, it will alter the original numbering, causing \textsf{\mglTeX} to recompile the scripts from that point on (for more details, read subsection \ref{subsection: recompilation decision}). If the |\mglname| command is used, only the scripts of the current document block will be recompiled.
+%
+% \DescribeMacro{\mglquality} The default quality for the creation of MGL graphics can be specified with this command. Its effect is local, meaning that the new quality will be applied from the point this command is used on. An info message will be printed in the |.log| file indicating the characteristics of the chosen value, according to the following table:
 % \begin{center}
-%   \begin{tabular}{cl}
+%   \DeleteShortVerb{\|}
+%   \begin{tabular}{|c|l|}
 %     \hline
 %     Quality & Description\\
 %     \hline
 %     \hline
 %     $6$ & High quality, direct bitmap drawing (low memory usage)\\
 %     \hline
-%     $7$ & High quality with 3d primitives, direct bitmap drawing (not implemented yet)\\
+%     $7$ & High quality with 3d primitives, direct bitmap drawing\\
+%     & (not implemented yet)\\
 %     \hline
 %     $8$ & Draw dots instead of primitives (extremely fast)\\
 %     \hline
 %   \end{tabular}
+%   \MakeShortVerb{\|}
 % \end{center}
-% 
-% \DescribeMacro{\mgltexon} This command has the same effect as the package option |on|, i.e., create all the scripts and corresponding graphics, but its effect is local, meaning that it work only from the point it is used on.
+% If a non available quality is chosen, it will be changed to $2$ (the default), and a warning message will be issued for the user.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglquality|\marg{quality value}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+%
+% \DescribeMacro{\mglscale} Can be used to specify the default scaling for the creation of MGL graphics (1 is normal scaling, 2 is twice as bigger, etc.). Its effect is local, meaning that the new scaling will be applied from the point this command is used on. Any non negative value can be specified.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglscale|\marg{scale value}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+%
+% \DescribeMacro{\mgltexon} This command has the same effect as the package option |on|, i.e., create all the scripts and corresponding graphics, but its effect is local.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% \DescribeMacro{\mgltexoff} This command has the same effect as the package option |off|, i.e., DO NOT create the scripts and corresponding graphics, and include images anyway, but its effect is also local, meaning that it work only from the point it is used on.
+%
+% \DescribeMacro{\mgltexoff} This command has the same effect as the package option |off|, i.e., DO NOT create the scripts and corresponding graphics, but its effect is local.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% Observe the commands |\mgltexon| and |\mgltexoff| can be used to save compilation time of a document. For example, when writing an article, if the graphics of the first section are already in final version, instead of compilling them every time \LaTeX{} is called, they can be created only once, and then the section can be wrapped with |mgltexoff| and |mgltexon|, so the graphics do not get recompiled again (wasting time), but only included.
-% 
-% \DescribeMacro{\mglcomments} This command has the same effect as the package option |comments|, i.e., show all the commentaries contained int the |mglcomment| environments, but its effect is local, meaning that it work only from the point it is used on.
+%
+% Observe that |\mgltexon| and |\mgltexoff| can be used to save time when writing a document, wrapping a section with them, avoiding recompilation of the corresponding scripts.
+%
+% \DescribeMacro{\mglcomments} This command has the same effect as the package option |comments|, i.e., show all the commentaries contained within |mglcomment| environments, but its effect is local.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglcoments|\\[0.25em]
+%     |\mglcomments|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% \DescribeMacro{\mglnocomments} This command has the same effect as the package option |nocomments|, i.e., DO NOT show the contentsof the |mglcomment| environments, but its effect is also local, meaning that it work only from the point it is used on.
+%
+% \DescribeMacro{\mglnocomments} This command has the same effect as the package option |nocomments|, i.e., DO~NOT show the contents of |mglcomment| environments, but its effect is also local.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
-% Observe the commands |\mglcomments| and |\mglnocomments| can be used to activate/deactivate commentaries on the document: just like \LaTeX{} commentaries, but with the possibilty of making them visible/invisible. This feature could be used, for example, to show remainders or commentaries for readers of test versions of an article.
-% 
+%
+% \DescribeMacro{\listofmglscripts} Opens a new section or chapter---depending on the \LaTeX{} class used---, where all the scripts that have been transcript in the document with the unstarred versions of the |mglblock| and |mglverbatim| environments, and the |\mglinclude| command, are listed. In case a |mglverbatim| is used, but no |label| is specified, the default name to display is specified by the |\mglverbatimname| macro (see below), otherwise, the corresponding label is typeset. The output is like this:
+% \begin{center}
+%   \begin{minipage}{0.9\textwidth}
+%     \listofmglscripts
+%   \end{minipage}
+% \end{center}
+%
 % \DescribeMacro{\mglTeX} This command just pretty-prints the name of the package.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline
 %   \end{tabular}
 % \end{center}
-% 
+%
+% \DescribeMacro{\mglTeXwVer} This command just pretty-prints the name of the package with its version in a coherent manner, separated by a an unbreakable space.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglTeXwVer|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+%
 % \subsection{User-definable macros}
-% \noindent There are two macros that the user is allowed to modify:
-% 
-% \DescribeMacro{\mgltexsignature}
-% As an alternative to the |mglsignature| environment for declaring signatures, the user can manually redefine the signature macro |\mgltexsignature|, according to the following rules:
-% \begin{itemize}
-%   \item The positions of the comment signs for the MGL language have to be manually specified in the signature using the |\mglcomm| macro.
-%   \item The new-line character is declared as ``|^^J|''.
-%   \item A percent sign (|%|) has to be added at the end of every physical line of |\mgltexsignature|, otherwise an inelegant space at the beginning of every line will appear.
-%   \item Any \LaTeX{} command can be used in this case.
-% \end{itemize}
-% For example, the default signature:
+% \noindent There are macros that the user is allowed to modify in order to customize some aspects of the behavior of \textsf{\mglTeX}. For example, if writing in spanish, french or russian, the user would like to modify the name of the common script, the words typeset in the separator lines of MGL commentaries, the name of the list of MGL scripts, etc.
+%
+% \DescribeMacro{\mglcommonscriptname} It is the name for the common script that takes the contents of the |mglcommon| environment. The default name is defined by
 % \begin{quote}
-%   \mglcomm\\
-%   \mglcomm\ This script was generated from \meta{document}.mgl on date \meta{today}\\
-%   \mglcomm
+%   |\def\mglcommonscriptname{MGL_common_script}|
 % \end{quote}
-% can be achieved with
-% \begin{verbatim}
-%   \def\mgltexsignature{%
-%     \mglcomm^^J%
-%     \mglcomm\ This script was generated from \jobname.mgl on date \today^^J%
-%     \mglcomm%
-%   }
-% \end{verbatim}
-% 
-% \DescribeMacro{\mglcommonscript}
-% It is the name for the common script that takes the contents of the |mglcommon| environment. For example, the default name of the script (``mgl\_common\_script'') is defined by doing
-% \begin{verbatim}
-%   \def\mglcommonscript{mgl_common_script}
-% \end{verbatim}
-% 
-% \subsection{Behavior of \textsf{\mglTeX}}
-% \noindent As a convenient feature, the environments |mglcode|, |mglscript| and |mglblock| will automatically check if they are being used to create different scripts with the same name, in which case \textsf{\mglTeX} will issue a warning; however, if one of these environments overwrite an external script (not embedded in the document), it won't be noticed. Likewise, the user will be warned if the environment |mglfunc| is being used to create different MGL functions with the same name.
-% 
-% When \textsf{\mglTeX} is unable to find a graphic that is supposed to include, instead of producing an error, it will warn the user about it, and will display a box in the corresponding position of the document, like the following one:
-% \begin{center}
-%   \framebox[10em]{
-%     \centering
-%     \bfseries\Huge
-%     \vbox{MGL\\image\\not\\found}
-%   }
-% \end{center}
-% Notice that the first time \LaTeX{} is executed, many of these boxes will appear in the document because the graphics from the MGL scripts are created, but not all are included (until \LaTeX{} is run for the second time).
-% \section{Warning for the user}
-% \mglTeX{} assummes that the |\begin{|\meta{environment}|}| and |\end{|\meta{environment}|}| commands will occupy their own physical line of \LaTeX{} code. So the correct form to use the environments is the following:
-% \begin{verbatim}
-%   \begin{<environment>}
-%     <contents of the environment>
-%   \end{<environment>}
-% \end{verbatim}
-% The following forms of use could cause problems:
-% \begin{verbatim}
-%   \begin{<environment>}<contents of the environment>\end{<environment>}
-% \end{verbatim}
-% \begin{verbatim}
-%   \begin{<environment>}<contents of the environment>
-%   \end{<environment>}
-% \end{verbatim}
-% \begin{verbatim}
-%   \begin{<environment>}
-%   <contents of the environment>
-%   \end{<environment>}<text>
-% \end{verbatim}
-% One of the reasons for this is that some of the environments in \mglTeX{} are programmed to ignore the empty space following the |\begin{|\meta{environment}|}|, which would cause an inelegant empty line in the script, so the first two incorrect forms would cause \mglTeX{} to ignore a complete line of code. The other reason is the method used to detect the |\end{|\meta{environment}|}| command, which could fail in the case of the third incorrect use.
-% \StopEventually{\PrintChanges\PrintIndex}
-% \section{Implementation}
-% \noindent This section documents the implementation of \mglTeX. Its purpose is to facilitate the comprehension and maintenance of the package.
-% \subsection{Initialization}
-% \noindent The \textsf{keyval} package is loaded to facilitate the declaration of \meta{key}=\meta{value} options for commands and environments; the \textsf{graphicx} package is loaded in order to manipulate and include the images created by MGL code.
-%    \begin{macrocode}
-
-\RequirePackage{keyval}
-\RequirePackage{graphicx}
-%    \end{macrocode}
-
-% We declare the options of the package. The first two are |draft| and |final|, which are passed directly to the \textsf{graphicx} package.
-%    \begin{macrocode}
-
-\DeclareOption{draft}{%
-  \PassOptionsToPackage{\CurrentOption}{graphicx}%
+%
+% \DescribeMacro{\mglcommentname} This macro expands to the words typeset before and after a MGL commentary, in the middle of the separator lines. The default words are set by
+% \begin{quote}
+%   |\def\mglcommentname{MGL commentary}|
+% \end{quote}
+%
+% \DescribeMacro{\listofmglscriptsname} This is the name of the section/chapter created by the command |\listofmglscripts|. The default is set by
+% \begin{quote}
+%   |\def\listofmglscriptsname{List of MGL scripts}|
+% \end{quote}
+%
+% \DescribeMacro{\mglverbatimname} This is the default name to be printed in the list of MGL scripts for scripts created with the unstarred version of |mglverbatim|, for which a |label| hasn't been specified. The default is
+% \begin{quote}
+%   |\def\mglverbatimname{(Unnamed MGL script)}|
+% \end{quote}
+%
+% \DescribeMacro{\mgllinenostyle} Indicates the style for typeseting the line numbers inside the |mglblock| and |mglverbatim| environments, and the |\mglinclude| command. The default is
+% \begin{quote}
+%   |\def\mgllinenostyle{\footnotesize}|
+% \end{quote}
+%
+% \DescribeMacro{\mgldashwidth} The dashes of the separator lines for the |mglcomment| environment are contained inside boxes whose width is specified by this macro. For practical purposes, this dimension can be used to increase/decrease the space between the dashes. The default is
+% \begin{quote}
+%   |\mgldashwidth=0.75em|
+% \end{quote}
+% It is recommended to use font-dependent units for this dimension, like |em|, just in case the font is changed later, so it adapts to the new metric.\footnote{A rule of thumb is to use \texttt{em} units for horizontal dimensions, and \texttt{ex} units for vertical dimensions.}
+%
+% \DescribeMacro{\mgllinethickness} It is the thickness of the separator lines for the |mglblock| and |mglverbatim| environments, and the |\mglinclude| command. The default is
+% \begin{quote}
+%   |\mgllinethickness=0.25ex|
+% \end{quote}
+% It is also recommended to use font-dependent units for this dimension, like |ex|.
+%
+% \DescribeMacro{\mglbreakindent} \textsf{\mglTeX} allows line breaking inside verbatim-like environments and commands. When a line of code is broken, |\mglbreakindent| is the indentation of the second, third, etc. continuation lines. The default is
+% \begin{quote}
+%   |\mglbreakindent=1em|
+% \end{quote}
+% Once more, font-dependent units are encourage.
+%
+% \section{Behavior of \textsf{\mglTeX}}
+% \noindent \textsf{\mglTeX} has many convenient features designed for the comfort of the user, and to reduce the possibility of unintentional malfunction.
+% \subsection{Creation and inclusion of MGL scripts and graphics}
+% \noindent All environments and commands for MGL code embedding check for multiple scripts with the same name. This detection is performed in order to avoid unintentionally overwriting scripts, or creating confusion with different verbatim chunks of code with the same name. If such multiple naming is found a warning will be issued. However, external scripts are supposed to be responsibility of the user, so no detection of multiple naming will be performed on them.
+%
+% When \textsf{\mglTeX} is unable to find a graphic that is supposed to include, instead of producing an error, it will warn the user about it, and will display a box in the corresponding position of the document like the one shown in figure~\ref{fig: MGL image not found box}.
+% \begin{figure}[!ht]
+%   \centering
+%   \fbox{%
+%     \centering%
+%     \bfseries\Huge%
+%     \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
+%   }
+%   \caption{This box is shown by \textsf{\mglTeX} instead of a graphic that should be included, but can't be found.}\label{fig: MGL image not found box}
+% \end{figure}
+% Notice that the first time or even the second time \LaTeX{} is executed, many of these boxes will appear in the document, because the first run detects changes on scripts, while the second run creates the graphics, but not all of them are included, until \LaTeX{} is run for the third time.
+%
+% Likewise, when a script isn't found, a warning will be issued for the user, and, if that script was meant to be included in the document by a |\mglinclude| command, the box shown in figure~\ref{fig: MGL script not found box} will be displayed instead.
+% \begin{figure}[!ht]
+%   \centering
+%   \fbox{%
+%     \centering%
+%     \bfseries\Huge%
+%     \begin{tabular}{c}MGL\\script\\not\\found\end{tabular}%
+%   }
+%    \caption{This box is shown by \textsf{\mglTeX} instead of a script that should be included, but can't be found.}\label{fig: MGL script not found box}
+% \end{figure}
+%
+% When \textsf{\mglTeX} is |off| no MGL graphics will be generated nor will be included, but instead, a box like the one of figure~\ref{fig: mglTeX is off box} will be shown.
+% \begin{figure}[!ht]
+%   \centering
+%   \fbox{%
+%     \centering%
+%     \bfseries\Huge%
+%     \begin{tabular}{c}\mglTeX\\is off;\\no image\\included\end{tabular}%
+%   }
+%   \caption{This box is shown instead of an image when \textsf{\mglTeX} is \texttt{off}.}\label{fig: mglTeX is off box}
+% \end{figure}
+%
+% \subsection{Recompilation-decision algorithm}\label{subsection: recompilation decision}
+% \noindent \textsf{\mglTeX} has the builtin capacity of detecting changes in MGL scripts, so that a script is recompiled only when it has changed, not every time \LaTeX{} is executed. This saves a lot of time, since most of the compilation time of a document is spent on the creation (and conversion to another format, if necessary) of the graphics.
+%
+% This is how the recompilation-decision is performed: When \textsf{\mglTeX} finds an environment or command meant to create a graphic, it checks if the command |\MGL@@@|\meta{script} is defined, where \meta{script} is the name of the current script. If the command is undefined, this means the script has changed, so the corresponding code is transcript to the file \meta{script}.mgl, and the command |\MGL@@@|\meta{script} is defined. If the command is already defined, this means the script has been created on a previous \LaTeX{} run, so this time the embedded code is compared against the contents of the script; if they are equal, then |\MGL@@@|\meta{script} is defined again, otherwise, it is undefined, so the next \LaTeX{} run will rewrite/recompile the code. This process is schematically represented in figure~\ref{fig: recompilation decision}.
+%
+% \begin{figure}[ht!]
+%   \centering
+%   \includegraphics[scale=0.35]{Recompilation_decision}
+%   \caption{The algorithm used by \textsf{\mglTeX} to decide which scripts recereate/recompile.}\label{fig: recompilation decision}
+% \end{figure}
+%
+% The recompilation-decision mechanism can be fooled, however. The |mgl| environment and |\mglplot| command have the ability to automatically name scripts by means of the use of an internal counter, unless the |label| option is specified. Suppose the user wants to add a new |mgl| environment or |\mglplot| command exactly after the $(n-1)$th script, so the $n$th script will be the newly added, while the old $n$th will be the new $(n+1)$th, and so on, altering the original numbering. This will cause \textsf{\mglTeX} to compare the old $n$th script with the old $(n+1)$th, and so on, deciding they are different, so they will be recompiled.
+%
+% There are two ways to avoid this problem: The first one is to use the |label| option on the newly arrived; the second is to wrap a complete block of the document with the |\mgltexoff| and |\mgltexon| commands, avoiding recompilation and saving time. This last option will avoid the inclusion of the MGL graphics, so it is only recommended in case of the wrapped scripts being in their final version (not needing further modification), so there is no need of updating the corresponding graphics; then, when the document is compiled in its final version, the |\mgltexoff| and |\mgltexon| can be removed. However, the most recommended way of proceeding is to use the |\mglname| command to create a separated main script per document block (section, chapter, part, etc.), so that, if a new script disrupts the original numbering, \textsf{\mglTeX} will recompile only the scripts of the current block.
+%
+% There are situations when recompilation of a script has to be forced. For example, if the default quality has changed, but the script hasn't, \textsf{\mglTeX} won't recreate the corresponding graphic by its own initiative, because it won't detect any changes in the code. In order to force recompilation, the image of the corresponding script can be deleted: \textsf{\mglTeX} will detect this abscence in the next \LaTeX{} run and recompile.
+%
+% \section{Acknowledgements}
+% \noindent \textsf{\mglTeX} was born as a small personal project. It has grown and mature under the constant suggestions and requests from Prof. Alexey Balakin.
+%
+% \section{Redistributing and modifying}
+% \noindent The \emph{source code} of \textsf{\mglTeX} (.sty, .dtx, and .ins files) can be redistributed and/or modified under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The \emph{documentation} of \textsf{\mglTeX} (.dvi, .ps, .pdf and other files) is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 
+%
+% \StopEventually{\PrintChanges\PrintIndex}
+%
+% \section{Implementation}
+% \noindent This section documents the complete implementation of \textsf{\mglTeX}. It's main purpose is to facilitate the understanding and maintanance of the package's code. For the following, we use ``|@|'' in the name of macros the user should not modify; the prefix ``|MGL|'' is used to simulate a namespace, so the macros from \textsf{\mglTeX} won't interfere with the ones from other packages.
+%
+% \subsection{Initialization}
+% \noindent We first define some macros that will serve different purposes on different parts of the package.
+% \begin{macro}{\MGL@TeX@ext}
+% Is used to determine whether the user has chosen to save graphics in \LaTeX/Tikz format.
+%    \begin{macrocode}
+\def\MGL@TeX@ext{.tex}
+%    \end{macrocode}
+% \end{macro}
+%
+% Now we declare the options |final| and |draft|, which are simply passed to the \textsf{graphicx} package.
+%    \begin{macrocode}
+
+\DeclareOption{draft}{%
+  \PassOptionsToPackage{\CurrentOption}{graphicx}%
 }
 \DeclareOption{final}{%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
 }
 %    \end{macrocode}
-% 
-% The next two options are |on| and |off|, where |on| indicates \mglTeX{} to create every script and every corresponding image every time \LaTeX{} is executed, while |off| tells not to do it, but to include the images anyway. First we declare a flag (boolean variable) |\@mgltex@on@| to know if the used passed the |on| or the |off| option.
+%
+% The next options are |on| and |off|. Since they are equivalent to the commands |\mgltexon| and |\mgltexoff|, respectively, instead of writing the same code twice (one time for the options and one time for the commands), we first define the commands and then make the options execute them. 
+% \begin{macro}{\mgltexon}
+% (Re)defines the commands to open, read, write and close scripts, and the command that includes MGL graphics.
 %    \begin{macrocode}
-\newif\if@mgltex@on@
+
+\def\mgltexon{%
+%    \end{macrocode}
+% \begin{macro}{\MGL@openout}
+% Opens a script for writing. It takes two arguments, the first being an output stream number, allocate by |\newwrite| (\TeX{} command), and the second being the path to the script.
+%    \begin{macrocode}
+  \def\MGL@openout##1##2{%
+    \immediate\openout##1="##2"%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@openin}
+% Opens a script for reading. It takes two arguments, the first being an input stream number, allocate by |\newread| (\TeX{} command), and the second being the path to the script.
+%    \begin{macrocode}
+  \def\MGL@openin##1##2{%
+    \immediate\openin##1="##2"%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@write}
+% Writes to a script opened with |\MGL@openout|. Its first argument is the output stream number of the script, and the second is the text to write.
+%    \begin{macrocode}
+  \def\MGL@write##1##2{%
+    \immediate\write##1{##2}%
+  }%
 %    \end{macrocode}
-% If the user passes the option |on|, |\@mgltex@on@| is true, and the command |\mgl@write| (which takes care of writing code to the scripts) is the normal \LaTeX{} |\immediate\write| commands;
-% \changes{v.2.0}{2014/11/15}{Add package options \texttt{on} and \texttt{off}}
+% \end{macro}
+% \begin{macro}{\MGL@read}
+% Reads one line from a script opened with |\MGL@openin|. Its first argument is the input stream number of the script, and the second is a variable where the read text will be stored. The variable is first initialized as empty; if the end of the script has been reached, then there is nothing to read, so it remains empty; otherwise, one line is read and stored in the variable, locally supressing any end line character (|\endlinechar=-1|).
 %    \begin{macrocode}
-\DeclareOption{on}{%
-  \@mgltex@on@true%
-  \def\mgl@write#1#2{%
-    \immediate\write#1{#2}%
+  \def\MGL@read##1##2{%
+    \def##2{}%
+    \ifeof##1\else%
+      \bgroup%
+      \endlinechar=-1%
+      \immediate\global\read##1 to ##2%
+      \egroup%
+    \fi%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@closeout}
+% Closes a script opened with |\MGL@openout|, whose stream number is passed as argument.
+%    \begin{macrocode}
+  \def\MGL@closeout##1{%
+    \immediate\closeout##1%
   }
-}
 %    \end{macrocode}
-% if the user passes the option |off|, |\@mgltex@on@| is false, and the command |\mgl@write| does nothing (doesn't write to scripts).
+% \end{macro}
+% \begin{macro}{\MGL@closein}
+% Closes a script opened with |\MGL@openin|, whose stream number is passed as argument.
 %    \begin{macrocode}
-\DeclareOption{off}{%
-  \@mgltex@on@false%
-  \def\mgl@write#1#2{}%
-}
+  \def\MGL@closein##1{%
+    \immediate\closein##1%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@includegraphics}
+% This is a quite sophisticated command. It is in charge of including the graphics created by \textsf{\mglTeX}.
+%    \begin{macrocode}
+  \def\MGL@includegraphics{%
 %    \end{macrocode}
-% The next options are |comments| and |nocomments|, where |comments| indicates \mglTeX{} to show the comments included inside |\mglcomments| environments, while |nocomments| tells not to do it. First we create a flag that will indicate which of these options is passed by the user.
+% First checks if the image exists. Note the |\MGL@dir| and |\MGL@graphics@dir| macros are set by the user with the |\mgldir| and |\mglgraphicsdir| commands, respectively, while |\MGL@script@name| stores the name of the script ---and thus the image--- executed, and |\MGL@graph@ext| is the extension chosen by the user to save the graphics.
 %    \begin{macrocode}
-\newif\if@mgl@comments@
+    \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}{%
 %    \end{macrocode}
-% If the user passes the option |comments|, |\@mgl@comments@| is true, and the |\mglcomments| environments print their contents;
-% \changes{v2.0}{2014/11/22}{Add package options \texttt{comments} and \texttt{nocomments}}
+% If the chosen extension is |.tex|, a \LaTeX/Tikz file has been created, which has to be simply included in the document; it will be automatically compiled by \LaTeX{}. (Observe we use the |\MGL@TeX@ext| macro defined above.)
+%    \begin{macrocode}
+      \ifx\MGL@graph@ext\MGL@TeX@ext%
+        \include{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}%
+%    \end{macrocode}
+% If the chosen extension is not |.tex|, a normal visual image has been created, so the |\includegraphics| command is invoked to deal with it. The options for this command (like |scale|, |angle|, etc.) are stored in the |\MGL@graph@keys| macro, which is defined by every environment or command that creates and compiles MGL scripts, according to the optional arguments the user has passed.
+%    \begin{macrocode}
+      \else%
+        \expandafter\includegraphics\expandafter[\MGL@graph@keys]{%
+          \MGL@dir\MGL@graphics@dir\MGL@script@name%
+        }%
+      \fi%
+    }{%
+%    \end{macrocode}
+% If the requested image doesn't exist, the issue a warning message for the user, and print a warning framed box (``\textbf{MGL image not found}'') in the place the image should occupy.
+%    \begin{macrocode}
+      \PackageWarning{mgltex}{MGL image "\MGL@script@name" not found}%
+      \fbox{%
+        \centering%
+        \bfseries\Huge%
+        \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
+      }%
+    }%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% And here ends the |\mgltexon| command.
 %    \begin{macrocode}
-\DeclareOption{comments}{%
-  \@mgl@comments@true%
 }
 %    \end{macrocode}
-% if the user passes the option |nocomments|, |\@mgl@comments@| is false, and the |\mglcomments| environments won't print their contents.
+% \end{macro}
+%
+% \begin{macro}{\mgltexoff}
+% (Re)defines the same commands as |\mgltexon| in such a way they accept the same arguments, but do nothing. The exception is |\MGL@includegraphics| which, instead of doing nothing, prints a warning framed box (``\textbf{\mglTeX{} is off; no image included}'').
 %    \begin{macrocode}
-\DeclareOption{nocomments}{%
-  \@mgl@comments@false%
+\def\mgltexoff{%
+  \PackageWarning{mgltex}{mglTeX is off}%
+  \def\MGL@openout##1##2{}%
+  \def\MGL@openin##1##2{}%
+  \def\MGL@write##1##2{}%
+  \def\MGL@read##1##2{}%
+  \def\MGL@closeout##1{}
+  \def\MGL@closein##1{}
+  \def\MGL@includegraphics{%
+    \fbox{%
+      \centering%
+      \bfseries\Huge%
+      \begin{tabular}{c}\mglTeX\\is off;\\no image\\included\end{tabular}%
+    }%
+  }%
 }
 %    \end{macrocode}
-% We then indicate the supported extensions to save the images created by the package, and the corresponding package options. The chosen extension is stored in the |\mgl@image@ext| macro for future use.
+% \end{macro}
+% Now we can declare the package options |on| and |off| so that they execute |\mgltexon| and |\mgltexoff|, respectively.
+%    \begin{macrocode}
+\DeclareOption{on}{\mgltexon}
+\DeclareOption{off}{\mgltexoff}
+%    \end{macrocode}
+%
+% The options |nocomments| and |comments| are equivalent to the commands |\mglnocomments| and |\mglcomments|, respectively, so, following the same logic as before, we first define the commands and make the options execute them.
+% \begin{macro}{\@MGL@comments@}
+% We will need a boolean switch to activate/deactivate commentaries later.
 %    \begin{macrocode}
 
-\DeclareGraphicsExtensions{%
-  .png,.eps,.jpg,.jpeg,.bps,.pdf,.epsz,.eps.gz,.bpsz,.bps.gz,.gif%
+\newif\if@MGL@comments@
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglnocomments} Declares |\@MGL@comments@| as false.
+%    \begin{macrocode}
+\def\mglnocomments{\@MGL@comments@false}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglcomments} Declares |\@MGL@comments@| as true.
+%    \begin{macrocode}
+\def\mglcomments{\@MGL@comments@true}
+%    \end{macrocode}
+% \end{macro}
+% Now, the options call the respective commands.
+%    \begin{macrocode}
+\DeclareOption{nocomments}{\mglnocomments}
+\DeclareOption{comments}{\mglcomments}
+%    \end{macrocode}
+%
+% \begin{macro}{\mglscale}\begin{macro}{\MGL@scale}
+% |\mglscale| sets the value of the |\MGL@scale| macro, which is used later to specify the default scaling for graphics. It only accepts integer values from $1$ to $9$, otherwise it issues a warning and restarts the scaling to $1$. In order to be able to check the validity of the value passed by the user, we first set the |\MGL@scale| macro to that value and test it with the |\ifcase| conditional; if the value is valid, we do nothing, but if it is invalid, we issue a warning and overwrite |\MGL@scale| to $1$.
+%    \begin{macrocode}
+
+\def\mglscale#1{
+  \def\MGL@scale{#1}%
+  \ifcase\MGL@scale\or\or\or\or\or\or\or\or\else%
+    \PackageWarning{mgltex}{%
+      Scaling value of \MGL@scale\space not allowed; using default (1)%
+    }%
+    \def\MGL@scale{1}%
+  \fi%
 }
+%    \end{macrocode}
+% \end{macro}\end{macro}
+% The pacakage options |1x|, \ldots, |9x| just call |\mglscale| with the appropiate value.
+%    \begin{macrocode}
+\DeclareOption{1x}{\mglscale{1}}
+\DeclareOption{2x}{\mglscale{2}}
+\DeclareOption{3x}{\mglscale{3}}
+\DeclareOption{4x}{\mglscale{4}}
+\DeclareOption{5x}{\mglscale{5}}
+\DeclareOption{6x}{\mglscale{6}}
+\DeclareOption{7x}{\mglscale{7}}
+\DeclareOption{8x}{\mglscale{8}}
+\DeclareOption{9x}{\mglscale{9}}
+%    \end{macrocode}
+%
+% \begin{macro}{\mglquality}\begin{macro}{\MGL@quality}
+% |\mglquality| sets the value of the |\MGL@quality| macro, which is used later to specify the default quality for graphics. It only accepts integer values from $0$ to $8$ (the only ones defined by |MathGL|), otherwise it issues a warning and restarts to $2$ (the default for |MathGL|). In order to be able to check the validity of the value passed by the user, we first set the |\MGL@quality| macro to that value and test it with the |\ifcase| conditional; if the value is valid, we print an info message to the |.log| file about the characteristics of the chosen quality, but if it is invalid, we issue a warning and overwrite |\MGL@scale| to $2$.
+% \end{macro}\end{macro}
+%    \begin{macrocode}
 
-\DeclareOption{jpg}{\def\mgl@image@ext{.jpg}}
-\DeclareOption{jpeg}{\def\mgl@image@ext{.jpeg}}
-\DeclareOption{pdf}{\def\mgl@image@ext{.pdf}}
-\DeclareOption{png}{\def\mgl@image@ext{.png}}
-\DeclareOption{eps}{\def\mgl@image@ext{.eps}}
-\DeclareOption{epsz}{\def\mgl@image@ext{.eps.gz}}
-\DeclareOption{bps}{\def\mgl@image@ext{.bps}}
-\DeclareOption{bpsz}{\def\mgl@image@ext{.bps.gz}}
-\DeclareOption{gif}{\def\mgl@image@ext{.gif}}
+\def\mglquality#1{%
+  \def\MGL@quality{#1}%
+  \ifcase\MGL@quality%
+    \PackageInfo{mgltex}{%
+      Quality 0: No face drawing (fastest)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 1: No color interpolation (fast)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 2: High quality (normal)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 3: High quality with 3d primitives (not implemented yet)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 4: No face drawing, direct bitmap drawing (low memory usage)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 5: No color interpolation, direct bitmap drawing (low memory usage)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 6: High quality, direct bitmap drawing (low memory usage)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 7: High quality with 3d primitives, direct bitmap drawing (not implemented yet)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 8: Draw dots instead of primitives (extremely fast)%
+    }%
+  \else%
+    \PackageWarning{mgltex}{%
+      Quality #1 not available; using default (2)%
+    }%
+    \def\MGL@quality{2}%
+  \fi%
+}
+%    \end{macrocode}
+% The package options |0q|, \ldots, |8q| just call |\mglquality| with the appropiate value.
+%    \begin{macrocode}
+\DeclareOption{0q}{\mglquality{0}}
+\DeclareOption{1q}{\mglquality{1}}
+\DeclareOption{2q}{\mglquality{2}}
+\DeclareOption{3q}{\mglquality{3}}
+\DeclareOption{4q}{\mglquality{4}}
+\DeclareOption{5q}{\mglquality{5}}
+\DeclareOption{6q}{\mglquality{6}}
+\DeclareOption{7q}{\mglquality{7}}
+\DeclareOption{8q}{\mglquality{8}}
+%    \end{macrocode}
+%
+% \begin{macro}{\MGL@graph@ext}
+% The following options set the default graphics extension, which is stored in the |\MGL@graph@ext| macro for later use.
+%    \begin{macrocode}
 
-\DeclareOption{tex}{\def\mgl@image@ext{.tex}}
+\DeclareOption{eps}{\def\MGL@graph@ext{.eps}}
+\DeclareOption{epsz}{\def\MGL@graph@ext{.epsz}}
+\DeclareOption{epsgz}{\def\MGL@graph@ext{.eps.gz}}
+\DeclareOption{bps}{\def\MGL@graph@ext{.bps}}
+\DeclareOption{bpsz}{\def\MGL@graph@ext{.bpsz}}
+\DeclareOption{bpsgz}{\def\MGL@graph@ext{.bps.gz}}
+\DeclareOption{pdf}{\def\MGL@graph@ext{.pdf}}
+\DeclareOption{png}{\def\MGL@graph@ext{.png}}
+\DeclareOption{jpg}{\def\MGL@graph@ext{.jpg}}
+\DeclareOption{jpeg}{\def\MGL@graph@ext{.jpeg}}
+\DeclareOption{gif}{\def\MGL@graph@ext{.gif}}
+\DeclareOption{tex}{\def\MGL@graph@ext{.tex}}
 %    \end{macrocode}
-% 
-% Other options produce an error message.
+% \end{macro}
+%
+% Any other option passed by the user is invalid, so an error message is issued.
 %    \begin{macrocode}
+
 \DeclareOption*{\@unknownoptionerror}
 %    \end{macrocode}
-% 
-% The default options for the package are set to |final| and |eps|, then the options passed by the user are processed. 
+%
+% We now declare the default package options, and, finally, process the options the user specifies in the order they are introduced.
 %    \begin{macrocode}
 
-\ExecuteOptions{final,on,nocomments,eps}
+\ExecuteOptions{final,on,nocomments,1x,2q,eps}
 \ProcessOptions*
 %    \end{macrocode}
-% 
-% Declare the \meta{key}=\meta{value} pairs for the |mgl| environment and companions. The pairs corresponding to the |\includegraphics| command are repeated, and saved in the |\graph@keys| macro; the new option is |imgext|, which can be used to overwrite the default extension chosen for the package. Notice that |imgext| can be any supported extension by MathGL but, of course, not all of them are supported by \LaTeX.
+%
+% \textsf{\mglTeX} requires the \textsf{keyval} package to define \meta{key}=\meta{value} options for the environments and commands; the \textsf{graphicx} package apports the facilities for inclusion of graphics, and the \textsf{verbatim} package is used as engine for the environments.
 %    \begin{macrocode}
 
-\define@key{mgl@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
-\define@key{mgl@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
-\define@key{mgl@keys}{bblly}{\g@addto@macro{\graph@keys}{bblly=#1,}}
-\define@key{mgl@keys}{bburx}{\g@addto@macro{\graph@keys}{bburx=#1,}}
-\define@key{mgl@keys}{bbury}{\g@addto@macro{\graph@keys}{bbury=#1,}}
-\define@key{mgl@keys}{natwidth}{\g@addto@macro{\graph@keys}{natwidth=#1,}}
-\define@key{mgl@keys}{natheight}{\g@addto@macro{\graph@keys}{natheight=#1,}}
-\define@key{mgl@keys}{hiresbb}{\g@addto@macro{\graph@keys}{hiresbb=#1,}}
-\define@key{mgl@keys}{viewport}{\g@addto@macro{\graph@keys}{viewport=#1,}}
-\define@key{mgl@keys}{trim}{\g@addto@macro{\graph@keys}{trim=#1,}}
-\define@key{mgl@keys}{angle}{\g@addto@macro{\graph@keys}{angle=#1,}}
-\define@key{mgl@keys}{origin}{\g@addto@macro{\graph@keys}{origin=#1,}}
-\define@key{mgl@keys}{width}{\g@addto@macro{\graph@keys}{width=#1,}}
-\define@key{mgl@keys}{height}{\g@addto@macro{\graph@keys}{height=#1,}}
-\define@key{mgl@keys}{totalheight}{\g@addto@macro{\graph@keys}{totalheight=#1,}}
-\define@key{mgl@keys}{keepaspectratio}{\g@addto@macro{\graph@keys}{keepaspectratio=#1,}}
-\define@key{mgl@keys}{scale}{\g@addto@macro{\graph@keys}{scale=#1,}}
-\define@key{mgl@keys}{clip}[true]{\g@addto@macro{\graph@keys}{clip=#1,}}
-\define@key{mgl@keys}{draft}[false]{\g@addto@macro{\graph@keys}{draft=#1,}}
-\define@key{mgl@keys}{type}{\g@addto@macro{\graph@keys}{type=#1,}}
-\define@key{mgl@keys}{ext}{\g@addto@macro{\graph@keys}{ext=#1,}}
-\define@key{mgl@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
-\define@key{mgl@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
-\define@key{mgl@keys}{imgext}{\def\mgl@image@ext{.#1}}
+\RequirePackage{keyval}
+\RequirePackage{graphicx}
+\RequirePackage{verbatim}
 %    \end{macrocode}
+% The supported graphic formats are declared, and the |\verbatim@finish| command from the \textsf{verbatim} package is disabled to avoid it from writing a blank line at the end of every script (see subsection~\ref{subsection: warning}).
+%    \begin{macrocode}
+\DeclareGraphicsExtensions{%
+  .eps,.epsz,.eps.gz,.bps,.bpsz,.bps.gz,.pdf,.png,.jpg,.jpeg,.gif%
+}
+\let\verbatim@finish\relax
+%    \end{macrocode}
+%
+% \begin{macro}{\MGL@graph@keys}
+% The main family of \meta{key}=\meta{value} pairs is defined. These pairs are common to every environment or command that produces graphics. Most of the \meta{key}'s are redefinitions of the optional arguments for the |\includegraphics| commands, so they are stored inside the |\MGL@graph@keys| macro, which is later passed to that command as optional argument by |\MGL@includegraphics|.
+%    \begin{macrocode}
 
-% We do the same for the |\mglplot| command. The options for the |\includegraphics| command are repeated and stored in the |\graph@keys| macro; the new options are |imgext|, which is the same as the one for the |mgl| environment, and |setup|, which is used to specify a keyword associated to a block of MGL code stored by the |mglsetup| environment.
+\define@key{MGL@keys}{bb}{\g@addto@macro\MGL@graph@keys{bb=#1,}}
+\define@key{MGL@keys}{bbllx}{\g@addto@macro\MGL@graph@keys{bbllx=#1,}}
+\define@key{MGL@keys}{bblly}{\g@addto@macro\MGL@graph@keys{bblly=#1,}}
+\define@key{MGL@keys}{bburx}{\g@addto@macro\MGL@graph@keys{bburx=#1,}}
+\define@key{MGL@keys}{bbury}{\g@addto@macro\MGL@graph@keys{bbury=#1,}}
+\define@key{MGL@keys}{natwidth}{\g@addto@macro\MGL@graph@keys{natwidth=#1,}}
+\define@key{MGL@keys}{natheight}{\g@addto@macro\MGL@graph@keys{natheight=#1,}}
+\define@key{MGL@keys}{hiresbb}{\g@addto@macro\MGL@graph@keys{hiresbb=#1,}}
+\define@key{MGL@keys}{viewport}{\g@addto@macro\MGL@graph@keys{viewport=#1,}}
+\define@key{MGL@keys}{trim}{\g@addto@macro\MGL@graph@keys{trim=#1,}}
+\define@key{MGL@keys}{angle}{\g@addto@macro\MGL@graph@keys{angle=#1,}}
+\define@key{MGL@keys}{origin}{\g@addto@macro\MGL@graph@keys{origin=#1,}}
+\define@key{MGL@keys}{width}{\g@addto@macro\MGL@graph@keys{width=#1,}}
+\define@key{MGL@keys}{height}{\g@addto@macro\MGL@graph@keys{height=#1,}}
+\define@key{MGL@keys}{totalheight}{\g@addto@macro\MGL@graph@keys{totalheight=#1,}}
+\define@key{MGL@keys}{keepaspectratio}[true]{%
+  \g@addto@macro\MGL@graph@keys{keepaspectratio=#1,}%
+}
+\define@key{MGL@keys}{scale}{\g@addto@macro\MGL@graph@keys{scale=#1,}}
+\define@key{MGL@keys}{clip}[true]{\g@addto@macro\MGL@graph@keys{clip=#1,}}
+\define@key{MGL@keys}{draft}[true]{\g@addto@macro\MGL@graph@keys{draft=#1,}}
+\define@key{MGL@keys}{type}{\g@addto@macro\MGL@graph@keys{type=#1,}}
+\define@key{MGL@keys}{ext}{\g@addto@macro\MGL@graph@keys{ext=#1,}}
+\define@key{MGL@keys}{read}{\g@addto@macro\MGL@graph@keys{read=#1,}}
+\define@key{MGL@keys}{command}{\g@addto@macro\MGL@graph@keys{command=#1,}}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@graph@ext}
+% Stores the default extension for the creation of the graphics.
+%    \begin{macrocode}
+\define@key{MGL@keys}{imgext}{\def\MGL@graph@ext{.#1}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@MGL@lineno@}
+% The only \meta{key}=\meta{value} pair needed for verbatim-like environments and commands is the one for the |lineno| option, which sets the value of the |\@MGL@lineno@| boolean macro.
 %    \begin{macrocode}
 
-\define@key{mglplot@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
-\define@key{mglplot@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
-\define@key{mglplot@keys}{bblly}{\g@addto@macro{\graph@keys}{bblly=#1,}}
-\define@key{mglplot@keys}{bburx}{\g@addto@macro{\graph@keys}{bburx=#1,}}
-\define@key{mglplot@keys}{bbury}{\g@addto@macro{\graph@keys}{bbury=#1,}}
-\define@key{mglplot@keys}{natwidth}{\g@addto@macro{\graph@keys}{natwidth=#1,}}
-\define@key{mglplot@keys}{natheight}{\g@addto@macro{\graph@keys}{natheight=#1,}}
-\define@key{mglplot@keys}{hiresbb}{\g@addto@macro{\graph@keys}{hiresbb=#1,}}
-\define@key{mglplot@keys}{viewport}{\g@addto@macro{\graph@keys}{viewport=#1,}}
-\define@key{mglplot@keys}{trim}{\g@addto@macro{\graph@keys}{trim=#1,}}
-\define@key{mglplot@keys}{angle}{\g@addto@macro{\graph@keys}{angle=#1,}}
-\define@key{mglplot@keys}{origin}{\g@addto@macro{\graph@keys}{origin=#1,}}
-\define@key{mglplot@keys}{width}{\g@addto@macro{\graph@keys}{width=#1,}}
-\define@key{mglplot@keys}{height}{\g@addto@macro{\graph@keys}{height=#1,}}
-\define@key{mglplot@keys}{totalheight}{\g@addto@macro{\graph@keys}{totalheight=#1,}}
-\define@key{mglplot@keys}{keepaspectratio}{\g@addto@macro{\graph@keys}{keepaspectratio=#1,}}
-\define@key{mglplot@keys}{scale}{\g@addto@macro{\graph@keys}{scale=#1,}}
-\define@key{mglplot@keys}{clip}[true]{\g@addto@macro{\graph@keys}{clip=#1,}}
-\define@key{mglplot@keys}{draft}[false]{\g@addto@macro{\graph@keys}{draft=#1,}}
-\define@key{mglplot@keys}{type}{\g@addto@macro{\graph@keys}{type=#1,}}
-\define@key{mglplot@keys}{ext}{\g@addto@macro{\graph@keys}{ext=#1,}}
-\define@key{mglplot@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
-\define@key{mglplot@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
-\define@key{mglplot@keys}{imgext}{\def\mglplot@image@ext{.#1}}
-\define@key{mglplot@keys}{setup}{\def\mglplot@setup{#1}}
+\newif\if@MGL@lineno@
+\define@key{MGL@verb@keys}{lineno}[true]{\csname @MGL@lineno@#1\endcsname}
 %    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MGL@main@script@name}
+% \noindent This macro stores the name of the of the document's main script. It is initialized to the name of the \LaTeX{} document.
+%    \begin{macrocode}
 
-% A special extension for images created with MathGL is ``.tex'', so we store it within a macro for future use.
+\edef\MGL@main@script@name{\jobname}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MGL@dir}
+% This is the \textsf{\mglTeX} main working directory. By default, it is defined to empty, so it points to the path of the \LaTeX{} document.
 %    \begin{macrocode}
 
-\def\TeX@ext{.tex}
+\def\MGL@dir{}
 %    \end{macrocode}
-% \subsection{Environments for MGL code embedding}
-% \begin{macro}{\mgl@include@image}
-% This is the command that will include graphics created by MGL code. We can't use |\includegraphics| directly for two reasons: first, MathGL has the capacity of creating graphics with \LaTeX{} commands (with the aid of the \textsf{tikz} package), in which case there is no image, but a ``.tex'' file, which has to be included; the second reason is that |\includegraphics| issues an error when the specified image doesn't exist, and remember that the first \LaTeX{} run only creates the images at the end of the document, but they cannot be included yet, so there would be a lot of errors in the process of compilation.
+% \end{macro}
+% \begin{macro}{\MGL@scripts@dir}
+% The subdirectory inside |\MGL@dir| where all MGL scripts will be created.
 %    \begin{macrocode}
-\def\mgl@include@image#1{%
+\def\MGL@scripts@dir{}
 %    \end{macrocode}
-% If the extension of the graphics is ``.tex'',
+% \end{macro}
+% \begin{macro}{\MGL@graphics@dir}
+% The subdirectory inside |\MGL@dir| where all MGL graphics will be created.
 %    \begin{macrocode}
-  \ifx\mgl@image@ext\TeX@ext%
+\def\MGL@graphics@dir{}
 %    \end{macrocode}
-% first check if the file exists;
+% \end{macro}
+% \begin{macro}{\MGL@backups@dir}
+% The subdirectory inside |\MGL@dir| where all backups of scripts will be created.
 %    \begin{macrocode}
-    \IfFileExists{#1.tex}{%
+\def\MGL@backups@dir{}
 %    \end{macrocode}
-% if so, include it,
+% \end{macro}
+% \begin{macro}{\MGL@paths}
+% This is a list of paths where extracted and external scripts will be searched for by the |\mglgraphics| and |\mglinclude| commands. Since extracted scripts are created inside |\MGL@dir\MGL@scripts@dir| and |\MGL@dir\MGL@backups@dir|, this directories are included.
 %    \begin{macrocode}
-      \include{#1}%
-    }{%
+\def\MGL@paths{\MGL@dir\MGL@scripts@dir,\MGL@dir\MGL@backups@dir}
 %    \end{macrocode}
-% otherwise use the command |\mgl@img@not@found| to create a warning.
+% \end{macro}
+%
+% We set some additional staff that will be used later.
+% \begin{macro}{\MGL@main@stream}
+% The output stream for the document's main script.
 %    \begin{macrocode}
-      \mgl@img@not@found{#1}%
-    }%
+
+\newwrite\MGL@main@stream
 %    \end{macrocode}
-% If the extension of the graphics is not ``.tex'',
+% \end{macro}
+% \begin{macro}{\MGL@out@stream}
+% The output stream for scripts other than the main one.
 %    \begin{macrocode}
-  \else%
+\newwrite\MGL@out@stream
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@in@stream}
+% The input stream for scripts other than the main one.
+%    \begin{macrocode}
+\newread\MGL@in@stream
 %    \end{macrocode}
-% we define the next action to be performed as warning that requested image doesn't exist. This is stored in the |\next@action| macro, and will be overwriten if the image is found.
+% \end{macro}
+% \begin{macro}{MGL@script@no}
+% The internal counter used by environments like |mgl| and commands like |\mglplot| to automatically name scripts.
 %    \begin{macrocode}
-  \def\next@action{\mgl@img@not@found{#1}}%
+\newcounter{MGL@script@no}
 %    \end{macrocode}
-% For every extension supported by \mglTeX{},
+% \end{macro}
+% \begin{macro}{MGL@line@no}
+% The counter used for verbatim-like environments and commands to numerate the lines of code.
 %    \begin{macrocode}
-    \@for\img@ext:=\Gin@extensions\do{%
+\newcounter{MGL@line@no}
 %    \end{macrocode}
-% if the file with the current extension exists,
+% \end{macro}
+% \begin{macro}{MGL@verb@script@no}
+% The counter used to numerate verbatim-written scripts with the |\listofmglscripts| command.
 %    \begin{macrocode}
-      \IfFileExists{#1\img@ext}{%
+\newcounter{MGL@verb@script@no}
 %    \end{macrocode}
-% overwrite the |\next@action| macro so it uses the |\includegraphics| command to include the image, otherwise do nothing.
+% \end{macro}
+% \begin{macro}{\@MGL@list@script@}
+% The boolean switch used to determine whether to add a verbatim-written script to the \emph{list of MGL scripts}.
 %    \begin{macrocode}
-        \def\next@action{%
-          \expandafter\includegraphics\expandafter[\graph@keys]{#1}%
-        }%
-      }{}%
-    }%
+\newif\if@MGL@list@script@
 %    \end{macrocode}
-% Execute |\next@action|.
+% \end{macro}
+% \begin{macro}{\l@MGL@script}
+% Finally, the style for the leaders associating script name and page number in the \emph{list of MGL scripts}.
 %    \begin{macrocode}
-    \next@action%
-  \fi%
+\def\l@MGL@script{\@dottedtocline{1}{0em}{1.5em}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Anatomy of environments and commands}\label{subsection: anatomy}
+% \noindent Many of the environments and commands defined by \textsf{\mglTeX} are based on the same pieces of code. So, in order to avoid repetition of commands, we use the concept of \emph{anatomy of environments and commands}, which is basically the idea of taking repetitive pieces of code and enclose them into macros which can later be used.
+%
+% \begin{macro}{\MGL@setkeys}
+% This command recieves two arguments: a family of \meta{key}=\meta{value} pairs, like |MGL@keys|, and a list of such pairs. It first cleans the |\MGL@graph@keys| macro, and the process the list of pairs.
+%    \begin{macrocode}
+
+\def\MGL@setkeys#1#2{%
+  \def\MGL@graph@keys{}%
+  \setkeys{#1}{#2}%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgl@img@not@found}
-% \changes{v2.0}{2014/11/22}{Fixed incompatibility of command \texttt{\textbackslash{}mgl@img@not@found} with environment \texttt{tabular}}
-% When this command is called with the name of a MGL image as argument, it issues a package warning indicating that the MGL image can't be found, and creates the following box in the corresponding position:
-% \begin{center}
-% \framebox[10em]{%
-%   \centering%
-%   \bfseries\Huge%
-%   \vbox{MGL\\image\\not\\found}%
-% }%
-% \end{center}
+%
+% \begin{macro}{\MGL@codes}
+% This macro changes the category codes of all special characters (like |\|, |$|, etc.) to $12$ (other), so they don't have any special meaning and can be processed as normal text. The exception is the new line character (|^^M|), which is kept active for compatibility with the \textsf{verbatim} package.
 %    \begin{macrocode}
-\def\mgl@img@not@found#1{%
-  \PackageWarning{mgltex}{MGL image "#1" not found}%
-  \framebox[10em]{%
-    \centering%
-    \bfseries\Huge%
-    \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
-  }%
+
+\def\MGL@codes{%
+  \let\do\@makeother\dospecials%
+  \catcode`\^^M\active%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{environment}{mgl}
-% This environment writes its contents to the main script \meta{document}.mgl.
-% 
-% First, declare a counter for numeration and naming of the images created from the main script \meta{document}.mgl.
+%
+% \begin{macro}{\MGL@document@scripts}
+% A macro to store the names of the scripts created or compiled in the document.
 %    \begin{macrocode}
 
-\newcounter{mgl@image@no}
+\def\MGL@document@scripts{}
 %    \end{macrocode}
-% Create an output stream for the main script \meta{document}.mgl.
+% \end{macro}
+% \begin{macro}{\MGL@set@script@name}\begin{macro}{\MGL@script@name}
+% |\MGL@set@script@name| recieves the name of a script without extension as argument, defines |\MGL@script@name| as that name, and checks if it has already been created or compiled, by comparing it with the names already stored in |\MGL@document@scripts|; if it's there already, warns the user. Finally, adds the name of the script to |\MGL@document@scripts|.
+%    \begin{macrocode}
+\def\MGL@set@script@name#1{%
+  \edef\MGL@script@name{#1}%
+  \@for\MGL@temp@a:=\MGL@document@scripts\do{%
+    \ifx\MGL@temp@a\MGL@script@name%
+      \PackageWarning{mgltex}{Multiple MGL scripts named "\MGL@script@name.mgl"}%
+    \fi%
+  }%
+  \g@addto@macro\MGL@document@scripts{\MGL@script@name,}%
+}
+%    \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\MGL@unchanged}
+% This command defines the ``switch'' |\MGL@@@|\meta{script}, where \meta{script} is passed as argument, which indicates the script \meta{script}|.mgl| has not changed. This command has to be written to the |.aux| file to be preserved from compilation to compilation.
 %    \begin{macrocode}
 
-\newwrite\mgl@script
+\def\MGL@unchanged#1{%
+  \global\@namedef{MGL@@@#1}{}%
+}
 %    \end{macrocode}
-% Open the main script at the beginning of the document (at the moment of the |\begin{document}| command).
+% \end{macro}
+%
+% \begin{macro}{\MGL@process@script}
+% It checks whether the ``switch'' |\MGL@@@\MGL@script@name| is undefined, in which case executes its first argument. If the switch is defined, it checks if the corresponding image has been created; if so, it executes its second argument; otherwise, the first one.
 %    \begin{macrocode}
-\AtBeginDocument{%
-  \if@mgltex@on@%
-    \immediate\openout\mgl@script="\mgl@dir\jobname.mgl"%
-    \mglsignature@write\mgl@script%
-  \fi%
+
+\def\MGL@process@script#1#2{%
+  \@ifundefined{MGL@@@\MGL@script@name}{%
+    #1%
+  }{%
+    \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}{%
+      #2%
+    }{%
+      #1%
+    }%
+  }%
 }
 %    \end{macrocode}
-% At the end of the document (at the moment of the |\end{document}| command):
+% \end{macro}
+%
+% \begin{macro}{\MGL@def@for@loop}\begin{macro}{\MGL@for}
+% |\MGL@def@for@loop| defines the command |\MGL@for| which is similar to the |\@for| command from the \LaTeX{} kernel, with the only exception that, instead of iterating over comma-separated lists, it can iterate over lists of items with any kind of separator, which is passed as argument of |\MGL@def@for@loop|. The body of this command is copied from the definition code of |\@for|, extracted from \emph{The \LaTeXe{} Sources} document, replacing the ``|,|'' by ``|#1|''. Note that |\MGL@for| is used only by the |\mglplot| command, but it has been included as part of the \emph{anatomy of environments and commands} to keep cleanness because it is quite long code.
 %    \begin{macrocode}
-\AtEndDocument{%
+
+\def\MGL@def@for@loop#1{%
+  \long\def\MGL@for##1:=##2\do##3{%
+    \expandafter\def\expandafter\@fortmp\expandafter{##2}%
+    \ifx\@fortmp\@empty\else%
+      \expandafter\MGL@forloop##2#1\@nil#1\@nil\@@##1{##3}%
+    \fi%
+  }%
+  \long\def\MGL@forloop##1#1##2#1##3\@@##4##5{%
+    \def##4{##1}%
+    \ifx##4\@nnil\else%
+      ##5\def##4{##2}%
+      \ifx##4\@nnil\else%
+        ##5\MGL@iforloop##3\@@##4{##5}%
+      \fi%
+    \fi%
+  }%
+  \long\def\MGL@iforloop##1#1##2\@@##3##4{%
+    \def##3{##1}%
+    \ifx##3\@nnil%
+      \expandafter\@fornoop%
+    \else%
+      ##4\relax\expandafter\MGL@iforloop%
+    \fi%
+    ##2\@@##3{##4}%
+  }%
+}
 %    \end{macrocode}
-% write an empty line on the main script (just for elegance),
+% The default |\MGL@for| loop iterates over |^^J|-separated lists, i.e, \meta{new line}-character-lists.
 %    \begin{macrocode}
-  \mgl@write\mgl@script{}%
+\MGL@def@for@loop{^^J}
 %    \end{macrocode}
-% write the MGL \emph{stop} command to stop the MathGL compiler.
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\MGL@compare@code}
+% |\MGL@compare@code| is in charge of comparing the user's MGL code, embedded within \textsf{\mglTeX} environments, with its corresponding extracted script. For that purpose, the |\verbatim@processline| and |\verbatim@finish| commands from the \textsf{verbatim} package are redefined.
 %    \begin{macrocode}
-  \mgl@write\mgl@script{stop}%
+
+\def\MGL@compare@code#1{%
 %    \end{macrocode}
-% The |\mgl@func| is a buffer that contains instructions to write MGL functions declared with |mglfunc| environment. Here, we execute those instructions.
+% \begin{macro}{\MGL@next}
+% This macro is called at the end of environments that use the |\MGL@compare@code| macro, and performs the ending actions of the comparision process, which are closing the |\MGL@in@stream| and writing the |\MGL@unchanged{\MGL@script@name}| to the |.aux| file. If during the comparison process a difference in the code is found, |\MGL@next| is redefined to only close the |\MGL@in@stream|.
 %    \begin{macrocode}
-  \mgl@func%
+  \def\MGL@next{%
+    \MGL@closein\MGL@in@stream%
+    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
+  }%
 %    \end{macrocode}
-% Close the main script.
+% \end{macro}
+% The |\verbatim@processline| command is redefined to read from the input stream to a temporary variable (|\MGL@temp@a|), and compare it with one line of code in the \LaTeX{} document, which is stored in another temporary variable (|\MGL@temp@b|). In case they are not equal, the |\MGL@next| macro is redefined to only close the input stream, and |\verbatim@processline| is redefine again to do nothing (a little speed-up).
 %    \begin{macrocode}
-  \immediate\closeout\mgl@script%
+  \def\verbatim@processline{%
+    \MGL@read\MGL@in@stream{\MGL@temp@a}%
+    \edef\MGL@temp@b{\the\verbatim@line}%
+    \ifx\MGL@temp@a\MGL@temp@b\else%
+      \def\MGL@next{\MGL@closein\MGL@in@stream}%
+      \def\verbatim@processline{}%
+    \fi%
+  }%
+%    \end{macrocode}
+% The |\verbatim@finish| macro, which is called at the end of the environment, is also redefined to perform one last read of the input stream, and then check if the end of file has been reached; if it hasn't, then, despite the end of the environment has been reached ---thus the end of code---, there is still code inside the script, so there are differences between them, and |\MGL@next| has to be redefined to do nothing but close the input stream.
+%    \begin{macrocode}
+  \def\verbatim@finish{%
+    \MGL@read\MGL@in@stream{\MGL@temp@a}%
+    \ifeof\MGL@in@stream\else%
+      \def\MGL@next{\MGL@closein\MGL@in@stream}%
+    \fi%
+  }%
 %    \end{macrocode}
-% Use the program |mglconv| (part of MathGL) to compile the main script.
+% Finally, the input stream is opened, and the comparison is started by calling |\verbatim@start|.
 %    \begin{macrocode}
-  \mgl@write{18}{mglconv -n "\mgl@dir\jobname.mgl"}%
+  \MGL@openin\MGL@in@stream{#1}%
+  \verbatim@start%
 }
-
 %    \end{macrocode}
-% \begin{macro}{\mgl}
-% The beginning of the |mgl| environment.
+% \end{macro}
+%
+% \begin{macro}{\MGL@write@funcs}
+% This macro is used only by the |mglfunc| environment. Its only purpose is to store the commands to insert MGL functions in the main script, and is called at the end of the document or when the |\mglname| command is used. For now, we only ask it to write the |stop| command\footnote{Note the |stop| command is unnecesary in newer versions of the MGL language, but it is kept in \textsf{\mglTeX} for compatibility and for elegance.} that separates the section of scripts from the section of functions in the main script.
 %    \begin{macrocode}
 
-\newcommand\mgl[1][]{%
+\def\MGL@write@funcs{\MGL@write\MGL@main@stream{stop^^J}}
 %    \end{macrocode}
-% First, process the \meta{key}=\meta{value} options for the environment.
+% \end{macro}
+% \begin{macro}{\MGL@func}
+% This is the command that writes the MGL functions. It is intended to be stored inside |\MGL@write@funcs|. It opens the backup file of the MGL function whose name is passed as argument (and has been created by a |mglfunc| environment), and then calls |\MGL@@func| to transcript from that file, line by line, to the main script.
 %    \begin{macrocode}
-  \def\graph@keys{}%
-  \setkeys{mgl@keys}{#1}%
+\def\MGL@func#1{%
+  \MGL@openin\MGL@in@stream{\MGL@dir\MGL@backups@dir#1.mgl}%
+  \MGL@@func%
+}
 %    \end{macrocode}
-% Now, make every ``special'' character (\textbackslash, \$, etc.) of category $13$ (other), i.e., make them common characters.
+% \end{macro}
+% \begin{macro}{\MGL@@func}
+% This command transcripts only one line from backup file of a MGL function to the main script. It calls itself recursively until the end of the backup.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
+\def\MGL@@func{%
 %    \end{macrocode}
-% Add an end-line character at the end of every read line. This end-line character is declared active (category 12).
+% It first reads from the input stream to the |\MGL@temp@a| temporary variable.
 %    \begin{macrocode}
-  \endlinechar`\^^M \catcode`\^^M\active%
+  \MGL@read\MGL@in@stream{\MGL@temp@a}%
 %    \end{macrocode}
-% Spaces characters are category 10; the spaces at the beginning of every read line are ignored.
+% If the end of the file has been reached, the stream is closed.
 %    \begin{macrocode}
-  \catcode`\ =10%
+  \ifeof\MGL@in@stream%
+    \MGL@closein\MGL@in@stream%
 %    \end{macrocode}
-% Finally, the command that reads/writes each line of the contents of the environment is called.
+% If the end of file hasn't been reached, |\MGL@temp@a| is written to the main script, and |\MGL@@func| is called recursively.
 %    \begin{macrocode}
-  \mgl@write\mgl@script{quality \mgl@quality}%
-  \expandafter\mgl@write@line%
+  \else%
+    \MGL@write\MGL@main@stream{\MGL@temp@a}%
+    \expandafter\MGL@@func%
+  \fi%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\end@mgl}
-% Define a macro that contains the |\end{mgl}| command as text, so the end of the environment can be tested by comparison with it. From now on, we adopt the convention that the macro |\end@|\meta{environment} contains the |\end{|\meta{environment}|}| command as text.
+%
+% \begin{macro}{\MGL@set@verbatim@code}
+% This command sets the parameters for verbatim-like environments and commands.
+%    \begin{macrocode}
+
+\def\MGL@set@verbatim@code{%
+%    \end{macrocode}
+% The following is standard stuff for verbatim-like environments and commands.
+%    \begin{macrocode}
+  \if@minipage\else\vskip\parskip\fi%
+  \leftskip\@totalleftmargin\rightskip\z@skip%
+  \parindent\z@\parfillskip\@flushglue\parskip\z@%
+  \@@par%
+  \def\par{%
+    \if@tempswa%
+      \leavevmode\null\@@par\penalty\interlinepenalty%
+    \else%
+      \@tempswatrue%
+      \ifhmode\@@par\penalty\interlinepenalty\fi%
+    \fi%
+  }%
+  \obeylines%
+  \let\do\@makeother\dospecials%
+  \verbatim@font%
+  \frenchspacing%
+  \everypar\expandafter{\the\everypar\unpenalty}%
+%    \end{macrocode}
+% If there are no lines of MGL code, instead of issuing an error, we display a package warning.
+%    \begin{macrocode}
+  \def\@noitemerr{\PackageWarning{mglTeX}{Empty MGL script}}%
+%    \end{macrocode}
+% The space between the end of the label box and the text of the first item (|\labelsep|) is set to |1em|, while the separation between items (|\itemsep|) is set to zero.
+%    \begin{macrocode}
+  \labelsep1em%
+  \itemsep\z@%
+%    \end{macrocode}
+% Since we want the lines of code to be broken between words, but verbatim spaces are unbreakable, we trick \LaTeX{} by inserting a breakable spaces (|\space|) instead.
 %    \begin{macrocode}
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mgl{\string\\end\string\{mgl\string\}}%
-\endgroup
+  \def\@xobeysp{\space}\@vobeyspaces%
+%    \end{macrocode}
+% However, \LaTeX{} still resists breaking lines as much as possible in order to preserve the shape of paragraphs, so we tell it it's OK not to do so by setting the badness tolerance before hyphenation (|\pretolerance|) and the badness above which bad hboxes will be shown (|\hbadness|) to the maximum value of $10000$ (|\@M|).
+%    \begin{macrocode}
+  \pretolerance\@M%
+  \hbadness\@M%
+%    \end{macrocode}
+% In order to achieve the desired indentation of broken lines, we use the following trick: We increase the |\leftskip| parameter by the amount specified by |\mglbreakindent|, so that lines will be indented; but then we decrease the |\itemindent| parameter by the same amount so the first line won't be indented.
+%    \begin{macrocode}
+  \advance\leftskip\mglbreakindent%
+  \itemindent-\mglbreakindent%
+}
 %    \end{macrocode}
 % \end{macro}
+%
+% \begin{macro}{\MGL@line@sep}
+% This is the separator displayed at the beginning and ending of the |mglblock| and |mglverbatim| environments, to distinguish the MGL code from the normal text. Its definition is similar to the one of the |\dotfill| command, which can be found in \emph{The \LaTeXe{} Sources} document, but |\nopagebreak| commands have been added to avoid unaesthetic page breaking before and after the separators.
+%    \begin{macrocode}
 
-% \begin{macro}{\mgl@write@line}
-% This command reads each line from the |mgl| environment and writes it to the general script \meta{document}.mgl. We start by wrapping the new command with a \LaTeX{} group because we will change the code of the end-line character to ``active'' \emph{locally}, so we can indicate |\mgl@write@line| that its argument stretches until the end of the line.
+\def\MGL@line@sep{%
+  \nopagebreak%
+  \leavevmode\cleaders\hrule height\mgllinethickness\hfill\kern\z@%
+  \nopagebreak%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MGL@dash@sep}
+% This is the separator displayed at the begginning and ending of the |mglcomments| environment, when it is allowed to be displayed.
 %    \begin{macrocode}
-\begingroup%
+\def\MGL@dash@sep{%
+  \nopagebreak%
+  \leavevmode\cleaders\hb@xt@\mgldashwidth{\hss-\hss}\hfill\kern\z@%
+  \nopagebreak%
+}
 %    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Environments for MGL code embedding}
+% \noindent For the following, we agree that if a macro is required by an environment, and it hasn't been already defined, it will be defined between the commands that start and end such environment; also the command's name will have the environment's name as prefix.
+%
+% \begin{environment}{mgl}
+% This environment has to transcript its contents to the document's main script, and create a backup of the code simultaneously; the backup is used to detect changes in following compilations.
+% \begin{macro}{\mgl}
+% The command that starts the |mgl| environment. It is called by the |\begin{mgl}| command.
+%    \begin{macrocode}
 
-% Declare the end-line character as active.
+\newcommand\mgl[1][]{%
+%    \end{macrocode}
+% We define an additional \meta{key}=\meta{value} pair in the main family of pairs, corresponding to the |label| option for this environment. This definition is local because we don't want to be valid outside the environment.
 %    \begin{macrocode}
-  \catcode`\^^M\active%
+  \define@key{MGL@keys}{label}{\def\MGL@script@name{##1}}%
 %    \end{macrocode}
-% The command |\mgl@write@line| reads its argument until it finds the end-line character, i.e., it reads a complete line of text, which is MGL code in this case.
+% The list of comma-separated options is processed.
 %    \begin{macrocode}
-  \gdef\mgl@write@line#1^^M{%
+  \MGL@setkeys{MGL@keys}{#1}%
 %    \end{macrocode}
-% The next action to be performed is write the read line of code to the main script \meta{document}.mgl and recursively call |\mgl@write@line|, so it reads the next line of text. These instructions are stored in the |\next@action| macro.
+% If the user hasn't used the |label| option, the automatic naming mechanism is called. Note that |\MGL@main@script@name| is set using the |\mglname| command.
 %    \begin{macrocode}
-    \def\next@action{%
-      \mgl@write\mgl@script{#1}%
-      \mgl@write@line%
-    }%
+  \@ifundefined{MGL@script@name}{%
+    \stepcounter{MGL@script@no}%
+    \edef\MGL@script@name{\MGL@main@script@name-MGL-\arabic{MGL@script@no}}%
+  }{}%
+%    \end{macrocode}
+% We use the |\MGL@set@script@name| to test whether the given name has already been used.
+%    \begin{macrocode}
+  \MGL@set@script@name{\MGL@script@name}%
 %    \end{macrocode}
-% The |\test@end@mgl| command test if the end of the |mgl| environment has been reached in the current line. If so, it overwrites the |\next@action| macro so it doesn't read the next line of text, but executes the |\end{mgl}| command (see bellow).
+% |\MGL@codes| is used to change the codes of special characters.
 %    \begin{macrocode}
-    \test@end@mgl{#1}%
+  \MGL@codes%
 %    \end{macrocode}
-% Execute the |\next@action| macro.
+% |\MGL@process@script| is used to test whether the code has changed or not the last time \LaTeX{} has been executed. If it has changed, we call the |\mgl@write@script| command to (re)write the code; otherwise, the code is scanned again by asking |\MGL@compare@code| to perform a comparison on the backup file, in order to determine whether the code has changed now.
 %    \begin{macrocode}
-    \next@action%
+  \MGL@process@script{%
+    \mgl@write@script%
+  }{%
+    \MGL@compare@code{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
   }%
-\endgroup
+}
 %    \end{macrocode}
 % \end{macro}
-
-% \begin{macro}{\test@end@mgl}
-% This command checks if its argument is equal to |\end@mgl|; if so, overwrites  the |\next@action| macro (see above) so that it executes the end of the |mgl| environment (|\end{mgl}|). Here, we adopt another convention: the |\test@end@|\meta{environment} checks if its argument is equal to |\end@|\meta{environment}, i.e., tests whether the |\end{|\meta{environment}|}| command has been reached, in which case, it executes that command.
+% \begin{macro}{\mgl@write@script}
+% (Re)writes the contents of the |mgl| environment.
 %    \begin{macrocode}
-\def\test@end@mgl#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mgl%
-    \def\next@action{\end{mgl}}%
-  \fi%
+\def\mgl@write@script{%
+%    \end{macrocode}
+% \begin{macro}{\MGL@next}
+% It contains the actions to perform immediately after the end of |\mgl@write@script|. They are close the output stream; write in the main script the commands to save the image, and to reset the initial values for all MGL parameters and clear the image; finally, write |\MGL@unchanged{\MGL@script@name}| in the |.aux| file.
+%    \begin{macrocode}
+  \def\MGL@next{%
+    \MGL@closeout\MGL@out@stream%
+    \MGL@write\MGL@main@stream{%
+      write '\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext'^^J%
+      ^^Jreset^^J%
+    }%
+    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% Now we redefine the |\verbatim@processline| macro to write |\the\verbatim@line| to the main script and to the backup file.
+%    \begin{macrocode}
+  \def\verbatim@processline{%
+    \MGL@write\MGL@main@stream{\the\verbatim@line}%
+    \MGL@write\MGL@out@stream{\the\verbatim@line}%
+  }%
+%    \end{macrocode}
+% Before writing the MGL code of the environment, we set the default quality.
+%    \begin{macrocode}
+  \MGL@write\MGL@main@stream{quality \MGL@quality}%
+%    \end{macrocode}
+% We open the backup file in the output stream.
+%    \begin{macrocode}
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
+%    \end{macrocode}
+% The transcription process starts by calling the |\verbatim@start| command.
+%    \begin{macrocode}
+  \verbatim@start%
 }
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\endmgl}
-% The end of the environment is quite simple: the |mgl@image@no| counter is increased by one, then the MGL command to save the corresponding image is written; the name given to the image is ``\meta{document}-mgl-\meta{mgl@image@no}.\meta{mgl@image@ext}''; the MGL \emph{reset} command is written in the main script to clean the image and restart graphic parameters for the following image to be created. Finally, the |\mgl@include@image| command (see below) is called to include the image created.
+% The command that ends the |mgl| evironment. It is called by the |\end{mgl}| command. It simply calls |\MGL@next| to execute the final actions, and |\MGL@includegraphics| to insert the corresponding image. Note that |\MGL@next| performs different actions depending on whether |\MGL@process@script| calls |\mgl@write@script| or |\MGL@compare@code|, both of which define |\MGL@next| differently.
 %    \begin{macrocode}
 \def\endmgl{%
-  \stepcounter{mgl@image@no}%
-  \mgl@write\mgl@script{%
-    write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'%
-  }%
-  \mgl@write\mgl@script{reset}%
-  \mgl@write\mgl@script{}%
-  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
+  \MGL@next%
+  \MGL@includegraphics%
 }
 %    \end{macrocode}
 % \end{macro}
 % \end{environment}
+%
 % \begin{environment}{mgladdon}
-% This is just a modification of the |mgl| environment. First, we define the |\end@mgladdon| to contain the |\end{mgladdon}| command as text as specified above, then we redefined |\test@end@mgl| command to check for the end of the |mgladdon| environment instead of |mgl|, finally we call the |\mgl| command with no options. The end of |mgladdon| is defined to do nothing.
+% This environment only writes its contents to the document's main script, so no backup is created, nor compilation or inclusion of graphics.
+% \begin{macro}{\mgladdon}
+% Since this environment doesn't produce any output in the \LaTeX{} document, we start a \emph{space hack} by calling |\@bsphack|. We set the appropiate category codes with |\MGL@codes|; the |\verbatim@processline| is redefined to transcript |\the\verbatim@line| to the main script; finally, the |\verbatim@start| command starts the transcription process.
 %    \begin{macrocode}
 
-\bgroup%
-  \escapechar=-1\relax%
-  \xdef\end@mgladdon{\string\\end\string\{mgladdon\string\}}%
-\egroup%
-\newenvironment{mgladdon}{%
-  \def\test@end@mgl##1{%
-    \edef\this@line{##1}%
-    \ifx\this@line\end@mgladdon%
-      \def\next@action{\end{mgladdon}}%
-    \fi%
+\def\mgladdon{%
+  \@bsphack%
+  \MGL@codes%
+  \def\verbatim@processline{%
+    \MGL@write\MGL@main@stream{\the\verbatim@line}%
   }%
-  \mgl[]%
-}{}
+  \verbatim@start%
+}
 %    \end{macrocode}
-% \end{environment}
-% \begin{environment}{mglcode}
-% This is like |mgl|, but it writes its contents to its own file, whose name is passed as mandatory argument.
-% \begin{macro}{\mgl@script@written}
-
-% The names of all the scripts written from the \LaTeX{} document will be stored in this macro, so we can later check if some script is being overwritten. This macro will be used in other environments.
+% \end{macro}
+% \begin{macro}{\endmgladdon}
+% The environment ends by closing the \emph{space hack} with |\@esphack|.
 %    \begin{macrocode}
-\def\mgl@script@written{}
+\def\endmgladdon{\@esphack}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgl@out@stream}
-% Declare an output stream for MGL scripts other than the main one. This stream will be used in other environments.
+% \end{environment}
+%
+% \begin{environment}{mglfunc}
+% This environment is used to define MGL functions inside the document's main script. Instead of writing directly to the main script, which would cause the MGL parser to end the execution of that script, it writes to a backup file which is later transcript before closing the main script.
+% \begin{macro}{\mglfunc}
+% It starts the |mglfunc| environment.
 %    \begin{macrocode}
-\newwrite\mgl@out@stream
+
+\newcommand\mglfunc[2][0]{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglcode}
-% The beginning of the |mglcode| environment.
+% Once again, since this command doesn't produce any output in the \LaTeX{} document, we use a \emph{space hack}.
 %    \begin{macrocode}
-\newcommand\mglcode[2][]{%
-  \def\graph@keys{}%
+  \@bsphack%
 %    \end{macrocode}
-% Process the \meta{key}=\meta{value} options. These are the same for the |mgl| environment.
+% Although MGL functions and normal scripts are diferent in nature, in the sense that the first don't produce graphics by themselves, we have to check whether the function is being named as another script, because otherwise we run the risk of overwriting a backup file or confusing the parser.
 %    \begin{macrocode}
-  \setkeys{mgl@keys}{#1}%
+  \MGL@set@script@name{#2}%
 %    \end{macrocode}
-% Test if a script with the same name is already created from the \LaTeX{} document. If so, a warning is issue, but we proceed anyway.
+% The instruction to transcript from the backup file to the main stream is stored in |\MGL@write@funcs| (see subsection \ref{subsection: anatomy}).
 %    \begin{macrocode}
-  \test@mgl@script@written{#2}%
+  \g@addto@macro\MGL@write@funcs{\MGL@func{#2}}%
 %    \end{macrocode}
-% Add the script's name to the |\mgl@script@written| macro.
+% The codes for special characters are set.
 %    \begin{macrocode}
-  \xdef\mgl@script@written{\mgl@script@written#2,}%
+  \MGL@codes%
 %    \end{macrocode}
-% Open the script for writing.
+% The |\verbatim@processline| command is redefined to write |\the\verbatim@line| to the backup file.
 %    \begin{macrocode}
-  \def\this@script{#2}%
-  \if@mgltex@on@%
-    \immediate\openout\mgl@out@stream=\mgl@dir\this@script.mgl%
-    \mglsignature@write\mgl@out@stream%
-  \fi%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
 %    \end{macrocode}
-%   Here, we do the same changes of categories as in the |mgl| environment, except for the spaces, which in this case will be respected, even the ones at the beginning of each like, i.e., we will write each line \emph{verbatim}.
+% The backup file is opened for writing.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \obeyspaces%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
 %    \end{macrocode}
-% Call the command that will write each line of the contents of the environment.
+% The head of the function is written.
 %    \begin{macrocode}
-  \expandafter\mglcode@write@line%
+  \MGL@write\MGL@out@stream{func '\MGL@script@name' #1}%
+%    \end{macrocode}
+% The writing process is started.
+%    \begin{macrocode}
+  \verbatim@start%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\test@mgl@script@written}
-% The macro that checks is we are overwriting any script.
+% \begin{macro}{\endmglfunc}
+% It ends the |mglfunc| environment.
+%    \begin{macrocode}
+\def\endmglfunc{%
+%    \end{macrocode}
+% The end of the function is written.
 %    \begin{macrocode}
-\def\test@mgl@script@written#1{%
+  \MGL@write\MGL@out@stream{return^^J}%
 %    \end{macrocode}
-% For every script already written (whose name is stored in |\mgl@script@written|), check if the current script's name matches; if so, issue a warning telling we are overwriting, but proceed.
+% The output stream is closed.
 %    \begin{macrocode}
-  \edef\this@script{#1}%
-  \@for\mgl@script@name:=\mgl@script@written\do{%
-    \ifx\this@script\mgl@script@name%
-      \PackageWarning{mgltex}{Overwriting MGL script "\this@script.mgl"}%
-    \fi%
+  \MGL@closeout\MGL@out@stream%
+%    \end{macrocode}
+% The \emph{space hack} is terminated.
+%    \begin{macrocode}
+  \@esphack%
+}%
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \begin{environment}{mglcode}
+% This environment also checks for changes on the code, but, since it writes to its own script, there is no need to create a backup file (the check is performed using the script itself).
+% \begin{macro}{\mglcode}
+% It starts the |mglcode| environment. Its anatomy is similar to that of the |\mgl| command.
+%    \begin{macrocode}
+
+\newcommand\mglcode[2][]{%
+  \MGL@setkeys{MGL@keys}{#1}%
+  \MGL@set@script@name{#2}%
+  \MGL@codes%
+  \MGL@process@script{%
+    \mglcode@write@script%
+  }{%
+    \MGL@compare@code{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
   }%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglcode@write@line}
-% This writes each line of the contents of the |mglcode| environment. However, contrary to the case of the |\mgl@write@line| command, it doesn't read line by line, but character by character, and stores each word in |\mgl@word| and each line in |\mgl@line|.
+% \begin{macro}{\mglcode@write@script}
+% This command takes care of creating the script for the |mglcode| environment.
 %    \begin{macrocode}
-\newtoks\mgl@word
-\newtoks\mgl@line
-\def\mglcode@write@line#1{%
+\def\mglcode@write@script{%
 %    \end{macrocode}
-% The next action (stored as |\next@action|) is to read the following character, unless overwritten later.
+% \begin{macro}{\MGL@next}
+% It performs the actions immediately following the end of |\mglcode@write@script|.
 %    \begin{macrocode}
-  \let\next@action\mglcode@write@line%
+  \def\MGL@next{%
 %    \end{macrocode}
-% If the current character is an end-line character,
+% The output stream is closed.
 %    \begin{macrocode}
-  \expandafter\if#1\^^M%
+    \MGL@closeout\MGL@out@stream%
 %    \end{macrocode}
-% write the contents of |\mgl@line|, i.e., the current line, and clean |\mgl@word| and |\mgl@line|;
+% The |\MGL@unchanged{\MGL@script@name}| command is written to the |.aux| file.
 %    \begin{macrocode}
-    \mgl@write\mgl@out@stream{\the\mgl@line}%
-    \mgl@word{}%
-    \mgl@line{}%
+    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
 %    \end{macrocode}
-% if the current character is a space, clean |\mgl@word|, but add the space to |\mgl@line|;
+% The script compilation instruction is written to the terminal.
 %    \begin{macrocode}
-  \else\expandafter\if#1\space%
-    \mgl@word{}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
+    \MGL@write{18}{%
+      mglconv -q \MGL@quality\space -S \MGL@scale\space%
+      -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+      -o "\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext"\space%
+      "\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl"%
+    }%
+  }%
 %    \end{macrocode}
-% otherwise, the current character is alphanumeric and is added both to |\mgl@word| and |\mgl@line|, and
+% \end{macro}
+% The |\verbatim@processline| command is redefined so it writes |\the\verbatim@line| to the output stream.
 %    \begin{macrocode}
-  \else%
-    \mgl@word\expandafter{\the\mgl@word#1}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
 %    \end{macrocode}
-% we test if the current word (|\mgl@word|) is |\end{mglcode}|, in which case, |\next@action| is overwritten to |\end{mglcode}|.
+% The script is opened for writing in the output stream.
 %    \begin{macrocode}
-    \test@end@mglcode{\the\mgl@word}%
-  \fi\fi%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
 %    \end{macrocode}
-% Finally, execute |\next@action|.
+% The writing process is started by calling the |\verbatim@start| command.
 %    \begin{macrocode}
-  \next@action%
-}
-%    \end{macrocode}
-% \end{macro}
-% 
-% \begin{macro}{\test@end@mglcode}
-% The |\test@end@mglcode| checks if it's argument is equal to |\end@mglcode|, in which case overwrites |\next@action| to |\end{mglcode}|.
-%    \begin{macrocode}
-\begingroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglcode{\string\\end\string\{mglcode\string\}}%
-\endgroup%
-\def\test@end@mglcode#1{%
-  \edef\this@word{#1}%
-  \ifx\this@word\end@mglcode%
-    \def\next@action{\end{mglcode}}%
-  \fi%
+  \verbatim@start%
 }
 %    \end{macrocode}
 % \end{macro}
-% 
 % \begin{macro}{\endmglcode}
-% The end of the |mglcode| environment. It closes the output stream |\mgl@out@stream|, and calls the \textsf{mglconv} program (part of MathGL) to execute the script. Finally, the |\mgl@include@image| command is used to include the image created.
+% It ends the |mglcode| environment. |\MGL@next| is called to perform the final actions and |\MGL@includegraphics| is called to insert the corresponding image. Once more, |\MGL@next| has different meanings depending on whether |\MGL@process@script| branches to |\MGL@compare@code| or |\mglcode@write@script|.
 %    \begin{macrocode}
 \def\endmglcode{%
-  \immediate\closeout\mgl@out@stream%
-  \mgl@write{18}{%
-    mglconv "\mgl@dir\this@script.mgl" -s "\mgl@dir\mglcommonscript.mgl" -o "\mgl@dir\this@script\mgl@image@ext"%
-  }%
-  \mgl@include@image{\mgl@dir\this@script}%
+  \MGL@next%
+  \MGL@includegraphics%
 }
 %    \end{macrocode}
 % \end{macro}
 % \end{environment}
-% 
 % \begin{environment}{mglscript}
-% This is just a modification of the |mglcode| environment. First, we define the |\end@mglscript| macro; then we modify the |\test@end@mglcode| to check for |\end{mglscript}| instead of |\end{mglcode}|; finally, we call the |\mglcode| macro with the same mandatory argument as |mglscript|. The |\end{mglscript}| just closes the output stream |\mgl@out@stream|, but doesn't create nor includes any image.
+% The only function of this environment is to write its contents to a script; no image is created. It has been considered that scanning the code looking for changes is as much operation-expensive as simply writing the code, so it has been decided that this environment (over)writes the script everytime it's executed, without performing any check.
+% \begin{macro}{\mglscript}
+% Starts the environment. Its anatomy is similar to the previous environments. Since no output is written to the \LaTeX{} document, a \emph{space hack} is used.
 %    \begin{macrocode}
 
-\bgroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglscript{\string\\end\string\{mglscript\string\}}%
-\egroup%
-\newenvironment{mglscript}[1]{%
-  \def\test@end@mglcode##1{%
-    \edef\this@word{##1}%
-    \ifx\this@word\end@mglscript%
-      \def\next@action{\end{mglscript}}%
-    \fi%
-  }%
-  \mglcode{#1}%
-}{%
-  \immediate\closeout\mgl@out@stream%
+\def\mglscript#1{%
+  \@bsphack%
+  \MGL@set@script@name{#1}%
+  \MGL@codes%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  \verbatim@start%
 }
 %    \end{macrocode}
-% \end{environment}
-% 
-% \begin{environment}{mglfunc}
-% This environment is used to create MGL functions in the main script \meta{document}.mgl.
-% \begin{macro}{\mglfunc@defined}
-% Within this macro we will store the names of the MGL functions already defined from the \LaTeX{} document, so that we can check if we are overwriting one of them
-%    \begin{macrocode}
-
-\def\mglfunc@defined{}
-%    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgl@func}
-% This is a buffer to store the instructions to write the MGL functions code when the |\end{document}| command is called. This is done this way, because the functions have to be after the \emph{stop} command from the MGL language, which stops the execution of the MGL compiler, so no code should be after the \emph{stop}, except for functions.
+% \begin{macro}{\endmglscript}
+% It ends the |mglscript| environment. The \emph{space hack} ends here, too.
 %    \begin{macrocode}
-\def\mgl@func{}
+\def\endmglscript{%
+  \MGL@closeout\MGL@out@stream%
+  \@esphack%
+}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglgunc}
-% The beginning of the |mglfunc| environment.
+% \end{environment}
+%
+% \begin{environment}{mglcommon}
+% This environment doesn't require any backup file nor any scanning for changes. Although the user sets the name of the script by redifining |\mglcommonscriptname|, it is necessary to perform a check of the name, just in case a name has been inadvertedly repeated.
+% \begin{macro}{\mglcommon}
+% Starts the |mglcommon| environment.
 %    \begin{macrocode}
 
-\newcommand\mglfunc[2][0]{%
-%    \end{macrocode}
-% First, check if a function with the current name is already defined, in which case we issue a warning, but proceed anyway.
-%    \begin{macrocode}
-  \test@mglfunc@defined{#2}%
+\def\mglcommon{%
+  \@bsphack%
+  \MGL@set@script@name{\mglcommonscriptname}%
+  \MGL@codes%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  \verbatim@start%
+}
 %    \end{macrocode}
-% Add the name of the current function to the list of functions defined.
+% It is declared to be an only-preamble command, so it can't be used after the |\begin{document}| instruction.
 %    \begin{macrocode}
-  \g@addto@macro{\mglfunc@defined}{#2,}%
+\@onlypreamble\mglcommon
 %    \end{macrocode}
 % \end{macro}
-% Here we do the same changes of categories as in the |mgl| environment.
-%    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \catcode`\ =10%
-%    \end{macrocode}
-% Write an empty line in the main script just for elegance (and to visually separate different functions, too).
-%    \begin{macrocode}
-  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{}}%
-%    \end{macrocode}
-% Write the heading of the function.
-%    \begin{macrocode}
-  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{func '#2' #1}}%
-%    \end{macrocode}
-% Call the command that will write each line of the contents of the environment.
+% \begin{macro}{\endmglcommon}
+% It ends the |mglcommon| environment.
 %    \begin{macrocode}
-  \expandafter\mglfunc@write@line%
+\def\endmglcommon{%
+  \MGL@closeout\MGL@out@stream%
+  \@esphack%
 }
 %    \end{macrocode}
-% \begin{macro}{\test@mglfunc@defined}
-% This command tests if a function with a given name---given as argument---is already defined from the \LaTeX{} document; if so, a warning will be issued indicating multiple definitions for the same function, but we will proceed anyway.
+% \end{macro}
+% \end{environment}
+%
+% \subsection{Fast creation of graphics}
+% \begin{environment}{mglsetup}
+% This environment is meant to contain code that is executed just before the instruction of a |\mglplot| command, producing always the same ouput. Instead of writing a new chunk of code for that purpose, |mglsetup| is defined as a special case of the |mglfunc| environment, with the exception that the MGL function obtained this way doesn't accept any argument ---thus producing always the same output.
+% \begin{macro}{\mglsetup}
+% It is defined as an alias for |\mglfunc|, but only the name of the MGL function is passed to it, forcing the assumption that the number of arguments for the function is zero.
 %    \begin{macrocode}
-\def\test@mglfunc@defined#1{%
-  \def\this@func{#1}%
-  \@for\mglfunc@name:=\mglfunc@defined\do{%
-    \ifx\this@func\mglfunc@name%
-      \PackageWarning{\mgl@name}{MGL function "#1" has multiple definitions}%
-    \fi%
-  }%
-}
+
+\def\mglsetup#1{\mglfunc{#1}}%
 %    \end{macrocode}
 % \end{macro}
-% We declare \emph{locally} the end-line character as active.
+% \begin{macro}{\endmglsetup}
+% Likewise, it is defined as an alias for |\endmglfunc|.
 %    \begin{macrocode}
-\begingroup%
-  \catcode`\^^M\active%
+\let\endmglsetup\endmglfunc
 %    \end{macrocode}
-% \begin{macro}{\mglfunc@write@line}
-% This is the command that reads each line of code of the |mglfunc| environment, and stores in the buffer |\mgl@func| the instructions to write each of these lines.
+% \end{macro}
+% \end{environment}
+%
+% \begin{macro}{\mglplot}
+% Although the function of this command is quite simple and straightforward, it requires many lines of code and some tricks in order to reach the desired functionality.
 %    \begin{macrocode}
-  \gdef\mglfunc@write@line#1^^M{%
+
+\newcommand\mglplot[2][]{%
 %    \end{macrocode}
-% The next action (|\next@action|) is to store in the buffer the instruction to write the current line, and then call recursively the |\mglfunc@write@line| command, unless overwritten below.
+% We add some \meta{key}=\meta{value} pairs locally. The |label| key works exactly as the one of the |mgl| environment.
 %    \begin{macrocode}
-    \def\next@action{%
-      \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{#1}}%
-      \expandafter\mglfunc@write@line%
-    }%
+  \define@key{MGL@keys}{label}{\edef\MGL@script@name{##1}}%
 %    \end{macrocode}
-% Check for the end of the |mglfunc| environment, in which case, |\next@action| is redefined to be |\end{mglfunc}|.
+% The |setup| key defines the variable |\MGL@mglplot@setup| which is later used to call a setup function for the corresponding image.
 %    \begin{macrocode}
-    \test@end@mglfunc{#1}%
+  \define@key{MGL@keys}{setup}{\def\MGL@mglplot@setup{##1}}%
 %    \end{macrocode}
-% Execute |\next@action|.
+% The |separator| key uses the |\MGL@def@for@loop| to define |\MGL@for| so that it iterates over lists separated by the indicated separator symbol.
 %    \begin{macrocode}
-    \next@action%
+  \define@key{MGL@keys}{separator}{%
+    \MGL@def@for@loop{##1}%
   }%
 %    \end{macrocode}
-% \end{macro}
+% Now, we process the keys passed by the user.
 %    \begin{macrocode}
-\endgroup
+  \MGL@setkeys{MGL@keys}{#1}%
 %    \end{macrocode}
-% \begin{macro}{\end@mglfunc}
-% \begin{macro}{\test@end@mglfunc}
-% By now, we already know now these two commands work.
+% If the user hasn't specified a name using the |label| option, then a name is autogenerated following the same naming mechanism of the |mgl| environment.
 %    \begin{macrocode}
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mglfunc{\string\\end\string\{mglfunc\string\}}%
-\endgroup
-\def\test@end@mglfunc#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mglfunc%
-    \def\next@action{\end{mglfunc}}%
-  \fi%
-}
+  \@ifundefined{MGL@script@name}{%
+    \stepcounter{MGL@script@no}
+    \edef\MGL@script@name{\MGL@main@script@name-MGL-\arabic{MGL@script@no}}
+  }{}%
 %    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\endmglfunc}
-% Just stores in the buffer the instruction that closes the MGL function with the \emph{return} command.
+% The name of the script is checked.
 %    \begin{macrocode}
-\def\endmglfunc{%
-  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{return}}%
-}
-
-% \begin{environment}{mglcommon}
-% Writes its contents to a common script that will be executed together with each of the other scripts. It is useful to define constants ---for example--- that will be available to all other scripts.
-% \begin{macro}{\mglcommonscript}
-% \changes{v2.0}{2014/11/22}{Add \texttt{\backslash{}mglcommonscript} user-definable macro}
-% We define a macro to store the name of the setup script that will contain common code to all other scripts. The default name is \emph{common\_script}.mgl.
+  \MGL@set@script@name{\MGL@script@name}%
+%    \end{macrocode}
+% If the user hasn't specified a setup, then the only code that has to be written is the non-optional argument of |\mglplot|; it is stored in the temporary variable |\MGL@temp@a|.
 %    \begin{macrocode}
-
-\def\mglcommonscript{mgl_common_script}
+  \@ifundefined{MGL@mglplot@setup}{%
+    \edef\MGL@temp@a{#2}%
+  }{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\end@mglcommon}
-% We already know the purpose of this macro.
+% If the user has specified a setup, we store the code to call the setup and the code passed by the user in the temporary variable |\MGL@temp@a|.
 %    \begin{macrocode}
-\bgroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglcommon{\string\\end\string\{mglcommon\string\}}%
-\egroup%
+    \edef\MGL@temp@a{call '\MGL@mglplot@setup'^^J#2}%
+  }
 %    \end{macrocode}
-% \end{macro}
-% 
-% The |mglcommon| environment redefines the |\test@end@mglcode| so it detects the |\end{mglcommon}| command instead, and uses the |\mglcode| to create the common script.
+% If the code has changed the last time \LaTeX{} has been run, we call |\mglplot@write@script| to (re)write and (re)compile the script; otherwise, we call |\mglplot@compare@code| to check if it has changed this time.
 %    \begin{macrocode}
-\newenvironment{mglcommon}{%
-  \def\test@end@mglcode##1{%
-    \edef\this@word{##1}%
-    \ifx\this@word\end@mglcommon%
-      \def\next@action{\end{mglcommon}}%
-    \fi%
+  \MGL@process@script{%
+    \mglplot@write@script%
+  }{%
+    \mglplot@compare@code%
   }%
-  \mglcode{\mglcommonscript}%
-}{%
-  \mgl@write\mgl@out@stream{quality \mgl@quality}%
-  \immediate\closeout\mgl@out@stream%
-}
 %    \end{macrocode}
-% This environment can be used only in the preamble.
+% Finally, the corresponding image is included in the document.
 %    \begin{macrocode}
-\@onlypreamble\mglcommon
+  \MGL@includegraphics%
+}
 %    \end{macrocode}
-% \end{environment}
-% \begin{environment}{mglsignature}
-% This environment is used to declare signature text that will be written as comment on every script generated by \mglTeX.
-% \begin{macro}{\mglcomm}
-% We store the comment sign for MGL in this macro. For that, we need to declare \emph{locally} the symbol ``\#'' as one of category $12$.
+% \begin{macro}{\mglplot@write@script}
+% This command takes the code stored in the |\MGL@temp@a| variable by the |\mglplot| command and writes it to the document's main script and to a backup file, so changes in the code can be detected.
 %    \begin{macrocode}
-\bgroup
-  \catcode`#=12
-  \gdef\mglcomm{#}
-\egroup
+\def\mglplot@write@script{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mgltexsignature}
-% \changes{v2.0}{2014/11/22}{Add \texttt{\textbackslash{}mgltexsignature} user-definable macro}
-% The buffer where the signature will be stored. Here, we declare a default signature.
+% The default quality is written to the main script.
 %    \begin{macrocode}
-\def\mgltexsignature{%
-  \mglcomm^^J%
-  \mglcomm\space This file was autogenerated from the document \jobname.tex on date \today^^J%
-  \mglcomm%
-}
+  \MGL@write\MGL@main@stream{quality \MGL@quality}%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglsignature}
-% The beginning of the |mglsignature| environment.
+% The backup file is opened to write in the output stream.
 %    \begin{macrocode}
-\newcommand\mglsignature{%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
 %    \end{macrocode}
-% Delete |\mgltexsignature| contents.
+% Now we use the |\MGL@for| command to iterate over |\MGL@temp@a|. It takes a piece of code up to the separator symbol indicated by the user, and stores it in the temporary variable |\MGL@temp@b|, which is then written to the main script and backup file.
 %    \begin{macrocode}
-  \def\mgltexsignature{}%
+  \MGL@for\MGL@temp@b:=\MGL@temp@a\do{%
+    \MGL@write\MGL@main@stream{\MGL@temp@b}%
+    \MGL@write\MGL@out@stream{\MGL@temp@b}%
+  }%
 %    \end{macrocode}
-% We do the same changes of category as in the |mglcode| environment.
+% The output stream is closed.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \@vobeyspaces%
+  \MGL@closeout\MGL@out@stream%
 %    \end{macrocode}
-% Call the command that will store each line of the signature in the |\mgltexsignature| macro.
+% The instructions to save the image and reset the MGL parameters are written to the main script.
 %    \begin{macrocode}
-  \expandafter\mglsignature@write@line%
-}
+  \MGL@write\MGL@main@stream{%
+    write '\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext'^^J%
+    ^^Jreset^^J%
+  }%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\end@mglsignature}
-% We already know the purpose of this command.
+% Finally, |\MGL@unchanged{\MGL@script@name}| is written to the |.aux| file.
 %    \begin{macrocode}
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mglsignature{\string\\end\string\{mglsignature\string\}}%
-\endgroup
+  \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
+}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglsignature@write@line}
-% This command stores each line of the signature in the |\mgltexsignature| buffer.
+% \begin{macro}{\mglplot@compare@code}
+% This macro is in charge of comparing the code from a |\mglplot| command to detect changes.
 %    \begin{macrocode}
-\begingroup%
-%   \catcode`\\=0%
-  \catcode`\^^M\active%
-  \gdef\mglsignature@write@line#1^^M{%
+\def\mglplot@compare@code{%
 %    \end{macrocode}
-% Unless overwritten later, the next action (|\next@action|) is to store the current line of the signature in the |\mgltexsignature| buffer, ending with a new-line character, and call |\mglsignature@write@line| recursively.
+% The action that will finish this command is, for now, to write |\MGL@unchanged{\MGL@script@name}| in the |.aux| file; it is stored in the |\MGL@next| variable. If no changes in the code are found, this will remain as the last action; otherwise, it will be overwritten to do nothing.
 %    \begin{macrocode}
-    \def\next@action{%
-      \g@addto@macro{\mgltexsignature}{\mglcomm\space#1^^J}
-      \mglsignature@write@line%
-    }%
+  \def\MGL@next{\MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}}%
 %    \end{macrocode}
-% We check if the current line is |\end{mglsignature}|, in which case, overwrite |\next@action| to that command.
+% The backup file is opened for reading in the input stream.
 %    \begin{macrocode}
-    \test@end@mglsignature{#1}%
+  \MGL@openin\MGL@in@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
 %    \end{macrocode}
-% Execute |\next@action|.
+% Once again, the |\MGL@for| command is used to iterate over the |\MGL@temp@a| variable defined by |\mglplot|. Pieces of code are taken up to the appearance of the separator symbol indicated by the user. In every iteration, the corresponding piece of code is stored in the |\MGL@temp@b| variable, one line of code is read from the input stream to the variable |\MGL@temp@c|, and these two are compared; if they are different, we redefined |\MGL@next| to do nothing.
 %    \begin{macrocode}
-    \next@action%
+  \MGL@for\MGL@temp@b:=\MGL@temp@a\do{%
+    \MGL@read\MGL@in@stream{\MGL@temp@c}%
+    \ifx\MGL@temp@b\MGL@temp@c\else%
+      \let\MGL@next\relax%
+    \fi%
   }%
-\endgroup
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\test@end@mglsignature}
-% We already know the purpose of this command.
+% The input stream is closed.
 %    \begin{macrocode}
-\def\test@end@mglsignature#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mglsignature%
-    \def\next@action{\end{mglsignature}}%
-  \fi%
-}
+  \MGL@closein\MGL@in@stream%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\endmglsignature}
-% The end of the |mglsignature| environment. It just adds a comment sign to |\mgltexsignature| for elegance.
+% |\MGL@next| is executed.
 %    \begin{macrocode}
-\def\endmglsignature{%
-  \g@addto@macro{\mgltexsignature}{\mglcomm}
+  \MGL@next%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglsignature@write}
-% It takes care of writing the signature to the output stream which is passed as its argument.
-%    \begin{macrocode}
-\def\mglsignature@write#1{\mgl@write#1{\mgltexsignature}}
-%    \end{macrocode}
 % \end{macro}
-% \end{environment}
-% \begin{environment}{mglcomment}
-% \changes{v2.0}{2014/11/22}{Add the |mglcomment| environment.}
-% An environment to contain multiline comments that won't be printed to the document nor to any script in the case of the user passes the option |nocomments| to the package, and it'll print the comments if the |comments| option is passed to the package.
-% 
-% \begin{macro}{\mglcomment}
-% The beginning of the |mglcomment| environment. Here, we change categories of special characters (like \#, \@, etc.) and indicate to obey lines and spaces.
+%
+% \subsection{Verbatim-like environments}
+% \begin{environment}{mglblock}
+% \begin{environment}{mglblock*}
+% The main body of these environments is the same; the only difference is that the unstarred version creates an entry in the |\listofmglscripts|, while the starred version doesn't.
+% \begin{macro}{\mglblock}
+% This command defines the switch |\@MGL@list@script@| as true, so a |\listofmglscripts| entry for the code is created, then calls the main body of the environment (|\mglblock@|).
 %    \begin{macrocode}
 
-\def\mglcomment{%
-  \let\do\@makeother\dospecials%
-  \obeylines%
-  \@vobeyspaces%
-  \verbatim@font%
-  \small%
+\def\mglblock{\@MGL@list@script@true\mglblock@}
 %    \end{macrocode}
-% Call the command that will ignore all the commentary.
+% \end{macro}
+% \begin{macro}{\mglblock*}
+% This command defines the switch |\@MGL@list@script@| as false, so no |\listofmglscripts| entry is created, then calls the main body of the environment (|\mglblock@|).
 %    \begin{macrocode}
-  \mgl@comment%
-}
+\@namedef{mglblock*}{\@MGL@list@script@false\mglblock@}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgl@comment}
-% This command reads everything up to the |\end{mglcomment}| and ignores it if the |nocomments| option is passed to the package, or prints it otherwise. (We use the trick to consider everything up to the |\end{mglcomment}| the argument of |\mgl@comment|.)
+% \begin{macro}{\mglblock@}
+% This macro contains the real functionality of the |mglblock| and |mglblock*| environments. It is the common code they both have.
 %    \begin{macrocode}
-\begingroup%
+\newcommand\mglblock@[2][]{%
 %    \end{macrocode}
-% We do some adequate changes of code locally, so that \texttt{\textbackslash}, \texttt{\{} and \texttt{\}} are special, and \texttt{\textbar}, \texttt{[} and \texttt{]} take their functions, respectively.
+% First, the switch |\@MGL@lineno@| is set to true, so the lines of code will be numbered by default.
 %    \begin{macrocode}
-  \catcode`|=0\catcode`[= 1\catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\\=12%
+  \@MGL@lineno@true%
 %    \end{macrocode}
-% Define |\mgl@comment| to do nothing with its argument if the |nocomments| option has been passed to the package; otherwise, if the |comments| options has been passed, it will print the commentary, with delimiters to indicate where it starts and where it ends. Then call the end of the environment.
+% Now we process the decision of the user of keeping the line numbering or not.
 %    \begin{macrocode}
-  |gdef|mgl@comment#1\end{mglcomment}[%
-    |if@mgl@comments@%
-      |begin[center]%
-        <------------------ MGL comment ------------------>%
-        #1%
-        <------------------ MGL comment ------------------>%
-      |end[center]%
-    |fi%
-    |end[mglcomment]]%
-|endgroup%
+  \setkeys{MGL@verb@keys}{#1}%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\endmglcomment}
-% The end of the environment; it does nothing.
+% The name of the script is checked for repetition.
 %    \begin{macrocode}
-\def\endmglcomment{}
+  \MGL@set@script@name{#2}%
 %    \end{macrocode}
-% \end{macro}
-% \end{environment}
-
-% \subsection{Fast creation of graphics}
-% \begin{environment}{mglsetup}
-% This environment is used to store lines of code that need to be repeated many times. Later, the |\mglplot| command (see below) uses this lines of code without the need to repeat them.
-% \begin{macro}{\mglsetup@defined}
-% A macro to list the names of all the setups already defined.
+% If the switch |\@MGL@list@script@| is true, we increase the counter for verbatim code (|MGL@verb@script@no|), and add a contents line to the |.lms| file, using the style set by |\l@MGL@script|. In order to be able to use special characters in the name of the script, we use the |\detokenize| primitive.
 %    \begin{macrocode}
-
-\def\mglsetup@defined{}
+  \if@MGL@list@script@%
+    \refstepcounter{MGL@verb@script@no}%
+    \addcontentsline{lms}{MGL@script}{%
+      \protect\numberline{\theMGL@verb@script@no.}%
+      {\ttfamily\protect\detokenize{\MGL@script@name.mgl}}%
+    }%
+  \fi%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglsetup}
-% The beginning of the |mglsetup| environment. It accepts one optional argument, which is a name (keyword) to be associated to the block of code.
+% If the switch |\@MGL@lineno@| is true, we create a list such that each item will be labeled or numbered by the |MGL@lineno| counter. The style for the label is set by |\mgllinenostyle|.
 %    \begin{macrocode}
-\newcommand\mglsetup[1][generic]{%
+  \if@MGL@lineno@%
+    \list{\mgllinenostyle\arabic{MGL@line@no}.}{\usecounter{MGL@line@no}}%
 %    \end{macrocode}
-% Test if there already exists a setup with the current name; if so, issue a warning of redefinition of the setup, but proceed anyway.
+% Otherwise, we create a list without labeling for the items.
 %    \begin{macrocode}
-  \test@mglsetup@defined{#1}%
+  \else%
+    \list{}{}%
+  \fi%
 %    \end{macrocode}
-% Add the name of the current setup to |\mglsetup@defined|.
+% The parameters for the environment are set.
 %    \begin{macrocode}
-  \g@addto@macro{\mglsetup@defined}{#1,}%
+  \MGL@set@verbatim@code%
 %    \end{macrocode}
-% Define a new buffer which will contain the instructions to write the contents of the environment when the |\mglplot|. command is used. If the |mglsetup| environment is called like |\mglsetup\oarg{\meta{keyword}}|, the buffer will be called |\mgl@setup@\meta{keyword}|; if no name is given, use ``generic'' as keyword.
+% The thickness of the box that will contain the name of the script has to be the same as the thickness for the separation line at the begining of the verbatim code.
 %    \begin{macrocode}
-  \expandafter\def\csname mgl@setup@#1\endcsname{\mgl@write\mgl@script{}}%
-  \expandafter\def\csname mgl@setup@#1\endcsname{\mgl@write\mgl@script{quality \mgl@quality}}%
+  \fboxrule=\mgllinethickness%
 %    \end{macrocode}
-% Here, we do the same changes of category for special characters as we did in the |mgl| environment.
+% The separator to indicate the begining of the verbatim code is positioned; we use the |\MGL@line@sep| command to draw it.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \catcode`\ =10%
+  \item[\MGL@line@sep]\fbox{%
+    \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}%
+  }\hskip\labelsep\MGL@line@sep\par\par%
 %    \end{macrocode}
-% Call the command that will store in the buffer the instructions to write the lines of MGL code.
+% The |\verbatim@processline| is redefined to put |\the\verbatim@line| in an item of the list, and to to also write it to the script file.
 %    \begin{macrocode}
-  \expandafter\mglsetup@write@line%
-}
+  \def\verbatim@processline{%
+    \item\the\verbatim@line%
+    \MGL@write\MGL@out@stream{\the\verbatim@line}%
+  }%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\test@mglsetup@defined}
-% For every name stored in |\mglsetup@defined|, check if its argument (the name of the current setup) matches, in which case we will issue a warning, but proceed.
+% The script file is opened for writing.
 %    \begin{macrocode}
-\def\test@mglsetup@defined#1{%
-  \def\this@setup{#1}%
-  \@for\mglsetup@name:=\mglsetup@defined\do{%
-    \ifx\this@mglsetup\mglsetup@name%
-      \PackageWarning{\mgl@name}{Redefining "#1" setup for \noexpand\mglplot}%
-    \fi%
-  }%
-}
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglsetup@write@line}
-% This works exactly as the |\mgl@write@line|, but instead of writing directly to a script, it stores the writing instructions in the buffer.
+% The writing process starts.
 %    \begin{macrocode}
-\begingroup%
-  \catcode`\^^M\active%
-  \gdef\mglsetup@write@line#1^^M{%
-    \def\next@action{%
-      \expandafter\g@addto@macro\csname mgl@setup@\this@setup\endcsname{%
-        \mgl@write\mgl@script{#1}%
-      }%
-      \expandafter\mglsetup@write@line%
-    }%
-    \test@end@mglsetup{#1}%
-    \next@action%
-  }%
-\endgroup
+  \verbatim@start%
+}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\end@mglsetup}
-% \begin{macro}{\test@end@mglsetup}
-% We already know how these two macros work
+% \begin{macro}{\endmglblock}
+% To finish the environment's work, the script file is closed, the separator indicating the end of the verbatim code is placed, and the list is ended.
 %    \begin{macrocode}
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mglsetup{\string\\end\string\{mglsetup\string\}}%
-\endgroup
-\def\test@end@mglsetup#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mglsetup%
-    \def\next@action{\end{mglsetup}}%
-  \fi%
+\def\endmglblock{%
+  \MGL@closeout\MGL@out@stream%
+  \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+  \endlist%
 }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \begin{macro}{\endmglsetup}
-% The end of the |mglsetup| environment. It does nothing.
+% \begin{macro}{\endmglblock*}
+% It's defined as an alias for |\endmglblock|.
 %    \begin{macrocode}
-\def\endmglsetup{}
+\expandafter\let\csname endmglblock*\endcsname\endmglblock
 %    \end{macrocode}
 % \end{macro}
 % \end{environment}
-
-% \begin{macro}{\mglplot}
-% This macro uses the blocks of code stored by |mglsetup| environments to complete the code contained in its mandatory argument.
-% 
-% If there is an optional argument, make |\@mglplot| process it, otherwise pass no argument to |\@mglplot|.
+% \end{environment}
+%
+% \begin{environment}{mglverbatim}
+% \begin{environment}{mglverbatim*}
+% These two environments have the same main body. They difference in that the unstarred version creates an entry for the |\listofmglscripts|, while the starred version doesn't. We will apply a similar approach to the used for the |mglblock| and |mglblock*| environments.
+% \begin{macro}{\mglverbatim}
+% Similar in function to |\mglblock|.
 %    \begin{macrocode}
 
-\def\mglplot{%
-  \@ifnextchar[{\@mglplot}{\@mglplot[]}%
-}
+\def\mglverbatim{\@MGL@list@script@true\mglverbatim@}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\@mglplot}
-% This command receives one mandatory argument, but enclosed between brackets; so it receives the optional argument of |\mglplot|.
-%    \begin{macrocode}
-\def\@mglplot[#1]{%
-%    \end{macrocode}
-% Unless overwritten by the user with the |setup=\meta{setup}| option,  the default setup is ``generic''; initialize the |\graph@keys| macro; process the \meta{key}=\meta{value} pairs passed by the user; increase the counter |mgl@image@no| for numbering and naming of images.
+% \begin{macro}{\mglverbatim}
+% Similar in function to |\mglblock*|.
 %    \begin{macrocode}
-  \def\mglplot@setup{generic}%
-  \def\graph@keys{}%
-  \setkeys{mglplot@keys}{#1}%
-  \stepcounter{mgl@image@no}%
+\@namedef{mglverbatim*}{\@MGL@list@script@false\mglverbatim@}
 %    \end{macrocode}
-% If the given setup is undefined, issue a package error; otherwise, execute the buffer of the setup, which will write the contents of the corresponding |mglsetup| blocks to the general script.
+% \end{macro}
+% \begin{macro}{\mglverbatim@}
+% The main body of these environments; it's similar to |\mglblock@|. To explain each line of this command would be repetitive, so we explain only the different parts.
 %    \begin{macrocode}
-  \ifx\csname mgl@setup@\mglplot@setup\endcsname\@undefined%
-    \PackageError{\mgl@name}{Setup "\mglplot@setup" undefined}{}%
+\newcommand\mglverbatim@[1][]{%
+  \@MGL@lineno@true%
+  \define@key{MGL@verb@keys}{label}{\edef\MGL@script@name{##1}}%
+  \setkeys{MGL@verb@keys}{#1}%
+  \if@MGL@lineno@%
+    \list{\mgllinenostyle\arabic{MGL@line@no}.}{\usecounter{MGL@line@no}}%
   \else%
-    \csname mgl@setup@\mglplot@setup\endcsname%
+    \list{}{}%
   \fi%
+  \MGL@set@verbatim@code%
+  \fboxrule=\mgllinethickness%
+%    \end{macrocode}
+% The separator that indicates the begining of the verbatim code is different depending on whether the user has specified a name associated to the code or not. If no name has been indicated, i.e., |\MGL@script@name| is undefined, the separator is just a line; otherwise, i.e., |\MGL@script@name| is defined, the separator is similar to the one of the |mglblock| environment.
+%    \begin{macrocode}
+  \@ifundefined{MGL@script@name}{%
+    \edef\MGL@script@name{\mglverbatimname}%
+    \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+  }{%
+    \item[\MGL@line@sep]\fbox{%
+      \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}%
+    }\hskip\labelsep\MGL@line@sep\par\par%
+  }%
 %    \end{macrocode}
-% Call |\@@mglplot| (see below).
+% Note that, if the user requests an entry in the |\listofmglscripts|, the contents line is added to the same |.lms| file. So here start the similitudes again.
 %    \begin{macrocode}
-  \@@mglplot%
+  \if@MGL@list@script@%
+    \refstepcounter{MGL@verb@script@no}%
+    \addcontentsline{lms}{MGL@script}{%
+      \protect\numberline{\theMGL@verb@script@no.}%
+      {\ttfamily\protect\detokenize{\MGL@script@name}}%
+    }%
+  \fi%
+  \def\verbatim@processline{%
+    \item\the\verbatim@line%
+  }%
+  \verbatim@start%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\@@mglplot}
-% This command writes its argument verbatim to the main script, then writes the command to save the corresponding image, and the \emph{reset} command to prepare MathGL for the next image; finally, it uses the |\mgl@include@image| to include the corresponding graphics in the document.
+% \begin{macro}{\endmglverbatim}
+% This command could be defined as an alias for |\endmglblock|, for they execute the same instructions. But, for the sake of congruence, we rewrite the code.
 %    \begin{macrocode}
-\long\def\@@mglplot#1{%
-  \mgl@write\mgl@script{\detokenize{#1}}%
-  \mgl@write\mgl@script{%
-    write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'%
-  }%
-  \mgl@write\mgl@script{reset}%
-  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
+\def\endmglverbatim{%
+  \MGL@closeout\MGL@out@stream%
+  \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+  \endlist%
 }
 %    \end{macrocode}
 % \end{macro}
-% \subsection{Verbatim-like environments}
-% \begin{macro}{mgl@verb@line@no}
-% \noindent We create a counter to number the lines of code in verbatim-like environments.
+% \begin{macro}{\endmglverbatim*}
+% It is an alias for |\endmglverbatim|.
 %    \begin{macrocode}
-
-\newcounter{mgl@verb@line@no}
+\expandafter\let\csname endmglverbatim*\endcsname\endmglverbatim
 %    \end{macrocode}
 % \end{macro}
-% \begin{environment}{mglverbatim}
-% This environment writes its contents \emph{verbatim} to the \LaTeX{} document, numbering each line of code.
-% \begin{macro}{\mglverbatim}
-% The beginning of the |mglverbatim| environment.
+% \end{environment}
+% \end{environment}
+%
+% \begin{environment}{mglcomment}
+% This environment has two different behaviors: When commentaries are allowed by the user, it behaves similarly to the |mglverbatim| environment; if commentaries are not allowed, it behaves as the |comment| environment from the \textsf{verbatim} package. So it is natural that we borrow code from them and adapt it to the corresponding situation.
+% \begin{macro}{\mglcomment}
+% The switch |\@MGL@comments@| governs the behavior of this command.
 %    \begin{macrocode}
 
-\def\mglverbatim{%
-%    \end{macrocode}
-% Initialize the counter for lines of code.
-%    \begin{macrocode}
-  \setcounter{mgl@verb@line@no}{0}%
+\def\mglcomment{%
 %    \end{macrocode}
-% We use the list environment to set the numeration of the lines of code that will be written to the \LaTeX{} document as items of the list. We also set the separation between lines of code, the indentation of the line, and some other length parameters.
+% If the switch is true, i.e., the user requests displaying of commentaries, we start a list without labels, and set the parameters for verbatim text.
 %    \begin{macrocode}
-  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
-  \setlength{\labelsep}{1em}%
-  \itemsep\z@skip%
-  \leftskip\z@skip\rightskip\z@skip%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+  \if@MGL@comments@%
+    \list{}{}%
+    \MGL@set@verbatim@code%
 %    \end{macrocode}
-% We do the same changes of categories as in the |mglcode| environment.
+% The separator indicating the begining of the commentary is similar to the one used by the |mglblock| and |mglverbatim| environments; the differences are that, instead of using a solid line, we use a dashed line (|\MGL@dash@sep|), and instead of displaying the name of a script, we display |\mglcommentname|.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \obeyspaces%
+    \item\hskip-\labelsep<\MGL@dash@sep\mglcommentname\MGL@dash@sep>%
 %    \end{macrocode}
-% use verbatim font.
+% The two following lines redefine the |\verbatim@processline| command to display the commentary text line by line as items of the list, and start the process of writing the text.
 %    \begin{macrocode}
-  \verbatim@font%
+    \def\verbatim@processline{\item\the\verbatim@line}%
+    \verbatim@start%
 %    \end{macrocode}
-% Call the command that will write each line of the contents of the environment.
+% If the switch is false, i.e., the user requests no to display commentaries, we start a \emph{space hack}, since no text output will be produced. Then, the category codes are changed with |\MGL@codes|, and the macros |\verbatim@startline|, |\verbatim@addtoline|, |\verbatim@processline| and |\verbatim@finish| are disabled, as done in the |comment| environment of the \textsf{verbatim} package. Finally, we call the |\verbatim@| command to start reading the text in the environment.
 %    \begin{macrocode}
-  \expandafter\mglverbatim@ignore@line%
+  \else%
+    \@bsphack%
+    \MGL@codes%
+    \let\verbatim@startline\relax%
+    \let\verbatim@addtoline\@gobble%
+    \let\verbatim@processline\relax%
+    \let\verbatim@finish\relax%
+    \verbatim@%
+  \fi%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglverbatim@ignore@line}
-% This command ignores the first line of the |verbatim| environment, which is an empty line.
+% \begin{macro}{\endmglcomment}
+% The |\@MGL@comments@| switch also governs the behavior of this command. If it's true, then the separator that ends the commentary ---which is the same as the one that starts it--- is displayed, and the list is ended; otherwise, simply the \emph{space hack} is ended.
 %    \begin{macrocode}
-\def\mglverbatim@ignore@line#1{%
-  \expandafter\mglverbatim@write@line%
+\def\endmglcomment{%
+  \if@MGL@comments@%
+    \item\hskip-\labelsep<\MGL@dash@sep\mglcommentname\MGL@dash@sep>%
+    \endlist%
+  \else%
+    \@esphack%
+  \fi%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglverbatim@write@line}
-% Reads the contents of the |mglverbatim| character by character, and stores words in the |\mgl@word| buffer and lines in the |\mgl@line| buffer, just like the |mglcode| environment did.
+% \end{environment}
+%
+% \subsection{Commands for external scripts}
+% \noindent Since external scripts exist independently of the \LaTeX{} document, there is no need of environments to process them, just commands. Remember these commands work on the suposition that the scripts don't change.
+%
+% \begin{macro}{\mglgraphics}
+% This command compiles the external script and includes it in the document. Although that process is simple, the code to execute it is relatively large due to the possibility of the user specifying an optional path, so many parameters have to be checked.
 %    \begin{macrocode}
-\def\mglverbatim@write@line#1{%
+
+\newcommand\mglgraphics[2][]{%
 %    \end{macrocode}
-% Unless overwritten later, the next action (|\next@action|) is recursively call |\mglverbatim@write@line|.
+% In order to keep all definitions and changes local, we start a local group inside which all \LaTeX{} code will be contained.
 %    \begin{macrocode}
-  \let\next@action\mglverbatim@write@line%
+  \bgroup%
 %    \end{macrocode}
-% If the character read is an end-line character,
+% We add the option |path| for the user to be able to specify the location of the script, which is stored in the variable |\MGL@force@path|.
 %    \begin{macrocode}
-  \expandafter\if#1\^^M%
+  \define@key{MGL@keys}{path}{\def\MGL@forced@path{##1}}%
 %    \end{macrocode}
-% increase the line of code counter, write the line contained in |\mgl@line| as an item of the |list| environment, and clean |\mgl@word| and |\mgl@line|;
+% The optional arguments are processed.
 %    \begin{macrocode}
-    \stepcounter{mgl@verb@line@no}%
-    \item\mbox{\the\mgl@line}%
-    \mgl@word{}%
-    \mgl@line{}%
+  \MGL@setkeys{MGL@keys}{#1}%
 %    \end{macrocode}
-% if the character is a space, clean |\mgl@wors|, but add the space to |\mgl@line|;
+% The name of the script is set, though it is not check for multiple naming. This is necessary, since |\MGL@includegraphics| uses this macro.
 %    \begin{macrocode}
-  \else\expandafter\if#1\space%
-    \mgl@word{}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
+  \edef\MGL@script@name{#2}%
 %    \end{macrocode}
-% otherwise, the character is aphanumeric, so add it to the |\mgl@word| and |\mgl@line| buffers, and check if |\mgl@word| is |\end{mglverbatim}|, in which case overwrite |\next@action| to be that command.
+% If the corresponding image exists, then this script has been compiled in a previous \LaTeX{} run, so nothing is done, but the inclusion of the image.
 %    \begin{macrocode}
-  \else%
-    \mgl@word\expandafter{\the\mgl@word#1}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
-    \test@end@mglverbatim{\the\mgl@word}%
-  \fi\fi%
-  \next@action%
-}
+  \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}{}{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\end@mglverbatim}
-% \begin{macro}{\test@end@mglverbatim}
-% We already know the purpose of these macros.
+% If the image doesn't exist, we check if the user has specified a custom location.
 %    \begin{macrocode}
-\begingroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglverbatim{\string\\end\string\{mglverbatim\string\}}%
-\endgroup%
-\def\test@end@mglverbatim#1{%
-  \edef\this@word{#1}%
-  \ifx\this@word\end@mglverbatim%
-    \def\next@action{\end{mglverbatim}}%
-  \fi%
-}
+    \@ifundefined{MGL@forced@path}{%
 %    \end{macrocode}
-% \end{macro}
-% \end{macro}
+% If no custom location has been used, we iterate over the list of search paths (|\MGL@paths|): If we find the requested script, then we store its location in |\MGL@temp@b|.
 %    \begin{macrocode}
+      \@for\MGL@temp@a:=\MGL@paths\do{%
+        \IfFileExists{\MGL@temp@a\MGL@script@name.mgl}{%
+          \edef\MGL@temp@b{\MGL@temp@a}%
+        }{}%
+      }%
+    }{%
 %    \end{macrocode}
-% \begin{macro}{\endmglverbaim}
-% The end of the |mglverbatim| environment. It just closes the |list| environment.
+% If the user has specified a path for the script, we check if the script actually exists. If it does, we store its location inside |\MGL@temp@b|.
 %    \begin{macrocode}
-\def\endmglverbatim{\endlist}
+      \IfFileExists{\MGL@forced@path\MGL@script@name.mgl}{%
+        \edef\MGL@temp@b{\MGL@forced@path}%
+      }{}%
+    }%
 %    \end{macrocode}
-% \end{macro}
-% \end{environment}
-% \begin{environment}{mglblock}
-% This environment writes its contents to a script, whose name is passed as mandatory argument, ad then it also writes its contents to the \LaTeX{} document, numbering each line.
-% \begin{macro}{\mglblock}
-% The beginning of the |mglblock environment|.
+% If |\MGL@temp@b| is not defined, the script has not been found, so a warning is issued.
 %    \begin{macrocode}
-
-\def\mglblock#1{%
+    \@ifundefined{MGL@temp@b}{%
+      \PackageWarning{mgltex}{%
+        MGL script "\MGL@script@name.mgl" not found%
+      }%
+    }{%
 %    \end{macrocode}
-% Check if the script already exists, in which case we issue a warning, but proceed anyway.
+% If |\MGL@temp@b| is defined, the script has been found, so we compile it.
 %    \begin{macrocode}
-  \test@mgl@script@written{#1}%
+      \MGL@write{18}{%
+        mglconv -q \MGL@quality\space -S \MGL@scale\space%
+        -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+        -o "\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext"\space%
+        "\MGL@temp@b\MGL@script@name.mgl"%
+      }%
+    }%
+  }%
 %    \end{macrocode}
-% Add the name of the script to the list of scripts written.
+% The image is included.
 %    \begin{macrocode}
-  \xdef\mgl@script@written{\mgl@script@written#1,}%
+  \MGL@includegraphics%
 %    \end{macrocode}
-% We make the same changes of categories as in the |mglcode| environment.
+% The local group ends here.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \obeyspaces%
+  \egroup%
+}
 %    \end{macrocode}
-% Open the output stream for the current script.
+% \end{macro}
+%
+% \begin{macro}{\mglinclude}\begin{macro}{\mglinclude*}
+% The purpose of these commands is to transcript the MGL code from a script. Once again, this is a straightforward functionality, but the code is quite large, so it has been separated in various macros.
+%
+% The unstarred version defines the |\@MGL@list@script@| switch to be true, so the script is listed with the |\listofmglscripts| command, and then it calls the main body of code (|\mglinclude@|), just like the |mglblock| environment does. The starred version defines the switch as false and calls the main body, too.
 %    \begin{macrocode}
-  \def\this@script{#1}%
-  \if@mgltex@on@%
-    \immediate\openout\mgl@out@stream="\mgl@dir\this@script.mgl"%
-    \mglsignature@write\mgl@out@stream%
-  \fi%
+
+\def\mglinclude{\@MGL@list@script@true\mglinclude@}
+\@namedef{mglinclude*}{\@MGL@list@script@false\mglinclude@}
 %    \end{macrocode}
-% Call the command that will write each line of the contents of the environment.
+% \begin{macro}{\mglinclude@}
 %    \begin{macrocode}
-  \expandafter\mglblock@write@line%
-}
+\newcommand\mglinclude@[2][]{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglblock@write@line}
-% This macro reads characater by character the code inside |mglblock|, and uses the |\mgl@word| and |\mgl@line| buffers to store words and lines of codes, just like we did with the |mglcode| environment.
+% We start a local group to keep definitions and changes local.
 %    \begin{macrocode}
-\def\mglblock@write@line#1{%
+  \bgroup%
 %    \end{macrocode}
-% The next action (|\next@action|) is set to recursively call |\mglblock@write@line|, unless it is overwritten later.
+% The default behavior is to number lines of MGL code, so the switch |\@MGL@lineno@| is set to true.
 %    \begin{macrocode}
-  \let\next@action\mglblock@write@line%
+  \@MGL@lineno@true%
 %    \end{macrocode}
-% If the read character is an end-line character, write the contents of |\mgl@line| to the script, and the clean |\mgl@word| and |\mgl@line|;
+% We add the option |path| for the user to be able to specify the location of the script, which is stored in |\MGL@forced@path|.
 %    \begin{macrocode}
-  \expandafter\if#1\^^M%
-    \mgl@write\mgl@out@stream{\the\mgl@line}%
-    \mgl@word{}%
-    \mgl@line{}%
+  \define@key{MGL@verb@keys}{path}{\def\MGL@forced@path{##1}}%
 %    \end{macrocode}
-% if the read character if a space, clean |\mgl@word|, but add the space to |\mgl@line|;
+% The options are processed.
 %    \begin{macrocode}
-  \else\expandafter\if#1\space%
-    \mgl@word{}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
+  \setkeys{MGL@verb@keys}{#1}%
 %    \end{macrocode}
-% otherwise, the character is alphnumeric, and should be added to |\mgl@word| and |\mgl@line|, and we test if |\mgl@word| is |\end{mglblock}|, in which case, we overwrite |\next@action| to that command.
+% We don't need to check if there are multiple scripts with the same name, so we namually set |\MGL@script@name|, instead of using |\MGL@set@script@name|.
 %    \begin{macrocode}
-  \else%
-    \mgl@word\expandafter{\the\mgl@word#1}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
-    \test@end@mglblock{\the\mgl@word}%
-  \fi\fi%
+  \edef\MGL@script@name{#2}%
 %    \end{macrocode}
-% Execute |\next@action|.
+% We check if the user has specified a custom location for the script.
 %    \begin{macrocode}
-  \next@action%
-}
+  \@ifundefined{MGL@forced@path}{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\end@mglblock}
-% \begin{macro}{\test@end@mglblock}
-% We already know the purpose of these macros.
+% If no custom location has been used, we iterate over the list |\MGL@paths| to find the script.
 %    \begin{macrocode}
-\begingroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglblock{\string\\end\string\{mglblock\string\}}%
-\endgroup%
-\def\test@end@mglblock#1{%
-  \edef\this@word{#1}%
-  \ifx\this@word\end@mglblock%
-    \def\next@action{\end{mglblock}}%
-  \fi%
-}
+    \@for\MGL@temp@b:=\MGL@paths\do{%
 %    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\mgl@in@stream}
-% We create an input stream to read from MGL scripts.
+% If the script exists, we store its location in |\MGL@temp@a|%
 %    \begin{macrocode}
-\newread\mgl@in@stream
+      \IfFileExists{\MGL@temp@b\MGL@script@name.mgl}{%
+        \edef\MGL@temp@a{\MGL@temp@b}%
+      }{}%
+    }%
+  }{%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\endmglblock}
-% The end of the |mglblock| environment.
+% If the user specified the location of the script, we check if it exists, in which case we store its location in |\MGL@temp@a|.
 %    \begin{macrocode}
-\def\endmglblock{%
+    \IfFileExists{\MGL@script@name.mgl}{%
+      \edef\MGL@temp@a{\MGL@forced@path}%
+    }{}%
+  }%
 %    \end{macrocode}
-% Close the output stream.
+% If |\MGL@temp@a| is not defined, the script has not been found, so we issue a warning, and display a box in the document with the words \emph{MGL script not found}.
 %    \begin{macrocode}
-  \immediate\closeout\mgl@out@stream%
+  \@ifundefined{MGL@temp@a}{%
+    \PackageWarning{mgltex}{%
+      MGL script "\MGL@forced@path\MGL@script@name.mgl" not found%
+    }%
+    \center%
+      \fbox{%
+        \centering%
+        \bfseries\Huge%
+        \begin{tabular}{c}MGL\\script\\not\\found\end{tabular}%
+      }%
+    \endcenter%
+  }{%
 %    \end{macrocode}
-% Open the input stream.
+% If |\MGL@temp@a| is defined, the script has been found, so we call |\mglinclude@@| to set up the inclusion of the script.
 %    \begin{macrocode}
-  \immediate\openin\mgl@in@stream="\mgl@dir\this@script.mgl"%
+    \mglinclude@@%
+  }%
+  \egroup%
+}
 %    \end{macrocode}
-% Here, we use the |list| environment to set the numeration of the lines of code that will be written to the \LaTeX{} document as items of the list. We also set the separation between lines of code, the indentation of the line, and some other lenght parameters.
+% \end{macro}
+% \begin{macro}{\mglinclude@@}
+% This macro sets the parameters for the inclusion of the script, and calls the command in charge of the transcription.
 %    \begin{macrocode}
-  \begingroup%
-  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
-  \setlength{\labelsep}{1em}%
-  \itemsep\z@skip%
-  \leftskip\z@skip\rightskip\z@skip%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+\def\mglinclude@@{%
 %    \end{macrocode}
-% Use the verbatim font, and obey spaces, including spaces at the beggining of the line.
+% We first add the script to the \LaTeX{} list of included files.
 %    \begin{macrocode}
-  \verbatim@font%
-  \@vobeyspaces%
+  \@addtofilelist{\MGL@script@name.mgl}%
 %    \end{macrocode}
-% Call the command that will write the lines of code to the \LaTeX{} document.
+% If the user has used the unstarred version of |\mglinclude|, we add a contents line to the |.lms| file.
 %    \begin{macrocode}
-  \mglblock@read@line%
-}
+  \if@MGL@list@script@%
+    \refstepcounter{MGL@verb@script@no}%
+    \addcontentsline{lms}{MGL@script}{%
+      \protect\numberline{\theMGL@verb@script@no.}%
+      {\ttfamily\protect\detokenize{\MGL@script@name.mgl}}%
+    }%
+  \fi%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglblock@read@line}
-% This command reads lines of code from the input stream and writes them as items of the |list| environment.
+% We start a |\list| in which each line of code will be an item. If the lines have to be numbered, we use the |MGL@line@no| counter.
 %    \begin{macrocode}
-\def\mglblock@read@line{%
+  \if@MGL@lineno@%
+    \list{\mgllinenostyle\arabic{MGL@line@no}.}{\usecounter{MGL@line@no}}%
+  \else%
+    \list{}{}%
+  \fi%
 %    \end{macrocode}
-% Increase the line counter.
+% We set the parameters for a verbatim code.
 %    \begin{macrocode}
-  \stepcounter{mgl@verb@line@no}%
+  \MGL@set@verbatim@code%
 %    \end{macrocode}
-% Read a line from the input stream.
+% The heading of the environment is set. It is similar to that of the |mglblock| environment.
 %    \begin{macrocode}
-  \read\mgl@in@stream to \this@line%
+  \fboxrule=\mgllinethickness%
+  \item[\MGL@line@sep]\fbox{%
+    \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}%
+  }\hskip\labelsep\MGL@line@sep\par\par%
 %    \end{macrocode}
-% If the end of file has been reached, define |\next@action| to close the input stream, and en the |list| environment;
+% We redefine the |\verbatim@processline| macro from the \textsf{verbatim} package to put |\the\verbatim@line| on an item.
 %    \begin{macrocode}
-  \ifeof\mgl@in@stream%
-    \def\next@action{%
-      \immediate\closein\mgl@in@stream%
-      \endlist%
-      \endgroup%
-    }%
+  \def\verbatim@processline{%
+    \item\the\verbatim@line%
+  }%
 %    \end{macrocode}
-% otherwise, |\next@action| is write the read line as an item of the |list| environment, and recursively call |\mglblock@read@line|.
+% The script is opened for reading.
 %    \begin{macrocode}
-  \else%
-    \def\next@action{%
-      \item\mbox{\this@line}%
-      \mglblock@read@line%
-    }%
-  \fi%
+  \immediate\openin\MGL@in@stream="\MGL@temp@a\MGL@script@name.mgl"%
 %    \end{macrocode}
-% Execute |\next@action|.
+% We call |\mglinclude@@@| to start the transcription.
 %    \begin{macrocode}
-  \next@action%
+  \mglinclude@@@%
 }
 %    \end{macrocode}
 % \end{macro}
-% \end{environment}
-% \subsection{Working with external scripts}
-% \begin{macro}{\mglgraphics}
-% This command allows to generate and include graphics from a external (not embedded) script.
-%    \begin{macrocode}
-
-\newcommand\mglgraphics[2][]{%
-%    \end{macrocode}
-%   Initialize |\graph@keys|, which will contain the \meta{key}=\meta{value} options for the |\includegraphics|command.
+% \begin{macro}{\mglinclude@@@}
+% This command transcripts the MGL code of the script and closes the list started in |\mglinclude@@|, adding the corresponding separation line to separate the code from normal text.
 %    \begin{macrocode}
-  \def\graph@keys{}%
+\def\mglinclude@@@{%
 %    \end{macrocode}
-% Process the \meta{key}=\meta{value} options passed by the user.
+% Since the transcription has to be done even when \textsf{\mglTeX} is off, instead of using the |\MGL@read| command ---which is inactive when the package is off---, we use the usual commands from \LaTeX{} to read from the file.
 %    \begin{macrocode}
-  \setkeys{mgl@keys}{#1}%
+  \immediate\read\MGL@in@stream to \MGL@temp@b%
 %    \end{macrocode}
-% Execute the program |mglconv| (included in MathGL) to compile the corresponding script.
+% If the end of file has been reached, we close the input stream, add the separation line, and end the |\list|.
 %    \begin{macrocode}
-  \mgl@write{18}{mglconv "\mgl@dir#2.mgl" -s "\mgl@dir\mglcommonscript.mgl" -o "\mgl@dir#2\mgl@image@ext"}
+  \ifeof\MGL@in@stream%
+    \immediate\closein\MGL@in@stream%
+    \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+    \endlist%
 %    \end{macrocode}
-% Include the generated image with the |\mgl@include@image| command.
+% Otherwise, we use |\verbatim@startline| to clean the |\verbatim@line| buffer, then we add the just read line to the buffer, and call |\verbatim@processline| to include it as an item of the list. Finally, we recursively call |\mglinclude@@@| to read the next line.
 %    \begin{macrocode}
-  \mgl@include@image{\mgl@dir#2}%
+  \else%
+    \verbatim@startline%
+    \expandafter\verbatim@addtoline\expandafter{\MGL@temp@b}%
+    \verbatim@processline%
+    \expandafter\mglinclude@@@%
+  \fi%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglinclude}
-% This command copies verbatim the contents of an external script, and numerates each line of code.
+% \end{macro}\end{macro}
+%
+% \subsection{Additional commands}
+% \begin{macro}{\mglname}
+% \noindent The purpose of this command is to force the closure of the current main script, compile the corresponding figures, and open a new main script. At first, it is defined to only change the value of |\MGL@main@script@name| because the main script is not opened until the call of |\begin{document}|; but at that point, it is redefined to perform the described actions.
 %    \begin{macrocode}
-
-\def\mglinclude#1{%
+\def\mglname#1{\edef\MGL@main@script@name{#1}}
 %    \end{macrocode}
-% Initialize the line counter.
+% Here is the redefinition of |\mglname|.
 %    \begin{macrocode}
-  \setcounter{mgl@verb@line@no}{0}%
+\AtBeginDocument{%
+  \def\mglname#1{%
 %    \end{macrocode}
-% Open the script in the input stream.
+% We start a space hack, ince this function has no real effect on the document.
 %    \begin{macrocode}
-  \immediate\openin\mgl@in@stream="\mgl@dir#1.mgl"%
+    \@bsphack%
 %    \end{macrocode}
-% Here, we use the |list| environment to numerate each line of code as an item. We also set some length parameters.
+% The MGL functions created throughout the document are written.
 %    \begin{macrocode}
-  \begingroup%
-  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
-  \setlength{\labelsep}{1em}%
-  \itemsep\z@skip%
-  \leftskip\z@skip\rightskip\z@skip%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+    \MGL@write@funcs%
 %    \end{macrocode}
-% We do the same changes of category as in the |mglcode| environment, and set the font to verbatim font.
+% We force the closure of the main script. We use |\immediate\closeout| instead of |\MGL@closeout| in case \textsf{\mglTeX} is off.
 %    \begin{macrocode}
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \@vobeyspaces%
-  \verbatim@font%
+    \immediate\closeout{\MGL@main@stream}%
+%    \end{macrocode}
+% The closed script is compiled.
+%    \begin{macrocode}
+    \MGL@write{18}{%
+      mglconv -q \MGL@quality\space -S \MGL@scale\space%
+      -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+      -n "\MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl"%
+    }%
+%    \end{macrocode}
+% The name of the new main script is updated, and it is check for overwriting, using |\MGL@set@script@name| inside a local group, since this command defines |\MGL@script@name|, which we need undefined in some parts of the code of the package.
+%    \begin{macrocode}
+    \edef\MGL@main@script@name{#1}%
+    \bgroup\MGL@set@script@name{\MGL@main@script@name}\egroup%
+    \MGL@openout\MGL@main@stream{%
+      \MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl%
+    }%
 %    \end{macrocode}
-% We (re)use the |\mglblock@read@line| command to numerate and write each line of code.
+% The space hack is ended.
 %    \begin{macrocode}
-  \mglblock@read@line%
+    \@esphack%
+  }%
 }
 %    \end{macrocode}
 % \end{macro}
-% \subsection{Additional commands}
-% \begin{macro}{\mgldir}
-% A command to specify a directory to write the scripts and create the images.
-% First, we create a macro that will store the specified directory for later use.
+%
+% \begin{macro}{\listofmglscripts}
+% This command creates the \emph{list of MGL scripts} section. It has to be defined differently depending on whether the used document class defines the |\l@chapter| command or it only the |\l@section| command, which set the style for making a table of contents entry for the |\chapter| command and the |\section| command, respectively. If none of them are defined, we define our own style based on the latter.
 %    \begin{macrocode}
 
-\def\mgl@dir{}
+\ifx\l@chapter\@undefined%
 %    \end{macrocode}
-% The command |\mgldir| is the only way to modify |\mgl@dir|. This is done so the user won't be able to modify the default directory, dangerously altering the internal behavior of the package.
+% If |\l@chapter| is not defined, we check if |\l@section| is.
 %    \begin{macrocode}
-\def\mgldir#1{%
-  \def\mgl@dir{#1}%
-}
+  \ifx\l@section\@undefined%
 %    \end{macrocode}
-% Declare |\mgldir| so that it can only be used in the preamble. This is because the main script \meta{document}.mgl is opened at the moment of the |\begin{document}| instruction.
+% If |\l@section| is not defined, we set the |\lisofmglscripts| command to perform exactly as the |\section*{\listofmglscriptsname}| would do in the usual \textsf{book} and \textsf{article} \LaTeX{} classes, except that the type of section is |MGL@list|.
 %    \begin{macrocode}
-\@onlypreamble\mgldir
+    \def\listofmglscripts{%
+      \@startsection{MGL@list}%
+      {1}{0em}{-3.5ex plus -1ex minus -0.2ex}%
+      {2.5ex plus 0.2ex}%
+      {\centering\normalfont\bfseries\large}*%
+      {\listofmglscriptsname}%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mgl@quality}
-% We define a macro to store the quality.
+% We use the |\@mkboth| command to set the page marks according to the current page style.
 %    \begin{macrocode}
-\def\mgl@quality{2}
+      \@mkboth{%
+        \MakeUpperCase\listofmglscriptsname%
+      }{%
+        \MakeUppercase\listofmglscriptsname%
+      }%
 %    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglquality}
-% This is used to define the quality for MGL graphics.
+% The \emph{list of MGL scripts} is created by reading the document's |.lms| file.
 %    \begin{macrocode}
-\def\mglquality#1{%
+      \@starttoc{lms}%
+    }%
 %    \end{macrocode}
-% Write the quality command to a setup script.
-%    \begin{macrocode}
-  \def\mgl@quality{#1}%
-  \if@mgltex@on@%
-    \immediate\openout\mgl@out@stream="\mgl@dir\mglcommonscript.mgl"%
-    \mgl@write\mgl@out@stream{quality #1}%
-    \immediate\closeout\mgl@out@stream%
-%    \end{macrocode}
-% Print an info message about the corresponding quality, or a warning if the quality doesn't exist.
-%    \begin{macrocode}
-    \ifcase#1
-      \PackageInfo{mgltex}{Quality 0: No face drawing (fastest)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 1: No color interpolation (fast)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 2: High quality (normal)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 3: High quality with 3d primitives (not implemented yet)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 4: No face drawing, direct bitmap drawing (low memory usage)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 5: No color interpolation, direct bitmap drawing (low memory usage)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 6: High quality, direct bitmap drawing (low memory usage)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 7: High quality with 3d primitives, direct bitmap drawing (not implemented yet)}%
-    \or%
-      \PackageInfo{mgltex}{Quality 8: Draw dots instead of primitives (extremely fast)}%
-    \else%
-      \PackageWarning{mgltex}{Quality #1 not available. Using default (2)}%
-    \fi%
+% The |\l@MGL@list| style has the same code as the |\l@section| style.
+%    \begin{macrocode}
+    \newcommand*\l@MGL@list[2]{%
+      \ifnum \c@tocdepth >\z@
+        \addpenalty\@secpenalty
+        \addvspace{1.0em \@plus\p@}%
+        \setlength\@tempdima{1.5em}%
+        \begingroup
+          \parindent \z@ \rightskip \@pnumwidth
+          \parfillskip -\@pnumwidth
+          \leavevmode \bfseries
+          \advance\leftskip\@tempdima
+          \hskip -\leftskip
+          #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
+        \endgroup
+      \fi%
+    }%
   \else%
-    \PackageWarning{mgltex}{mglTeX is off, quality changes won't have effect}%
+%    \end{macrocode}
+% If the |\l@section| style is defined, the \emph{list of MGL scripts} is just an unumbered section.
+%    \begin{macrocode}
+    \def\listofmglscripts{%
+      \section*{\listofmglscriptsname}%
+      \@mkboth{%
+        \MakeUppercase\listofmglscriptsname%
+      }{%
+        \MakeUppercase\listofmglscriptsname%
+      }%
+      \@starttoc{lms}%
+    }%
   \fi%
-}
+\else%
+%    \end{macrocode}
+% If the |\l@chapter| style is defined, the \emph{list of MGL scripts} is just an unumbered chapter.
+%    \begin{macrocode}
+  \def\listofmglscripts{%
+    \chapter*{\listofmglscriptsname}%
+    \@mkboth{%
+      \MakeUpperCase\listofmglscriptsname%
+    }{%
+      \MakeUppercase\listofmglscriptsname%
+    }%
+    \@starttoc{lms}%
+  }%
+\fi%
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgltexon}
-% \changes{v.2.0}{2014/11/15}{Add the command \texttt{\textbackslash mgltexon}}
-% Has the same effect as the package option |on|, but its effect is local, meaning that works only from the point this command is called on.
+%
+% \begin{macro}{\mglTeX}
+% This macro pretty-prints the name of the package.
 %    \begin{macrocode}
 
-\def\mgltexon{
-  \@mgltex@on@true
-  \def\mgl@write##1##2{%
-    \immediate\write##1{##2}%
-  }
-}
+\def\mglTeX{mgl\TeX}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgltexoff}
-% \changes{v.2.0}{2014/11/15}{Add the command \texttt{\textbackslash mgltexoff}}
-% Has the same effect as the package option |off|, but its effect is local.
+% \begin{macro}{\mglTeXwVersion}
+% This macro pretty-prints the name of the package with its version in a coherent manner, and separated with an unbreakable space.
 %    \begin{macrocode}
-\def\mgltexoff{%
-  \@mgltex@on@false
-  \def\mgl@write##1##2{}%
-}
+
+\def\mglTeXwVer{\mglTeX~v4.0}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglcomments}
-% \changes{v2.0}{2014/11/22}{Add the command \texttt{\textbackslash mglcomments}}
-% Has the same effect as the package option |comments|, but its effect is local, meaning that works only from the point this command is called on.
+%
+% \begin{macro}{\mgldir}
+% This command is the interface for the user to change the value of |\MGL@dir|. It is an only-preamble macro, since using it elsewhere would cause faulty behavior.
 %    \begin{macrocode}
 
-\def\mglcomments{
-  \@mgl@comments@true
-}
+\def\mgldir#1{\def\MGL@dir{#1}}\@onlypreamble\mgldir
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglnocomments}
-% \changes{v2.0}{2014/11/22}{Add the command \texttt{\textbackslash mglnocomments}}
-% Has the same effect as the package option |off|, but its effect is local.
+% \begin{macro}{\mglscriptsdir}
+% This command modifies the value of |\MGL@scripts@dir|. It is also an only-preamble macro.
 %    \begin{macrocode}
-\def\mglnocomments{%
-  \@mgl@comments@false
-}
+\def\mglscriptsdir#1{\def\MGL@scripts@dir{#1}}\@onlypreamble\mglscriptsdir
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mglTeX}
-% Just pretty-prints the name of the package.
+% \begin{macro}{\mglgraphicsdir}
+% Modifies the value of |\MGL@graphics@dir|. It is an only-preamble macro.
 %    \begin{macrocode}
-
-\def\mglTeX{mgl\TeX}
+\def\mglgraphicsdir#1{\def\MGL@graphics@dir{#1}}\@onlypreamble\mglgraphicsdir
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglbackupsdir}
+% Modifies the value of |\MGL@backups@dir|. It is an only-preamble macro.
+%    \begin{macrocode}
+\def\mglbackupsdir#1{\def\MGL@backups@dir{#1}}\@onlypreamble\mglbackupsdir
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglpaths}
+% This command adds a list of search paths for scripts to the existing one (|\MGL@paths|).
+%    \begin{macrocode}
+\def\mglpaths#1{\g@addto@macro\MGL@paths{,#1}}
 %    \end{macrocode}
 % \end{macro}
+%
+% \begin{macro}{\mglcommonscriptname}\begin{macro}{\mglcommentname}\begin{macro}{\listofmglscriptsname}\begin{macro}{\mglverbatimname}\begin{macro}{\mgllinenostyle}\begin{macro}{\mgldashwidth}\begin{macro}{\mgllinethickness}\begin{macro}{\mglbreakindent}
+%    \begin{macrocode}
 
+\def\mglcommonscriptname{MGL_common_script}
+\def\mglcommentname{MGL commentary}
+\def\listofmglscriptsname{List of MGL scripts}
+\def\mglverbatimname{(Unnamed MGL verbatim script)}
+\def\mgllinenostyle{\footnotesize}
+\newdimen\mgldashwidth\mgldashwidth=0.75em
+\newdimen\mgllinethickness\mgllinethickness=0.25ex
+\newdimen\mglbreakindent\mglbreakindent=1em
+%    \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \subsection{Final adjustments}
+% To finish the code of \textsf{\mglTeX}, we set the behavior of the package at the call of the |\begin{document}| and |\end{document}| commands.
+%
+% We tell \LaTeX{} to check the name of the document's main script for overwriting. We do this by calling |\MGL@set@script@name| inside a local group, because it defines |\MGL@script@name|, which we need undefined in certain parts of the code. Then the script is opened. We use |\immediate\openout| instead of |\MGL@openout| for this purpose, since, otherwise, we run the risk of the main script not being created when needed, if the user turns off \textsf{\mglTeX} before the |\begin{document}| command, and turns it on immediately after.
+%    \begin{macrocode}
 
+\AtBeginDocument{%
+  \bgroup\MGL@set@script@name{\MGL@main@script@name}\egroup%
+  \immediate\openout\MGL@main@stream=%
+  \MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl%
+}
+%    \end{macrocode}
+% We also set the actions for the call of |\end{document}|
+%    \begin{macrocode}
+\AtEndDocument{%
+%    \end{macrocode}
+% |\MGL@write@funcs| will simply write the MGL functions throughout the \LaTeX{} document.
+%    \begin{macrocode}
+  \MGL@write@funcs%
+%    \end{macrocode}
+% The main script is closed. We use the |\immediate\closeout| construction instead of |\MGL@closeout|, since the script must be closed even when \textsf{\mglTeX} is off.
+%    \begin{macrocode}
+  \immediate\closeout\MGL@main@stream%
+%    \end{macrocode}
+% The main script is compiled.
+%    \begin{macrocode}
+  \MGL@write{18}{%
+    mglconv -q \MGL@quality\space -S \MGL@scale\space%
+    -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+    -n "\MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl"%
+  }%
+}
+%    \end{macrocode}
+%
 % \Finale
\ No newline at end of file
index f780ff36b27b278339a2f323133fef0594ac1381..8dc591b2e1c512f9df0d309b469fc45b4ce76f0e 100644 (file)
@@ -1,16 +1,17 @@
 %%
-%% Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
-%% 
+%% Copyright (C) 2014--2015 by Diego Sejas Viscarra <diego.mathematician@gmail.com>
+%% Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin@gmail.com>
+%%
 %% This program is free software: you can redistribute it and/or modify it
 %% under the terms of the GNU General Public License as published by the
 %% Free Software Foundation, either version 3 of the License, or (at your
 %% option) any later version.
-%% 
+%%
 %% This program is distributed in the hope that it will be useful, but
 %% WITHOUT ANY WARRANTY; without even the implied warranty of
 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 %% Public License for more details.
-%% 
+%%
 %% You should have received a copy of the GNU General Public License along
 %% with this program.  If not, see <http://www.gnu.org/licenses/>.
 %%
@@ -24,7 +25,8 @@
 
 This is a generated file.
 
-Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
+Copyright (C) 2014--2015 by Diego Sejas Viscarra <diego.mathematician@gmail.com>
+Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin@gmail.com>
 
 This program is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
index fb4fedfe9a45fcc560e47c830ec8c60b2585331f..fe33fb9449eb503ffd661ddf262edf9795705363 100644 (file)
Binary files a/mgltex/mgltex.pdf and b/mgltex/mgltex.pdf differ
index 642aa1e970325a033f2570cae4b8df8d73367e4d..73fa21c45dabd4024ba97bbaebe18d7b6bb5f7af 100644 (file)
@@ -1,6 +1,15 @@
 %%
-%% Copyright (C) 2015 by Diego Sejas Viscarra <diego.mathematician@gmail.com>
-%% Copyright (C) 2015 by Alexey Balakin <mathgl.abalakin@gmail.com>
+%% This is file `mgltex.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% mgltex.dtx  (with options: `package')
+%% 
+%% This is a generated file.
+%% 
+%% Copyright (C) 2014--2015 by Diego Sejas Viscarra <diego.mathematician@gmail.com>
+%% Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin@gmail.com>
 %% 
 %% This program is free software: you can redistribute it and/or modify it
 %% under the terms of the GNU General Public License as published by the
 %% 
 %% You should have received a copy of the GNU General Public License along
 %% with this program.  If not, see <http://www.gnu.org/licenses/>.
-%%
+%% 
 
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{mgltex}[/2015/03/29 v3.0 Embed MGL scripts in LaTeX documents]
+\ProvidesPackage{mgltex}[2015/11/02 v4.0 Embed MGL scripts into LaTeX documents]
 
-\RequirePackage{keyval}
-\RequirePackage{graphicx}
+\def\MGL@TeX@ext{.tex}
 
 \DeclareOption{draft}{%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
 }
 
-\DeclareOption{epstopdf}{%
-  \DeclareGraphicsRule{.eps}{pdf}{.pdf}{`epstopdf #1}%
-}
-
-\DeclareOption{on}{%
-  \def\MGL@openout#1#2{%
-    \immediate\openout#1="#2"%
+\def\mgltexon{%
+  \def\MGL@openout##1##2{%
+    \immediate\openout##1="##2"%
+  }%
+  \def\MGL@openin##1##2{%
+    \immediate\openin##1="##2"%
   }%
-  \def\MGL@write#1#2{%
-    \immediate\write#1{#2}%
+  \def\MGL@write##1##2{%
+    \immediate\write##1{##2}%
+  }%
+  \def\MGL@read##1##2{%
+    \def##2{}%
+    \ifeof##1\else%
+      \bgroup%
+      \endlinechar=-1%
+      \immediate\global\read##1 to ##2%
+      \egroup%
+    \fi%
+  }%
+  \def\MGL@closeout##1{%
+    \immediate\closeout##1%
+  }
+  \def\MGL@closein##1{%
+    \immediate\closein##1%
+  }
+  \def\MGL@includegraphics{%
+    \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}{%
+      \ifx\MGL@graph@ext\MGL@TeX@ext%
+        \include{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}%
+      \else%
+        \expandafter\includegraphics\expandafter[\MGL@graph@keys]{%
+          \MGL@dir\MGL@graphics@dir\MGL@script@name%
+        }%
+      \fi%
+    }{%
+      \PackageWarning{mgltex}{MGL image "\MGL@script@name" not found}%
+      \fbox{%
+        \centering%
+        \bfseries\Huge%
+        \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
+      }%
+    }%
   }%
-  \def\MGL@graph@not@found@text{MGL\\image\\not\\found}%
-  \def\MGL@graph@not@found@message{MGL image "\MGL@this@code@label" not found}%
 }
-\DeclareOption{off}{%
-  \def\MGL@openout#1#2{}%
-  \def\MGL@write#1#2{}%
-  \def\MGL@graph@not@found@text{\mglTeX\\is off,\\no image\\generated}%
-  \def\MGL@graph@not@found@message{mglTeX is off, MGL image "\MGL@this@code@label" not generated}%
+\def\mgltexoff{%
+  \PackageWarning{mgltex}{mglTeX is off}%
+  \def\MGL@openout##1##2{}%
+  \def\MGL@openin##1##2{}%
+  \def\MGL@write##1##2{}%
+  \def\MGL@read##1##2{}%
+  \def\MGL@closeout##1{}
+  \def\MGL@closein##1{}
+  \def\MGL@includegraphics{%
+    \fbox{%
+      \centering%
+      \bfseries\Huge%
+      \begin{tabular}{c}\mglTeX\\is off;\\no image\\included\end{tabular}%
+    }%
+  }%
 }
+\DeclareOption{on}{\mgltexon}
+\DeclareOption{off}{\mgltexoff}
 
 \newif\if@MGL@comments@
-\DeclareOption{comments}{%
-  \@MGL@comments@true%
-}
-\DeclareOption{nocomments}{%
-  \@MGL@comments@false%
+\def\mglnocomments{\@MGL@comments@false}
+\def\mglcomments{\@MGL@comments@true}
+\DeclareOption{nocomments}{\mglnocomments}
+\DeclareOption{comments}{\mglcomments}
+
+\def\mglscale#1{
+  \def\MGL@scale{#1}%
+  \ifcase\MGL@scale\or\or\or\or\or\or\or\or\else%
+    \PackageWarning{mgltex}{%
+      Scaling value of \MGL@scale\space not allowed; using default (1)%
+    }%
+    \def\MGL@scale{1}%
+  \fi%
 }
+\DeclareOption{1x}{\mglscale{1}}
+\DeclareOption{2x}{\mglscale{2}}
+\DeclareOption{3x}{\mglscale{3}}
+\DeclareOption{4x}{\mglscale{4}}
+\DeclareOption{5x}{\mglscale{5}}
+\DeclareOption{6x}{\mglscale{6}}
+\DeclareOption{7x}{\mglscale{7}}
+\DeclareOption{8x}{\mglscale{8}}
+\DeclareOption{9x}{\mglscale{9}}
 
-\DeclareOption{1x}{\def\MGL@scale{1}}
-\DeclareOption{2x}{\def\MGL@scale{2}}
-\DeclareOption{3x}{\def\MGL@scale{3}}
-\DeclareOption{4x}{\def\MGL@scale{4}}
-\DeclareOption{5x}{\def\MGL@scale{5}}
-\DeclareOption{6x}{\def\MGL@scale{6}}
-\DeclareOption{7x}{\def\MGL@scale{7}}
-\DeclareOption{8x}{\def\MGL@scale{8}}
-\DeclareOption{9x}{\def\MGL@scale{9}}
-
-\DeclareGraphicsExtensions{%
-  .png,.eps,.jpg,.jpeg,.bps,.pdf,.epsz,.eps.gz,.bpsz,.bps.gz,.gif%
-}
-\DeclareOption{jpg}{\def\MGL@graphics@ext{.jpg}}
-\DeclareOption{jpeg}{\def\MGL@graphics@ext{.jpeg}}
-\DeclareOption{pdf}{\def\MGL@graphics@ext{.pdf}}
-\DeclareOption{png}{\def\MGL@graphics@ext{.png}}
-\DeclareOption{eps}{\def\MGL@graphics@ext{.eps}}
-\DeclareOption{epsz}{\def\MGL@graphics@ext{.eps.gz}}
-\DeclareOption{bps}{\def\MGL@graphics@ext{.bps}}
-\DeclareOption{bpsz}{\def\MGL@graphics@ext{.bps.gz}}
-\DeclareOption{gif}{\def\MGL@graphics@ext{.gif}}
-\DeclareOption{tex}{\def\MGL@graphics@ext{.tex}}
+\def\mglquality#1{%
+  \def\MGL@quality{#1}%
+  \ifcase\MGL@quality%
+    \PackageInfo{mgltex}{%
+      Quality 0: No face drawing (fastest)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 1: No color interpolation (fast)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 2: High quality (normal)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 3: High quality with 3d primitives (not implemented yet)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 4: No face drawing, direct bitmap drawing (low memory usage)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 5: No color interpolation, direct bitmap drawing (low memory usage)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 6: High quality, direct bitmap drawing (low memory usage)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 7: High quality with 3d primitives, direct bitmap drawing (not implemented yet)%
+    }%
+  \or%
+    \PackageInfo{mgltex}{%
+      Quality 8: Draw dots instead of primitives (extremely fast)%
+    }%
+  \else%
+    \PackageWarning{mgltex}{%
+      Quality #1 not available; using default (2)%
+    }%
+    \def\MGL@quality{2}%
+  \fi%
+}
+\DeclareOption{0q}{\mglquality{0}}
+\DeclareOption{1q}{\mglquality{1}}
+\DeclareOption{2q}{\mglquality{2}}
+\DeclareOption{3q}{\mglquality{3}}
+\DeclareOption{4q}{\mglquality{4}}
+\DeclareOption{5q}{\mglquality{5}}
+\DeclareOption{6q}{\mglquality{6}}
+\DeclareOption{7q}{\mglquality{7}}
+\DeclareOption{8q}{\mglquality{8}}
+
+\DeclareOption{eps}{\def\MGL@graph@ext{.eps}}
+\DeclareOption{epsz}{\def\MGL@graph@ext{.epsz}}
+\DeclareOption{epsgz}{\def\MGL@graph@ext{.eps.gz}}
+\DeclareOption{bps}{\def\MGL@graph@ext{.bps}}
+\DeclareOption{bpsz}{\def\MGL@graph@ext{.bpsz}}
+\DeclareOption{bpsgz}{\def\MGL@graph@ext{.bps.gz}}
+\DeclareOption{pdf}{\def\MGL@graph@ext{.pdf}}
+\DeclareOption{png}{\def\MGL@graph@ext{.png}}
+\DeclareOption{jpg}{\def\MGL@graph@ext{.jpg}}
+\DeclareOption{jpeg}{\def\MGL@graph@ext{.jpeg}}
+\DeclareOption{gif}{\def\MGL@graph@ext{.gif}}
+\DeclareOption{tex}{\def\MGL@graph@ext{.tex}}
 
 \DeclareOption*{\@unknownoptionerror}
 
-\ExecuteOptions{final,on,nocomments,1x,eps}
+\ExecuteOptions{final,on,nocomments,1x,2q,eps}
 \ProcessOptions*
 
-\define@key{MGL@keys}{dir}{\def\MGL@dir{#1}}
-\define@key{MGL@keys}{scriptsdir}{\def\MGL@scripts@dir{#1}}
-\define@key{MGL@keys}{graphicsdir}{\def\MGL@graphics@dir{#1}}
-\define@key{MGL@keys}{backupsdir}{\def\MGL@backups@dir{#1}}
-\define@key{MGL@keys}{quality}{\def\MGL@quality{#1}}
-\define@key{MGL@keys}{width}{\def\MGL@width{#1}}
-\define@key{MGL@keys}{height}{\def\MGL@height{#1}}
-
-\define@key{mgl@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
-\define@key{mgl@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
-\define@key{mgl@keys}{bblly}{\g@addto@macro{\graph@keys}{bblly=#1,}}
-\define@key{mgl@keys}{bburx}{\g@addto@macro{\graph@keys}{bburx=#1,}}
-\define@key{mgl@keys}{bbury}{\g@addto@macro{\graph@keys}{bbury=#1,}}
-\define@key{mgl@keys}{natwidth}{\g@addto@macro{\graph@keys}{natwidth=#1,}}
-\define@key{mgl@keys}{natheight}{\g@addto@macro{\graph@keys}{natheight=#1,}}
-\define@key{mgl@keys}{hiresbb}{\g@addto@macro{\graph@keys}{hiresbb=#1,}}
-\define@key{mgl@keys}{viewport}{\g@addto@macro{\graph@keys}{viewport=#1,}}
-\define@key{mgl@keys}{trim}{\g@addto@macro{\graph@keys}{trim=#1,}}
-\define@key{mgl@keys}{angle}{\g@addto@macro{\graph@keys}{angle=#1,}}
-\define@key{mgl@keys}{origin}{\g@addto@macro{\graph@keys}{origin=#1,}}
-\define@key{mgl@keys}{width}{\g@addto@macro{\graph@keys}{width=#1,}}
-\define@key{mgl@keys}{height}{\g@addto@macro{\graph@keys}{height=#1,}}
-\define@key{mgl@keys}{totalheight}{\g@addto@macro{\graph@keys}{totalheight=#1,}}
-\define@key{mgl@keys}{keepaspectratio}{\g@addto@macro{\graph@keys}{keepaspectratio=#1,}}
-\define@key{mgl@keys}{scale}{\g@addto@macro{\graph@keys}{scale=#1,}}
-\define@key{mgl@keys}{clip}[true]{\g@addto@macro{\graph@keys}{clip=#1,}}
-\define@key{mgl@keys}{draft}[false]{\g@addto@macro{\graph@keys}{draft=#1,}}
-\define@key{mgl@keys}{type}{\g@addto@macro{\graph@keys}{type=#1,}}
-\define@key{mgl@keys}{ext}{\g@addto@macro{\graph@keys}{ext=#1,}}
-\define@key{mgl@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
-\define@key{mgl@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
-\define@key{mgl@keys}{imgext}{\def\mgl@graphics@ext{.#1}}
-
-\define@key{mglplot@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
-\define@key{mglplot@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
-\define@key{mglplot@keys}{bblly}{\g@addto@macro{\graph@keys}{bblly=#1,}}
-\define@key{mglplot@keys}{bburx}{\g@addto@macro{\graph@keys}{bburx=#1,}}
-\define@key{mglplot@keys}{bbury}{\g@addto@macro{\graph@keys}{bbury=#1,}}
-\define@key{mglplot@keys}{natwidth}{\g@addto@macro{\graph@keys}{natwidth=#1,}}
-\define@key{mglplot@keys}{natheight}{\g@addto@macro{\graph@keys}{natheight=#1,}}
-\define@key{mglplot@keys}{hiresbb}{\g@addto@macro{\graph@keys}{hiresbb=#1,}}
-\define@key{mglplot@keys}{viewport}{\g@addto@macro{\graph@keys}{viewport=#1,}}
-\define@key{mglplot@keys}{trim}{\g@addto@macro{\graph@keys}{trim=#1,}}
-\define@key{mglplot@keys}{angle}{\g@addto@macro{\graph@keys}{angle=#1,}}
-\define@key{mglplot@keys}{origin}{\g@addto@macro{\graph@keys}{origin=#1,}}
-\define@key{mglplot@keys}{width}{\g@addto@macro{\graph@keys}{width=#1,}}
-\define@key{mglplot@keys}{height}{\g@addto@macro{\graph@keys}{height=#1,}}
-\define@key{mglplot@keys}{totalheight}{\g@addto@macro{\graph@keys}{totalheight=#1,}}
-\define@key{mglplot@keys}{keepaspectratio}{\g@addto@macro{\graph@keys}{keepaspectratio=#1,}}
-\define@key{mglplot@keys}{scale}{\g@addto@macro{\graph@keys}{scale=#1,}}
-\define@key{mglplot@keys}{clip}[true]{\g@addto@macro{\graph@keys}{clip=#1,}}
-\define@key{mglplot@keys}{draft}[false]{\g@addto@macro{\graph@keys}{draft=#1,}}
-\define@key{mglplot@keys}{type}{\g@addto@macro{\graph@keys}{type=#1,}}
-\define@key{mglplot@keys}{ext}{\g@addto@macro{\graph@keys}{ext=#1,}}
-\define@key{mglplot@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
-\define@key{mglplot@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
-\define@key{mglplot@keys}{imgext}{\def\MGL@graphics@ext{.#1}}
-\define@key{mglplot@keys}{setup}{\def\mglplot@setup{#1}}
-
-\def\mglsettings#1{%
-  \setkeys{MGL@keys}{#1}%
-}
-\@onlypreamble\mglsettings
+\RequirePackage{keyval}
+\RequirePackage{graphicx}
+\RequirePackage{verbatim}
+\DeclareGraphicsExtensions{%
+  .eps,.epsz,.eps.gz,.bps,.bpsz,.bps.gz,.pdf,.png,.jpg,.jpeg,.gif%
+}
+\let\verbatim@finish\relax
+
+\define@key{MGL@keys}{bb}{\g@addto@macro\MGL@graph@keys{bb=#1,}}
+\define@key{MGL@keys}{bbllx}{\g@addto@macro\MGL@graph@keys{bbllx=#1,}}
+\define@key{MGL@keys}{bblly}{\g@addto@macro\MGL@graph@keys{bblly=#1,}}
+\define@key{MGL@keys}{bburx}{\g@addto@macro\MGL@graph@keys{bburx=#1,}}
+\define@key{MGL@keys}{bbury}{\g@addto@macro\MGL@graph@keys{bbury=#1,}}
+\define@key{MGL@keys}{natwidth}{\g@addto@macro\MGL@graph@keys{natwidth=#1,}}
+\define@key{MGL@keys}{natheight}{\g@addto@macro\MGL@graph@keys{natheight=#1,}}
+\define@key{MGL@keys}{hiresbb}{\g@addto@macro\MGL@graph@keys{hiresbb=#1,}}
+\define@key{MGL@keys}{viewport}{\g@addto@macro\MGL@graph@keys{viewport=#1,}}
+\define@key{MGL@keys}{trim}{\g@addto@macro\MGL@graph@keys{trim=#1,}}
+\define@key{MGL@keys}{angle}{\g@addto@macro\MGL@graph@keys{angle=#1,}}
+\define@key{MGL@keys}{origin}{\g@addto@macro\MGL@graph@keys{origin=#1,}}
+\define@key{MGL@keys}{width}{\g@addto@macro\MGL@graph@keys{width=#1,}}
+\define@key{MGL@keys}{height}{\g@addto@macro\MGL@graph@keys{height=#1,}}
+\define@key{MGL@keys}{totalheight}{\g@addto@macro\MGL@graph@keys{totalheight=#1,}}
+\define@key{MGL@keys}{keepaspectratio}[true]{%
+  \g@addto@macro\MGL@graph@keys{keepaspectratio=#1,}%
+}
+\define@key{MGL@keys}{scale}{\g@addto@macro\MGL@graph@keys{scale=#1,}}
+\define@key{MGL@keys}{clip}[true]{\g@addto@macro\MGL@graph@keys{clip=#1,}}
+\define@key{MGL@keys}{draft}[true]{\g@addto@macro\MGL@graph@keys{draft=#1,}}
+\define@key{MGL@keys}{type}{\g@addto@macro\MGL@graph@keys{type=#1,}}
+\define@key{MGL@keys}{ext}{\g@addto@macro\MGL@graph@keys{ext=#1,}}
+\define@key{MGL@keys}{read}{\g@addto@macro\MGL@graph@keys{read=#1,}}
+\define@key{MGL@keys}{command}{\g@addto@macro\MGL@graph@keys{command=#1,}}
+\define@key{MGL@keys}{imgext}{\def\MGL@graph@ext{.#1}}
+
+\newif\if@MGL@lineno@
+\define@key{MGL@verb@keys}{lineno}[true]{\csname @MGL@lineno@#1\endcsname}
+
+\edef\MGL@main@script@name{\jobname}
 
 \def\MGL@dir{}
-\def\mgldir#1{%
-  \def\MGL@dir{#1}%
-}
-\@onlypreamble\mgldir
-
 \def\MGL@scripts@dir{}
-\def\mglscriptsdir#1{%
-  \def\MGL@scripts@dir{#1}%
-}
-\@onlypreamble\mglscriptsdir
-
 \def\MGL@graphics@dir{}
-\def\mglgraphicsdir#1{%
-  \def\MGL@graphics@dir{#1}%
-}
-\@onlypreamble\mglscriptsdir
-
 \def\MGL@backups@dir{}
-\def\mglbackupsdir#1{%
-  \def\MGL@backups@dir{#1}%
-}
-\@onlypreamble\mglbackupsdir
+\def\MGL@paths{\MGL@dir\MGL@scripts@dir,\MGL@dir\MGL@backups@dir}
 
-\def\TeX@ext{.tex}
-\def\MGL@include@graphics{%
-  \ifx\MGL@graphics@ext\TeX@ext%
-    \IfFileExists{\MGL@this@code@label.tex}{%
-      \include{\MGL@dir\MGL@graphics@dir\MGL@this@code@label}%
-    }{%
-      \MGL@graph@not@found%
-    }%
-  \else%
-  \def\MGL@next@action{\MGL@graph@not@found}%
-    \@for\MGL@graph@ext:=\Gin@extensions\do{%b
-      \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@this@code@label\MGL@graph@ext}{%
-        \def\MGL@next@action{%
-          \expandafter\includegraphics\expandafter[\graph@keys]{\MGL@dir\MGL@graphics@dir\MGL@this@code@label}%
-        }%
-      }{}%
-    }%
-    \MGL@next@action%
-  \fi%
-}
-\def\MGL@graph@not@found{%
-  \PackageWarning{mgltex}{\MGL@graph@not@found@message}%
-  \fbox{%
-    \centering%
-    \bfseries\Huge%
-    \begin{tabular}{c}\MGL@graph@not@found@text\end{tabular}%
-  }%
-}
-
-\def\MGL@openin#1#2{%
-  \immediate\openin#1="#2"%
-}
-\def\MGL@read#1#2{%
-  \def#2{}%
-  \ifeof#1\else%
-    \immediate\read#1 to #2%
-  \fi%
-}
-\def\MGL@closein#1{%
-  \immediate\closein#1%
-}
-\def\MGL@closeout#1{%
-  \immediate\closeout#1%
-}
-\def\MGL@unchanged#1{%
-  \global\@namedef{MGL@@@#1}{}%
-}
-\def\MGL@scripts@written{}
-\def\MGL@funcs{}
-
-\newwrite\MGL@script
-\newread\MGL@in@stream
+\newwrite\MGL@main@stream
 \newwrite\MGL@out@stream
+\newread\MGL@in@stream
+\newcounter{MGL@script@no}
+\newcounter{MGL@line@no}
+\newcounter{MGL@verb@script@no}
+\newif\if@MGL@list@script@
+\def\l@MGL@script{\@dottedtocline{1}{0em}{1.5em}}
 
-\AtBeginDocument{%
-  \MGL@openout{\MGL@script}{\MGL@dir\MGL@scripts@dir\jobname.mgl}%
-  \MGL@write\MGL@script{\MGL@signature}%
-}
-\AtEndDocument{%
-  \MGL@write\MGL@script{stop}%
-  \MGL@write\MGL@script{}%
-  \bgroup%
-    \endlinechar=-1\relax%
-    \MGL@funcs%
-  \egroup%
-  \MGL@closeout{\MGL@script}%
-  \MGL@write{18}{mglconv -n -q \MGL@quality\space -S \MGL@scale\space "\MGL@dir\MGL@scripts@dir\jobname.mgl"}%
-}
-
-%%%%% Anatomy of environments and commands %%%%%
 \def\MGL@setkeys#1#2{%
-  \def\graph@keys{}%
+  \def\MGL@graph@keys{}%
   \setkeys{#1}{#2}%
 }
 
-\newcounter{MGL@script@no}
-\def\MGL@create@code@label{%
-  \stepcounter{MGL@script@no}%
-  \edef\MGL@this@code@label{\jobname-MGL-\arabic{MGL@script@no}}%
-  \xdef\MGL@scripts@written{\MGL@scripts@written\MGL@this@code@label,}%
+\def\MGL@codes{%
+  \let\do\@makeother\dospecials%
+  \catcode`\^^M\active%
 }
 
-\def\MGL@test@code@label#1{%
-  \edef\MGL@this@code@label{#1}%
-  \@for\MGL@script@name:=\MGL@scripts@written\do{%
-    \ifx\MGL@this@code@label\MGL@script@name%
-      \PackageWarning{mgltex}{Overwriting MGL code labeled "\MGL@this@code@label"}%
+\def\MGL@document@scripts{}
+\def\MGL@set@script@name#1{%
+  \edef\MGL@script@name{#1}%
+  \@for\MGL@temp@a:=\MGL@document@scripts\do{%
+    \ifx\MGL@temp@a\MGL@script@name%
+      \PackageWarning{mgltex}{Multiple MGL scripts named "\MGL@script@name.mgl"}%
     \fi%
   }%
-  \xdef\MGL@scripts@written{\MGL@scripts@written\MGL@this@code@label,}%
+  \g@addto@macro\MGL@document@scripts{\MGL@script@name,}%
 }
 
-\def\MGL@codes{%
-  \let\do\@makeother\dospecials\relax%
-  \endlinechar`\^^M \catcode`\^^M\active\relax%
-  \catcode`\ =10\relax%
-}
-\def\MGL@verb@codes{%
-  \let\do\@makeother\dospecials\relax%
-  \endlinechar`\^^M\relax\catcode`\^^M\active\relax%
-}
-
-\def\MGL@test@end@env#1{%
-  \edef\MGL@this@line{#1}%
-  \ifx\MGL@this@line\MGL@end@env@cmd%
-    \def\MGL@next@action{\MGL@end@env}%
-  \fi%
+\def\MGL@unchanged#1{%
+  \global\@namedef{MGL@@@#1}{}%
 }
 
-\def\MGL@def@end@env@cmd#1{%
-  \def\MGL@end@env{\end{#1}}%
-  \begingroup%
-    \escapechar=-1 \relax%
-    \xdef\MGL@end@env@cmd{\string\\end\string\{#1\string\}}%
-  \endgroup%
+\def\MGL@process@script#1#2{%
+  \@ifundefined{MGL@@@\MGL@script@name}{%
+    #1%
+  }{%
+    \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}{%
+      #2%
+    }{%
+      #1%
+    }%
+  }%
 }
 
-\def\MGL@set@write@script@out{%
-  \def\MGL@write@code@action##1{%
-    \MGL@write\MGL@script{##1}%
-    \MGL@write\MGL@out@stream{##1}%
+\def\MGL@def@for@loop#1{%
+  \long\def\MGL@for##1:=##2\do##3{%
+    \expandafter\def\expandafter\@fortmp\expandafter{##2}%
+    \ifx\@fortmp\@empty\else%
+      \expandafter\MGL@forloop##2#1\@nil#1\@nil\@@##1{##3}%
+    \fi%
   }%
-}
-\def\MGL@set@write@script{%
-  \def\MGL@write@code@action##1{%
-    \MGL@write\MGL@script{##1}%
+  \long\def\MGL@forloop##1#1##2#1##3\@@##4##5{%
+    \def##4{##1}%
+    \ifx##4\@nnil\else%
+      ##5\def##4{##2}%
+      \ifx##4\@nnil\else%
+        ##5\MGL@iforloop##3\@@##4{##5}%
+      \fi%
+    \fi%
   }%
-}
-\def\MGL@set@write@out{%
-  \def\MGL@write@code@action##1{%
-    \MGL@write\MGL@out@stream{##1}%
+  \long\def\MGL@iforloop##1#1##2\@@##3##4{%
+    \def##3{##1}%
+    \ifx##3\@nnil%
+      \expandafter\@fornoop%
+    \else%
+      ##4\relax\expandafter\MGL@iforloop%
+    \fi%
+    ##2\@@##3{##4}%
   }%
 }
-\begingroup%
-  \catcode`\^^M\active\relax%
-  \gdef\MGL@ignore@line#1^^M{%
-    \expandafter\MGL@write@line%
+\MGL@def@for@loop{^^J}
+
+\def\MGL@compare@code#1{%
+  \def\MGL@next{%
+    \MGL@closein\MGL@in@stream%
+    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
   }%
-  \gdef\MGL@write@line#1^^M{%
-    \def\MGL@next@action{%
-      \MGL@write@code@action{#1}%
-      \MGL@write@line%
-    }%
-    \MGL@test@end@env{#1}%
-    \MGL@next@action%
-  }%
-  \gdef\MGL@compare@line#1^^M{%
-    \def\MGL@next@action{%
-      \def\MGL@this@line{#1^^M}%
-      \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-      \ifx\MGL@this@code@line\MGL@this@line\else%
-        \def\MGL@future@action{}%
-      \fi%
-      \MGL@compare@line%
-    }%
-    \edef\MGL@this@line{#1}%
-    \ifx\MGL@this@line\MGL@end@env@cmd%
-      \def\MGL@next@action{\MGL@end@env}%
-      \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-      \ifeof\MGL@in@stream\else%
-        \def\MGL@future@action{}%
-      \fi%
+  \def\verbatim@processline{%
+    \MGL@read\MGL@in@stream{\MGL@temp@a}%
+    \edef\MGL@temp@b{\the\verbatim@line}%
+    \ifx\MGL@temp@a\MGL@temp@b\else%
+      \def\MGL@next{\MGL@closein\MGL@in@stream}%
+      \def\verbatim@processline{}%
     \fi%
-    \MGL@next@action%
   }%
-\endgroup
-
-\def\MGL@set@write@verb@out{%
-  \def\MGL@write@verb@code@action{%
-    \MGL@write\MGL@out@stream{\the\MGL@line}%
+  \def\verbatim@finish{%
+    \MGL@read\MGL@in@stream{\MGL@temp@a}%
+    \ifeof\MGL@in@stream\else%
+      \def\MGL@next{\MGL@closein\MGL@in@stream}%
+    \fi%
   }%
+  \MGL@openin\MGL@in@stream{#1}%
+  \verbatim@start%
 }
-\def\MGL@set@write@verb@to@doc{%
-  \def\MGL@write@verb@code@action{%
-    \stepcounter{MGL@verb@line@no}%
-    \item\mbox{\the\MGL@line}%
-  }%
+
+\def\MGL@write@funcs{\MGL@write\MGL@main@stream{stop^^J}}
+\def\MGL@func#1{%
+  \MGL@openin\MGL@in@stream{\MGL@dir\MGL@backups@dir#1.mgl}%
+  \MGL@@func%
 }
-\begingroup%
-  \catcode`\^^M\active\relax%
-  \gdef\MGL@ignore@verb@line#1^^M{%
-    \expandafter\MGL@write@verb@line%
-  }
-\endgroup%
-\newtoks\MGL@word
-\newtoks\MGL@line
-\def\MGL@write@verb@line#1{%
-  \let\MGL@next@action\MGL@write@verb@line%
-  \expandafter\if#1\^^M%
-    \MGL@write@verb@code@action%
-    \MGL@word{}%
-    \MGL@line{}%
-  \else\expandafter\if#1\space%
-    \MGL@word{}%
-    \MGL@line\expandafter{\the\MGL@line#1}%
-  \else%
-    \MGL@word\expandafter{\the\MGL@word#1}%
-    \MGL@line\expandafter{\the\MGL@line#1}%
-    \MGL@test@end@env{\the\MGL@word}%
-  \fi\fi%
-  \MGL@next@action%
-}
-\def\MGL@rewrite@code#1{%
-  \MGL@read\MGL@in@stream{\MGL@this@code@line}%
+\def\MGL@@func{%
+  \MGL@read\MGL@in@stream{\MGL@temp@a}%
   \ifeof\MGL@in@stream%
-    \MGL@closein{\MGL@in@stream}%
+    \MGL@closein\MGL@in@stream%
   \else%
-    \MGL@write#1{\MGL@this@code@line}%
-    \MGL@rewrite@code{#1}%
+    \MGL@write\MGL@main@stream{\MGL@temp@a}%
+    \expandafter\MGL@@func%
   \fi%
 }
-\begingroup%
-  \catcode`\^^M\active\relax%  
-  \gdef\MGL@compare@next@verb@line#1^^M{%
-    \expandafter\MGL@compare@verb@line%
-  }%
-\endgroup
-\def\MGL@compare@verb@line#1{%
-  \let\MGL@next@action\MGL@compare@verb@line%
-  \expandafter\if#1\^^M%
-    \MGL@line\expandafter{\the\MGL@line#1}%
-    \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-    \edef\MGL@this@line{\the\MGL@line}%
-    \ifx\MGL@this@line\MGL@this@code@line\else%
-      \def\MGL@future@action{}%
-    \fi%
-    \MGL@word{}%
-    \MGL@line{}%
-  \else\expandafter\if#1\space%
-    \MGL@word{}%
-    \MGL@line\expandafter{\the\MGL@line#1}%
-  \else%
-    \MGL@word\expandafter{\the\MGL@word#1}%
-    \MGL@line\expandafter{\the\MGL@line#1}%
-    \edef\MGL@this@line{\the\MGL@word}%
-    \ifx\MGL@this@line\MGL@end@env@cmd%
-      \def\MGL@next@action{\MGL@end@env}%
-      \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-      \ifeof\MGL@in@stream\else%
-        \def\MGL@future@action{}%
-      \fi%
+
+\def\MGL@set@verbatim@code{%
+  \if@minipage\else\vskip\parskip\fi%
+  \leftskip\@totalleftmargin\rightskip\z@skip%
+  \parindent\z@\parfillskip\@flushglue\parskip\z@%
+  \@@par%
+  \def\par{%
+    \if@tempswa%
+      \leavevmode\null\@@par\penalty\interlinepenalty%
+    \else%
+      \@tempswatrue%
+      \ifhmode\@@par\penalty\interlinepenalty\fi%
     \fi%
-  \fi\fi%
-  \MGL@next@action%
-}
-\newcounter{MGL@verb@line@no}
-\def\MGL@prepare@verb@env{%
-  \setcounter{MGL@verb@line@no}{0}%
-  \list{\itshape\footnotesize\arabic{MGL@verb@line@no}.}{}%
-  \setlength{\labelsep}{1em}%
-  \itemsep\z@skip%
-  \leftskip\z@skip\rightskip\z@skip%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
-  \MGL@verb@codes%
-  \obeyspaces%
+  }%
+  \obeylines%
+  \let\do\@makeother\dospecials%
   \verbatim@font%
+  \frenchspacing%
+  \everypar\expandafter{\the\everypar\unpenalty}%
+  \def\@noitemerr{\PackageWarning{mglTeX}{Empty MGL script}}%
+  \labelsep1em%
+  \itemsep\z@%
+  \def\@xobeysp{\space}\@vobeyspaces%
+  \pretolerance\@M%
+  \hbadness\@M%
+  \advance\leftskip\mglbreakindent%
+  \itemindent-\mglbreakindent%
 }
-\def\MGL@rewrite@code@verb{%
-  \stepcounter{MGL@verb@line@no}%
-  \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-  \ifeof\MGL@in@stream%
-    \def\MGL@next@action{%
-      \MGL@closein{\MGL@in@stream}%
-      \endlist%
-    }%
-  \else%
-    \def\MGL@next@action{%
-      \item\mbox{\MGL@this@code@line}%
-      \MGL@rewrite@code@verb%
-    }%
-  \fi%
-  \MGL@next@action%
-}
-%%%%% Anatomy of environments and commands %%%%%
+
+\def\MGL@line@sep{\leavevmode\cleaders\hrule height\mgllinethickness\hfill\kern\z@}
+\def\MGL@dash@sep{\leavevmode\cleaders\hb@xt@\mgldashwidth{\hss-\hss}\hfill\kern\z@}
 
 \newcommand\mgl[1][]{%
-  \MGL@setkeys{mgl@keys}{#1}%
-  \MGL@create@code@label%
+  \define@key{MGL@keys}{label}{\def\MGL@script@name{##1}}%
+  \MGL@setkeys{MGL@keys}{#1}%
+  \@ifundefined{MGL@script@name}{%
+    \stepcounter{MGL@script@no}%
+    \edef\MGL@script@name{\MGL@main@script@name-MGL-\arabic{MGL@script@no}}%
+  }{}%
+  \MGL@set@script@name{\MGL@script@name}%
   \MGL@codes%
-  \MGL@def@end@env@cmd{mgl}%
-  \def\MGL@future@action{%
-    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@this@code@label}}%
-  }%
-  \MGL@set@write@script@out%
-  \@ifundefined{MGL@@@\MGL@this@code@label}{%
-    \MGL@write\MGL@script{quality \MGL@quality}%
-    \MGL@write\MGL@script{setsize \MGL@width\space\MGL@height}%
-    \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-    \def\MGL@save@action{%
-      \MGL@write\MGL@script{write '\MGL@dir\MGL@graphics@dir\MGL@this@code@label\MGL@graphics@ext'}%
-      \MGL@write\MGL@script{reset}%
-      \MGL@write\MGL@script{}%
-    }
-    \expandafter\MGL@write@line%
+  \MGL@process@script{%
+    \mgl@write@script%
   }{%
-    \def\MGL@save@action{}%
-    \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-    \expandafter\MGL@compare@line%
+    \MGL@compare@code{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
   }%
 }
+\def\mgl@write@script{%
+  \def\MGL@next{%
+    \MGL@closeout\MGL@out@stream%
+    \MGL@write\MGL@main@stream{%
+      write '\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext'^^J%
+      ^^Jreset^^J%
+    }%
+    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
+  }%
+  \def\verbatim@processline{%
+    \MGL@write\MGL@main@stream{\the\verbatim@line}%
+    \MGL@write\MGL@out@stream{\the\verbatim@line}%
+  }%
+  \MGL@write\MGL@main@stream{quality \MGL@quality}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
+  \verbatim@start%
+}
 \def\endmgl{%
-  \MGL@closeout{\MGL@out@stream}%
-  \MGL@closein{\MGL@in@stream}%
-  \MGL@save@action%
-  \MGL@future@action%
-  \MGL@include@graphics%
+  \MGL@next%
+  \MGL@includegraphics%
 }
 
 \def\mgladdon{%
+  \@bsphack%
   \MGL@codes%
-  \MGL@def@end@env@cmd{mgladdon}%
-  \MGL@set@write@out%
-  \MGL@set@write@script%
-  \expandafter\MGL@write@line%
+  \def\verbatim@processline{%
+    \MGL@write\MGL@main@stream{\the\verbatim@line}%
+  }%
+  \verbatim@start%
 }
-\def\endmgladdon{%
-  \MGL@write\MGL@script{}%
+\def\endmgladdon{\@esphack}
+
+\newcommand\mglfunc[2][0]{%
+  \@bsphack%
+  \MGL@set@script@name{#2}%
+  \g@addto@macro\MGL@write@funcs{\MGL@func{#2}}%
+  \MGL@codes%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
+  \MGL@write\MGL@out@stream{func '\MGL@script@name' #1}%
+  \verbatim@start%
 }
+\def\endmglfunc{%
+  \MGL@write\MGL@out@stream{return^^J}%
+  \MGL@closeout\MGL@out@stream%
+  \@esphack%
+}%
 
 \newcommand\mglcode[2][]{%
-  \MGL@setkeys{mgl@keys}{#1}%
-  \MGL@test@code@label{#2}%
-  \MGL@verb@codes%
-  \MGL@def@end@env@cmd{mglcode}%
-  \@ifundefined{MGL@@@\MGL@this@code@label}{%
-    \def\MGL@future@action{%
-      \MGL@write{18}{%
-        mglconv -q \MGL@quality\space -S \MGL@scale\space -s "\MGL@dir\MGL@scripts@dir\mglcommonscript.mgl" -o "\MGL@dir\MGL@graphics@dir\MGL@this@code@label\MGL@graphics@ext" "\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl"%
-      }%
-      \MGL@write\@auxout{\string\MGL@unchanged{\MGL@this@code@label}}%
-    }%
-    \MGL@set@write@verb@out%
-    \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-    \expandafter\MGL@ignore@verb@line%
+  \MGL@setkeys{MGL@keys}{#1}%
+  \MGL@set@script@name{#2}%
+  \MGL@codes%
+  \MGL@process@script{%
+    \mglcode@write@script%
   }{%
-    \def\MGL@future@action{%
-      \MGL@write\@auxout{\string\MGL@unchanged{\MGL@this@code@label}}%
+    \MGL@compare@code{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  }%
+}
+\def\mglcode@write@script{%
+  \def\MGL@next{%
+    \MGL@closeout\MGL@out@stream%
+    \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
+    \MGL@write{18}{%
+      mglconv -q \MGL@quality\space -S \MGL@scale\space%
+      -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+      -o "\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext"\space%
+      "\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl"%
     }%
-    \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-    \expandafter\MGL@compare@next@verb@line%
   }%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  \verbatim@start%
 }
 \def\endmglcode{%
-  \MGL@closeout{\MGL@out@stream}%
-  \MGL@closein{\MGL@in@stream}%
-  \bgroup%
-    \endlinechar=-1\relax%
-    \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-    \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl}%
-    \MGL@write\MGL@out@stream{\MGL@signature}%
-    \MGL@rewrite@code{\MGL@out@stream}%
-    \MGL@closein{\MGL@in@stream}%
-    \MGL@closeout{\MGL@out@stream}%
-  \egroup%
-  \MGL@future@action%
-  \MGL@include@graphics%
+  \MGL@next%
+  \MGL@includegraphics%
 }
 
 \def\mglscript#1{%
-  \MGL@test@code@label{#1}%
-  \MGL@verb@codes%
-  \MGL@def@end@env@cmd{mglscript}%
-  \MGL@set@write@verb@out%
-  \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl}%
-  \MGL@write\MGL@out@stream{\MGL@signature}%
-  \expandafter\MGL@ignore@verb@line%
+  \@bsphack%
+  \MGL@set@script@name{#1}%
+  \MGL@codes%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  \verbatim@start%
 }
 \def\endmglscript{%
-  \MGL@closeout{\MGL@out@stream}%
+  \MGL@closeout\MGL@out@stream%
+  \@esphack%
 }
 
-\newcommand\mglfunc[2][0]{%
-  \MGL@test@code@label{#2}%
+\def\mglcommon{%
+  \@bsphack%
+  \MGL@set@script@name{\mglcommonscriptname}%
   \MGL@codes%
-  \MGL@def@end@env@cmd{mglfunc}%
-  \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-  \MGL@write\MGL@out@stream{func #2 #1}%
-  \g@addto@macro{\MGL@funcs}{\MGL@rewrite@func{#2}}%
-  \MGL@set@write@out%
-  \expandafter\MGL@ignore@line%
+  \def\verbatim@processline{\MGL@write\MGL@out@stream{\the\verbatim@line}}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  \verbatim@start%
 }
-\def\endmglfunc{%
-  \MGL@write\MGL@out@stream{return}%
-  \MGL@write\MGL@out@stream{}%
-  \MGL@closeout{\MGL@out@stream}%
-}
-\def\MGL@rewrite@func#1{%
-  \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@backups@dir#1.mgl.backup}%
-  \MGL@rewrite@code{\MGL@script}%
+\@onlypreamble\mglcommon
+\def\endmglcommon{%
+  \MGL@closeout\MGL@out@stream%
+  \@esphack%
 }
 
-\def\mglverbatim{%
-  \MGL@def@end@env@cmd{mglverbatim}%
-  \MGL@prepare@verb@env%
-  \MGL@set@write@verb@to@doc
-  \expandafter\MGL@ignore@verb@line%
-}
-\def\endmglverbatim{\endlist}
+\def\mglsetup#1{\mglfunc{#1}}%
+\let\endmglsetup\endmglfunc
 
-\def\mglblock#1{%
-  \MGL@test@code@label{#1}%
-  \MGL@verb@codes%
-  \obeyspaces%
-  \MGL@def@end@env@cmd{mglblock}%
-  \MGL@set@write@verb@out%
-  \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl}%
-  \MGL@write\MGL@out@stream{\MGL@signature}%
-  \expandafter\MGL@ignore@verb@line%
+\newcommand\mglplot[2][]{%
+  \define@key{MGL@keys}{label}{\edef\MGL@script@name{##1}}%
+  \define@key{MGL@keys}{setup}{\def\MGL@mglplot@setup{##1}}%
+  \define@key{MGL@keys}{separator}{%
+    \MGL@def@for@loop{##1}%
+  }%
+  \MGL@setkeys{MGL@keys}{#1}%
+  \@ifundefined{MGL@script@name}{%
+    \stepcounter{MGL@script@no}
+    \edef\MGL@script@name{\MGL@main@script@name-MGL-\arabic{MGL@script@no}}
+  }{}%
+  \MGL@set@script@name{\MGL@script@name}%
+  \@ifundefined{MGL@mglplot@setup}{%
+    \edef\MGL@temp@a{#2}%
+  }{%
+    \edef\MGL@temp@a{call '\MGL@mglplot@setup'^^J#2}%
+  }
+  \MGL@process@script{%
+    \mglplot@write@script%
+  }{%
+    \mglplot@compare@code%
+  }%
+  \MGL@includegraphics%
+}
+\def\mglplot@write@script{%
+  \MGL@write\MGL@main@stream{quality \MGL@quality}%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
+  \MGL@for\MGL@temp@b:=\MGL@temp@a\do{%
+    \MGL@write\MGL@main@stream{\MGL@temp@b}%
+    \MGL@write\MGL@out@stream{\MGL@temp@b}%
+  }%
+  \MGL@closeout\MGL@out@stream%
+  \MGL@write\MGL@main@stream{%
+    write '\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext'^^J%
+    ^^Jreset^^J%
+  }%
+  \MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}%
+}
+\def\mglplot@compare@code{%
+  \def\MGL@next{\MGL@write\@auxout{\string\MGL@unchanged{\MGL@script@name}}}%
+  \MGL@openin\MGL@in@stream{\MGL@dir\MGL@backups@dir\MGL@script@name.mgl}%
+  \MGL@for\MGL@temp@b:=\MGL@temp@a\do{%
+    \MGL@read\MGL@in@stream{\MGL@temp@c}%
+    \ifx\MGL@temp@b\MGL@temp@c\else%
+      \let\MGL@next\relax%
+    \fi%
+  }%
+  \MGL@closein\MGL@in@stream%
+  \MGL@next%
+}
+
+\def\mglblock{\@MGL@list@script@true\mglblock@}
+\@namedef{mglblock*}{\@MGL@list@script@false\mglblock@}
+\newcommand\mglblock@[2][]{%
+  \@MGL@lineno@true%
+  \setkeys{MGL@verb@keys}{#1}%
+  \MGL@set@script@name{#2}%
+  \if@MGL@list@script@%
+    \refstepcounter{MGL@verb@script@no}%
+    \addcontentsline{lms}{MGL@script}{%
+      \protect\numberline{\theMGL@verb@script@no.}%
+      {\ttfamily\protect\detokenize{\MGL@script@name.mgl}}%
+    }%
+  \fi%
+  \if@MGL@lineno@%
+    \list{\mgllinenostyle\arabic{MGL@line@no}.}{\usecounter{MGL@line@no}}%
+  \else%
+    \list{}{}%
+  \fi%
+  \MGL@set@verbatim@code%
+  \fboxrule=\mgllinethickness%
+  \item[\MGL@line@sep]\fbox{%
+    \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}%
+  }\hskip\labelsep\MGL@line@sep\par\par%
+  \def\verbatim@processline{%
+    \item\the\verbatim@line%
+    \MGL@write\MGL@out@stream{\the\verbatim@line}%
+  }%
+  \MGL@openout\MGL@out@stream{\MGL@dir\MGL@scripts@dir\MGL@script@name.mgl}%
+  \verbatim@start%
 }
 \def\endmglblock{%
-  \MGL@closeout{\MGL@out@stream}%
-  \mglinclude{\MGL@this@code@label}%
+  \MGL@closeout\MGL@out@stream%
+  \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+  \endlist%
+}
+\expandafter\let\csname endmglblock*\endcsname\endmglblock
+
+\def\mglverbatim{\@MGL@list@script@true\mglverbatim@}
+\@namedef{mglverbatim*}{\@MGL@list@script@false\mglverbatim@}
+\newcommand\mglverbatim@[1][]{%
+  \@MGL@lineno@true%
+  \define@key{MGL@verb@keys}{label}{\edef\MGL@script@name{##1}}%
+  \setkeys{MGL@verb@keys}{#1}%
+  \if@MGL@lineno@%
+    \list{\mgllinenostyle\arabic{MGL@line@no}.}{\usecounter{MGL@line@no}}%
+  \else%
+    \list{}{}%
+  \fi%
+  \MGL@set@verbatim@code%
+  \fboxrule=\mgllinethickness%
+  \@ifundefined{MGL@script@name}{%
+    \edef\MGL@script@name{\mglverbatimname}%
+    \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+  }{%
+    \item[\MGL@line@sep]\fbox{%
+      \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}%
+    }\hskip\labelsep\MGL@line@sep\par\par%
+  }%
+  \if@MGL@list@script@%
+    \refstepcounter{MGL@verb@script@no}%
+    \addcontentsline{lms}{MGL@script}{%
+      \protect\numberline{\theMGL@verb@script@no.}%
+      {\ttfamily\protect\detokenize{\MGL@script@name}}%
+    }%
+  \fi%
+  \def\verbatim@processline{%
+    \item\the\verbatim@line%
+  }%
+  \verbatim@start%
 }
+\def\endmglverbatim{%
+  \MGL@closeout\MGL@out@stream%
+  \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+  \endlist%
+}
+\expandafter\let\csname endmglverbatim*\endcsname\endmglverbatim
 
-\def\mglinclude#1{%
-  \bgroup%
-    \MGL@prepare@verb@env%
-    \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@scripts@dir#1.mgl}%
-    \MGL@rewrite@code@verb%
-  \egroup%
+\def\mglcomment{%
+  \if@MGL@comments@%
+    \list{}{}%
+    \MGL@set@verbatim@code%
+    \item\hskip-\labelsep<\MGL@dash@sep\mglcommentname\MGL@dash@sep>%
+    \def\verbatim@processline{\item\the\verbatim@line}%
+    \verbatim@start%
+  \else%
+    \@bsphack%
+    \MGL@codes%
+    \let\verbatim@startline\relax%
+    \let\verbatim@addtoline\@gobble%
+    \let\verbatim@processline\relax%
+    \let\verbatim@finish\relax%
+    \verbatim@%
+  \fi%
+}
+\def\endmglcomment{%
+  \if@MGL@comments@%
+    \item\hskip-\labelsep<\MGL@dash@sep\mglcommentname\MGL@dash@sep>%
+    \endlist%
+  \else%
+    \@esphack%
+  \fi%
 }
 
 \newcommand\mglgraphics[2][]{%
-  \MGL@setkeys{mgl@keys}{#1}%
-  \edef\MGL@this@code@label{#2}%
-  \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@this@code@label\MGL@graphics@ext}{}{%
-    \MGL@write{18}{mglconv -q \MGL@quality\space -S \MGL@scale\space -s "\MGL@dir\MGL@scripts@dir\mglcommonscript.mgl" -o "\MGL@dir\MGL@graphics@dir\MGL@this@code@label\MGL@graphics@ext" "\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl"}
+  \bgroup%
+  \define@key{MGL@keys}{path}{\def\MGL@forced@path{##1}}%
+  \MGL@setkeys{MGL@keys}{#1}%
+  \edef\MGL@script@name{#2}%
+  \IfFileExists{\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext}{}{%
+    \@ifundefined{MGL@forced@path}{%
+      \@for\MGL@temp@a:=\MGL@paths\do{%
+        \IfFileExists{\MGL@temp@a\MGL@script@name.mgl}{%
+          \edef\MGL@temp@b{\MGL@temp@a}%
+        }{}%
+      }%
+    }{%
+      \IfFileExists{\MGL@forced@path\MGL@script@name.mgl}{%
+        \edef\MGL@temp@b{\MGL@forced@path}%
+      }{}%
+    }%
+    \@ifundefined{MGL@temp@b}{%
+      \PackageWarning{mgltex}{%
+        MGL script "\MGL@script@name.mgl" not found%
+      }%
+    }{%
+      \MGL@write{18}{%
+        mglconv -q \MGL@quality\space -S \MGL@scale\space%
+        -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+        -o "\MGL@dir\MGL@graphics@dir\MGL@script@name\MGL@graph@ext"\space%
+        "\MGL@temp@b\MGL@script@name.mgl"%
+      }%
+    }%
   }%
-  \MGL@write\@auxout{\string\MGL@unchanged{\MGL@this@code@label}}%
-  \MGL@include@graphics%
+  \MGL@includegraphics%
+  \egroup%
 }
 
-\def\mglcommonscript{common_script}
-\def\mglcommon{%
-  \MGL@test@code@label{\mglcommonscript}%
-  \MGL@codes%
-  \MGL@def@end@env@cmd{mglcommon}%
-  \MGL@set@write@out%
-  \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl}%
-  \MGL@write\MGL@out@stream{\MGL@signature}%
-  \MGL@write\MGL@out@stream{quality \MGL@quality}%
-  \MGL@write\MGL@out@stream{setsize \MGL@width\space\MGL@height}%
-  \expandafter\MGL@ignore@line%
-}
-\@onlypreamble\mglcommon
-\def\endmglcommon{%
-  \MGL@closeout\MGL@out@stream%
+\def\mglinclude{\@MGL@list@script@true\mglinclude@}
+\@namedef{mglinclude*}{\@MGL@list@script@false\mglinclude@}
+\newcommand\mglinclude@[2][]{%
   \bgroup%
-    \endlinechar=-1\relax%
-    \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@scripts@dir\MGL@this@code@label.mgl}%
-    \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-    \MGL@rewrite@code{\MGL@out@stream}%
-    \MGL@closein{\MGL@in@stream}%
-    \MGL@closeout{\MGL@out@stream}%
+  \@MGL@lineno@true%
+  \define@key{MGL@verb@keys}{path}{\def\MGL@forced@path{##1}}%
+  \setkeys{MGL@verb@keys}{#1}%
+  \edef\MGL@script@name{#2}%
+  \@ifundefined{MGL@forced@path}{%
+    \@for\MGL@temp@b:=\MGL@paths\do{%
+      \IfFileExists{\MGL@temp@b\MGL@script@name.mgl}{%
+        \edef\MGL@temp@a{\MGL@temp@b}%
+      }{}%
+    }%
+  }{%
+    \IfFileExists{\MGL@script@name.mgl}{%
+      \edef\MGL@temp@a{\MGL@forced@path}%
+    }{}%
+  }%
+  \@ifundefined{MGL@temp@a}{%
+    \PackageWarning{mgltex}{%
+      MGL script "\MGL@forced@path\MGL@script@name.mgl" not found%
+    }%
+    \center%
+      \fbox{%
+        \centering%
+        \bfseries\Huge%
+        \begin{tabular}{c}MGL\\script\\not\\found\end{tabular}%
+      }%
+    \endcenter%
+  }{%
+    \mglinclude@@%
+  }%
   \egroup%
 }
-
-\def\MGL@setups@written{}
-\def\mglsetup#1{%
-  \MGL@test@code@label{#1}%
-  \xdef\MGL@setups@written{\MGL@setups@written\MGL@this@code@label,}
-  \g@addto@macro{\MGL@funcs}{\MGL@rewrite@func{#1}}%
-  \MGL@codes%
-  \MGL@def@end@env@cmd{mglsetup}%
-  \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-  \MGL@write\MGL@out@stream{func #1}%
-  \MGL@set@write@out%
-  \expandafter\MGL@ignore@line%
-}
-\def\endmglsetup{%
-  \MGL@write\MGL@out@stream{return}%
-  \MGL@write\MGL@out@stream{}%
-  \MGL@closeout{\MGL@out@stream}%
-}
-
-\def\mglplot@call@setup{%
-  \ifx\mglplot@setup\@empty\else%
-    \def\MGL@future@action{%
-      \PackageWarning{mgltex}{No "\mglplot@setup" setup for \string\mglplot}%
-    }%
-    \@for\MGL@setup:=\MGL@setups@written\do{%
-      \ifx\MGL@setup\mglplot@setup%
-        \MGL@write\MGL@script{call '\mglplot@setup'}%
-        \MGL@write\MGL@out@stream{\mglplot@setup}%
-        \def\MGL@future@action{}%
-      \fi%
+\def\mglinclude@@{%
+  \@addtofilelist{\MGL@script@name.mgl}%
+  \if@MGL@list@script@%
+    \refstepcounter{MGL@verb@script@no}%
+    \addcontentsline{lms}{MGL@script}{%
+      \protect\numberline{\theMGL@verb@script@no.}%
+      {\ttfamily\protect\detokenize{\MGL@script@name.mgl}}%
     }%
   \fi%
+  \if@MGL@lineno@%
+    \list{\mgllinenostyle\arabic{MGL@line@no}.}{\usecounter{MGL@line@no}}%
+  \else%
+    \list{}{}%
+  \fi%
+  \MGL@set@verbatim@code%
+  \fboxrule=\mgllinethickness%
+  \item[\MGL@line@sep]\fbox{%
+    \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL@script@name.mgl}%
+  }\hskip\labelsep\MGL@line@sep\par\par%
+  \def\verbatim@processline{%
+    \item\the\verbatim@line%
+  }%
+  \immediate\openin\MGL@in@stream="\MGL@temp@a\MGL@script@name.mgl"%
+  \mglinclude@@@%
+}
+\def\mglinclude@@@{%
+  \immediate\read\MGL@in@stream to \MGL@temp@b%
+  \ifeof\MGL@in@stream%
+    \immediate\closein\MGL@in@stream%
+    \item[\MGL@line@sep]\hskip-\labelsep\MGL@line@sep%
+    \endlist%
+  \else%
+    \verbatim@startline%
+    \expandafter\verbatim@addtoline\expandafter{\MGL@temp@b}%
+    \verbatim@processline%
+    \expandafter\mglinclude@@@%
+  \fi%
+}
+\def\mglname#1{\edef\MGL@main@script@name{#1}}
+\AtBeginDocument{%
+  \def\mglname#1{%
+    \@bsphack%
+    \MGL@write@funcs%
+    \immediate\closeout{\MGL@main@stream}%
+    \MGL@write{18}{%
+      mglconv -q \MGL@quality\space -S \MGL@scale\space%
+      -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+      -n "\MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl"%
+    }%
+    \edef\MGL@main@script@name{#1}%
+    \bgroup\MGL@set@script@name{\MGL@main@script@name}\egroup%
+    \MGL@openout\MGL@main@stream{%
+      \MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl%
+    }%
+    \@esphack%
+  }%
 }
 
-\newcommand\mglplot[2][]{%
-  \bgroup%
-    \def\mglplot@setup{}%
-    \MGL@setkeys{mglplot@keys}{#1}%
-    \MGL@create@code@label%
-    \@ifundefined{MGL@@@\MGL@this@code@label}{%
-      \MGL@write\MGL@script{quality \MGL@quality}%
-      \MGL@write\MGL@script{setsize \MGL@width\space\MGL@height}%
-      \MGL@openout{\MGL@out@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-      \mglplot@call@setup%
-      \MGL@write\MGL@script{#2}%
-      \MGL@write\MGL@out@stream{#2}%
-      \MGL@closeout{\MGL@out@stream}%
-      \MGL@write\MGL@script{write '\MGL@dir\MGL@graphics@dir\MGL@this@code@label\MGL@graphics@ext'}%
-      \MGL@write\MGL@script{reset}%
-      \MGL@write\MGL@script{}%
-      \MGL@write\@auxout{\string\MGL@unchanged{\MGL@this@code@label}}%
-    }{%
-      \endlinechar=-1\relax%
-      \MGL@openin{\MGL@in@stream}{\MGL@dir\MGL@backups@dir\MGL@this@code@label.mgl.backup}%
-      \ifx\mglplot@setup\@empty\else%
-        \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-        \ifx\MGL@this@code@line\mglplot@setup%
-          \MGL@read\MGL@in@stream{\MGL@this@code@line}%
-          \edef\MGL@this@line{#2}%
-          \ifx\MGL@this@code@line\MGL@this@line%
-            \MGL@write\@auxout{\string\MGL@unchanged{\MGL@this@code@label}}%
-          \fi%
-        \fi%
+\ifx\l@chapter\@undefined%
+  \ifx\l@section\@undefined%
+    \def\listofmglscripts{%
+      \@startsection{MGL@list}%
+      {1}{0em}{-3.5ex plus -1ex minus -0.2ex}%
+      {2.5ex plus 0.2ex}%
+      {\centering\normalfont\bfseries\large}*%
+      {\listofmglscriptsname}%
+      \@mkboth{%
+        \MakeUpperCase\listofmglscriptsname%
+      }{%
+        \MakeUppercase\listofmglscriptsname%
+      }%
+      \@starttoc{lms}%
+    }%
+    \newcommand*\l@MGL@list[2]{%
+      \ifnum \c@tocdepth >\z@
+        \addpenalty\@secpenalty
+        \addvspace{1.0em \@plus\p@}%
+        \setlength\@tempdima{1.5em}%
+        \begingroup
+          \parindent \z@ \rightskip \@pnumwidth
+          \parfillskip -\@pnumwidth
+          \leavevmode \bfseries
+          \advance\leftskip\@tempdima
+          \hskip -\leftskip
+          #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
+        \endgroup
       \fi%
-      \MGL@closein{\MGL@in@stream}
     }%
-  \egroup%
-}%
-
-\def\mglcomment{%
-  \MGL@codes%
-  \verbatim@font%
-  \small%
-  \mgl@comment%
-}
-\begingroup%
-  \catcode`|=0\catcode`[= 1\catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\\=12%
-  |gdef|mgl@comment#1\end{mglcomment}[%
-    |if@MGL@comments@%
-      |begin[center]%
-        <------------------ MGL comment ------------------>%
-        #1%
-        <------------------ MGL comment ------------------>%
-      |end[center]%
-    |fi%
-    |end[mglcomment]]%
-|endgroup%
-\def\endmglcomment{}
-
-\def\MGL@signature{}
-\begingroup%
-  \catcode`#=12\relax%
-  \gdef\MGL@comm@sym{#}
-\endgroup
-\def\mglsignature{%
-  \MGL@verb@codes%
-  \obeyspaces%
-  \MGL@def@end@env@cmd{mglsignature}%
-  \def\MGL@write@code@action##1{\g@addto@macro{\MGL@signature}{\MGL@comm@sym\space##1^^J}}%
-  \catcode`|=0\relax\catcode`[=1\relax\catcode`]=2\relax%
-  \expandafter\MGL@ignore@line%
-}
-\def\endmglsignature{}
-
-\def\MGL@quality{2}
-\def\mglquality#1{%
-  \def\MGL@quality{#1}%
-  \ifcase#1
-    \PackageInfo{mgltex}{Quality 0: No face drawing (fastest)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 1: No color interpolation (fast)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 2: High quality (normal)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 3: High quality with 3d primitives (not implemented yet)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 4: No face drawing, direct bitmap drawing (low memory usage)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 5: No color interpolation, direct bitmap drawing (low memory usage)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 6: High quality, direct bitmap drawing (low memory usage)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 7: High quality with 3d primitives, direct bitmap drawing (not implemented yet)}%
-  \or%
-    \PackageInfo{mgltex}{Quality 8: Draw dots instead of primitives (extremely fast)}%
   \else%
-    \PackageWarning{mgltex}{Quality #1 not available. Using default (2)}%
+    \def\listofmglscripts{%
+      \section*{\listofmglscriptsname}%
+      \@mkboth{%
+        \MakeUppercase\listofmglscriptsname%
+      }{%
+        \MakeUppercase\listofmglscriptsname%
+      }%
+      \@starttoc{lms}%
+    }%
   \fi%
-}
-\@onlypreamble\mglquality
+\else%
+  \def\listofmglscripts{%
+    \chapter*{\listofmglscriptsname}%
+    \@mkboth{%
+      \MakeUpperCase\listofmglscriptsname%
+    }{%
+      \MakeUppercase\listofmglscriptsname%
+    }%
+    \@starttoc{lms}%
+  }%
+\fi%
 
-\def\MGL@width{640}
-\def\MGL@height{480}
-\def\mglsetsize#1#2{%
-  \def\MGL@width{#1}%
-  \def\MGL@height{#2}%
-}
-\@onlypreamble\mglsetsize
+\def\mglTeX{mgl\TeX}
 
-\def\mgltexon{
-  \def\MGL@openout##1##2{%
-    \immediate\openout##1="##2"%
-  }%
-  \def\MGL@write##1##2{%
-    \immediate\write##1{##2}%
-  }%
-  \def\MGL@graph@not@found@text{MGL\\image\\not\\found}%
-  \def\MGL@graph@not@found@message{MGL image "\MGL@this@code@label" not found}%
-}
-\def\mgltexoff{%
-  \def\MGL@openout##1##2{}%
-  \def\MGL@write##1##2{}%
-  \def\MGL@graph@not@found@text{\mglTeX\\is off,\\no image\\generated}%
-  \def\MGL@graph@not@found@message{mglTeX is off, MGL image "\MGL@this@code@label" not generated}%
-}
+\def\mglTeXwVer{\mglTeX~v4.0}
+
+\def\mgldir#1{\def\MGL@dir{#1}}\@onlypreamble\mgldir
+\def\mglscriptsdir#1{\def\MGL@scripts@dir{#1}}\@onlypreamble\mglscriptsdir
+\def\mglgraphicsdir#1{\def\MGL@graphics@dir{#1}}\@onlypreamble\mglgraphicsdir
+\def\mglbackupsdir#1{\def\MGL@backups@dir{#1}}\@onlypreamble\mglbackupsdir
+\def\mglpaths#1{\g@addto@macro\MGL@paths{,#1}}
 
-\def\mglcomments{
-  \@MGL@comments@true%
+\def\mglcommonscriptname{MGL_common_script}
+\def\mglcommentname{MGL commentary}
+\def\listofmglscriptsname{List of MGL scripts}
+\def\mglverbatimname{(Unnamed MGL verbatim script)}
+\def\mgllinenostyle{\footnotesize}
+\newdimen\mgldashwidth\mgldashwidth=0.75em
+\newdimen\mgllinethickness\mgllinethickness=0.25ex
+\newdimen\mglbreakindent\mglbreakindent=1em
+
+\AtBeginDocument{%
+  \bgroup\MGL@set@script@name{\MGL@main@script@name}\egroup%
+  \immediate\openout\MGL@main@stream=%
+  \MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl%
 }
-\def\mglnocomments{%
-  \@MGL@comments@false%
+\AtEndDocument{%
+  \MGL@write@funcs%
+  \immediate\closeout\MGL@main@stream%
+  \MGL@write{18}{%
+    mglconv -q \MGL@quality\space -S \MGL@scale\space%
+    -s "\MGL@dir\MGL@scripts@dir\mglcommonscriptname.mgl"\space%
+    -n "\MGL@dir\MGL@scripts@dir\MGL@main@script@name.mgl"%
+  }%
 }
-
-\def\mglTeX{mgl\TeX}
\ No newline at end of file
+\endinput
+%%
+%% End of file `mgltex.sty'.
index 0fe9dc2a39575797138fe5169d7fe7a8a65936d1..a44dedbf564a87c384a7d0d372ec185d3de1adb3 100644 (file)
@@ -15,9 +15,9 @@
   define gravity 9.81
 \end{mglcommon}
 
-\begin{mglsignature}
-  This scripts was generated on date |today.
-\end{mglsignature}
+%\begin{mglsignature}
+%  This scripts was generated on date |today.
+%\end{mglsignature}
 
 
 \begin{document}
index 504e7a8c11ba9fef6994aa2c868ef2f6b3cf5e76..a16a01c97b7e7f26adc6d78300084a19b9a0bd73 100644 (file)
@@ -23,6 +23,9 @@ ${MathGL_BINARY_DIR}/include/mgl2/dllexport.h cont.hpp
 )
 
 add_definitions(-DMGL_SRC)
+if(MGL_HAVE_GSL2)
+       add_definitions(-DMGL_HAVE_GSL2)
+endif(MGL_HAVE_GSL2)
 
 if(MGL_HAVE_PNG)
        set(prc_src prc/PRCbitStream.cc prc/PRCdouble.cc prc/oPRCFile.cc prc/writePRC.cc prc.cpp )
@@ -40,20 +43,9 @@ endif(MGL_HAVE_OPENGL)
 
 include(GenerateExportHeader)
 add_compiler_export_flags()
-add_library(mgl SHARED ${mgl_src} ${mgl_hdr})
-add_library(mgl-static STATIC ${mgl_src} ${mgl_hdr})
-set_target_properties(mgl PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-set_target_properties(mgl-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-target_compile_definitions(mgl-static PUBLIC MGL_STATIC_DEFINE)
+mgl_add_lib(mgl ${mgl_src} ${mgl_hdr})
 generate_export_header(mgl EXPORT_FILE_NAME ../include/mgl2/dllexport.h)
 
-if(enable-mgl2)
-       set_target_properties(mgl PROPERTIES OUTPUT_NAME "mgl2")
-       set_target_properties(mgl-static PROPERTIES OUTPUT_NAME "mgl2")
-else(enable-mgl2)
-       set_target_properties(mgl-static PROPERTIES OUTPUT_NAME "mgl")
-endif(enable-mgl2)
-
 # if(MGL_HAVE_LTDL)
 #      target_link_libraries(mgl ${LTDL_LIB})
 #      include_directories(${LTDL_INCLUDE_DIR})
@@ -113,44 +105,14 @@ if(MGL_HAVE_ZLIB)
        include_directories(${ZLIB_INCLUDE_DIR})
 endif(MGL_HAVE_ZLIB)
 
-if(MGL_HAVE_MPI)
-       add_library(mgl-mpi SHARED mpi.cpp ../include/mgl2/mpi.h)
-       add_library(mgl-mpi-static STATIC mpi.cpp ../include/mgl2/mpi.h)
-       set_target_properties(mgl-mpi PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       set_target_properties(mgl-mpi PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-       set_target_properties(mgl-mpi-static PROPERTIES OUTPUT_NAME "mgl-mpi")
-       set_target_properties(mgl-mpi-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       target_compile_definitions(mgl-mpi-static PUBLIC MGL_STATIC_DEFINE)
-
-       if(enable-mgl2)
-               set_target_properties(mgl-mpi PROPERTIES OUTPUT_NAME "mgl2-mpi")
-               set_target_properties(mgl-mpi-static PROPERTIES OUTPUT_NAME "mgl2-mpi")
-       else(enable-mgl2)
-               set_target_properties(mgl-mpi-static PROPERTIES OUTPUT_NAME "mgl-mpi")
-       endif(enable-mgl2)
-
-       target_link_libraries(mgl-mpi ${MPI_LIBRARIES} )
-#      include_directories(${MPI_C_INCLUDE_PATH})
-       include_directories(${MPI_CXX_INCLUDE_PATH})
-
-       set_target_properties(mgl-mpi PROPERTIES SOVERSION ${MathGL_SOVERSION})
-       install(
-               TARGETS mgl-mpi mgl-mpi-static
-               RUNTIME DESTINATION bin
-               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-       )
-endif(MGL_HAVE_MPI)
-
 if(M_LIB)
        target_link_libraries(mgl ${M_LIB})
 endif(M_LIB)
 
-set_target_properties(mgl PROPERTIES SOVERSION ${MathGL_SOVERSION})
-install(
-       TARGETS mgl mgl-static
-       RUNTIME DESTINATION bin
-       ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-       LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-)
+if(MGL_HAVE_MPI)
+       mgl_add_lib(mpi mpi.cpp ../include/mgl2/mpi.h)
+       target_link_libraries(mgl-mpi ${MPI_LIBRARIES} )
+       target_include_directories(mgl-mpi SYSTEM PUBLIC ${MPI_CXX_INCLUDE_PATH})
+endif(MGL_HAVE_MPI)
+
 install(FILES ${MathGL_BINARY_DIR}/include/mgl2/dllexport.h DESTINATION ${MGL_INCLUDE_PATH})
index 9537f09a9ca3bef1d9a1ac575309aa434835c83f..c0f64d7d258816708fc07953d45dce25095bb015 100644 (file)
@@ -75,12 +75,12 @@ MGL_EXPORT char *mgl_fgetstr(FILE *fp)
 void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...)
 {
        if(!str || !str[0])     return;
-       long len=strlen(str);
+       const size_t len=strlen(str);
        char *s, *t;
        va_list lst;
        va_start(lst,str);
        t = mgl_fgetstr(fp);
-       for(long i=0;i<len;i++)
+       for(size_t i=0;i<len;i++)
        {
                if(str[i]=='%')
                {
index 0bdacba278912d2521cc0e455f1cca07c1499151..36164ee3a182ccbb382ad46160cbf81f82b22d66 100644 (file)
@@ -306,8 +306,7 @@ void mglCanvas::AdjustTicks(mglAxis &aa, bool ff)
        {
                d /= -aa.d;
                long n = floor(log10(d));
-               int k = mgl_int(d*pow(10.,-n));
-               aa.dv = pow(10.,n)*k;
+               aa.dv = pow(10.,n)*mgl_int(d*pow(10.,-n));
                aa.o=0; aa.ds = pow(10.,n);
        }
        LabelTicks(aa);
@@ -553,7 +552,7 @@ void mglCanvas::DrawAxis(mglAxis &aa, bool text, char arr,const char *stl,mreal
                        for(long j=2;j<10 && v*j<aa.v1;j++)     tick_draw(o+d*(v*j),da,db,1);
                if(dif_color)   SetPenPal(TickStl);
        }
-       if(aa.ds>0 && !get(MGL_NOSUBTICKS))
+       if(aa.ds>0 && !get(MGL_NOSUBTICKS) && (fabs(aa.v1)>1e-150 || fabs(aa.v2)>1e-150))
        {
                if(aa.v2>aa.v1) v0 = v0 - aa.ds*floor((v0-aa.v1)/aa.ds+1e-3);
                else                    v0 = v0 - aa.ds*floor((v0-aa.v2)/aa.ds+1e-3);
@@ -633,7 +632,7 @@ void mglCanvas::DrawLabels(mglAxis &aa, bool inv, const mglMatrix *M)
                if(ux<0 || (ux==0 && uy<0))     {       ux=-ux; uy=-uy; pp.w=-pp.w;     }
                pp.u = ux;      pp.v = uy;
                mreal pu = p.x*ux+p.y*uy, pv = p.y*ux-p.x*uy; /*, su = ps.x*ux+ps.y*uy;*/
-               if(aa.ch!='c')  up[i] = ((pv>0) ^ inv) ? 'T':'t'; 
+               if(aa.ch!='c')  up[i] = ((pv>0) ^ inv) ? 'T':'t';
                else            up[i]=(aa.ns==0 || aa.ns==3)?'t':'T';
                int t=0;
                if(algn)
index a502780a9c248b13a8c72897624f5dacaf4e66e6..bd605a32a91409ef337ed0c4493b6d4c77e22921 100644 (file)
@@ -187,11 +187,11 @@ const char *mglWarn[mglWarnEnd] = {"data dimension(s) is incompatible",   //mglWar
                                                                "axis ranges are incompatible",                 //mglWarnTern\r
                                                                "pointer is NULL",                                              //mglWarnNull\r
                                                                "not enough space for plot",                    //mglWarnSpc\r
-                                                               "There are wrong argument(s) in script",//mglScrArg\r
-                                                               "There are wrong command in script",    //mglScrCmd\r
-                                                               "There are too long string in script",  //mglScrLong\r
-                                                               "There are unbalanced ' in script",             //mglScrStr\r
-                                                               "There are changing temporary data in script"}; //mglScrTemp\r
+                                                               "There is wrong argument(s) in script", //mglScrArg\r
+                                                               "There is wrong command(s) in script",  //mglScrCmd\r
+                                                               "There is too long string(s) in script",        //mglScrLong\r
+                                                               "There is unbalanced ' in script",              //mglScrStr\r
+                                                               "There is changing temporary data in script"};  //mglScrTemp\r
 //-----------------------------------------------------------------------------\r
 extern bool mglPrintWarn;\r
 void mglBase::SetWarn(int code, const char *who)\r
@@ -251,6 +251,17 @@ long mglBase::AddGlyph(int s, long j)
 //-----------------------------------------------------------------------------\r
 //             Add points to the buffer\r
 //-----------------------------------------------------------------------------\r
+void inline mgl_put_inbox(mreal a1, mreal a2, mreal &a)\r
+{\r
+       if(a1<a2)       {       if(a<a1)        a=a1;   if(a>a2)        a=a2;   }\r
+       else            {       if(a<a2)        a=a2;   if(a>a1)        a=a1;   }\r
+}\r
+void MGL_NO_EXPORT mgl_coor_box(HMGL gr, mglPoint &p)\r
+{\r
+       mgl_put_inbox(gr->Min.x, gr->Max.x, p.x);\r
+       mgl_put_inbox(gr->Min.y, gr->Max.y, p.y);\r
+       mgl_put_inbox(gr->Min.z, gr->Max.z, p.z);\r
+}\r
 long mglBase::AddPnt(const mglMatrix *mat, mglPoint p, mreal c, mglPoint n, mreal a, int scl)\r
 {\r
        // scl=0 -- no scaling\r
@@ -258,9 +269,14 @@ long mglBase::AddPnt(const mglMatrix *mat, mglPoint p, mreal c, mglPoint n, mrea
        // scl&2 -- disable NAN at scaling\r
        // scl&4 -- disable NAN for normales if no light\r
        // scl&8 -- bypass palette for enabling alpha\r
+       // scl&16 -- put points inside axis range\r
        if(mgl_isnan(c) || mgl_isnan(a))        return -1;\r
        bool norefr = mgl_isnan(n.x) && mgl_isnan(n.y) && !mgl_isnan(n.z);\r
-       if(scl>0)       ScalePoint(mat,p,n,!(scl&2));\r
+       if(scl>0)\r
+       {\r
+               if(scl&16)      mgl_coor_box(this, p);\r
+               ScalePoint(mat,p,n,!(scl&2));\r
+       }\r
        if(mgl_isnan(p.x))      return -1;\r
        a = (a>=0 && a<=1) ? a : AlphaDef;\r
        c = (c>=0) ? c:CDef;\r
@@ -442,12 +458,36 @@ bool mglBase::ScalePoint(const mglMatrix *, mglPoint &p, mglPoint &n, bool use_n
        }\r
        else\r
        {\r
-               if(x1<Min.x)    {x=Min.x;       n.Set(1,0,0);}\r
-               if(x2>Max.x)    {x=Max.x;       n.Set(1,0,0);}\r
-               if(y1<Min.y)    {y=Min.y;       n.Set(0,1,0);}\r
-               if(y2>Max.y)    {y=Max.y;       n.Set(0,1,0);}\r
-               if(z1<Min.z)    {z=Min.z;       n.Set(0,0,1);}\r
-               if(z2>Max.z)    {z=Max.z;       n.Set(0,0,1);}\r
+               if(Min.x<Max.x)\r
+               {\r
+                       if(x1<Min.x)    {x=Min.x;       n.Set(1,0,0);}\r
+                       if(x2>Max.x)    {x=Max.x;       n.Set(1,0,0);}\r
+               }\r
+               else\r
+               {\r
+                       if(x1<Max.x)    {x=Max.x;       n.Set(1,0,0);}\r
+                       if(x2>Min.x)    {x=Min.x;       n.Set(1,0,0);}\r
+               }\r
+               if(Min.y<Max.y)\r
+               {\r
+                       if(y1<Min.y)    {y=Min.y;       n.Set(0,1,0);}\r
+                       if(y2>Max.y)    {y=Max.y;       n.Set(0,1,0);}\r
+               }\r
+               else\r
+               {\r
+                       if(y1<Max.y)    {y=Max.y;       n.Set(0,1,0);}\r
+                       if(y2>Min.y)    {y=Min.y;       n.Set(0,1,0);}\r
+               }\r
+               if(Min.z<Max.z)\r
+               {\r
+                       if(z1<Min.z)    {z=Min.z;       n.Set(0,0,1);}\r
+                       if(z2>Max.z)    {z=Max.z;       n.Set(0,0,1);}\r
+               }\r
+               else\r
+               {\r
+                       if(z1<Max.z)    {z=Max.z;       n.Set(0,0,1);}\r
+                       if(z2>Min.z)    {z=Min.z;       n.Set(0,0,1);}\r
+               }\r
        }\r
 \r
        x1=x;   y1=y;   z1=z;\r
@@ -494,7 +534,7 @@ bool mglBase::ScalePoint(const mglMatrix *, mglPoint &p, mglPoint &n, bool use_n
 //-----------------------------------------------------------------------------\r
 void mglScaleAxis(mreal &v1, mreal &v2, mreal &v0, mreal x1, mreal x2)\r
 {\r
-       if(x1==x2 || v1==v2)    return;\r
+       if(!mgl_isrange(x1,x2) || !mgl_isrange(v1,v2))  return;\r
        mreal dv,d0;    x2-=1;\r
        if(v1*v2>0 && (v2/v1>=100 || v2/v1<=0.01))      // log scale\r
        {\r
@@ -523,11 +563,11 @@ void mglBase::SetOrigin(mreal x0, mreal y0, mreal z0, mreal c0)
 //-----------------------------------------------------------------------------\r
 void mglBase::SetRanges(mglPoint m1, mglPoint m2)\r
 {\r
-       if(m1.x!=m2.x)  {       Min.x=m1.x;     Max.x=m2.x;     }\r
-       if(m1.y!=m2.y)  {       Min.y=m1.y;     Max.y=m2.y;     }\r
-       if(m1.z!=m2.z)  {       Min.z=m1.z;     Max.z=m2.z;     }\r
-       if(m1.c!=m2.c)  {       Min.c=m1.c;     Max.c=m2.c;     }\r
-       else                    {       Min.c=Min.z;Max.c=Max.z;}\r
+       if(mgl_isrange(m1.x, m2.x))     {       Min.x=m1.x;     Max.x=m2.x;     }\r
+       if(mgl_isrange(m1.y, m2.y))     {       Min.y=m1.y;     Max.y=m2.y;     }\r
+       if(mgl_isrange(m1.z, m2.z))     {       Min.z=m1.z;     Max.z=m2.z;     }\r
+       if(mgl_isrange(m1.c, m2.c))     {       Min.c=m1.c;     Max.c=m2.c;     }\r
+       else    {       Min.c=Min.z;Max.c=Max.z;}\r
 \r
        if(Org.x<Min.x && mgl_isnum(Org.x))     Org.x = Min.x;\r
        if(Org.x>Max.x && mgl_isnum(Org.x))     Org.x = Max.x;\r
@@ -557,7 +597,7 @@ void mglBase::CRange(HCDT a,bool add, mreal fact)
 }\r
 void mglBase::CRange(mreal v1,mreal v2,bool add)\r
 {\r
-       if(v1==v2 && !add)      return;\r
+       if(!mgl_isrange(v1,v2) && !add) return;\r
        if(!add)\r
        {\r
                if(mgl_isnum(v1))       Min.c = v1;\r
@@ -592,7 +632,7 @@ void mglBase::XRange(HCDT a,bool add,mreal fact)
 }\r
 void mglBase::XRange(mreal v1,mreal v2,bool add)\r
 {\r
-       if(v1==v2 && !add)      return;\r
+       if(!mgl_isrange(v1,v2) && !add) return;\r
        if(!add)\r
        {\r
                if(mgl_isnum(v1))       Min.x = v1;\r
@@ -627,7 +667,7 @@ void mglBase::YRange(HCDT a,bool add,mreal fact)
 }\r
 void mglBase::YRange(mreal v1,mreal v2,bool add)\r
 {\r
-       if(v1==v2 && !add)      return;\r
+       if(!mgl_isrange(v1,v2) && !add) return;\r
        if(!add)\r
        {\r
                if(mgl_isnum(v1))       Min.y = v1;\r
@@ -663,7 +703,7 @@ void mglBase::ZRange(HCDT a,bool add,mreal fact)
 }\r
 void mglBase::ZRange(mreal v1,mreal v2,bool add)\r
 {\r
-       if(v1==v2 && !add)      return;\r
+       if(!mgl_isrange(v1,v2) && !add) return;\r
        if(!add)\r
        {\r
                if(mgl_isnum(v1))       Min.z = v1;\r
@@ -692,10 +732,10 @@ void mglBase::ZRange(mreal v1,mreal v2,bool add)
 //-----------------------------------------------------------------------------\r
 void mglBase::SetAutoRanges(mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2, mreal c1, mreal c2)\r
 {\r
-       if(x1!=x2)      {       Min.x = x1;     Max.x = x2;     }\r
-       if(y1!=y2)      {       Min.y = y1;     Max.y = y2;     }\r
-       if(z1!=z2)      {       Min.z = z1;     Max.z = z2;     }\r
-       if(c1!=c2)      {       Min.c = c1;     Max.c = c2;     }\r
+       if(mgl_isrange(x1,x2))  {       Min.x = x1;     Max.x = x2;     }\r
+       if(mgl_isrange(y1,y2))  {       Min.y = y1;     Max.y = y2;     }\r
+       if(mgl_isrange(z1,z2))  {       Min.z = z1;     Max.z = z2;     }\r
+       if(mgl_isrange(c1,c2))  {       Min.c = c1;     Max.c = c2;     }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglBase::Ternary(int t)\r
index c016c2d749b7203b5954f81e8f3fdb79e2a40f64..ba7dfd2d738f633faff585876a7e93b1877b48cb 100644 (file)
@@ -223,7 +223,7 @@ int Height;                 ///< Height of the image
 int Depth;                     ///< Depth of the image\r
 int CurFrameId;                ///< Number of automaticle created frames\r
 GifFileType *gif;*/\r
-       SetDrawReg(1,1,0);              Perspective(0);\r
+       SetDrawReg(1,1,0);              Perspective(0); SetPenDelta(1);\r
        memcpy(mgl_mask_val, mgl_mask_def, 16*sizeof(uint64_t));        // should be > 16*8\r
        ax.Clear();     ay.Clear();     az.Clear();     ac.Clear();\r
        mgl_clear_fft();                DefMaskAn=0;    ResetMask();\r
@@ -497,8 +497,7 @@ pthread_mutex_lock(&mutexPtx);
                        mglColor mc = Txt[long(col1)].GetC(col1);\r
                        mglPrim a(6);   a.n1 = p;\r
                        a.n2 = int(255*mc.r) + 256*(int(255*mc.g) + 256*int(255*mc.b));\r
-                       mglText txt(text,font);\r
-                       a.n3 = Ptx.size();      Ptx.push_back(txt);\r
+                       a.n3 = Ptx.size();      Ptx.push_back(mglText(text,font));\r
                        a.s = size;     a.w = shift;    a.p=ftet;\r
                        add_prim(a);\r
                }\r
@@ -530,6 +529,7 @@ pthread_mutex_lock(&mutexPtx);
                        pt.x=pt.xx=pp.x;        pt.y=pt.yy=pp.y;\r
 #pragma omp critical(pnt)\r
                        {k4=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);}\r
+                       PDef = 0xffff;  // reset to solid line\r
                        line_plot(k1,k2);       line_plot(k1,k3);\r
                        line_plot(k4,k2);       line_plot(k4,k3);\r
                        mreal bl = AddTexture('w');\r
@@ -831,15 +831,18 @@ std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt)
 \r
        // clear exp format\r
        int st = se[0]=='-'?1:0;\r
-       if(plus || se[3+st+dig]=='-')   // first remove zeros after 'e'\r
+       if(strcmp(sf,"nan"))\r
        {\r
-               for(i=(dig>0?4:3)+st+dig;i<le && se[i]=='0';i++);\r
-               memmove(se+(dig>0?4:3)+st+dig,se+i,le-i+1);\r
-       }\r
-       else\r
-       {\r
-               for(i=(dig>0?3:2)+st+dig;i<le && (se[i]=='0' || se[i]=='+');i++);\r
-               memmove(se+(dig>0?3:2)+st+dig,se+i,le-i+1);\r
+               if(plus || se[3+st+dig]=='-')   // first remove zeros after 'e'\r
+               {\r
+                       for(i=(dig>0?4:3)+st+dig;i<le && se[i]=='0';i++);\r
+                       memmove(se+(dig>0?4:3)+st+dig,se+i,le-i+1);\r
+               }\r
+               else\r
+               {\r
+                       for(i=(dig>0?3:2)+st+dig;i<le && (se[i]=='0' || se[i]=='+');i++);\r
+                       memmove(se+(dig>0?3:2)+st+dig,se+i,le-i+1);\r
+               }\r
        }\r
        le=strlen(se);\r
        // don't allow '+' at the end\r
index 76f84487520ffa71edb484d0cb6509f28a0ee4cf..f8b3af62e9e03cca8939b3a706b3aed2f844facd 100644 (file)
@@ -483,3 +483,7 @@ void MGL_EXPORT mgl_rasterize(HMGL gr)
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Rasterize(); }\r
 void MGL_EXPORT mgl_rasterize_(uintptr_t *gr)  {       _GR_->Rasterize();      }\r
 //-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pen_delta(HMGL gr, double d)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetPenDelta(d);      }\r
+void MGL_EXPORT mgl_pen_delta_(uintptr_t *gr, double *d)       {       _GR_->SetPenDelta(*d);  }\r
+//-----------------------------------------------------------------------------\r
index 7967e67fc0a016bbfb2e750d480924abb77636f3..73dabab29380249a4d15f965b1486fbf9cf2ebc1 100644 (file)
@@ -22,6 +22,9 @@
 #include "mgl2/thread.h"\r
 \r
 #include "interp.hpp"\r
+#define mgl2   mreal(2)\r
+#define mgl3   mreal(3)\r
+#define mgl4   mreal(4)\r
 \r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mglStartThreadC(void *(*func)(void *), void (*post)(mglThreadC *,dual *), long n,\r
index 5ddb46280a7001ec57d34707ed6ef475a84f63ea..a1dee5d99bd546ff467fb55ad2c34cda0a009160 100644 (file)
@@ -236,41 +236,49 @@ void MGL_EXPORT mgl_datac_set_id_(uintptr_t *d, const char *eq,int l)
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
        mgl_datac_set_id(_DC_, s);      delete []s;     }\r
 //-----------------------------------------------------------------------------\r
-void MGL_NO_EXPORT mgl_cprint(FILE *fp, mreal re, mreal im, char ch)\r
+std::string MGL_NO_EXPORT mgl_cprint(mreal re, mreal im, char ch)\r
 {\r
-       if(im>0)        fprintf(fp,"%g+i%g%c",re,im,ch);\r
-       else if(im<0)   fprintf(fp,"%g-i%g%c",re,-im,ch);\r
-       else    fprintf(fp,"%g%c",re,ch);\r
+       char buf[128];\r
+       if(im>0)        snprintf(buf,128,"%g+i%g%c",re,im,ch);\r
+       else if(im<0)   snprintf(buf,128,"%g-i%g%c",re,-im,ch);\r
+       else    snprintf(buf,128,"%g%c",re,ch);\r
+       return std::string(buf);\r
 }\r
-void MGL_EXPORT mgl_datac_save(HCDT d, const char *fname,long ns)\r
+std::string MGL_EXPORT mgl_datac_to_string(HCDT d, long ns)\r
 {\r
+       std::string out;\r
        const mglDataC *dd = dynamic_cast<const mglDataC*>(d);\r
-       if(!dd) {       mgl_data_save(d,fname,ns);      return; }\r
-       FILE *fp = fopen(fname,"w");\r
-       if(!fp) return;\r
+       if(!dd) {       return  mgl_data_to_string(d,ns);       }\r
        long nx=dd->nx, ny=dd->ny, nz=dd->nz;\r
        const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        if(ns<0 || (ns>=nz && nz>1))    for(long k=0;k<nz;k++)\r
        {       // save whole data\r
                for(long i=0;i<ny;i++)\r
                {\r
-                       for(long j=0;j<nx-1;j++)        mgl_cprint(fp, real(dd->a[j+nx*(i+ny*k)]), imag(dd->a[j+nx*(i+ny*k)]),'\t');\r
-                       mgl_cprint(fp, real(dd->a[nx-1+nx*(i+ny*k)]), imag(dd->a[nx-1+nx*(i+ny*k)]),'\n');\r
+                       for(long j=0;j<nx-1;j++)\r
+                               out+=mgl_cprint(real(dd->a[j+nx*(i+ny*k)]), imag(dd->a[j+nx*(i+ny*k)]),'\t');\r
+                       out+=mgl_cprint(real(dd->a[nx-1+nx*(i+ny*k)]), imag(dd->a[nx-1+nx*(i+ny*k)]),'\n');\r
                }\r
-               fprintf(fp,"\n");\r
+               out += "\n";\r
        }\r
        else\r
        {       // save selected slice\r
                if(nz>1)        for(long i=0;i<ny;i++)\r
                {\r
-                       for(long j=0;j<nx-1;j++)        mgl_cprint(fp, real(dd->a[j+nx*(i+ny*ns)]), imag(dd->a[j+nx*(i+ny*ns)]),'\t');\r
-                       mgl_cprint(fp, real(dd->a[nx-1+nx*(i+ny*ns)]), imag(dd->a[nx-1+nx*(i+ny*ns)]),'\n');\r
+                       for(long j=0;j<nx-1;j++)\r
+                               out+=mgl_cprint(real(dd->a[j+nx*(i+ny*ns)]), imag(dd->a[j+nx*(i+ny*ns)]),'\t');\r
+                       out+=mgl_cprint(real(dd->a[nx-1+nx*(i+ny*ns)]), imag(dd->a[nx-1+nx*(i+ny*ns)]),'\n');\r
                }\r
                else if(ns<ny)  for(long j=0;j<nx;j++)\r
-                       mgl_cprint(fp, real(dd->a[j+nx*ns]), imag(dd->a[j+nx*ns]),'\t');\r
+                       out+=mgl_cprint(real(dd->a[j+nx*ns]), imag(dd->a[j+nx*ns]),'\t');\r
        }\r
        setlocale(LC_NUMERIC, loc.c_str());\r
-       fclose(fp);\r
+       return out;\r
+}\r
+void MGL_EXPORT mgl_datac_save(HCDT d, const char *fname,long ns)\r
+{\r
+       FILE *fp = fopen(fname,"w");\r
+       if(fp)  {       fprintf(fp,"%s",mgl_datac_to_string(d,ns).c_str());     fclose(fp);     }\r
 }\r
 void MGL_EXPORT mgl_datac_save_(uintptr_t *d, const char *fname,int *ns,int l)\r
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
@@ -607,7 +615,7 @@ MGL_NO_EXPORT void *mgl_cmodify(void *par)
 void MGL_EXPORT mgl_datac_modify(HADT d, const char *eq,long dim)\r
 {\r
        long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz};\r
-       if(dim<=0)      mgl_datac_modify_vw(d,eq,0,0);  // fastes variant for whole array\r
+       if(dim<=0)      mgl_datac_modify_vw(d,eq,0,0);  // fastest variant for whole array\r
        mglFormulaC f(eq);\r
        if(nz>1)        // 3D array\r
        {\r
@@ -779,6 +787,22 @@ HMDT MGL_EXPORT mgl_datac_imag(HCDT d)
 uintptr_t MGL_EXPORT mgl_datac_imag_(uintptr_t *d)\r
 {      return uintptr_t(mgl_datac_imag(_DC_)); }\r
 //-----------------------------------------------------------------------------\r
+HMDT MGL_EXPORT mgl_datac_norm(HCDT d)\r
+{\r
+       long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();\r
+       mglData *r=new mglData(nx,ny,nz);\r
+       const mglDataC *dd = dynamic_cast<const mglDataC*>(d);\r
+       if(dd)\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx*ny*nz;i++)    r->a[i] = norm(dd->a[i]);\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx*ny*nz;i++)    r->a[i] = mgl_ipow(d->vthr(i),2);\r
+       return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_norm_(uintptr_t *d)\r
+{      return uintptr_t(mgl_datac_norm(_DC_)); }\r
+//-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_datac_abs(HCDT d)\r
 {\r
        long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();\r
@@ -871,18 +895,36 @@ int MGL_EXPORT mgl_datac_read_hdf(HADT d,const char *fname,const char *data)
        if(hd<0)        return false;\r
        hs = H5Dget_space(hd);\r
        rank = H5Sget_simple_extent_ndims(hs);\r
-       if(rank>0 && rank<=3)\r
+       if(rank>0 && rank<=4)\r
        {\r
                H5Sget_simple_extent_dims(hs,dims,0);\r
-               if(rank==2)                     {       dims[2]=dims[0];        dims[0]=dims[1]=1;      }\r
-               else if(rank==3)        {       dims[2]=dims[1];        dims[1]=dims[0];        dims[0]=1;      }\r
-//             else if(rank>3)         continue;\r
-               mgl_datac_create(d,dims[2],dims[1],dims[0]);\r
+               if(dims[rank-1]==2)\r
+               {\r
+                       if(rank==1)                     {       dims[2]=dims[0]=dims[1]=1;      }\r
+                       else if(rank==2)        {       dims[2]=dims[0];        dims[0]=dims[1]=1;      }\r
+                       else if(rank==3)        {       dims[2]=dims[1];        dims[1]=dims[0];        dims[0]=1;      }\r
+                       mgl_datac_create(d,dims[2],dims[1],dims[0]);\r
 #if MGL_USE_DOUBLE\r
-               H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);\r
+                       H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);\r
 #else\r
-               H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);\r
+                       H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);\r
 #endif\r
+               }\r
+               else if(rank<=3)\r
+               {\r
+                       if(rank==1)                     {       dims[2]=dims[0];        dims[0]=dims[1]=1;      }\r
+                       else if(rank==2)        {       dims[2]=dims[1];        dims[1]=dims[0];        dims[0]=1;      }\r
+                       mgl_datac_create(d,dims[2],dims[1],dims[0]);\r
+                       long nn = dims[2]*dims[1]*dims[0];\r
+                       mreal *a = new mreal[nn];\r
+#if MGL_USE_DOUBLE\r
+                       H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, a);\r
+#else\r
+                       H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, a);\r
+#endif\r
+                       for(long i=0;i<nn;i++)  d->a[i] = a[i];\r
+                       delete []a;\r
+               }\r
        }\r
        H5Sclose(hs);   H5Dclose(hd);   H5Fclose(hf);   return true;\r
 }\r
index 5c48f2815a105c381828bdb7ec049f59d128f9a5..954f626c1fc1065a9186c891d9a236e4ae241870 100644 (file)
@@ -20,6 +20,7 @@
 #include <float.h>\r
 #include <math.h>\r
 #include <list>\r
+#include <limits>
 #include "mgl2/other.h"\r
 #include "mgl2/data.h"\r
 #include "mgl2/thread.h"\r
@@ -497,30 +498,72 @@ HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y)
        if(y->GetNN()!=n)       return nums;\r
        // use s-hull here\r
        std::vector<Shx> pts;\r
-       std::vector<long> out;\r
        Shx pt;\r
 \r
-       double mx = 0, my = 0;\r
-       for(long i=0;i<n;i++)\r
-       {\r
-               register double t;\r
-               t = fabs(x->vthr(i));   if(t>mx)        mx=t;\r
-               t = fabs(y->vthr(i));   if(t>my)        my=t;\r
-       }\r
-       mx *= 1e-15;    my *= 1e-15;\r
+       // Filter NaNs and Infs and calculate axiswise ranges\r
+\r
+       double min_r =  std::numeric_limits<double>::infinity();\r
+       double max_r = -std::numeric_limits<double>::infinity();\r
+       double min_c =  std::numeric_limits<double>::infinity();\r
+       double max_c = -std::numeric_limits<double>::infinity();\r
+\r
        for(long i=0;i<n;i++)\r
        {\r
                pt.r = x->vthr(i);      pt.c = y->vthr(i);\r
                if(mgl_isbad(pt.r) || mgl_isbad(pt.c))  continue;\r
-               if(fabs(pt.r)<mx)       pt.r=0;\r
-               if(fabs(pt.c)<my)       pt.c=0;\r
                pt.id = i;    pts.push_back(pt);\r
+\r
+               min_r = std::min(min_r, pt.r);\r
+               min_c = std::min(min_c, pt.c);\r
+               max_r = std::max(max_r, pt.r);\r
+               max_c = std::max(max_c, pt.c);\r
        }\r
 \r
        std::vector<Triad> triads;\r
-       if(de_duplicate(pts, out))\r
-               mgl_set_global_warn("There are duplicated points for triangulation.");\r
-       s_hull_pro(pts, triads);\r
+\r
+       static const double float_eps = std::numeric_limits<float>::epsilon();\r
+       Dupex grid_step(float_eps*std::max((max_r - min_r), std::max(std::abs(max_r), std::abs(min_r))), \r
+                       float_eps * std::max((max_c - min_c), std::max(std::abs(max_c), std::abs(min_c))));\r
+\r
+       const size_t original_size = pts.size();\r
+\r
+       if(pts.size() >= 3u && 0. < grid_step.r && 0. < grid_step.c) {\r
+               std::vector<long> out;\r
+               de_duplicate(pts, out, grid_step);\r
+\r
+               if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) {\r
+                       // Error occured. It may be caused by degenerated dataset. Well, let's try to increment rounding grid step.\r
+                       // Why 4? Why not. There are no particular reasons for this.\r
+                       grid_step.r *= 4.; \r
+                       grid_step.c *= 4.;\r
+\r
+                       out.clear();\r
+                       triads.clear();\r
+\r
+                       de_duplicate(pts, out, grid_step);\r
+\r
+                       if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) {\r
+                               // Last try. Let's assume uniform points distribution and use range / sqrt(pts.size()) * 2 as epsilon. \r
+                               // It removes a 3/4 of points in optimal case but in the worst case it merges all points to the one.\r
+                               const double density = 1. + floor(0.5 + std::sqrt(static_cast<double>(pts.size())));\r
+                               grid_step.r = (max_r - min_r) / density * 2.;\r
+                               grid_step.c = (max_c - min_c) / density * 2.;\r
+                               \r
+                               out.clear();\r
+                               de_duplicate(pts, out, grid_step);\r
+\r
+                               triads.clear();\r
+                               s_hull_pro(pts, triads);\r
+                       }\r
+               }\r
+       }\r
+\r
+       if (triads.empty()) {\r
+               mgl_set_global_warn("Cannot triangulate this set!");\r
+       } else if(original_size > pts.size()) {\r
+               mgl_set_global_warn("There are duplicated or indistinguishably adjacent points for triangulation.");\r
+       }\r
+\r
        long m = triads.size();\r
        nums=new mglData(3,m);\r
        for(long i=0;i<m;i++)\r
@@ -682,7 +725,7 @@ long MGL_NO_EXPORT mgl_get_next(long k1,long n,long *,long *set,mglPoint *qq)
        for(i=0;i<n;i++)\r
        {\r
                if(i==k1 || set[i]>0)   continue;\r
-               r = mgl_norm(qq[i]-qq[k1]);\r
+               r = mgl_anorm(qq[i]-qq[k1]);\r
                if(r<rm)        {       rm=r;   j=i;    }\r
        }\r
        return j;\r
@@ -698,7 +741,7 @@ long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff)
                for(rm = FLT_MAX,j=0;j<n;j++)\r
                {\r
                        if(i==j)        continue;\r
-                       r = mgl_norm(pp[i]-pp[j]);\r
+                       r = mgl_anorm(pp[i]-pp[j]);\r
                        if(rm>r)        rm = r;\r
                }\r
                rs += sqrt(rm);\r
@@ -712,7 +755,7 @@ long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff)
                memset(set,0,100*sizeof(long));\r
                for(ii=0,j=0;j<n;j++)   // find close vertexes\r
                {\r
-                       r = mgl_norm(pp[i]-pp[j]);\r
+                       r = mgl_anorm(pp[i]-pp[j]);\r
                        if(r<=rs && j!=i)       {       ind[ii] = j;    ii++;   if(ii==99)      break;}\r
                }\r
                if(ii<3)        continue;       // nothing to do\r
index fca5a20f793d8044c5f1b28e82795d819a860a8f..aca5500585ccaee6648d5393c88cb56d02bc0763 100644 (file)
@@ -1053,36 +1053,13 @@ mreal MGL_EXPORT mgl_data_linear(HCDT d, mreal x,mreal y,mreal z)
 mreal MGL_EXPORT mgl_data_spline(HCDT d, mreal x,mreal y,mreal z)\r
 {\r
        if(mgl_isbad(x) || mgl_isbad(y) || mgl_isbad(z))        return NAN;\r
-       mreal res = 0;\r
-       const mglData *dd=dynamic_cast<const mglData *>(d);\r
-       if(dd)  res = dd->ny*dd->nz==1?mglSpline1st<mreal>(dd->a,dd->nx,x):mglSpline3st<mreal>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z);\r
-       const mglDataC *dc=dynamic_cast<const mglDataC *>(d);\r
-       if(dc)  res = abs(dc->ny*dc->nz==1?mglSpline1st<dual>(dc->a,dc->nx,x):mglSpline3st<dual>(dc->a,dc->nx,dc->ny,dc->nz,x,y,z));\r
-       const mglDataV *dv=dynamic_cast<const mglDataV *>(d);\r
-       if(dv)  res = dv->value(x,y,z);\r
-       const mglDataF *df=dynamic_cast<const mglDataF *>(d);\r
-       if(df)  res = df->value(x,y,z);\r
-       return res;     // TODO non-mglData: spline mglDataT, mglDataR\r
+       return d->value(x,y,z);\r
 }\r
 //-----------------------------------------------------------------------------\r
 mreal MGL_EXPORT mgl_data_spline_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz)\r
 {\r
        if(mgl_isbad(x) || mgl_isbad(y) || mgl_isbad(z))        return NAN;\r
-       mreal res = 0;\r
-       const mglData *dd=dynamic_cast<const mglData *>(d);\r
-       if(dd)  res = mglSpline3t<mreal>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,dx,dy,dz);\r
-       const mglDataC *dc=dynamic_cast<const mglDataC *>(d);\r
-       if(dc)\r
-       {       dual a,ax,ay,az;        mreal res;\r
-               a = mglSpline3t<dual>(dc->a,dc->nx,dc->ny,dc->nz,x,y,z,&ax,&ay,&az);    res = abs(a);\r
-               if(dx)  *dx = res?(real(a)*real(ax)+imag(a)*imag(ax))/res:0;\r
-               if(dy)  *dy = res?(real(a)*real(ay)+imag(a)*imag(ay))/res:0;\r
-               if(dz)  *dz = res?(real(a)*real(az)+imag(a)*imag(az))/res:0;    }\r
-       const mglDataV *dv=dynamic_cast<const mglDataV *>(d);\r
-       if(dv)  res = dv->value(x,y,z,dx,dy,dz);\r
-       const mglDataF *df=dynamic_cast<const mglDataF *>(d);\r
-       if(df)  res = df->value(x,y,z,dx,dy,dz);\r
-       return res;     // TODO non-mglData: spline mglDataT, mglDataR\r
+       return d->valueD(x,y,z,dx,dy,dz);\r
 }\r
 //-----------------------------------------------------------------------------\r
 mreal MGL_EXPORT mgl_data_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
index 031c0b1261dc43fa67479d5fcc6c8782a3158f4b..2a6a92c7eed92d64c6c2900e10de30bd978de364 100644 (file)
@@ -826,3 +826,164 @@ mreal MGL_EXPORT mgl_find_root_txt_(const char *func, mreal *ini, const char *va
        mreal r = mgl_find_root_txt(s,*ini,*var);\r
        delete []s;     return r;       }\r
 //-----------------------------------------------------------------------------\r
+MGL_NO_EXPORT void *mgl_pulse_z(void *par)\r
+{\r
+       mglThreadD *t=(mglThreadD *)par;\r
+       long nz=t->p[2], nn=t->n;\r
+       mreal *b=t->a;\r
+       const mreal *a=t->b;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       {\r
+               long j0=0;      mreal m=a[i];\r
+               for(long j=1;j<nz;j++)  // get maximum\r
+               {       register long i0=i+nn*j;\r
+                       if(m<a[i0])     {       m=a[i0];        j0=j;   }\r
+               }\r
+               if(j0>0 && j0<nz-1)\r
+               {\r
+                       register long i0=i+nn*j0;\r
+                       mreal A = (a[i0-nn]-2*a[i0]+a[i0+nn])/2;\r
+                       mreal B = (a[i0+nn]-a[i0-nn])/2;\r
+                       mreal C = a[i0] - B*B/(4*A);\r
+                       b[i]=C; b[i+nn]=j0-B/(2*A);     b[i+2*nn]=sqrt(fabs(C/A));      C /= 2;\r
+                       mreal j1=NAN,j2=NAN;\r
+                       for(long j=j0;j<nz-1;j++)\r
+                       {       register long i0 = i+nn*j;\r
+                               if((a[i0]-C)*(a[i0+nn]-C)<0)    j2 = j + (a[i0]-C)/(a[i0]-a[i0+nn]);\r
+                       }\r
+                       for(long j=j0;j>0;j--)\r
+                       {       register long i0=i+nn*j;\r
+                               if((a[i0]-C)*(a[i0-nn]-C)<0)    j1 = j - (a[i0]-C)/(a[i0]-a[i0-nn]);\r
+                       }\r
+                       b[i+3*nn]=j2-j1;        b[i+4*nn]=0;\r
+                       if(j2>j1)       for(long j = j1;j<=j2;j++)      b[i+4*nn] += a[i+nn*j];\r
+               }\r
+               else    // maximum at the edges\r
+               {       b[i]=m; b[i+nn]=j0;     b[i+2*nn]=b[i+3*nn]=b[i+4*nn]=NAN;      }\r
+       }\r
+       return 0;\r
+}\r
+MGL_NO_EXPORT void *mgl_pulse_y(void *par)\r
+{\r
+       mglThreadD *t=(mglThreadD *)par;\r
+       long nx=t->p[0], ny=t->p[1], nn=t->n;\r
+       mreal *b=t->a;\r
+       const mreal *a=t->b;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       {\r
+               long k = (i%nx)+nx*ny*(i/nx), j0=0;     mreal m=a[k];\r
+               long ki = (i%nx)+5*nx*(i/nx);\r
+               for(long j=1;j<ny;j++)  // get maximum\r
+               {       register long i0=k+nx*j;\r
+                       if(m<a[i0])     {       m=a[i0];        j0=j;   }\r
+               }\r
+               if(j0>0 && j0<ny-1)\r
+               {\r
+                       register long i0=k+nx*j0;\r
+                       mreal A = (a[i0-nx]-2*a[i0]+a[i0+nx])/2;\r
+                       mreal B = (a[i0+nx]-a[i0-nx])/2;\r
+                       mreal C = a[i0] - B*B/(4*A);\r
+                       b[ki]=C;        b[ki+nx]=j0-B/(2*A);    b[ki+2*nx]=sqrt(fabs(C/A));     C /= 2;\r
+                       mreal j1=NAN,j2=NAN;\r
+                       for(long j=j0;j<ny-1;j++)\r
+                       {       register long i0 = k+nx*j;\r
+                               if((a[i0]-C)*(a[i0+nx]-C)<0)    j2 = j + (a[i0]-C)/(a[i0]-a[i0+nx]);\r
+                       }\r
+                       for(long j=j0;j>0;j--)\r
+                       {       register long i0=k+nx*j;\r
+                               if((a[i0]-C)*(a[i0-nx]-C)<0)    j1 = j - (a[i0]-C)/(a[i0]-a[i0-nx]);\r
+                       }\r
+                       b[ki+3*nx]=j2-j1;       b[ki+4*nx]=0;\r
+                       if(j2>j1)       for(long j = j1;j<=j2;j++)      b[ki+4*nx] += a[k+nx*j];\r
+               }\r
+               else    // maximum at the edges\r
+               {       b[ki]=m;        b[ki+nx]=j0;    b[ki+2*nx]=b[ki+3*nx]=b[ki+4*nx]=NAN;   }\r
+       }\r
+       return 0;\r
+}\r
+MGL_NO_EXPORT void *mgl_pulse_x(void *par)\r
+{\r
+       mglThreadD *t=(mglThreadD *)par;\r
+       long nx=t->p[0], nn=t->n;\r
+       mreal *b=t->a;\r
+       const mreal *a=t->b;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       {\r
+               long k = i*nx, j0=0;    mreal m=a[k];\r
+               for(long j=1;j<nx;j++)  // get maximum\r
+               {       register long i0=j+k;\r
+                       if(m<a[i0])     {       m=a[i0];        j0=j;   }\r
+               }\r
+               if(j0>0 && j0<nx-1)\r
+               {\r
+                       register long i0=j0+k;\r
+                       mreal A = (a[i0-1]-2*a[i0]+a[i0+1])/2;\r
+                       mreal B = (a[i0+1]-a[i0-1])/2;\r
+                       mreal C = a[i0] - B*B/(4*A);\r
+                       b[5*i]=C;       b[5*i+1]=j0-B/(2*A);    b[5*i+2]=sqrt(fabs(C/A));       C /= 2;\r
+                       mreal j1=NAN,j2=NAN;\r
+                       for(long j=j0;j<nx-1;j++)\r
+                       {       register long i0 = j+k;\r
+                               if((a[i0]-C)*(a[i0+1]-C)<0)     j2 = j + (a[i0]-C)/(a[i0]-a[i0+1]);\r
+                       }\r
+                       for(long j=j0;j>0;j--)\r
+                       {       register long i0=j+k;\r
+                               if((a[i0]-C)*(a[i0-1]-C)<0)     j1 = j - (a[i0]-C)/(a[i0]-a[i0-1]);\r
+                       }\r
+                       b[5*i+3]=j2-j1; b[5*i+4]=0;\r
+                       if(j2>j1)       for(long j = j1;j<=j2;j++)      b[5*i+4] += a[j+k];\r
+               }\r
+               else    // maximum at the edges\r
+               {       b[5*i]=m;       b[5*i+1]=j0;    b[5*i+2]=b[5*i+3]=b[5*i+4]=NAN; }\r
+       }\r
+       return 0;\r
+}\r
+HMDT MGL_EXPORT mgl_data_pulse(HCDT dat, char dir)\r
+{\r
+//     if(!dir || *dir==0)     return 0;\r
+       long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();\r
+       long p[3]={nx,ny,nz};\r
+       mreal *c = new mreal[nx*ny*nz], *b=0;\r
+\r
+       const mglData *d=dynamic_cast<const mglData *>(dat);\r
+       if(d)   memcpy(c,d->a,nx*ny*nz*sizeof(mreal));\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx*ny*nz;i++)    c[i]=dat->vthr(i);\r
+\r
+       if(dir=='z' && nz>1)\r
+       {\r
+               b = new mreal[nx*ny*5];\r
+               mglStartThread(mgl_pulse_z,0,nx*ny,b,c,0,p);    p[2] = 5;\r
+       }\r
+       else if(dir=='y' && ny>1)\r
+       {\r
+               b = new mreal[5*nx*nz];\r
+               mglStartThread(mgl_pulse_y,0,nx*p[2],b,c,0,p);  p[1] = 5;\r
+       }\r
+       else if(dir=='x' && nx>1)\r
+       {\r
+               b = new mreal[5*ny*nz];\r
+               mglStartThread(mgl_pulse_x,0,p[1]*p[2],b,c,0,p);        p[0] = 5;\r
+       }\r
+       mglData *r=0;\r
+       if(b)\r
+       {\r
+               r=new mglData(p[0],p[1],p[2]);\r
+               memcpy(r->a,b,p[0]*p[1]*p[2]*sizeof(mreal));\r
+               delete []b;\r
+       }\r
+       delete []c;     return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_data_pulse_(uintptr_t *d, const char *dir,int l)\r
+{      return uintptr_t(mgl_data_pulse(_DT_,dir[0]));  }\r
+//-----------------------------------------------------------------------------\r
index 576125652e08039caa9931c18e5bb1476a271611..69299120791078a45882e0c4bcfe061824e704dc 100644 (file)
@@ -286,37 +286,45 @@ void MGL_EXPORT mgl_data_set_name_(uintptr_t *d, const char *name,int l)
 void MGL_EXPORT mgl_data_set_func(mglDataA *dat, void (*func)(void *), void *par)\r
 {      dat->func = func;       dat->o = par;   }\r
 //-----------------------------------------------------------------------------\r
-void MGL_EXPORT mgl_data_save(HCDT d, const char *fname,long ns)\r
+std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns)\r
 {\r
-       FILE *fp = fopen(fname,"w");\r
-       if(!fp) return;\r
        long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();\r
        const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
+       std::string out;        char buf[512];\r
        if(ns<0 || (ns>=nz && nz>1))    for(long k=0;k<nz;k++)\r
        {       // save whole data\r
                const mglData *dr = dynamic_cast<const mglData *>(d);\r
-               if(dr && !dr->id.empty())       fprintf(fp,"## %s\n",dr->id.c_str());\r
+               if(dr && !dr->id.empty())\r
+               {       snprintf(buf,512,"## %s\n",dr->id.c_str());     out += buf;     }\r
                const mglDataC *dc = dynamic_cast<const mglDataC *>(d);\r
-               if(dc && !dc->id.empty())       fprintf(fp,"## %s\n",dc->id.c_str());\r
+               if(dc && !dc->id.empty())\r
+               {       snprintf(buf,512,"## %s\n",dc->id.c_str());     out += buf;     }\r
                for(long i=0;i<ny;i++)\r
                {\r
-                       for(long j=0;j<nx-1;j++)        fprintf(fp,"%g\t",d->v(j,i,k));\r
-                       fprintf(fp,"%g\n",d->v(nx-1,i,k));\r
+                       for(long j=0;j<nx-1;j++)        \r
+                       {       snprintf(buf,512,"%g\t",d->v(j,i,k));   out += buf;     }\r
+                       snprintf(buf,512,"%g\n",d->v(nx-1,i,k));        out += buf;\r
                }\r
-               fprintf(fp,"\n");\r
+               out += "\n";\r
        }\r
        else\r
        {       // save selected slice\r
                if(nz>1)        for(long i=0;i<ny;i++)\r
                {\r
-                       for(long j=0;j<nx-1;j++)        fprintf(fp,"%g\t",d->v(j,i,ns));\r
-                       fprintf(fp,"%g\n",d->v(nx-1,i,ns));\r
+                       for(long j=0;j<nx-1;j++)\r
+                       {       snprintf(buf,512,"%g\t",d->v(j,i,ns));  out += buf;     }\r
+                       snprintf(buf,512,"%g\n",d->v(nx-1,i,ns));       out += buf;\r
                }\r
                else if(ns<ny)  for(long j=0;j<nx;j++)\r
-                       fprintf(fp,"%g\t",d->v(j,ns));\r
+               {       snprintf(buf,512,"%g\t",d->v(j,ns));    out += buf;     }\r
        }\r
        setlocale(LC_NUMERIC, loc.c_str());\r
-       fclose(fp);\r
+       return out;\r
+}\r
+void MGL_EXPORT mgl_data_save(HCDT d, const char *fname,long ns)\r
+{\r
+       FILE *fp = fopen(fname,"w");\r
+       if(fp)  {       fprintf(fp,"%s",mgl_data_to_string(d,ns).c_str());      fclose(fp);     }\r
 }\r
 void MGL_EXPORT mgl_data_save_(uintptr_t *d, const char *fname,int *ns,int l)\r
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
index 1eca3d942f68c71957e2d10ee70898862668cb4e..6be9232c500f570d89c9f66c905ea15aad7d1bd7 100644 (file)
@@ -30,6 +30,9 @@ EQ_NUM=0,     // a variable substitution
 EQ_RND,                // random number\r
 EQ_A,          // numeric constant\r
 // normal functions of 2 arguments\r
+EQ_LT,         // comparison x<y                       !!! MUST BE FIRST 2-PLACE FUNCTION\r
+EQ_GT,         // comparison x>y\r
+EQ_EQ,         // comparison x=y\r
 EQ_ADD,                // addition x+y\r
 EQ_SUB,                // substraction x-y\r
 EQ_MUL,                // multiplication x*y\r
@@ -91,6 +94,17 @@ mglFormulaC::mglFormulaC(const char *string)
                len-=2; str[len]=0;\r
        }\r
        len=strlen(str);\r
+       n=mglFindInText(str,"<>=");                             // low priority -- conditions\r
+       if(n>=0)\r
+       {\r
+               if(str[n]=='<') Kod=EQ_LT;\r
+               else if(str[n]=='>') Kod=EQ_GT;\r
+               else Kod=EQ_EQ;\r
+               str[n]=0;\r
+               Left=new mglFormulaC(str);\r
+               Right=new mglFormulaC(str+n+1);\r
+               delete []str;   return;\r
+       }\r
        n=mglFindInText(str,"+-");                              // normal priority -- additions\r
        if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2]))))\r
        {\r
@@ -208,6 +222,9 @@ dual mglFormulaC::Calc(const dual var[MGL_VS]) const
        return CalcIn(var);\r
 }\r
 //-----------------------------------------------------------------------------\r
+dual MGL_LOCAL_CONST ceqc(dual a,dual b)       {return a==b?1:0;}\r
+dual MGL_LOCAL_CONST cltc(dual a,dual b)       {return real(a-b)<0?1:0;}\r
+dual MGL_LOCAL_CONST cgtc(dual a,dual b)       {return real(a-b)>0?1:0;}\r
 dual MGL_LOCAL_CONST addc(dual a,dual b)       {return a+b;}\r
 dual MGL_LOCAL_CONST subc(dual a,dual b)       {return a-b;}\r
 dual MGL_LOCAL_CONST mulc(dual a,dual b)       {return a*b;}\r
@@ -241,12 +258,12 @@ dual MGL_LOCAL_CONST lgc(dual x)  {       return log10(x);}
 //-----------------------------------------------------------------------------\r
 typedef dual (*func_1)(dual);\r
 typedef dual (*func_2)(dual, dual);\r
+static const func_2 f2[EQ_SIN-EQ_LT] = {cltc,cgtc,ceqc,addc,subc,mulc,divc,ipwc,powc,llgc};\r
+static const func_1 f1[EQ_LAST-EQ_SIN] = {sinc,cosc,tanc,asinc,acosc,atanc,sinhc,coshc,tanhc,\r
+                                       asinhc,acoshc,atanhc,sqrtc,expc,expi,logc,lgc,absc,argc,conjc};\r
 // evaluation of embedded (included) expressions\r
 dual mglFormulaC::CalcIn(const dual *a1) const\r
 {\r
-       func_2 f2[EQ_SIN-EQ_ADD] = {addc,subc,mulc,divc,ipwc,powc,llgc};\r
-       func_1 f1[EQ_LAST-EQ_SIN] = {sinc,cosc,tanc,asinc,acosc,atanc,sinhc,coshc,tanhc,\r
-                                       asinhc,acoshc,atanhc,sqrtc,expc,expi,logc,lgc,absc,argc,conjc};\r
 //     if(Error)       return 0;\r
        if(Kod==EQ_A)   return a1[(int)Res.real()];\r
        if(Kod==EQ_RND) return mgl_rnd();\r
@@ -258,7 +275,7 @@ dual mglFormulaC::CalcIn(const dual *a1) const
                if(Kod<EQ_SIN)\r
                {\r
                        dual b = Right->CalcIn(a1);\r
-                       b = mgl_isfin(b)?f2[Kod-EQ_ADD](a,b):NAN;\r
+                       b = mgl_isfin(b)?f2[Kod-EQ_LT](a,b):NAN;\r
                        return mgl_isfin(b)?b:NAN;\r
                }\r
                else\r
index af4d016a95a53489906eb93509004f383f1edd0e..0499fa097afd486ab49c8347ef3bec79dce6c6b2 100644 (file)
@@ -714,9 +714,9 @@ HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std::v
        HMDT res = new mglData; res->a[0]=NAN;  return res;
 }
 //-----------------------------------------------------------------------------
-dual MGL_LOCAL_CONST ceqc(dual a,dual b)       {return a==b?1:0;}
-dual MGL_LOCAL_CONST cltc(dual a,dual b)       {return real(a-b)<0?1:0;}
-dual MGL_LOCAL_CONST cgtc(dual a,dual b)       {return real(a-b)>0?1:0;}
+dual MGL_LOCAL_CONST ceqc(dual a,dual b);      //{return a==b?1:0;}
+dual MGL_LOCAL_CONST cltc(dual a,dual b);      //{return real(a-b)<0?1:0;}
+dual MGL_LOCAL_CONST cgtc(dual a,dual b);      //{return real(a-b)>0?1:0;}
 dual MGL_LOCAL_CONST ipwc(dual a,dual b);      //{return mgl_ipowc(a,int(b.real()));}
 dual MGL_LOCAL_CONST powc(dual a,dual b);      //{return exp(b*log(a));        }
 dual MGL_LOCAL_CONST llgc(dual a,dual b);      //{return log(a)/log(b);        }
index 98e8b0a3d1757d1c3b1e354a414f57de19be0002..621315563119f84d47848f9005a00e3e602ba26b 100644 (file)
@@ -66,6 +66,13 @@ int MGL_NO_EXPORT mgls_alpha(mglGraph *gr, long , mglArg *a, const char *k, cons
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_pendelta(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(!strcmp(k,"n"))      gr->SetPenDelta(a[0].v);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_plotid(mglGraph *gr, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
@@ -426,7 +433,7 @@ int MGL_NO_EXPORT mgls_copy(mglGraph *gr, long , mglArg *a, const char *k, const
                mglData *D = dynamic_cast<mglData *>(a[1].d);
                mglDataC *C = dynamic_cast<mglDataC *>(a[2].d);
                if(D && C)      {       d->Set(C->Real());      D->Set(C->Imag());      }
-               else    res = 1;                
+               else    res = 1;
        }
        else if(!strcmp(k,"dn"))        *d = a[1].v;
        else res = 1;   return res;
@@ -1096,6 +1103,26 @@ int MGL_NO_EXPORT mgls_line(mglGraph *gr, long , mglArg *a, const char *k, const
        else res = 1;   gr->Self()->LoadState();        return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_lamerey(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;
+       if(!strcmp(k,"nd"))     gr->Lamerey(a[0].v,*(a[1].d),"",opt);
+       else if(!strcmp(k,"nds"))       gr->Lamerey(a[0].v,*(a[1].d),a[2].s.c_str(),opt);
+       else if(!strcmp(k,"ns"))        gr->Lamerey(a[0].v,a[1].s.c_str(),"",opt);
+       else if(!strcmp(k,"nss"))       gr->Lamerey(a[0].v,a[1].s.c_str(),a[2].s.c_str(),opt);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_bifurcation(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;
+       if(!strcmp(k,"nd"))     gr->Bifurcation(a[0].v,*(a[1].d),"",opt);
+       else if(!strcmp(k,"nds"))       gr->Bifurcation(a[0].v,*(a[1].d),a[2].s.c_str(),opt);
+       else if(!strcmp(k,"ns"))        gr->Bifurcation(a[0].v,a[1].s.c_str(),"",opt);
+       else if(!strcmp(k,"nss"))       gr->Bifurcation(a[0].v,a[1].s.c_str(),a[2].s.c_str(),opt);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_errbox(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;      gr->Self()->SaveState(opt);
@@ -1222,6 +1249,18 @@ int MGL_NO_EXPORT mgls_mark(mglGraph *gr, long , mglArg *a, const char *k, const
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_pmap(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;
+       if(!strcmp(k,"dd"))     gr->Pmap(*(a[0].d), *(a[1].d), "",opt);
+       else if(!strcmp(k,"dds"))       gr->Pmap(*(a[0].d), *(a[1].d), a[2].s.c_str(),opt);
+       else if(!strcmp(k,"ddd"))       gr->Pmap(*(a[0].d), *(a[1].d), *(a[2].d), "",opt);
+       else if(!strcmp(k,"ddds"))      gr->Pmap(*(a[0].d), *(a[1].d), *(a[2].d), a[3].s.c_str(),opt);
+       else if(!strcmp(k,"dddd"))      gr->Pmap(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), "",opt);
+       else if(!strcmp(k,"dddds"))     gr->Pmap(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d), a[4].s.c_str(),opt);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_map(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
@@ -1325,6 +1364,7 @@ int MGL_NO_EXPORT mgls_savehdf(mglGraph *, long , mglArg *a, const char *k, cons
 {
        int res=0;
        if(!strcmp(k,"dss"))    a[0].d->SaveHDF(a[1].s.c_str(), a[2].s.c_str());
+       else if(!strcmp(k,"dssn"))      a[0].d->SaveHDF(a[1].s.c_str(), a[2].s.c_str(),mgl_int(a[3].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1431,6 +1471,24 @@ int MGL_NO_EXPORT mgls_save(mglGraph *, long , mglArg *a, const char *k, const c
 {
        int res=0;
        if(!strcmp(k,"ds"))     a[0].d->Save(a[1].s.c_str());
+       else if(!strcmp(k,"ss"))
+       {
+               FILE *fp = fopen(a[1].s.c_str(),"a");
+               size_t pos;     std::string s=a[0].s;
+               while((pos=s.find("\\n"))!=std::string::npos)
+               {       s[pos]=' ';     s[pos+1]='\n';  }
+               while((pos=s.find("\b\b"))!=std::string::npos)  s.erase(pos,2);
+               fprintf(fp,"%s\n",s.c_str());   fclose(fp);
+       }
+       else if(!strcmp(k,"sss"))
+       {
+               FILE *fp = fopen(a[1].s.c_str(),a[2].s.c_str());
+               size_t pos;     std::string s=a[0].s;
+               while((pos=s.find("\\n"))!=std::string::npos)
+               {       s[pos]=' ';     s[pos+1]='\n';  }
+               while((pos=s.find("\b\b"))!=std::string::npos)  s.erase(pos,2);
+               fprintf(fp,"%s\n",s.c_str());   fclose(fp);
+       }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2267,6 +2325,22 @@ int MGL_NO_EXPORT mgls_info(mglGraph *gr, long , mglArg *a, const char *k, const
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_print(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(!strcmp(k,"d"))      printf("%s\n",a[0].d->PrintInfo());
+       else if(!strcmp(k,"s")) printf("%s\n",a[0].s.c_str());
+       else if(!strcmp(k,"n")) printf("value = %g\n",a[0].v);
+       else res = 1;   fflush(stdout); return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_echo(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(!strcmp(k,"d"))      gr->SetWarn(-1,a[0].d->Get().c_str());
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_integrate(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
@@ -2529,6 +2603,15 @@ int MGL_NO_EXPORT mgls_momentum(mglGraph *, long , mglArg *a, const char *k, con
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_pulse(mglGraph *, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(k[0]=='d' && a[0].d->temp)   return 5;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(d && !strcmp(k,"dds"))       *d = mglData(true,mgl_data_pulse(a[1].d,a[2].s[0]));
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_fit(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
@@ -2666,10 +2749,10 @@ int MGL_NO_EXPORT mgls_fsurf(mglGraph *gr, long , mglArg *a, const char *k, cons
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
-int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)           // NOTE don't use options -- Puts can be part of group
+int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;      gr->Self()->SaveState(opt);
-       char buf[1024];
+       char buf[4096];
        FILE *fp;
        if(!strncmp(k,"nns",3))
        {
@@ -2680,9 +2763,9 @@ int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, cons
                        gr->SetWarn(mglWarnOpen,a[2].s.c_str());
                        return res;
 }
-               for(i=0;i<n;i++)        if(!fgets(buf,1024,fp)) continue;
-               memset(buf,0,1024);
-               if(!fgets(buf,1024,fp))
+               for(i=0;i<n;i++)        if(!fgets(buf,4096,fp)) continue;
+               memset(buf,0,4096);
+               if(!fgets(buf,4096,fp))
                {
                        char b[32];     snprintf(b,32,"%d",n);  b[31]=0;
                        gr->SetWarn(mglWarnOpen,(a[2].s+" - line "+b).c_str());
@@ -2700,9 +2783,9 @@ int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, cons
                        gr->SetWarn(mglWarnOpen,a[3].s.c_str());
                        return res;
                }
-               for(i=0;i<n;i++)        if(!fgets(buf,1024,fp)) continue;
-               memset(buf,0,1024);
-               if(!fgets(buf,1024,fp))
+               for(i=0;i<n;i++)        if(!fgets(buf,4096,fp)) continue;
+               memset(buf,0,4096);
+               if(!fgets(buf,4096,fp))
                {
                        char b[32];     snprintf(b,32,"%d",n);  b[31]=0;
                        gr->SetWarn(mglWarnOpen,(a[3].s+" - line "+b).c_str());
@@ -2714,6 +2797,59 @@ int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, cons
        else res = 1;   gr->Self()->LoadState();        return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_fscanf(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(!strcmp(k,"dss"))
+       {
+               mglData *d = dynamic_cast<mglData *>(a[0].d);
+               if(!d)  return 1;
+               // first scan for all "%g"
+               char *buf=new char[a[2].s.length()],*s=buf;
+               strcpy(buf,a[2].s.c_str());
+               std::vector<std::string> strs;
+               for(size_t i=0;buf[i];i++)
+               {
+                       if(buf[i]=='%' && buf[i+1]=='%')        i++;
+                       else if(buf[i]=='%' && buf[i+1]=='g')
+                       {       buf[i]=0;       strs.push_back(s);      s = buf+i+2;    }
+               }
+               delete []buf;
+               if(strs.size()<1)       return 0;
+               // read proper lines from file
+               std::vector<std::string> bufs;
+               FILE *fp=fopen(a[1].s.c_str(),"r");
+               if(!fp)
+               {
+                       gr->SetWarn(mglWarnOpen,a[3].s.c_str());
+                       return res;
+               }
+               while(!feof(fp))
+               {
+                       s = mgl_fgetstr(fp);
+                       if(!strncmp(s,strs[0].c_str(),strs[0].length()))
+                               bufs.push_back(s);
+               }
+               fclose(fp);
+               // parse lines and collect data
+               const size_t nx=strs.size(), ny=bufs.size();
+               if(ny<1)        return 0;
+               d->Create(nx,ny);
+               for(size_t j=0;j<ny;j++)
+               {
+                       const char *c = bufs[j].c_str();
+                       for(size_t i=0;i<nx;i++)
+                       {
+                               const char *p = strstr(c,strs[i].c_str());
+                               if(!p)  break;
+                               p += strs[i].length();  c=p;
+                               d->a[i+nx*j] = atof(p);
+                       }
+               }
+       }
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_import(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
@@ -3266,6 +3402,7 @@ mglCommand mgls_base_cmd[] = {
        {"barwidth","Set default bars width","barwidth val", mgls_barwidth ,2},
        {"beam","Draw quasioptical beam","beam Tr G1 G2 Adat r ['sch' flag num] ", mgls_beam ,9},
        {"belt","Draw belts","belt Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_belt ,8},
+       {"bifurcation","Draw Bifurcation diagram","bifurcation dx Func ['fmt']|dx 'func' ['fmt']", mgls_bifurcation,13},
        {"box","Draw bounding box","box ['fmt' ticks]", mgls_box ,12},
        {"boxplot","Draw boxplot for 2D data","boxplot Ydat ['fmt']|Xdat Ydat ['fmt']", mgls_boxplot ,7},
        {"boxs","Draw boxes","boxs Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_boxs ,8},
@@ -3328,6 +3465,7 @@ mglCommand mgls_base_cmd[] = {
        {"dots","Draw dots for arbitrary data points","dots Xdat Ydat Zdat ['fmt']|Xdat Ydat Zdat Adat ['fmt']|Xdat Ydat Zdat Cdat Adat ['fmt']", mgls_dots ,9},
        {"drawreg","Set draw region for quality&4","drawreg|nx ny m", mgls_drawreg ,2},
        {"drop","Draw drop","drop x0 y0 dx dy r ['col' sh asp]|x0 y0 z0 dx dy dz r ['col' sh asp]", mgls_drop ,13},
+       {"echo","Print content of the data","echo Dat", mgls_echo ,3},
        {"ellipse","Draw ellipse","ellipse x1 y1 x2 y2 r ['fmt']|x1 y1 z1 x2 y2 z2 r ['fmt']", mgls_ellipse ,13},
        {"else","Execute if condition is false","else", 0, 6},
        {"elseif","Conditional operator","elseif val|Dat ['cond']", 0, 6},
@@ -3355,8 +3493,9 @@ mglCommand mgls_base_cmd[] = {
        {"font","Setup font","font 'fmt' [size]", mgls_font ,15},
        {"for","For cycle","for $N v1 v2 [dv] | $N Dat", 0, 6},
        {"fourier","In-place Fourier transform","fourier ReDat ImDat 'dir'|Cmplx 'dir'", mgls_fourier , 16},
-       {"fplot","Plot curve by formula","fplot 'y_x' ['fmt']|'x_t' 'y_t' 'z_t' ['fmt']", mgls_fplot ,1},
-       {"fsurf","Plot surface by formula","fsurf 'z_xy' ['fmt']|'x_uv' 'y_uv' 'z_uv' ['fmt']", mgls_fsurf ,1},
+       {"fplot","Plot curve by formula","fplot 'y(x)' ['fmt']|'x(t)' 'y(t)' 'z(t)' ['fmt']", mgls_fplot ,1},
+       {"fscanf","Get fromated data from file","fscanf Dat 'fname 'templ'", mgls_fscanf ,4},
+       {"fsurf","Plot surface by formula","fsurf 'z(x,y)' ['fmt']|'x(u,v)' 'y(u,v)' 'z(u,v)' ['fmt']", mgls_fsurf ,1},
        {"func","Start function definition and stop execution of main script","func 'name' [narg]", 0, 6},
        {"grad","Draw gradient lines for scalar field","grad Phi ['fmt' num]|Xdat Ydat Phi ['fmt' num]|Xdat Ydat Zdat Phi ['fmt' num]", mgls_grad ,8},
        {"grid","Draw grid","grid ['dir' 'fmt']", mgls_grid ,12},
@@ -3369,13 +3508,14 @@ mglCommand mgls_base_cmd[] = {
        {"idset","Set column id for data","idset Dat 'ids'", mgls_idset ,3},
        {"if","Conditional operator","if val|Dat ['cond']", 0, 6},
        {"import","Import data from PNG picture","import Dat 'fname' 'scheme' [v1 v2]", mgls_import ,4},
-       {"info","Print information about data","info Dat [detail]|'message'", mgls_info ,3},
+       {"info","Print message or information about the data","info Dat [detail]|'message'|const", mgls_info ,3},
        {"inplot","Set position of plot in picture","x1 x2 y1 y2 [rel]", mgls_inplot ,5},
        {"insert","Insert slice of data","insert Dat 'dir' [pos=0 num=1]", mgls_insert ,3},
        {"integrate","Integrate data","integrate Dat 'dir'", mgls_integrate ,16},
        {"jacobian","Get Jacobian","jacobian Res Xdat Ydat [Zdat]", mgls_jacobian ,4},
        {"join","Join data arrays","join Dat Add", mgls_join ,3},
        {"label","Draw label at arbitrary position","label Ydat 'txt' ['fmt'='']|Xdat Ydat 'txt' ['fmt'='']|Xdat Ydat Zdat 'txt' ['fmt'='']", mgls_label ,7},
+       {"lamerey","Draw Lamerey diagram","lamerey x0 Func ['fmt']|x0 'func' ['fmt']", mgls_lamerey ,13},
        {"legend","Draw legend","legend [pos 'fmt']|x y ['fmt']", mgls_legend ,15},
        {"legendmarks","Set number of marks in the legend","legendmarks val", mgls_legendmarks ,15},
        {"light","Setup light","light [val] | val num | num xpos ypos zpos ['fmt' br]", mgls_light ,2},
@@ -3408,11 +3548,15 @@ mglCommand mgls_base_cmd[] = {
        {"origintick","Set tick labels drawing at origin","origintick val", mgls_origintick ,14},
        {"palette","Set palette for 1D plots","palette 'colors'", mgls_palette ,2},
        {"pde","Solve PDE","pde Res 'ham' IniRe IniIm [dz k0]", mgls_pde ,4},
+       {"pendelta","Set size of semi-transparent area","pen_delta val", mgls_pendelta ,2},
        {"perspective","Set perspective","perspective val", mgls_perspective ,2},
        {"pipe","Draw flow pipes for vector field","pipe Udat Vdat ['fmt' rad num]|Xdat Ydat Udat Vdat ['fmt' rad num]|Udat Vdat Wdat ['fmt' rad num]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' rad num]", mgls_pipe ,11},
        {"plot","Draw usual plot for 1D data","plot Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_plot ,7},
        {"plotid","Set default filename","plotid 'name'", mgls_plotid ,2},
+       {"pmap","Draw Poincare map","pmap Ydat Rdat ['fmt']|Xdat Ydat Rdat ['fmt']|Xdat Ydat Zdat Rdat ['fmt']", mgls_pmap ,7},
        {"polygon","Draw polygon","polygon x1 y1 x2 y2 num ['fmt']|x1 y1 z1 x2 y2 z2 num ['fmt']", mgls_polygon ,13},
+       {"print","Immediately print the message","info 'message'|Dat [detail]|const", mgls_print ,3},
+       {"pulse","Get pulse properties","pulse Res Dat 'dir'", mgls_pulse ,4},
        {"put","Put value (numeric or array) to given data element","put Dat val [i j k] | Dat Val [i j k]", mgls_put ,3},
        {"putsfit","Print fitted formula","putsfit x y ['pre' 'font' size]|x y z ['pre' 'font' size]", mgls_putsfit ,15},
        {"qo2d","Solve PDE in accompanied coordinates for 2d case","qo2d Res 'ham' IniRe IniIm Ray [r k0 Xout Yout]", mgls_qo2d ,4},
@@ -3440,7 +3584,7 @@ mglCommand mgls_base_cmd[] = {
        {"roots", "Find roots using data as initial values", "roots Res 'func' Ini ['var']|Res 'func' ini ['var']", mgls_roots ,4},
        {"rotate","Rotate plot","rotate tetz tetx [tety] | tet x y z", mgls_rotate ,5},
        {"rotatetext","Set to auto rotate text or not","rotatetext val", mgls_rotatetext ,15},
-       {"save","Save data to file","save Dat 'file'", mgls_save ,3},
+       {"save","Save data to file","save Dat 'file'|'str' 'file'|'str' 'file' 'how'", mgls_save ,3},
        {"savehdf","Save data to HDF5 file","savehdf Dat 'file' 'id'", mgls_savehdf ,3},
        {"setsize","Set picture size","setsize width height", mgls_setsize ,2},
        {"sew","Remove jump into the data, like phase jumps","sew Dat ['dir' da]", mgls_sew ,16},
index 4c6c7a22aa9737e67ba5fc211ec7b48d8e24d828..b8013f4c9373fbf52c70476a4f065cbadf5f400d 100644 (file)
@@ -190,7 +190,7 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
                fprintf(fb, "%%%%BoundingBox: 0 0 %d %d\n", w, h);
                fclose(fb);     delete []buf;
        }
-       
+
        const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");
        mgl_printf(fp, gz, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: 0 0 %d %d\n", w, h);
        mgl_printf(fp, gz, "%%%%Created by MathGL library\n%%%%Title: %s\n",descr ? descr : fname);
@@ -248,7 +248,7 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
        if(m_P) mgl_printf(fp, gz, "/m_P {m_p 0 sm rm m_s} def\n");
        if(m_X) mgl_printf(fp, gz, "/m_X {m_x ss sm rm m_s} def\n");
        //      if(m_C) mgl_printf(fp, gz, "/m_C {m_c m_o} def\n");
-       mgl_printf(fp, gz, "\n");
+       mgl_printf(fp, gz, "1 setlinecap\n1 setlinejoin\n\n");  // manual setting round line cap
 
        // Write background image first
        const unsigned char *img = mgl_get_background(gr);
@@ -434,7 +434,7 @@ void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr)
 
 
        // currentColor -> inherit ???
-       mgl_printf(fp, gz, "<g fill=\"none\" stroke=\"none\" stroke-width=\"0.5\">\n");
+       mgl_printf(fp, gz, "<g fill=\"none\" stroke=\"none\" stroke-width=\"0.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n");
        // write primitives
        mreal wp=-1;
        register long i;
index 7ea43f8d4248581c3d7db3b78ef34b8416953fea..f100f573f30e81fc05055513fc6511282dc675e9 100644 (file)
@@ -1072,12 +1072,12 @@ void MGL_EXPORT mgl_data_hankel_(uintptr_t *d, const char *dir,int l)
 void MGL_EXPORT mgl_data_fill_sample(HMDT d, const char *how)
 {
        if(!how || *how==0)     return;
-       bool kk = strchr(how,'k');
+       bool kk = mglchr(how,'k');
        long n=d->nx,dn=1;
        mreal *aa=d->a;
-       if(strchr(how,'y'))     {       n=d->ny;        dn=d->nx;       }
-       if(strchr(how,'z'))     {       n=d->nz;        dn=d->nx*d->ny; }
-       if(strchr(how,'h'))     // Hankel
+       if(mglchr(how,'y'))     {       n=d->ny;        dn=d->nx;       }
+       if(mglchr(how,'z'))     {       n=d->nz;        dn=d->nx*d->ny; }
+       if(mglchr(how,'h'))     // Hankel
        {
 #if MGL_HAVE_GSL
                gsl_dht *dht = gsl_dht_new(n,0,1);
index 6a42a4bd57065950e65ff9b247ef0e7a99cc5905..d4f62e323a057008c6d11db6af85bf16142f5e94 100644 (file)
@@ -192,14 +192,23 @@ mreal MGL_NO_EXPORT mgl_fit_base(mglFitData &fd, mreal *ini)
                status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4 );\r
        }\r
        while ( status == GSL_CONTINUE && iter < 500 );\r
+\r
        gsl_matrix *covar = gsl_matrix_alloc(m, m);\r
-       gsl_multifit_covar (s->J, 0.0, covar );\r
+#ifdef HAVE_GSL_2\r
+       gsl_matrix *J = gsl_matrix_alloc(s->fdf->n, s->fdf->p);\r
+       gsl_multifit_fdfsolver_jac(s, J);\r
+       gsl_multifit_covar (J, 0.0, covar);\r
+       gsl_matrix_free (J);\r
+#else\r
+       gsl_multifit_covar(s->J, 0.0, covar);\r
+#endif\r
        mglFitCovar.Set(covar);\r
+       gsl_matrix_free(covar);\r
+\r
        mreal res = gsl_blas_dnrm2(s->f);\r
        for(i=0;i<m;i++)        ini[i] = gsl_vector_get(s->x, i);\r
        // free memory\r
-       gsl_multifit_fdfsolver_free (s);\r
-       gsl_matrix_free (covar);\r
+       gsl_multifit_fdfsolver_free(s);\r
        delete []x_init;\r
        return res;\r
 #else\r
index 46eee6dc84df8c2759a567b6ac885a99c73aeae5..61b2a33162f2d96f684333629773c54db3006dbb 100644 (file)
@@ -39,22 +39,20 @@ template <class Treal> Treal mglLineart(const Treal *a, long nx, long ny, long n
 //-----------------------------------------------------------------------------
 template <class Treal> Treal mgl_spline3t(const Treal y[4], long n, mreal dx, Treal &dy)
 {
-       Treal d[3], t0,t1, f0,d0;
+       Treal d[3];
        d[0] = -(y[2]-mreal(4)*y[1]+mreal(3)*y[0])/mreal(2);
        d[1] = (y[2]-y[0])/mreal(2);
        d[2] = (y[3]-y[1])/mreal(2);
-//     d[3] = (mreal(3)*y[3]-mreal(4)*y[2]+y[1])/mreal(2);
 
-       t0 = (y[2]+y[0])/mreal(2)-y[1];
-       t1 = (y[3]+y[1])/mreal(2)-y[2];
-       f0 = y[n];              d0 = d[n];
-       Treal res = 0;
+       Treal t0 = (y[2]+y[0])/mreal(2)-y[1];
+       Treal t1 = (y[3]+y[1])/mreal(2)-y[2];
+       Treal f0 = y[n], d0 = d[n], res = 0;
        if(n==1)
        {
-               Treal f1 = y[2], d1 = d[2];
-               Treal b3 = mreal(10)*(f1-f0)+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0;
-               Treal b4 = mreal(15)*(f0-f1)-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0;
-               Treal b5 = mreal(6)*(f1-f0)+t1-t0-mreal(3)*d1-mreal(3)*d0;
+               Treal df = y[2]-f0, d1 = d[2];
+               Treal b3 = mreal(10)*df+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0;
+               Treal b4 = mreal(-15)*df-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0;
+               Treal b5 = mreal(6)*df+t1-t0-mreal(3)*d1-mreal(3)*d0;
                dy = d0 + dx*(mreal(2)*t0+dx*(mreal(3)*b3+dx*(mreal(4)*b4+dx*mreal(5)*b5)));
 //             d2y = mreal(2)*t0 + dx*(mreal(6)*b3+dx*(mreal(12)*b4+dx*mreal(20)*b5)); // 2nd derivative for future
                res = f0 + dx*(d0+dx*(t0+dx*(b3+dx*(b4+dx*b5))));
@@ -68,22 +66,20 @@ template <class Treal> Treal mgl_spline3t(const Treal y[4], long n, mreal dx, Tr
 //-----------------------------------------------------------------------------
 template <class Treal> Treal mgl_spline3st(const Treal y[4], long n, mreal dx)
 {
-       Treal d[3], t0,t1, f0,d0;
+       Treal d[3];
        d[0] = -(y[2]-mreal(4)*y[1]+mreal(3)*y[0])/mreal(2);
        d[1] = (y[2]-y[0])/mreal(2);
        d[2] = (y[3]-y[1])/mreal(2);
-//     d[3] = (mreal(3)*y[3]-mreal(4)*y[2]+y[1])/mreal(2);
 
-       Treal res;
-       f0 = y[n];              d0 = d[n];
-       t0 = (y[2]+y[0])/mreal(2)-y[1];
-       t1 = (y[3]+y[1])/mreal(2)-y[2];
+       Treal f0 = y[n], d0 = d[n], res;
+       Treal t0 = (y[2]+y[0])/mreal(2)-y[1];
+       Treal t1 = (y[3]+y[1])/mreal(2)-y[2];
        if(n==1)
        {
-               Treal f1 = y[2], d1 = d[2];
-               Treal b3 = mreal(10)*(f1-f0)+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0;
-               Treal b4 = mreal(15)*(f0-f1)-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0;
-               Treal b5 = mreal(6)*(f1-f0)+t1-t0-mreal(3)*d1-mreal(3)*d0;
+               Treal df = y[2]-f0, d1 = d[2];
+               Treal b3 = mreal(10)*df+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0;
+               Treal b4 = mreal(-15)*df-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0;
+               Treal b5 = mreal(6)*df+t1-t0-mreal(3)*d1-mreal(3)*d0;
                res = f0 + dx*(d0+dx*(t0+dx*(b3+dx*(b4+dx*b5))));
        }
        else    res = f0 + dx*(d0+dx*(n<1?t0:t1));
index abdf610d0a0fd6407c225514b2457613f20a2395..f0bc69989e60003c1fbed6818a0abbd38a267d62 100644 (file)
@@ -79,7 +79,6 @@ void mglCanvasGL::Finish()
                PDef=pdef;      pPos=ss;        PenWidth=ww;\r
        }\r
        glFinish();\r
-//     glBegin(GL_LINES);      glColor3f(0,0,1);       glVertex2f(0.1,0.1);    glVertex2f(0.9,0.9);    glEnd();\r
 }\r
 //-----------------------------------------------------------------------------\r
 bool mglCanvasGL::Alpha(bool enable)\r
index 7d34b410d02f57c87b360b3f775edf558d4b9466..7d5070a3e1952a51b325dece80b25c43dd953cef 100644 (file)
@@ -59,6 +59,7 @@ void mglParser::ScanFunc(const wchar_t *line)
        if(!line)
        {       func.clear();   num=0;  return; }
        num++;
+       while(*line<=' ' && *line!=0)   line++;
        if(wcsncmp(line,L"func",4) || line[4]>' ')      return;
        register long i;
        for(i=4;line[i]<=' ' || line[i]=='\'';i++);
@@ -167,6 +168,9 @@ mglParser::mglParser(bool setsize)
 mglParser::~mglParser()
 {
        DeleteAll();    delete []fval;
+       for(size_t i=0;i<NumList.size();i++)    // force delete built-in variables
+               if(NumList[i])  delete NumList[i];
+       NumList.clear();
 #if MGL_HAVE_LTDL
        lt_dlexit();
 #endif
@@ -897,7 +901,6 @@ void mglParser::Execute(mglGraph *gr, FILE *fp, bool print)
        std::wstring str;
        wchar_t ch;
        while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) str.push_back(ch);
-//     while(!feof(fp))        str.push_back(fgetwc(fp));
        Execute(gr,str.c_str());
        if(print)       printf("%s\n",gr->Message());
 }
index 3a753ed98dba00dfa6ca9126c8180be4da15538a..0427ef75978243fb5331953abb0ed6ed098c60b9 100644 (file)
@@ -31,16 +31,18 @@ inline mreal get_pfact(float pf, float Depth)
 void mglCanvas::SetSize(int w,int h,bool clf)\r
 {\r
        if(w<=0 || h<=0)        {       SetWarn(mglWarnSize,"SetSize"); return; }\r
-       if(Width==w || Height==h)\r
+       if(Width==w && Height==h)\r
        {\r
                InPlot(0,1,0,1,false);\r
                if(clf || (Quality&4))  Clf();\r
                return;\r
        }\r
 \r
-       double dx = double(w)/Width, dy = double(h)/Height, dz = sqrt(double(w*h))/Depth;\r
+       const double dx = double(w)/Width;\r
+       const double dy = double(h)/Height;\r
+       const double dz = sqrt(double(w*h))/Depth;\r
        Width = w;      Height = h;     Depth = long(sqrt(double(w*h)));\r
-       long s = long(w)*long(h);\r
+       const long s = long(w)*long(h);\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_lock(&mutexClf);\r
 #elif MGL_HAVE_OMP\r
@@ -71,7 +73,7 @@ void mglCanvas::SetSize(int w,int h,bool clf)
 #elif MGL_HAVE_OMP\r
                omp_set_lock(&lockClf);\r
 #endif\r
-               long n = long(Pnt.size());\r
+               const long n = long(Pnt.size());\r
 #pragma omp parallel for\r
                for(long i=0;i<n;i++)\r
                {\r
@@ -86,7 +88,7 @@ void mglCanvas::SetSize(int w,int h,bool clf)
                for(size_t k=0;k<DrwDat.size();k++)     // scale frames too\r
                {\r
                        mglStack<mglPnt>  &pnt = DrwDat[k].Pnt;\r
-                       n = long(pnt.size());\r
+                       const long n = long(pnt.size());\r
 #pragma omp parallel for\r
                        for(long i=0;i<n;i++)\r
                        {\r
@@ -122,7 +124,7 @@ void mglCanvas::PutDrawReg(mglDrawReg *d, const mglCanvas *gr)
 {\r
        if(gr)\r
        {\r
-               int dd = d->x2 - d->x1;\r
+               const int dd = d->x2 - d->x1;\r
                for(long j=d->y1;j<d->y2;j++)\r
                {\r
                        register long i = d->x1+Width*(Height-1-j);\r
@@ -161,7 +163,7 @@ long mglCanvas::ProjScale(int nf, long id, bool text)
        const mglPnt &pi = Pnt[id];\r
        mglPoint pp(pi.x,pi.y,pi.z), nn(pi.u,pi.v,pi.w), p, n;\r
        if(mgl_isnan(pp.x))     return -1;\r
-       mreal w=B1.b[0]/2, h=B1.b[4]/2, d=B1.b[8]/2, xx=B1.x-w/2, yy=B1.y-h/2;\r
+       const mreal w=B1.b[0]/2, h=B1.b[4]/2, d=B1.b[8]/2, xx=B1.x-w/2, yy=B1.y-h/2;\r
        if(pi.sub>=0)\r
        {\r
                mglPoint q(RestorePnt(pp)/(2*B.pf));\r
@@ -206,23 +208,23 @@ void mglCanvas::LightScale(const mglMatrix *M)
 // NOTE: Perspective is not fully supported now !!! Also it use LAST InPlot parameters!!!\r
 mglPoint mglCanvas::RestorePnt(mglPoint ps, bool norm) const\r
 {\r
-       mreal s3 = 2*B.pf;\r
+       const mreal s3 = 2*B.pf;\r
        mglPoint p;\r
 \r
-       mreal W=Width/2, H=Height/2, D=Depth/2;\r
+       const mreal W=Width/2, H=Height/2, D=Depth/2;\r
        const mreal *b=B.b,*d=Bp.b;\r
        mreal cx = B.z*d[2]+B.y*d[1]+B.x*d[0]-Bp.x*W-d[0]*W+W-d[1]*H-d[2]*D;\r
-       mreal c0 = b[6]*d[2]+b[3]*d[1]+b[0]*d[0];\r
-       mreal c1 = b[7]*d[2]+b[4]*d[1]+b[1]*d[0];\r
-       mreal c2 = b[8]*d[2]+b[5]*d[1]+b[2]*d[0];\r
+       const mreal c0 = b[6]*d[2]+b[3]*d[1]+b[0]*d[0];\r
+       const mreal c1 = b[7]*d[2]+b[4]*d[1]+b[1]*d[0];\r
+       const mreal c2 = b[8]*d[2]+b[5]*d[1]+b[2]*d[0];\r
        mreal cy = B.z*d[5]+B.y*d[4]+B.x*d[3]-d[3]*W-Bp.y*H-d[4]*H+H-d[5]*D;\r
-       mreal c3 = b[6]*d[5]+b[3]*d[4]+b[0]*d[3];\r
-       mreal c4 = b[7]*d[5]+b[4]*d[4]+b[1]*d[3];\r
-       mreal c5 = b[8]*d[5]+b[5]*d[4]+b[2]*d[3];\r
+       const mreal c3 = b[6]*d[5]+b[3]*d[4]+b[0]*d[3];\r
+       const mreal c4 = b[7]*d[5]+b[4]*d[4]+b[1]*d[3];\r
+       const mreal c5 = b[8]*d[5]+b[5]*d[4]+b[2]*d[3];\r
        mreal cz = B.z*d[8]+B.y*d[7]+B.x*d[6]-d[6]*W-d[7]*H-Bp.z*D-d[8]*D+D;\r
-       mreal c6 = b[6]*d[8]+b[3]*d[7]+b[0]*d[6];\r
-       mreal c7 = b[7]*d[8]+b[4]*d[7]+b[1]*d[6];\r
-       mreal c8 = b[8]*d[8]+b[5]*d[7]+b[2]*d[6];\r
+       const mreal c6 = b[6]*d[8]+b[3]*d[7]+b[0]*d[6];\r
+       const mreal c7 = b[7]*d[8]+b[4]*d[7]+b[1]*d[6];\r
+       const mreal c8 = b[8]*d[8]+b[5]*d[7]+b[2]*d[6];\r
        if(norm)        cx=cy=cz=0;\r
 \r
        if(mgl_isnum(ps.z))     // try to take into account perspective if z-value is provided\r
@@ -231,8 +233,8 @@ mglPoint mglCanvas::RestorePnt(mglPoint ps, bool norm) const
                ps.x = Width/2 + (ps.x-Width/2)/dd;\r
                ps.y = Height/2+ (ps.y-Height/2)/dd;\r
        }\r
-       mreal xx = ps.x-cx, yy = ps.y-cy, zz = ps.z-cz;\r
-       mreal d1=c0*c4-c1*c3, d2=c1*c5-c2*c4, d3=c0*c5-c2*c3;\r
+       const mreal xx = ps.x-cx, yy = ps.y-cy, zz = ps.z-cz;\r
+       const mreal d1=c0*c4-c1*c3, d2=c1*c5-c2*c4, d3=c0*c5-c2*c3;\r
 \r
        if(mgl_isnum(zz))       // try to use z-values\r
        {\r
@@ -291,7 +293,7 @@ void MGL_NO_EXPORT mgl_prm_swap(mglPrim &s1,mglPrim &s2,mglPrim *buf)
        memcpy(&s1, &s2, sizeof(mglPrim));\r
        memcpy(&s2, buf, sizeof(mglPrim));\r
 }\r
-void MGL_NO_EXPORT sort_prm_c(size_t l0, size_t r0, mglStack<mglPrim> &s, mglPrim *buf)\r
+void MGL_NO_EXPORT sort_prm_c(const size_t l0, const size_t r0, mglStack<mglPrim> &s, mglPrim *buf)\r
 {\r
        if(l0==r0)      return;\r
        if(l0+1==r0)\r
@@ -303,7 +305,7 @@ void MGL_NO_EXPORT sort_prm_c(size_t l0, size_t r0, mglStack<mglPrim> &s, mglPri
        if(del) buf = (mglPrim*)malloc(sizeof(mglPrim));\r
 \r
        size_t l=l0, r=r0;\r
-       long v = s[(l+r)/2].n1;\r
+       const long v = s[(l+r)/2].n1;\r
 \r
        for(size_t i=l0;i<=r0;i++)      // first collect <0\r
                if(s[i].n1<v)\r
@@ -336,11 +338,10 @@ void mglStartThread(void (mglCanvas::*func)(long i, long n, const void *p), mglC
        {\r
                pthread_t *tmp=new pthread_t[mglNumThr];\r
                mglThreadG *par=new mglThreadG[mglNumThr];\r
-               register long i;\r
-               for(i=0;i<mglNumThr;i++)        // put parameters into the structure\r
+               for(long i=0;i<mglNumThr;i++)   // put parameters into the structure\r
                {       par[i].gr=gr;   par[i].f=func;  par[i].n=n;     par[i].p=p;     par[i].id=i;    }\r
-               for(i=0;i<mglNumThr;i++)        pthread_create(tmp+i, 0, mgl_canvas_thr, par+i);\r
-               for(i=0;i<mglNumThr;i++)        pthread_join(tmp[i], 0);\r
+               for(long i=0;i<mglNumThr;i++)   pthread_create(tmp+i, 0, mgl_canvas_thr, par+i);\r
+               for(long i=0;i<mglNumThr;i++)   pthread_join(tmp[i], 0);\r
                delete []tmp;   delete []par;\r
        }\r
        else\r
@@ -382,7 +383,7 @@ void mglCanvas::pxl_backgr(long id, long n, const void *)
 void mglCanvas::pxl_transform(long id, long n, const void *)\r
 {\r
        const mreal *b = Bp.b;\r
-       mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
+       const mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -513,7 +514,7 @@ void mglCanvas::PreparePrim(int fast)
 void mglCanvas::pxl_primdr(long id, long , const void *)\r
 {\r
 #define Q      4       // should be >= sqrt(2*num_thr) ???\r
-       int nx=Q,ny=Q;          // TODO find dependence on Q for 1, 2, 4, 8 threads. Try to select optimal\r
+       const int nx=Q,ny=Q;    // TODO find dependence on Q for 1, 2, 4, 8 threads. Try to select optimal\r
        if(!(Quality&3))\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
@@ -628,7 +629,7 @@ void mglCanvas::pxl_primpx(long id, long n, const void *)   // NOTE this variant i
 void mglCanvas::pxl_dotsdr(long id, long n, const void *)\r
 {\r
        const mreal *b = Bp.b;\r
-       mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
+       const mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -813,6 +814,11 @@ void mglCanvas::pnt_plot(long x,long y,mreal z,const unsigned char ci[4], int ob
                                {       combine(c,cc+8);        memcpy(cc+8,c,4);       }\r
                        }\r
                }\r
+               if(Quality&MGL_DRAW_FAST)\r
+               {\r
+                       if(z>=zz[0])    // point upper the background\r
+                       {       zz[0]=z;        combine(cc,c);  OI[i0]=obj_id;  }\r
+               }\r
                else\r
                {\r
                        if(z>=zz[0])    // point upper the background\r
@@ -826,16 +832,15 @@ unsigned char* mglCanvas::col2int(const mglPnt &p,unsigned char *r, int obj_id)
 //     if(!r)  return r;       // NOTE r must be provided!\r
        if(p.a<=0)      {       memset(r,0,4);  return r;       }\r
        register float b0=0,b1=0,b2=0, ar,ag,ab,dif;\r
-       size_t nl = p.sub>=0?p.sub:1-p.sub;\r
-       bool glob = !get(MGL_LOCAL_LIGHT);\r
+       const size_t nl = p.sub>=0?p.sub:1-p.sub;\r
+       const bool glob = !get(MGL_LOCAL_LIGHT);\r
        ar = ag = ab = glob?AmbBr:Sub[nl].AmbBr;\r
        dif = glob?DifBr:Sub[nl].DifBr;\r
 \r
        if(mgl_isnum(p.u+p.v+p.w))\r
        {\r
                float d0,d1,d2,nn;\r
-               register long i;\r
-               for(i=0;i<10;i++)\r
+               for(long i=0;i<10;i++)\r
                {\r
                        const mglLight &ll=glob?light[i]:Sub[nl].light[i];\r
                        if(!ll.n)       continue;\r
@@ -897,7 +902,7 @@ void mglCanvas::combine(unsigned char *c1, const unsigned char *c2) const
 {\r
        if(c2[3])\r
        {\r
-               register unsigned a1=c1[3], a2=c2[3];\r
+               const register unsigned a1=c1[3], a2=c2[3];\r
                if(a2==255 || a1==0)    {       memcpy(c1,c2,4);        return; }\r
                if((Flag&3)==0)\r
                {\r
@@ -937,7 +942,7 @@ unsigned char **mglCanvas::GetRGBLines(long &w, long &h, unsigned char *&f, bool
        return p;\r
 }\r
 //-----------------------------------------------------------------------------\r
-bool MGL_LOCAL_PURE visible(long i, long j, const unsigned char m[8], mreal pw, int a) // Check if pixel visible\r
+bool inline visible(long i, long j, const unsigned char m[8], mreal pw, int a) // Check if pixel visible\r
 {\r
        register float c = mgl_cos[(a+360)%360], s = mgl_cos[(a+450)%360];\r
 //     register int ii = int(0.5+(i*c+j*s)/pw)%8, jj = int(0.5+(j*c-i*s)/pw)%8;\r
@@ -960,7 +965,6 @@ void mglCanvas::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3,
        }\r
        unsigned char r[4];\r
        long y1,x1,y2,x2;\r
-       float dd,dsx,dsy;\r
        mglPnt d1(p2-p1), d2(p3-p1), d3(p4+p1-p2-p3);\r
 \r
        if(d1.x==0 && d1.y==0)  {       trig_draw(p1,p3,p4,true,d);     return; }\r
@@ -974,18 +978,18 @@ void mglCanvas::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3,
        y1=mgl_max(y1,d->y1);   y2=mgl_min(y2,d->y2);\r
 //     if(x1>x2 || y1>y2)      return;\r
 \r
-       dd = d1.x*d2.y-d1.y*d2.x;\r
-       dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y;\r
-       dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x;\r
+       const float dd = d1.x*d2.y-d1.y*d2.x;\r
+       const float dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y;\r
+       const float dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x;\r
 \r
        mglPoint n1(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z));\r
        mglPoint n2(mglPoint(p2.x-p4.x,p2.y-p4.y,p2.z-p4.z)^mglPoint(p3.x-p4.x,p3.y-p4.y,p3.z-p4.z));\r
        mglPoint nr((n1.x+n2.x)*0.5,(n1.y+n2.y)*0.5,(n1.z+n2.z)*0.5);\r
 \r
-       float x0 = p1.x, y0 = p1.y;\r
-       int oi = d->ObjId, ang=d->angle;\r
-       mreal pw = d->PenWidth;\r
-       uint64_t pd = d->PDef;\r
+       const float x0 = p1.x, y0 = p1.y;\r
+       const int oi = d->ObjId, ang=d->angle;\r
+       const mreal pw = d->PenWidth;\r
+       const uint64_t pd = d->PDef;\r
        for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
        {\r
                if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
@@ -1068,13 +1072,12 @@ void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3,
        {       fast_draw(p1,p2,d);     fast_draw(p1,p3,d);     fast_draw(p2,p3,d);     return; }\r
        unsigned char r[4];\r
        long y1,x1,y2,x2;\r
-       float dxu,dxv,dyu,dyv;\r
-       mglPnt d1(p2-p1), d2(p3-p1), p;\r
+       const mglPnt d1(p2-p1), d2(p3-p1);\r
 \r
-       dxu = d2.x*d1.y - d1.x*d2.y;\r
-       if(fabs(dxu)<1e-5)      return;         // points lies on the same line\r
-       dyv =-d1.x/dxu; dxv = d1.y/dxu;\r
-       dyu = d2.x/dxu; dxu =-d2.y/dxu;\r
+       const float tmp = d2.x*d1.y - d1.x*d2.y;\r
+       if(fabs(tmp)<1e-5)      return;         // points lies on the same line\r
+       const float dyv =-d1.x/tmp,     dxv = d1.y/tmp;\r
+       const float dyu = d2.x/tmp,     dxu =-d2.y/tmp;\r
 \r
        x1 = long(mgl_min(p1.x<p2.x?p1.x:p2.x, p3.x));  // bounding box\r
        y1 = long(mgl_min(p1.y<p2.y?p1.y:p2.y, p3.y));\r
@@ -1084,13 +1087,13 @@ void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3,
        y1=y1>d->y1?y1:d->y1;   y2=y2<d->y2?y2:d->y2;\r
 //     if(x1>x2 || y1>y2)      return;\r
        // default normale\r
-       mglPoint nr(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z));\r
-       float x0 = p1.x, y0 = p1.y;\r
-       float dz = Width>2 ? 1 : 1e-5*Width;    // provide additional height to be well visible on the surfaces\r
-       if(anorm)       dz=0;\r
-       int oi = d->ObjId, ang=d->angle;\r
-       mreal pw = d->PenWidth;\r
-       uint64_t pd = d->PDef;\r
+       const mglPoint nr(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z));\r
+       const float x0 = p1.x, y0 = p1.y;\r
+       // provide additional height to be well visible on the surfaces\r
+       const float dz = anorm? 0 : (Width>2 ? 1 : 1e-5*Width);\r
+       const int oi = d->ObjId, ang=d->angle;\r
+       const mreal pw = d->PenWidth;\r
+       const uint64_t pd = d->PDef;\r
        if(Quality&MGL_DRAW_NORM)       for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
        {\r
                if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
@@ -1098,7 +1101,7 @@ void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3,
                        register float xx = (i-x0), yy = (j-y0);\r
                        register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
                        if(u<0 || v<0 || u+v>1) continue;\r
-                       p = p1+d1*u+d2*v;\r
+                       mglPnt p(p1+d1*u+d2*v);\r
                        if(mgl_isnan(p.u) && mgl_isnum(p.v) && anorm)\r
                        {       p.u = nr.x;     p.v = nr.y;     p.w = nr.z;     }\r
                        pnt_plot(i,j,p.z+dz,col2int(p,r,oi),oi);\r
@@ -1143,37 +1146,35 @@ inline unsigned char mgl_sline(unsigned char c,float x)
 {      x*=x/2; return (unsigned char)((c)/(1+x+x*x/5));        }\r
 void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr)\r
 {\r
-       if((Quality&3)<2)       {       fast_draw(p1,p2,dr);    return; }\r
+       if((Quality&3)==MGL_DRAW_WIRE)  {       fast_draw(p1,p2,dr);    return; }       // previously was <2. This may slightly slow down for Quality=1\r
        unsigned char r[4];\r
        long y1,x1,y2,x2;\r
 \r
-       float pw=dr->PenWidth, dxu,dxv,dyu,dyv,dd,dpw=3;\r
-       float dz = Width>2 ? 1 : 1e-5*Width;            // provide additional height to be well visible on the surfaces\r
-       int oi = dr->ObjId;\r
-\r
-       if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
-       mglPnt d(p2-p1), p;\r
+       const float dz = Width>2 ? 1 : 1e-5*Width;              // provide additional height to be well visible on the surfaces\r
+       const int oi = dr->ObjId;\r
+       const float pw=dr->PenWidth*(oi==HighId?2:1), dpw=pen_delta*(oi==HighId?2:3);\r
+       const mglPnt d(p2-p1);\r
        bool hor = fabs(d.x)>fabs(d.y);\r
 \r
        x1 = long(p1.x<p2.x?p1.x:p2.x); y1 = long(p1.y<p2.y?p1.y:p2.y); // bounding box\r
        x2 = long(p1.x>p2.x?p1.x:p2.x); y2 = long(p1.y>p2.y?p1.y:p2.y);\r
-       x1 -= pw+3.5;   x2 += pw+3.5;\r
-       y1 -= pw+3.5;   y2 += pw+3.5;\r
+       x1 -= pw+10/dpw;        x2 += pw+10/dpw;\r
+       y1 -= pw+10/dpw;        y2 += pw+10/dpw;\r
        x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
        y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
-       dd = hypot(d.x, d.y);\r
+       const float dd = hypot(d.x, d.y);\r
 //     if(x1>x2 || y1>y2 || dd<1e-5)   return;\r
        if(dd<1e-5)     return;\r
 \r
-       dxv = d.y/dd;   dyv =-d.x/dd;\r
-       dxu = d.x/dd;   dyu = d.y/dd;\r
+       const float dxv = d.y/dd, dyv =-d.x/dd;\r
+       const float dxu = d.x/dd, dyu = d.y/dd;\r
 \r
-       uint64_t pd = dr->PDef;\r
-       mreal pp = dr->pPos;\r
+       const uint64_t pd = dr->PDef;\r
+       const mreal pp = dr->pPos;\r
        if(hor) for(long i=x1;i<=x2;i++)\r
        {\r
-               y1 = int(p1.y+d.y*(i-p1.x)/d.x - pw - 3.5);\r
-               y2 = int(p1.y+d.y*(i-p1.x)/d.x + pw + 3.5);\r
+               y1 = int(p1.y+d.y*(i-p1.x)/d.x - pw - 10/dpw);\r
+               y2 = int(p1.y+d.y*(i-p1.x)/d.x + pw + 10/dpw);\r
                y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
                if(y1>y2)       continue;\r
                for(long j=y1;j<=y2;j++)\r
@@ -1182,17 +1183,17 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
                        register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;    v = v*v;\r
                        if(u<0)                 v += u*u;\r
                        else if(u>dd)   v += (u-dd)*(u-dd);\r
-                       if(v>pw*pw)             continue;\r
+//                     if(v>pw*pw)             continue;\r
                        if(!(pd & ( 1L<<long(fmod(pp+u/pw/1.5, 16)) ) ))        continue;\r
-                       p = p1+d*(u/dd);        col2int(p,r,oi);\r
+                       mglPnt p(p1+d*(u/dd));  col2int(p,r,oi);\r
                        r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                        pnt_plot(i,j,p.z+dz,r,oi);\r
                }\r
        }\r
        else    for(long j=y1;j<=y2;j++)\r
        {\r
-               x1 = int(p1.x+d.x*(j-p1.y)/d.y - pw - 3.5);\r
-               x2 = int(p1.x+d.x*(j-p1.y)/d.y + pw + 3.5);\r
+               x1 = int(p1.x+d.x*(j-p1.y)/d.y - pw - 10/dpw);\r
+               x2 = int(p1.x+d.x*(j-p1.y)/d.y + pw + 10/dpw);\r
                x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
                if(x1>x2)       continue;\r
 \r
@@ -1202,9 +1203,9 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
                        register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;    v = v*v;\r
                        if(u<0)                 v += u*u;\r
                        else if(u>dd)   v += (u-dd)*(u-dd);\r
-                       if(v>pw*pw)             continue;\r
+//                     if(v>pw*pw)             continue;\r
                        if(!(pd & (1L<<long(fmod(pp+u/pw/1.5, 16)))))           continue;\r
-                       p = p1+d*(u/dd);        col2int(p,r,oi);\r
+                       mglPnt p(p1+d*(u/dd));  col2int(p,r,oi);\r
                        r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                        pnt_plot(i,j,p.z+dz,r,oi);\r
                }\r
@@ -1221,19 +1222,19 @@ void mglCanvas::pnt_fast(long x,long y,mreal z,const unsigned char ci[4], int ob
 void mglCanvas::fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr)\r
 {\r
        if(p1.x==p2.x && p1.y==p2.y) return;\r
-       mglPnt d(p2-p1);\r
-       int oi = dr->ObjId;\r
+       const mglPnt d(p2-p1);\r
+       const int oi = dr->ObjId;\r
        unsigned char r[4];     col2int(p1,r,oi);\r
        long y1,x1,y2,x2;\r
 \r
-       bool hor = fabs(d.x)>fabs(d.y);\r
+       const bool hor = fabs(d.x)>fabs(d.y);\r
 \r
        x1 = long(p1.x<p2.x?p1.x:p2.x); y1 = long(p1.y<p2.y?p1.y:p2.y); // bounding box\r
        x2 = long(p1.x>p2.x?p1.x:p2.x); y2 = long(p1.y>p2.y?p1.y:p2.y);\r
        x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
        y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
        if(x1>x2 || y1>y2)      return;\r
-       float dz = Width>2 ? 1 : 1e-5*Width;            // provide additional height to be well visible on the surfaces\r
+       const float dz = Width>2 ? 1 : 1e-5*Width;      // provide additional height to be well visible on the surfaces\r
 \r
        if(hor) for(long i=x1;i<=x2;i++)\r
        {\r
@@ -1258,8 +1259,8 @@ void mglCanvas::line_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, con
        register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;    v = v*v;\r
        if(u<0)                 v += u*u;\r
        else if(u>dd)   v += (u-dd)*(u-dd);\r
-       register float pw=dr->PenWidth, dpw=3;\r
-       if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2;  }\r
+       register float pw=dr->PenWidth, dpw=3*pen_delta;\r
+       if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2*pen_delta;        }\r
        if(v>pw*pw || !(dr->PDef & ( 1L<<long(fmod(dr->pPos+u/pw/1.5, 16)) ) )) return;\r
        mglPnt p(p1+d*(u/dd));\r
        unsigned char r[4];\r
@@ -1272,14 +1273,14 @@ void mglCanvas::line_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, con
 void mglCanvas::pnt_draw(const mglPnt &p, const mglDrawReg *dr)\r
 {\r
 //     if(k<0 || !dr)  return;\r
-       float pw=3*dr->PenWidth,dpw=3;\r
-       int oi = dr->ObjId;\r
-       if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
+       const int oi = dr->ObjId;\r
+       const float pw=(oi==HighId?6:3)*dr->PenWidth,dpw=(oi==HighId?2:3)*pen_delta;\r
        unsigned char cs[4], cc;\r
        col2int(p,cs,oi);       cc = cs[3];\r
        if(cc==0)       return;\r
-       long s = long(5.5+fabs(pw));\r
-       long i1=mgl_max(-s,dr->x1-p.x),i2=mgl_min(s,dr->x2-p.x), j1=mgl_max(-s,dr->y1-p.y),j2=mgl_min(s,dr->y2-p.y);\r
+       const long s = long(pw+10/dpw+fabs(pw));\r
+       const long i1=mgl_max(-s,dr->x1-p.x),i2=mgl_min(s,dr->x2-p.x);\r
+       const long j1=mgl_max(-s,dr->y1-p.y),j2=mgl_min(s,dr->y2-p.y);\r
        if(!(Quality&3))        for(long j=j1;j<=j2;j++)        for(long i=i1;i<=i2;i++)        // fast draw\r
        {\r
                register float v = i*i+j*j;\r
@@ -1296,33 +1297,36 @@ void mglCanvas::pnt_draw(const mglPnt &p, const mglDrawReg *dr)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pnt_pix(long i, long j, const mglPnt &p, const mglDrawReg *dr)\r
 {\r
-       register float pw=3*dr->PenWidth,dpw=3;\r
-       if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2;  }\r
+       register float pw=3*dr->PenWidth,dpw=3*pen_delta;\r
+       if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2*pen_delta;        }\r
        unsigned char cs[4];\r
        col2int(p,cs,dr->ObjId);\r
        register float xx = (i-p.x), yy = (j-p.y), v = xx*xx+yy*yy;\r
-       if(cs[3]==0 || v>(5.5+pw)*(5.5+pw))     return;\r
+       if(cs[3]==0 || v>(10/dpw+pw)*(10/dpw+pw))       return;\r
        if(v<(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],dpw*(sqrt(v)+(1-pw)/2));\r
        pnt_plot(i,j,p.z,cs,dr->ObjId);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)\r
 {\r
-       int oi = d->ObjId;\r
-       unsigned char cs[4], ca;        col2int(q,cs,oi);       ca = cs[3];// = size>0 ? 255 : 255*q.t;\r
-       mreal ss=fabs(size), pw=1,dpw=3;\r
+       const int oi = d->ObjId;\r
+       unsigned char cs[4];    col2int(q,cs,oi);\r
+       const unsigned char ca = cs[3];// = size>0 ? 255 : 255*q.t;\r
+       const mreal ss=(strchr("xsSoO",type)?1:1.1)*fabs(size), dpw=(oi==HighId?2:3)*pen_delta;\r
+       mreal PW=1;\r
 \r
        if(type=='.' || ss==0)\r
        {\r
-               if(d)   pw = 3*(ss?ss:sqrt(font_factor/400));\r
-               register mreal dd = pw+3.5;\r
+               if(d)   PW = 3*(ss?ss:sqrt(font_factor/400));\r
+               if(oi==HighId)  PW *= 2;\r
+               const mreal pw = PW;\r
+               register mreal dd = pw+10/dpw;\r
                long x1 = long(q.x-dd), y1 = long(q.y-dd);      // bounding box\r
                long x2 = long(q.x+dd), y2 = long(q.y+dd);\r
                x1=x1>d->x1?x1:d->x1;   x2=x2<d->x2?x2:d->x2;\r
                y1=y1>d->y1?y1:d->y1;   y2=y2<d->y2?y2:d->y2;\r
                if(x1>x2 || y1>y2)      return;\r
 \r
-               if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
                for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
                {\r
                        register float dx=i-q.x, dy=j-q.y, v=dx*dx+dy*dy;\r
@@ -1336,13 +1340,13 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                if(d)\r
                {\r
                        d->PDef = MGL_SOLID_MASK;       d->angle = 0;\r
-                       pw = d->PenWidth*sqrt(fabs(50*size));\r
-                       if(pw<1)        pw=1;\r
+                       PW = d->PenWidth*sqrt(fabs(50*size));\r
+                       if(PW<1)        PW=1;\r
                }\r
-               if(!strchr("xsSoO",type))       ss *= 1.1;\r
-               if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
+               if(oi==HighId)  PW *= 2;\r
+               const mreal pw = PW;\r
 \r
-               register mreal dd = ss+pw+3.5;\r
+               register mreal dd = ss+pw+10/dpw;\r
                long x1 = long(q.x-dd), y1 = long(q.y-dd);      // bounding box\r
                long x2 = long(q.x+dd), y2 = long(q.y+dd);\r
                x1=x1>d->x1?x1:d->x1;   x2=x2<d->x2?x2:d->x2;\r
@@ -1811,7 +1815,7 @@ void mglCanvas::mark_pix(long i, long j, const mglPnt &q, char type, mreal size,
                                register float pw=d->PenWidth;\r
                                register float xx = (i-q.x), yy = (j-q.y), v = hypot(xx,yy);\r
                                v = (v-ss)*(v-ss);\r
-                               if(v>pw*pw)     return;\r
+//                             if(v>pw*pw)     return;\r
                                if(v>(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],2*(sqrt(v)+(1-pw)/2));\r
                                register float dz = Width>2 ? 1 : 1e-5*Width;           // provide additional height to be well visible on the surfaces\r
                                pnt_plot(i,j,q.z+dz,cs,d->ObjId);\r
@@ -1823,7 +1827,7 @@ void mglCanvas::mark_pix(long i, long j, const mglPnt &q, char type, mreal size,
                                register float pw=d->PenWidth;\r
                                register float xx = (i-q.x), yy = (j-q.y), v = hypot(xx,yy);\r
                                v = (v-ss)*(v-ss);\r
-                               if(v>pw*pw)     return;\r
+//                             if(v>pw*pw)     return;\r
                                if(v>(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],2*(sqrt(v)+(1-pw)/2));\r
                                register float dz = Width>2 ? 1 : 1e-5*Width;           // provide additional height to be well visible on the surfaces\r
                                pnt_plot(i,j,q.z+dz,cs,d->ObjId);\r
index c0c6787dc6533b7127d433c1b2d98de73671dbd4..4226c3133bd5f44eaa0ed1fb38bf581d70e1f4aa 100644 (file)
@@ -511,15 +511,15 @@ void MGL_EXPORT mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 \r
                nn.Set(-y->dvx(0,my),x->dvx(0,mx));\r
                mglPoint p(x->v(0,mx),y->v(0,my),z->v(0,mz));\r
-               long n1 = gr->AddPnt(p,c1,nn,-1,11);    p.z = z0;\r
-               long n2 = gr->AddPnt(p,c2,nn,-1,11);\r
+               long n1 = gr->AddPnt(p,c1,nn,-1,27);    p.z = z0;\r
+               long n2 = gr->AddPnt(p,c2,nn,-1,27);\r
                for(long i=1;i<n;i++)\r
                {\r
                        long n3=n1, n4=n2;\r
                        nn.Set(-y->dvx(i,my),x->dvx(i,mx));\r
                        p.Set(x->v(i,mx),y->v(i,my),z->v(i,mz));\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
-                       n1 = gr->AddPnt(p,c1,nn,-1,11); p.z = z0;       n2 = gr->AddPnt(p,c2,nn,-1,11);\r
+                       n1 = gr->AddPnt(p,c1,nn,-1,27); p.z = z0;       n2 = gr->AddPnt(p,c2,nn,-1,27);\r
                        if(wire)\r
                        {\r
                                gr->line_plot(n1,n2);   gr->line_plot(n3,n4);\r
@@ -556,14 +556,14 @@ void MGL_EXPORT mgl_area_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
                mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
 \r
                mglPoint p(x->v(0,mx),y->v(0,my),z0);\r
-               long n1 = gr->AddPnt(p,c1,nn,-1,11);    p.y = y0;\r
-               long n2 = gr->AddPnt(p,c2,nn,-1,11);\r
+               long n1 = gr->AddPnt(p,c1,nn,-1,27);    p.y = y0;\r
+               long n2 = gr->AddPnt(p,c2,nn,-1,27);\r
                for(long i=1;i<n;i++)\r
                {\r
                        long n3=n1, n4=n2;\r
                        p.Set(x->v(i,mx),y->v(i,my),z0);\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
-                       n1 = gr->AddPnt(p,c1,nn,-1,11); p.y = y0;       n2 = gr->AddPnt(p,c2,nn,-1,11);\r
+                       n1 = gr->AddPnt(p,c1,nn,-1,27); p.y = y0;       n2 = gr->AddPnt(p,c2,nn,-1,27);\r
                        if(wire)\r
                        {\r
                                gr->line_plot(n1,n2);   gr->line_plot(n3,n4);\r
@@ -631,14 +631,14 @@ void MGL_EXPORT mgl_region_3d(HMGL gr, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT
                long mz = (zhave && j<z1->GetNy()) ? j:0;\r
                mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
 \r
-               long n1 = gr->AddPnt(mglPoint(x1->v(0,mx),y1->v(0,my),zhave?z1->v(0,mz):z0),c1,nn,-1,11);\r
-               long n2 = gr->AddPnt(mglPoint(x2->v(0,mx),y2->v(0,my),zhave?z2->v(0,mz):z0),c2,nn,-1,11);\r
+               long n1 = gr->AddPnt(mglPoint(x1->v(0,mx),y1->v(0,my),zhave?z1->v(0,mz):z0),c1,nn,-1,27);\r
+               long n2 = gr->AddPnt(mglPoint(x2->v(0,mx),y2->v(0,my),zhave?z2->v(0,mz):z0),c2,nn,-1,27);\r
                for(long i=1;i<n;i++)\r
                {\r
                        long n3=n1, n4=n2;\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
-                       n1 = gr->AddPnt(mglPoint(x1->v(i,mx),y1->v(i,my),zhave?z1->v(i,mz):z0),c1,nn,-1,11);\r
-                       n2 = gr->AddPnt(mglPoint(x2->v(i,mx),y2->v(i,my),zhave?z2->v(i,mz):z0),c2,nn,-1,11);\r
+                       n1 = gr->AddPnt(mglPoint(x1->v(i,mx),y1->v(i,my),zhave?z1->v(i,mz):z0),c1,nn,-1,27);\r
+                       n2 = gr->AddPnt(mglPoint(x2->v(i,mx),y2->v(i,my),zhave?z2->v(i,mz):z0),c2,nn,-1,27);\r
                        gr->quad_plot(n1,n2,n3,n4);\r
                }\r
        }\r
@@ -670,16 +670,16 @@ void MGL_EXPORT mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen
                mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
 \r
                mreal f1 = y1->v(0,j), f2 = y2->v(0,j), xx = x->v(0,mx);\r
-               long n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,11);\r
-               long n2 = gr->AddPnt(mglPoint(xx,f2,z0),c2,nn,-1,11);\r
+               long n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,27);\r
+               long n2 = gr->AddPnt(mglPoint(xx,f2,z0),c2,nn,-1,27);\r
                for(long i=1;i<n;i++)\r
                {\r
                        long n3=n1, n4=n2;\r
                        mreal f3=f1, f4=f2;\r
                        f1 = y1->v(i,j);        f2 = y2->v(i,j);        xx = x->v(i,mx);\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
-                       n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,11);\r
-                       n2 = gr->AddPnt(mglPoint(xx,f2,z0),c2,nn,-1,11);\r
+                       n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,27);\r
+                       n2 = gr->AddPnt(mglPoint(xx,f2,z0),c2,nn,-1,27);\r
                        if(!inside || (f2>f1 && f4>f3)) gr->quad_plot(n1,n2,n3,n4);\r
                }\r
        }\r
@@ -1327,10 +1327,10 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                        {\r
                                mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
                                mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                               long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,11);\r
-                               long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,11);\r
-                               long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,11);\r
-                               long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,11);\r
+                               long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27);\r
+                               long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27);\r
+                               long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27);\r
+                               long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27);\r
                                gr->line_plot(n1,n2);   gr->line_plot(n1,n3);\r
                                gr->line_plot(n4,n2);   gr->line_plot(n4,n3);\r
                        }\r
@@ -1338,10 +1338,10 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                        {\r
                                mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
                                mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                               long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
-                               long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,11);\r
-                               long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
-                               long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,11);\r
+                               long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
+                               long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,27);\r
+                               long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
+                               long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,27);\r
                                gr->line_plot(n1,n2);   gr->line_plot(n2,n3);\r
                                gr->line_plot(n3,n4);   gr->line_plot(n4,n1);\r
                        }\r
@@ -1354,7 +1354,7 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                {\r
                                        n1 = n2;\r
                                        n2 = gr->AddPnt(mglPoint(vx+ve*mgl_cos[(18*k)%360],\r
-                                                       vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,11);\r
+                                                       vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,27);\r
                                        if(k>0) gr->line_plot(n1,n2);\r
                                }\r
                        }\r
@@ -1365,10 +1365,10 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
                                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
-                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,11);\r
-                                       long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
-                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,11);\r
+                                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
+                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,27);\r
+                                       long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
+                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,27);\r
                                        gr->line_plot(n1,n3);   gr->line_plot(n2,n4);\r
                                }       break;\r
                        case 'X':       case 'x':\r
@@ -1376,10 +1376,10 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
                                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,11);\r
-                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,11);\r
-                                       long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,11);\r
-                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,11);\r
+                                       long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27);\r
+                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27);\r
+                                       long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27);\r
+                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27);\r
                                        gr->line_plot(n1,n4);   gr->line_plot(n2,n3);\r
                                }       break;\r
                        case 'S':\r
@@ -1387,10 +1387,10 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
                                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,11);\r
-                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,11);\r
-                                       long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,11);\r
-                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,11);\r
+                                       long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27);\r
+                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27);\r
+                                       long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27);\r
+                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27);\r
                                        gr->quad_plot(n1,n2,n3,n4);\r
                                }       break;\r
                        case 'D':\r
@@ -1398,10 +1398,10 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
                                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
-                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,11);\r
-                                       long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
-                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,11);\r
+                                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
+                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,27);\r
+                                       long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
+                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,27);\r
                                        gr->quad_plot(n1,n4,n2,n3);\r
                                }       break;\r
                        case 'O':\r
@@ -1414,7 +1414,7 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                        {\r
                                                n1 = n2;\r
                                                n2 = gr->AddPnt(mglPoint(vx+ve*mgl_cos[(18*k)%360],\r
-                                                               vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,11);\r
+                                                               vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,27);\r
                                                if(k>0) gr->trig_plot(n1,n2,n3);\r
                                        }\r
                                }       break;\r
@@ -1432,12 +1432,12 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        if(mk)  gr->mark_plot(gr->AddPnt(mglPoint(vx,vy,zVal),c), mk);\r
 \r
-                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
-                       long n2 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
+                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
+                       long n2 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
                        gr->line_plot(n1,n2);   gr->arrow_plot(n1,n2,'I');      gr->arrow_plot(n2,n1,'I');\r
 \r
-                       n1 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),-1,q,c,11);\r
-                       n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),-1,q,c,11);\r
+                       n1 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),-1,q,c,27);\r
+                       n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),-1,q,c,27);\r
                        gr->line_plot(n1,n2);   gr->arrow_plot(n1,n2,'I');      gr->arrow_plot(n2,n1,'I');\r
                }\r
        }\r
@@ -1581,7 +1581,7 @@ void MGL_EXPORT mgl_mark_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char
        m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
        m = z->GetNy() > m ? z->GetNy() : m;\r
        char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(n*m);\r
-       if(mk==0)       return;\r
+       if(mk==0)       mk='.';\r
        bool sh = mglchr(pen,'!');\r
 \r
        for(long j=0;j<m;j++)\r
@@ -1860,3 +1860,72 @@ void MGL_EXPORT mgl_tape_(uintptr_t *gr, uintptr_t *y,   const char *pen, const ch
        char *o=new char[lo+1];         memcpy(o,opt,lo);       o[lo]=0;\r
        mgl_tape(_GR_, _DA_(y),s,o);    delete []s;     delete []o;     }\r
 //-----------------------------------------------------------------------------\r
+//\r
+//     Pmap series\r
+//\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pmap_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt)\r
+{\r
+       long m,n=y->GetNx(),pal;\r
+       if(mgl_check_dim0(gr,x,y,z,r,"Mark"))   return;\r
+\r
+       gr->SaveState(opt);\r
+       static int cgid=1;      gr->StartGroup("Mark",cgid++);\r
+       m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
+       m = z->GetNy() > m ? z->GetNy() : m;\r
+       char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(n*m);\r
+       if(mk==0)       mk='.';\r
+\r
+       for(long j=0;j<m;j++)\r
+       {\r
+               if(gr->NeedStop())      break;\r
+               gr->NextColor(pal);\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
+               for(long i=0;i<n-1;i++)\r
+               {\r
+                       mreal r1=r->v(i,mr), r2 = r->v(i+1,mr);\r
+                       if(r1==0)       gr->mark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz))), mk);\r
+                       if(r1*r2<0)\r
+                       {\r
+                               mreal d = r1/(r1-r2);\r
+                               mglPoint p(x->v(i,mx)*(1-d)+x->v(i+1,mx)*d, y->v(i,my)*(1-d)+y->v(i+1,my)*d, z->v(i,mz)*(1-d)+d*z->v(i+1,mz));\r
+                               gr->mark_plot(gr->AddPnt(p), mk);\r
+                       }\r
+               }\r
+       }\r
+       gr->EndGroup();\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pmap_xy(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt)\r
+{\r
+       gr->SaveState(opt);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
+       mgl_pmap_xyz(gr,x,y,&z,r,pen,0);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pmap(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt)\r
+{\r
+       register long n=y->GetNx();\r
+       gr->SaveState(opt);\r
+       mglDataV x(n), z(n);\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
+       mgl_pmap_xyz(gr,&x,y,&z,r,pen,0);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pmap_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,pen,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_pmap_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r),s,o);\r
+       delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pmap_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,pen,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_pmap_xy(_GR_, _DA_(x), _DA_(y), _DA_(r),s,o);       delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_pmap_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,pen,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_pmap(_GR_,_DA_(y),_DA_(r),s,o);     delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
index 8d5c1f23453494546d67c6d202824e8429d99060..d62c0868b8f6dc7f39e8d77f5c674530ef6b52bf 100644 (file)
@@ -918,7 +918,7 @@ void MGL_EXPORT mgl_logo(HMGL gr, long w, long h, const unsigned char *rgba, int
                gr->Reserve(4*(w+1)*(h+1));\r
                for(long j=0;j<h;j++)   for(long i=0;i<w;i++)\r
                {\r
-                       long i0 = 4*(w-1-i+w*j), k1,k2,k3,k4;\r
+                       long i0 = 4*(i+w*(h-1-j)), k1,k2,k3,k4;\r
                        mglColor c(rgba[i0]/255.,rgba[i0+1]/255.,rgba[i0+2]/255.);\r
                        k1 = gr->AddPnt(mglPoint(x1+dx*i,y1+dy*j,z),0); gr->SetRGBA(k1,c);\r
                        k2 = gr->AddPnt(mglPoint(x1+dx*(i+1),y1+dy*j,z),0);     gr->SetRGBA(k2,c);\r
@@ -934,7 +934,7 @@ void MGL_EXPORT mgl_logo(HMGL gr, long w, long h, const unsigned char *rgba, int
                long *pos = new long[w*h];\r
                for(long j=0;j<h;j++)   for(long i=0;i<w;i++)\r
                {\r
-                       long i0 = 4*(w-1-i+w*j), i1 = i+w*j;\r
+                       long i0 = 4*(i+w*(h-1-j)), i1 = i+w*j;\r
                        pos[i1] = gr->AddPnt(mglPoint(x1+dx*i,y1+dy*j,z),0);\r
                        gr->SetRGBA(pos[i1],mglColor(rgba[i0]/255.,rgba[i0+1]/255.,rgba[i0+2]/255.));\r
                }\r
@@ -963,3 +963,144 @@ void MGL_EXPORT mgl_logo_file_(uintptr_t *gr, const char *fname, int *smooth, co
        char *f=new char[n+1];  memcpy(f,opt,n);        f[n]=0;\r
        mgl_logo_file(_GR_,s,*smooth,f);        delete []s;             delete []f;     }\r
 //-----------------------------------------------------------------------------\r
+//\r
+//     Lamerey series\r
+//\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_lamerey(HMGL gr, double x0, double (*f)(double,void *), void *par, const char *stl, const char *opt)\r
+{\r
+       static int cgid=1;      gr->StartGroup("Lamerey",cgid++);\r
+       mreal r=gr->SaveState(opt);\r
+       double x=x0, dx = 1e-5*fabs(gr->Max.x-gr->Min.x);\r
+       long n = r>2 ? long(r+0.5):20, n1, n2;\r
+       gr->SetPenPal(stl);     gr->Reserve(6*n+1);\r
+       bool vect = mglchr(stl,'v');\r
+       n2 = gr->AddPnt(mglPoint(x,x,gr->Max.z));\r
+       if(!mglchr(stl,'~'))\r
+       {\r
+               n1 = gr->AddPnt(mglPoint(x,gr->GetOrgY('x'),gr->Max.z));\r
+               gr->line_plot(n1,n2);   if(vect)        gr->vect_plot(n1,n2,0.3*gr->GetArrowSize());\r
+       }\r
+       for(long i=0;i<n;i++)\r
+       {\r
+               x0 = x;         x = f(x0,par);\r
+               if(fabs(x-x0)<dx)       break;\r
+               n1=n2;  n2 = gr->AddPnt(mglPoint(x0,x,gr->Max.z));\r
+               gr->line_plot(n1,n2);   if(vect)        gr->vect_plot(n1,n2,0.3*gr->GetArrowSize());\r
+               n1=n2;  n2 = gr->AddPnt(mglPoint(x,x,gr->Max.z));\r
+               gr->line_plot(n1,n2);   if(vect)        gr->vect_plot(n1,n2,0.3*gr->GetArrowSize());\r
+       }\r
+       gr->EndGroup();\r
+}\r
+//-----------------------------------------------------------------------------\r
+struct mglDatSpl       {       HCDT d; double x0,dx;   double y0,dy;   };\r
+double MGL_NO_EXPORT func_dat(double x, void *p)\r
+{      mglDatSpl *s = (mglDatSpl *)p;  return s->d->value((x-s->x0)*s->dx);    }\r
+void MGL_EXPORT mgl_lamerey_dat(HMGL gr, double x0, HCDT f, const char *stl, const char *opt)\r
+{\r
+       mreal r = gr->SaveState(opt);\r
+       char buf[64]="";        if(r>2) sprintf(buf,"value %g",r);\r
+       mglDatSpl s;    s.d=f;  s.x0=gr->Min.x; s.dx=f->GetNx()/(gr->Max.x-gr->Min.x);\r
+       mgl_lamerey(gr,x0,func_dat,&s,stl,buf);\r
+}\r
+//-----------------------------------------------------------------------------\r
+double MGL_NO_EXPORT func_str(double x, void *p)\r
+{      HMEX s = (HMEX)p;       return mgl_expr_eval(s,x,0,0);  }\r
+void MGL_EXPORT mgl_lamerey_str(HMGL gr, double x0, const char *f, const char *stl, const char *opt)\r
+{\r
+       HMEX eq = mgl_create_expr(f);\r
+       mgl_lamerey(gr,x0,func_str,eq,stl,opt);\r
+       mgl_delete_expr(eq);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_lamerey_dat_(uintptr_t *gr, double *x0, uintptr_t *f, const char *stl, const char *opt, int l,int n)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       char *o=new char[n+1];  memcpy(o,opt,n);        o[n]=0;\r
+       mgl_lamerey_dat(_GR_,*x0,_DA_(f),s,o);  delete []s;     delete []o;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_lamerey_str_(uintptr_t *gr, double *x0, const char *func, const char *stl, const char *opt, int m,int l,int n)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       char *o=new char[n+1];  memcpy(o,opt,n);        o[n]=0;\r
+       char *f=new char[m+1];  memcpy(f,func,m);       f[m]=0;\r
+       mgl_lamerey_str(_GR_,*x0,f,s,o);        delete []f;     delete []s;     delete []o;     }\r
+//-----------------------------------------------------------------------------\r
+//\r
+//     Bifurcation series\r
+//\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_bifurcation(HMGL gr, double dx, double (*f)(double,double,void *), void *par, const char *stl, const char *opt)\r
+{\r
+       if((gr->Max.x-gr->Min.x)*dx<=0) {       gr->SetWarn(mglWarnSlc,"Bifurcation");  return; }\r
+       static int cgid=1;      gr->StartGroup("Bifurcation",cgid++);\r
+       mreal res=gr->SaveState(opt);\r
+       long n = res>2 ? long(res+0.5):1024, m=(gr->Max.x-gr->Min.x)/dx, m1=0,m2=0;\r
+       gr->SetPenPal(stl);     gr->Reserve(2*n*m);\r
+       double *v1=new double[n], *v2=new double[n], dd=0.1*fabs(gr->Max.y-gr->Min.y)/n;\r
+       double r = gr->Min.y+mgl_rnd()*(gr->Max.y-gr->Min.y), r0 = r;\r
+\r
+       bool fin=false;\r
+       for(long i=0;i<10*n;i++)        r = f(gr->Min.x,r,par); // wait for loop stabilization\r
+       for(m1=0;m1<n;m1++)     // collect period information\r
+       {\r
+               r = f(gr->Min.x,r,par);\r
+               for(long j=0;j<m1;j++)  if(fabs(v1[j]-r)<dd)\r
+               {       fin=true;       break;  }\r
+               if(fin) break;  v1[m1]=r;\r
+       }\r
+       for(mreal xx = gr->Min.x+dx;xx<=gr->Max.x;xx+=dx)\r
+       {\r
+               m2=m1;  memcpy(v2,v1,n*sizeof(double)); r=r0;\r
+               for(long i=0;i<10*n;i++)        r = f(xx,r,par);        // wait for loop stabilization\r
+               for(fin=false,m1=0;m1<n;m1++)   // collect period information\r
+               {\r
+                       r = f(xx,r,par);\r
+                       for(long j=0;j<m1;j++)  if(fabs(v1[j]-r)<dd)\r
+                       {       fin=true;       break;  }\r
+                       if(fin) break;  v1[m1]=r;\r
+               }\r
+               if(m1>=m2)      for(long i=0;i<m1;i++)\r
+               {\r
+                       double vv=v2[0], vi=v1[i];\r
+                       for(long j=1;j<m2;j++)  if(fabs(v2[j]-vi)<fabs(vv-vi))  vv = v2[j];\r
+                       gr->line_plot(gr->AddPnt(mglPoint(xx-dx,vv,gr->Max.z)), gr->AddPnt(mglPoint(xx,v1[i],gr->Max.z)));\r
+               }\r
+               else    for(long i=0;i<m1;i++)\r
+                       gr->line_plot(gr->AddPnt(mglPoint(xx-dx,v1[i],gr->Max.z)), gr->AddPnt(mglPoint(xx,v1[i],gr->Max.z)));\r
+       }\r
+       gr->EndGroup(); delete []v1;    delete []v2;\r
+}\r
+//-----------------------------------------------------------------------------\r
+double MGL_NO_EXPORT bif_dat(double x, double y, void *p)\r
+{      mglDatSpl *s = (mglDatSpl *)p;  return s->d->value((x-s->x0)*s->dx, (y-s->y0)*s->dy);   }\r
+void MGL_EXPORT mgl_bifurcation_dat(HMGL gr, double dx, HCDT f, const char *stl, const char *opt)\r
+{\r
+       if(dx==0 || (gr->Max.x-gr->Min.x)*dx<0) {       gr->SetWarn(mglWarnSlc,"Bifurcation");  return; }\r
+       if(f->GetNy()<2)        {       gr->SetWarn(mglWarnLow,"Bifurcation");  return; }\r
+       mreal r = gr->SaveState(opt);\r
+       char buf[64]="";        if(r>2) sprintf(buf,"value %g",r);\r
+       mglDatSpl s;    s.d=f;\r
+       s.x0=gr->Min.x; s.dx=f->GetNx()/(gr->Max.x-gr->Min.x);\r
+       s.y0=gr->Min.y; s.dy=f->GetNy()/(gr->Max.y-gr->Min.y);\r
+       mgl_bifurcation(gr,dx,bif_dat,&s,stl,buf);\r
+}\r
+//-----------------------------------------------------------------------------\r
+double MGL_NO_EXPORT bif_str(double x, double y, void *p)\r
+{      HMEX s = (HMEX)p;       return mgl_expr_eval(s,x,y,0);  }\r
+void MGL_EXPORT mgl_bifurcation_str(HMGL gr, double dx, const char *f, const char *stl, const char *opt)\r
+{\r
+       HMEX eq = mgl_create_expr(f);\r
+       mgl_bifurcation(gr,dx,bif_str,eq,stl,opt);\r
+       mgl_delete_expr(eq);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_bifurcation_dat_(uintptr_t *gr, double *dx, uintptr_t *f, const char *stl, const char *opt, int l,int n)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       char *o=new char[n+1];  memcpy(o,opt,n);        o[n]=0;\r
+       mgl_bifurcation_dat(_GR_,*dx,_DA_(f),s,o);      delete []s;     delete []o;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_bifurcation_str_(uintptr_t *gr, double *dx, const char *func, const char *stl, const char *opt, int m,int l,int n)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       char *o=new char[n+1];  memcpy(o,opt,n);        o[n]=0;\r
+       char *f=new char[m+1];  memcpy(f,func,m);       f[m]=0;\r
+       mgl_bifurcation_str(_GR_,*dx,f,s,o);    delete []f;     delete []s;     delete []o;     }\r
+//-----------------------------------------------------------------------------\r
index 2ff4236fb4377177dab35bd77a61ac1bc1fba095..eb022b442af388b3b9bc90c3b6f3cdc0ce68a856 100644 (file)
@@ -532,6 +532,10 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
 
                        }
 
+       if (e1 < 0) {
+               // Cannot find visible point - it might be caused by numerical issues on some kind of datasets
+               return (-5);
+       }
 
                        // triangle pidx starts at e1 and ends at e2 (inclusive).
                        if( e2 < numh )
@@ -766,20 +770,31 @@ void circle_cent4(double r1,double c1, double r2,double c2, double r3,double c3,
 }
 
 
+namespace {
+
+/**
+ * Rounds the value given to the nearest multiple of the epsilon given
+ */
+double coarsen(const double value, const double epsilon) {
+       const double minimal_epsilon = std::numeric_limits<double>::epsilon() * value;
+       return (epsilon < minimal_epsilon) ? value : floor(value / epsilon + 0.5) * epsilon;
+}
+
+}
+
 /* test a set of points for duplicates.
 
    erase duplicate points, do not change point ids.
 
 */
 
-long de_duplicate( std::vector<Shx> &pts, std::vector<long> &outx ) {
-
+long de_duplicate( std::vector<Shx> &pts, std::vector<long> &outx, const Dupex epsilon ) {
        long nump = (long) pts.size();
        std::vector<Dupex> dpx;
        Dupex d;
        for( long k=0; k<nump; k++) {
-               d.r = pts[k].r;
-               d.c = pts[k].c;
+               d.r = coarsen(pts[k].r, epsilon.r);
+               d.c = coarsen(pts[k].c, epsilon.c);
                d.id = k;
                dpx.push_back(d);
        }
index ceb81b0a58cdb0a70839b190277962499e83e29b..f9bb4180968b0823104573c50a2907c371314b68 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <vector>
 #include <set>
+#include <limits>
 
 /*
        for use in s_hull_pro.cpp
@@ -137,7 +138,7 @@ long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<
 long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, std::set<long> &ids);
 
 long read_Shx(std::vector<Shx> &pts, char * fname);
-long de_duplicate( std::vector<Shx> &pts,  std::vector<long> &outx );
+long de_duplicate( std::vector<Shx> &pts,  std::vector<long> &outx, Dupex epsilon = Dupex(std::numeric_limits<float>::epsilon(),std::numeric_limits<float>::epsilon()) );
 long de_duplicateX( std::vector<Shx> &pts, std::vector<long> &outx,std::vector<Shx> &pts2 );
 long  test_center(Shx &pt0, Shx &pt1,Shx &pt2);
 
index 9983da4df7fe2e511a555032e1aa68e3b1767ec6..1e3c23a37c42a182a7688f73f8112407ca26dc8a 100644 (file)
@@ -21,7 +21,6 @@
 #include "mgl2/eval.h"\r
 #include "mgl2/data.h"\r
 #include "mgl2/base.h"\r
-#define MGL_FLOW_ACC   0.05    // accuracy of loop detection\r
 //-----------------------------------------------------------------------------\r
 //\r
 //     Traj series\r
@@ -72,7 +71,7 @@ void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
                                dd = dd ? sqrt(dx*dx+dy*dy+dz*dz)/dd : 0;\r
                        }\r
                        else dd = len;\r
-                       gr->vect_plot(gr->AddPnt(p1), gr->AddPnt(p1+dd*p2,-1,mglPoint(NAN),-1,2));\r
+                       gr->vect_plot(gr->AddPnt(p1), gr->AddPnt(p1+dd*p2,-1,mglPoint(NAN),-1,2),gr->GetArrowSize());\r
                }\r
        }\r
        gr->EndGroup();\r
@@ -168,7 +167,7 @@ void MGL_EXPORT mgl_vect_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
                        if(n1<0 && n2>=0)       n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
                        if(n2<0 && n1>=0)       n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
                        if(dot) {       gr->line_plot(n1,n2);   gr->mark_plot(n1,'.');  }\r
-                       else    gr->vect_plot(n1,n2);\r
+                       else    gr->vect_plot(n1,n2,gr->GetArrowSize());\r
                }\r
        }\r
        gr->EndGroup();\r
@@ -267,7 +266,7 @@ void MGL_EXPORT mgl_vect_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
                        if(n1<0 && n2>=0)       n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
                        if(n2<0 && n1>=0)       n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
                        if(dot) {       gr->line_plot(n1,n2);   gr->mark_plot(n1,'.');  }\r
-                       else    gr->vect_plot(n1,n2);\r
+                       else    gr->vect_plot(n1,n2,gr->GetArrowSize());\r
                }\r
        }\r
        gr->EndGroup();\r
@@ -469,7 +468,7 @@ void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
                if(n1<0 && n2>=0)       n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
                if(n2<0 && n1>=0)       n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
                if(dot) {       gr->line_plot(n1,n2);   gr->mark_plot(n1,'.');  }\r
-               else    gr->vect_plot(n1,n2);\r
+               else    gr->vect_plot(n1,n2,gr->GetArrowSize());\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -501,26 +500,29 @@ void MGL_EXPORT mgl_vect3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, long ss, bool vv)\r
 {\r
-       long n=10*(ax.nx+ax.ny);\r
+       long n=100*(ax.nx+ax.ny);\r
        bool nboth = x.nx*x.ny!=ax.nx*ax.ny || y.nx*y.ny!=ax.nx*ax.ny;\r
 \r
        mglPoint *pp = new mglPoint[n], dp;\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
+       mglPoint nx(ax.nx,ax.ny);\r
 \r
-       mreal dt = 0.5/(ax.nx > ax.ny ? ax.nx : ax.ny),e,f,g,ff[4],gg[4],h,s=2;\r
+       mreal dt = 0.5/(ax.nx > ax.ny ? ax.nx : ax.ny),e,f,g,ff[4],gg[4],h,s=2,acc=dt/20;\r
        if(u<0 || v<0)  {       dt = -dt;       u = -u; v = -v; s *= -1;}\r
-       register long k=0,m;\r
+       long k=0;\r
        bool end = false;\r
        if(nboth) do{\r
                mglPoint dif;\r
                pp[k].x = x.Spline1(dif,u,0,0); f = ax.Spline1(u,v,0)/dif.x;\r
                pp[k].y = y.Spline1(dif,v,0,0); g = ay.Spline1(u,v,0)/dif.x;\r
                pp[k].z = zVal;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt*MGL_FLOW_ACC)  {       end = true;     break;  }\r
+               if(mgl_isbad(f+g))      end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = hypot(f,g); pp[k].c = gr->GetC(ss,s*h);\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                e = u+ff[0]/2;  h = v+gg[0]/2;\r
@@ -543,16 +545,18 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
        else do{\r
                mglPoint dif;\r
                register mreal xu,xv,yu,yv,det,xx,yy;\r
-                       pp[k].x = x.Spline1(dif,u,v,0); xu=dif.x;       xv=dif.y;\r
-                       pp[k].y = y.Spline1(dif,u,v,0); yu=dif.x;       yv=dif.y;\r
-                       xx = ax.Spline1(u,v,0); yy = ay.Spline1(u,v,0);\r
-                       det = xv*yu-xu*yv;      f = (yy*xv-xx*yv)/det;  g = (xx*yu-yy*xu)/det;\r
+               pp[k].x = x.Spline1(dif,u,v,0); xu=dif.x;       xv=dif.y;\r
+               pp[k].y = y.Spline1(dif,u,v,0); yu=dif.x;       yv=dif.y;\r
+               xx = ax.Spline1(u,v,0); yy = ay.Spline1(u,v,0);\r
+               det = xv*yu-xu*yv;      f = (yy*xv-xx*yv)/det;  g = (xx*yu-yy*xu)/det;\r
                pp[k].z = zVal;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt*MGL_FLOW_ACC)  {       end = true;     break;  }\r
+               if(mgl_isbad(f+g))      end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = hypot(f,g); pp[k].c = gr->GetC(ss,s*h);\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                e = u+ff[0]/2;  h = v+gg[0]/2;\r
@@ -580,15 +584,15 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
        } while(!end);\r
        if(k>1)\r
        {\r
-               long j,a=long(1./fabs(dt));\r
+               long j,a=long(0.3*gr->GetArrowSize()/fabs(dt));\r
                gr->Reserve(k);         j = gr->AddPnt(pp[0],pp[0].c);\r
                for(long i=1;i<k;i++)\r
                {\r
                        long jj=j;      j = gr->AddPnt(pp[i],pp[i].c);\r
                        if(vv && i%a==0)\r
                        {\r
-                               if(dt<0)        gr->vect_plot(j,jj,a/5);\r
-                               else            gr->vect_plot(jj,j,a/5);\r
+                               if(dt<0)        gr->vect_plot(j,jj,a/3);\r
+                               else            gr->vect_plot(jj,j,a/3);\r
                        }\r
                        else    gr->line_plot(jj,j);\r
                }\r
@@ -615,7 +619,6 @@ void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
        {\r
                if(gr->NeedStop())      break;\r
                if(ax->GetNz()>1)       zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
-//#pragma omp parallel for collapse(2)\r
                for(long i=0;i<num;i++) for(int s=-1;s<=1;s+=2)\r
                {\r
                        mreal u,v;\r
@@ -730,29 +733,32 @@ void MGL_EXPORT mgl_flowp_2d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, ui
 //-----------------------------------------------------------------------------\r
 void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az,long ss,bool vv, bool xo, bool zo)\r
 {\r
-       static long n=10*(ax.nx+ax.ny);\r
+       static long n=100*(ax.nx+ax.ny+ax.nz);\r
        long nn = ax.nx*ax.ny*ax.nz;\r
        bool nboth = x.nx*x.ny*x.nz!=nn || y.nx*y.ny*y.nz!=nn || z.nx*z.ny*z.nz!=nn;\r
        mglPoint *pp = new mglPoint[n], dp;\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
+       mglPoint nx(ax.nx,ax.ny,ax.nz);\r
 \r
        nn = (ax.nx > ax.ny ? ax.nx : ax.ny);\r
        nn = (nn > ax.nz ? nn : ax.nz);\r
-       mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1;\r
+       mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1,acc=dt/20;\r
        if(u<0 || v<0 || w<0)\r
        {       dt = -dt;       u = -u; v = -v; w = -w; s *= -1;}\r
-       register long k=0,m;\r
+       long k=0;\r
        bool end = false;\r
        if(nboth) do{\r
                mglPoint dif;\r
                pp[k].x = x.Spline1(dif,u,0,0); e = ax.Spline1(u,v,w)/dif.x;\r
                pp[k].y = y.Spline1(dif,v,0,0); f = ay.Spline1(u,v,w)/dif.x;\r
                pp[k].z = z.Spline1(dif,w,0,0); g = az.Spline1(u,v,w)/dif.x;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt*MGL_FLOW_ACC)  {       end = true;     break;  }\r
+               if(mgl_isbad(e+f+g))    end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = sqrt(e*e+f*f+g*g);  pp[k].c = gr->GetC(ss,s*h);\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ee[0]=e*dt/h;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
@@ -790,11 +796,13 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
                e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
                f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
                g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt/10.)   {       end = true;     break;  }\r
+               if(mgl_isbad(e+f+g))    end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = sqrt(e*e+f*f+g*g);  pp[k].c = gr->GetC(ss,s*h);\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ee[0]=e*dt/h;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
@@ -835,14 +843,14 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
        } while(!end);\r
        if(k>1)\r
        {\r
-               long j,a=long(1./fabs(dt));\r
-               mreal rr = mgl_norm(gr->Max-gr->Min)*gr->BarWidth/25, ll;\r
+               long j,a=long(gr->GetArrowSize()/fabs(dt));\r
+               mreal rr = mgl_anorm(gr->Max-gr->Min)*gr->BarWidth/25, ll;\r
                mglPoint q1,q2,l;\r
                long n1=-1,n2=-1,n3=-1,n4=-1;\r
 \r
                gr->Reserve(4*k);       j = gr->AddPnt(pp[0],pp[0].c);\r
-               l = pp[1] - pp[0];      l /= mgl_norm(l);\r
-               q1.Set(l.y,-l.x,0);     ll = mgl_norm(q1);\r
+               l = pp[1] - pp[0];      l /= mgl_anorm(l);\r
+               q1.Set(l.y,-l.x,0);     ll = mgl_anorm(q1);\r
                if(ll)  q1 /= ll;       else    q1.Set(0,1,0);\r
                q2 = q1^l;\r
                if(xo)  {       n1 = gr->AddPnt(pp[0],-1,q2);   n2 = gr->AddPnt(pp[0]+rr*q1,-1,q2);     }\r
@@ -852,12 +860,12 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
                        long jj=j;      j = gr->AddPnt(pp[i],pp[i].c);\r
                        if(vv && i%a==0)\r
                        {\r
-                               if(dt<0)        gr->vect_plot(j,jj,a/5);\r
-                               else            gr->vect_plot(jj,j,a/5);\r
+                               if(dt<0)        gr->vect_plot(j,jj,a/3);\r
+                               else            gr->vect_plot(jj,j,a/3);\r
                        }\r
                        else    gr->line_plot(jj,j);\r
-                       l = pp[i]-pp[i-1];              l /= mgl_norm(l);\r
-                       q1 -= l*(l*q1); q1/= mgl_norm(q1);      q2 = q1^l;\r
+                       l = pp[i]-pp[i-1];              l /= mgl_anorm(l);\r
+                       q1 -= l*(l*q1); q1/= mgl_anorm(q1);     q2 = q1^l;\r
                        long m1 = n1, m2 = n2, m3 = n3, m4 = n4;\r
                        if(xo)\r
                        {       n1 = gr->AddPnt(pp[i],-1,q2);   n2 = gr->AddPnt(pp[i]+rr*q1,-1,q2);     gr->quad_plot(n1,n2,m1,m2);     }\r
@@ -880,7 +888,6 @@ void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        bool vv = mglchr(sch,'v'), xo = mglchr(sch,'x'), zo = mglchr(sch,'z');\r
 \r
        mglData xx(x), yy(y), zz(z), bx(ax), by(ay), bz(az);\r
-//#pragma omp parallel for collapse(3)\r
        for(long i=0;i<num;i++) for(long j=0;j<num;j++) for(int s=-1;s<=1;s+=2)\r
        {\r
                mreal u,v,w;\r
@@ -1072,29 +1079,32 @@ void MGL_EXPORT mgl_grad_(uintptr_t *gr, uintptr_t *ph, const char *sch, const c
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, double r0,long sc)\r
 {\r
-       long n=10*(ax.nx+ax.ny);\r
+       long n=100*(ax.nx+ax.ny);\r
        bool nboth = x.nx*x.ny!=ax.nx*ax.ny || y.nx*y.ny!=ax.nx*ax.ny;\r
 \r
        mglPoint *pp = new mglPoint[n], dp;\r
        mreal *cc = new mreal[n];\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
+       mglPoint nx(ax.nx,ax.ny);\r
 \r
-       mreal dt = 0.5/(ax.nx > ax.ny ? ax.nx : ax.ny),e,f,g,ff[4],gg[4],h,s=2;\r
+       mreal dt = 0.5/(ax.nx > ax.ny ? ax.nx : ax.ny),e,f,g,ff[4],gg[4],h,s=2,acc=dt/20;\r
        mreal ss = 16./mgl_ipow(gr->Max.c - gr->Min.c,2);\r
        if(u<0 || v<0)  {       dt = -dt;       u = -u; v = -v; s *= -1;}\r
-       register long k=0,m;\r
+       long k=0;\r
        bool end = false;\r
        if(nboth) do{\r
                mglPoint dif;\r
                pp[k].x = x.Spline1(dif,u,0,0); f = ax.Spline1(u,v,0)/dif.x;\r
                pp[k].y = y.Spline1(dif,v,0,0); g = ay.Spline1(u,v,0)/dif.x;\r
                pp[k].z = zVal;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt*MGL_FLOW_ACC)  {       end = true;     break;  }\r
+               if(mgl_isbad(f+g))      end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = hypot(f,g); cc[k] = gr->GetC(sc,s*h);\r
                pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                e = u+ff[0]/2;  h = v+gg[0]/2;\r
@@ -1122,12 +1132,14 @@ void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, const mgl
                        xx = ax.Spline1(u,v,0); yy = ay.Spline1(u,v,0);\r
                        det = xv*yu-xu*yv;      f = (yy*xv-xx*yv)/det;  g = (xx*yu-yy*xu)/det;\r
                pp[k].z = zVal;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt*MGL_FLOW_ACC)  {       end = true;     break;  }\r
+               if(mgl_isbad(f+g))      end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = hypot(f,g); cc[k] = gr->GetC(sc,s*h);\r
                pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                e = u+ff[0]/2;  h = v+gg[0]/2;\r
@@ -1211,7 +1223,6 @@ void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
        {\r
                if(gr->NeedStop())      break;\r
                if(ax->GetNz()>1)       zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
-//#pragma omp parallel for collapse(2)\r
                for(long i=0;i<num;i++) for(int s=-1;s<=1;s+=2)\r
                {\r
                        mreal u,v;\r
@@ -1260,33 +1271,36 @@ void MGL_EXPORT mgl_pipe_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const
 //-----------------------------------------------------------------------------\r
 void flowr(mglBase *gr, double u, double v, double w, const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, double r0,long sc)\r
 {\r
-       static long n=10*(ax.nx+ax.ny);\r
+       static long n=100*(ax.nx+ax.ny+ax.nz);\r
        long nn = ax.nx*ax.ny*ax.nz;\r
        bool nboth = x.nx*x.ny*x.nz!=nn || y.nx*y.ny*y.nz!=nn || z.nx*z.ny*z.nz!=nn;\r
        mglPoint *pp = new mglPoint[n], dp;\r
        mreal *cc = new mreal[n];\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
+       mglPoint nx(ax.nx,ax.ny,ax.nz);\r
 \r
        nn = (ax.nx > ax.ny ? ax.nx : ax.ny);\r
        nn = (nn > ax.nz ? nn : ax.nz);\r
-       mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1;\r
+       mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1,acc=dt/20;\r
        mreal ss = 16./mgl_ipow(gr->Max.c - gr->Min.c,2);\r
 \r
        if(u<0 || v<0 || w<0)\r
        {       dt = -dt;       u = -u; v = -v; w = -w; s *= -1;}\r
-       register long k=0,m;\r
+       long k=0;\r
        bool end = false;\r
        if(nboth) do{\r
                mglPoint dif;\r
                pp[k].x = x.Spline1(dif,u,0,0); e = ax.Spline1(u,v,w)/dif.x;\r
                pp[k].y = y.Spline1(dif,v,0,0); f = ay.Spline1(u,v,w)/dif.x;\r
                pp[k].z = z.Spline1(dif,w,0,0); g = az.Spline1(u,v,w)/dif.x;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt*MGL_FLOW_ACC)  {       end = true;     break;  }\r
+               if(mgl_isbad(e+f+g))    end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = sqrt(e*e+f*f+g*g);  cc[k] = gr->GetC(sc,s*h);\r
                pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ee[0]=e*dt/h;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
@@ -1324,12 +1338,14 @@ void flowr(mglBase *gr, double u, double v, double w, const mglData &x, const mg
                e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
                f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
                g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
-               for(m=0;m<k-1;m++)      // determines encircle\r
-                       if(mgl_norm((pp[k]-pp[m])/dx)<dt/10.)   {       end = true;     break;  }\r
+               if(mgl_isbad(e+f+g))    end = true;\r
+               else    for(long m=0;m<k-1;m+=10)       // determines encircle\r
+                       if(mgl_anorm((pp[k]-pp[m])/dx)<acc)     end = true;\r
+               if(end) break;\r
                h = sqrt(e*e+f*f+g*g);  cc[k] = gr->GetC(sc,s*h);\r
                pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
                if(h<1e-5)      break;  // stationary point\r
-               k++;\r
+               if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)    k++;\r
                // find next point by midpoint method\r
                h+=1;   ee[0]=e*dt/h;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
@@ -1420,7 +1436,6 @@ void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        bool cnt=!mglchr(sch,'#');\r
 \r
        mglData xx(x), yy(y), zz(z), bx(ax), by(ay), bz(az);\r
-//#pragma omp parallel for collapse(3)\r
        for(long i=0;i<num;i++) for(long j=0;j<num;j++) for(int s=-1;s<=1;s+=2)\r
        {\r
                mreal u,v,w;\r
index d36b11e6a6cd31e9302f2dc2d4be0f646f3561d3..f7b3ca0876532886462f9ff56e95bb3bfcd0de43 100644 (file)
@@ -643,7 +643,11 @@ void MGL_EXPORT mgl_beam_val(HMGL gr, double val, HCDT tr, HCDT g1, HCDT g2, HCD
                        }\r
                if(flag & 2)\r
 #pragma omp parallel for collapse(2)\r
-                       for(j=0;j<m;j++)        for(k=0;k<l;k++)        x.a[i0] = hypot(x.a[i0],y.a[i0]);\r
+                       for(j=0;j<m;j++)        for(k=0;k<l;k++)\r
+                       {\r
+                               long i0 = j+m*(k+l*i);\r
+                               x.a[i0] = hypot(x.a[i0],y.a[i0]);\r
+                       }\r
        }\r
        mgl_surf3_xyz_val(gr,val,&x,&y,&z,&b,stl,0);\r
 }\r
index 4104713cc1aa599f816596d6d75649526290fe2a..24dd1d8b5d358feff049d5bd010e45b64cd51a45 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -21,6 +21,7 @@
 19. Simplified triangle filling for Quality=1 ?!?
 20. Extend 'ask' by adding multiple questions simultaneously (+ set/get default values from file ???)
 21. Occasional seg.fault in mgl_qt_example at exit
+22. \overline{\overline{a}} ???
 
 
 ============= NEW FEATURES =============
 8. Contour lines for bilinear interpolation (strong saddle-like faces)
 9. More accurate face cutting if one partially out of axis ranges
 
-17. Iris plot -- https://en.wikipedia.org/wiki/Iris_flower_data_set
+10. Direct export to MP4 ?!!
+11. Iris plot -- https://en.wikipedia.org/wiki/Iris_flower_data_set
+12. Parallel drawing in QMathGL.
+13. CMAKE + COMPONENTS ???
+14. mglQt, nglFLTK -- add 2-3 callback functions+toolbuttons+hotkeys for user(s)
 
 ZZ. Update *.i for new functions {before release!!!}
 
 
 ============= DOCUMENTATION =============
 
-A. Paper about MathGL!!!
+A. Paper about MathGL!!! 6099610006
 B. Add chapter with real samples
 C. Translate to Russian everything
 D. Docs about JS interface
 
+1. Docs + sample about Pmap() -- Poincare map
+2. Docs + sample about Lamerey() -- Lamerey diagram
+3. Docs + sample about Bifurcation() -- Bifurcation diagram
+4. Docs + sample about Pulse() -- see pulse.mgl
+       new a 100 'exp(-6*x^2)'
+       xrange 0 a.nx-1:yrange 0 1
+       axis:plot a
+
+       pulse b a 'x'
+
+       line b(1) 0 b(1) 1 'r='
+       line b(1)-b(3)/2 0  b(1)-b(3)/2 1 'm|'
+       line b(1)+b(3)/2 0  b(1)+b(3)/2 1 'm|'
+       line 0 0.5 a.nx-1 0.5 'h'
+       new x 100 'x'
+       plot b(0)*(1-((x-b(1))/b(2))^2) 'g'
+5. Docs about MGL commands: 'print' and 'echo'
+6. Docs about mgl_pen_delta(), SetPenDelta(), 'pen_delta'
+7. Option to rewrite in 'savehdf'
+8. Docs about MGL command 'fscanf'
+9. About "#undef I"
 
 YY. Sample like http://pyxplot.org.uk/examples/05ap/02hlines/index.html using Stem()
 
@@ -69,6 +95,9 @@ YY. Sample like http://pyxplot.org.uk/examples/05ap/02hlines/index.html using St
 
 4. List of constants into the list of data?!
 5. Add color cycle ???
+6. Color position in color scheme dialog
+7. QML ???
+8, Changable panels???
 
 
 ============= UNSURE ===========
index 274ae10148f063056f0809617402b8c0109ae090..9ccc07b2a9ba0279184310e33ec3190f446c81f5 100644 (file)
@@ -31,20 +31,18 @@ endif(MGL_HAVE_GSL)
 if(enable-qt5)
        include(../cmake-qt5.txt)
        qt5_add_resources(udav_rc_src ${udav_rc} )
-       qt5_wrap_cpp(udav_moc_src ${udav_moc_hdr} )
 else(enable-qt5)
        include(../cmake-qt4.txt)
        qt4_add_resources(udav_rc_src ${udav_rc} )
-       qt4_wrap_cpp(udav_moc_src ${udav_moc_hdr} )
 endif(enable-qt5)
-add_executable(udav ${udav_src} ${udav_moc_src} ${udav_rc_src})
+add_executable(udav ${udav_src} ${udav_moc_hdr} ${udav_rc_src})
 #set_target_properties(udav PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
 if(enable-qt5)
        target_link_libraries(udav mgl-qt5)
-       qt5_use_modules(udav Core Widgets Gui PrintSupport)
+       qt5_use_modules(udav ${MGL_QT5_LIBS})
 else(enable-qt5)
        target_link_libraries(udav mgl-qt4)
-       target_link_libraries(udav ${QT_LIBRARIES})
+       qt4_use_modules(udav ${MGL_QT4_LIBS})
 endif(enable-qt5)
 
 if(MGL_HAVE_PTHREAD)
index 1ebfebd5a2b97ccdd29a8cec333021ac072e7363..09ddf5c262f51ea342e7d03f99637d0b65305c5d 100644 (file)
@@ -32,6 +32,7 @@
 #include <QSettings>\r
 #include <QDir>\r
 //-----------------------------------------------------------------------------\r
+#include <mgl2/qmathgl.h>\r
 #include "prop_dlg.h"\r
 #include "udav_wnd.h"\r
 #include "plot_pnl.h"\r
@@ -43,12 +44,13 @@ extern int defFontSize;
 extern QString pathHelp;\r
 extern bool mglAutoExecute;\r
 extern bool mglAutoSave;\r
-extern bool mglAutoPure;\r
+// extern bool mglAutoPure;\r
 extern bool mglCompleter;\r
 extern bool editPosBottom;\r
 extern bool loadInNewWnd;\r
 extern bool mglHighlight;\r
 extern bool mglDotsRefr;\r
+extern bool mglWheelZoom;\r
 int defWidth, defHeight;\r
 QString pathFont;\r
 QString lang[]={"","ru"};\r
@@ -161,8 +163,10 @@ PropDialog::PropDialog(QWidget *parent) : QDialog(parent)
        load->setChecked(loadInNewWnd); v->addWidget(load);\r
        save = new QCheckBox(tr("Automatically save before redrawing (F5)"), this);\r
        save->setChecked(mglAutoSave);  v->addWidget(save);\r
-       pure = new QCheckBox(tr("Disable face drawing (faster) for mouse rotation/shift/zoom."), this);\r
-       pure->setChecked(mglAutoPure);  v->addWidget(pure);     pure->setEnabled(false);\r
+//     pure = new QCheckBox(tr("Disable face drawing (faster) for mouse rotation/shift/zoom."), this);\r
+//     pure->setChecked(mglAutoPure);  v->addWidget(pure);     pure->setEnabled(false);\r
+       wheel = new QCheckBox(tr("Enable mouse wheel for zooming."), this);\r
+       wheel->setChecked(mglWheelZoom);        v->addWidget(wheel);\r
        cmpl = new QCheckBox(tr("Enable keywords completition"), this);\r
        cmpl->setChecked(mglCompleter); v->addWidget(cmpl);\r
        high = new QCheckBox(tr("Highlight current object(s)"), this);\r
@@ -231,9 +235,10 @@ void PropDialog::applyChanges()
        loadInNewWnd = load->isChecked();\r
        mglAutoSave = save->isChecked();\r
        mglHighlight = high->isChecked();\r
-       mglAutoPure = pure->isChecked();\r
+//     mglAutoPure = pure->isChecked();\r
        mglCompleter = cmpl->isChecked();\r
        mglDotsRefr = dots->isChecked();\r
+       mglWheelZoom = wheel->isChecked();\r
 \r
        // apply changes for all windows\r
 #ifdef WIN32\r
@@ -248,6 +253,7 @@ void PropDialog::applyChanges()
                        if(ok)  {       s->writeSettings();     ok = false;     }\r
                        s->edit->setEditorFont();\r
                        s->graph->setMGLFont(pathFont);\r
+                       s->graph->mgl->enableWheel = mglWheelZoom;\r
                        s->setEditPos(editPosBottom);\r
                        s->edit->setCompleter(mglCompleter);\r
                        s->update();\r
index 22b58e322b10ff111787745f8b9176bedcfffec6..193aaef5bb17b4a295ca1a0324af19cf31e9c248 100644 (file)
@@ -56,7 +56,7 @@ private:
        void setC(int k);
        QLabel *lbl;
        QPushButton *cb[10];
-       QCheckBox *run, *edt, *load, *save, *pure, *cmpl, *high, *dots;
+       QCheckBox *run, *edt, *load, *save, *cmpl, *high, *dots, *wheel;        //, *pure;
        QLineEdit *hlp, *defW, *defH;
        QFont defFont;
        QColor cc[10];
index c088d982384b096fe9418c7495fa12e014c64c97..1534a49ea1a88c1ada869d4023e396d55b52dd00 100644 (file)
@@ -114,7 +114,7 @@ MessSyntax::MessSyntax(QTextEdit *textEdit) : QSyntaxHighlighter(textEdit)  {}
 //-----------------------------------------------------------------------------\r
 void MessSyntax::highlightBlock(const QString &text)\r
 {\r
-       if(text.left(7) == ("In line"))\r
+       if(text.contains("in line "))\r
                setFormat(0, text.length(), QColor(255,0,0));\r
 }\r
 //-----------------------------------------------------------------------------\r
index 3ff5462f485b56ae58fda2db6d98fdc06984c2a6..293c10b0b36c4d9a2d7fff12d900c9702eb552a3 100644 (file)
@@ -78,6 +78,8 @@ TextPanel::TextPanel(QWidget *parent) : QWidget(parent)
        defFontSize = int(edit->fontPointSize());
        edit->setLineWrapMode(QTextEdit::NoWrap);
        setCompleter(mglCompleter);
+       QFontMetrics metrics(edit->currentFont());
+       edit->setTabStopWidth(4 * metrics.width(' '));
 
        menu = new QMenu(tr("Edit"),this);
        QBoxLayout *v = new QVBoxLayout(this);
@@ -256,7 +258,12 @@ void TextPanel::addStyle()
 }
 //-----------------------------------------------------------------------------
 void TextPanel::setEditorFont(QFont *f)
-{      edit->setFont(f ? *f : QFont(defFontFamily, defFontSize));      }
+{
+       QFont d(defFontFamily, defFontSize);
+       edit->setFont(f ? *f : d);
+       QFontMetrics metrics(f ? *f : d);
+       edit->setTabStopWidth(4 * metrics.width(' '));
+}
 //-----------------------------------------------------------------------------
 QString TextPanel::selection()
 {      return edit->textCursor().block().text();       }
@@ -453,7 +460,7 @@ void TextPanel::load(const QString &fileName)
                        graph->mgl->primitives = str.section("#----- End of QMathGL block -----\n",0,0);
                        str = str.section("#----- End of QMathGL block -----\n",1);
                }
-               
+
                if(narg>0)      setCurrentFile(fileName.left(fileName.length()-3)+"mgl");
                edit->setText(str);
                graph->animParseText(edit->toPlainText());
index ff16d9572681e916809473fd1c4eee7ffbb74721..7a046108de8d60f79dfa794267b3879139d5c3cc 100644 (file)
@@ -39,6 +39,7 @@
  ****************************************************************************/
 
 #include "textedit.h"
+#include <string.h>
 #include <QCompleter>
 #include <QKeyEvent>
 #include <QAbstractItemView>
 #include <QScrollBar>
 #include <QPainter>
 #include <QTextBlock>
+#include <QAbstractTextDocumentLayout>
+
 extern QColor mglColorScheme[10];
 //-----------------------------------------------------------------------------
 TextEdit::TextEdit(QWidget *parent) : QTextEdit(parent)
 {
        c=0;
        connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlight()));
+       // Line numbers
+       lineNumberArea = new LineNumberArea(this);
+       connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
+       connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberArea(int)));
+       connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateLineNumberArea(int)));
+       connect(this, SIGNAL(textChanged()), this, SLOT(updateLineNumberArea()));
+       connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateLineNumberArea()));
+       updateLineNumberAreaWidth(0);
 }
 //-----------------------------------------------------------------------------
 void TextEdit::highlight()
@@ -149,3 +160,166 @@ void TextEdit::keyPressEvent(QKeyEvent *e)
        c->complete(cr); // popup it up!
 }
 //-----------------------------------------------------------------------------
+//
+//     Line numbering (slightly modified code of Gauthier Boaglio)
+//     Original: https://stackoverflow.com/questions/2443358/how-to-add-lines-numbers-to-qtextedit/
+//
+//-----------------------------------------------------------------------------
+int TextEdit::lineNumberAreaWidth()
+{
+       int digits = 1;
+       int max = qMax(1, document()->blockCount());
+       while (max >= 10)       {       max /= 10;      ++digits;       }
+       int space = 13 +  fontMetrics().width(QLatin1Char('9')) * (digits);
+       return space;
+}
+//-----------------------------------------------------------------------------
+void TextEdit::updateLineNumberAreaWidth(int /* newBlockCount */)
+{      setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);     }
+//-----------------------------------------------------------------------------
+void TextEdit::updateLineNumberArea(QRectF /*rect_f*/)
+{      TextEdit::updateLineNumberArea();       }
+//-----------------------------------------------------------------------------
+void TextEdit::updateLineNumberArea(int /*slider_pos*/)
+{      TextEdit::updateLineNumberArea();       }
+//-----------------------------------------------------------------------------
+void TextEdit::updateLineNumberArea()
+{
+       /* When the signal is emitted, the sliderPosition has been adjusted according to the action,
+        * but the value has not yet been propagated (meaning the valueChanged() signal was not yet emitted),
+        * and the visual display has not been updated. In slots connected to this signal you can thus safely
+        * adjust any action by calling setSliderPosition() yourself, based on both the action and the
+        * slider's value. */
+       // Make sure the sliderPosition triggers one last time the valueChanged() signal with the actual value !!!!
+       verticalScrollBar()->setSliderPosition(verticalScrollBar()->sliderPosition());
+
+       // Since "QTextEdit" does not have an "updateRequest(...)" signal, we chose
+       // to grab the imformations from "sliderPosition()" and "contentsRect()".
+       // See the necessary connections used (Class constructor implementation part).
+
+       QRect rect =  contentsRect();
+       lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
+       updateLineNumberAreaWidth(0);
+       //----------
+       int dy = verticalScrollBar()->sliderPosition();
+       if (dy > -1) {
+               lineNumberArea->scroll(0, dy);
+       }
+
+       // Addjust slider to alway see the number of the currently being edited line...
+       int first_block_id = getFirstVisibleBlockId();
+       if (first_block_id == 0 || textCursor().block().blockNumber() == first_block_id-1)
+               verticalScrollBar()->setSliderPosition(dy-document()->documentMargin());
+}
+//-----------------------------------------------------------------------------
+void TextEdit::resizeEvent(QResizeEvent *e)
+{
+       QTextEdit::resizeEvent(e);
+       QRect cr = contentsRect();
+       lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
+}
+//-----------------------------------------------------------------------------
+int TextEdit::getFirstVisibleBlockId()
+{
+       // Detect the first block for which bounding rect - once translated
+       // in absolute coordinated - is contained by the editor's text area
+
+       // Costly way of doing but since "blockBoundingGeometry(...)" doesn't
+       // exists for "QTextEdit"...
+
+       QTextCursor curs = QTextCursor(document());
+       curs.movePosition(QTextCursor::Start);
+       for(int i=0; i < document()->blockCount(); ++i)
+       {
+               QTextBlock block = curs.block();
+
+               QRect r1 = viewport()->geometry();
+               QRect r2 = document()->documentLayout()->blockBoundingRect(block).translated(
+                                       viewport()->geometry().x(), viewport()->geometry().y() - (
+                                               verticalScrollBar()->sliderPosition()
+                                               ) ).toRect();
+
+               if (r1.contains(r2, true)) { return i; }
+
+               curs.movePosition(QTextCursor::NextBlock);
+       }
+
+       return 0;
+}
+//-----------------------------------------------------------------------------
+void TextEdit::lineNumberAreaPaintEvent(QPaintEvent *event)
+{
+       verticalScrollBar()->setSliderPosition(verticalScrollBar()->sliderPosition());
+
+       QPainter painter(lineNumberArea);
+       painter.fillRect(event->rect(), Qt::lightGray);
+       int blockNumber = getFirstVisibleBlockId();
+
+       QTextBlock block = document()->findBlockByNumber(blockNumber);
+       QTextBlock prev_block = (blockNumber > 0) ? document()->findBlockByNumber(blockNumber-1) : block;
+       int translate_y = (blockNumber > 0) ? -verticalScrollBar()->sliderPosition() : 0;
+
+       int top = viewport()->geometry().top();
+
+       // Adjust text position according to the previous "non entirely visible" block
+       // if applicable. Also takes in consideration the document's margin offset.
+       int additional_margin;
+       if (blockNumber == 0)   // Simply adjust to document's margin
+               additional_margin = (int) document()->documentMargin() -1 - verticalScrollBar()->sliderPosition();
+       else    // Getting the height of the visible part of the previous "non entirely visible" block
+               additional_margin = (int) document()->documentLayout()->blockBoundingRect(prev_block)
+                               .translated(0, translate_y).intersected(viewport()->geometry()).height();
+       top += additional_margin;       // Shift the starting point
+
+       int bottom = top + (int) document()->documentLayout()->blockBoundingRect(block).height();
+
+       QColor colErr(255, 0, 0);       // Error line
+       QColor colCur(0, 128, 255);     // Current line
+       QColor colDef(0,0,0);           // Other lines
+
+       // Draw the numbers (displaying the current line number in green)
+       while (block.isValid() && top <= event->rect().bottom())
+       {
+               if (block.isVisible() && bottom >= event->rect().top())
+               {
+                       QString number = QString::number(blockNumber + 1);
+                       painter.setPen(QColor(120, 120, 120));
+                       painter.setPen((textCursor().blockNumber() == blockNumber) ? colCur :
+                                                                               (isErrLine(blockNumber+1)?colErr:colDef) );
+                       painter.drawText(-5, top, lineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number);
+               }
+
+               block = block.next();
+               top = bottom;
+               bottom = top + (int) document()->documentLayout()->blockBoundingRect(block).height();
+               blockNumber++;
+       }
+}
+//-----------------------------------------------------------------------------
+bool TextEdit::isErrLine(int line) const
+{
+       for(size_t i=0;i<err.size();i++)        if(err[i]==line)        return true;
+       return false;
+}
+//-----------------------------------------------------------------------------
+void TextEdit::setErrMessage(const QString &mess)
+{
+       err.clear();
+       const char *s = mess.toStdString().c_str();
+       s = strstr(s,"in line ");
+       while(s)
+       {
+               err.push_back(atoi(s+8));
+               s = strstr(s+8,"in line ");
+       }
+}
+//-----------------------------------------------------------------------------
+LineNumberArea::LineNumberArea(TextEdit *editor) : QWidget(editor)
+{      codeEditor = editor;    }
+//-----------------------------------------------------------------------------
+QSize LineNumberArea::sizeHint() const
+{      return QSize(codeEditor->lineNumberAreaWidth(), 0);     }
+//-----------------------------------------------------------------------------
+void LineNumberArea::paintEvent(QPaintEvent *event)
+{      codeEditor->lineNumberAreaPaintEvent(event);    }
+//-----------------------------------------------------------------------------
index 85b9c12ca794a33e28dc928f2c1879741a37d924..6a54db948253944f1061c5c7ca2743f27b182cd7 100644 (file)
@@ -52,19 +52,46 @@ public:
        TextEdit(QWidget *parent = 0);
        void setCompleter(QCompleter *c);
        QCompleter *completer() const { return c;       }
-       
+       int getFirstVisibleBlockId();
+       void lineNumberAreaPaintEvent(QPaintEvent *event);
+       int lineNumberAreaWidth();
+
+public slots:
+       void resizeEvent(QResizeEvent *e);
+       void setErrMessage(const QString &s);
+
 protected:
        void keyPressEvent(QKeyEvent *e);
        void focusInEvent(QFocusEvent *e);
-       
+       bool isErrLine(int line) const;
+
 private slots:
        void insertCompletion(const QString &completion);
        void highlight();
+       void updateLineNumberAreaWidth(int newBlockCount);
+       void updateLineNumberArea(QRectF /*rect_f*/);
+       void updateLineNumberArea(int /*slider_pos*/);
+       void updateLineNumberArea();
 
 private:
        QString textUnderCursor() const;
        QCompleter *c;
+       QWidget *lineNumberArea;
+       std::vector<int> err;
 };
+//-----------------------------------------------------------------------------
+class LineNumberArea : public QWidget
+{
+       Q_OBJECT
+public:
+       LineNumberArea(TextEdit *editor);
+       QSize sizeHint() const;
+protected:
+       void paintEvent(QPaintEvent *event);
+private:
+       TextEdit *codeEditor;
+};
+
 //-----------------------------------------------------------------------------
 #endif // TEXTEDIT_H
 //-----------------------------------------------------------------------------
index 3565b805ad61a3d5eaa0b2e2349defb695164282..4c06fe3ea4a7ac1a21ae80beb9aa655471f8b378 100755 (executable)
@@ -4,9 +4,10 @@ Type=Application
 Terminal=false
 Icon=udav
 Name=UDAV
-Exec=udav
+Exec=udav %f
 MimeType=text/mgl;
 Comment=Data handling and plotting tool
 Comment[en_US]=Data handling and plotting tool
 Comment[ru_RU]=Обработка Ð¸ Ð¾Ñ‚ображение Ð´Ð°Ð½Ð½Ñ‹Ñ…
 Categories=Education;Science;Math;
+Keywords=Visualization;Data;Array;
\ No newline at end of file
index 66087cdc3db8601e14c5809a3ec6a50b057aa918..9ce96a604db0e96a0361d0690a9eb337d8f34845 100644 (file)
@@ -53,9 +53,10 @@ bool editPosBottom = false;
 bool mglAutoSave = false;
 bool mglHighlight = true;
 bool mglDotsRefr = true;
-bool mglAutoPure = true;
+// bool mglAutoPure = true;
 bool mglCompleter = true;
 bool loadInNewWnd = false;
+bool mglWheelZoom = false;
 QString pathHelp;
 extern mglParse parser;
 extern QColor mglColorScheme[10];
@@ -132,6 +133,7 @@ int main(int argc, char **argv)
                mw->load(codec->toUnicode(argv[1]), true);
        }
        mw->show();
+       mw->edit->edit->setFocus();
        a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
        if(showHint)    udavShowHint(mw);
        return a.exec();
@@ -161,7 +163,7 @@ MainWindow::MainWindow(QWidget *wp) : QMainWindow(wp)
        rtab->setMovable(true); rtab->setTabPosition(QTabWidget::South);
 
        messWnd = new QDockWidget(tr("Messages and warnings"),this);
-       mess = new TextEdit(this);      messWnd->setWidget(mess);
+       mess = new QTextEdit(this);     messWnd->setWidget(mess);
        messWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
        addDockWidget(Qt::BottomDockWidgetArea, messWnd);
        messWnd->resize(size().width(), 0);     new MessSyntax(mess);
@@ -217,6 +219,7 @@ MainWindow::MainWindow(QWidget *wp) : QMainWindow(wp)
        edit = new TextPanel(this);     edit->graph = graph;
        graph->textMGL = edit->edit;
        connect(graph->mgl,SIGNAL(showWarn(QString)),mess,SLOT(setText(QString)));
+       connect(graph->mgl,SIGNAL(showWarn(QString)),edit->edit,SLOT(setErrMessage(QString)));
        connect(graph,SIGNAL(clearWarn()),mess,SLOT(clear()));
        ltab->addTab(edit,QPixmap(":/png/text-plain.png"),tr("Script"));
 
@@ -471,12 +474,13 @@ void MainWindow::writeSettings()
        settings.setValue("/autoSave",  mglAutoSave);
        settings.setValue("/highlight",  mglHighlight);
        settings.setValue("/dotsRefresh", mglDotsRefr);
-       settings.setValue("/autoPure",  mglAutoPure);
+//     settings.setValue("/autoPure",  mglAutoPure);
        settings.setValue("/editAtTop", editPosBottom);
        settings.setValue("/fontFamily", defFontFamily);
        settings.setValue("/fontSize", defFontSize);
        settings.setValue("/loadInNewWnd", loadInNewWnd);
        settings.setValue("/completer",  mglCompleter);
+       settings.setValue("/wheelZoom",  mglWheelZoom);
        settings.endGroup();
 }
 //-----------------------------------------------------------------------------
@@ -506,18 +510,20 @@ void MainWindow::readSettings()
        mglColorScheme[7] = QColor(settings.value("/colFCKeyword","#007F7F").toString());
        mglColorScheme[8] = QColor(settings.value("/colReserved", "#0000FF").toString());
        mglColorScheme[9] = QColor(settings.value("/colCurrLine", "#FFFFCC").toString());
-       mglAutoSave = settings.value("/autoSave",  false).toBool();
-       mglHighlight = settings.value("/highlight",  true).toBool();
-       mglAutoPure = settings.value("/autoPure",  true).toBool();
-       mglAutoExecute = settings.value("/autoExec",  true).toBool();
+       mglAutoSave = settings.value("/autoSave", false).toBool();
+       mglHighlight = settings.value("/highlight", true).toBool();
+//     mglAutoPure = settings.value("/autoPure", true).toBool();
+       mglAutoExecute = settings.value("/autoExec", true).toBool();
        editPosBottom = settings.value("/editAtTop", false).toBool();
-       mglCompleter = settings.value("/completer",  true).toBool();
+       mglCompleter = settings.value("/completer", true).toBool();
+       mglWheelZoom = settings.value("/wheelZoom", false).toBool();
        loadInNewWnd = settings.value("/loadInNewWnd", false).toBool();
        mglDotsRefr = settings.value("/dotsRefresh", true).toBool();
        defFontFamily = settings.value("/fontFamily", "Georgia").toString();
        defFontSize = settings.value("/fontSize", 10).toInt();
        edit->setEditorFont();  setEditPos(editPosBottom);
        graph->setMGLFont(pathFont);
+       graph->mgl->enableWheel = mglWheelZoom;
 
        defWidth = settings.value("/defWidth", 640).toInt();
        defHeight = settings.value("/defHeight", 480).toInt();
index b6e5beacf0b87f37f7e31d62e9b2be001d1e9d75..8b04bf1e686cd972b945792b4208fd7b942a5066 100644 (file)
@@ -24,11 +24,11 @@ if(enable-qt)
        if(enable-qt5)
                include(../cmake-qt5.txt)
                target_link_libraries(mglview mgl-qt5)
-               qt5_use_modules(mglview Core Widgets Gui PrintSupport)
+               qt5_use_modules(mglview ${MGL_QT5_LIBS})
        else(enable-qt5)
                include(../cmake-qt4.txt)
                target_link_libraries(mglview mgl-qt4)
-               target_link_libraries(mglview ${QT_LIBRARIES})
+               qt4_use_modules(mglview ${MGL_QT4_LIBS})
        endif(enable-qt5)
 
        install(
index ac9a44c361d37a00569a0d43d5442e9524276a58..44d25eed4da3e08f9bc1b08911c6d4946bd6f675 100644 (file)
@@ -24,11 +24,10 @@ int main(int argc, char *argv[])
 {
        mglFont fnt;
        std::string path, base, fname;
-       char ch;
 
        while(1)
        {
-               ch = getopt(argc, argv, "p:o:h");
+               int ch = getopt(argc, argv, "p:o:h");
                if(ch=='p')     path = optarg;
                else if(ch=='o')        fname = optarg;
                else if(ch=='h' || (ch==-1 && optind>=argc))
@@ -39,11 +38,10 @@ int main(int argc, char *argv[])
                                "\t-p path      set specific path for base font files\n"
                                "\t-o fname     set output filename (use ${base}.vfmb by default)\n"
                                "\t-h           print this message\n" );
-                       ch = 'h';       break;
+                       return 0;
                }
                else if(ch==-1 && optind<argc)  {       base = argv[optind];    break;  }
        }
-       if(ch=='h')     return 0;
        if(fname.empty())       fname = base + ".vfmb";
        fnt.Load(base.c_str(),path.c_str());
        size_t size = fnt.SaveBin(fname.c_str());
index c5477221dcff4fd054476a404e7116d7e04b2437..14ae65ebda1fd66891df49571bc831f0214eaca1 100644 (file)
@@ -28,14 +28,14 @@ int main(int argc, char *argv[])
        mgl_suppress_warn(true);\r
        mglGraph gr;\r
        mglParse p(true);\r
-       char ch, buf[2048], iname[256]="", oname[256]="";\r
+       char buf[2048], iname[256]="", oname[256]="";\r
        std::vector<std::wstring> var;\r
        std::wstring str;\r
        bool none=false;\r
 \r
        while(1)\r
        {\r
-               ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hno:L:C:A:s:S:q:");\r
+               int ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hno:L:C:A:s:S:q:");\r
                if(ch>='1' && ch<='9')  p.AddParam(ch-'0', optarg);\r
                else if(ch=='s')\r
                {\r
@@ -89,13 +89,12 @@ int main(int argc, char *argv[])
                                "\t-C n1:n2     add animation value in range [n1,n2] with step 1\n"\r
                                "\t-            get script from standard input\n"\r
                                "\t-h           print this message\n" );\r
-                       ch = 'h';       break;\r
+                       return 0;\r
                }\r
                else if(ch=='o')        strncpy(oname, optarg,256);\r
                else if(ch==-1 && optind<argc)\r
                {       strncpy(iname, argv[optind][0]=='-'?"":argv[optind],256);       break;  }\r
        }\r
-       if(ch=='h')     return 0;\r
        if(*oname==0)   {       strncpy(oname,*iname?iname:"out",250);  strcat(oname,".png");   }\r
        else    none = false;\r
 \r
index 8264492f0305f1fbc054b912f7d50a1294b35753..a34e55bbbc71b37faea5c572a7adfc0673fdba5c 100644 (file)
@@ -39,11 +39,11 @@ int show(mglGraph *gr)
 //-----------------------------------------------------------------------------
 int main(int argc, char **argv)
 {
-       char ch, iname[256]="";
+       char iname[256]="";
        mgl_suppress_warn(true);
        while(1)
        {
-               ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hL:s:");
+               int ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hL:s:");
                if(ch>='1' && ch<='9')  p.AddParam(ch-'0', optarg);
                else if(ch=='s')
                {
@@ -69,12 +69,11 @@ int main(int argc, char **argv)
                                "\t-L loc       set locale to loc\n"
                                "\t-            get script from standard input\n"
                                "\t-h           print this message\n" );
-                       ch = 'h';       break;
+                       return 0;
                }
                else if(ch==-1 && optind<argc)
                {       strncpy(iname, argv[optind][0]=='-'?"":argv[optind],256);       break;  }
        }
-       if(ch=='h')     return 0;
 
        bool mgld=(*iname && iname[strlen(iname)-1]=='d');
        if(!mgld)
index 756124b641ce99c45069eaef7485fccf633d32b6..f05ea5ad5380fc52b94741b2507300970beaca5a 100644 (file)
@@ -2,83 +2,24 @@ include(GenerateExportHeader)
 add_compiler_export_flags()
 
 if(MGL_HAVE_FLTK)
-       include_directories(${FLTK_INCLUDE_DIR})
-       add_library(mgl-fltk SHARED fltk.cpp ../include/mgl2/fltk.h)
-       add_library(mgl-fltk-static STATIC fltk.cpp ../include/mgl2/fltk.h)
-       set_target_properties(mgl-fltk PROPERTIES SOVERSION ${MathGL_SOVERSION})
-       set_target_properties(mgl-fltk PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       set_target_properties(mgl-fltk PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-       set_target_properties(mgl-fltk-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       target_compile_definitions(mgl-fltk-static PUBLIC MGL_STATIC_DEFINE)
+       mgl_add_lib(fltk fltk.cpp ../include/mgl2/fltk.h)
+       target_include_directories(mgl-fltk SYSTEM PUBLIC ${FLTK_INCLUDE_DIR})
+       target_include_directories(mgl-fltk-static SYSTEM PUBLIC ${FLTK_INCLUDE_DIR})
        target_link_libraries(mgl-fltk mgl ${FLTK_LIBRARIES})
-
-       if(enable-mgl2)
-               set_target_properties(mgl-fltk PROPERTIES OUTPUT_NAME "mgl2-fltk")
-               set_target_properties(mgl-fltk-static PROPERTIES OUTPUT_NAME "mgl2-fltk")
-       else(enable-mgl2)
-               set_target_properties(mgl-fltk-static PROPERTIES OUTPUT_NAME "mgl-fltk")
-       endif(enable-mgl2)
-
-       install(
-               TARGETS mgl-fltk mgl-fltk-static
-               RUNTIME DESTINATION bin
-               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-       )
 endif(MGL_HAVE_FLTK)
 
 if(MGL_HAVE_GLUT)
-       include_directories(${GLUT_INCLUDE_DIR})
-       add_library(mgl-glut SHARED glut.cpp ../include/mgl2/glut.h)
-       add_library(mgl-glut-static STATIC glut.cpp ../include/mgl2/glut.h)
-       set_target_properties(mgl-glut PROPERTIES SOVERSION ${MathGL_SOVERSION})
-       set_target_properties(mgl-glut PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       set_target_properties(mgl-glut PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-       set_target_properties(mgl-glut-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       target_compile_definitions(mgl-glut-static PUBLIC MGL_STATIC_DEFINE)
-       target_link_libraries(mgl-glut mgl)
-       target_link_libraries(mgl-glut ${GLUT_LIBRARIES} ${OPENGL_LIBRARIES})
-
-       if(enable-mgl2)
-               set_target_properties(mgl-glut PROPERTIES OUTPUT_NAME "mgl2-glut")
-               set_target_properties(mgl-glut-static PROPERTIES OUTPUT_NAME "mgl2-glut")
-       else(enable-mgl2)
-               set_target_properties(mgl-glut-static PROPERTIES OUTPUT_NAME "mgl-glut")
-       endif(enable-mgl2)
-
-       install(
-               TARGETS mgl-glut mgl-glut-static
-               RUNTIME DESTINATION bin
-               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-       )
+       mgl_add_lib(glut glut.cpp ../include/mgl2/glut.h)
+       target_include_directories(mgl-glut SYSTEM PUBLIC ${GLUT_INCLUDE_DIR})
+       target_include_directories(mgl-glut-static SYSTEM PUBLIC ${GLUT_INCLUDE_DIR})
+       target_link_libraries(mgl-glut mgl ${GLUT_LIBRARIES} ${OPENGL_LIBRARIES})
 endif(MGL_HAVE_GLUT)
 
 if(MGL_HAVE_WX)
+       mgl_add_lib(wx wx.cpp ../include/mgl2/wx.h)
        include(${wxWidgets_USE_FILE})
-       add_library(mgl-wx SHARED wx.cpp ../include/mgl2/wx.h)
-       add_library(mgl-wx-static STATIC wx.cpp ../include/mgl2/wx.h)
-       set_target_properties(mgl-wx PROPERTIES SOVERSION ${MathGL_SOVERSION})
-       set_target_properties(mgl-wx PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       set_target_properties(mgl-wx PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-       set_target_properties(mgl-wx-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       target_compile_definitions(mgl-wx-static PUBLIC MGL_STATIC_DEFINE)
        target_link_libraries(mgl-wx mgl)
        target_link_libraries(mgl-wx ${wxWidgets_LIBRARIES})
-
-       if(enable-mgl2)
-               set_target_properties(mgl-wx PROPERTIES OUTPUT_NAME "mgl2-wx")
-               set_target_properties(mgl-wx-static PROPERTIES OUTPUT_NAME "mgl2-wx")
-       else(enable-mgl2)
-               set_target_properties(mgl-wx-static PROPERTIES OUTPUT_NAME "mgl-wx")
-       endif(enable-mgl2)
-
-       install(
-               TARGETS mgl-wx mgl-wx-static
-               RUNTIME DESTINATION bin
-               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-       )
 endif(MGL_HAVE_WX)
 
 add_subdirectory( qt4 )
index 3e725b9bb4f05a74c6ebc58652552b50f63fc1a2..53e159ff29e0fa8c84964694e95a0452d582b836 100644 (file)
@@ -34,7 +34,7 @@
 #endif
 //-----------------------------------------------------------------------------
 #include "mgl2/canvas_wnd.h"
-#include "mgl2/fltk.h"
+#include "mgl2/Fl_MathGL.h"
 //-----------------------------------------------------------------------------
 #include "xpm/show_sl.xpm"
 #include "xpm/next_sl.xpm"
@@ -127,7 +127,7 @@ void Fl_MathGL::set_graph(HMGL GR)
 {
        mglCanvas *gg = dynamic_cast<mglCanvas *>(GR);
        if(!gg) return;
-       if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);
+       if(gr && mgl_use_graph(gr,-1)<1)        mgl_delete_graph(gr);
        gr=gg;  mgl_use_graph(gg,1);
        gr->SetEventFunc(mgl_fltk_event_func, NULL);
 }
@@ -378,7 +378,7 @@ void Fl_MGLView::update()
 }
 void MGL_NO_EXPORT mgl_draw_cb(Fl_Widget*, void* v)
 {      if(v)   ((Fl_MGLView*)v)->update();     }
-void mglCanvasFL::Update()             {       mgl->update();  }
+void mglCanvasFL::Update()             {       mgl->update();  Wnd->show();    }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_png_cb(Fl_Widget*, void* v)
 {
@@ -649,7 +649,7 @@ Fl_MGLView::~Fl_MGLView()   {}
 //
 //-----------------------------------------------------------------------------
 mglCanvasFL::mglCanvasFL() : mglCanvasWnd()    {       Wnd=0;  }
-mglCanvasFL::~mglCanvasFL()            {       if(Wnd) delete Wnd;     }
+mglCanvasFL::~mglCanvasFL()            {       if(Wnd) {       mgl->FMGL->gr=0;        delete Wnd;     }       }
 //-----------------------------------------------------------------------------
 void mglCanvasFL::GotoFrame(int d)
 {
index ad6bb1be0d6b13a7960e9890eea06b43f34e4439..e371e45ebcfa4e2425a1b03104e17965bb17ea74 100644 (file)
@@ -82,27 +82,7 @@ void MGL_EXPORT mgl_ask_qt(const wchar_t *quest, wchar_t *res)
 {      QInputDialog::getText(QApplication::activeWindow(), "MathGL",
                                                QString::fromWCharArray(quest)).toWCharArray(res);      }
 //-----------------------------------------------------------------------------
-//
-//             class QMathGL
-//
-//-----------------------------------------------------------------------------
-/// Internal class to be used for multi-threading plotting
-/*class mglTask : public QObject
-{
-       Q_OBJECT
-public:
-       mglCanvas *gr;          ///< Built-in mglCanvasQT-er instance (used by default)
-       void *draw_par;         ///< Parameters for drawing function mglCanvasWnd::DrawFunc.
-       /// Drawing function for window procedure. It should return the number of frames.
-       int (*draw_func)(mglBase *gr, void *par);
-       mglDraw *draw;          ///< Class for drawing -- need to call directly due to inheritance mechanism
-public slots:
-       void doWork();
-signals:
-       void plotDone();
-};
-//-----------------------------------------------------------------------------
-void mglTask::doWork()
+/*void mglTask::doWork()
 {
        setlocale(LC_NUMERIC, "C");
        if(mgl_is_frames(gr))   mgl_new_frame(gr);
@@ -142,7 +122,7 @@ QMathGL::QMathGL(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
 QMathGL::~QMathGL()
 {
        timer->stop();  timerRefr->stop();
-       if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);
+       if(gr && mgl_use_graph(gr,-1)<1)        mgl_delete_graph(gr);
        if(grBuf)       delete []grBuf;
        if(draw)        delete draw;
 }
@@ -988,7 +968,7 @@ void QMathGL::addText(QString txt)
 mglCanvasQT::mglCanvasQT() : mglCanvasWnd()
 {      Wnd = 0;        }
 mglCanvasQT::~mglCanvasQT()
-{      if(Wnd) delete Wnd;     }
+{      if(Wnd) {       QMGL->gr=0;     delete Wnd;     }       }
 //-----------------------------------------------------------------------------
 void mglCanvasQT::GotoFrame(int d)
 {
@@ -1009,13 +989,13 @@ void mglCanvasQT::ToggleAlpha()  {       QMGL->setAlpha(!QMGL->getAlpha());      }
 //-----------------------------------------------------------------------------
 void mglCanvasQT::ToggleLight()        {       QMGL->setLight(!QMGL->getLight());      }
 //-----------------------------------------------------------------------------
-void mglCanvasQT::ToggleNo()           {       QMGL->restore();        }
+void mglCanvasQT::ToggleNo()   {       QMGL->restore();        }
 //-----------------------------------------------------------------------------
 void mglCanvasQT::ToggleZoom() {       QMGL->setZoom(!QMGL->getZoom());        }
 //-----------------------------------------------------------------------------
 void mglCanvasQT::ToggleRotate(){      QMGL->setRotate(!QMGL->getRotate());}
 //-----------------------------------------------------------------------------
-void mglCanvasQT::Update()             {       SetCurFig(0);   QMGL->update(); }
+void mglCanvasQT::Update()             {       SetCurFig(0);   QMGL->update(); Wnd->show();    }
 //-----------------------------------------------------------------------------
 void mglCanvasQT::Adjust()             {       QMGL->adjust(); }
 //-----------------------------------------------------------------------------
index 00affe5ad249991ee37ff0f340d0332bbd2e3f70..569f931143e84c871420a1c1c0a96e25d2d601f3 100644 (file)
@@ -1,71 +1,29 @@
 include(GenerateExportHeader)
 add_compiler_export_flags()
-function(libmglqt mglqt)
-       add_library(mgl-${mglqt} SHARED ${MGL_QT_FILES})
-       add_library(mgl-${mglqt}-static STATIC ${MGL_QT_FILES})
-       set_target_properties(mgl-${mglqt} PROPERTIES SOVERSION ${MathGL_SOVERSION})
-       set_target_properties(mgl-${mglqt} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       set_target_properties(mgl-${mglqt} PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-       set_target_properties(mgl-${mglqt}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       target_compile_definitions(mgl-${mglqt}-static PUBLIC MGL_STATIC_DEFINE)
-       target_link_libraries(mgl-${mglqt} mgl)
-       target_link_libraries(mgl-${mglqt} ${QT_LIBRARIES})
-
-       if(enable-mgl2)
-               set_target_properties(mgl-${mglqt} PROPERTIES OUTPUT_NAME "mgl2-${mglqt}")
-               set_target_properties(mgl-${mglqt}-static PROPERTIES OUTPUT_NAME "mgl2-${mglqt}")
-       else(enable-mgl2)
-               set_target_properties(mgl-${mglqt}-static PROPERTIES OUTPUT_NAME "mgl-${mglqt}")
-       endif(enable-mgl2)
-
-       install(
-               TARGETS mgl-${mglqt} mgl-${mglqt}-static
-               RUNTIME DESTINATION bin
-               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-       )
-endfunction(libmglqt mglqt)
 
 if(enable-qt4)
        include(../../cmake-qt4.txt)
-       qt4_wrap_cpp(MGL_MOC_FILES ../../include/mgl2/qmathgl.h)
-       set(MGL_QT_FILES ../qt.cpp ${MGL_MOC_FILES} ../../include/mgl2/qt.h ../../include/mgl2/qmathgl.h)
-       libmglqt(qt4)
+       set(MGL_QT4_FILES ../qt.cpp ../../include/mgl2/qt.h ../../include/mgl2/qmathgl.h)
+       mgl_add_lib(qt4 ${MGL_QT4_FILES})
+       qt4_use_modules(mgl-qt4 ${MGL_QT4_LIBS})
+       qt4_use_modules(mgl-qt4-static ${MGL_QT4_LIBS})
+       target_link_libraries(mgl-qt4 mgl)
+       target_link_libraries(mgl-qt4-static mgl)
        if(NOT enable-qt5asqt)
-               libmglqt(qt)
+               mgl_add_lib(qt ${MGL_QT4_FILES})
+               qt4_use_modules(mgl-qt ${MGL_QT4_LIBS})
+               qt4_use_modules(mgl-qt-static ${MGL_QT4_LIBS})
+               target_link_libraries(mgl-qt mgl)
+               target_link_libraries(mgl-qt-static mgl)
        endif(NOT enable-qt5asqt)
 
        if(MGL_HAVE_FLTK AND NOT enable-qt5)
-               include_directories(${FLTK_INCLUDE_DIR})
-
-               set(MGL_WND_SRC ${MGL_QT_FILES} ../fltk.cpp ../../include/mgl2/fltk.h)
-
-               add_library(mgl-wnd SHARED ${MGL_WND_SRC})
-               add_library(mgl-wnd-static STATIC ${MGL_WND_SRC})
-
-               set_target_properties(mgl-wnd PROPERTIES SOVERSION ${MathGL_SOVERSION})
-               set_target_properties(mgl-wnd PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-               set_target_properties(mgl-wnd PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-               set_target_properties(mgl-wnd-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-               target_compile_definitions(mgl-wnd-static PUBLIC MGL_STATIC_DEFINE)
-               if(enable-mgl2)
-                       set_target_properties(mgl-wnd PROPERTIES OUTPUT_NAME "mgl2-wnd")
-                       set_target_properties(mgl-wnd-static PROPERTIES OUTPUT_NAME "mgl2-wnd")
-               else(enable-mgl2)
-                       set_target_properties(mgl-wnd-static PROPERTIES OUTPUT_NAME "mgl-wnd")
-               endif(enable-mgl2)
-
-               target_link_libraries(mgl-wnd mgl)
-               target_link_libraries(mgl-wnd ${QT_LIBRARIES})
-               target_link_libraries(mgl-wnd ${FLTK_LIBRARIES})
-
-               install(
-                       TARGETS mgl-wnd mgl-wnd-static
-                       RUNTIME DESTINATION bin
-                       ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-                       LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-               )
+               mgl_add_lib(wnd ${MGL_QT4_FILES} ../fltk.cpp ../../include/mgl2/fltk.h)
+               target_include_directories(mgl-wnd SYSTEM PUBLIC ${FLTK_INCLUDE_DIR})
+               target_include_directories(mgl-wnd-static SYSTEM PUBLIC ${FLTK_INCLUDE_DIR})
+               qt4_use_modules(mgl-wnd ${MGL_QT4_LIBS})
+               qt4_use_modules(mgl-wnd-static ${MGL_QT4_LIBS})
+               target_link_libraries(mgl-wnd mgl ${FLTK_LIBRARIES})
+               target_link_libraries(mgl-wnd-static mgl ${FLTK_LIBRARIES})
        endif(MGL_HAVE_FLTK AND  NOT enable-qt5)
-else(enable-qt4)
-       set(MGL_HAVE_QT4 0)
 endif(enable-qt4)
index da87a6b835f1d305c074b4787b6697904e74d33e..dcc30e53ebde5e4e48c12a32042627a2cd18914b 100644 (file)
@@ -1,72 +1,28 @@
 include(GenerateExportHeader)
 add_compiler_export_flags()
 
-function(libmglqt mglqt)
-       add_library(mgl-${mglqt} SHARED ${MGL_QT_FILES})
-       add_library(mgl-${mglqt}-static STATIC ${MGL_QT_FILES})
-       set_target_properties(mgl-${mglqt} PROPERTIES SOVERSION ${MathGL_SOVERSION})
-       set_target_properties(mgl-${mglqt} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       set_target_properties(mgl-${mglqt} PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-       set_target_properties(mgl-${mglqt}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-       target_compile_definitions(mgl-${mglqt}-static PUBLIC MGL_STATIC_DEFINE)
-       target_link_libraries(mgl-${mglqt} mgl)
-       qt5_use_modules(mgl-${mglqt} Core Widgets Gui PrintSupport)
-       qt5_use_modules(mgl-${mglqt}-static Core Widgets Gui PrintSupport)
-       if(enable-mgl2)
-               set_target_properties(mgl-${mglqt} PROPERTIES OUTPUT_NAME "mgl2-${mglqt}")
-               set_target_properties(mgl-${mglqt}-static PROPERTIES OUTPUT_NAME "mgl2-${mglqt}")
-       else(enable-mgl2)
-               set_target_properties(mgl-${mglqt}-static PROPERTIES OUTPUT_NAME "mgl-${mglqt}")
-       endif(enable-mgl2)
-       install(
-               TARGETS mgl-${mglqt} mgl-${mglqt}-static
-               RUNTIME DESTINATION bin
-               ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-               LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-       )
-endfunction(libmglqt mglqt)
-
 if(enable-qt5)
        include(../../cmake-qt5.txt)
-       qt5_wrap_cpp(MGL_MOC_FILES ../../include/mgl2/qmathgl.h)
-       set(MGL_QT_FILES ../qt.cpp ${MGL_MOC_FILES} ../../include/mgl2/qt.h ../../include/mgl2/qmathgl.h)
-       libmglqt(qt5)
+       set(MGL_QT5_FILES ../qt.cpp ../../include/mgl2/qt.h ../../include/mgl2/qmathgl.h)
+       mgl_add_lib(qt5 ${MGL_QT5_FILES})
+       qt5_use_modules(mgl-qt5 ${MGL_QT5_LIBS})
+       qt5_use_modules(mgl-qt5-static ${MGL_QT5_LIBS})
+       target_link_libraries(mgl-qt5 mgl)
+       target_link_libraries(mgl-qt5-static mgl)
        if(enable-qt5asqt)
-               libmglqt(qt)
+               mgl_add_lib(qt ${MGL_QT5_FILES})
+               qt5_use_modules(mgl-qt ${MGL_QT5_LIBS})
+               qt5_use_modules(mgl-qt-static ${MGL_QT5_LIBS})
+               target_link_libraries(mgl-qt mgl)
+               target_link_libraries(mgl-qt-static mgl)
        endif(enable-qt5asqt)
-
        if(MGL_HAVE_FLTK)
-               include_directories(${FLTK_INCLUDE_DIR})
-
-               set(MGL_WND_SRC ${MGL_QT_FILES} ../fltk.cpp ../../include/mgl2/fltk.h)
-
-               add_library(mgl-wnd SHARED ${MGL_WND_SRC})
-               add_library(mgl-wnd-static STATIC ${MGL_WND_SRC})
-
-               set_target_properties(mgl-wnd PROPERTIES SOVERSION ${MathGL_SOVERSION})
-               set_target_properties(mgl-wnd PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-               set_target_properties(mgl-wnd PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
-               set_target_properties(mgl-wnd-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-               target_compile_definitions(mgl-wnd-static PUBLIC MGL_STATIC_DEFINE)
-               if(enable-mgl2)
-                       set_target_properties(mgl-wnd PROPERTIES OUTPUT_NAME "mgl2-wnd")
-                       set_target_properties(mgl-wnd-static PROPERTIES OUTPUT_NAME "mgl2-wnd")
-               else(enable-mgl2)
-                       set_target_properties(mgl-wnd-static PROPERTIES OUTPUT_NAME "mgl-wnd")
-               endif(enable-mgl2)
-
-               target_link_libraries(mgl-wnd mgl)
-               qt5_use_modules(mgl-wnd Core Widgets Gui PrintSupport)
-               qt5_use_modules(mgl-wnd-static Core Widgets Gui PrintSupport)
-               target_link_libraries(mgl-wnd ${FLTK_LIBRARIES})
-
-               install(
-                       TARGETS mgl-wnd mgl-wnd-static
-                       RUNTIME DESTINATION bin
-                       ARCHIVE DESTINATION ${MGL_LIB_INSTALL_DIR}
-                       LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR}
-               )
+               mgl_add_lib(wnd ${MGL_QT5_FILES} ../fltk.cpp ../../include/mgl2/fltk.h)
+               target_include_directories(mgl-wnd SYSTEM PUBLIC ${FLTK_INCLUDE_DIR})
+               target_include_directories(mgl-wnd-static SYSTEM PUBLIC ${FLTK_INCLUDE_DIR})
+               qt5_use_modules(mgl-wnd ${MGL_QT5_LIBS})
+               qt5_use_modules(mgl-wnd-static ${MGL_QT5_LIBS})
+               target_link_libraries(mgl-wnd mgl ${FLTK_LIBRARIES})
+               target_link_libraries(mgl-wnd-static mgl ${FLTK_LIBRARIES})
        endif(MGL_HAVE_FLTK)
-else(enable-qt5)
-       set(MGL_HAVE_QT5 0)
 endif(enable-qt5)