[mathgl] 01/02: Imported Upstream version 2.3.4

Dimitrios Eftaxiopoulos eftaxiop-guest at moszumanska.debian.org
Sun Feb 14 13:10:55 UTC 2016


This is an automated email from the git hooks/post-receive script.

eftaxiop-guest pushed a commit to branch master
in repository mathgl.

commit d43a236cf87b967008a7e19d29115f1ee6f6208d
Author: Dimitrios Eftaxiopoulos <eftaxi12 at otenet.gr>
Date:   Sun Feb 14 15:00:43 2016 +0200

    Imported Upstream version 2.3.4
---
 CMakeLists.txt                |   44 +-
 ChangeLog                     |    1 -
 ChangeLog.txt                 |   56 ++-
 clean-svn                     |    3 -
 examples/CMakeLists.txt       |    4 +-
 examples/fltk_example.cpp     |   37 +-
 examples/full_test.cpp        |   44 +-
 examples/qt_example.cpp       |   36 +-
 examples/samples.cpp          |  174 ++++++-
 fonts/CMakeLists.txt          |    7 +-
 {utils => fonts}/make_bin.cpp |    2 +-
 include/config.h.in           |    4 +-
 include/mgl2/Fl_MathGL.h      |   12 +-
 include/mgl2/abstract.h       |   42 +-
 include/mgl2/base.h           |    8 +-
 include/mgl2/canvas_cf.h      |   10 +-
 include/mgl2/canvas_wnd.h     |    3 +
 include/mgl2/data.h           |   39 +-
 include/mgl2/data_cf.h        |   18 +-
 include/mgl2/datac.h          |    4 +-
 include/mgl2/define.h         |    4 +
 include/mgl2/fltk.h           |    4 +-
 include/mgl2/font.h           |    2 +-
 include/mgl2/mgl.h            |   31 +-
 include/mgl2/pde.h            |   11 +
 include/mgl2/plot.h           |   12 +-
 include/mgl2/prim.h           |    2 +-
 include/mgl2/qmathgl.h        |    9 +
 include/mgl2/wnd.h            |   46 +-
 include/xpm/pause.xpm         |   22 +
 json/Backend.hpp              |    1 +
 lang/data.i                   |   26 +
 lang/mgl.i                    | 1102 ++++++++++++++++++++++++++++++++++++-----
 make_release                  |   57 +++
 mgltex/CMakeLists.txt         |   14 +-
 mgltex/mgltex.dtx             |  556 +++++++++++++--------
 mgltex/mgltex.ins             |    4 +-
 mgltex/mgltex.pdf             |  Bin 510993 -> 521993 bytes
 mgltex/mgltex.sty             |  882 ---------------------------------
 mgltex/sample.tex             |   26 +-
 src/CMakeLists.txt            |    2 +-
 src/addon.cpp                 |    1 -
 src/base.cpp                  |    5 +-
 src/canvas.cpp                |    4 +-
 src/canvas_cf.cpp             |    8 +
 src/complex.cpp               |   24 +-
 src/complex_ex.cpp            |    2 +-
 src/cont.cpp                  |    2 +-
 src/crust.cpp                 |  107 +++-
 src/data.cpp                  |   35 +-
 src/data_ex.cpp               |    6 +-
 src/data_gr.cpp               |    4 +-
 src/data_io.cpp               |   64 ++-
 src/def_font.cc               |    2 +-
 src/eval.cpp                  |   16 +-
 src/evalp.cpp                 |   22 +-
 src/exec.cpp                  |  123 +++--
 src/fit.cpp                   |    2 +-
 src/font.cpp                  |    6 +-
 src/parser.cpp                |    7 -
 src/pde.cpp                   |  223 ++++++++-
 src/pixel.cpp                 |  137 ++---
 src/prim.cpp                  |    8 +-
 src/vect.cpp                  |   10 +-
 src/volume.cpp                |   28 +-
 src/window.cpp                |   25 +-
 texinfo/CMakeLists.txt        |   11 +-
 texinfo/core_en.texi          |   56 ++-
 texinfo/core_ru.texi          |   55 +-
 texinfo/data_en.texi          |   84 +++-
 texinfo/data_ru.texi          |   86 +++-
 texinfo/ex_mgl_en.texi        |  191 ++++++-
 texinfo/ex_mgl_ru.texi        |  194 +++++++-
 texinfo/example_en.texi       |  435 +++++++++++-----
 texinfo/example_ru.texi       |  427 ++++++++++++----
 texinfo/overview_en.texi      |   31 +-
 texinfo/overview_ru.texi      |   29 +-
 texinfo/symbols_en.texi       |    4 +-
 texinfo/symbols_ru.texi       |    4 +-
 texinfo/version_hist.txt      |    4 +-
 texinfo/web_en.texi           |   55 +-
 texinfo/web_ru.texi           |   54 +-
 texinfo/widget_en.texi        |  166 +++++--
 texinfo/widget_ru.texi        |  168 +++++--
 todo.txt                      |   29 +-
 udav/CMakeLists.txt           |    4 +-
 utils/CMakeLists.txt          |    9 +-
 utils/mglcgi.cpp              |    1 -
 utils/mglconv.cpp             |    6 +-
 utils/mglview.cpp             |    2 +-
 widgets/fltk.cpp              |   42 +-
 widgets/qt.cpp                |   44 +-
 92 files changed, 4333 insertions(+), 2090 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e2f5e46..744680e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,8 +12,8 @@ endif(NOT CMAKE_BUILD_TYPE)
 
 set(CMAKE_VERBOSE_MAKEFILE ON)
 set(MathGL_VERSION_MAJOR 2)
-set(MathGL_VERSION_MINOR 3.3)
-set(MathGL_SOVERSION 7.4.0)
+set(MathGL_VERSION_MINOR 3.4)
+set(MathGL_SOVERSION 7.4.1)
 
 function(mgl_add_lib mgl_tmp_lib)
        if(${mgl_tmp_lib} MATCHES mgl)
@@ -104,7 +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-pthr-widget "Enable POSIX threads for widgets" ON)
 option(enable-openmp "Enable OpenMP support" ON)
 
 if(enable-pthread AND enable-openmp)
@@ -146,10 +146,10 @@ endif(UNIX AND enable-rvalue)
 # MSVC does not require any special flags
 
 if(enable-qt4 OR enable-qt5)
-set(enable-qt ON)
+set(QT_ENABLED ON)
 endif(enable-qt4 OR enable-qt5)
 
-CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample" ON "enable-qt" OFF)
+CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample" ON "QT_ENABLED" OFF)
 MGL_DEPENDENT_OPTION(enable-python "Enable python interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
 MGL_DEPENDENT_OPTION(enable-lua "Enable Lua (v.5.1) interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
 MGL_DEPENDENT_OPTION(enable-octave "Enable octave interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
@@ -291,15 +291,18 @@ else(enable-pthread)
 	set(MGL_HAVE_PTHREAD 0)
 endif(enable-pthread)
 
+if(enable-pthr-widget OR enable-pthread)
+	set(MGL_HAVE_PTHR_WIDGET 1)
+	include(FindThreads)
+	if(NOT CMAKE_USE_PTHREADS_INIT)
+		message(SEND_ERROR "Couldn't find POSIX threads library.")
+	endif(NOT CMAKE_USE_PTHREADS_INIT)
+else(enable-pthr-widget OR enable-pthread)
+	set(MGL_HAVE_PTHR_WIDGET 0)
+endif(enable-pthr-widget OR 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)
@@ -308,6 +311,12 @@ if(enable-gsl)
 		message(SEND_ERROR "${GSL_CBLAS_LIB}")
 		message(SEND_ERROR "${GSL_INCLUDE_DIR}")
 		message(SEND_ERROR "Couldn't find GSL libraries.")
+	else(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR)
+		set(CMAKE_REQUIRED_INCLUDES ${GSL_INCLUDE_DIR})
+		set(CMAKE_REQUIRED_LIBRARIES ${GSL_LIB} ${GSL_CBLAS_LIB})
+		CHECK_CXX_SOURCE_COMPILES("#include <gsl/gsl_multifit_nlin.h>
+		int main(){gsl_multifit_fdfsolver *s=0;gsl_matrix *J = 0;
+		gsl_multifit_fdfsolver_jac(s, J);}" MGL_HAVE_GSL2)
 	endif(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR)
 else(enable-gsl)
 	set(MGL_HAVE_GSL 0)
@@ -343,9 +352,12 @@ endif(enable-hdf4)
 
 if(enable-hdf5)
 	set(MGL_HAVE_HDF5 1)
-	include(FindHDF5)
+	find_package(HDF5)
 	if(NOT HDF5_FOUND)
-		message(SEND_ERROR "Couldn't find HDF5 library.")
+		find_package(HDF5 NAMES hdf5 COMPONENTS C shared static)
+		if(NOT HDF5_FOUND)
+			message(SEND_ERROR "Couldn't find HDF5 library.")
+		endif(NOT HDF5_FOUND)
 	endif(NOT HDF5_FOUND)
 else(enable-hdf5)
 	set(MGL_HAVE_HDF5 0)
@@ -556,8 +568,10 @@ if(NOT enable-lgpl)
 	endif(enable-python OR enable-lua OR enable-octave)
 	if(NOT MSVC AND NOT BORLAND)
 		add_subdirectory( utils )
-		add_subdirectory( fonts )
 	endif(NOT MSVC AND NOT BORLAND)
+	if(NOT WIN32)
+		add_subdirectory( fonts )
+	endif(NOT WIN32)
 #	add_subdirectory( mgllab )
 endif(NOT enable-lgpl)
 
diff --git a/ChangeLog b/ChangeLog
deleted file mode 120000
index 74b6820..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1 +0,0 @@
-ChangeLog.txt
\ No newline at end of file
diff --git a/ChangeLog.txt b/ChangeLog.txt
index f58b86c..c481c3d 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,45 +1,53 @@
-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
+2.3.4 Released 13 February 2016
+
+* Add mglData::Pulse() for determining pulse parameters.
+* Add mglData::ScanFile() for getting formated data from textual file.
+* Add mglData::SetList() for setting data from variable argument list of double values.
+* Add mglIFS2d() and mglIFS3d() for fractal generation using iterated function system (thanks to Diego Sejas Viscarra).
+* Add option to SetSize() for scaling only primitives but don't erase it.
+* 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'
+* Add MGL command 'echo' for printing the content of data.
+* Add MGL command 'print' -- like 'info' but print immediately in stdout.
+* Allow MGL command 'save' append textual strings to a file.
+* Add option to rewrite file in 'savehdf'.
+
+* Add callback functions to mglQt, mglFLTK, and extend mglDraw class for simpler drawing in parallel with calculation (see @ref{Draw and calculate}).
 
-* Force set focus for editor in UDAV
+* 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
+* Disable mouse wheel for zooming in UDAV by default.
 
-* Update mgltex (thanks to Diego Sejas Viscarra)
+* Update mgltex (thanks to Diego Sejas Viscarra).
+
+* INCOMPATIBLE: Scale internally d1,d2 arguments in Curve() to be exactly the same as Bezier curve (P0=p1, P1=d1+p1, P2=p2-d2, P3=p2).
 
-* Bugfixes
+* Minor bugfixes and improvements.
 
 2.3.3 Released 01 June 2015
 
-* Add SurfCA() and Surf3CA() plots
-* Add wavelet transforms
-* Add AttachLight() for attaching light settings to inplots
-* Add manual rotation angle for axis ticks (by "value" option)
+* Add SurfCA() and Surf3CA() plots.
+* Add wavelet transforms.
+* Add AttachLight() for attaching light settings to inplots.
+* Add manual rotation angle for axis ticks (by "value" option).
 * Add mglDataS class which is similar to std::vector<double> one.
-* Add missing mglDataC functions
+* Add missing mglDataC functions.
 
-* Add style '%' for color scheme along 2 coordinates (as in Map())
+* Add style '%' for color scheme along 2 coordinates (as in Map()).
 * If tick template start with '&' then long integer is passed instead of double.
 * Add style 'V' for drawing text centered vertically.
 * Add style "dN" in Smooth() for averaging over (2*N+1)-th points.
 * Add TeX symbols "\quote", "--" and Cyrillic ones.
 
-* Add complex numbers in MGL -- any expression started with '!' will have complex value(s)
-* Add 'rkstep' command for Runge-Kutta step in MGL script
+* Add complex numbers in MGL -- any expression started with '!' will have complex value(s).
+* Add 'rkstep' command for Runge-Kutta step in MGL script.
 * Add functions 'min()', 'max()' to MGL parser and formula evaluation.
 * MGL command 'join' now can join arbitrary number of data arrays.
-* Command 'stop' is not required to be placed before 'func'
-* Add warning about writing to temporary arrays in MGL scripts
+* Command 'stop' is not required to be placed before 'func'.
+* Add warning about writing to temporary arrays in MGL scripts.
 * Names 'rnd','nan','inf' are reserved in MGL scripts now.
 
 * Add annotation for plot styles and options into header files.
diff --git a/clean-svn b/clean-svn
deleted file mode 100755
index f0ba47a..0000000
--- a/clean-svn
+++ /dev/null
@@ -1,3 +0,0 @@
-find . -name '.svn' -print0 | xargs -0 rm -rf
-find . -name '*~' -print0 | xargs -0 rm -f
-rm ./clean-svn
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 4f71340..75a0465 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -22,7 +22,7 @@ if(MGL_HAVE_WX)
 	target_link_libraries(mgl_wx_example mgl-wx)
 endif(MGL_HAVE_WX)
 
-if(enable-qt)
+if(QT_ENABLED)
 	add_executable(mgl_qt_example wnd_samples.cpp qt_example.cpp)
 	if(enable-qt5)
 		include(../cmake-qt5.txt)
@@ -40,7 +40,7 @@ if(enable-qt)
 		qt4_use_modules(mgl_qgl_example ${MGL_QT4_LIBS})
 	endif(enable-qt5)
 
-endif(enable-qt)
+endif(QT_ENABLED)
 
 if(MGL_HAVE_LTDL)
 	include_directories(${LTDL_INCLUDE_DIR})
diff --git a/examples/fltk_example.cpp b/examples/fltk_example.cpp
index e4a8013..6595211 100644
--- a/examples/fltk_example.cpp
+++ b/examples/fltk_example.cpp
@@ -74,11 +74,13 @@ int main(int argc,char **argv)
 		gr.Clf();			// make new drawing
 		gr.Line(mglPoint(),pnt,"Ar2");
 		char str[10] = "i=0";	str[3] = '0'+i;
+		gr->Puts(mglPoint(),str);
 		gr.Update();		// update window
 	}
 	return 0;	// finish calculations and close the window
 }
 #else		// just default samples
+//-----------------------------------------------------------------------------
 int test_wnd(mglGraph *gr);
 int sample(mglGraph *gr);
 int sample_1(mglGraph *gr);
@@ -86,12 +88,41 @@ int sample_2(mglGraph *gr);
 int sample_3(mglGraph *gr);
 int sample_d(mglGraph *gr);
 //-----------------------------------------------------------------------------
+#if MGL_HAVE_PTHR_WIDGET
+class myDraw : public mglDraw
+{
+	mglPoint pnt;	// some variable for changeable data
+	long i;			// another variable to be shown
+	mglWnd *wnd;	// external window for plotting
+public:
+	myDraw(mglWnd *w=0) : mglDraw()	{	wnd=w;	}
+	void SetWnd(mglWnd *w)	{	wnd=w;	}
+	int Draw(mglGraph *gr)
+	{
+		gr->Line(mglPoint(),pnt,"Ar2");
+		char str[16];	snprintf(str,15,"i=%ld",i);
+		gr->Puts(mglPoint(),str);
+		return 0;
+	}
+	void Calc()
+	{
+		for(i=0;;i++)	// do calculation
+		{
+			Check();	// check if need pause
+			long_calculations();// which can be very long
+			pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+			if(wnd)	wnd->Update();
+		}
+	}
+} dr;
+#endif
+//-----------------------------------------------------------------------------
 int main(int argc,char **argv)
 {
 	mglFLTK *gr;
 	char key = 0;
 	if(argc>1)	key = argv[1][0]!='-' ? argv[1][0]:argv[1][1];
-	else	printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");
+	else	printf("You may specify argument '1', '2', '3', 'd' for viewing examples of 1d, 2d, 3d, dual plotting,\nor 'm' for multi-threading sample.\n");
 	switch(key)
 	{
 	case '0':	gr = new mglFLTK((mglDraw *)NULL,"1D plots");	break;
@@ -100,6 +131,10 @@ int main(int argc,char **argv)
 	case '3':	gr = new mglFLTK(sample_3,"3D plots");	break;
 	case 'd':	gr = new mglFLTK(sample_d,"Dual plots");break;
 	case 't':	gr = new mglFLTK(test_wnd,"Testing");	break;
+#if MGL_HAVE_PTHR_WIDGET
+	case 'm':	gr = new mglFLTK(&dr,"Multi-threading test");
+	dr.SetWnd(gr);	dr.Run();	break;
+#endif
 	default:	gr = new mglFLTK(sample,"Drop and waves");	break;
 	}
 	if(key=='0')
diff --git a/examples/full_test.cpp b/examples/full_test.cpp
index 154b4eb..acf8612 100644
--- a/examples/full_test.cpp
+++ b/examples/full_test.cpp
@@ -65,6 +65,9 @@ void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez);
 void save(mglGraph *gr,const char *name,const char *suf);
 void test(mglGraph *gr)
 {
+	mglData a;	a.SetList(5,0.,1.,0.,1.,-1.,2.);
+	gr->Plot(a);
+	return;
 	mglParse par;
 	par.Execute(gr,"call 'test' -1\n func 'test' 1\nline $1 0 1 1 'b'\nreturn\n");
 //	par.Execute(gr,"load '/home/balakin/mathgl-code/mathgl-2x/build/examples/libmgl_module.so':baxis\n");
@@ -75,37 +78,41 @@ void test(mglGraph *gr)
 #if !defined(_MSC_VER) && !defined(__BORLANDC__)
 static struct option longopts[] =
 {
-	{ "mini",	no_argument,	&big,	3 },
 	{ "big",	no_argument,	&big,		1 },
 	{ "web",	no_argument,	&big,		2 },
-	{ "bps",	no_argument,	&type,		8 },
+	{ "mini",	no_argument,	&big,		3 },
 	{ "help",	no_argument,	NULL,		'?' },
 	{ "height",	required_argument,	NULL,	'h' },
-	{ "png",	no_argument,	&type,		0 },
-	{ "eps",	no_argument,	&type,		1 },
-	{ "gif",	no_argument,	&type,		6 },
-	{ "jpeg",	no_argument,	&type,		4 },
 	{ "kind",	required_argument,	NULL,	'k' },
 	{ "list",	no_argument,	NULL,		'l' },
 	{ "mgl",	no_argument,	&use_mgl,	1 },
+	{ "srnd",	no_argument,	&srnd,		1 },
+
+	{ "png",	no_argument,	&type,		0 },
+	{ "eps",	no_argument,	&type,		1 },
+	{ "svg",	no_argument,	&type,		2 },
+	{ "solid",	no_argument,	&type,		3 },
+	{ "jpeg",	no_argument,	&type,		4 },
+	{ "prc",	no_argument,	&type,		5 },
+	{ "gif",	no_argument,	&type,		6 },
 	{ "none",	no_argument,	&type,		7 },
-	{ "obj",	no_argument,	&type,		11 },
+	{ "bps",	no_argument,	&type,		8 },
+	{ "pdf",	no_argument,	&type,		9 },
 	{ "obj_old",no_argument,	&type,		10 },
+	{ "obj",	no_argument,	&type,		11 },
 	{ "off",	no_argument,	&type,		12 },
-	{ "prc",	no_argument,	&type,		5 },
-	{ "pdf",	no_argument,	&type,		9 },
-	{ "solid",	no_argument,	&type,		3 },
-	{ "srnd",	no_argument,	&srnd,		1 },
-	{ "svg",	no_argument,	&type,		2 },
 	{ "stl",	no_argument,	&type,		13 },
 	{ "tex",	no_argument,	&type,		14 },
 	{ "json",	no_argument,	&type,		15 },
 	{ "jsonz",	no_argument,	&type,		16 },
+	{ "docs",	no_argument,	&type,		17 },
+
 	{ "test",	no_argument,	&dotest,	1 },
 	{ "font",	no_argument,	&dotest,	2 },
 	{ "time",	no_argument,	&dotest,	3 },
 	{ "fexport",no_argument,	&dotest,	4 },
 	{ "textbl",	no_argument,	&dotest,	5 },
+
 	{ "thread",	required_argument,	NULL,	't' },
 	{ "verbose",no_argument,	&verbose,	1 },
 	{ "width",	required_argument,	NULL,	'w' },
@@ -135,6 +142,7 @@ void usage()
 		"--obj_old	- output obj/mtl in old way\n"
 		"--off		- output off\n"
 		"--stl		- output stl\n"
+		"--docs		- output in png, prc/pdf and json\n"
 		"--none		- none output\n"
 		"--srnd		- use the same random numbers in any run\n"
 		"--list		- print list of sample names\n"
@@ -205,6 +213,14 @@ void save(mglGraph *gr,const char *name,const char *suf="")
 		case 16:	// JSON
 			snprintf(buf,128,"%s%s.jsonz",name,suf);
 			gr->WriteJSON(buf,"",true);	break;
+		case 17:	// PNG + JSON + PDF
+			snprintf(buf,128,"%s%s.png",name,suf);
+			gr->WritePNG(buf,0,true);
+			snprintf(buf,128,"%s%s.json",name,suf);
+			gr->WriteJSON(buf);
+			gr->SetSize(height,height,false);
+			snprintf(buf,128,"%s%s.prc",name,suf);
+			gr->WritePRC(buf);	remove(buf);	break;
 		default:// PNG (no alpha)
 #if MGL_HAVE_PNG
 			snprintf(buf,128,"%s%s.png",name,suf);
@@ -482,9 +498,9 @@ int main(int argc,char **argv)
 	{	smgl_fexport(gr);	delete gr;	return 0;	}
 	else if(dotest==5)
 	{
-		size_t i=0;	while(mgl_tex_symb[i].tex[0])	i++;
+		long i=0;	while(mgl_tex_symb[i].tex[0])	i++;
 		if(mgl_tex_num!=i)	printf("real=%lu, set=%ld\n",i,mgl_tex_num);
-		for(size_t i=0;mgl_tex_symb[i].tex[0];i++)
+		for(long i=0;mgl_tex_symb[i].tex[0];i++)
 		{
 				mglTeXsymb tst, *rts;	tst.tex = mgl_tex_symb[i].tex;
 				rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, mgl_tex_num, sizeof(mglTeXsymb), mgl_tex_symb_cmp);
diff --git a/examples/qt_example.cpp b/examples/qt_example.cpp
index 5fd80e9..1b7a3b0 100644
--- a/examples/qt_example.cpp
+++ b/examples/qt_example.cpp
@@ -94,6 +94,7 @@ int main(int argc,char **argv)
 	return gr.Run();
 }
 #else		// just default samples
+//-----------------------------------------------------------------------------
 int test_wnd(mglGraph *gr);
 int sample(mglGraph *gr);
 int sample_1(mglGraph *gr);
@@ -101,12 +102,41 @@ int sample_2(mglGraph *gr);
 int sample_3(mglGraph *gr);
 int sample_d(mglGraph *gr);
 //-----------------------------------------------------------------------------
+#if MGL_HAVE_PTHR_WIDGET
+class myDraw : public mglDraw
+{
+	mglPoint pnt;	// some variable for changeable data
+	long i;			// another variable to be shown
+	mglWnd *wnd;	// external window for plotting
+public:
+	myDraw(mglWnd *w=0) : mglDraw()	{	wnd=w;	}
+	void SetWnd(mglWnd *w)	{	wnd=w;	}
+	int Draw(mglGraph *gr)
+	{
+		gr->Line(mglPoint(),pnt,"Ar2");
+		char str[16];	snprintf(str,15,"i=%ld",i);
+		gr->Puts(mglPoint(),str);
+		return 0;
+	}
+	void Calc()
+	{
+		for(i=0;;i++)	// do calculation
+		{
+			Check();	// check if need pause
+			long_calculations();// which can be very long
+			pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+			if(wnd)	wnd->Update();
+		}
+	}
+} dr;
+#endif
+//-----------------------------------------------------------------------------
 int main(int argc,char **argv)
 {
 	mglQT *gr;
 	char key = 0;
 	if(argc>1)	key = argv[1][0]!='-' ? argv[1][0]:argv[1][1];
-	else	printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");
+	else	printf("You may specify argument '1', '2', '3', 'd' for viewing examples of 1d, 2d, 3d, dual plotting,\nor 'm' for multi-threading sample.\n");
 	switch(key)
 	{
 	case '0':	gr = new mglQT((mglDraw *)NULL,"1D plots");	break;
@@ -115,6 +145,10 @@ int main(int argc,char **argv)
 	case '3':	gr = new mglQT(sample_3,"3D plots");	break;
 	case 'd':	gr = new mglQT(sample_d,"Dual plots");	break;
 	case 't':	gr = new mglQT(test_wnd,"Testing");	break;
+#if MGL_HAVE_PTHR_WIDGET
+	case 'm':	gr = new mglQT(&dr,"Multi-threading test");
+	dr.SetWnd(gr);	dr.Run();	break;
+#endif
 	default: 	gr = new mglQT(sample,"Drop and waves");	break;
 	}
 	if(key=='0')
diff --git a/examples/samples.cpp b/examples/samples.cpp
index f023900..437990d 100644
--- a/examples/samples.cpp
+++ b/examples/samples.cpp
@@ -2616,15 +2616,176 @@ void smgl_mirror(mglGraph *gr)	// flag #
 	gr->Box();	gr->Axis();	gr->Legend(2,"");
 }
 //-----------------------------------------------------------------------------
+const char *mmgl_pulse="subplot 1 1 0 '<_':title 'Pulse sample'\n"
+"new a 100 'exp(-6*x^2)':ranges 0 a.nx-1 0 1\naxis:plot a\n\n"
+"pulse b a 'x'\n\ndefine m a.max\n\nline b(1) 0 b(1) m 'r='\n"
+"line b(1)-b(3)/2 0  b(1)-b(3)/2 m 'm|'\nline b(1)+b(3)/2 0  b(1)+b(3)/2 m 'm|'\n"
+"line 0 0.5*m a.nx-1 0.5*m 'h'\nnew x 100 'x'\nplot b(0)*(1-((x-b(1))/b(2))^2) 'g'";
+void smgl_pulse(mglGraph *gr)
+{
+	gr->SubPlot(1,1,0,"<_");
+	if(big!=3)	gr->Title("Pulse sample");
+	mglData a(100);	gr->Fill(a,"exp(-6*x^2)");
+	gr->SetRanges(0, a.nx-1, 0, 1);
+	gr->Axis();	gr->Plot(a);
+	mglData b(a.Pulse('x'));
+	double m = b[0];
+	gr->Line(mglPoint(b[1],0), mglPoint(b[1],m),"r=");
+	gr->Line(mglPoint(b[1]-b[3]/2,0), mglPoint(b[1]-b[3]/2,m),"m|");
+	gr->Line(mglPoint(b[1]+b[3]/2,0), mglPoint(b[1]+b[3]/2,m),"m|");
+	gr->Line(mglPoint(0,m/2), mglPoint(a.nx-1,m/2),"h");
+	char func[128];	sprintf(func,"%g*(1-((x-%g)/%g)^2)",b[0],b[1],b[2]);
+	gr->FPlot(func,"g");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_scanfile="subplot 1 1 0 '<_':title 'Save and scanfile sample'\n"
+"list a 1 -1 0\nsave 'This is test: 0 -> ',a(0),' q' 'test.txt' 'w'\n"
+"save 'This is test: 1 -> ',a(1),' q' 'test.txt'\nsave 'This is test: 2 -> ',a(2),' q' 'test.txt'\n"
+"\nscanfile a 'test.txt' 'This is test: %g -> %g'\nranges a(0) a(1):axis:plot a(0) a(1) 'o'";
+void smgl_scanfile(mglGraph *gr)
+{
+	gr->SubPlot(1,1,0,"<_");
+	if(big!=3)	gr->Title("Save and scanfile sample");
+	FILE *fp=fopen("test.txt","w");
+	fprintf(fp,"This is test: 0 -> 1 q\n");
+	fprintf(fp,"This is test: 1 -> -1 q\n");
+	fprintf(fp,"This is test: 2 -> 0 q\n");
+	fclose(fp);
+
+	mglData a;
+	a.ScanFile("test.txt","This is test: %g -> %g");
+	gr->SetRanges(a.SubData(0), a.SubData(1));
+	gr->Axis();	gr->Plot(a.SubData(0),a.SubData(1),"o");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_pendelta="quality 6\nlist a 0.25 0.5 1 2 4\nfor $0 0 4\n"
+"pendelta a($0)\ndefine $1 0.5*$0-1\nline -1 $1 1 $1 'r'\ntext 0 $1 'delta=',a($0)\nnext";
+void smgl_pendelta(mglGraph *gr)
+{
+	double a[5]={0.25,0.5,1,2,4};
+	gr->SetQuality(6);
+	char buf[64];
+	for(int i=0;i<5;i++)
+	{
+		gr->SetPenDelta(a[i]);
+		gr->Line(mglPoint(-1,0.5*i-1), mglPoint(1,0.5*i-1),"r");
+		sprintf(buf,"delta=%g",a[i]);
+		gr->Puts(mglPoint(0,0.5*i-1),buf);
+	}
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_bifurcation="subplot 1 1 0 '<_':title 'Bifurcation sample'\n"
+"ranges 0 4 0 1:axis\nbifurcation 0.005 'x*y*(1-y)' 'r'";
+void smgl_bifurcation(mglGraph *gr)
+{
+	gr->SubPlot(1,1,0,"<_");
+	if(big!=3)	gr->Title("Bifurcation sample");
+	gr->SetRanges(0,4,0,1);	gr->Axis();
+	gr->Bifurcation(0.005,"x*y*(1-y)","r");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_lamerey="subplot 1 1 0 '<_':title 'Lamerey sample'\n"
+"axis:xlabel '\\i x':ylabel '\\bar{\\i x} = 2 \\i{x}'\nfplot 'x' 'k='\nfplot '2*x' 'b'\n"
+"lamerey 0.00097 '2*x' 'rv~';size 2\nlamerey -0.00097 '2*x' 'rv~';size 2";
+void smgl_lamerey(mglGraph *gr)
+{
+	gr->SubPlot(1,1,0,"<_");
+	if(big!=3)	gr->Title("Lamerey sample");
+	gr->Axis();	gr->Label('x',"\\i x");	gr->Label('y',"\\bar{\\i x} = 2 \\i{x}");
+	gr->FPlot("x","k=");	gr->FPlot("2*x","b");
+	gr->Lamerey( 0.00097,"2*x","rv~");
+	gr->Lamerey(-0.00097,"2*x","rv~");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_pmap="subplot 1 1 0 '<_^':title 'Poincare map sample'\n"
+"ode r 'cos(y)+sin(z);cos(z)+sin(x);cos(x)+sin(y)' 'xyz' [0.1,0,0] 0.1 100\n"
+"rotate 40 60:copy x r(0):copy y r(1):copy z r(2)\nranges x y z\naxis:plot x y z 'b'\n"
+"xlabel '\\i x' 0:ylabel '\\i y' 0:zlabel '\\i z'\n"
+"pmap x y z z 'b#o'\nfsurf '0'";
+void smgl_pmap(mglGraph *gr)
+{
+	gr->SubPlot(1,1,0,"<_^");
+	if(big!=3)	gr->Title("Poincare map sample");
+	mglData ini(3);	ini[0]=0.1;
+	mglData r(mglODE("cos(y)+sin(z);cos(z)+sin(x);cos(x)+sin(y)","xyz",ini,0.1,100));
+	mglData x(r.SubData(0)),y(r.SubData(1)), z(r.SubData(2));
+	gr->Rotate(40,60);	gr->SetRanges(x,y,z);
+	gr->Axis();	gr->FSurf("0");	gr->Plot(x,y,z,"b");
+	gr->Label('x',"\\i x",0);	gr->Label('y',"\\i y",0);	gr->Label('z',"\\i z",0);
+	gr->Pmap(x,y,z,z, "b#o");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_apde="ranges -1 1 0 2 0 2\nnew ar 256 'exp(-2*(x+0.0)^2)'\nnew ai 256\n\n"
+"apde res1 'exp(-x^2-p^2)' ar ai 0.01:transpose res1\npde res2 'exp(-x^2-p^2)' ar ai 0.01\n\n"
+"subplot 1 2 0 '_':title 'Advanced PDE solver'\nranges 0 2 -1 1:crange res1\ndens res1:box\n"
+"axis:xlabel '\\i z':ylabel '\\i x'\n"
+"text -0.5 0.2 'i\\partial_z\\i u = exp(-\\i x^2+\\partial_x^2)[\\i u]' 'y'\n\n"
+"subplot 1 2 1 '_':title 'Simplified PDE solver'\n"
+"dens res2:box\naxis:xlabel '\\i z':ylabel '\\i x'\n"
+"text -0.5 0.2 'i\\partial_z\\i u \\approx\\ exp(-\\i x^2)\\i u+exp(\\partial_x^2)[\\i u]' 'y'";
+void smgl_apde(mglGraph *gr)
+{
+	gr->SetRanges(-1,1,0,2,0,2);
+	mglData ar(256), ai(256);	gr->Fill(ar,"exp(-2*(x+0.0)^2)");
+
+	mglData res1(gr->APDE("exp(-x^2-p^2)",ar,ai,0.01));	res1.Transpose();
+	mglData res2(gr->PDE("exp(-x^2-p^2)",ar,ai,0.01));
+
+	gr->SubPlot(1,2,0,"_");	gr->Title("Advanced PDE solver");
+	gr->SetRanges(0,2,-1,1);	gr->SetRange('c',res1);
+	gr->Dens(res1);	gr->Axis();	gr->Box();
+	gr->Label('x',"\\i z");	gr->Label('y',"\\i x");
+	gr->Puts(mglPoint(-0.5,0.2),"i\\partial_z\\i u = exp(-\\i x^2+\\partial_x^2)[\\i u]","y");
+
+	gr->SubPlot(1,2,1,"_");	gr->Title("Simplified PDE solver");
+	gr->Dens(res2);	gr->Axis();	gr->Box();
+	gr->Label('x',"\\i z");	gr->Label('y',"\\i x");
+	gr->Puts(mglPoint(-0.5,0.2),"i\\partial_z\\i u \\approx\\ exp(-\\i x^2)\\i u+exp(\\partial_x^2)[\\i u]","y");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_ifs2d="list A [0.33,0,0,0.33,0,0,0.2] [0.33,0,0,0.33,0.67,0,0.2] [0.33,0,0,0.33,0.33,0.33,0.2]\\\n\t"
+"[0.33,0,0,0.33,0,0.67,0.2] [0.33,0,0,0.33,0.67,0.67,0.2]\nifs2d fx fy A 100000\n"
+"subplot 1 1 0 '<_':title 'IFS 2d sample'\nranges fx fy:axis\nplot fx fy 'r#o ';size 0.05";
+void smgl_ifs2d(mglGraph *gr)
+{
+	mglData A;
+	A.SetList(35, 0.33,0.,0.,0.33,0.,0.,0.2, 0.33,0.,0.,0.33,0.67,0.,0.2, 0.33,0.,0.,0.33,0.33,0.33,0.2, 0.33,0.,0.,0.33,0.,0.67,0.2, 0.33,0.,0.,0.33,0.67,0.67,0.2);
+	A.Rearrange(7);
+	mglData f(mglIFS2d(A,100000));
+	gr->SubPlot(1,1,0,"<_");
+	if(big!=3)	gr->Title("IFS 2d sample");
+	gr->SetRanges(f.SubData(0), f.SubData(1));
+	gr->Axis();	gr->Plot(f.SubData(0), f.SubData(1),"r#o ","size 0.05");
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_ifs3d="list A [0,0,0,0,.18,0,0,0,0,0,0,0,.01] [.85,0,0,0,.85,.1,0,-0.1,0.85,0,1.6,0,.85]\\\n"
+"\t[.2,-.2,0,.2,.2,0,0,0,0.3,0,0.8,0,.07] [-.2,.2,0,.2,.2,0,0,0,0.3,0,0.8,0,.07]\n"
+"ifs3d f A 100000\ntitle 'IFS 3d sample':rotate 50 60\n"
+"ranges f(0) f(1) f(2):axis:box\ndots f(0) f(1) f(2) 'G#o';size 0.05";
+void smgl_ifs3d(mglGraph *gr)
+{
+	mglData A;
+	A.SetList(52, 0.,0.,0.,0.,.18,0.,0.,0.,0.,0.,0.,0.,.01, .85,0.,0.,0.,.85,.1,0.,-0.1,0.85,0.,1.6,0.,.85,
+			.2,-.2,0.,.2,.2,0.,0.,0.,0.3,0.,0.8,0.,.07, -.2,.2,0.,.2,.2,0.,0.,0.,0.3,0.,0.8,0.,.07);
+	A.Rearrange(13);
+	mglData f(mglIFS3d(A,100000));
+	if(big!=3)	gr->Title("IFS 3d sample");
+	gr->SetRanges(f.SubData(0), f.SubData(1), f.SubData(2));
+	gr->Rotate(50,60);	gr->Axis();	gr->Box();
+	gr->Dots(f.SubData(0), f.SubData(1), f.SubData(2),"G#o","size 0.05");
+}
+//-----------------------------------------------------------------------------
 mglSample samp[] = {
-	{"alpha", smgl_alpha, mmgl_alpha },
+	{"alpha", smgl_alpha, mmgl_alpha},
+	{"apde", smgl_apde, mmgl_apde},
 	{"area", smgl_area, mmgl_area},
-	{"aspect", smgl_aspect, mmgl_aspect },
-	{"axial", smgl_axial, mmgl_axial },
+	{"aspect", smgl_aspect, mmgl_aspect},
+	{"axial", smgl_axial, mmgl_axial},
 	{"axis", smgl_axis, mmgl_axis},
 	{"barh", smgl_barh, mmgl_barh},
 	{"bars", smgl_bars, mmgl_bars},
 	{"belt", smgl_belt, mmgl_belt},
+	{"bifurcation", smgl_bifurcation, mmgl_bifurcation},
 	{"box", smgl_box, mmgl_box},
 	{"boxplot", smgl_boxplot, mmgl_boxplot},
 	{"boxs", smgl_boxs, mmgl_boxs},
@@ -2665,9 +2826,12 @@ mglSample samp[] = {
 	{"fonts", smgl_fonts, mmgl_fonts},
 	{"grad", smgl_grad, mmgl_grad},
 	{"hist", smgl_hist, mmgl_hist},
+	{"ifs2d", smgl_ifs2d, mmgl_ifs2d},
+	{"ifs3d", smgl_ifs3d, mmgl_ifs3d},
 	{"indirect",smgl_indirect,mmgl_indirect},
 	{"inplot", smgl_inplot, mmgl_inplot},
 	{"label", smgl_label, mmgl_label},
+	{"lamerey", smgl_lamerey, mmgl_lamerey},
 	{"legend", smgl_legend, mmgl_legend },
 	{"light", smgl_light, mmgl_light},
 	{"loglog", smgl_loglog, mmgl_loglog},
@@ -2685,15 +2849,19 @@ mglSample samp[] = {
 	{"paramv", smgl_paramv, mmgl_paramv},
 	{"parser", smgl_parser, mmgl_parser},
 	{"pde", smgl_pde, mmgl_pde},
+	{"pendelta", smgl_pendelta, mmgl_pendelta},
 	{"pipe", smgl_pipe, mmgl_pipe},
 	{"plot", smgl_plot, mmgl_plot},
+	{"pmap", smgl_pmap, mmgl_pmap},
 	{"primitives", smgl_primitives, mmgl_primitives },
 	{"projection", smgl_projection, mmgl_projection },
 	{"projection5", smgl_projection5, mmgl_projection5 },
+	{"pulse", smgl_pulse, mmgl_pulse },
 	{"qo2d", smgl_qo2d, mmgl_qo2d},
 	{"radar", smgl_radar, mmgl_radar},
 	{"refill", smgl_refill, mmgl_refill},
 	{"region", smgl_region, mmgl_region},
+	{"scanfile", smgl_scanfile, mmgl_scanfile },
 	{"schemes", smgl_schemes, mmgl_schemes },
 	{"several_light", smgl_several_light, mmgl_several_light },
 	{"solve", smgl_solve, mmgl_solve},
diff --git a/fonts/CMakeLists.txt b/fonts/CMakeLists.txt
index b3428f8..28ea013 100644
--- a/fonts/CMakeLists.txt
+++ b/fonts/CMakeLists.txt
@@ -1,4 +1,6 @@
-configure_file(${MathGL_SOURCE_DIR}/texinfo/version.texi.in ${MathGL_BINARY_DIR}/texinfo/version.texi)
+
+add_executable(make_bin make_bin.cpp)
+target_link_libraries(make_bin mgl)
 
 set(MGL_FONTS STIX adventor  bonum  cursor  heroscn  heros  pagella  schola  termes)
 set(MGL_FONTS_BIN )
@@ -8,8 +10,7 @@ foreach(SAMPLE ${MGL_FONTS})
 	set(MGL_FONTS_BIN ${MGL_FONTS_BIN} ${MathGL_BINARY_DIR}/fonts/${SAMPLE}.vfmb)
 	add_custom_command(OUTPUT ${MathGL_BINARY_DIR}/fonts/${SAMPLE}.vfmb
 		COMMAND make_bin -p ${MathGL_SOURCE_DIR}/fonts/ -o ${MathGL_BINARY_DIR}/fonts/${SAMPLE}.vfmb ${SAMPLE}
-		DEPENDS ${SAMPLE}.vfm
-		WORKING_DIRECTORY ${MGL_OUT} )
+		DEPENDS ${SAMPLE}.vfm make_bin )
 endforeach(SAMPLE)
 
 add_custom_target(fonts ALL DEPENDS ${MGL_FONTS_BIN})
diff --git a/utils/make_bin.cpp b/fonts/make_bin.cpp
similarity index 99%
rename from utils/make_bin.cpp
rename to fonts/make_bin.cpp
index 44d25ee..bb4aada 100644
--- a/utils/make_bin.cpp
+++ b/fonts/make_bin.cpp
@@ -17,7 +17,7 @@
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-#include <unistd.h>
+#include <getopt.h>
 #include "mgl2/font.h"
 //-----------------------------------------------------------------------------
 int main(int argc, char *argv[])
diff --git a/include/config.h.in b/include/config.h.in
index 053824c..233e312 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -15,14 +15,14 @@
 #define MGL_SYS_NAN		0
 #define MGL_HAVE_TYPEOF	0
 #define MGL_HAVE_PTHREAD	0
-#define MGL_HAVE_PTHREAD_FLTK	0
+#define MGL_HAVE_PTHR_WIDGET	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_PTHR_WIDGET	${MGL_HAVE_PTHR_WIDGET}
 #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
index 6929500..387a347 100644
--- a/include/mgl2/Fl_MathGL.h
+++ b/include/mgl2/Fl_MathGL.h
@@ -17,7 +17,6 @@
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-//-----------------------------------------------------------------------------
 #ifndef _MGL_FL_MATHGL_H_
 #define _MGL_FL_MATHGL_H_
 
@@ -37,6 +36,7 @@ class mglCanvas;
 /// Class is FLTK widget which display MathGL graphics
 class MGL_EXPORT Fl_MathGL : public Fl_Widget
 {
+	friend class Fl_MGLView;
 public:
 	Fl_Valuator	*tet_val;	///< pointer to external tet-angle validator
 	Fl_Valuator	*phi_val;	///< pointer to external phi-angle validator
@@ -57,6 +57,11 @@ public:
 	{	set_graph(Gr->Self());	}
 	/// Get pointer to grapher
 	inline HMGL get_graph()	{	return (HMGL)gr;	}
+	/// Get mglDraw pointer or NULL
+	inline mglDraw *get_class()
+	{	mglDraw *d=0;
+		if(draw_func==mgl_draw_class)	d = (mglDraw*)draw_par;
+		if(draw_cl)	d = draw_cl;	return d;	}
 	/// Set drawing functions and its parameter
 	inline void set_draw(int (*func)(mglBase *gr, void *par), void *par)
 	{	if(draw_cl)	delete draw_cl;	draw_cl=0;	draw_func=func;	draw_par=par;	}
@@ -122,6 +127,7 @@ public:
 	void setoff_zoom()	{	setoff(zoom, zoom_bt);	}
 	void setoff_rotate(){	setoff(rotate, rotate_bt);	}
 	bool is_sshow()		{	return sshow;	}
+	void toggle_pause()	{	toggle(pauseC, pause_bt, "Graphics/Pause calc");	exec_pause();	}
 	void adjust()
 	{	mgl_set_size(FMGL->get_graph(),scroll->w(),scroll->h());	FMGL->size(scroll->w(),scroll->h());	update();	}
 
@@ -129,14 +135,16 @@ public:
 	virtual ~Fl_MGLView();
 	void update();			///< Update picture by calling user drawing function
 protected:
-	Fl_Button *alpha_bt, *light_bt, *rotate_bt, *anim_bt, *zoom_bt, *grid_bt;
+	Fl_Button *alpha_bt, *light_bt, *rotate_bt, *anim_bt, *zoom_bt, *grid_bt, *pause_bt;
 //	Fl_Counter *tet, *phi;
 
 	int grid, alpha, light;	///< Current states of wire, alpha, light switches (toggle buttons)
 	int sshow, rotate, zoom;///< Current states of slideshow, rotate, zoom switches (toggle buttons)
+	int pauseC;	///< Current state of pause for calculations
 
 	void toggle(int &val, Fl_Button *b, const char *txt=NULL);
 	void setoff(int &val, Fl_Button *b, const char *txt=NULL);
+	void exec_pause();
 };
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w);
diff --git a/include/mgl2/abstract.h b/include/mgl2/abstract.h
index 19c222e..48cc733 100644
--- a/include/mgl2/abstract.h
+++ b/include/mgl2/abstract.h
@@ -42,11 +42,22 @@ typedef mglParser* HMPR;
 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" {
+
+#else
+#define mglDataA void
+typedef void *HMGL;
+typedef void *HMDT;
+typedef void *HADT;
+typedef void *HMEX;
+typedef void *HAEX;
+typedef void *HMPR;
+typedef const void *HCDT;
 #endif
+
 /// Set seed for random numbers
 void MGL_EXPORT mgl_srnd(long seed);
 void MGL_EXPORT mgl_srnd_(int *seed);
@@ -117,13 +128,19 @@ mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *dat, mreal *x, mreal *y, mreal *z
 mreal MGL_EXPORT mgl_data_momentum_val(HCDT d, char dir, mreal *m, mreal *w, mreal *s, mreal *k);
 mreal MGL_EXPORT mgl_data_momentum_val_(uintptr_t *dat, char *dir, mreal *m, mreal *w, mreal *s, mreal *k,int);
 
-#ifdef __cplusplus
-}
-#endif
+/// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
+mreal MGL_EXPORT mgl_data_linear(HCDT dat, mreal x,mreal y,mreal z);
+mreal MGL_EXPORT mgl_data_linear_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);
+/// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
+mreal MGL_EXPORT mgl_data_linear_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);
+mreal MGL_EXPORT mgl_data_linear_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);
+
 //-----------------------------------------------------------------------------
 /// Callback function for asking user a question. Result shouldn't exceed 1024.
 extern MGL_EXPORT void (*mgl_ask_func)(const wchar_t *quest, wchar_t *res);
 //-----------------------------------------------------------------------------
+#ifdef __cplusplus
+}
 /// Abstract class for data array
 class MGL_EXPORT mglDataA
 {
@@ -140,6 +157,12 @@ public:
 	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;
+	/// Interpolate by linear function the data to given point
+	inline mreal linear(mreal x,mreal y=0,mreal z=0)	const
+	{	return mgl_data_linear_ext(this,x,y,z,0,0,0);	}
+	/// Interpolate by linear function the data to given point and get the gradient
+	inline mreal linearD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0)	const
+	{	return mgl_data_linear_ext(this,x,y,z,dx,dy,dz);	}
 	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;
@@ -158,7 +181,7 @@ public:
 	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)
+	virtual std::string Get(long ns=-1) const
 	{	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
@@ -224,15 +247,6 @@ struct MGL_EXPORT mglColorID
 MGL_EXPORT extern mglColorID mglColorIds[31];
 MGL_EXPORT extern std::string mglGlobalMess;	///< Buffer for receiving global messages
 //-----------------------------------------------------------------------------
-#else
-#define mglDataA void
-typedef void *HMGL;
-typedef void *HMDT;
-typedef void *HADT;
-typedef void *HMEX;
-typedef void *HAEX;
-typedef void *HMPR;
-typedef const void *HCDT;
 #endif
 
 #ifdef MGL_SRC
diff --git a/include/mgl2/base.h b/include/mgl2/base.h
index 9aa0c41..8ef2c3f 100644
--- a/include/mgl2/base.h
+++ b/include/mgl2/base.h
@@ -26,8 +26,11 @@
 #include <vector>
 #include <string>
 
-#if MGL_HAVE_PTHREAD
+#if (MGL_HAVE_PTHREAD|MGL_HAVE_PTHR_WIDGET)
 #include <pthread.h>
+#endif
+
+#if MGL_HAVE_PTHREAD
 #define MGL_PUSH(a,v,m)	{pthread_mutex_lock(&m);	a.push_back(v);	pthread_mutex_unlock(&m);}
 #else
 #define MGL_PUSH(a,v,m)	a.push_back(v);
@@ -344,7 +347,8 @@ public:
 	int FaceNum;		///< Set approximate number of visible faces and lines. By default (=0) it draw everything.
 	char Arrow1, Arrow2;///< Style of arrows at end and at start of curve
 	long InUse;			///< Smart pointer (number of users)
-	uint32_t Flag;			///< Flags for controlling drawing
+	uint32_t Flag;		///< Flags for controlling drawing
+	mreal size_opt;		///< Value of size option (or NAN if not specified)
 
 	inline bool get(uint32_t fl) const	{	return Flag&fl;	}
 	inline void set(uint32_t fl)	{	Flag |= fl;	}
diff --git a/include/mgl2/canvas_cf.h b/include/mgl2/canvas_cf.h
index a13c46e..e648164 100644
--- a/include/mgl2/canvas_cf.h
+++ b/include/mgl2/canvas_cf.h
@@ -34,6 +34,9 @@ void MGL_EXPORT mgl_delete_graph_(uintptr_t *gr);
 /// Set size of frame in pixels. Normally this function is called internally.
 void MGL_EXPORT mgl_set_size(HMGL gr, int width, int height);
 void MGL_EXPORT mgl_set_size_(uintptr_t *gr, int *width, int *height);
+/// Set size of frame in pixels, but don't erase primitives
+void MGL_EXPORT mgl_scale_size(HMGL gr, int width, int height);
+void MGL_EXPORT mgl_scale_size_(uintptr_t *gr, int *width, int *height);
 /// Scaling for all further set size calls.
 void MGL_EXPORT mgl_set_size_scl(double scl);
 void MGL_EXPORT mgl_set_size_scl_(double *scl);
@@ -508,11 +511,12 @@ void MGL_EXPORT mgl_zoom(HMGL gr, double x1, double y1, double x2, double y2);
 void MGL_EXPORT mgl_zoom_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *x2, mreal *y2);
 
 //-----------------------------------------------------------------------------
-#if MGL_HAVE_PTHREAD
-void MGL_EXPORT mgl_draw_thr(void *);
-#endif
 /// Callback function for mouse click
 void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p));
+#if MGL_HAVE_PTHR_WIDGET
+/// Mutex for lock/unlock by widget
+void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex);
+#endif
 
 /// Set callback functions for drawing and data reloading
 void MGL_EXPORT mgl_wnd_set_func(HMGL gr, int (*draw)(HMGL gr, void *p), void *par, void (*reload)(void *p));
diff --git a/include/mgl2/canvas_wnd.h b/include/mgl2/canvas_wnd.h
index c98cb55..b157d6d 100644
--- a/include/mgl2/canvas_wnd.h
+++ b/include/mgl2/canvas_wnd.h
@@ -29,6 +29,9 @@ class MGL_EXPORT mglCanvasWnd : public mglCanvas
 public:
 	mglPoint LastMousePos;			///< Last mouse position
 	void (*ClickFunc)(void *par);	///< Callback function on click
+#if MGL_HAVE_PTHR_WIDGET
+	pthread_mutex_t *mutex;
+#endif
 
 	mglCanvasWnd();
 	virtual ~mglCanvasWnd();
diff --git a/include/mgl2/data.h b/include/mgl2/data.h
index 44f99c6..834ca26 100644
--- a/include/mgl2/data.h
+++ b/include/mgl2/data.h
@@ -25,6 +25,7 @@
 //-----------------------------------------------------------------------------
 #include <vector>
 #include <string>
+#include <stdarg.h>
 //-----------------------------------------------------------------------------
 mreal MGL_EXPORT mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);
 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);
@@ -137,6 +138,14 @@ using mglDataA::Momentum;
 	{	if(d.size()>0)	Set(&(a[0]),d.size());	else	Create(1);	}
 	inline void Set(const std::vector<double> &d)
 	{	if(d.size()>0)	Set(&(a[0]),d.size());	else	Create(1);	}
+	/// Allocate memory and set data from variable argument list of double values
+	inline void SetList(long n, ...)
+	{
+		if(n<1)	return;
+		mgl_data_create(this,n,1,1);
+		va_list vl;	va_start(vl,n);
+		for(long i=0;i<n;i++)	a[i] = va_arg(vl,double);
+	}
 
 	/// Create or recreate the array with specified size and fill it by zero
 	inline void Create(long mx,long my=1,long mz=1)
@@ -246,6 +255,10 @@ using mglDataA::Momentum;
 	/// Read data array from HDF file (parse HDF4 and HDF5 files)
 	inline int ReadHDF(const char *fname,const char *data)
 	{	return mgl_data_read_hdf(this,fname,data);	}
+	/// Scan textual file for template and fill data array
+	inline int ScanFile(const char *fname, const char *templ)
+	{	return mgl_data_scan_file(this,fname, templ);	}
+
 
 	/// Get column (or slice) of the data filled by formulas of named columns
 	inline mglData Column(const char *eq) const
@@ -381,23 +394,23 @@ using mglDataA::Momentum;
 
 	/// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 	inline mreal Spline(mreal x,mreal y=0,mreal z=0) const
-	{	return mgl_data_spline(this, x,y,z);	}
+	{	return value(x,y,z);	}
 	/// Interpolate by cubic spline the data to given point x,\a y,\a z which normalized in range [0, 1]
 	inline mreal Spline1(mreal x,mreal y=0,mreal z=0) const
-	{	return mgl_data_spline(this, x*(nx-1),y*(ny-1),z*(nz-1));	}
+	{	return value(x*(nx-1),y*(ny-1),z*(nz-1));	}
 	/// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 	inline mreal Linear(mreal x,mreal y=0,mreal z=0)	const
-	{	return mgl_data_linear(this,x,y,z);	}
+	{	return mgl_data_linear_ext(this,x,y,z,0,0,0);	}
 	/// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1]
 	inline mreal Linear1(mreal x,mreal y=0,mreal z=0) const
-	{	return mgl_data_linear(this,x*(nx-1),y*(ny-1),z*(nz-1));	}
+	{	return mgl_data_linear_ext(this,x*(nx-1),y*(ny-1),z*(nz-1),0,0,0);	}
 
 	/// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 	inline mreal Spline(mglPoint &dif, mreal x,mreal y=0,mreal z=0) const
-	{	return mgl_data_spline_ext(this, x,y,z, &(dif.x),&(dif.y), &(dif.z));	}
+	{	return valueD(x,y,z, &(dif.x),&(dif.y), &(dif.z));	}
 	/// Interpolate by cubic spline the data and return its derivatives at given point x,\a y,\a z which normalized in range [0, 1]
 	inline mreal Spline1(mglPoint &dif, mreal x,mreal y=0,mreal z=0) const
-	{	mreal res=mgl_data_spline_ext(this, x*(nx-1),y*(ny-1),z*(nz-1), &(dif.x),&(dif.y), &(dif.z));
+	{	mreal res=valueD(x*(nx-1),y*(ny-1),z*(nz-1), &(dif.x),&(dif.y), &(dif.z));
 		dif.x*=nx>1?nx-1:1;	dif.y*=ny>1?ny-1:1;	dif.z*=nz>1?nz-1:1;	return res;	}
 	/// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 	inline mreal Linear(mglPoint &dif, mreal x,mreal y=0,mreal z=0)	const
@@ -540,6 +553,12 @@ inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y, const mglD
 {	return mglData(true,mgl_triangulation_3d(&x,&y,&z));	}
 inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y)
 {	return mglData(true,mgl_triangulation_2d(&x,&y));	}
+/// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A
+inline mglData mglIFS2d(const mglDataA &A, long n, long skip=20)
+{	return mglData(true,mgl_data_ifs_2d(&A,n,skip));	}
+/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A
+inline mglData mglIFS3d(const mglDataA &A, long n, long skip=20)
+{	return mglData(true,mgl_data_ifs_3d(&A,n,skip));	}
 //-----------------------------------------------------------------------------
 /// Get sub-array of the data with given fixed indexes
 inline mglData mglSubData(const mglDataA &dat, long xx, long yy=-1, long zz=-1)
@@ -698,15 +717,15 @@ public:
 	/// Get the interpolated value and its derivatives in given data cell without border checking
 	mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const
 	{	if(dx)	*dx=di;	if(dy)	*dy=dj;	if(dz)	*dz=dk;
-		return di*(x<nx/2?x:nx-x)+dj*(y<ny/2?y:ny-y)+dk*(z<nz/2?z:nz-z);	}
+		return di*(x<nx/2?x:x-nx)+dj*(y<ny/2?y:y-ny)+dk*(z<nz/2?z:z-nz);	}
 	/// Get the interpolated value in given data cell without border checking
 	mreal value(mreal x,mreal y=0,mreal z=0) const
-	{	return di*(x<nx/2?x:nx-x)+dj*(y<ny/2?y:ny-y)+dk*(z<nz/2?z:nz-z);	}
+	{	return di*(x<nx/2?x:x-nx)+dj*(y<ny/2?y:y-ny)+dk*(z<nz/2?z:z-nz);	}
 	mreal v(long i,long j=0,long k=0) const
-	{	return di*(i<nx/2?i:nx-i)+dj*(j<ny/2?j:ny-j)+dk*(k<nz/2?k:nz-k);	}
+	{	return di*(i<nx/2?i:i-nx)+dj*(j<ny/2?j:j-ny)+dk*(k<nz/2?k:k-nz);	}
 	mreal vthr(long ii) const
 	{	register long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);
-		return di*(i<nx/2?i:nx-i)+dj*(j<ny/2?j:ny-j)+dk*(k<nz/2?k:nz-k);	}
+		return di*(i<nx/2?i:i-nx)+dj*(j<ny/2?j:j-ny)+dk*(k<nz/2?k:k-nz);	}
 	// add for speeding up !!!
 	mreal dvx(long ,long =0,long =0) const	{	return di;	}
 	mreal dvy(long ,long =0,long =0) const	{	return dj;	}
diff --git a/include/mgl2/data_cf.h b/include/mgl2/data_cf.h
index 44cbfeb..b7ae601 100644
--- a/include/mgl2/data_cf.h
+++ b/include/mgl2/data_cf.h
@@ -122,6 +122,9 @@ int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice
 /// Import data array from PNG file according color scheme
 void MGL_EXPORT mgl_data_import(HMDT dat, const char *fname, const char *scheme,mreal v1,mreal v2);
 void MGL_EXPORT mgl_data_import_(uintptr_t *dat, const char *fname, const char *scheme,mreal *v1,mreal *v2,int,int);
+/// Scan textual file for template and fill data array
+int MGL_EXPORT mgl_data_scan_file(HMDT dat,const char *fname, const char *templ);
+int MGL_EXPORT mgl_data_scan_file_(uintptr_t *dat,const char *fname, const char *templ,int,int);
 
 /// Create or recreate the array with specified size and fill it by zero
 void MGL_EXPORT mgl_data_create(HMDT dat, long nx,long ny,long nz);
@@ -190,6 +193,15 @@ void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *dat, const char *eq, uintptr_t *v
 void MGL_EXPORT mgl_data_squeeze(HMDT dat, long rx,long ry,long rz,long smooth);
 void MGL_EXPORT mgl_data_squeeze_(uintptr_t *dat, int *rx,int *ry,int *rz,int *smooth);
 
+/// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A
+/** NOTE: A.nx must be >= 7. */
+HMDT MGL_EXPORT mgl_data_ifs_2d(HCDT A, long n, long skip);
+uintptr_t MGL_EXPORT mgl_data_ifs_2d_(uintptr_t *A, long *n, long *skip);
+/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A
+/** NOTE: A.nx must be >= 13. */
+HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip);
+uintptr_t MGL_EXPORT mgl_data_ifs_3d_(uintptr_t *A, long *n, long *skip);
+
 /// Returns pointer to data element [i,j,k]
 MGL_EXPORT mreal *mgl_data_value(HMDT dat, long i,long j,long k);
 /// Returns pointer to internal data array
@@ -306,9 +318,6 @@ void MGL_EXPORT mgl_clear_fft();
 /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 mreal MGL_EXPORT mgl_data_spline(HCDT dat, mreal x,mreal y,mreal z);
 mreal MGL_EXPORT mgl_data_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);
-/// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
-mreal MGL_EXPORT mgl_data_linear(HCDT dat, mreal x,mreal y,mreal z);
-mreal MGL_EXPORT mgl_data_linear_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);
 /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 mreal MGL_EXPORT mgl_data_spline_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);
 mreal MGL_EXPORT mgl_data_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);
@@ -318,9 +327,6 @@ uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v);
 /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef
 mreal MGL_EXPORT mgl_gspline(HCDT coef, mreal dx, mreal *d1, mreal *d2);
 mreal MGL_EXPORT mgl_gspline_(uintptr_t *c, mreal *dx, mreal *d1, mreal *d2);
-/// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
-mreal MGL_EXPORT mgl_data_linear_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);
-mreal MGL_EXPORT mgl_data_linear_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);
 /// Return an approximated x-value (root) when dat(x) = val
 mreal MGL_EXPORT mgl_data_solve_1d(HCDT dat, mreal val, int spl, long i0);
 mreal MGL_EXPORT mgl_data_solve_1d_(uintptr_t *dat, mreal *val, int *spl, int *i0);
diff --git a/include/mgl2/datac.h b/include/mgl2/datac.h
index 4cf7dcd..c3687fa 100644
--- a/include/mgl2/datac.h
+++ b/include/mgl2/datac.h
@@ -370,10 +370,10 @@ using mglDataA::Momentum;
 	{	return mgl_datac_spline(this, x*(nx-1),y*(ny-1),z*(nz-1));	}
 	/// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 	inline dual Linear(mreal x,mreal y=0,mreal z=0)	const
-	{	return mgl_datac_linear(this,x,y,z);	}
+	{	return mgl_datac_linear_ext(this,x,y,z,0,0,0);	}
 	/// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1]
 	inline dual Linear1(mreal x,mreal y=0,mreal z=0) const
-	{	return mgl_datac_linear(this,x*(nx-1),y*(ny-1),z*(nz-1));	}
+	{	return mgl_datac_linear_ext(this,x*(nx-1),y*(ny-1),z*(nz-1),0,0,0);	}
 	/// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 	inline dual Linear(mglPoint &dif, mreal x,mreal y=0,mreal z=0)	const
 	{
diff --git a/include/mgl2/define.h b/include/mgl2/define.h
index edf2837..ada4ce5 100644
--- a/include/mgl2/define.h
+++ b/include/mgl2/define.h
@@ -23,6 +23,10 @@
 #include "mgl2/config.h"
 #ifndef SWIG
 
+#if MGL_HAVE_PTHR_WIDGET|MGL_HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
 #include "mgl2/dllexport.h"
 #if MGL_HAVE_ATTRIBUTE
 #define MGL_FUNC_CONST	__attribute__((const))
diff --git a/include/mgl2/fltk.h b/include/mgl2/fltk.h
index 343059b..129ac08 100644
--- a/include/mgl2/fltk.h
+++ b/include/mgl2/fltk.h
@@ -17,7 +17,6 @@
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-//-----------------------------------------------------------------------------
 #ifndef _MGL_FLTK_H_
 #define _MGL_FLTK_H_
 
@@ -55,6 +54,9 @@ public:
 	{	gr = mgl_create_graph_fltk(draw?mgl_draw_graph:0,title,(void*)draw,0);	}
 	mglFLTK(mglDraw *draw, const char *title="MathGL") : mglWnd()
 	{	gr = mgl_create_graph_fltk(draw?mgl_draw_class:0,title,draw,mgl_reload_class);
+#if MGL_HAVE_PTHR_WIDGET
+		mgl_wnd_set_mutex(gr, &(draw->mutex));
+#endif
 		mgl_set_click_func(gr, mgl_click_class);	}
     virtual ~mglFLTK() {}
 	int Run()	{	return mgl_fltk_run();	}	///< Run main loop for event handling
diff --git a/include/mgl2/font.h b/include/mgl2/font.h
index 678681e..3bb937c 100644
--- a/include/mgl2/font.h
+++ b/include/mgl2/font.h
@@ -111,7 +111,7 @@ protected:
 	std::vector<mglGlyphDescr> glyphs;	///< information about know glyphs
 	float fact[4];	///< Divider for width of glyph
 	short *Buf;		///< Buffer for glyph descriptions
-	long numb;		///< Buffer size
+	size_t numb;		///< Buffer size
 
 	/// Print text string for font specified by integer constant
 	float Puts(const wchar_t *str,int font,int align, float c1,float c2) const;
diff --git a/include/mgl2/mgl.h b/include/mgl2/mgl.h
index 7fdfb54..993596a 100644
--- a/include/mgl2/mgl.h
+++ b/include/mgl2/mgl.h
@@ -344,7 +344,9 @@ public:
 	{	mgl_zoom(gr, x1, y1, x2, y2);	}
 
 	/// Set size of frame in pixels. Normally this function is called internally.
-	inline void SetSize(int width, int height)	{	mgl_set_size(gr, width, height);	}
+	inline void SetSize(int width, int height, bool clf=true)
+	{	if(clf)	mgl_set_size(gr, width, height);
+		else	mgl_scale_size(gr, width, height);	}
 	/// Scaling for all further set size calls.
 	static inline void SetSizeScl(double scl)	{	mgl_set_size_scl(scl);	}
 	/// Set plot quality
@@ -574,7 +576,7 @@ public:
 
 	/// Draws Lamerey diagram for mapping x_new = f(x_old)
 	/** String \a stl may contain: ‘v’ for drawing arrows; ‘~’ for disable 1st segment.
-	 *	Option value set the number of iterations (default is 20).*/
+	 *	Option value set the number of segments (default is 20).*/
 	inline void Lamerey(double x0, const mglDataA &f, const char *stl="", const char *opt="")
 	{	mgl_lamerey_dat(gr,x0,&f,stl,opt);	}
 	inline void Lamerey(double x0, const char *func, const char *stl="", const char *opt="")
@@ -1045,15 +1047,15 @@ public:
 	inline void Mark(const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")
 	{	mgl_mark_y(gr, &y, &r, pen, opt);	}
 
-	/// Draw Poincare map at condition r==0 for curve {x,y,z}
-	inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *pen, const char *opt="")
-	{	mgl_pmap_xyz(gr, &x, &y, &z, &r, pen, opt);	}
-	/// Draw Poincare map at condition r==0 for curve {x,y}
-	inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")
-	{	mgl_pmap_xy(gr, &x, &y, &r, pen, opt);	}
-	/// Draw Poincare map at condition r==0 for curve {x,y} with x in x-axis range
-	inline void Pmap(const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")
-	{	mgl_pmap(gr, &y, &r, pen, opt);	}
+	/// Draw Poincare map at condition s==0 for curve {x,y,z}
+	inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *pen, const char *opt="")
+	{	mgl_pmap_xyz(gr, &x, &y, &z, &s, pen, opt);	}
+	/// Draw Poincare map at condition s==0 for curve {x,y}
+	inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *pen, const char *opt="")
+	{	mgl_pmap_xy(gr, &x, &y, &s, pen, opt);	}
+	/// Draw Poincare map at condition s==0 for curve {x,y} with x in x-axis range
+	inline void Pmap(const mglDataA &y, const mglDataA &s, const char *pen, const char *opt="")
+	{	mgl_pmap(gr, &y, &s, pen, opt);	}
 
 	/// Draw textual marks with size r at points {x,y,z}
 	inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *text, const char *fnt="", const char *opt="")
@@ -2063,6 +2065,13 @@ public:
 	inline mglDataC PDEc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")
 	{	return mglDataC(true,mgl_pde_solve_c(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
 
+	/// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only)
+	inline mglData APDE(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")
+	{	return mglData(true,mgl_pde_adv(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
+	/// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only)
+	inline mglDataC APDEc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")
+	{	return mglDataC(true,mgl_pde_adv_c(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
+
 	/// Fill data by formula with x,y,z in range axis range
 	inline void Fill(mglData &u, const char *eq, const char *opt="")
 	{	mgl_data_fill_eq(gr, &u, eq, 0, 0, opt);	}
diff --git a/include/mgl2/pde.h b/include/mgl2/pde.h
index 3bee32d..f358ce7 100644
--- a/include/mgl2/pde.h
+++ b/include/mgl2/pde.h
@@ -32,6 +32,14 @@ uintptr_t MGL_EXPORT mgl_pde_solve_c_(uintptr_t* gr, const char *ham, uintptr_t*
 /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini
 HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt);
 uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int);
+
+/// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini. This function use more accurate but slow algorithm.
+HADT MGL_EXPORT mgl_pde_adv_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt);
+uintptr_t MGL_EXPORT mgl_pde_adv_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int);
+/// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini. This function use more accurate but slow algorithm.
+HMDT MGL_EXPORT mgl_pde_adv(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0,const char *opt);
+uintptr_t MGL_EXPORT mgl_pde_adv_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int);
+
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 HADT MGL_EXPORT mgl_qo2d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
 HADT MGL_EXPORT mgl_qo2d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
@@ -40,6 +48,7 @@ uintptr_t MGL_EXPORT mgl_qo2d_solve_c_(const char *ham, uintptr_t* ini_re, uintp
 HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
 HMDT MGL_EXPORT mgl_qo2d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
 uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int);
+
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 HADT MGL_EXPORT mgl_qo3d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
 HADT MGL_EXPORT mgl_qo3d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
@@ -48,6 +57,7 @@ uintptr_t MGL_EXPORT mgl_qo3d_solve_c_(const char *ham, uintptr_t* ini_re, uintp
 HMDT MGL_EXPORT mgl_qo3d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
 HMDT MGL_EXPORT mgl_qo3d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
 uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int);
+
 /// Saves result of ODE solving of n equations with right part func and initial conditions x0 over time interval [0,tmax] with time step dt
 HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par);
 /// Saves result of ODE solving for var variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt
@@ -57,6 +67,7 @@ HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *p
 /// Finds ray with starting point r0, p0 (and prepares ray data for mgl_qo2d_solve)
 HMDT MGL_EXPORT mgl_ray_trace(const char *ham, mreal x0, mreal y0, mreal z0, mreal px, mreal py, mreal pz, mreal dt, mreal tmax);
 uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int);
+
 /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du
 HMDT MGL_EXPORT mgl_jacobian_2d(HCDT x, HCDT y);
 uintptr_t MGL_EXPORT mgl_jacobian_2d_(uintptr_t* x, uintptr_t* y);
diff --git a/include/mgl2/plot.h b/include/mgl2/plot.h
index e1ed4f0..fe7a59d 100644
--- a/include/mgl2/plot.h
+++ b/include/mgl2/plot.h
@@ -208,14 +208,14 @@ 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);
 void MGL_EXPORT mgl_mark_y_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int);
 
-/// Draw Poincare map at condition r==0 for curve {x,y,z}
-void MGL_EXPORT mgl_pmap_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt);
+/// Draw Poincare map at condition s==0 for curve {x,y,z}
+void MGL_EXPORT mgl_pmap_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, HCDT s, const char *pen, const char *opt);
 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);
-/// Draw Poincare map at condition r==0 for curve {x,y}
-void MGL_EXPORT mgl_pmap_xy(HMGL graph, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt);
+/// Draw Poincare map at condition s==0 for curve {x,y}
+void MGL_EXPORT mgl_pmap_xy(HMGL graph, HCDT x, HCDT y, HCDT s, const char *pen, const char *opt);
 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);
-/// Draw Poincare map at condition r==0 for curve {x,y} with x in x-axis range
-void MGL_EXPORT mgl_pmap(HMGL graph, HCDT y, HCDT r, const char *pen, const char *opt);
+/// Draw Poincare map at condition s==0 for curve {x,y} with x in x-axis range
+void MGL_EXPORT mgl_pmap(HMGL graph, HCDT y, HCDT s, const char *pen, const char *opt);
 void MGL_EXPORT mgl_pmap_(uintptr_t *graph, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int,int);
 
 /// Draw tube with variable radius r around curve {x,y,z}
diff --git a/include/mgl2/prim.h b/include/mgl2/prim.h
index b27c3c0..d6959b0 100644
--- a/include/mgl2/prim.h
+++ b/include/mgl2/prim.h
@@ -222,7 +222,7 @@ void MGL_EXPORT mgl_logo_file_(uintptr_t *gr, const char *fname, int *smooth, co
 
 /// Draws Lamerey diagram for mapping x_new = f(x_old)
 /** String \a stl may contain: ‘v’ for drawing arrows; ‘~’ for disable 1st segment.
- *	Option value set the number of iterations (default is 20).*/
+ *	Option value set the number of segments (default is 20).*/
 void MGL_EXPORT mgl_lamerey(HMGL gr, double x0, double (*f)(double,void *), void *par, const char *stl, const char *opt);
 void MGL_EXPORT mgl_lamerey_dat(HMGL gr, double x0, HCDT f, const char *stl, const char *opt);
 void MGL_EXPORT mgl_lamerey_str(HMGL gr, double x0, const char *f, const char *stl, const char *opt);
diff --git a/include/mgl2/qmathgl.h b/include/mgl2/qmathgl.h
index 504875f..79ed157 100644
--- a/include/mgl2/qmathgl.h
+++ b/include/mgl2/qmathgl.h
@@ -62,6 +62,11 @@ public:
 	{	setDraw(func?mgl_draw_graph:0,(void*)func);	}
 	inline void zoomRegion(mreal xx1,mreal xx2,mreal yy1, mreal yy2)
 	{	x1=xx1;	y1=yy1;	x2=xx2;	y2=yy2;	}
+	/// Get mglDraw pointer or NULL
+	inline mglDraw *getClass()
+	{	mglDraw *d=0;
+		if(draw_func==mgl_draw_class)	d = (mglDraw*)draw_par;
+		if(draw)	d = draw;	return d;	}
 
 	int getPer() const	{return int(per);}	///< Get perspective value
 	int getPhi() const	{return int(phi);}	///< Get Phi-angle value
@@ -71,6 +76,7 @@ public:
 	bool getZoom() const	{return zoom;}	///< Get mouse zooming state
 	bool getRotate() const	{return rotate;}///< Get mouse rotation state
 	bool getViewYZ() const	{return viewYZ;}///< Get mouse rotation axis
+	bool getPause() const	{return pause;}	///< Get calculation pause state
 	bool isActive(int xs,int ys);	///< Check if active point is pressed
 
 public slots:
@@ -95,6 +101,7 @@ public slots:
 	void setCustDraw(bool a);	///< Switch on/off using custom draw
 	void setZoom(bool z);	///< Switch on/off mouse zooming
 	void setRotate(bool r);	///< Switch on/off mouse rotation
+	void setPause(bool p);	///< Switch on/off calculation pause
 	void zoomIn();			///< Zoom in graphics
 	void zoomOut();			///< Zoom out graphics
 	void restore();			///< Restore zoom and rotation to default values
@@ -153,6 +160,7 @@ signals:
 	void lightChanged(bool);	///< Lighting changed (by toolbar)
 	void zoomChanged(bool);		///< Zooming changed (by toolbar)
 	void rotateChanged(bool);	///< Rotation changed (by toolbar)
+	void pauseChanged(bool);	///< Pause changed (by toolbar)
 	void usePrimChanged(bool);	///< Use primitive changed (i.e. have or not drawing function)
 	void viewYZChanged(bool);	///< Rotation axis changed (by toolbar)
 	void mouseClick(mreal,mreal,mreal);	///< Position of mouse click
@@ -188,6 +196,7 @@ protected:
 	double per;			///< Value of perspective ( must be in [0,1) )
 	bool alpha;			///< Transparency state
 	bool light;			///< Lightning state
+	bool pause;			///< Pause state
 	bool custZoom;		///< Use custom zoom instead of built in
 	bool custDraw;		///< Use custom draw before main drawing
 	bool zoom;			///< Mouse zoom state
diff --git a/include/mgl2/wnd.h b/include/mgl2/wnd.h
index 885e5a8..ad496e7 100644
--- a/include/mgl2/wnd.h
+++ b/include/mgl2/wnd.h
@@ -22,24 +22,44 @@
 
 #include "mgl2/mgl.h"
 //-----------------------------------------------------------------------------
+MGL_EXPORT void *mgl_draw_calc(void *p);
+//-----------------------------------------------------------------------------
 /// Class for drawing in windows (like, mglCanvasFL, mglCanvasQT and so on)
 /// Make inherited class and redefine Draw() function if you don't want to use function pointers.
 class MGL_EXPORT mglDraw
 {
 public:
 	virtual int Draw(mglGraph *)=0;	///< Function for drawing
-	virtual void Reload()	{}		///< Function for reloading data
-	virtual void Click()	{}		///< Callback function on mouse click
-	virtual ~mglDraw()	{}
-#if MGL_HAVE_PTHREAD
+	virtual void Reload(){}		///< Function for reloading data
+	virtual void Click() {}		///< Callback function on mouse click
+#if MGL_HAVE_PTHR_WIDGET
+	mglDraw()	{	running=false;	pthread_mutex_init(&mutex,NULL);	}
+	virtual ~mglDraw()	{	pthread_mutex_destroy(&mutex);	}
+
+	virtual void Calc()	{}		///< Function for calculations
+	inline void Run()			///< Run/resume calculation in other thread
+	{
+		if(!running)
+		{	pthread_mutex_trylock(&mutex);	pthread_mutex_unlock(&mutex);
+			pthread_create(&thr,0,mgl_draw_calc,this);
+			pthread_detach(thr);	running = true;	}
+	}
+	inline void Cancel()		///< Cancel thread with calculations
+	{	pthread_cancel(thr);	running = false;	}
+	inline void Pause()			///< Pause calculation
+	{	pthread_mutex_lock(&mutex);	}
+	inline void Continue()		///< Continue calculation
+	{	pthread_mutex_trylock(&mutex);	pthread_mutex_unlock(&mutex);	}
+	inline void Check()			///< Check if calculation can be continued (should be called inside Calc() )
+	{	pthread_mutex_lock(&mutex);	pthread_mutex_unlock(&mutex);	}
+//protected:
 	pthread_t thr;
 	bool running;
-	mglDraw()	{	running=false;	}
-	virtual void Calc()	{}			///< Function for calculations
-	inline void Run()				///< Run calculations in other thread
-	{	mgl_draw_thr(this);	}
+	pthread_mutex_t mutex;
+	
 #else
-	mglDraw(){}
+	mglDraw() {}
+	virtual ~mglDraw() {}
 #endif
 };
 //-----------------------------------------------------------------------------
@@ -92,7 +112,15 @@ public:
 	{	mgl_wnd_set_func(gr,draw?mgl_draw_graph:0,(void*)draw,0);	}
 	inline void SetDrawFunc(mglDraw *draw)
 	{	mgl_wnd_set_func(gr,draw?mgl_draw_class:0,draw,mgl_reload_class);
+#if MGL_HAVE_PTHR_WIDGET
+		mgl_wnd_set_mutex(gr, &(draw->mutex));
+#endif
 		mgl_set_click_func(gr, mgl_click_class);	}
+#if MGL_HAVE_PTHR_WIDGET
+	/// Mutex for lock/unlock by widget
+	inline void SetMutex(pthread_mutex_t *mutex)
+	{	mgl_wnd_set_mutex(gr, mutex);	}
+#endif
 
 	inline void SetDelay(double dt)	///< Set delay for animation in seconds
 	{	mgl_wnd_set_delay(gr, dt);	}
diff --git a/include/xpm/pause.xpm b/include/xpm/pause.xpm
new file mode 100644
index 0000000..e09d88b
--- /dev/null
+++ b/include/xpm/pause.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char * pause_xpm[] = {
+"16 16 3 1",
+" 	c None",
+".	c #777777",
+"q	c #000000",
+"                ",
+"                ",
+"                ",
+"   qqq    qqq   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   q.q    q.q   ",
+"   qqq    qqq   ",
+"                ",
+"                ",
+"                "};
diff --git a/json/Backend.hpp b/json/Backend.hpp
index 3c7ecbe..33081d6 100644
--- a/json/Backend.hpp
+++ b/json/Backend.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <QObject>
 #include <QStringList>
 
 class Backend : public QObject
diff --git a/lang/data.i b/lang/data.i
index 1435bbe..9a18d50 100644
--- a/lang/data.i
+++ b/lang/data.i
@@ -216,6 +216,9 @@ public:
 	/// Put HDF data names into buf as '\t' separated.
 	inline static int DatasHDF(const char *fname, char *buf, long size)
 	{	return mgl_datas_hdf(fname,buf,size);	}
+	/// Scan textual file for template and fill data array
+	inline int ScanFile(const char *fname, const char *templ)
+	{	return mgl_data_scan_file(this,fname, templ);	}
 
 	/// Get column (or slice) of the data filled by formulas of named columns
 	inline mglData Column(const char *eq) const
@@ -223,6 +226,9 @@ public:
 	/// 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.
 	inline mglData Momentum(char dir, const char *how) const
 	{	return mglData(true,mgl_data_momentum(this,dir,how));	}
+	/// Get pulse properties: pulse maximum and its position, pulse duration near maximum and by half height, energy in first pulse.
+	inline mglData Pulse(char dir) const
+	{	return mglData(true,mgl_data_pulse(this,dir));	}
 	/// Get sub-array of the data with given fixed indexes
 	inline mglData SubData(long xx,long yy=-1,long zz=-1) const
 	{	return mglData(true,mgl_data_subdata(this,xx,yy,zz));	}
@@ -304,6 +310,12 @@ public:
 	inline void Sew(const char *dirs="xyz", mreal da=2*Pi)
 	{	mgl_data_sew(this,dirs,da);	}
 	/// Smooth the data on specified direction or directions
+	/** String \a dir may contain:
+	 *  ‘x’, ‘y’, ‘z’ for 1st, 2nd or 3d dimension;
+	 *  ‘dN’ for linear averaging over N points;
+	 *  ‘3’ for linear averaging over 3 points;
+	 *  ‘5’ for linear averaging over 5 points.
+	 *  By default quadratic averaging over 5 points is used. */
 	inline void Smooth(const char *dirs="xyz",mreal delta=0)
 	{	mgl_data_smooth(this,dirs,delta);	}
 	/// Normalize the data to range [v1,v2]
@@ -322,6 +334,14 @@ public:
 	/// Fill data by 'x'/'k' samples for Hankel ('h') or Fourier ('f') transform
 	inline void FillSample(const char *how)
 	{	mgl_data_fill_sample(this,how);	}
+	/// Apply wavelet transform
+	/** Parameter \a dir may contain:
+	 * ‘x‘,‘y‘,‘z‘ for directions,
+	 * ‘d‘ for daubechies, ‘D‘ for centered daubechies,
+	 * ‘h‘ for haar, ‘H‘ for centered haar,
+	 * ‘b‘ for bspline, ‘B‘ for centered bspline,
+	 * ‘i‘ for applying inverse transform. */
+	inline void Wavelet(const char *how, int k)	{	mgl_data_wavelet(this, how, k);	}
 
 	/// Return an approximated x-value (root) when dat(x) = val
 	inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const
@@ -470,6 +490,12 @@ inline mglData mglTriangulation(const mglData &x, const mglData &y, const mglDat
 {	return mglData(true,mgl_triangulation_3d(&x,&y,&z));	}
 inline mglData mglTriangulation(const mglData &x, const mglData &y)
 {	return mglData(true,mgl_triangulation_2d(&x,&y));	}
+/// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A
+inline mglData mglIFS2d(const mglData &A, long n, long skip=20)
+{	return mglData(true,mgl_data_ifs_2d(&A,n,skip));	}
+/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A
+inline mglData mglIFS3d(const mglData &A, long n, long skip=20)
+{	return mglData(true,mgl_data_ifs_3d(&A,n,skip));	}
 //-----------------------------------------------------------------------------
 /// Get sub-array of the data with given fixed indexes
 inline mglData mglSubData(const mglData &dat, long xx, long yy=-1, long zz=-1)
diff --git a/lang/mgl.i b/lang/mgl.i
index 3a05562..d050ccc 100644
--- a/lang/mgl.i
+++ b/lang/mgl.i
@@ -55,9 +55,6 @@ public:
 	inline void Stop(bool stop=true)	{	mgl_ask_stop(gr, stop);	}
 	/// Check if plot termination is asked
 	inline bool NeedStop()	{	return mgl_need_stop(gr);	}
-	/// Set callback function for event processing
-	inline void SetEventFunc(void (*func)(void *), void *par=NULL)
-	{	mgl_set_event_func(gr, func, par);	}
 
 	/// Set the transparency on/off.
 	inline void Alpha(bool enable)			{	mgl_set_alpha(gr, enable);	}
@@ -65,6 +62,8 @@ public:
 	inline void SetAlphaDef(double alpha)	{	mgl_set_alpha_default(gr, alpha);	}
 	/// Set the transparency type (0 - usual, 1 - glass, 2 - lamp)
 	inline void SetTranspType(int type)		{	mgl_set_transp_type(gr, type);	}
+	/// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1.
+	inline void SetPenDelta(double d)	{	mgl_pen_delta(gr,d);	}
 
 	/// Set the using of light on/off.
 	inline void Light(bool enable)			{	mgl_set_light(gr, enable);	}
@@ -72,6 +71,8 @@ public:
 	inline void Light(int n,bool enable)	{	mgl_set_light_n(gr, n, enable);	}
 	/// Use diffusive light (only for local light sources) -- OBSOLETE
 	inline void SetDifLight(bool dif)		{	mgl_set_light_dif(gr, dif);	}
+	/// Set to attach light settings to inplot.
+	inline void AttachLight(bool enable)		{	mgl_set_attach_light(gr, enable);	}
 	/// Add a light source.
 	inline void AddLight(int n, mglPoint p, char col='w', double bright=0.5, double ap=0)
 	{	mgl_add_light_ext(gr, n, p.x, p.y, p.z, col, bright, ap);	}
@@ -84,7 +85,7 @@ public:
 	/// Set the fog distance or switch it off (if d=0).
 	inline void Fog(double d, double dz=0.25)	{	mgl_set_fog(gr, d, dz);		}
 
-	/// Set relative width of rectangles in Bars, Barh, BoxPlot
+	/// Set relative width of rectangles in Bars, Barh, BoxPlot, Candle, OHLC (default is 0.7)
 	inline void SetBarWidth(double width)	{	mgl_set_bar_width(gr, width);	}
 	/// Set default size of marks (locally you can use "size" option)
 	inline void SetMarkSize(double size)		{	mgl_set_mark_size(gr, size);	}
@@ -122,6 +123,8 @@ public:
 	inline void RestoreFont()				{	mgl_restore_font(gr);	}
 	/// Set to use or not text rotation
 	inline void SetRotatedText(bool rotated)	{	mgl_set_rotated_text(gr, rotated);	}
+	/// Set default font for all new HMGL and mglGraph objects
+	static inline void SetDefFont(const char *name, const char *path="")	{	mgl_def_font(name,path);	}
 
 	/// Set default palette
 	inline void SetPalette(const char *colors)	{	mgl_set_palette(gr, colors);	}
@@ -141,8 +144,16 @@ public:
 	inline int  GetWarn()	{	return mgl_get_warn(gr);}
 	/// Set warning code ant fill message
 	inline void SetWarn(int code, const char *info)	{	mgl_set_warn(gr,code,info);	}
-	/// Set buffer for warning messages
+	/// Get text of warning message(s)
 	inline const char *Message()	{	return mgl_get_mess(gr);	}
+	/// Set global warning message
+	static inline void SetGlobalWarn(const char *text)	{	mgl_set_global_warn(text);	}
+	/// Get text of global warning message(s)
+	static inline const char *GlobalWarn()	{	return mgl_get_global_warn();	}
+	/// Suppress printing warnings to stderr
+	static inline void SuppressWarn(bool on)	{	mgl_suppress_warn(on);	}
+	/// Check if MathGL version is valid (return false) or not (return true)
+	static inline bool CheckVersion(const char *ver)	{	return mgl_check_version(ver);	}
 
 	/// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image!
 	inline void ZoomAxis(mglPoint p1=mglPoint(0,0,0,0), mglPoint p2=mglPoint(1,1,1,1))
@@ -156,15 +167,15 @@ public:
 	/// Set range in direction dir as minimal and maximal values of data a
 	inline void SetRange(char dir, const mglData &dat, bool add=false)
 	{	mgl_set_range_dat(gr, dir, &dat, add);	}
-	/// Set values of axis range as minimal and maximal values of datas
+	/// Set values of axis range as minimal and maximal values of corresponding data
 	inline void SetRanges(const mglData &xx, const mglData &yy, const mglData &zz, const mglData &cc)
 	{	mgl_set_range_dat(gr,'x',&xx,0);	mgl_set_range_dat(gr,'y',&yy,0);
 		mgl_set_range_dat(gr,'z',&zz,0);	mgl_set_range_dat(gr,'c',&cc,0);	}
-	/// Set values of axis range as minimal and maximal values of datas
+	/// Set values of axis range as minimal and maximal values of corresponding data
 	inline void SetRanges(const mglData &xx, const mglData &yy, const mglData &zz)
 	{	mgl_set_range_dat(gr,'x',&xx,0);	mgl_set_range_dat(gr,'y',&yy,0);
 		mgl_set_range_dat(gr,'z',&zz,0);	mgl_set_range_dat(gr,'c',&zz,0);	}
-	/// Set values of axis range as minimal and maximal values of datas
+	/// Set values of axis range as minimal and maximal values of corresponding data
 	inline void SetRanges(const mglData &xx, const mglData &yy)
 	{	mgl_set_range_dat(gr,'x',&xx,0);	mgl_set_range_dat(gr,'y',&yy,0);	}
 	/// Set values of axis ranges
@@ -185,12 +196,15 @@ public:
 	inline void SetOrigin(double x0, double y0, double z0=NaN)
 	{	mgl_set_origin(gr, x0, y0, z0);	}
 
-	/// Set the transformation formulas for coordinate
+	/// Set the transformation formulas for coordinate. Use "" for built-in ones
 	inline void SetFunc(const char *EqX, const char *EqY, const char *EqZ=NULL, const char *EqA=NULL)
 	{	mgl_set_func(gr, EqX, EqY, EqZ, EqA);	}
 	/// Set one of predefined transformation rule
 	inline void SetCoor(int how)		{	mgl_set_coor(gr, how);	}
 	/// Set to draw Ternary axis (triangle like axis, grid and so on)
+	/** val=1 for Ternary axis (a+b+c=1, z=z),
+	 *  val=2 for Quaternary axis (a+b+c+d=1),
+	 *  val|4 for projections. */
 	inline void Ternary(int val)		{	mgl_set_ternary(gr, val);	}
 
 	/// Set to use or not tick labels rotation
@@ -235,7 +249,7 @@ public:
 	{	mgl_set_tick_templ(gr,dir,t);	}
 	inline void SetTickTempl(char dir, const wchar_t *t)
 	{	mgl_set_tick_templw(gr,dir,t);	}
-	/// Tune ticks
+	/// Tune ticks (tune|1 for common multiplier, tune|2 for common component)
 	inline void SetTuneTicks(int tune, double fact_pos=1.15)
 	{	mgl_tune_ticks(gr, tune, fact_pos);	}
 	/// Set additional shift of tick labels
@@ -248,13 +262,25 @@ public:
 	inline void SetOriginTick(bool enable=true)
 	{	mgl_set_flag(gr,!enable, MGL_NO_ORIGIN);	}
 
-	/// Put further plotting in some region of whole frame.
+	/// Put further plotting in m-th cell of nx*ny grid of the image.
+	/** String \a style may contain:
+	 *  '<' for reserving space at left
+	 *  '>' for reserving space at right
+	 *  '^' for reserving space at top
+	 *  '_' for reserving space at bottom
+	 *  '#' for using whole region. */
 	inline void SubPlot(int nx,int ny,int m,const char *style="<>_^", double dx=0, double dy=0)
 	{	mgl_subplot_d(gr, nx, ny, m, style, dx, dy);	}
-	/// Like SubPlot() but "join" several cells
+	/// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image.
+	/** String \a style may contain:
+	 *  '<' for reserving space at left
+	 *  '>' for reserving space at right
+	 *  '^' for reserving space at top
+	 *  '_' for reserving space at bottom
+	 *  '#' for using whole region. */
 	inline void MultiPlot(int nx,int ny,int m, int dx, int dy, const char *style="<>_^")
 	{	mgl_multiplot(gr, nx, ny, m, dx, dy, style);	}
-	/// Put further plotting in a region of whole frame.
+	/// Put further plotting in a region [x1,x2]*[y1,y2] of the image or subplot (x1,x2,y1,y2 in range [0, 1]).
 	inline void InPlot(double x1,double x2,double y1,double y2, bool rel=true)
 	{	if(rel)	mgl_relplot(gr, x1, x2, y1, y2);
 		else	mgl_inplot(gr, x1, x2, y1, y2);	}
@@ -277,8 +303,11 @@ public:
 	inline void Pop()	{	mgl_mat_pop(gr);	}
 
 	/// Add title for current subplot/inplot
+	/** Style '#' draw box around the title. */
 	inline 	void Title(const char *title,const char *stl="",double size=-2)
 	{	mgl_title(gr,title,stl,size);	}
+	/// Add title for current subplot/inplot
+	/** Style '#' draw box around the title. */
 	inline 	void Title(const wchar_t *title,const char *stl="",double size=-2)
 	{	mgl_titlew(gr,title,stl,size);	}
 	/// Set aspect ratio for further plotting.
@@ -304,8 +333,17 @@ public:
 	{	mgl_zoom(gr, x1, y1, x2, y2);	}
 
 	/// Set size of frame in pixels. Normally this function is called internally.
-	inline void SetSize(int width, int height)	{	mgl_set_size(gr, width, height);	}
+	inline void SetSize(int width, int height, bool clf=true)
+	{	if(clf)	mgl_set_size(gr, width, height);
+		else	mgl_scale_size(gr, width, height);	}
+	/// Scaling for all further set size calls.
+	static inline void SetSizeScl(double scl)	{	mgl_set_size_scl(scl);	}
 	/// Set plot quality
+	/** qual=0 -- no face drawing (fastest),
+	 *  qual=1 -- no color interpolation (fast),
+	 *  qual=2 -- high quality (normal),
+	 *  qual|4 -- direct bitmap drawing (low memory usage);
+	 *  qual|8 for dots drawing instead of primitives (extremely fast). */
 	inline void SetQuality(int qual=MGL_DRAW_NORM)	{	mgl_set_quality(gr, qual);	}
 	/// Get plot quality
 	inline int GetQuality()	{	return mgl_get_quality(gr);	}
@@ -415,20 +453,26 @@ public:
 	{	mgl_import_mgld(gr, fname, add);	}
 
 	/// Copy RGB values into array which is allocated by user
+	/** Position of element {i,j} is [3*i + 3*Width*j]. */
 	inline bool GetRGB(char *imgdata, int imglen)
 	{
 		long w=mgl_get_width(gr), h=mgl_get_height(gr);
 		if(imglen>=3*w*h)	memcpy(imgdata, mgl_get_rgb(gr),3*w*h);
 		return imglen>=3*w*h;
 	}
+	/// Get RGB values of current bitmap
+	/** Position of element {i,j} is [3*i + 3*Width*j]. */
 	inline const unsigned char *GetRGB()		{	return mgl_get_rgb(gr);	}
 	/// Copy RGBA values into array which is allocated by user
+	/** Position of element {i,j} is [4*i + 4*Width*j]. */
 	inline bool GetRGBA(char *imgdata, int imglen)
 	{
 		long w=mgl_get_width(gr), h=mgl_get_height(gr);
 		if(imglen>=4*w*h)	memcpy(imgdata, mgl_get_rgba(gr),4*w*h);
 		return imglen>=4*w*h;
 	}
+	/// Get RGBA values of current bitmap
+	/** Position of element {i,j} is [4*i + 4*Width*j]. */
 	inline const unsigned char *GetRGBA()	{	return mgl_get_rgba(gr);	}
 	/// Copy BGRN values into array which is allocated by user
 	inline bool GetBGRN(unsigned char *imgdata, int imglen)
@@ -445,12 +489,15 @@ public:
 		return imglen>=4*w*h;
 	}
 	/// Copy RGBA values of background image into array which is allocated by user
+	/** Position of element {i,j} is [4*i + 4*Width*j]. */
 	inline bool GetBackground(char *imgdata, int imglen)
 	{
 		long w=mgl_get_width(gr), h=mgl_get_height(gr);
 		if(imglen>=4*w*h)	memcpy(imgdata, mgl_get_background(gr),4*w*h);
 		return imglen>=4*w*h;
 	}
+	/// Get RGBA values of background image
+	/** Position of element {i,j} is [4*i + 4*Width*j]. */
 	inline const unsigned char *GetBackground()	{	return mgl_get_background(gr);	}
 	/// Get width of the image
 	inline int GetWidth()	{	return mgl_get_width(gr);	}
@@ -482,10 +529,13 @@ public:
 	/// Combine plots from 2 canvases. Result will be saved into this
 	inline void Combine(const mglGraph *g)	{	mgl_combine_gr(gr,g->gr);	}
 
-	/// Clear up the frame
+	/// Clear up the frame and fill background by specified color
 	inline void Clf(double r, double g, double b)	{	mgl_clf_rgb(gr, r, g, b);	}
+	/// Clear up the frame and fill background by specified color with manual transparency
 	inline void Clf(const char *col)	{	mgl_clf_str(gr, col);	}
+	/// Clear up the frame and fill background by specified color
 	inline void Clf(char col)	{	mgl_clf_chr(gr, col);	}
+	/// Clear up the frame
 	inline void Clf()	{	mgl_clf(gr);	}
 	/// Clear unused points and primitives. Useful only in combination with SetFaceNum().
 	inline void ClearUnused()	{	mgl_clear_unused(gr);	}
@@ -503,6 +553,7 @@ public:
 	inline void Mark(mglPoint p, const char *mark)
 	{	mgl_mark(gr, p.x, p.y, p.z, mark);	}
 	/// Draws the line between points by specified pen
+	/** Large \a n (for example, n=100) should be used for geodesic line in curved coordinates */
 	inline void Line(mglPoint p1, mglPoint p2, const char *pen="B",int n=2)
 	{	mgl_line(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, pen, n);	}
 	/// Draws the spline curve between points by specified pen
@@ -512,6 +563,20 @@ public:
 	inline void Error(mglPoint p, mglPoint e, const char *pen="k")
 	{	mgl_error_box(gr, p.x, p.y, p.z, e.x, e.y, e.z, pen);	}
 
+	/// Draws Lamerey diagram for mapping x_new = f(x_old)
+	/** String \a stl may contain: ‘v’ for drawing arrows; ‘~’ for disable 1st segment.
+	 *	Option value set the number of segments (default is 20).*/
+	inline void Lamerey(double x0, const mglData &f, const char *stl="", const char *opt="")
+	{	mgl_lamerey_dat(gr,x0,&f,stl,opt);	}
+	inline void Lamerey(double x0, const char *func, const char *stl="", const char *opt="")
+	{	mgl_lamerey_str(gr,x0,func,stl,opt);	}
+	/// Draws Bifurcation diagram for mapping x_new = f(x_old) in x-axis range
+	/** Option value set the number of stationary points (default is 1024).*/
+	inline void Bifurcation(double dx, const mglData &f, const char *stl="", const char *opt="")
+	{	mgl_bifurcation_dat(gr,dx,&f,stl,opt);	}
+	inline void Bifurcation(double dx, const char *func, const char *stl="", const char *opt="")
+	{	mgl_bifurcation_str(gr,dx,func,stl,opt);	}
+
 	/// Draws the face between points with color stl (include interpolation up to 4 colors).
 	inline void Face(mglPoint p1, mglPoint p2, mglPoint p3, mglPoint p4, const char *stl="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);	}
@@ -525,24 +590,42 @@ public:
 	inline void FaceZ(mglPoint p, double wx, double wy, const char *stl="w", double dx=0, double dy=0)
 	{	mgl_facez(gr, p.x, p.y, p.z, wx, wy, stl, dx, dy);	}
 	/// Draws the drop at point p in direction d with color col and radius r
+	/** Parameter \a shift set the degree of drop oblongness: ‘0’ is sphere, ‘1’ is maximally oblongness drop. Parameter \a ap set relative width of the drop (this is analogue of “ellipticity” for the sphere).*/
 	inline void Drop(mglPoint p, mglPoint d, double r, const char *col="r", double shift=1, double ap=1)
 	{	mgl_drop(gr, p.x, p.y, p.z, d.x, d.y, d.z, r, col, shift, ap);	}
 	/// Draws the sphere at point p with color col and radius r
 	inline void Sphere(mglPoint p, double r, const char *col="r")
 	{	mgl_sphere(gr, p.x, p.y, p.z, r, col);	}
 	/// Draws the cone between points p1,p2 with radius r1,r2 and with style stl
+	/** Parameter \a stl can contain:
+	 * ‘@’ for drawing edges;
+	 * ‘#’ for wired cones;
+	 * ‘t’ for drawing tubes/cylinder instead of cones/prisms;
+	 * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones.*/
 	inline void Cone(mglPoint p1, mglPoint p2, double r1, double r2=-1, const char *stl="r@")
 	{	mgl_cone(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z,r1,r2,stl);	}
 	/// Draws the ellipse between points p1,p2 with color stl and width r
+	/** Parameter \a stl can contain:
+	 * ‘#’ for wired figure (boundary only);
+	 * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/
 	inline void Ellipse(mglPoint p1, mglPoint p2, double r, const char *stl="r")
 	{	mgl_ellipse(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl);	}
 	/// Draws the circle at point p with color stl and radius r
+	/** Parameter \a stl can contain:
+	 * ‘#’ for wired figure (boundary only);
+	 * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/
 	inline void Circle(mglPoint p, double r, const char *stl="r")
 	{	mgl_ellipse(gr, p.x, p.y, p.z, p.x, p.y, p.z, r,stl);	}
 	/// Draws the rhomb between points p1,p2 with color stl and width r
+	/** Parameter \a stl can contain:
+	 * ‘#’ for wired figure (boundary only);
+	 * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/
 	inline void Rhomb(mglPoint p1, mglPoint p2, double r, const char *stl="r")
 	{	mgl_rhomb(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl);	}
 	/// Draws the polygon based on points p1,p2 with color stl
+	/** Parameter \a stl can contain:
+	 * ‘#’ for wired figure (boundary only);
+	 * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/
 	inline void Polygon(mglPoint p1, mglPoint p2, int n, const char *stl="r")
 	{	mgl_polygon(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, n,stl);	}
 	/// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees)
@@ -551,59 +634,143 @@ public:
 	/// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees)
 	inline void Arc(mglPoint p0, mglPoint p1, double a, const char *stl="r")
 	{	mgl_arc_ext(gr, p0.x,p0.y,p0.z, 0,0,1, p1.x,p1.y,p0.z, a,stl);	}
+	/// Draws bitmap (logo) which is stretched along whole axis range
+	inline void Logo(long w, long h, const unsigned char *rgba, bool smooth=false, const char *opt="")
+	{	mgl_logo(gr, w, h, rgba, smooth, opt);	}
+	inline void Logo(const char *fname, bool smooth=false, const char *opt="")
+	{	mgl_logo_file(gr, fname, smooth, opt);	}
 
 	/// Print text in position p with specified font
 	inline void Putsw(mglPoint p,const wchar_t *text,const char *font=":C",double size=-1)
 	{	mgl_putsw(gr, p.x, p.y, p.z, text, font, size);	}
+	/// Print text in position p with specified font
 	inline void Puts(mglPoint p,const char *text,const char *font=":C",double size=-1)
 	{	mgl_puts(gr, p.x, p.y, p.z, text, font, size);	}
+	/// Print text in position p with specified font
 	inline void Putsw(double x, double y,const wchar_t *text,const char *font=":AC",double size=-1)
 	{	mgl_putsw(gr, x, y, 0, text, font, size);	}
+	/// Print text in position p with specified font
 	inline void Puts(double x, double y,const char *text,const char *font=":AC",double size=-1)
 	{	mgl_puts(gr, x, y, 0, text, font, size);	}
 	/// Print text in position p along direction d with specified font
 	inline void Putsw(mglPoint p, mglPoint d, const wchar_t *text, const char *font=":L", double size=-1)
 	{	mgl_putsw_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, text, font, size);	}
+	/// Print text in position p along direction d with specified font
 	inline void Puts(mglPoint p, mglPoint d, const char *text, const char *font=":L", double size=-1)
 	{	mgl_puts_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, text, font, size);	}
 
 	/// Print text along the curve
 	inline void Text(const mglData &x, const mglData &y, const mglData &z, const char *text, const char *font="", const char *opt="")
 	{	mgl_text_xyz(gr, &x, &y, &z, text, font, opt);	}
+	/// Print text along the curve
 	inline void Text(const mglData &x, const mglData &y, const char *text, const char *font="", const char *opt="")
 	{	mgl_text_xy(gr, &x, &y, text, font, opt);	}
+	/// Print text along the curve
 	inline void Text(const mglData &y, const char *text, const char *font="", const char *opt="")
 	{	mgl_text_y(gr, &y, text, font, opt);	}
+	/// Print text along the curve
 	inline void Text(const mglData &x, const mglData &y, const mglData &z, const wchar_t *text, const char *font="", const char *opt="")
 	{	mgl_textw_xyz(gr, &x, &y, &z, text, font, opt);	}
+	/// Print text along the curve
 	inline void Text(const mglData &x, const mglData &y, const wchar_t *text, const char *font="", const char *opt="")
 	{	mgl_textw_xy(gr, &x, &y, text, font, opt);	}
+	/// Print text along the curve
 	inline void Text(const mglData &y, const wchar_t *text, const char *font="", const char *opt="")
 	{	mgl_textw_y(gr, &y, text, font, opt);	}
 
 	/// Draws bounding box outside the plotting volume with color c.
+	/** Style ‘@’ produce filled back faces. */
 	inline void Box(const char *col="", bool ticks=true)
 	{	mgl_box_str(gr, col, ticks);	}
 	/// Draw axises with ticks in direction(s) dir.
+	/** Parameter \a dir may contain:
+	 *	‘xyzt’for drawing axis in corresponding direction;
+	 *	‘XYZT’ for drawing axis in corresponding direction but with inverted positions of labels;
+	 *	‘~’, ‘_’ for disabling tick labels;
+	 *	‘U’ for disabling rotation of tick labels;
+	 *	‘^’ for inverting default axis origin;
+	 *	‘!’ for disabling ticks tuning;
+	 *	‘AKDTVISO’ for drawing arrow at the end of axis;
+	 *	‘a’ for forced adjusting of axis ticks;
+	 *	‘f’ for printing ticks labels in fixed format;
+	 *	‘E’ for using ‘E’ instead of ‘e’ in ticks labels;
+	 *	‘F’ for printing ticks labels in LaTeX format;
+	 *	‘+’ for printing ‘+’ for positive ticks;
+	 *	‘-’ for printing usual ‘-’ in ticks labels;
+	 *	‘0123456789’ for precision at printing ticks labels.
+	 *	 Option "value" set the manual rotation angle for the ticks. */
 	inline void Axis(const char *dir="xyzt", const char *stl="", const char *opt="")
 	{	mgl_axis(gr, dir,stl,opt);	}
 	/// Draw grid lines perpendicular to direction(s) dir.
 	inline void Grid(const char *dir="xyzt",const char *pen="B", const char *opt="")
 	{	mgl_axis_grid(gr, dir, pen, opt);	}
 	/// Print the label text for axis dir.
+	/** Option "value" set additional shifting of the label. */
 	inline void Label(char dir, const char *text, double pos=+1, const char *opt="")
 	{	mgl_label(gr, dir, text, pos, opt);	}
+	/// Print the label text for axis dir.
+	/** Option "value" set additional shifting of the label. */
 	inline void Label(char dir, const wchar_t *text, double pos=+1, const char *opt="")
 	{	mgl_labelw(gr, dir, text, pos, opt);	}
 
 	/// Draw colorbar at edge of axis
+	/** Parameter \a sch may contain:
+	 *	 ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;
+	 *	 ‘I’ for positioning near bounding (by default, at edges of subplot);
+	 *	 ‘A’ for using absolute coordinates;
+	 *	 ‘~’ for disabling tick labels.
+	 *	 ‘!’ for disabling ticks tuning;
+	 *	 ‘f’ for printing ticks labels in fixed format;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;
+	 *	 ‘F’ for printing ticks labels in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive ticks;
+	 *	 ‘-’ for printing usual ‘-’ in ticks labels;
+	 *	 ‘0123456789’ for precision at printing ticks labels.*/
 	inline void Colorbar(const char *sch="")
 	{	mgl_colorbar(gr, sch);	}
+	/// Draw colorbar at manual position
+	/** Parameter \a sch may contain:
+	 *	 ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;
+	 *	 ‘I’ for positioning near bounding (by default, at edges of subplot);
+	 *	 ‘A’ for using absolute coordinates;
+	 *	 ‘~’ for disabling tick labels.
+	 *	 ‘!’ for disabling ticks tuning;
+	 *	 ‘f’ for printing ticks labels in fixed format;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;
+	 *	 ‘F’ for printing ticks labels in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive ticks;
+	 *	 ‘-’ for printing usual ‘-’ in ticks labels;
+	 *	 ‘0123456789’ for precision at printing ticks labels.*/
 	inline void Colorbar(const char *sch,double x,double y,double w=1,double h=1)
 	{	mgl_colorbar_ext(gr, sch, x,y,w,h);	}
 	/// Draw colorbar with manual colors at edge of axis
+	/** Parameter \a sch may contain:
+	 *	 ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;
+	 *	 ‘I’ for positioning near bounding (by default, at edges of subplot);
+	 *	 ‘A’ for using absolute coordinates;
+	 *	 ‘~’ for disabling tick labels.
+	 *	 ‘!’ for disabling ticks tuning;
+	 *	 ‘f’ for printing ticks labels in fixed format;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;
+	 *	 ‘F’ for printing ticks labels in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive ticks;
+	 *	 ‘-’ for printing usual ‘-’ in ticks labels;
+	 *	 ‘0123456789’ for precision at printing ticks labels.*/
 	inline void Colorbar(const mglData &val, const char *sch="")
 	{	mgl_colorbar_val(gr, &val, sch);	}
+	/// Draw colorbar with manual colors at manual position
+	/** Parameter \a sch may contain:
+	 *	 ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;
+	 *	 ‘I’ for positioning near bounding (by default, at edges of subplot);
+	 *	 ‘A’ for using absolute coordinates;
+	 *	 ‘~’ for disabling tick labels.
+	 *	 ‘!’ for disabling ticks tuning;
+	 *	 ‘f’ for printing ticks labels in fixed format;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;
+	 *	 ‘F’ for printing ticks labels in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive ticks;
+	 *	 ‘-’ for printing usual ‘-’ in ticks labels;
+	 *	 ‘0123456789’ for precision at printing ticks labels.*/
 	inline void Colorbar(const mglData &val, const char *sch,double x,double y,double w=1,double h=1)
 	{	mgl_colorbar_val_ext(gr, &val, sch, x,y,w,h);	}
 
@@ -616,9 +783,26 @@ public:
 	inline void ClearLegend()
 	{	mgl_clear_legend(gr);	}
 	/// Draw legend of accumulated strings at position {x,y}
+	/** Parameter fnt may contain:
+	 *	 font style for legend text;
+	 *	 colors for background (first one), border (second one) and text (last one);
+	 *	 ‘A’ for positioning in absolute coordinates;
+	 *	 ‘^’ for positioning outside of specified point;
+	 *	 ‘-’ for arranging entries horizontally;
+	 *	 ‘#’ for drawing box around legend.
+	 * Option value set the space between line samples and text (default is 0.1).*/
 	inline void Legend(double x, double y, const char *font="#", const char *opt="")
 	{	mgl_legend_pos(gr, x, y, font, opt);	}
 	/// Draw legend of accumulated strings
+	/** Parameter fnt may contain:
+	 *	 font style for legend text;
+	 *	 colors for background (first one), border (second one) and text (last one);
+	 *	 ‘A’ for positioning in absolute coordinates;
+	 *	 ‘^’ for positioning outside of specified point;
+	 *	 ‘-’ for arranging entries horizontally;
+	 *	 ‘#’ for drawing box around legend.
+	 * Option value set the space between line samples and text (default is 0.1).
+	 * Parameter \a where sets position: 0 at bottom-left, 1 at bottom-right, 2 at top-left, 3 at top-right (default).*/
 	inline void Legend(int where=3, const char *font="#", const char *opt="")
 	{	mgl_legend(gr, where, font, opt);	}
 	/// Set number of marks in legend sample
@@ -627,517 +811,1148 @@ public:
 	/// Draw usual curve {x,y,z}
 	inline void Plot(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_plot_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Draw usual curve {x,y}
 	inline void Plot(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_plot_xy(gr, &x, &y, pen,opt);	}
+	/// Draw usual curve {x,y} with x in x-axis range
 	inline void Plot(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_plot(gr, &y, pen,opt);	}
-	/// Draw tape(s) which rotates as (bi-)normales of curve {x,y,z}
+	/// Draw tapes which rotates as (bi-)normales of curve {x,y,z}
+	/** The width of tape is proportional to barwidth and can be changed by option "value".*/
 	inline void Tape(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_tape_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Draw tapes which rotates as (bi-)normales of curve {x,y}
+	/** The width of tape is proportional to barwidth and can be changed by option "value".*/
 	inline void Tape(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_tape_xy(gr, &x, &y, pen,opt);	}
+	/// Draw tapes which rotates as (bi-)normales of curve {x,y} with x in x-axis range
+	/** The width of tape is proportional to barwidth and can be changed by option "value".*/
 	inline void Tape(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_tape(gr, &y, pen,opt);	}
 	/// Draw radar chart (plot in curved coordinates)
+	/** Option "value" set the additional shift of data (i.e. the data a+value is used instead of a).*/
 	inline void Radar(const mglData &a, const char *pen="", const char *opt="")
 	{	mgl_radar(gr, &a, pen, opt);	}
+
 	/// Draw stairs for points in arrays {x,y,z}
 	inline void Step(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_step_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Draw stairs for points in arrays {x,y}
 	inline void Step(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_step_xy(gr, &x, &y, pen, opt);	}
+	/// Draw stairs for points in arrays {x,y} with x in x-axis range
 	inline void Step(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_step(gr, &y, pen, opt);	}
+
 	/// Draw curve {x,y,z} which is colored by c (like tension plot)
 	inline void Tens(const mglData &x, const mglData &y, const mglData &z, const mglData &c, const char *pen="", const char *opt="")
 	{	mgl_tens_xyz(gr, &x, &y, &z, &c, pen, opt);	}
+	/// Draw curve {x,y} which is colored by c (like tension plot)
 	inline void Tens(const mglData &x, const mglData &y, const mglData &c, const char *pen="", const char *opt="")
 	{	mgl_tens_xy(gr, &x, &y, &c, pen, opt);	}
+	/// Draw curve {x,y} with x in x-axis range which is colored by c (like tension plot)
 	inline void Tens(const mglData &y, const mglData &c, const char *pen="", const char *opt="")
 	{	mgl_tens(gr, &y, &c, pen, opt);	}
+
 	/// Fill area between curve {x,y,z} and axis plane
+	/** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Area(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_area_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Fill area between curve {x,y} and axis plane
+	/** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Area(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_area_xy(gr, &x, &y, pen, opt);	}
+	/// Fill area between curve {x,y} with x in x-axis range and axis plane
+	/** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Area(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_area(gr, &y, pen, opt);	}
-	/// Fill area between curves y1 and y2 specified parametrically
+
+	/// Fill area between curves {x,y1} and {x,y2} with x in x-axis range
+	/** Style 'i' will fill area only if y1 < y2.
+	  * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Region(const mglData &y1, const mglData &y2, const char *pen="", const char *opt="")
 	{	mgl_region(gr, &y1, &y2, pen, opt);	}
+	/// Fill area between curves {x,y1} and {x,y2}
+	/** Style 'i' will fill area only if y1 < y2.
+	  * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Region(const mglData &x, const mglData &y1, const mglData &y2, const char *pen="", const char *opt="")
 	{	mgl_region_xy(gr, &x, &y1, &y2, pen, opt);	}
 	/// Fill area (draw ribbon) between curves {x1,y1,z1} and {x2,y2,z2}
+	/** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Region(const mglData &x1, const mglData &y1, const mglData &z1, const mglData &x2, const mglData &y2, const mglData &z2, const char *pen="", const char *opt="")
 	{	mgl_region_3d(gr, &x1, &y1, &z1, &x2, &y2, &z2, pen, opt);	}
+	/// Fill area (draw ribbon) between curves {x1,y1} and {x2,y2}
+	/** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Region(const mglData &x1, const mglData &y1, const mglData &x2, const mglData &y2, const char *pen="", const char *opt="")
 	{	mgl_region_3d(gr, &x1, &y1, NULL, &x2, &y2, NULL, pen, opt);	}
+
 	/// Draw vertical lines from points {x,y,z} to axis plane
 	inline void Stem(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_stem_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Draw vertical lines from points {x,y} to axis plane
 	inline void Stem(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_stem_xy(gr, &x, &y, pen, opt);	}
+	/// Draw vertical lines from points {x,y} with x in x-axis range to axis plane
 	inline void Stem(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_stem(gr, &y, pen, opt);	}
 
 	/// Draw vertical bars from points {x,y,z} to axis plane
+	/** String \a pen may contain:
+	 * ‘a’ for drawing boxes one above another (like summation);
+	 * ‘f’ for waterfall chart;
+	 * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Bars(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_bars_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Draw vertical bars from points {x,y} to axis plane
+	/** String \a pen may contain:
+	 * ‘a’ for drawing boxes one above another (like summation);
+	 * ‘f’ for waterfall chart;
+	 * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Bars(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_bars_xy(gr, &x, &y, pen, opt);	}
+	/// Draw vertical bars from points {x,y} with x in x-axis range to axis plane
+	/** String \a pen may contain:
+	 * ‘a’ for drawing boxes one above another (like summation);
+	 * ‘f’ for waterfall chart;
+	 * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Bars(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_bars(gr, &y, pen, opt);	}
 	/// Draw horizontal bars from points {x,y} to axis plane
+	/** String \a pen may contain:
+	 * ‘a’ for drawing boxes one above another (like summation);
+	 * ‘f’ for waterfall chart;
+	 * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Barh(const mglData &y, const mglData &v, const char *pen="", const char *opt="")
 	{	mgl_barh_yx(gr, &y, &v, pen, opt);	}
+	/// Draw horizontal bars from points {x,y} with y in y-axis range to axis plane
+	/** String \a pen may contain:
+	 * ‘a’ for drawing boxes one above another (like summation);
+	 * ‘f’ for waterfall chart;
+	 * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Barh(const mglData &v, const char *pen="", const char *opt="")
 	{	mgl_barh(gr, &v, pen, opt);	}
 	/// Draw chart for data a
+	/** Space denote transparent color. Style '#' draw black borders. */
 	inline void Chart(const mglData &a, const char *colors="", const char *opt="")
 	{	mgl_chart(gr, &a, colors,opt);	}
 
 	/// Draw Open-High-Low-Close (OHLC) diagram
+	/**  Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */
 	inline void OHLC(const mglData &x, const mglData &open, const mglData &high, const mglData &low, const mglData &close, const char *pen="", const char *opt="")
 	{	mgl_ohlc_x(gr, &x, &open,&high,&low,&close,pen,opt);	}
+	/// Draw Open-High-Low-Close (OHLC) diagram with x in x-axis range
+	/**  Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */
 	inline void OHLC(const mglData &open, const mglData &high, const mglData &low, const mglData &close, const char *pen="", const char *opt="")
 	{	mgl_ohlc(gr, &open,&high,&low,&close,pen,opt);	}
 
 	/// Draw box-plot (special 5-value plot used in statistic)
+	/** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/
 	inline void BoxPlot(const mglData &x, const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_boxplot_xy(gr, &x, &y, pen,opt);	}
+	/// Draw box-plot (special 5-value plot used in statistic) with x in x-axis range
+	/** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/
 	inline void BoxPlot(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_boxplot(gr, &y, pen,opt);	}
+
 	/// Draw candle plot
+	/** Different colors are used for up and down values if 2 colors are specified.
+	 *  Style ‘#’ force drawing wire candle even for 2-color scheme. */
 	inline void Candle(const mglData &x, const mglData &v1, const mglData &v2, const mglData &y1, const mglData &y2, const char *pen="", const char *opt="")
 	{	mgl_candle_xyv(gr, &x, &v1, &v2, &y1, &y2, pen, opt);	}
+	/// Draw candle plot with x in x-axis range
+	/** Different colors are used for up and down values if 2 colors are specified.
+	 *  Style ‘#’ force drawing wire candle even for 2-color scheme. */
 	inline void Candle(const mglData &v1, const mglData &v2, const mglData &y1, const mglData &y2, const char *pen="", const char *opt="")
 	{	mgl_candle_yv(gr, &v1, &v2, &y1, &y2, pen, opt);	}
 	inline void Candle(const mglData &v1, const mglData &v2, const char *pen="", const char *opt="")
 	{	mgl_candle_yv(gr, &v1, &v2, NULL, NULL, pen, opt);	}
+	/// Draw candle plot with v1=v[i], v2=v[i+1]
+	/** Different colors are used for up and down values if 2 colors are specified.
+	 *  Style ‘#’ force drawing wire candle even for 2-color scheme. */
 	inline void Candle(const mglData &y, const mglData &y1, const mglData &y2, const char *pen="", const char *opt="")
 	{	mgl_candle(gr, &y, &y1, &y2, pen, opt);	}
+	/// Draw candle plot with v1=v[i], v2=v[i+1]
+	/** Different colors are used for up and down values if 2 colors are specified.
+	 *  Style ‘#’ force drawing wire candle even for 2-color scheme. */
 	inline void Candle(const mglData &y, const char *pen="", const char *opt="")
 	{	mgl_candle(gr, &y, NULL, NULL, pen, opt);	}
+
 	/// Draw cones from points {x,y,z} to axis plane
+	/** String \a pen may contain:
+	 * ‘@’ for drawing edges;
+	 * ‘#’ for wired cones;
+	 * ‘t’ for drawing tubes/cylinders instead of cones/prisms;
+	 * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones;
+	 * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Cones(const mglData &x, const mglData &y, const mglData &z, const char *pen="@", const char *opt="")
 	{	mgl_cones_xyz(gr, &x, &y, &z, pen, opt);	}
+	/// Draw cones from points {x,z} to axis plane
+	/** String \a pen may contain:
+	 * ‘@’ for drawing edges;
+	 * ‘#’ for wired cones;
+	 * ‘t’ for drawing tubes/cylinders instead of cones/prisms;
+	 * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones;
+	 * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Cones(const mglData &x, const mglData &z, const char *pen="@", const char *opt="")
 	{	mgl_cones_xz(gr, &x, &z, pen, opt);	}
+	/// Draw cones from points {x,z} with x in x-axis range to axis plane
+	/** String \a pen may contain:
+	 * ‘@’ for drawing edges;
+	 * ‘#’ for wired cones;
+	 * ‘t’ for drawing tubes/cylinders instead of cones/prisms;
+	 * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones;
+	 * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates.
+	 * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/
 	inline void Cones(const mglData &z, const char *pen="@", const char *opt="")
 	{	mgl_cones(gr, &z, pen, opt);	}
 
-	/// Draw error boxes {ex,ey} at points {x,y}
+	/// Draw error boxes {ey} at points {x,y} with x in x-axis range
+	/** Style ‘@’ set to draw large semitransparent mark instead of error box.*/
 	inline void Error(const mglData &y, const mglData &ey, const char *pen="", const char *opt="")
 	{	mgl_error(gr, &y, &ey, pen, opt);	}
+	/// Draw error boxes {ey} at points {x,y}
+	/** Style ‘@’ set to draw large semitransparent mark instead of error box.*/
 	inline void Error(const mglData &x, const mglData &y, const mglData &ey, const char *pen="", const char *opt="")
 	{	mgl_error_xy(gr, &x, &y, &ey, pen, opt);	}
+	/// Draw error boxes {ex,ey} at points {x,y}
+	/** Style ‘@’ set to draw large semitransparent mark instead of error box.*/
 	inline void Error(const mglData &x, const mglData &y, const mglData &ex, const mglData &ey, const char *pen="", const char *opt="")
 	{	mgl_error_exy(gr, &x, &y, &ex, &ey, pen, opt);	}
+
 	/// Draw marks with size r at points {x,y,z}
 	inline void Mark(const mglData &x, const mglData &y, const mglData &z, const mglData &r, const char *pen, const char *opt="")
 	{	mgl_mark_xyz(gr, &x, &y, &z, &r, pen, opt);	}
+	/// Draw marks with size r at points {x,y}
 	inline void Mark(const mglData &x, const mglData &y, const mglData &r, const char *pen, const char *opt="")
 	{	mgl_mark_xy(gr, &x, &y, &r, pen, opt);	}
+	/// Draw marks with size r at points {x,y} with x in x-axis range
 	inline void Mark(const mglData &y, const mglData &r, const char *pen, const char *opt="")
 	{	mgl_mark_y(gr, &y, &r, pen, opt);	}
+
+	/// Draw Poincare map at condition s==0 for curve {x,y,z}
+	inline void Pmap(const mglData &x, const mglData &y, const mglData &z, const mglData &s, const char *pen, const char *opt="")
+	{	mgl_pmap_xyz(gr, &x, &y, &z, &s, pen, opt);	}
+	/// Draw Poincare map at condition s==0 for curve {x,y}
+	inline void Pmap(const mglData &x, const mglData &y, const mglData &s, const char *pen, const char *opt="")
+	{	mgl_pmap_xy(gr, &x, &y, &s, pen, opt);	}
+	/// Draw Poincare map at condition s==0 for curve {x,y} with x in x-axis range
+	inline void Pmap(const mglData &y, const mglData &s, const char *pen, const char *opt="")
+	{	mgl_pmap(gr, &y, &s, pen, opt);	}
+
 	/// Draw textual marks with size r at points {x,y,z}
 	inline void TextMark(const mglData &x, const mglData &y, const mglData &z, const mglData &r, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_textmark_xyzr(gr, &x, &y, &z, &r, text, fnt, opt);	}
+	/// Draw textual marks with size r at points {x,y}
 	inline void TextMark(const mglData &x, const mglData &y, const mglData &r, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_textmark_xyr(gr, &x, &y, &r, text, fnt, opt);	}
+	/// Draw textual marks with size r at points {x,y} with x in x-axis range
 	inline void TextMark(const mglData &y, const mglData &r, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_textmark_yr(gr, &y, &r, text, fnt, opt);	}
+	/// Draw textual marks at points {x,y} with x in x-axis range
 	inline void TextMark(const mglData &y, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_textmark(gr, &y, text, fnt, opt);	}
+	/// Draw textual marks with size r at points {x,y,z}
 	inline void TextMark(const mglData &x, const mglData &y, const mglData &z, const mglData &r, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_textmarkw_xyzr(gr, &x, &y, &z, &r, text, fnt, opt);	}
+	/// Draw textual marks with size r at points {x,y}
 	inline void TextMark(const mglData &x, const mglData &y, const mglData &r, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_textmarkw_xyr(gr, &x, &y, &r, text, fnt, opt);	}
+	/// Draw textual marks with size r at points {x,y} with x in x-axis range
 	inline void TextMark(const mglData &y, const mglData &r, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_textmarkw_yr(gr, &y, &r, text, fnt, opt);	}
+	/// Draw textual marks at points {x,y} with x in x-axis range
 	inline void TextMark(const mglData &y, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_textmarkw(gr, &y, text, fnt, opt);	}
 
 	/// Draw labels for points coordinate(s) at points {x,y,z}
+	/** String \a fnt may contain:
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.*/
 	inline void Label(const mglData &x, const mglData &y, const mglData &z, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_label_xyz(gr, &x, &y, &z, text, fnt, opt);	}
+	/// Draw labels for points coordinate(s) at points {x,y}
+	/** String \a fnt may contain:
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.*/
 	inline void Label(const mglData &x, const mglData &y, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_label_xy(gr, &x, &y, text, fnt, opt);	}
+	/// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range
+	/** String \a fnt may contain:
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.*/
 	inline void Label(const mglData &y, const char *text, const char *fnt="", const char *opt="")
 	{	mgl_label_y(gr, &y, text, fnt, opt);	}
+	/// Draw labels for points coordinate(s) at points {x,y,z}
+	/** String \a fnt may contain:
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.*/
 	inline void Label(const mglData &x, const mglData &y, const mglData &z, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_labelw_xyz(gr, &x, &y, &z, text, fnt, opt);	}
+	/// Draw labels for points coordinate(s) at points {x,y}
+	/** String \a fnt may contain:
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.*/
 	inline void Label(const mglData &x, const mglData &y, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_labelw_xy(gr, &x, &y, text, fnt, opt);	}
+	/// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range
+	/** String \a fnt may contain:
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.*/
 	inline void Label(const mglData &y, const wchar_t *text, const char *fnt="", const char *opt="")
 	{	mgl_labelw_y(gr, &y, text, fnt, opt);	}
 
 	/// Draw table for values val along given direction with row labels text
+	/** String \a fnt may contain:
+	 *	 ‘#’ for drawing cell borders;
+	 *	 ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);
+	 *	 ‘=’ for equal width of all cells;
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.
+	 * Option value set the width of the table (default is 1).*/
 	inline void Table(const mglData &val, const char *text, const char *fnt="#|", const char *opt="")
 	{	mgl_table(gr, 0, 0, &val, text, fnt, opt);	}
+	/// Draw table for values val along given direction with row labels text
+	/** String \a fnt may contain:
+	 *	 ‘#’ for drawing cell borders;
+	 *	 ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);
+	 *	 ‘=’ for equal width of all cells;
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.
+	 * Option value set the width of the table (default is 1).*/
 	inline void Table(const mglData &val, const wchar_t *text, const char *fnt="#|", const char *opt="")
 	{	mgl_tablew(gr, 0, 0, &val, text, fnt, opt);	}
 	/// Draw table for values val along given direction with row labels text at given position
+	/** String \a fnt may contain:
+	 *	 ‘#’ for drawing cell borders;
+	 *	 ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);
+	 *	 ‘=’ for equal width of all cells;
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.
+	 * Option value set the width of the table (default is 1).*/
 	inline void Table(double x, double y, const mglData &val, const char *text, const char *fnt="#|", const char *opt="")
 	{	mgl_table(gr, x, y, &val, text, fnt, opt);	}
+	/// Draw table for values val along given direction with row labels text at given position
+	/** String \a fnt may contain:
+	 *	 ‘#’ for drawing cell borders;
+	 *	 ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);
+	 *	 ‘=’ for equal width of all cells;
+	 *	 ‘f’ for fixed format of printed numbers;
+	 *	 ‘E’ for using ‘E’ instead of ‘e’;
+	 *	 ‘F’ for printing in LaTeX format;
+	 *	 ‘+’ for printing ‘+’ for positive numbers;
+	 *	 ‘-’ for printing usual ‘-’;
+	 *	 ‘0123456789’ for precision at printing numbers.
+	 * Option value set the width of the table (default is 1).*/
 	inline void Table(double x, double y, const mglData &val, const wchar_t *text, const char *fnt="#|", const char *opt="")
 	{	mgl_tablew(gr, x, y, &val, text, fnt, opt);	}
 
 	/// Draw tube with radius r around curve {x,y,z}
 	inline void Tube(const mglData &x, const mglData &y, const mglData &z, const mglData &r, const char *pen="", const char *opt="")
 	{	mgl_tube_xyzr(gr, &x, &y, &z, &r, pen, opt);	}
+	/// Draw tube with radius r around curve {x,y,z}
 	inline void Tube(const mglData &x, const mglData &y, const mglData &z, double r, const char *pen="", const char *opt="")
 	{	mgl_tube_xyz(gr, &x, &y, &z, r, pen, opt);	}
+	/// Draw tube with radius r around curve {x,y}
 	inline void Tube(const mglData &x, const mglData &y, const mglData &r, const char *pen="", const char *opt="")
 	{	mgl_tube_xyr(gr, &x, &y, &r, pen, opt);	}
+	/// Draw tube with radius r around curve {x,y}
 	inline void Tube(const mglData &x, const mglData &y, double r, const char *pen="", const char *opt="")
 	{	mgl_tube_xy(gr, &x, &y, r, pen, opt);	}
+	/// Draw tube with radius r around curve {x,y} with x in x-axis range
 	inline void Tube(const mglData &y, const mglData &r, const char *pen="", const char *opt="")
 	{	mgl_tube_r(gr, &y, &r, pen, opt);	}
+	/// Draw tube with radius r around curve {x,y} with x in x-axis range
 	inline void Tube(const mglData &y, double r, const char *pen="", const char *opt="")
 	{	mgl_tube(gr, &y, r, pen, opt);	}
-	/// Draw surface of curve {r,z} rotatation around axis
+	/// Draw surface of curve {r,z} rotation around axis
+	/** Style ‘#’ produce wire plot. Style ‘.’ produce plot by dots.*/
 	inline void Torus(const mglData &r, const mglData &z, const char *pen="", const char *opt="")
 	{	mgl_torus(gr, &r, &z, pen,opt);	}
 
 	/// Draw mesh lines for 2d data specified parametrically
 	inline void Mesh(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_mesh_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw mesh lines for 2d data
 	inline void Mesh(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_mesh(gr, &z, stl, opt);	}
-	/// Draw mesh lines for 2d data specified parametrically
+
+	/// Draw waterfall plot for 2d data specified parametrically
+	/** Style 'x' draw lines in x-direction. */
 	inline void Fall(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_fall_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw waterfall plot for 2d data
+	/** Style 'x' draw lines in x-direction. */
 	inline void Fall(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_fall(gr, &z, stl, opt);	}
+
 	/// Draw belts for 2d data specified parametrically
+	/** Style 'x' draw belts in x-direction. */
 	inline void Belt(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_belt_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw belts for 2d data
+	/** Style 'x' draw belts in x-direction. */
 	inline void Belt(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_belt(gr, &z, stl, opt);	}
+
 	/// Draw surface for 2d data specified parametrically with color proportional to z
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void Surf(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_surf_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw surface for 2d data with color proportional to z
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void Surf(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_surf(gr, &z, stl, opt);	}
+
 	/// Draw grid lines for density plot of 2d data specified parametrically
 	inline void Grid(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_grid_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw grid lines for density plot of 2d data
 	inline void Grid(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_grid(gr, &z, stl, opt);	}
+
 	/// Draw vertical tiles for 2d data specified parametrically
 	inline void Tile(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_tile_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw vertical tiles for 2d data
 	inline void Tile(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_tile(gr, &z, stl, opt);	}
 	/// Draw density plot for 2d data specified parametrically
-	inline void Dens(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
-	{	mgl_dens_xy(gr, &x, &y, &z, stl, opt);	}
-	inline void Dens(const mglData &z, const char *stl="", const char *opt="")
-	{	mgl_dens(gr, &z, stl, opt);	}
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void Dens(const mglData &x, const mglData &y, const mglData &c, const char *stl="", const char *opt="")
+	{	mgl_dens_xy(gr, &x, &y, &c, stl, opt);	}
+	/// Draw density plot for 2d data
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void Dens(const mglData &c, const char *stl="", const char *opt="")
+	{	mgl_dens(gr, &c, stl, opt);	}
+
 	/// Draw vertical boxes for 2d data specified parametrically
+	/** Style ‘#’ draw filled boxes. */
 	inline void Boxs(const mglData &x, const mglData &y, const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_boxs_xy(gr, &x, &y, &z, stl, opt);	}
+	/// Draw vertical boxes for 2d data
+	/** Style ‘#’ draw filled boxes. */
 	inline void Boxs(const mglData &z, const char *stl="", const char *opt="")
 	{	mgl_boxs(gr, &z, stl, opt);	}
 
-	/// Draw contour lines for 2d data specified parametrically
+	/// Draw contour lines at manual levels for 2d data specified parametrically
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style 't'/'T' draw contour labels below/above contours.*/
 	inline void Cont(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_cont_xy_val(gr, &v, &x, &y, &z, sch, opt);	}
+	/// Draw contour lines for 2d data
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style 't'/'T' draw contour labels below/above contours.*/
 	inline void Cont(const mglData &v, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_cont_val(gr, &v, &z, sch, opt);	}
+	/// Draw contour lines at manual levels for 2d data specified parametrically
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void Cont(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_cont_xy(gr, &x, &y, &z, sch, opt);	}
+	/// Draw contour lines for 2d data
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void Cont(const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_cont(gr, &z, sch, opt);	}
-	/// Draw solid contours for 2d data specified parametrically
+
+	/// Draw solid contours at manual levels for 2d data specified parametrically
+	/** Style ‘_’ to draw contours at bottom of axis box. */
 	inline void ContF(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contf_xy_val(gr, &v, &x, &y, &z, sch, opt);	}
+	/// Draw solid contours at manual levels for 2d data
+	/** Style ‘_’ to draw contours at bottom of axis box. */
 	inline void ContF(const mglData &v, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contf_val(gr, &v, &z, sch, opt);	}
+	/// Draw solid contours for 2d data specified parametrically
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void ContF(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contf_xy(gr, &x, &y, &z, sch, opt);	}
+	/// Draw solid contours for 2d data
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void ContF(const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contf(gr, &z, sch, opt);	}
-	/// Draw solid contours for 2d data specified parametrically with manual colors
+
+	/// Draw solid contours at manual levels for 2d data specified parametrically with specified colors
+	/** Style ‘_’ to draw contours at bottom of axis box. */
 	inline void ContD(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contd_xy_val(gr, &v, &x, &y, &z, sch, opt);	}
+	/// Draw solid contours at manual levels for 2d data with specified colors
+	/** Style ‘_’ to draw contours at bottom of axis box. */
 	inline void ContD(const mglData &v, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contd_val(gr, &v, &z, sch, opt);	}
+	/// Draw solid contours for 2d data specified parametrically with specified colors
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void ContD(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contd_xy(gr, &x, &y, &z, sch, opt);	}
+	/// Draw solid contours for 2d data with specified colors
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void ContD(const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contd(gr, &z, sch, opt);	}
-	/// Draw contour tubes for 2d data specified parametrically
+
+	/// Draw contour tubes between manual levels for 2d data specified parametrically
+	/** Style ‘_’ to draw contours at bottom of axis box. */
 	inline void ContV(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contv_xy_val(gr, &v, &x, &y, &z, sch, opt);	}
+	/// Draw contour tubes between manual levels for 2d data
+	/** Style ‘_’ to draw contours at bottom of axis box. */
 	inline void ContV(const mglData &v, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contv_val(gr, &v, &z, sch, opt);	}
+	/// Draw contour tubes for 2d data specified parametrically
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void ContV(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contv_xy(gr, &x, &y, &z, sch, opt);	}
+	/// Draw contour tubes for 2d data
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void ContV(const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_contv(gr, &z, sch, opt);	}
 
-	/// Draw axial-symmetric isosurfaces for 2d data specified parametrically
+	/// Draw axial-symmetric isosurfaces at manual levels for 2d data specified parametrically
+	/** String \a sch may contain:
+	 * ‘#’ for wired plot;
+	 * ‘.’ for plot by dots;
+	 * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */
 	inline void Axial(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_axial_xy_val(gr, &v, &x, &y, &z, sch,opt);	}
+	/// Draw axial-symmetric isosurfaces at manual levels for 2d data
+	/** String \a sch may contain:
+	 * ‘#’ for wired plot;
+	 * ‘.’ for plot by dots;
+	 * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */
 	inline void Axial(const mglData &v, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_axial_val(gr, &v, &z, sch, opt);	}
+	/// Draw axial-symmetric isosurfaces for 2d data specified parametrically
+	/** String \a sch may contain:
+	 * ‘#’ for wired plot;
+	 * ‘.’ for plot by dots;
+	 * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis).
+	 * Option "value" set the number of isosurfaces (default is 3). */
 	inline void Axial(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_axial_xy(gr, &x, &y, &z, sch, opt);	}
+	/// Draw axial-symmetric isosurfaces for 2d data
+	/** String \a sch may contain:
+	 * ‘#’ for wired plot;
+	 * ‘.’ for plot by dots;
+	 * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis).
+	 * Option "value" set the number of isosurfaces (default is 3). */
 	inline void Axial(const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_axial(gr, &z, sch, opt);	}
 
 	/// Draw grid lines for density plot at slice for 3d data specified parametrically
+	/** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/
 	inline void Grid3(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *stl="", double sVal=-1, const char *opt="")
 	{	mgl_grid3_xyz(gr, &x, &y, &z, &a, stl, sVal, opt);	}
+	/// Draw grid lines for density plot at slice for 3d data
+	/** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/
 	inline void Grid3(const mglData &a, const char *stl="", double sVal=-1, const char *opt="")
 	{	mgl_grid3(gr, &a, stl, sVal, opt);	}
+
 	/// Draw density plot at slice for 3d data specified parametrically
+	/** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/
 	inline void Dens3(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *stl="", double sVal=-1, const char *opt="")
 	{	mgl_dens3_xyz(gr, &x, &y, &z, &a, stl, sVal, opt);	}
+	/// Draw density plot at slice for 3d data
+	/** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/
 	inline void Dens3(const mglData &a, const char *stl="", double sVal=-1, const char *opt="")
 	{	mgl_dens3(gr, &a, stl, sVal, opt);	}
 
-	/// Draw isosurface(s) for 3d data specified parametrically
+	/// Draw isosurface for 3d data specified parametrically
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/
 	inline void Surf3(double Val, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *stl="", const char *opt="")
 	{	mgl_surf3_xyz_val(gr, Val, &x, &y, &z, &a, stl, opt);	}
+	/// Draw isosurface for 3d data
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/
 	inline void Surf3(double Val, const mglData &a, const char *stl="", const char *opt="")
 	{	mgl_surf3_val(gr, Val, &a, stl, opt);	}
+	/// Draw isosurfaces for 3d data specified parametrically
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
 	inline void Surf3(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *stl="", const char *opt="")
 	{	mgl_surf3_xyz(gr, &x, &y, &z, &a, stl, opt);	}
+	/// Draw isosurfaces for 3d data
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
 	inline void Surf3(const mglData &a, const char *stl="", const char *opt="")
 	{	mgl_surf3(gr, &a, stl, opt);	}
 
-	/// Draw a semi-transparent cloud for 3d data
+	/// Draw a semi-transparent cloud for 3d data specified parametrically
+	/** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */
 	inline void Cloud(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *stl="", const char *opt="")
 	{	mgl_cloud_xyz(gr, &x, &y, &z, &a, stl, opt);	}
+	/// Draw a semi-transparent cloud for 3d data
+	/** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */
 	inline void Cloud(const mglData &a, const char *stl="", const char *opt="")
 	{	mgl_cloud(gr, &a, stl, opt);	}
 
-	/// Draw contour lines at slice for 3d data specified parametrically
+	/// Draw contour lines at manual levels along slice for 3d data specified parametrically
+	/** Style ‘#’ draw grid lines.
+	 * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours. */
 	inline void Cont3(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_cont3_xyz_val(gr, &v, &x, &y, &z, &a, sch, sVal, opt);	}
+	/// Draw contour lines at manual levels along slice for 3d data
+	/** Style ‘#’ draw grid lines.
+	 * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours. */
 	inline void Cont3(const mglData &v, const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_cont3_val(gr, &v, &a, sch, sVal, opt);	}
+	/// Draw contour lines along slice for 3d data specified parametrically
+	/** Style ‘#’ draw grid lines.
+	 * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void Cont3(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_cont3_xyz(gr, &x, &y, &z, &a, sch, sVal, opt);	}
+	/// Draw contour lines along slice for 3d data
+	/** Style ‘#’ draw grid lines.
+	 * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void Cont3(const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_cont3(gr, &a, sch, sVal, opt);	}
 
-	/// Draw solid contours at slice for 3d data specified parametrically
+	/// Draw solid contours at manual levels along slice for 3d data specified parametrically
+	/** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */
 	inline void ContF3(const mglData &v, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_contf3_xyz_val(gr, &v, &x, &y, &z, &a, sch, sVal, opt);	}
+	/// Draw solid contours at manual levels along slice for 3d data
+	/** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */
 	inline void ContF3(const mglData &v, const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_contf3_val(gr, &v, &a, sch, sVal, opt);	}
+	/// Draw solid contours along slice for 3d data specified parametrically
+	/** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.
+	 *  Option "value" set the number of contour levels (default is 7).*/
 	inline void ContF3(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_contf3_xyz(gr, &x, &y, &z, &a, sch, sVal, opt);	}
+	/// Draw solid contours along slice for 3d data
+	/** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.
+	 *  Option "value" set the number of contour levels (default is 7).*/
 	inline void ContF3(const mglData &a, const char *sch="", double sVal=-1, const char *opt="")
 	{	mgl_contf3(gr, &a, sch, sVal, opt);	}
 
 	/// Draw several isosurfaces for 3d beam in curvilinear coordinates
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.
+	 *  Variable \a flag is bitwise:
+	 * ‘0x1’ - draw in accompanied (not laboratory) coordinates;
+	 * ‘0x2’ - draw projection to \rho-z plane;
+	 * ‘0x4’ - draw normalized in each slice field.*/
 	inline void Beam(const mglData &tr, const mglData &g1, const mglData &g2, const mglData &a, double r, const char *stl=0, int flag=0, int num=3)
 	{	mgl_beam(gr, &tr,&g1,&g2,&a,r,stl,flag,num);	}
+	/// Draw isosurface at value \a val for 3d beam in curvilinear coordinates
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.
+	 *  Variable \a flag is bitwise:
+	 * ‘0x1’ - draw in accompanied (not laboratory) coordinates;
+	 * ‘0x2’ - draw projection to \rho-z plane;
+	 * ‘0x4’ - draw normalized in each slice field.*/
 	inline void Beam(double val, const mglData &tr, const mglData &g1, const mglData &g2, const mglData &a, double r, const char *stl=NULL, int flag=0)
 	{	mgl_beam_val(gr,val,&tr,&g1,&g2,&a,r,stl,flag);	}
 
 	/// Draw vertical tiles with variable size r for 2d data specified parametrically
 	inline void TileS(const mglData &x, const mglData &y, const mglData &z, const mglData &r, const char *stl="", const char *opt="")
 	{	mgl_tiles_xy(gr, &x, &y, &z, &r, stl, opt);	}
+	/// Draw vertical tiles with variable size r for 2d data
 	inline void TileS(const mglData &z, const mglData &r, const char *stl="", const char *opt="")
 	{	mgl_tiles(gr, &z, &r, stl, opt);	}
+
 	/// Draw surface for 2d data specified parametrically with color proportional to c
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void SurfC(const mglData &x, const mglData &y, const mglData &z, const mglData &c, const char *sch="", const char *opt="")
 	{	mgl_surfc_xy(gr, &x, &y, &z, &c, sch,opt);	}
+	/// Draw surface for 2d data with color proportional to c
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void SurfC(const mglData &z, const mglData &c, const char *sch="", const char *opt="")
 	{	mgl_surfc(gr, &z, &c, sch,opt);	}
+
 	/// Draw surface for 2d data specified parametrically with alpha proportional to c
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void SurfA(const mglData &x, const mglData &y, const mglData &z, const mglData &c, const char *sch="", const char *opt="")
 	{	mgl_surfa_xy(gr, &x, &y, &z, &c, sch,opt);	}
+	/// Draw surface for 2d data with alpha proportional to c
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void SurfA(const mglData &z, const mglData &c, const char *sch="", const char *opt="")
 	{	mgl_surfa(gr, &z, &c, sch,opt);	}
 
+	/// Draw surface for 2d data specified parametrically with color proportional to c and alpha proportional to a
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void SurfCA(const mglData &x, const mglData &y, const mglData &z, const mglData &c, const mglData &a, const char *sch="", const char *opt="")
+	{	mgl_surfca_xy(gr, &x, &y, &z, &c, &a, sch,opt);	}
+	/// Draw surface for 2d data with color proportional to c and alpha proportional to a
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void SurfCA(const mglData &z, const mglData &c, const mglData &a, const char *sch="", const char *opt="")
+	{	mgl_surfca(gr, &z, &c, &a, sch,opt);	}
+
 	/// Color map of matrix a to matrix b, both matrix can parametrically depend on coordinates
+	/** Style ‘.’ produce plot by dots. */
 	inline void Map(const mglData &x, const mglData &y, const mglData &a, const mglData &b, const char *sch="", const char *opt="")
 	{	mgl_map_xy(gr, &x, &y, &a, &b, sch, opt);	}
+	/// Color map of matrix a to matrix b
+	/** Style ‘.’ produce plot by dots. */
 	inline void Map(const mglData &a, const mglData &b, const char *sch="", const char *opt="")
 	{	mgl_map(gr, &a, &b, sch, opt);	}
+
 	/// Draw density plot for spectra-gramm specified parametrically
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void STFA(const mglData &x, const mglData &y, const mglData &re, const mglData &im, int dn, const char *sch="", const char *opt="")
 	{	mgl_stfa_xy(gr, &x, &y, &re, &im, dn, sch, opt);	}
+	/// Draw density plot for spectra-gramm
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
 	inline void STFA(const mglData &re, const mglData &im, int dn, const char *sch="", const char *opt="")
 	{	mgl_stfa(gr, &re, &im, dn, sch, opt);	}
 
-	/// Draw isosurface(s) for 3d data specified parametrically with alpha proportional to b
+	/// Draw isosurface for 3d data specified parametrically with alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */
 	inline void Surf3A(double Val, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &b, const char *stl="", const char *opt="")
 	{	mgl_surf3a_xyz_val(gr, Val, &x, &y, &z, &a, &b, stl, opt);	}
+	/// Draw isosurface for 3d data with alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */
 	inline void Surf3A(double Val, const mglData &a, const mglData &b, const char *stl="", const char *opt="")
 	{	mgl_surf3a_val(gr, Val, &a, &b, stl, opt);	}
+	/// Draw isosurfaces for 3d data specified parametrically with alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
 	inline void Surf3A(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &b, const char *stl="", const char *opt="")
 	{	mgl_surf3a_xyz(gr, &x, &y, &z, &a, &b, stl, opt);	}
+	/// Draw isosurfaces for 3d data with alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
 	inline void Surf3A(const mglData &a, const mglData &b, const char *stl="", const char *opt="")
 	{	mgl_surf3a(gr, &a, &b, stl, opt);	}
 
-	/// Draw isosurface(s) for 3d data specified parametrically with color proportional to b
-	inline void Surf3C(double Val, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &b, const char *stl="", const char *opt="")
-	{	mgl_surf3c_xyz_val(gr, Val, &x, &y, &z, &a, &b, stl,opt);	}
-	inline void Surf3C(double Val, const mglData &a, const mglData &b, const char *stl="", const char *opt="")
-	{	mgl_surf3c_val(gr, Val, &a, &b, stl, opt);	}
-	inline void Surf3C(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &b, const char *stl="", const char *opt="")
-	{	mgl_surf3c_xyz(gr, &x, &y, &z, &a, &b, stl, opt);	}
-	inline void Surf3C(const mglData &a, const mglData &b, const char *stl="", const char *opt="")
-	{	mgl_surf3c(gr, &a, &b, stl, opt);	}
+	/// Draw isosurface for 3d data specified parametrically with color proportional to c
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */
+	inline void Surf3C(double Val, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &c, const char *stl="", const char *opt="")
+	{	mgl_surf3c_xyz_val(gr, Val, &x, &y, &z, &a, &c, stl,opt);	}
+	/// Draw isosurface for 3d data with color proportional to c
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */
+	inline void Surf3C(double Val, const mglData &a, const mglData &c, const char *stl="", const char *opt="")
+	{	mgl_surf3c_val(gr, Val, &a, &c, stl, opt);	}
+	/// Draw isosurfaces for 3d data specified parametrically with color proportional to c
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
+	inline void Surf3C(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &c, const char *stl="", const char *opt="")
+	{	mgl_surf3c_xyz(gr, &x, &y, &z, &a, &c, stl, opt);	}
+	/// Draw isosurfaces for 3d data specified parametrically with color proportional to c
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
+	inline void Surf3C(const mglData &a, const mglData &c, const char *stl="", const char *opt="")
+	{	mgl_surf3c(gr, &a, &c, stl, opt);	}
+
+	/// Draw isosurface for 3d data specified parametrically with color proportional to c and alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */
+	inline void Surf3CA(double Val, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &c, const mglData &b, const char *stl="", const char *opt="")
+	{	mgl_surf3ca_xyz_val(gr, Val, &x, &y, &z, &a, &c, &b, stl,opt);	}
+	/// Draw isosurface for 3d data with color proportional to c and alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */
+	inline void Surf3CA(double Val, const mglData &a, const mglData &c, const mglData &b, const char *stl="", const char *opt="")
+	{	mgl_surf3ca_val(gr, Val, &a, &c, &b, stl, opt);	}
+	/// Draw isosurfaces for 3d data specified parametrically with color proportional to c and alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
+	inline void Surf3CA(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &c, const mglData &b, const char *stl="", const char *opt="")
+	{	mgl_surf3ca_xyz(gr, &x, &y, &z, &a, &c, &b, stl, opt);	}
+	/// Draw isosurfaces for 3d data with color proportional to c and alpha proportional to b
+	/** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.
+	 * Option "value" set the number of isosurfaces (default is 3). */
+	inline void Surf3CA(const mglData &a, const mglData &c, const mglData &b, const char *stl="", const char *opt="")
+	{	mgl_surf3ca(gr, &a, &c, &b, stl, opt);	}
 
 	/// Plot dew drops for vector field {ax,ay} parametrically depended on coordinate {x,y}
 	inline void Dew(const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_dew_xy(gr, &x, &y, &ax, &ay, sch, opt);	}
+	/// Plot dew drops for vector field {ax,ay}
 	inline void Dew(const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_dew_2d(gr, &ax, &ay, sch, opt);	}
-	/// Plot vectors at position {x,y,z} along {ax,ay,az} with length/color proportional to |a|
+
+	/// Plot vectors at position {x,y} along {ax,ay} with length/color proportional to |a|
+	/** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */
 	inline void Traj(const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_traj_xy(gr, &x, &y, &ax, &ay, sch, opt);	}
+	/// Plot vectors at position {x,y,z} along {ax,ay,az} with length/color proportional to |a|
+	/** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */
 	inline void Traj(const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_traj_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt);	}
 
-	/// Plot vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with length/color proportional to |a|
+	/// Plot vector field {ax,ay} parametrically depended on coordinate {x,y} with length/color proportional to |a|
+	/** String \a sch may contain:
+	 * ‘f’ for drawing arrows with fixed lengths,
+	 * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),
+	 * ‘.’ for drawing hachures with dots instead of arrows,
+	 * ‘=’ for enabling color gradient along arrows. */
 	inline void Vect(const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_vect_xy(gr, &x, &y, &ax, &ay, sch, opt);	}
+	/// Plot vector field {ax,ay} with length/color proportional to |a|
+	/** String \a sch may contain:
+	 * ‘f’ for drawing arrows with fixed lengths,
+	 * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),
+	 * ‘.’ for drawing hachures with dots instead of arrows,
+	 * ‘=’ for enabling color gradient along arrows. */
 	inline void Vect(const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_vect_2d(gr, &ax, &ay, sch, opt);	}
+	/// Plot vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with length/color proportional to |a|
+	/** String \a sch may contain:
+	 * ‘f’ for drawing arrows with fixed lengths,
+	 * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),
+	 * ‘.’ for drawing hachures with dots instead of arrows,
+	 * ‘=’ for enabling color gradient along arrows. */
 	inline void Vect(const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_vect_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt);	}
+	/// Plot vector field {ax,ay,az} with length/color proportional to |a|
+	/** String \a sch may contain:
+	 * ‘f’ for drawing arrows with fixed lengths,
+	 * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),
+	 * ‘.’ for drawing hachures with dots instead of arrows,
+	 * ‘=’ for enabling color gradient along arrows. */
 	inline void Vect(const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_vect_3d(gr, &ax, &ay, &az, sch, opt);	}
 
-	/// Draw vector plot at slice for 3d data specified parametrically
+	/// Draw vector plot along slice for 3d data specified parametrically
+	/** String \a sch may contain:
+	 * ‘f’ for drawing arrows with fixed lengths,
+	 * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),
+	 * ‘.’ for drawing hachures with dots instead of arrows,
+	 * ‘=’ for enabling color gradient along arrows,
+	 * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */
 	inline void Vect3(const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, const char *stl="", double sVal=-1, const char *opt="")
 	{	mgl_vect3_xyz(gr, &x, &y, &z, &ax,&ay,&az, stl, sVal, opt);	}
+	/// Draw vector plot along slice for 3d data
+	/** String \a sch may contain:
+	 * ‘f’ for drawing arrows with fixed lengths,
+	 * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),
+	 * ‘.’ for drawing hachures with dots instead of arrows,
+	 * ‘=’ for enabling color gradient along arrows,
+	 * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */
 	inline void Vect3(const mglData &ax, const mglData &ay, const mglData &az, const char *stl="", double sVal=-1, const char *opt="")
 	{	mgl_vect3(gr, &ax,&ay,&az, stl, sVal, opt);	}
 
-	/// Plot flows for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a|
+	/// Plot flows for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Flow(const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_flow_xy(gr, &x, &y, &ax, &ay, sch, opt);	}
+	/// Plot flows for vector field {ax,ay} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Flow(const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_flow_2d(gr, &ax, &ay, sch, opt);	}
+	/// Plot flows for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Flow(const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_flow_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt);	}
+	/// Plot flows for vector field {ax,ay,az} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Flow(const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_flow_3d(gr, &ax, &ay, &az, sch, opt);	}
 
-	/// Plot flow from point p for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a|
+	/// Plot flow from point p for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads. */
 	inline void FlowP(mglPoint p, const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_flowp_xy(gr, p.x, p.y, p.z, &x, &y, &ax, &ay, sch, opt);	}
+	/// Plot flow from point p for vector field {ax,ay} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads. */
 	inline void FlowP(mglPoint p, const mglData &ax, const mglData &ay, const char *sch="", const char *opt="")
 	{	mgl_flowp_2d(gr, p.x, p.y, p.z, &ax, &ay, sch, opt);	}
+	/// Plot flow from point p for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */
 	inline void FlowP(mglPoint p, const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_flowp_xyz(gr, p.x, p.y, p.z, &x, &y, &z, &ax, &ay, &az, sch, opt);	}
+	/// Plot flow from point p for vector field {ax,ay,az} with color proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */
 	inline void FlowP(mglPoint p, const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", const char *opt="")
 	{	mgl_flowp_3d(gr, p.x, p.y, p.z, &ax, &ay, &az, sch, opt);	}
 
 	/// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y,z}
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Grad(const mglData &x, const mglData &y, const mglData &z, const mglData &phi, const char *sch="", const char *opt="")
 	{	mgl_grad_xyz(gr,&x,&y,&z,&phi,sch,opt);	}
+	/// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y}
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Grad(const mglData &x, const mglData &y, const mglData &phi, const char *sch="", const char *opt="")
 	{	mgl_grad_xy(gr,&x,&y,&phi,sch,opt);	}
+	/// Plot flows for gradient of scalar field phi
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘v’ for drawing arrows on the threads;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Grad(const mglData &phi, const char *sch="", const char *opt="")
 	{	mgl_grad(gr,&phi,sch,opt);	}
 
-	/// Plot flow pipes for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color and radius proportional to |a|
+	/// Plot flow pipes for vector field {ax,ay} parametrically depended on coordinate {x,y} with color and radius proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘i’ for pipe radius to be inverse proportional to amplitude.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Pipe(const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, const char *sch="", double r0=0.05, const char *opt="")
 	{	mgl_pipe_xy(gr, &x, &y, &ax, &ay, sch, r0, opt);	}
+	/// Plot flow pipes for vector field {ax,ay} with color and radius proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘i’ for pipe radius to be inverse proportional to amplitude.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Pipe(const mglData &ax, const mglData &ay, const char *sch="", double r0=0.05, const char *opt="")
 	{	mgl_pipe_2d(gr, &ax, &ay, sch, r0, opt);	}
+	/// Plot flow pipes for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color and radius proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘i’ for pipe radius to be inverse proportional to amplitude;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Pipe(const mglData &x, const mglData &y, const mglData &z, const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", double r0=0.05, const char *opt="")
 	{	mgl_pipe_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, r0, opt);	}
+	/// Plot flow pipes for vector field {ax,ay,az} with color and radius proportional to |a|
+	/** String \a sch may contain:
+	 * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
+	 * ‘#’ for starting threads from edges only;
+	 * ‘i’ for pipe radius to be inverse proportional to amplitude;
+	 * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.
+	 * Option "value" sets the number of threads (default is 5). */
 	inline void Pipe(const mglData &ax, const mglData &ay, const mglData &az, const char *sch="", double r0=0.05, const char *opt="")
 	{	mgl_pipe_3d(gr, &ax, &ay, &az, sch, r0, opt);	}
 
 	/// Draw density plot for data at x = sVal
-	inline void DensX(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void DensX(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_dens_x(gr, &a, stl, sVal, opt);	}
 	/// Draw density plot for data at y = sVal
-	inline void DensY(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void DensY(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_dens_y(gr, &a, stl, sVal, opt);	}
 	/// Draw density plot for data at z = sVal
-	inline void DensZ(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/
+	inline void DensZ(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_dens_z(gr, &a, stl, sVal, opt);	}
+
 	/// Draw contour lines for data at x = sVal
-	inline void ContX(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
+	inline void ContX(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_cont_x(gr, &a, stl, sVal, opt);	}
-	inline void ContX(const mglData &v, const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/// Draw contour lines at manual levels for data at x = sVal
+	/** Style ‘t’/‘T’ draw contour labels below/above contours. */
+	inline void ContX(const mglData &v, const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_cont_x_val(gr, &v, &a, stl, sVal, opt);	}
 	/// Draw contour lines for data at y = sVal
-	inline void ContY(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
+	inline void ContY(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_cont_y(gr, &a, stl, sVal, opt);	}
-	inline void ContY(const mglData &v, const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/// Draw contour lines at manual levels for data at y = sVal
+	/** Style ‘t’/‘T’ draw contour labels below/above contours. */
+	inline void ContY(const mglData &v, const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_cont_y_val(gr, &v, &a, stl, sVal, opt);	}
 	/// Draw contour lines for data at z = sVal
-	inline void ContZ(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * Option "value" set the number of contour levels (default is 7). */
+	inline void ContZ(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_cont_z(gr, &a, stl, sVal, opt);	}
-	inline void ContZ(const mglData &v, const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/// Draw contour lines at manual levels for data at z = sVal
+	/** Style ‘t’/‘T’ draw contour labels below/above contours. */
+	inline void ContZ(const mglData &v, const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_cont_z_val(gr, &v, &a, stl, sVal, opt);	}
+
 	/// Draw solid contours for data at x = sVal
-	inline void ContFX(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Option "value" set the number of contour levels (default is 7). */
+	inline void ContFX(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_contf_x(gr, &a, stl, sVal, opt);	}
-	inline void ContFX(const mglData &v, const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/// Draw solid contours at manual levels for data at x = sVal
+	inline void ContFX(const mglData &v, const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_contf_x_val(gr, &v, &a, stl, sVal, opt);	}
 	/// Draw solid contours for data at y = sVal
-	inline void ContFY(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Option "value" set the number of contour levels (default is 7). */
+	inline void ContFY(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_contf_y(gr, &a, stl, sVal, opt);	}
-	inline void ContFY(const mglData &v, const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/// Draw solid contours at manual levels for data at y = sVal
+	inline void ContFY(const mglData &v, const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_contf_y_val(gr, &v, &a, stl, sVal, opt);	}
 	/// Draw solid contours for data at z = sVal
-	inline void ContFZ(const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/** Option "value" set the number of contour levels (default is 7). */
+	inline void ContFZ(const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_contf_z(gr, &a, stl, sVal, opt);	}
-	inline void ContFZ(const mglData &v, const mglData &a, const char *stl="", double sVal=NaN, const char *opt="")
+	/// Draw solid contours at manual levels for data at z = sVal
+	inline void ContFZ(const mglData &v, const mglData &a, const char *stl="", double sVal=mglNaN, const char *opt="")
 	{	mgl_contf_z_val(gr, &v, &a, stl, sVal, opt);	}
 
 	/// Draw curve for formula with x in x-axis range
+	/** Option "value" set initial number of points. */
 	inline void FPlot(const char *fy, const char *stl="", const char *opt="")
 	{	mgl_fplot(gr, fy, stl, opt);	}
 	/// Draw curve for formulas parametrically depended on t in range [0,1]
+	/** Option "value" set initial number of points. */
 	inline void FPlot(const char *fx, const char *fy, const char *fz, const char *stl, const char *opt="")
 	{	mgl_fplot_xyz(gr, fx, fy, fz, stl, opt);	}
 	/// Draw surface by formula with x,y in axis range
+	/** Option "value" set initial number of points. */
 	inline void FSurf(const char *fz, const char *stl="", const char *opt="")
 	{	mgl_fsurf(gr, fz, stl, opt);	}
 	/// Draw surface by formulas parametrically depended on u,v in range [0,1]
+	/** Option "value" set initial number of points. */
 	inline void FSurf(const char *fx, const char *fy, const char *fz, const char *stl, const char *opt="")
 	{	mgl_fsurf_xyz(gr, fx, fy, fz, stl, opt);	}
 
 	/// Draw triangle mesh for points in arrays {x,y,z} with specified color c.
+	/** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the triangle colors, else vertex colors. */
 	inline void TriPlot(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &c, const char *sch="", const char *opt="")
 	{	mgl_triplot_xyzc(gr, &nums, &x, &y, &z, &c, sch, opt);	}
+	/// Draw triangle mesh for points in arrays {x,y,z}
+	/** Style ‘#’ produce wire plot. */
 	inline void TriPlot(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_triplot_xyz(gr, &nums, &x, &y, &z, sch, opt);	}
+	/// Draw triangle mesh for points in arrays {x,y}
+	/** Style ‘#’ produce wire plot. */
 	inline void TriPlot(const mglData &nums, const mglData &x, const mglData &y, const char *sch="", const char *opt="")
 	{	mgl_triplot_xy(gr, &nums, &x, &y, sch, opt);	}
-	/// Draw quad mesh for points in arrays {x,y,z} with specified color c.
+
+	/// Draw quad mesh for points in arrays {x,y,z} with specified color c
+	/** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */
 	inline void QuadPlot(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &c, const char *sch="", const char *opt="")
 	{	mgl_quadplot_xyzc(gr, &nums, &x, &y, &z, &c, sch, opt);	}
+	/// Draw quad mesh for points in arrays {x,y,z}
+	/** Style ‘#’ produce wire plot. */
 	inline void QuadPlot(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_quadplot_xyz(gr, &nums, &x, &y, &z, sch, opt);	}
+	/// Draw quad mesh for points in arrays {x,y}
+	/** Style ‘#’ produce wire plot. */
 	inline void QuadPlot(const mglData &nums, const mglData &x, const mglData &y, const char *sch="", const char *opt="")
 	{	mgl_quadplot_xy(gr, &nums, &x, &y, sch, opt);	}
 
-	/// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.
+	/// Draw contour lines for triangle mesh for points in arrays {x,y,z}
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */
 	inline void TriCont(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_tricont_xyc(gr, &nums, &x, &y, &z, sch, opt);	}
+	/// Draw contour lines for triangle mesh for points in arrays {x,y,z}
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * If id.ny=c.nx then c set the quadrangle colors, else vertex colors.
+	 * Option "value" set the number of contour levels (default is 7). */
 	inline void TriContV(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_tricont_xycv(gr, &v, &nums, &x, &y, &z, sch, opt);	}
+	/// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */
 	inline void TriCont(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
 	{	mgl_tricont_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt);	}
+	/// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */
 	inline void TriContV(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
 	{	mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);	}
+	/// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.
+	/** Style ‘_’ to draw contours at bottom of axis box.
+	 * Style ‘t’/‘T’ draw contour labels below/above contours.
+	 * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */
 	inline void TriCont(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
 	{	mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);	}
 
-	/// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.
+	/// Draw contour tubes for triangle mesh for points in arrays {x,y,z}
+	/** Option "value" set the number of contour levels (default is 7). */
 	inline void TriContVt(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_tricontv_xyc(gr, &nums, &x, &y, &z, sch, opt);	}
+	/// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c
+	/** Option "value" set the number of contour levels (default is 7). */
 	inline void TriContVt(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
 	{	mgl_tricontv_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt);	}
+	/// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c
+	/** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */
 	inline void TriContVt(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
 	{	mgl_tricontv_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);	}
 
@@ -1151,76 +1966,108 @@ public:
 	inline void Dots(const mglData &x, const mglData &y, const mglData &z, const mglData &c, const mglData &a, const char *sch="", const char *opt="")
 	{	mgl_dots_ca(gr, &x, &y, &z, &c, &a, sch, opt);	}
 	/// Draw surface reconstructed for points in arrays {x,y,z}.
+	/** Style ‘#’ produce wired plot. */
 	inline void Crust(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
 	{	mgl_crust(gr, &x, &y, &z, sch, opt);	}
 
 	/// Fit data along x-direction for each data row. Return array with values for found formula.
-	inline mglData Fit(const mglData &y, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_1(gr, &y, eq,var,0, opt));	}
-	inline mglData Fit(const mglData &y, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_1(gr, &y, eq, var, &ini, opt));	}
+	inline mglData Fit(const mglData &y, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_1(gr, &y, eq,vars,0, opt));	}
+	/// Fit data along x-direction for each data row starting from \a ini values. Return array with values for found formula.
+	inline mglData Fit(const mglData &y, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_1(gr, &y, eq, vars, &ini, opt));	}
 	/// Fit data along x-, y-directions for each data slice. Return array with values for found formula.
-	inline mglData Fit2(const mglData &z, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_2(gr, &z, eq, var,0, opt));	}
-	inline mglData Fit2(const mglData &z, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_2(gr, &z, eq, var, &ini, opt));	}
+	inline mglData Fit2(const mglData &z, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_2(gr, &z, eq, vars,0, opt));	}
+	/// Fit data along x-, y-direction for each data slice starting from \a ini values. Return array with values for found formula.
+	inline mglData Fit2(const mglData &z, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_2(gr, &z, eq, vars, &ini, opt));	}
 	/// Fit data along along all directions. Return array with values for found formula.
-	inline mglData Fit3(const mglData &a, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_3(gr, &a, eq, var,0, opt));	}
-	inline mglData Fit3(const mglData &a, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_3(gr, &a, eq, var, &ini, opt));	}
+	inline mglData Fit3(const mglData &a, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_3(gr, &a, eq, vars,0, opt));	}
+	/// Fit data along all directions starting from \a ini values. Return array with values for found formula.
+	inline mglData Fit3(const mglData &a, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_3(gr, &a, eq, vars, &ini, opt));	}
+
 	/// Fit data along x-direction for each data row. Return array with values for found formula.
-	inline mglData Fit(const mglData &x, const mglData &y, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_xy(gr, &x, &y, eq, var,0, opt));	}
-	inline mglData Fit(const mglData &x, const mglData &y, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_xy(gr, &x, &y, eq, var, &ini, opt));	}
+	inline mglData Fit(const mglData &x, const mglData &y, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_xy(gr, &x, &y, eq, vars,0, opt));	}
+	/// Fit data along x-direction for each data row starting from \a ini values. Return array with values for found formula.
+	inline mglData Fit(const mglData &x, const mglData &y, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_xy(gr, &x, &y, eq, vars, &ini, opt));	}
 	/// Fit data along x-, y-directions for each data slice. Return array with values for found formula.
-	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, var,0, opt));	}
-	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, var, &ini, opt));	}
+	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, vars,0, opt));	}
+	/// Fit data along x-, y-directions for each data slice starting from \a ini values. Return array with values for found formula.
+	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, vars, &ini, opt));	}
 	/// Fit data along along all directions. Return array with values for found formula.
-	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq, var,0, opt));	}
-	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq,var, &ini, opt));	}
+	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq, vars,0, opt));	}
+	/// Fit data along along all directions starting from \a ini values. Return array with values for found formula.
+	inline mglData Fit(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq,vars, &ini, opt));	}
+
+	/// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula.
+	inline mglData FitS(const mglData &y, const mglData &s, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_ys(gr, &y, &s, eq, vars,0, opt));	}
+	/// Fit data with dispersion s along x-direction for each data row starting from \a ini values. Return array with values for found formula.
+	inline mglData FitS(const mglData &y, const mglData &s, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_ys(gr, &y, &s, eq, vars, &ini, opt));	}
 	/// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula.
-	inline mglData FitS(const mglData &y, const mglData &s, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_ys(gr, &y, &s, eq, var,0, opt));	}
-	inline mglData FitS(const mglData &y, const mglData &s, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_ys(gr, &y, &s, eq, var, &ini, opt));	}
-	inline mglData FitS(const mglData &x, const mglData &y, const mglData &s, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, var,0, opt));	}
-	inline mglData FitS(const mglData &x, const mglData &y, const mglData &s, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, var, &ini, opt));	}
+	inline mglData FitS(const mglData &x, const mglData &y, const mglData &s, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, vars,0, opt));	}
+	/// Fit data with dispersion s along x-direction for each data row starting from \a ini values. Return array with values for found formula.
+	inline mglData FitS(const mglData &x, const mglData &y, const mglData &s, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, vars, &ini, opt));	}
 	/// Fit data with dispersion s along x-, y-directions for each data slice. Return array with values for found formula.
-	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &s, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, var,0, opt));	}
-	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &s, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, var, &ini, opt));	}
+	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &s, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, vars,0, opt));	}
+	/// Fit data with dispersion s along x-, y-directions for each data slice starting from \a ini values. Return array with values for found formula.
+	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &s, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, vars, &ini, opt));	}
 	/// Fit data with dispersion s along all directions. Return array with values for found formula.
-	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &s, const char *eq, const char *var, const char *opt="")
-	{	return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, var,0, opt));	}
-	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &s, const char *eq, const char *var, mglData &ini, const char *opt="")
-	{	return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, var, &ini, opt));	}
+	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &s, const char *eq, const char *vars, const char *opt="")
+	{	return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, vars,0, opt));	}
+	/// Fit data with dispersion s along all directions starting from \a ini values. Return array with values for found formula.
+	inline mglData FitS(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const mglData &s, const char *eq, const char *vars, mglData &ini, const char *opt="")
+	{	return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, vars, &ini, opt));	}
+
 	/// Print fitted last formula (with coefficients)
 	inline void PutsFit(mglPoint p, const char *prefix=0, const char *font="", double size=-1)
 	{	mgl_puts_fit(gr, p.x, p.y, p.z, prefix, font, size);	}
 	/// Get last fitted formula
-	inline const char *GetFit()
+	inline const char *GetFit()	const
 	{	return mgl_get_fit(gr);	}
-
-	/// Solve PDE with x,y,z in range [Min, Max]
+	/// Get chi for last fitted formula
+	static inline mreal GetFitChi()
+	{	return mgl_get_fit_chi();	}
+	/// Get covariance matrix for last fitted formula
+	static inline mglData GetFitCovar()
+	{	return mglData(mgl_get_fit_covar());	}
+
+	/// Solve PDE with x,y,z in range axis range
 	inline mglData PDE(const char *ham, const mglData &ini_re, const mglData &ini_im, double dz=0.1, double k0=100, const char *opt="")
 	{	return mglData(true,mgl_pde_solve(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
-	/// Fill data by formula with x,y,z in range [Min, Max]
+	/// Solve PDE with x,y,z in range axis range
+	inline mglDataC PDEc(const char *ham, const mglData &ini_re, const mglData &ini_im, double dz=0.1, double k0=100, const char *opt="")
+	{	return mglDataC(true,mgl_pde_solve_c(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
+
+	/// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only)
+	inline mglData APDE(const char *ham, const mglData &ini_re, const mglData &ini_im, double dz=0.1, double k0=100, const char *opt="")
+	{	return mglData(true,mgl_pde_adv(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
+	/// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only)
+	inline mglDataC APDEc(const char *ham, const mglData &ini_re, const mglData &ini_im, double dz=0.1, double k0=100, const char *opt="")
+	{	return mglDataC(true,mgl_pde_adv_c(gr,ham,&ini_re,&ini_im,dz,k0, opt));	}
+
+	/// Fill data by formula with x,y,z in range axis range
 	inline void Fill(mglData &u, const char *eq, const char *opt="")
 	{	mgl_data_fill_eq(gr, &u, eq, 0, 0, opt);	}
 	inline void Fill(mglData &u, const char *eq, const mglData &v, const char *opt="")
 	{	mgl_data_fill_eq(gr, &u, eq, &v, 0, opt);	}
 	inline void Fill(mglData &u, const char *eq, const mglData &v, const mglData &w, const char *opt="")
 	{	mgl_data_fill_eq(gr, &u, eq, &v, &w, opt);	}
-	/// Fill data by formula with x,y,z in range [Min, Max]
+	/// Fill data by formula with x,y,z in range axis range
 	inline void Fill(mglDataC &u, const char *eq, const char *opt="")
 	{	mgl_datac_fill_eq(gr, &u, eq, 0, 0, opt);	}
 	inline void Fill(mglDataC &u, const char *eq, const mglData &v, const char *opt="")
@@ -1228,23 +2075,40 @@ public:
 	inline void Fill(mglDataC &u, const char *eq, const mglData &v, const mglData &w, const char *opt="")
 	{	mgl_datac_fill_eq(gr, &u, eq, &v, &w, opt);	}
 
-	/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range
+	/// Fill dat by interpolated values of vdat parametrically depended on xdat for x in axis range
 	inline void Refill(mglData &dat, const mglData &xdat, const mglData &vdat, long sl=-1, const char *opt="")
 	{	mgl_data_refill_gr(gr,&dat,&xdat,0,0,&vdat,sl,opt);	}
+	/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in axis range
 	inline void Refill(mglData &dat, const mglData &xdat, const mglData &ydat, const mglData &vdat, long sl=-1, const char *opt="")
 	{	mgl_data_refill_gr(gr,&dat,&xdat,&ydat,0,&vdat,sl,opt);	}
+	/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range
 	inline void Refill(mglData &dat, const mglData &xdat, const mglData &ydat, const mglData &zdat, const mglData &vdat, const char *opt="")
 	{	mgl_data_refill_gr(gr,&dat,&xdat,&ydat,&zdat,&vdat,-1,opt);	}
 
-	/// Set the data by triangulated surface values assuming x,y,z in range [Min, Max]
+	/// Fill dat by interpolated values of vdat parametrically depended on xdat for x in axis range
+	inline void Refill(mglDataC &dat, const mglData &xdat, const mglData &vdat, long sl=-1, const char *opt="")
+	{	mgl_datac_refill_gr(gr,&dat,&xdat,0,0,&vdat,sl,opt);	}
+	/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in axis range
+	inline void Refill(mglDataC &dat, const mglData &xdat, const mglData &ydat, const mglData &vdat, long sl=-1, const char *opt="")
+	{	mgl_datac_refill_gr(gr,&dat,&xdat,&ydat,0,&vdat,sl,opt);	}
+	/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range
+	inline void Refill(mglDataC &dat, const mglData &xdat, const mglData &ydat, const mglData &zdat, const mglData &vdat, const char *opt="")
+	{	mgl_datac_refill_gr(gr,&dat,&xdat,&ydat,&zdat,&vdat,-1,opt);	}
+
+	/// Set the data by triangulated surface values assuming x,y,z in range axis range
 	inline void DataGrid(mglData &d, const mglData &x, const mglData &y, const mglData &z, const char *opt="")
 	{	mgl_data_grid(gr,&d,&x,&y,&z,opt);	}
 
 	/// Make histogram (distribution) of data. This function do not plot data.
+	/** Option "value" sets the size of output array (default is mglFitPnts=100). */
 	inline mglData Hist(const mglData &x, const mglData &a, const char *opt="")
 	{	return mglData(true, mgl_hist_x(gr, &x, &a, opt));	}
+	/// Make histogram (distribution) of data. This function do not plot data.
+	/** Option "value" sets the size of output array (default is mglFitPnts=100). */
 	inline mglData Hist(const mglData &x, const mglData &y, const mglData &a, const char *opt="")
 	{	return mglData(true, mgl_hist_xy(gr, &x, &y, &a, opt));	}
+	/// Make histogram (distribution) of data. This function do not plot data.
+	/** Option "value" sets the size of output array (default is mglFitPnts=100). */
 	inline mglData Hist(const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *opt="")
 	{	return mglData(true, mgl_hist_xyz(gr, &x, &y, &z, &a, opt));	}
 
@@ -1300,6 +2164,14 @@ public:
 	/// Get number of defined commands
 	inline long GetCmdNum()
 	{	return mgl_parser_cmd_num(pr);	}
+	/// Load new commands from external dynamic Library (must have "const mglCommand *mgl_cmd_extra" variable)
+	inline void LoadDLL(const char *fname)
+	{	mgl_parser_load(pr, fname);	}
+	/// Apply one step for equation d vars[i]/dt = eqs[i] using Runge-Kutta method
+	inline void RK_Step(const char *eqs, const char *vars, mreal dt=1)
+	{	mgl_rk_step(pr, eqs, vars, dt);	}
+	inline void RK_Step(const wchar_t *eqs, const wchar_t *vars, mreal dt=1)
+	{	mgl_rk_step_w(pr, eqs, vars, dt);	}
 
 	/// Set value for parameter $N
 	inline void AddParam(int id, const char *str)
@@ -1312,6 +2184,8 @@ public:
 	inline void AllowSetSize(bool allow)	{	mgl_parser_allow_setsize(pr, allow);	}
 	/// Allow reading/saving files
 	inline void AllowFileIO(bool allow)		{	mgl_parser_allow_file_io(pr, allow);	}
+	/// Allow loading commands from external libraries
+	inline void AllowDllCall(bool allow)	{	mgl_parser_allow_dll_call(pr, allow);	}
 	/// Set flag to stop script parsing
 	inline void Stop()	{	mgl_parser_stop(pr);	}
 
diff --git a/make_release b/make_release
new file mode 100755
index 0000000..2fe9fe3
--- /dev/null
+++ b/make_release
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Make releases
+
+VER=2.3.4
+LVER=${VER}.LGPL
+BIN=MathGL
+LBIN=MathGL-LGPL
+SRC=/home/balakin/mathgl-code/mathgl-2x
+BSRC=${SRC}/build
+
+mkdir mathgl-${VER}-mingw.i686
+mkdir mathgl-${VER}-mingw.i686/bin/
+cp -p ${BIN}/bin/* mathgl-${VER}-mingw.i686/bin/
+mkdir mathgl-${VER}-mingw.i686/lib/
+cp -p ${BIN}/lib/* mathgl-${VER}-mingw.i686/lib/
+mkdir mathgl-${VER}-mingw.i686/include/
+mkdir mathgl-${VER}-mingw.i686/include/mgl2/
+cp -p ${BIN}/include/mgl2/* mathgl-${VER}-mingw.i686/include/mgl2/
+cp -p ${SRC}/ChangeLog.txt mathgl-${VER}-mingw.i686/
+cp -p ${SRC}/FindMathGL2.cmake mathgl-${VER}-mingw.i686/mathgl2-config.cmake
+7z a mathgl-${VER}-mingw.i686.7z mathgl-${VER}-mingw.i686/
+rm -R mathgl-${VER}-mingw.i686
+
+mkdir mathgl-${LVER}-mingw.i686
+mkdir mathgl-${LVER}-mingw.i686/bin/
+cp -p ${LBIN}/bin/* mathgl-${LVER}-mingw.i686/bin/
+mkdir mathgl-${VER}-mingw.i686/lib/
+cp -p ${LBIN}/lib/* mathgl-${LVER}-mingw.i686/lib/
+mkdir mathgl-${LVER}-mingw.i686/include/
+mkdir mathgl-${LVER}-mingw.i686/include/mgl2/
+cp -p ${LBIN}/include/mgl2/* mathgl-${LVER}-mingw.i686/include/mgl2/
+cp -p ${SRC}/ChangeLog.txt mathgl-${LVER}-mingw.i686/
+cp -p ${SRC}/FindMathGL2.cmake mathgl-${LVER}-mingw.i686/mathgl2-config.cmake
+7z a mathgl-${LVER}-mingw.i686.7z mathgl-${LVER}-mingw.i686/
+rm -R mathgl-${LVER}-mingw.i686
+
+mkdir mgl_scripts-${VER}
+cp -pR ${BIN}/extra/* mgl_scripts-${VER}/
+cp -p ${BIN}/bin/* mgl_scripts-${VER}/
+cp -p ${BIN}/share/mathgl/mgl.cgi.exe mgl_scripts-${VER}/
+cp -p ${BIN}/share/udav/*.qm mgl_scripts-${VER}/
+cp -p ${BSRC}/texinfo/mgl_??.html mgl_scripts-${VER}/
+cp -p ${SRC}/ChangeLog.txt mgl_scripts-${VER}/
+7z a mgl_scripts-${VER}.7z mgl_scripts-${VER}/
+rm -R mgl_scripts-${VER}
+
+cp -p ${BSRC}/texinfo/mathgl_en.pdf mathgl-${VER}.eng.pdf
+cp -p ${BSRC}/texinfo/mgl_en.pdf mgl-${VER}.eng.pdf
+cp -p ${SRC}/ChangeLog.txt ChangeLog-${VER}.txt
+7z a mathgl-doc-html-${VER}.7z ${BSRC}/texinfo/m*html ${BSRC}/texinfo/png/
+
+svn checkout svn://svn.code.sf.net/p/mathgl/code/mathgl-2x/ mathgl-${VER}
+cd mathgl-${VER}
+./clean-svn
+cd ..
+tar -zcf mathgl-${VER}.tar.gz mathgl-${VER}/
+rm -R mathgl-${VER}
diff --git a/mgltex/CMakeLists.txt b/mgltex/CMakeLists.txt
index cac7b7f..28844be 100644
--- a/mgltex/CMakeLists.txt
+++ b/mgltex/CMakeLists.txt
@@ -22,13 +22,23 @@ endif(NOT TEXMFLOCALDIR)
 
 # set(extramgl Axis_projection Vectorial)
 
+add_custom_command(OUTPUT mgltex.sty
+	COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/mgltex/mgltex.ins ${MathGL_BINARY_DIR}/mgltex/
+	COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/mgltex/mgltex.dtx ${MathGL_BINARY_DIR}/mgltex/
+	COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/mgltex/Recompilation_decision.pdf ${MathGL_BINARY_DIR}/mgltex/
+	COMMAND ${findpdflatex} mgltex.ins
+	COMMAND ${findpdflatex} mgltex.dtx
+	COMMAND ${findpdflatex} mgltex.dtx
+	COMMAND ${findpdflatex} mgltex.dtx
+	DEPENDS mgltex.dtx Recompilation_decision.pdf )
+
 add_custom_command(OUTPUT sample.pdf
 	COMMAND ${CMAKE_COMMAND} -E make_directory ${MathGL_BINARY_DIR}/mgltex/MGL
 	COMMAND ${CMAKE_COMMAND} -E make_directory ${MathGL_BINARY_DIR}/mgltex/MGL/scripts
 	COMMAND ${CMAKE_COMMAND} -E make_directory ${MathGL_BINARY_DIR}/mgltex/MGL/backups
 	COMMAND ${CMAKE_COMMAND} -E make_directory ${MathGL_BINARY_DIR}/mgltex/MGL/graphics
 	COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/mgltex/sample.tex ${MathGL_BINARY_DIR}/mgltex/
-	COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/mgltex/mgltex.sty ${MathGL_BINARY_DIR}/mgltex/
+# 	COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/mgltex/mgltex.sty ${MathGL_BINARY_DIR}/mgltex/
 	COMMAND PATH=$<TARGET_FILE_DIR:mglconv> ${findpdflatex} --shell-escape -draftmode sample.tex
 	COMMAND PATH=$<TARGET_FILE_DIR:mglconv> ${findpdflatex} --shell-escape -draftmode sample.tex
 	COMMAND PATH=$<TARGET_FILE_DIR:mglconv> ${findpdflatex} --shell-escape sample.tex
@@ -39,6 +49,6 @@ get_directory_property(mglconv_clean ADDITIONAL_MAKE_CLEAN_FILES)
 set(mglconv_clean ${mglconv_clean} scripts mgltex.sty sample.tex sample.aux sample.log)
 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${mglconv_clean}")
 
-install(FILES mgltex.sty DESTINATION ${TEXMFLOCALDIR}/tex/latex/mgltex/)
+install(FILES ${MathGL_BINARY_DIR}/mgltex/mgltex.sty DESTINATION ${TEXMFLOCALDIR}/tex/latex/mgltex/)
 install(FILES sample.tex mgltex.pdf ${MathGL_BINARY_DIR}/mgltex/sample.pdf DESTINATION ${TEXMFLOCALDIR}/doc/latex/mgltex/)
 install(CODE "execute_process(COMMAND ${findmktexlsr} ${TEXMFLOCALDIR})")
diff --git a/mgltex/mgltex.dtx b/mgltex/mgltex.dtx
index ecdd628..959e117 100644
--- a/mgltex/mgltex.dtx
+++ b/mgltex/mgltex.dtx
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2014--2015 by Diego Sejas Viscarra <diego.mathematician at gmail.com>
-% Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin at gmail.com>
+% Copyright (C) 2014--2016 by Diego Sejas Viscarra <dsejas.mathematics at gmail.com>
+% Copyright (C) 2014--2016 by Alexey Balakin <mathgl.abalakin at 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
@@ -22,14 +22,17 @@
 %
 %<package>
 %<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{mgltex}[2015/11/07 v4.0 Embed MGL scripts into LaTeX documents]
+%<package>\ProvidesPackage{mgltex}[2016/01/28 v4.1 Embed MGL scripts into LaTeX documents]
 %<package>
 %
 %<*driver>
 \documentclass[10pt]{ltxdoc}
 \usepackage{color}
-\IfFileExists{hyperref.sty}{\usepackage{hyperref}}{}
+\IfFileExists{hyperref.sty}{%
+	\usepackage[hidelinks=true]{hyperref}%
+}{}
 \usepackage{mgltex}
+\def\mglTeX{mgl\TeX} % Otherwise, incompatibility with \CharacterTable
 \EnableCrossrefs
 \CodelineIndex
 \RecordChanges
@@ -41,7 +44,8 @@
 %</driver>
 % \fi
 %
-% \CheckSum{1520}
+% \CheckSum{0}
+%
 %
 % \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
@@ -97,7 +101,7 @@
 % \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 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}
@@ -111,16 +115,26 @@
 % \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 at 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}{Remove the \texttt{\textbackslash MGL at setkeys} command, since it isn't needed as first thought}
 % \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}
 %
+% \changes{v4.1}{/2016/01/28}{Add the command \texttt{\textbackslash mglimgext} to specify locally the extension to save the generated graphics}
+% \changes{v4.1}{/2016/01/28}{Add the command \texttt{\textbackslash mglswitch}, which replaces \texttt{\textbackslash mgltexon} and \texttt{\textbackslash mgltexoff}}
+% \changes{v4.1}{/2016/01/28}{Rename the commands \texttt{\textbackslash mgltexon} as \texttt{\textbackslash MGL at switch@on} and \texttt{\textbackslash mgltexoff} as \texttt{\textbackslash MGL at switch@off} in order to avoid the user from unpurposely overwriting them}
+% \changes{v4.1}{/2016/01/28}{The command \texttt{\textbackslash mglcomments} has been reimplemented to accept one mandatory argument: \texttt{\textbackslash mglcomments\{on\}} replaces the old \texttt{\textbackslash mglcomments}, while \texttt{\textbackslash mglcomments\{off\}} replaces the old \texttt{\textbackslash mglnocomments}}
+% \changes{v4.1}{/2016/01/28}{Remove the command \texttt{\textbackslash mglnocomments} (rendered useless by the new implementation of \texttt{\textbackslash mglcomments})}
+% \changes{v4.1}{/2016/01/28}{Remove the command \texttt{\textbackslash mglTeXwVer} (rendered useless by the implementation of the starred version of \texttt{\textbackslash mglTeX})}
+% \changes{v4.1}{/2016/01/28}{Restore the command \texttt{\textbackslash mglsettings}, which was unintentionally deleted in version~4.0}
+% \changes{v4.1}{/2016/01/28}{Expand the key-val list family for the command \texttt{\textbackslash mglsettings}}
+% \changes{v4.1}{/2016/01/28}{Reimplement the \texttt{\textbackslash @MGL at comments@} switch}
+% \changes{v4.1}{/2016/01/28}{A starred version of the command \texttt{\textbackslash mglTeX} has been implemented, which prints the version of the package besides its name}
+%
 % \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{\@flushglue,\@for,\@ifnextchar,\@makeother,\{,\},\ ,\AtBeginDocument,\AtEndDocument,\centering}
 % \DoNotIndex{\closein,\closeout,\csname,\endcsname,\CurrentOption,\DeclareGraphicsExtensions,\define at key,\DeclareOption}
 % \DoNotIndex{\detokenize,\do,\dospecials,\endlinechar,\endlist,\escapechar,\ExecuteOptions,\expandafter,\footnotesize}
 % \DoNotIndex{\framebox,\Gin at extensions,\Huge,\ifeof,\IfFileExists,\ifx,\immediate,\include,\includegraphics,\item,\itemsep}
@@ -128,10 +142,18 @@
 % \DoNotIndex{\obeyspaces,\openin,\openout,\PackageError,\PackageWarning,\parfillskip,\parindent,\parskip}
 % \DoNotIndex{\PassOptionsToPackage,\ProcessOptions,\read,\relax,\RequirePackage,\rightskip,\setcounter,\setkeys,\setlength}
 % \DoNotIndex{\space,\stepcounter,\string,\TeX,\the,\vbox,\verbatim at font,\write,\z@,\z at skip,\newif,\PackageInfo,\today}
-% \DoNotIndex{\obeylines,\or\ifcase,\small}
+% \DoNotIndex{\obeylines,\or,\ifcase,\small,\vskip,\section,\refstepcounter,\protect,\pretolerance,\penalty,\ttfamily}
+% \DoNotIndex{\@@par,\@@,\@M,\@addtofilelist,\@auxout,\@bsphack,\@dottedtocline,\@empty,\@esphack,\@fornoop,\@fortmp}
+% \DoNotIndex{\@gobble,\@ifundefined,\@mkboth,\@namedef,\@nil,\@nnil,\@noitemerr,\@plus,\@pnumwidth,\@secpenalty}
+% \DoNotIndex{\@startsection,\@starttoc,\@tempdima,\@tempswatrue,\@totalleftmargin,\@unknownoptionerror,\@xobeysp}
+% \DoNotIndex{\^,\addcontentsline,\addpenalty,\addvspace,\advance,\begin,\c at tocdepth,\center,\chapter,\cleaders}
+% \DoNotIndex{\endcenter,\everypar,\fbox,\fboxrule,\frenchspacing,\g at addto@macro,\global,\hb at xt@,\hbadness,\hfil,\hfill}
+% \DoNotIndex{\hrule,\hskip,\hss,\if at minipage,\if at tempswa,\ifhmode,\ifnum,\interlinepenalty,\itemindent,\kern,\l at chapter}
+% \DoNotIndex{\l at section,\large,\leavevmode,\MakeUppercase,\newdimen,\nobreak,\nopagebreak,\normalfont,\null,\numberline}
+% \DoNotIndex{\p@,\par,\unpenalty,\usecounter,\@ifstar,\^}
 %
 % \title{The \textsf{\mglTeX} package\thanks{This document corresponds to \textsf{\mglTeX}~\fileversion, dated \filedate.}}
-% \author{Diego Sejas Viscarra\\\texttt{diego.mathematician at gmail.com}}
+% \author{Diego Sejas Viscarra\\\texttt{dsejas.mathematics at gmail.com}}
 %
 % \maketitle
 %
@@ -150,6 +172,21 @@
 %
 % 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.
 %
+% \subsection{Conventions and notations}
+% \noindent For what's left of this manual, the symbols ``$\langle$'' and ``$\rangle$'' will enclose the description of an object that should be placed in that location; this is called a \emph{meta-variable}. For example, $\meta{text}$ is a meta-variable that indicates that in that location should be placed any form of text.
+%
+% In order to save space and time, some special conventions should be applied to meta-variables:
+% \begin{enumerate}
+%   \item Any meta-variable that contain the word \emph{directory} indicates the name of a directory, in the form of an absolute or relative path, ending with the slash (``/'') character.
+%   \item Any meta-variable that contain the word \emph{subdirectory} indicates a relative path ending with the slash (``/'') character.
+%   \item \meta{$x_1\vert x_2\vert\ldots\vert x_n$} indicates that any of the values $x_1$, $x_2$, \ldots, $x_n$ can be placed there.
+%   \item A meta-variable of the form \meta{list of something} or \meta{something list} indicate a comma-separated list of values of type $\meta{something}$; if only one value is used, no comma is needed.
+% \item A meta-variable with underscores (``\_'') in its description indicate that spaces should not be used in that location.
+% \item \meta{key-val list} refers to a list of \meta{key}=\meta{value} pairs of options, where \meta{key} is a keyword name for an option and \meta{value} is a value assigned to it.
+% \end{enumerate}
+%
+% As is conventional for \LaTeX{} packages, the commands and environments of \textsf{\mglTeX{}} accept optional commands inside brackets and mandatory arguments inside curly braces.
+%
 % \section{Usage}
 % \noindent The simplest way to load \textsf{\mglTeX} to a \LaTeX{} document is to write the command
 % \begin{center}
@@ -159,7 +196,7 @@
 % \begin{center}
 % |\usepackage|\oarg{options list}|{mgltex}|,  
 % \end{center}
-% where \meta{options list} is a comma-separated list that can contain one or more of the following options:
+% where \meta{options list} 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|: Overrides the |draft| option.
@@ -206,7 +243,7 @@
 % \end{itemize}
 % 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 re [...]
+% 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 simultaneously, 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 [...]
 %
 % There are two ways to compile a document with \textsf{\mglTeX}: The first way is to run
 % \begin{center}
@@ -244,60 +281,8 @@
 %|\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]
-%     |\mgldir|\marg{\mglTeX{} main directory}\\[0.25em]
-%     \hline
-%   \end{tabular}
-% \end{center}
-% \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]
-%     |\mglscriptsdir|\marg{MGL scripts subdirectory}\\[0.25em]
-%     \hline
-%   \end{tabular}
-% \end{center}
-%
-% \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]
-%     |\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 [...]
-%
-% \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.
+% \DescribeEnv{mgl}\noindent The main environment defined by \textsf{\mglTeX} is |mgl|. It extracts its contents to a main script, called \meta{main\_script\_name}.mgl, where \meta{main\_script\_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]
@@ -380,7 +365,7 @@
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglsetup}|\marg{keyword}\\[0.5em]
+%     |\begin{mglsetup}|\marg{key\_word}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
 %     |\end{mglsetup}|\\[0.25em]
 %     \hline
@@ -405,12 +390,21 @@
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglblock}|\oarg{lineno value}\marg{script\_name}\\[0.5em]
+%     |\begin{mglblock}|\oarg{key-val list}\marg{script\_name}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
 %     |\end{mglblock}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\begin{mglblock*}|\oarg{key-val list}\marg{script\_name}\\[0.5em]
+%       \hss\meta{MGL code}\hss\\[0.5em]
+%     |\end{mglblock*}|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
 % The ouput looks like this:
 % \begin{quote}
 %   \makeatletter
@@ -446,6 +440,15 @@
 %     \hline
 %   \end{tabular}
 % \end{center}
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\begin{mglverbatim*}|\oarg{key-val list}\\[0.5em]
+%       \hss\meta{MGL code}\hss\\[0.5em]
+%     |\end{mglverbatim*}|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
 % The output looks like this without |label|:
 % \begin{quote}
 %   \makeatletter
@@ -500,7 +503,14 @@
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglinclude|\marg{script\_name}\oarg{lineno boolean value}\\[0.25em]
+%     |\mglinclude|\marg{script\_name}\oarg{key-val list}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglinclude*|\marg{script\_name}\oarg{key-val list}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
@@ -524,9 +534,18 @@
 %   \end{tabular}
 % \end{center}
 %
-% 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 [...]
+% The use of this command is encouraged 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, rea [...]
+%
+% \DescribeMacro{\mglimgext} Can be used to specify the extension to save graphics. Its effect is local, meaning that the new quality will be applied from the point this command is used~on.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglimgext|\marg{image extension}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
 %
-% \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:
+% \DescribeMacro{\mglquality} The default quality for the creation of MGL graphics can be specified locally with this command. An info message will be printed in the |.log| file indicating the characteristics of the chosen value, according to the following table:
 % \begin{center}
 %   \DeleteShortVerb{\|}
 %   \begin{tabular}{|c|l|}
@@ -560,7 +579,7 @@
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglquality|\marg{quality value}\\[0.25em]
+%     |\mglquality|\marg{0$\vert$1$\vert$\ldots$\vert$8}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
@@ -569,70 +588,144 @@
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglscale|\marg{scale value}\\[0.25em]
+%     |\mglscale|\marg{1$\vert$2$\vert$\ldots$\vert$9}\\[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.
+% \DescribeMacro{\mglswitch} This command is equivalent to the package options |on| and |off|, depending on the argument passed, but it's effect is local.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mgltexon|\\[0.25em]
+%     |\mglswitch{|\meta{on$\vert$off}|}|\\[0.25em]
 %     \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, but its effect is local.
+% Observe that |\mglswitch{on}| and |\mglswitch{off}| 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 is equivalent to the package options |comments| and |nocomments|, depending on the argument passed, but its effect is local.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mgltexoff|\\[0.25em]
+%     |\mglcomments{|\meta{on$\vert$off$\vert$true$\vert$false}|}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
 %
-% 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{\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.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\listofmglscripts|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% The output is like this:
+% \begin{center}
+%   \begin{minipage}{0.9\textwidth}
+%     \listofmglscripts
+%   \end{minipage}
+% \end{center}
 %
-% \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.
+% \DescribeMacro{\mglTeX}\DescribeMacro{\mglTeX*} This command just pretty-prints the name of the package; if followed by an asterisk, it will also print the version, separated with an unbreakable space.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglcomments|\\[0.25em]
+%     |\mglTeX|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglTeX*|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+%
+% \subsection{Advanced setup commands}
+% \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{\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.
+% \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]
-%     |\mglnocomments|\\[0.25em]
+%     |\mgldir|\marg{main\_directory}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
 %
-% \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. Th [...]
+% \DescribeMacro{\mglscriptsdir} It specifies the subdirectory inside \mglTeX's \meta{main\_directory} where the MGL scripts will be created.
 % \begin{center}
-%   \begin{minipage}{0.9\textwidth}
-%     \listofmglscripts
-%   \end{minipage}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglscriptsdir|\marg{scripts\_subdirectory}\\[0.25em]
+%     \hline
+%   \end{tabular}
 % \end{center}
 %
-% \DescribeMacro{\mglTeX} This command just pretty-prints the name of the package.
+% \DescribeMacro{\mglgraphicsdir} It specifies the subdirectory inside \mglTeX's \meta{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]
-%     |\mglTeX|\\[0.25em]
+%     |\mglgraphicsdir|\marg{graphics\_subdirectory}\\[0.25em]
 %     \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.
+% \DescribeMacro{\mglbackupsdir} It specifies the subdirectory inside \mglTeX's \meta{main\_directory} where backups for the MGL scripts will be created.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\mglTeXwVer|\\[0.25em]
+%     |\mglbackupsdir|\marg{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{main\_directory}; if only |\mgldir| and |\mglscriptsdir| are used, the scripts will be created inside \meta{main\_directory}\meta{scripts\_subdirectory}, while the graphics and backups will be inside \meta{main\_direc [...]
+%
+% \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{directory list}\\[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 or directories to the list of searching paths.
+%
+% \DescribeMacro{mglsettings} This command has been added for the confort of the user, since it handles all of the basic and advanced settings of \textsf{\mglTeX}, as an alternative to some package options and commands. It takes one mandatory argument which should be a list of \meta{key}=\meta{value} pairs, according to the following table:
+% \begin{center}
+%   \DeleteShortVerb{\|}
+%   \begin{tabular}{|l|l|l|}
+%     \hline
+%     \textbf{Key} & \textbf{Value} & \textbf{Description}\\
+%     \hline
+%     \hline
+%     dir & \meta{main\_directory} & The main working directory\\
+%     \hline
+%     scriptsdir & \meta{scripts\_subdirectory} & The subdirectory for scripts creation\\
+%     \hline
+%     graphicsdir & \meta{graphics\_subdirectory} & The subdirectory for graphics creation\\
+%     \hline
+%     backupsdir & \meta{backups\_subdirectory} & The subdirectory for backups creation\\
+%     \hline
+%     paths & \meta{directory list} & Paths to external scripts\\
+%     \hline
+%     quality & \meta{0$\vert$1$\vert$\ldots$\vert$8} & Quality for creation of graphics\\
+%     \hline
+%     scale & \meta{1$\vert$2$\vert$\ldots$\vert$9} & Scale for creation of graphics\\
+%     \hline
+%     imgext & \meta{image extension} & Extension for creation of graphics\\
+%     \hline
+%   \end{tabular}
+%   \MakeShortVerb{\|}
+% \end{center}
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglsettings|\marg{key-val list}\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
@@ -725,7 +818,7 @@
 % \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 scrip [...]
+% This is how the recompilation-decision is performed: When \textsf{\mglTeX} finds an environment or command meant to create a script/graphic, it checks if the command |\MGL@@@|\meta{script} is defined, where \meta{script} is the name of the 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 [...]
 %
 % \begin{figure}[ht!]
 %   \centering
@@ -735,7 +828,7 @@
 %
 % 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  [...]
 %
-% 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 graph [...]
+% 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 |\mglswitch{off}| and |\mglswitch{on}| 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 correspon [...]
 %
 % 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.
 %
@@ -759,23 +852,12 @@
 %    \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 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}
+% The macros |\MGL at switch@on| and |\MGL at switch@off| are called when the package options |on| and |off| are passed, respectively.
+% \begin{macro}{\MGL at switch@on}
 % (Re)defines the commands to open, read, write and close scripts, and the command that includes MGL graphics.
 %    \begin{macrocode}
 
-\def\mgltexon{%
+\def\MGL at switch@on{%
 %    \end{macrocode}
 % \begin{macro}{\MGL at 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.
@@ -866,16 +948,16 @@
   }%
 %    \end{macrocode}
 % \end{macro}
-% And here ends the |\mgltexon| command.
+% And here ends the |\MGL at switch@on| command.
 %    \begin{macrocode}
 }
 %    \end{macrocode}
 % \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 at includegraphics| which, instead of doing nothing, prints a warning framed box (``\textbf{\mglTeX{} is off; no image included}'').
+% \begin{macro}{\MGL at switch@off}
+% (Re)defines the same commands as |\MGL at switch@on| in such a way they accept the same arguments, but do nothing. The exception is |\MGL at includegraphics| which, instead of doing nothing, prints a warning framed box (``\textbf{\mglTeX{} is off; no image included}'').
 %    \begin{macrocode}
-\def\mgltexoff{%
+\def\MGL at switch@off{%
   \PackageWarning{mgltex}{mglTeX is off}%
   \def\MGL at openout##1##2{}%
   \def\MGL at openin##1##2{}%
@@ -893,35 +975,15 @@
 }
 %    \end{macrocode}
 % \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 at comments@}
+% \begin{macro}{\@MGL at comments@on}\begin{macro}{\@MGL at comments@off}
 % We will need a boolean switch to activate/deactivate commentaries later.
 %    \begin{macrocode}
 
-\newif\if at MGL@comments@
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglnocomments} Declares |\@MGL at comments@| as false.
-%    \begin{macrocode}
-\def\mglnocomments{\@MGL at comments@false}
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglcomments} Declares |\@MGL at comments@| as true.
-%    \begin{macrocode}
-\def\mglcomments{\@MGL at comments@true}
-%    \end{macrocode}
-% \end{macro}
-% Now, the options call the respective commands.
-%    \begin{macrocode}
-\DeclareOption{nocomments}{\mglnocomments}
-\DeclareOption{comments}{\mglcomments}
+\def\@MGL at comments@on{\let\if at MGL@comments@\iftrue}
+\def\@MGL at comments@off{\let\if at mglcomments@\iffalse}
 %    \end{macrocode}
+% \end{macro}\end{macro}
 %
 % \begin{macro}{\mglscale}\begin{macro}{\MGL at scale}
 % |\mglscale| sets the value of the |\MGL at 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 at 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 overwrit [...]
@@ -938,18 +1000,6 @@
 }
 %    \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 at quality}
 % |\mglquality| sets the value of the |\MGL at 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 at quality| macro to that value and test it with the |\ifcase| conditional; if the value is valid, we print an [...]
@@ -1002,6 +1052,39 @@
   \fi%
 }
 %    \end{macrocode}
+%
+% 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}
+% Now we can declare the package options |on| and |off| so that they execute |\MGL at switch@on| and |\MGL at switch@off|, respectively.
+%    \begin{macrocode}
+\DeclareOption{on}{\MGL at switch@on}
+\DeclareOption{off}{\MGL at switch@off}
+%    \end{macrocode}
+% Now, the options call the respective commands.
+%    \begin{macrocode}
+\DeclareOption{nocomments}{\@MGL at comments@off}
+\DeclareOption{comments}{\@MGL at comments@on}
+%    \end{macrocode}
+% 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}
 % The package options |0q|, \ldots, |8q| just call |\mglquality| with the appropiate value.
 %    \begin{macrocode}
 \DeclareOption{0q}{\mglquality{0}}
@@ -1054,13 +1137,6 @@
 \RequirePackage{graphicx}
 \RequirePackage{verbatim}
 %    \end{macrocode}
-% The supported graphic formats are declared, and the |\verbatim at 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 at finish\relax
-%    \end{macrocode}
 %
 % \begin{macro}{\MGL at 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 at graph@keys| macro, which is later passed to that command as optional argument by |\MGL at includegraphics|.
@@ -1109,14 +1185,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\MGL at main@script at 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}
-
-\edef\MGL at main@script at name{\jobname}
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\MGL at 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}
@@ -1148,6 +1216,32 @@
 \def\MGL at paths{\MGL at dir\MGL at scripts@dir,\MGL at dir\MGL at backups@dir}
 %    \end{macrocode}
 % \end{macro}
+% \begin{macro}{\mglsettings}
+% First, we define a \meta{key}=\meta{value} family, |MGL at sett@keys|, for the |\mglsettings| command.
+%    \begin{macrocode}
+\define at key{MGL at sett@keys}{dir}{\def\MGL at dir{#1}}
+\define at key{MGL at sett@keys}{scriptsdir}{\def\MGL at scripts@dir{#1}}
+\define at key{MGL at sett@keys}{graphicsdir}{\def\MGL at graphics@dir{#1}}
+\define at key{MGL at sett@keys}{backupsdir}{\def\MGL at backups@dir{#1}}
+\define at key{MGL at sett@keys}{paths}{\g at addto@macro\MGL at paths{,#1}}
+\define at key{MGL at sett@keys}{quality}{\mglquality{#1}}
+\define at key{MGL at sett@keys}{scale}{\mglscale{#1}}
+\define at key{MGL at sett@keys}{imgext}{\def\MGL at graph@ext{.#1}}
+%    \end{macrocode}
+% The command receives and executes the \meta{key}=\meta{value} pairs for |MGL at sett@keys|. This is an only-preamble command.
+%    \begin{macrocode}
+\def\mglsettings#1{\setkeys{MGL at sett@keys}{#1}}
+\@onlypreamble\mglsettings
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MGL at main@script at 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}
+
+\edef\MGL at main@script at name{\jobname}
+%    \end{macrocode}
+% \end{macro}
 %
 % We set some additional staff that will be used later.
 % \begin{macro}{\MGL at main@stream}
@@ -1194,17 +1288,24 @@
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\l at MGL@script}
-% Finally, the style for the leaders associating script name and page number in the \emph{list of MGL scripts}.
+% The style for the leaders associating script name and page number in the \emph{list of MGL scripts}.
 %    \begin{macrocode}
 \def\l at MGL@script{\@dottedtocline{1}{0em}{1.5em}}
 %    \end{macrocode}
 % \end{macro}
+% Finally, the supported graphic formats are declared, and the |\verbatim at 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 at finish\relax
+%    \end{macrocode}
 %
 % \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 at setkeys}
-% This command recieves two arguments: a family of \meta{key}=\meta{value} pairs, like |MGL at keys|, and a list of such pairs. It first cleans the |\MGL at graph@keys| macro, and the process the list of pairs.
+% This command receives two arguments: a family of \meta{key}=\meta{value} pairs, like |MGL at keys|, and a list of such pairs. It first cleans the |\MGL at graph@keys| macro, and the process the list of pairs.
 %    \begin{macrocode}
 
 \def\MGL at setkeys#1#2{%
@@ -1233,7 +1334,7 @@
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\MGL at set@script at name}\begin{macro}{\MGL at script@name}
-% |\MGL at set@script at name| recieves the name of a script without extension as argument, defines |\MGL at 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 at document@scripts|; if it's there already, warns the user. Finally, adds the name of the script to |\MGL at document@scripts|.
+% |\MGL at set@script at name| receives the name of a script without extension as argument, defines |\MGL at 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 at document@scripts|; if it's there already, warns the user. Finally, adds the name of the script to |\MGL at document@scripts|.
 %    \begin{macrocode}
 \def\MGL at set@script at name#1{%
   \edef\MGL at script@name{#1}%
@@ -1459,7 +1560,7 @@
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\MGL at dash@sep}
-% This is the separator displayed at the begginning and ending of the |mglcomments| environment, when it is allowed to be displayed.
+% This is the separator displayed at the beginning and ending of the |mglcomments| environment, when it is allowed to be displayed.
 %    \begin{macrocode}
 \def\MGL at dash@sep{%
   \nopagebreak%
@@ -1503,23 +1604,23 @@
 %    \begin{macrocode}
   \MGL at codes%
 %    \end{macrocode}
-% |\MGL at 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 at write@script| command to (re)write the code; otherwise, the code is scanned again by asking |\MGL at compare@code| to perform a comparison on the backup file, in order to determine whether the code has changed now.
+% |\MGL at 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 at write@script| command to (re)write the code; otherwise, the code is scanned again by asking |\MGL at compare@code| to perform a comparison on the backup file, in order to determine whether the code has changed now.
 %    \begin{macrocode}
   \MGL at process@script{%
-    \mgl at write@script%
+    \MGL at write@script%
   }{%
     \MGL at compare@code{\MGL at dir\MGL at backups@dir\MGL at script@name.mgl}%
   }%
 }
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\mgl at write@script}
+% \begin{macro}{\MGL at write@script}
 % (Re)writes the contents of the |mgl| environment.
 %    \begin{macrocode}
-\def\mgl at write@script{%
+\def\MGL at write@script{%
 %    \end{macrocode}
 % \begin{macro}{\MGL at next}
-% It contains the actions to perform immediately after the end of |\mgl at 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 at unchanged{\MGL at script@name}| in the |.aux| file.
+% It contains the actions to perform immediately after the end of |\MGL at 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 at unchanged{\MGL at script@name}| in the |.aux| file.
 %    \begin{macrocode}
   \def\MGL at next{%
     \MGL at closeout\MGL at out@stream%
@@ -1553,7 +1654,7 @@
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\endmgl}
-% The command that ends the |mgl| evironment. It is called by the |\end{mgl}| command. It simply calls |\MGL at next| to execute the final actions, and |\MGL at includegraphics| to insert the corresponding image. Note that |\MGL at next| performs different actions depending on whether |\MGL at process@script| calls |\mgl at write@script| or |\MGL at compare@code|, both of which define |\MGL at next| differently.
+% The command that ends the |mgl| evironment. It is called by the |\end{mgl}| command. It simply calls |\MGL at next| to execute the final actions, and |\MGL at includegraphics| to insert the corresponding image. Note that |\MGL at next| performs different actions depending on whether |\MGL at process@script| calls |\MGL at write@script| or |\MGL at compare@code|, both of which define |\MGL at next| differently.
 %    \begin{macrocode}
 \def\endmgl{%
   \MGL at next%
@@ -2449,6 +2550,58 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\mglswitch}
+% This command turns |on| and |off| the package according to its argument; it is just a call to the commands |\MGL at switch@on| or |\MGL at switch@off|.
+%    \begin{macrocode}
+\def\mglswitch#1{\csname MGL at switch@#1\endcsname}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mglcomments} Depending on the option passed by the user, it calls |\@MGL at comments@on| or |\@MGL at comments@off|.
+%    \begin{macrocode}
+\def\mglcomments#1{\csname @MGL at comments@#1\endcsname}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mgldir}
+% This command is the interface for the user to change the value of |\MGL at dir|. It is an only-preamble macro, since using it elsewhere would cause faulty behavior.
+%    \begin{macrocode}
+
+\def\mgldir#1{\def\MGL at dir{#1}}\@onlypreamble\mgldir
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglscriptsdir}
+% This command modifies the value of |\MGL at scripts@dir|. It is also an only-preamble macro.
+%    \begin{macrocode}
+\def\mglscriptsdir#1{\def\MGL at scripts@dir{#1}}\@onlypreamble\mglscriptsdir
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglgraphicsdir}
+% Modifies the value of |\MGL at graphics@dir|. It is an only-preamble macro.
+%    \begin{macrocode}
+\def\mglgraphicsdir#1{\def\MGL at graphics@dir{#1}}\@onlypreamble\mglgraphicsdir
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglbackupsdir}
+% Modifies the value of |\MGL at backups@dir|. It is an only-preamble macro.
+%    \begin{macrocode}
+\def\mglbackupsdir#1{\def\MGL at 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 at paths|).
+%    \begin{macrocode}
+\def\mglpaths#1{\g at addto@macro\MGL at paths{,#1}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mglimgext}
+% This command changes the value of |\MGL at graph@ext|.
+%    \begin{macrocode}
+\def\mglimgext#1{\def\MGL at graph@ext{#1}}
+%    \end{macrocode}
+% \end{macro}
+%
 % \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 at chapter| command or it only the |\l at 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}
@@ -2471,7 +2624,7 @@
 % We use the |\@mkboth| command to set the page marks according to the current page style.
 %    \begin{macrocode}
       \@mkboth{%
-        \MakeUpperCase\listofmglscriptsname%
+        \MakeUppercase\listofmglscriptsname%
       }{%
         \MakeUppercase\listofmglscriptsname%
       }%
@@ -2519,7 +2672,7 @@
   \def\listofmglscripts{%
     \chapter*{\listofmglscriptsname}%
     \@mkboth{%
-      \MakeUpperCase\listofmglscriptsname%
+      \MakeUppercase\listofmglscriptsname%
     }{%
       \MakeUppercase\listofmglscriptsname%
     }%
@@ -2529,53 +2682,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\mglTeX}
-% This macro pretty-prints the name of the package.
-%    \begin{macrocode}
-
-\def\mglTeX{mgl\TeX}
-%    \end{macrocode}
-% \end{macro}
-% \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\mglTeXwVer{\mglTeX~v4.0}
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\mgldir}
-% This command is the interface for the user to change the value of |\MGL at dir|. It is an only-preamble macro, since using it elsewhere would cause faulty behavior.
-%    \begin{macrocode}
-
-\def\mgldir#1{\def\MGL at dir{#1}}\@onlypreamble\mgldir
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglscriptsdir}
-% This command modifies the value of |\MGL at scripts@dir|. It is also an only-preamble macro.
-%    \begin{macrocode}
-\def\mglscriptsdir#1{\def\MGL at scripts@dir{#1}}\@onlypreamble\mglscriptsdir
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglgraphicsdir}
-% Modifies the value of |\MGL at graphics@dir|. It is an only-preamble macro.
-%    \begin{macrocode}
-\def\mglgraphicsdir#1{\def\MGL at graphics@dir{#1}}\@onlypreamble\mglgraphicsdir
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}{\mglbackupsdir}
-% Modifies the value of |\MGL at backups@dir|. It is an only-preamble macro.
-%    \begin{macrocode}
-\def\mglbackupsdir#1{\def\MGL at 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 at paths|).
-%    \begin{macrocode}
-\def\mglpaths#1{\g at addto@macro\MGL at 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}
 
@@ -2590,6 +2696,16 @@
 %    \end{macrocode}
 % \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
 %
+% \begin{macro}{\mglTeX}
+% This macro pretty-prints the name of the package. It has a starred version, which also prints the version.
+%    \begin{macrocode}
+
+\def\mglTeX{%
+  mgl\TeX\@ifstar{~v4.1}{}%
+}
+%    \end{macrocode}
+% \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.
 %
diff --git a/mgltex/mgltex.ins b/mgltex/mgltex.ins
index 8dc591b..f58fa72 100644
--- a/mgltex/mgltex.ins
+++ b/mgltex/mgltex.ins
@@ -25,8 +25,8 @@
 
 This is a generated file.
 
-Copyright (C) 2014--2015 by Diego Sejas Viscarra <diego.mathematician at gmail.com>
-Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin at gmail.com>
+Copyright (C) 2014--2016 by Diego Sejas Viscarra <dsejas.mathematics at gmail.com>
+Copyright (C) 2014--2016 by Alexey Balakin <mathgl.abalakin at 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
diff --git a/mgltex/mgltex.pdf b/mgltex/mgltex.pdf
index fe33fb9..296f42e 100644
Binary files a/mgltex/mgltex.pdf and b/mgltex/mgltex.pdf differ
diff --git a/mgltex/mgltex.sty b/mgltex/mgltex.sty
deleted file mode 100644
index 73fa21c..0000000
--- a/mgltex/mgltex.sty
+++ /dev/null
@@ -1,882 +0,0 @@
-%%
-%% 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 at gmail.com>
-%% Copyright (C) 2014--2015 by Alexey Balakin <mathgl.abalakin at 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/>.
-%% 
-
-\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{mgltex}[2015/11/02 v4.0 Embed MGL scripts into LaTeX documents]
-
-\def\MGL at TeX@ext{.tex}
-
-\DeclareOption{draft}{%
-  \PassOptionsToPackage{\CurrentOption}{graphicx}%
-}
-\DeclareOption{final}{%
-  \PassOptionsToPackage{\CurrentOption}{graphicx}%
-}
-
-\def\mgltexon{%
-  \def\MGL at openout##1##2{%
-    \immediate\openout##1="##2"%
-  }%
-  \def\MGL at openin##1##2{%
-    \immediate\openin##1="##2"%
-  }%
-  \def\MGL at write##1##2{%
-    \immediate\write##1{##2}%
-  }%
-  \def\MGL at read##1##2{%
-    \def##2{}%
-    \ifeof##1\else%
-      \bgroup%
-      \endlinechar=-1%
-      \immediate\global\read##1 to ##2%
-      \egroup%
-    \fi%
-  }%
-  \def\MGL at closeout##1{%
-    \immediate\closeout##1%
-  }
-  \def\MGL at closein##1{%
-    \immediate\closein##1%
-  }
-  \def\MGL at includegraphics{%
-    \IfFileExists{\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext}{%
-      \ifx\MGL at graph@ext\MGL at TeX@ext%
-        \include{\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext}%
-      \else%
-        \expandafter\includegraphics\expandafter[\MGL at graph@keys]{%
-          \MGL at dir\MGL at graphics@dir\MGL at script@name%
-        }%
-      \fi%
-    }{%
-      \PackageWarning{mgltex}{MGL image "\MGL at script@name" not found}%
-      \fbox{%
-        \centering%
-        \bfseries\Huge%
-        \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
-      }%
-    }%
-  }%
-}
-\def\mgltexoff{%
-  \PackageWarning{mgltex}{mglTeX is off}%
-  \def\MGL at openout##1##2{}%
-  \def\MGL at openin##1##2{}%
-  \def\MGL at write##1##2{}%
-  \def\MGL at read##1##2{}%
-  \def\MGL at closeout##1{}
-  \def\MGL at closein##1{}
-  \def\MGL at includegraphics{%
-    \fbox{%
-      \centering%
-      \bfseries\Huge%
-      \begin{tabular}{c}\mglTeX\\is off;\\no image\\included\end{tabular}%
-    }%
-  }%
-}
-\DeclareOption{on}{\mgltexon}
-\DeclareOption{off}{\mgltexoff}
-
-\newif\if at MGL@comments@
-\def\mglnocomments{\@MGL at comments@false}
-\def\mglcomments{\@MGL at comments@true}
-\DeclareOption{nocomments}{\mglnocomments}
-\DeclareOption{comments}{\mglcomments}
-
-\def\mglscale#1{
-  \def\MGL at scale{#1}%
-  \ifcase\MGL at scale\or\or\or\or\or\or\or\or\else%
-    \PackageWarning{mgltex}{%
-      Scaling value of \MGL at scale\space not allowed; using default (1)%
-    }%
-    \def\MGL at 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}}
-
-\def\mglquality#1{%
-  \def\MGL at quality{#1}%
-  \ifcase\MGL at 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 at 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 at graph@ext{.eps}}
-\DeclareOption{epsz}{\def\MGL at graph@ext{.epsz}}
-\DeclareOption{epsgz}{\def\MGL at graph@ext{.eps.gz}}
-\DeclareOption{bps}{\def\MGL at graph@ext{.bps}}
-\DeclareOption{bpsz}{\def\MGL at graph@ext{.bpsz}}
-\DeclareOption{bpsgz}{\def\MGL at graph@ext{.bps.gz}}
-\DeclareOption{pdf}{\def\MGL at graph@ext{.pdf}}
-\DeclareOption{png}{\def\MGL at graph@ext{.png}}
-\DeclareOption{jpg}{\def\MGL at graph@ext{.jpg}}
-\DeclareOption{jpeg}{\def\MGL at graph@ext{.jpeg}}
-\DeclareOption{gif}{\def\MGL at graph@ext{.gif}}
-\DeclareOption{tex}{\def\MGL at graph@ext{.tex}}
-
-\DeclareOption*{\@unknownoptionerror}
-
-\ExecuteOptions{final,on,nocomments,1x,2q,eps}
-\ProcessOptions*
-
-\RequirePackage{keyval}
-\RequirePackage{graphicx}
-\RequirePackage{verbatim}
-\DeclareGraphicsExtensions{%
-  .eps,.epsz,.eps.gz,.bps,.bpsz,.bps.gz,.pdf,.png,.jpg,.jpeg,.gif%
-}
-\let\verbatim at finish\relax
-
-\define at key{MGL at keys}{bb}{\g at addto@macro\MGL at graph@keys{bb=#1,}}
-\define at key{MGL at keys}{bbllx}{\g at addto@macro\MGL at graph@keys{bbllx=#1,}}
-\define at key{MGL at keys}{bblly}{\g at addto@macro\MGL at graph@keys{bblly=#1,}}
-\define at key{MGL at keys}{bburx}{\g at addto@macro\MGL at graph@keys{bburx=#1,}}
-\define at key{MGL at keys}{bbury}{\g at addto@macro\MGL at graph@keys{bbury=#1,}}
-\define at key{MGL at keys}{natwidth}{\g at addto@macro\MGL at graph@keys{natwidth=#1,}}
-\define at key{MGL at keys}{natheight}{\g at addto@macro\MGL at graph@keys{natheight=#1,}}
-\define at key{MGL at keys}{hiresbb}{\g at addto@macro\MGL at graph@keys{hiresbb=#1,}}
-\define at key{MGL at keys}{viewport}{\g at addto@macro\MGL at graph@keys{viewport=#1,}}
-\define at key{MGL at keys}{trim}{\g at addto@macro\MGL at graph@keys{trim=#1,}}
-\define at key{MGL at keys}{angle}{\g at addto@macro\MGL at graph@keys{angle=#1,}}
-\define at key{MGL at keys}{origin}{\g at addto@macro\MGL at graph@keys{origin=#1,}}
-\define at key{MGL at keys}{width}{\g at addto@macro\MGL at graph@keys{width=#1,}}
-\define at key{MGL at keys}{height}{\g at addto@macro\MGL at graph@keys{height=#1,}}
-\define at key{MGL at keys}{totalheight}{\g at addto@macro\MGL at graph@keys{totalheight=#1,}}
-\define at key{MGL at keys}{keepaspectratio}[true]{%
-  \g at addto@macro\MGL at graph@keys{keepaspectratio=#1,}%
-}
-\define at key{MGL at keys}{scale}{\g at addto@macro\MGL at graph@keys{scale=#1,}}
-\define at key{MGL at keys}{clip}[true]{\g at addto@macro\MGL at graph@keys{clip=#1,}}
-\define at key{MGL at keys}{draft}[true]{\g at addto@macro\MGL at graph@keys{draft=#1,}}
-\define at key{MGL at keys}{type}{\g at addto@macro\MGL at graph@keys{type=#1,}}
-\define at key{MGL at keys}{ext}{\g at addto@macro\MGL at graph@keys{ext=#1,}}
-\define at key{MGL at keys}{read}{\g at addto@macro\MGL at graph@keys{read=#1,}}
-\define at key{MGL at keys}{command}{\g at addto@macro\MGL at graph@keys{command=#1,}}
-\define at key{MGL at keys}{imgext}{\def\MGL at graph@ext{.#1}}
-
-\newif\if at MGL@lineno@
-\define at key{MGL at verb@keys}{lineno}[true]{\csname @MGL at lineno@#1\endcsname}
-
-\edef\MGL at main@script at name{\jobname}
-
-\def\MGL at dir{}
-\def\MGL at scripts@dir{}
-\def\MGL at graphics@dir{}
-\def\MGL at backups@dir{}
-\def\MGL at paths{\MGL at dir\MGL at scripts@dir,\MGL at dir\MGL at backups@dir}
-
-\newwrite\MGL at main@stream
-\newwrite\MGL at out@stream
-\newread\MGL at in@stream
-\newcounter{MGL at script@no}
-\newcounter{MGL at line@no}
-\newcounter{MGL at verb@script at no}
-\newif\if at MGL@list at script@
-\def\l at MGL@script{\@dottedtocline{1}{0em}{1.5em}}
-
-\def\MGL at setkeys#1#2{%
-  \def\MGL at graph@keys{}%
-  \setkeys{#1}{#2}%
-}
-
-\def\MGL at codes{%
-  \let\do\@makeother\dospecials%
-  \catcode`\^^M\active%
-}
-
-\def\MGL at document@scripts{}
-\def\MGL at set@script at name#1{%
-  \edef\MGL at script@name{#1}%
-  \@for\MGL at temp@a:=\MGL at document@scripts\do{%
-    \ifx\MGL at temp@a\MGL at script@name%
-      \PackageWarning{mgltex}{Multiple MGL scripts named "\MGL at script@name.mgl"}%
-    \fi%
-  }%
-  \g at addto@macro\MGL at document@scripts{\MGL at script@name,}%
-}
-
-\def\MGL at unchanged#1{%
-  \global\@namedef{MGL@@@#1}{}%
-}
-
-\def\MGL at process@script#1#2{%
-  \@ifundefined{MGL@@@\MGL at script@name}{%
-    #1%
-  }{%
-    \IfFileExists{\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext}{%
-      #2%
-    }{%
-      #1%
-    }%
-  }%
-}
-
-\def\MGL at def@for at loop#1{%
-  \long\def\MGL at for##1:=##2\do##3{%
-    \expandafter\def\expandafter\@fortmp\expandafter{##2}%
-    \ifx\@fortmp\@empty\else%
-      \expandafter\MGL at forloop##2#1\@nil#1\@nil\@@##1{##3}%
-    \fi%
-  }%
-  \long\def\MGL at 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 at iforloop##3\@@##4{##5}%
-      \fi%
-    \fi%
-  }%
-  \long\def\MGL at iforloop##1#1##2\@@##3##4{%
-    \def##3{##1}%
-    \ifx##3\@nnil%
-      \expandafter\@fornoop%
-    \else%
-      ##4\relax\expandafter\MGL at iforloop%
-    \fi%
-    ##2\@@##3{##4}%
-  }%
-}
-\MGL at def@for at loop{^^J}
-
-\def\MGL at compare@code#1{%
-  \def\MGL at next{%
-    \MGL at closein\MGL at in@stream%
-    \MGL at write\@auxout{\string\MGL at unchanged{\MGL at script@name}}%
-  }%
-  \def\verbatim at processline{%
-    \MGL at read\MGL at in@stream{\MGL at temp@a}%
-    \edef\MGL at temp@b{\the\verbatim at line}%
-    \ifx\MGL at temp@a\MGL at temp@b\else%
-      \def\MGL at next{\MGL at closein\MGL at in@stream}%
-      \def\verbatim at processline{}%
-    \fi%
-  }%
-  \def\verbatim at finish{%
-    \MGL at read\MGL at in@stream{\MGL at temp@a}%
-    \ifeof\MGL at in@stream\else%
-      \def\MGL at next{\MGL at closein\MGL at in@stream}%
-    \fi%
-  }%
-  \MGL at openin\MGL at in@stream{#1}%
-  \verbatim at start%
-}
-
-\def\MGL at write@funcs{\MGL at write\MGL at main@stream{stop^^J}}
-\def\MGL at func#1{%
-  \MGL at openin\MGL at in@stream{\MGL at dir\MGL at backups@dir#1.mgl}%
-  \MGL@@func%
-}
-\def\MGL@@func{%
-  \MGL at read\MGL at in@stream{\MGL at temp@a}%
-  \ifeof\MGL at in@stream%
-    \MGL at closein\MGL at in@stream%
-  \else%
-    \MGL at write\MGL at main@stream{\MGL at temp@a}%
-    \expandafter\MGL@@func%
-  \fi%
-}
-
-\def\MGL at set@verbatim at code{%
-  \if at minipage\else\vskip\parskip\fi%
-  \leftskip\@totalleftmargin\rightskip\z at skip%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@%
-  \@@par%
-  \def\par{%
-    \if at tempswa%
-      \leavevmode\null\@@par\penalty\interlinepenalty%
-    \else%
-      \@tempswatrue%
-      \ifhmode\@@par\penalty\interlinepenalty\fi%
-    \fi%
-  }%
-  \obeylines%
-  \let\do\@makeother\dospecials%
-  \verbatim at 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 at line@sep{\leavevmode\cleaders\hrule height\mgllinethickness\hfill\kern\z@}
-\def\MGL at dash@sep{\leavevmode\cleaders\hb at xt@\mgldashwidth{\hss-\hss}\hfill\kern\z@}
-
-\newcommand\mgl[1][]{%
-  \define at key{MGL at keys}{label}{\def\MGL at script@name{##1}}%
-  \MGL at setkeys{MGL at keys}{#1}%
-  \@ifundefined{MGL at script@name}{%
-    \stepcounter{MGL at script@no}%
-    \edef\MGL at script@name{\MGL at main@script at name-MGL-\arabic{MGL at script@no}}%
-  }{}%
-  \MGL at set@script at name{\MGL at script@name}%
-  \MGL at codes%
-  \MGL at process@script{%
-    \mgl at write@script%
-  }{%
-    \MGL at compare@code{\MGL at dir\MGL at backups@dir\MGL at script@name.mgl}%
-  }%
-}
-\def\mgl at write@script{%
-  \def\MGL at next{%
-    \MGL at closeout\MGL at out@stream%
-    \MGL at write\MGL at main@stream{%
-      write '\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext'^^J%
-      ^^Jreset^^J%
-    }%
-    \MGL at write\@auxout{\string\MGL at unchanged{\MGL at script@name}}%
-  }%
-  \def\verbatim at processline{%
-    \MGL at write\MGL at main@stream{\the\verbatim at line}%
-    \MGL at write\MGL at out@stream{\the\verbatim at line}%
-  }%
-  \MGL at write\MGL at main@stream{quality \MGL at quality}%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at backups@dir\MGL at script@name.mgl}%
-  \verbatim at start%
-}
-\def\endmgl{%
-  \MGL at next%
-  \MGL at includegraphics%
-}
-
-\def\mgladdon{%
-  \@bsphack%
-  \MGL at codes%
-  \def\verbatim at processline{%
-    \MGL at write\MGL at main@stream{\the\verbatim at line}%
-  }%
-  \verbatim at start%
-}
-\def\endmgladdon{\@esphack}
-
-\newcommand\mglfunc[2][0]{%
-  \@bsphack%
-  \MGL at set@script at name{#2}%
-  \g at addto@macro\MGL at write@funcs{\MGL at func{#2}}%
-  \MGL at codes%
-  \def\verbatim at processline{\MGL at write\MGL at out@stream{\the\verbatim at line}}%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at backups@dir\MGL at script@name.mgl}%
-  \MGL at write\MGL at out@stream{func '\MGL at script@name' #1}%
-  \verbatim at start%
-}
-\def\endmglfunc{%
-  \MGL at write\MGL at out@stream{return^^J}%
-  \MGL at closeout\MGL at out@stream%
-  \@esphack%
-}%
-
-\newcommand\mglcode[2][]{%
-  \MGL at setkeys{MGL at keys}{#1}%
-  \MGL at set@script at name{#2}%
-  \MGL at codes%
-  \MGL at process@script{%
-    \mglcode at write@script%
-  }{%
-    \MGL at compare@code{\MGL at dir\MGL at scripts@dir\MGL at script@name.mgl}%
-  }%
-}
-\def\mglcode at write@script{%
-  \def\MGL at next{%
-    \MGL at closeout\MGL at out@stream%
-    \MGL at write\@auxout{\string\MGL at unchanged{\MGL at script@name}}%
-    \MGL at write{18}{%
-      mglconv -q \MGL at quality\space -S \MGL at scale\space%
-      -s "\MGL at dir\MGL at scripts@dir\mglcommonscriptname.mgl"\space%
-      -o "\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext"\space%
-      "\MGL at dir\MGL at scripts@dir\MGL at script@name.mgl"%
-    }%
-  }%
-  \def\verbatim at processline{\MGL at write\MGL at out@stream{\the\verbatim at line}}%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at scripts@dir\MGL at script@name.mgl}%
-  \verbatim at start%
-}
-\def\endmglcode{%
-  \MGL at next%
-  \MGL at includegraphics%
-}
-
-\def\mglscript#1{%
-  \@bsphack%
-  \MGL at set@script at name{#1}%
-  \MGL at codes%
-  \def\verbatim at processline{\MGL at write\MGL at out@stream{\the\verbatim at line}}%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at scripts@dir\MGL at script@name.mgl}%
-  \verbatim at start%
-}
-\def\endmglscript{%
-  \MGL at closeout\MGL at out@stream%
-  \@esphack%
-}
-
-\def\mglcommon{%
-  \@bsphack%
-  \MGL at set@script at name{\mglcommonscriptname}%
-  \MGL at codes%
-  \def\verbatim at processline{\MGL at write\MGL at out@stream{\the\verbatim at line}}%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at scripts@dir\MGL at script@name.mgl}%
-  \verbatim at start%
-}
-\@onlypreamble\mglcommon
-\def\endmglcommon{%
-  \MGL at closeout\MGL at out@stream%
-  \@esphack%
-}
-
-\def\mglsetup#1{\mglfunc{#1}}%
-\let\endmglsetup\endmglfunc
-
-\newcommand\mglplot[2][]{%
-  \define at key{MGL at keys}{label}{\edef\MGL at script@name{##1}}%
-  \define at key{MGL at keys}{setup}{\def\MGL at mglplot@setup{##1}}%
-  \define at key{MGL at keys}{separator}{%
-    \MGL at def@for at loop{##1}%
-  }%
-  \MGL at setkeys{MGL at keys}{#1}%
-  \@ifundefined{MGL at script@name}{%
-    \stepcounter{MGL at script@no}
-    \edef\MGL at script@name{\MGL at main@script at name-MGL-\arabic{MGL at script@no}}
-  }{}%
-  \MGL at set@script at name{\MGL at script@name}%
-  \@ifundefined{MGL at mglplot@setup}{%
-    \edef\MGL at temp@a{#2}%
-  }{%
-    \edef\MGL at temp@a{call '\MGL at mglplot@setup'^^J#2}%
-  }
-  \MGL at process@script{%
-    \mglplot at write@script%
-  }{%
-    \mglplot at compare@code%
-  }%
-  \MGL at includegraphics%
-}
-\def\mglplot at write@script{%
-  \MGL at write\MGL at main@stream{quality \MGL at quality}%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at backups@dir\MGL at script@name.mgl}%
-  \MGL at for\MGL at temp@b:=\MGL at temp@a\do{%
-    \MGL at write\MGL at main@stream{\MGL at temp@b}%
-    \MGL at write\MGL at out@stream{\MGL at temp@b}%
-  }%
-  \MGL at closeout\MGL at out@stream%
-  \MGL at write\MGL at main@stream{%
-    write '\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext'^^J%
-    ^^Jreset^^J%
-  }%
-  \MGL at write\@auxout{\string\MGL at unchanged{\MGL at script@name}}%
-}
-\def\mglplot at compare@code{%
-  \def\MGL at next{\MGL at write\@auxout{\string\MGL at unchanged{\MGL at script@name}}}%
-  \MGL at openin\MGL at in@stream{\MGL at dir\MGL at backups@dir\MGL at script@name.mgl}%
-  \MGL at for\MGL at temp@b:=\MGL at temp@a\do{%
-    \MGL at read\MGL at in@stream{\MGL at temp@c}%
-    \ifx\MGL at temp@b\MGL at temp@c\else%
-      \let\MGL at next\relax%
-    \fi%
-  }%
-  \MGL at closein\MGL at in@stream%
-  \MGL at next%
-}
-
-\def\mglblock{\@MGL at list@script at true\mglblock@}
-\@namedef{mglblock*}{\@MGL at list@script at false\mglblock@}
-\newcommand\mglblock@[2][]{%
-  \@MGL at lineno@true%
-  \setkeys{MGL at verb@keys}{#1}%
-  \MGL at set@script at name{#2}%
-  \if at MGL@list at script@%
-    \refstepcounter{MGL at verb@script at no}%
-    \addcontentsline{lms}{MGL at script}{%
-      \protect\numberline{\theMGL at verb@script at no.}%
-      {\ttfamily\protect\detokenize{\MGL at script@name.mgl}}%
-    }%
-  \fi%
-  \if at MGL@lineno@%
-    \list{\mgllinenostyle\arabic{MGL at line@no}.}{\usecounter{MGL at line@no}}%
-  \else%
-    \list{}{}%
-  \fi%
-  \MGL at set@verbatim at code%
-  \fboxrule=\mgllinethickness%
-  \item[\MGL at line@sep]\fbox{%
-    \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL at script@name.mgl}%
-  }\hskip\labelsep\MGL at line@sep\par\par%
-  \def\verbatim at processline{%
-    \item\the\verbatim at line%
-    \MGL at write\MGL at out@stream{\the\verbatim at line}%
-  }%
-  \MGL at openout\MGL at out@stream{\MGL at dir\MGL at scripts@dir\MGL at script@name.mgl}%
-  \verbatim at start%
-}
-\def\endmglblock{%
-  \MGL at closeout\MGL at out@stream%
-  \item[\MGL at line@sep]\hskip-\labelsep\MGL at line@sep%
-  \endlist%
-}
-\expandafter\let\csname endmglblock*\endcsname\endmglblock
-
-\def\mglverbatim{\@MGL at list@script at true\mglverbatim@}
-\@namedef{mglverbatim*}{\@MGL at list@script at false\mglverbatim@}
-\newcommand\mglverbatim@[1][]{%
-  \@MGL at lineno@true%
-  \define at key{MGL at verb@keys}{label}{\edef\MGL at script@name{##1}}%
-  \setkeys{MGL at verb@keys}{#1}%
-  \if at MGL@lineno@%
-    \list{\mgllinenostyle\arabic{MGL at line@no}.}{\usecounter{MGL at line@no}}%
-  \else%
-    \list{}{}%
-  \fi%
-  \MGL at set@verbatim at code%
-  \fboxrule=\mgllinethickness%
-  \@ifundefined{MGL at script@name}{%
-    \edef\MGL at script@name{\mglverbatimname}%
-    \item[\MGL at line@sep]\hskip-\labelsep\MGL at line@sep%
-  }{%
-    \item[\MGL at line@sep]\fbox{%
-      \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL at script@name.mgl}%
-    }\hskip\labelsep\MGL at line@sep\par\par%
-  }%
-  \if at MGL@list at script@%
-    \refstepcounter{MGL at verb@script at no}%
-    \addcontentsline{lms}{MGL at script}{%
-      \protect\numberline{\theMGL at verb@script at no.}%
-      {\ttfamily\protect\detokenize{\MGL at script@name}}%
-    }%
-  \fi%
-  \def\verbatim at processline{%
-    \item\the\verbatim at line%
-  }%
-  \verbatim at start%
-}
-\def\endmglverbatim{%
-  \MGL at closeout\MGL at out@stream%
-  \item[\MGL at line@sep]\hskip-\labelsep\MGL at line@sep%
-  \endlist%
-}
-\expandafter\let\csname endmglverbatim*\endcsname\endmglverbatim
-
-\def\mglcomment{%
-  \if at MGL@comments@%
-    \list{}{}%
-    \MGL at set@verbatim at code%
-    \item\hskip-\labelsep<\MGL at dash@sep\mglcommentname\MGL at dash@sep>%
-    \def\verbatim at processline{\item\the\verbatim at line}%
-    \verbatim at start%
-  \else%
-    \@bsphack%
-    \MGL at codes%
-    \let\verbatim at startline\relax%
-    \let\verbatim at addtoline\@gobble%
-    \let\verbatim at processline\relax%
-    \let\verbatim at finish\relax%
-    \verbatim@%
-  \fi%
-}
-\def\endmglcomment{%
-  \if at MGL@comments@%
-    \item\hskip-\labelsep<\MGL at dash@sep\mglcommentname\MGL at dash@sep>%
-    \endlist%
-  \else%
-    \@esphack%
-  \fi%
-}
-
-\newcommand\mglgraphics[2][]{%
-  \bgroup%
-  \define at key{MGL at keys}{path}{\def\MGL at forced@path{##1}}%
-  \MGL at setkeys{MGL at keys}{#1}%
-  \edef\MGL at script@name{#2}%
-  \IfFileExists{\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext}{}{%
-    \@ifundefined{MGL at forced@path}{%
-      \@for\MGL at temp@a:=\MGL at paths\do{%
-        \IfFileExists{\MGL at temp@a\MGL at script@name.mgl}{%
-          \edef\MGL at temp@b{\MGL at temp@a}%
-        }{}%
-      }%
-    }{%
-      \IfFileExists{\MGL at forced@path\MGL at script@name.mgl}{%
-        \edef\MGL at temp@b{\MGL at forced@path}%
-      }{}%
-    }%
-    \@ifundefined{MGL at temp@b}{%
-      \PackageWarning{mgltex}{%
-        MGL script "\MGL at script@name.mgl" not found%
-      }%
-    }{%
-      \MGL at write{18}{%
-        mglconv -q \MGL at quality\space -S \MGL at scale\space%
-        -s "\MGL at dir\MGL at scripts@dir\mglcommonscriptname.mgl"\space%
-        -o "\MGL at dir\MGL at graphics@dir\MGL at script@name\MGL at graph@ext"\space%
-        "\MGL at temp@b\MGL at script@name.mgl"%
-      }%
-    }%
-  }%
-  \MGL at includegraphics%
-  \egroup%
-}
-
-\def\mglinclude{\@MGL at list@script at true\mglinclude@}
-\@namedef{mglinclude*}{\@MGL at list@script at false\mglinclude@}
-\newcommand\mglinclude@[2][]{%
-  \bgroup%
-  \@MGL at lineno@true%
-  \define at key{MGL at verb@keys}{path}{\def\MGL at forced@path{##1}}%
-  \setkeys{MGL at verb@keys}{#1}%
-  \edef\MGL at script@name{#2}%
-  \@ifundefined{MGL at forced@path}{%
-    \@for\MGL at temp@b:=\MGL at paths\do{%
-      \IfFileExists{\MGL at temp@b\MGL at script@name.mgl}{%
-        \edef\MGL at temp@a{\MGL at temp@b}%
-      }{}%
-    }%
-  }{%
-    \IfFileExists{\MGL at script@name.mgl}{%
-      \edef\MGL at temp@a{\MGL at forced@path}%
-    }{}%
-  }%
-  \@ifundefined{MGL at temp@a}{%
-    \PackageWarning{mgltex}{%
-      MGL script "\MGL at forced@path\MGL at script@name.mgl" not found%
-    }%
-    \center%
-      \fbox{%
-        \centering%
-        \bfseries\Huge%
-        \begin{tabular}{c}MGL\\script\\not\\found\end{tabular}%
-      }%
-    \endcenter%
-  }{%
-    \mglinclude@@%
-  }%
-  \egroup%
-}
-\def\mglinclude@@{%
-  \@addtofilelist{\MGL at script@name.mgl}%
-  \if at MGL@list at script@%
-    \refstepcounter{MGL at verb@script at no}%
-    \addcontentsline{lms}{MGL at script}{%
-      \protect\numberline{\theMGL at verb@script at no.}%
-      {\ttfamily\protect\detokenize{\MGL at script@name.mgl}}%
-    }%
-  \fi%
-  \if at MGL@lineno@%
-    \list{\mgllinenostyle\arabic{MGL at line@no}.}{\usecounter{MGL at line@no}}%
-  \else%
-    \list{}{}%
-  \fi%
-  \MGL at set@verbatim at code%
-  \fboxrule=\mgllinethickness%
-  \item[\MGL at line@sep]\fbox{%
-    \bfseries\ttfamily\expandafter\detokenize\expandafter{\MGL at script@name.mgl}%
-  }\hskip\labelsep\MGL at line@sep\par\par%
-  \def\verbatim at processline{%
-    \item\the\verbatim at line%
-  }%
-  \immediate\openin\MGL at in@stream="\MGL at temp@a\MGL at script@name.mgl"%
-  \mglinclude@@@%
-}
-\def\mglinclude@@@{%
-  \immediate\read\MGL at in@stream to \MGL at temp@b%
-  \ifeof\MGL at in@stream%
-    \immediate\closein\MGL at in@stream%
-    \item[\MGL at line@sep]\hskip-\labelsep\MGL at line@sep%
-    \endlist%
-  \else%
-    \verbatim at startline%
-    \expandafter\verbatim at addtoline\expandafter{\MGL at temp@b}%
-    \verbatim at processline%
-    \expandafter\mglinclude@@@%
-  \fi%
-}
-\def\mglname#1{\edef\MGL at main@script at name{#1}}
-\AtBeginDocument{%
-  \def\mglname#1{%
-    \@bsphack%
-    \MGL at write@funcs%
-    \immediate\closeout{\MGL at main@stream}%
-    \MGL at write{18}{%
-      mglconv -q \MGL at quality\space -S \MGL at scale\space%
-      -s "\MGL at dir\MGL at scripts@dir\mglcommonscriptname.mgl"\space%
-      -n "\MGL at dir\MGL at scripts@dir\MGL at main@script at name.mgl"%
-    }%
-    \edef\MGL at main@script at name{#1}%
-    \bgroup\MGL at set@script at name{\MGL at main@script at name}\egroup%
-    \MGL at openout\MGL at main@stream{%
-      \MGL at dir\MGL at scripts@dir\MGL at main@script at name.mgl%
-    }%
-    \@esphack%
-  }%
-}
-
-\ifx\l at chapter\@undefined%
-  \ifx\l at section\@undefined%
-    \def\listofmglscripts{%
-      \@startsection{MGL at 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 at MGL@list[2]{%
-      \ifnum \c at 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 at xt@\@pnumwidth{\hss #2}\par
-        \endgroup
-      \fi%
-    }%
-  \else%
-    \def\listofmglscripts{%
-      \section*{\listofmglscriptsname}%
-      \@mkboth{%
-        \MakeUppercase\listofmglscriptsname%
-      }{%
-        \MakeUppercase\listofmglscriptsname%
-      }%
-      \@starttoc{lms}%
-    }%
-  \fi%
-\else%
-  \def\listofmglscripts{%
-    \chapter*{\listofmglscriptsname}%
-    \@mkboth{%
-      \MakeUpperCase\listofmglscriptsname%
-    }{%
-      \MakeUppercase\listofmglscriptsname%
-    }%
-    \@starttoc{lms}%
-  }%
-\fi%
-
-\def\mglTeX{mgl\TeX}
-
-\def\mglTeXwVer{\mglTeX~v4.0}
-
-\def\mgldir#1{\def\MGL at dir{#1}}\@onlypreamble\mgldir
-\def\mglscriptsdir#1{\def\MGL at scripts@dir{#1}}\@onlypreamble\mglscriptsdir
-\def\mglgraphicsdir#1{\def\MGL at graphics@dir{#1}}\@onlypreamble\mglgraphicsdir
-\def\mglbackupsdir#1{\def\MGL at backups@dir{#1}}\@onlypreamble\mglbackupsdir
-\def\mglpaths#1{\g at addto@macro\MGL at paths{,#1}}
-
-\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 at set@script at name{\MGL at main@script at name}\egroup%
-  \immediate\openout\MGL at main@stream=%
-  \MGL at dir\MGL at scripts@dir\MGL at main@script at name.mgl%
-}
-\AtEndDocument{%
-  \MGL at write@funcs%
-  \immediate\closeout\MGL at main@stream%
-  \MGL at write{18}{%
-    mglconv -q \MGL at quality\space -S \MGL at scale\space%
-    -s "\MGL at dir\MGL at scripts@dir\mglcommonscriptname.mgl"\space%
-    -n "\MGL at dir\MGL at scripts@dir\MGL at main@script at name.mgl"%
-  }%
-}
-\endinput
-%%
-%% End of file `mgltex.sty'.
diff --git a/mgltex/sample.tex b/mgltex/sample.tex
index a44dedb..d7d39eb 100644
--- a/mgltex/sample.tex
+++ b/mgltex/sample.tex
@@ -75,7 +75,7 @@ As an alternative to this method of declaring signatures, the user can manually
     }
   \end{verbatim}
 \item[mglcomment]
-  Used to contain multiline commentaries. This commentaries will be visible/invisible in the output document, depending on the use of the package options \texttt{comments} and \texttt{nocomments} (see above), or the \texttt{\mglcomments} and \texttt{\mglnocomments} commands (see bellow).
+  Used to contain multiline commentaries. This commentaries will be visible/invisible in the output document, depending on the use of the package options \texttt{comments} and \texttt{nocomments} (see above), or the \texttt{\mglcomments{on}} and \texttt{\mglcomments{off}} commands (see bellow).
   
   When, visible, the comment will appear like this:
   \begin{center}
@@ -128,9 +128,9 @@ The package also defines the following commands:
       \hline
     \end{tabular}
   \end{center}
-\item[\textbackslash{}mgltexon, \textbackslash{}mgltexoff]
+\item[\textbackslash{}mglswitch\{on\}, \textbackslash{}mglswitch\{off\}]
   To activate/deactivate the creation of MGL scripts and images. Notice these commands have local behavior in the sense that their effect is from the point they are called on.
-\item[\textbackslash{}mglcomment, \textbackslash{}mglnocomment]
+\item[\textbackslash{}mglcomment\{on\}, \textbackslash{}mglnocomment\{off\}]
   To make visible/invisible the contents of the \texttt{mglcomment} environments. These commands have local effect too.
 \item[\textbackslash{}mglTeX]
 	It just pretty prints the name of the package ``\mglTeX''.
@@ -431,25 +431,25 @@ The result is:
   that can have multiple lines
 \end{mglcomment}
 
-The following commentary won't be visible, since it is wrapped by \texttt{\textbackslash{}mglnocomments} and \texttt{\textbackslash{}mglcomments}.
+The following commentary won't be visible, since it is wrapped by \texttt{\textbackslash{}mglnocomments\{off\}} and \texttt{\textbackslash{}mglcomments\{on\}}.
 \begin{verbatim}
-  \mglnocomments
+  \mglcomments{off}
   \begin{mglcomment}
     This is an invisible commentary
     that can have multiple lines
   \end{mglcomment}
-  \mglcomments
+  \mglcomments{on}
 \end{verbatim}
-\mglnocomments
+\mglcomments{off}
 \begin{mglcomment}
   This is an invisible commentary
   that can have multiple lines
 \end{mglcomment}
-\mglcomments
+\mglcomments{on}
 
-The last example is the use of the \texttt{\textbackslash{}mgltexon} and \texttt{\textbackslash{}mgltexoff} commands. For example, the following image won't be generated:
+The last example is the use of the \texttt{\textbackslash{}mglswitch\{on\}} and \texttt{\textbackslash{}mglswitch\{off\}} commands. For example, the following image won't be generated:
 \begin{verbatim}
-  \mgltexoff
+  \mglswitch{off}
   \begin{figure}[!ht]
     \centering
     \begin{mgl}
@@ -457,10 +457,10 @@ The last example is the use of the \texttt{\textbackslash{}mgltexon} and \texttt
       fplot 'sin(pi*x)' '2B'
     \end{mgl}
   \end{figure}
-  \mgltexon
+  \mglswitch{on}
 \end{verbatim}
 The result is:
-\mgltexoff
+\mglswitch{off}
 \begin{figure}[!ht]
   \centering
   \begin{mgl}
@@ -468,5 +468,5 @@ The result is:
     fplot 'sin(pi*x)' '2B'
   \end{mgl}
 \end{figure}
-\mgltexon
+\mglswitch{on}
 \end{document}
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a16a01c..0470c22 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -71,7 +71,7 @@ if(MGL_HAVE_GIF)
 endif(MGL_HAVE_GIF)
 
 if(MGL_HAVE_HDF5)
-	target_link_libraries(mgl ${HDF5_LIBRARIES})
+	target_link_libraries(mgl ${HDF5_LIBRARIES} ${HDF5_C_SHARED_LIBRARY})
 	include_directories(${HDF5_INCLUDE_DIR})
 endif(MGL_HAVE_HDF5)
 
diff --git a/src/addon.cpp b/src/addon.cpp
index c0f64d7..9e9b8c9 100644
--- a/src/addon.cpp
+++ b/src/addon.cpp
@@ -19,7 +19,6 @@
  ***************************************************************************/
 #include <stdarg.h>
 #ifdef WIN32
-#include <io.h>
 #include <direct.h>
 #else
 #include <unistd.h>
diff --git a/src/base.cpp b/src/base.cpp
index bd605a3..a1821c7 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -125,7 +125,7 @@ mglBase::mglBase()
 
 	strcpy(last_style,"__1 {dFFFF}k\0");
 	MinS.Set(-1,-1,-1);	MaxS.Set(1,1,1);
-	fnt = new mglFont;	fnt->gr = this;	PrevState=NAN;
+	fnt = new mglFont;	fnt->gr = this;	PrevState=NAN;	size_opt=NAN;
 }
 mglBase::~mglBase()
 {
@@ -1277,6 +1277,7 @@ mreal mglBase::SaveState(const char *opt)
 		mgl_strtrim(b);
 
 		mreal ff=atof(b),ss;
+		size_opt = NAN;
 		if(!strcmp(b,"on"))	ff=1;
 		if(!strcmp(a+1,"range"))
 		{
@@ -1295,7 +1296,7 @@ mreal mglBase::SaveState(const char *opt)
 		else if(!strcmp(a,"ambient"))	SetAmbient(ff);
 		else if(!strcmp(a,"diffuse"))	SetDifLight(ff);
 		else if(!strcmp(a,"size"))
-		{	SetMarkSize(ff);	SetFontSize(ff);	SetArrowSize(ff);	}
+		{	SetMarkSize(ff);	SetFontSize(ff);	SetArrowSize(ff);	size_opt=ff;	}
 		else if(!strcmp(a,"num") || !strcmp(a,"number") || !strcmp(a,"value"))	res=ff;
 		else if(!strcmp(a,"legend"))
 		{	if(*b=='\'')	{	b++;	b[strlen(b)-1]=0;	}	leg_str = b;	}
diff --git a/src/canvas.cpp b/src/canvas.cpp
index ba7dfd2..b413099 100644
--- a/src/canvas.cpp
+++ b/src/canvas.cpp
@@ -912,11 +912,11 @@ void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const
 		w = w>t ? w:t;
 	}
 	w += ll+0.01*iw;	// add space for lines
-	j = long((ih*0.95)/h);
+	j = long((ih*0.95)/h);	if(j<1)	j=1;
 	long ncol = 1+(n-1)/j, nrow = (n+ncol-1)/ncol;
 	if(strchr(font,'-'))	// horizontal legend
 	{
-		j = long((iw*0.95)/w);
+		j = long((iw*0.95)/w);	if(j<1)	j=1;
 		nrow = 1+(n-1)/j;
 		ncol = (n+nrow-1)/nrow;
 	}
diff --git a/src/canvas_cf.cpp b/src/canvas_cf.cpp
index f8b3af6..3eb207b 100644
--- a/src/canvas_cf.cpp
+++ b/src/canvas_cf.cpp
@@ -280,6 +280,12 @@ void MGL_EXPORT mgl_set_size(HMGL gr, int width, int height)
 	width = int(mgl_size_scl*width);	height = int(mgl_size_scl*height);
 	if(g)	g->SetSize(width, height);
 }
+void MGL_EXPORT mgl_scale_size(HMGL gr, int width, int height)
+{
+	mglCanvas *g = dynamic_cast<mglCanvas *>(gr);
+	width = int(mgl_size_scl*width);	height = int(mgl_size_scl*height);
+	if(g)	g->SetSize(width, height, false);
+}
 void MGL_EXPORT mgl_set_def_param(HMGL gr)
 {	mglCanvas *g = dynamic_cast<mglCanvas *>(gr);	if(g)	g->DefaultPlotParam();	}
 void MGL_EXPORT mgl_combine_gr(HMGL gr, HMGL in)
@@ -362,6 +368,8 @@ void MGL_EXPORT mgl_delete_graph_(uintptr_t *gr)	{	delete _GR_;	}
 void MGL_EXPORT mgl_set_size_scl_(double *scl)	{	mgl_set_size_scl(*scl);	}
 void MGL_EXPORT mgl_set_size_(uintptr_t *gr, int *width, int *height)
 {	mgl_set_size(_GR_,*width,*height);	}
+void MGL_EXPORT mgl_scale_size_(uintptr_t *gr, int *width, int *height)
+{	mgl_scale_size(_GR_,*width,*height);	}
 void MGL_EXPORT mgl_set_def_param_(uintptr_t *gr)	{	_GR_->DefaultPlotParam();	}
 void MGL_EXPORT mgl_combine_gr_(uintptr_t *gr, uintptr_t *in)
 {	_GR_->Combine((mglCanvas *)in);	}
diff --git a/src/complex.cpp b/src/complex.cpp
index 73dabab..ccfbb20 100644
--- a/src/complex.cpp
+++ b/src/complex.cpp
@@ -645,7 +645,7 @@ dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mr
 mdual MGL_EXPORT mgl_datac_spline(HCDT d, mreal x,mreal y,mreal z)
 {
 	const mglDataC *dd=dynamic_cast<const mglDataC *>(d);
-	dual r = dd ? mglSpline3st<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z) : mgl_data_spline(d,x,y,z);
+	dual r = dd ? mglSpline3st<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z) : d->value(x,y,z);
 	return r.real()+r.imag()*mgl_I;
 }
 //-----------------------------------------------------------------------------
@@ -655,7 +655,7 @@ mdual MGL_EXPORT mgl_datac_spline_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,
 	if(!dd)
 	{
 		mreal rx=0,ry=0,rz=0,res;
-		res=mgl_data_spline_ext(d,x,y,z,&rx,&ry,&rz);
+		res=d->valueD(x,y,z,&rx,&ry,&rz);
 		if(dx)	*dx=rx;	if(dy)	*dy=ry;	if(dz)	*dz=rz;
 		return res;
 	}
@@ -884,11 +884,11 @@ void MGL_EXPORT mgl_datac_join(HADT d, HCDT v)
 	const mglDataC *mv = dynamic_cast<const mglDataC *>(v);
 	long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(), m = vx*vy*vz;
 
-	if(nx==vx && ny==vy && (nz>1 || vz>1))	d->nz += vz;
+	if(nx==vx && ny==vy && ny>1)	d->nz += vz;
 	else
 	{
 		ny *= nz;	vy *= vz;
-		if(nx==vx && (ny>1 || vy>1))
+		if(nx==vx && nx>1)
 		{	d->nz = 1;	d->ny = ny+vy;	}
 		else
 		{	d->ny = d->nz = 1;	d->nx = k+m;	}
@@ -1246,7 +1246,7 @@ void MGL_EXPORT mgl_datac_refill_xy(HADT dat, HCDT xdat, HCDT ydat, HCDT vdat, m
 						v = 2.f*(d1x*yy - d1y*xx)/qv;
 						if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)	continue;	// second root bad
 					}
-					i0 = ii+nx*jj;	s = mgl_data_spline(vdat,i+u,j+v,0);
+					i0 = ii+nx*jj;	s = vdat->value(i+u,j+v,0);
 					if(sl<0)	for(long k=0;k<nz;k++)	dat->a[i0+k*nn] = s;
 					else	dat->a[i0+sl*nn] = s;
 				}
@@ -1284,9 +1284,9 @@ void MGL_EXPORT mgl_datac_refill_xyz(HADT dat, HCDT xdat, HCDT ydat, HCDT zdat,
 			mreal xx = x1+(x2-x1)*i/(nx-1.),dxx,dxy,dxz,vx,dx=0,dd;
 			mreal yy = y1+(y2-y1)*j/(ny-1.),dyx,dyy,dyz,vy,dy=0;
 			mreal zz = z1+(z2-z1)*k/(nz-1.),dzx,dzy,dzz,vz,dz=0;
-			vx = mgl_data_spline_ext(xdat,dx,dy,dz,&dxx,&dxy,&dxz);
-			vy = mgl_data_spline_ext(ydat,dx,dy,dz,&dyx,&dyy,&dyz);
-			vz = mgl_data_spline_ext(zdat,dx,dy,dz,&dzx,&dzy,&dzz);
+			vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz);
+			vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz);
+			vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz);
 			long count=0;
 			do	// use Newton method to find root
 			{
@@ -1295,11 +1295,11 @@ void MGL_EXPORT mgl_datac_refill_xyz(HADT dat, HCDT xdat, HCDT ydat, HCDT zdat,
 				dx += ((dyz*dzy-dyy*dzz)*(xx-vx)+(dxy*dzz-dxz*dzy)*(yy-vy)+(dxz*dyy-dxy*dyz)*(zz-vz))/dd;
 				dy += ((dyx*dzz-dyz*dzx)*(xx-vx)+(dxz*dzx-dxx*dzz)*(yy-vy)+(dxx*dyz-dxz*dyx)*(zz-vz))/dd;
 				dz += ((dyy*dzx-dyx*dzy)*(xx-vx)+(dxx*dzy-dxy*dzx)*(yy-vy)+(dxy*dyx-dxx*dyy)*(zz-vz))/dd;
-				vx = mgl_data_spline_ext(xdat,dx,dy,dz,&dxx,&dxy,&dxz);
-				vy = mgl_data_spline_ext(ydat,dx,dy,dz,&dyx,&dyy,&dyz);
-				vz = mgl_data_spline_ext(zdat,dx,dy,dz,&dzx,&dzy,&dzz);
+				vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz);
+				vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz);
+				vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz);
 			}	while(fabs(xx-vx)>acx && fabs(yy-vy)>acy && fabs(zz-vz)>acz);	// this valid for linear interpolation
-			dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:mgl_data_spline(vdat,dx,dy,dz);
+			dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:vdat->value(dx,dy,dz);
 		}
 	else
 	{
diff --git a/src/complex_ex.cpp b/src/complex_ex.cpp
index b1fc925..5d5ab4d 100644
--- a/src/complex_ex.cpp
+++ b/src/complex_ex.cpp
@@ -440,7 +440,7 @@ HADT MGL_EXPORT mgl_datac_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, in
 		for(long i=0;i<idat->GetNN();i++)
 		{
 			mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;
-			r->a[i] = mgl_isnum(x*y*z)?mgl_data_linear(dat, x,y,z):NAN;;
+			r->a[i] = mgl_isnum(x*y*z)?dat->linear(x,y,z):NAN;;
 		}
 	return r;
 }
diff --git a/src/cont.cpp b/src/cont.cpp
index d4776d2..b39a034 100644
--- a/src/cont.cpp
+++ b/src/cont.cpp
@@ -568,7 +568,7 @@ void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT
 			// draw it
 			bool b1d2 = a->v(i+1,j,ak)>v2 && a->v(i,j-1,ak)>v2;
 			bool b2d1 = a->v(i,j,ak)>v2 && a->v(i+1,j-1,ak)>v2;
-//			mreal vv = mgl_data_linear(a,i+0.5,j-0.5,ak);
+//			mreal vv = a->linearD(i+0.5,j-0.5,ak,0,0,0);
 //			vv = (vv-v1)*(vv-v2);
 			if(num<3)	continue;
 			if(num==4)	gr->quad_plot(p[0],p[1],p[3],p[2]);
diff --git a/src/crust.cpp b/src/crust.cpp
index 954f626..6c97cf2 100644
--- a/src/crust.cpp
+++ b/src/crust.cpp
@@ -20,7 +20,7 @@
 #include <float.h>
 #include <math.h>
 #include <list>
-#include <limits>
+#include <limits>
 #include "mgl2/other.h"
 #include "mgl2/data.h"
 #include "mgl2/thread.h"
@@ -45,7 +45,7 @@ void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCD
 	{
 		mglPoint p1,p2,p3,q;
 		gr->Reserve(m*3);
-		for(long i=0;i<m;i++)	if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0) 
+		for(long i=0;i<m;i++)	if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0)
 		{
 			register long k1 = long(nums->v(0,i)+0.5);
 			p1.Set(x->v(k1), y->v(k1), z->v(k1));
@@ -500,31 +500,25 @@ HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y)
 	std::vector<Shx> pts;
 	Shx pt;
 
-	// Filter NaNs and Infs and calculate axiswise ranges
-
-	double min_r =  std::numeric_limits<double>::infinity();
-	double max_r = -std::numeric_limits<double>::infinity();
-	double min_c =  std::numeric_limits<double>::infinity();
-	double max_c = -std::numeric_limits<double>::infinity();
-
+	double x1=mglInf, x2=-mglInf, y1=mglInf, y2=-mglInf;
 	for(long i=0;i<n;i++)
 	{
-		pt.r = x->vthr(i);	pt.c = y->vthr(i);
+		register mreal xx=x->vthr(i), yy = y->vthr(i);
+		if(xx<x1)	x1=xx;	if(xx>x2)	x2=xx;
+		if(yy<y1)	y1=yy;	if(yy>y2)	y2=yy;
+	}
+	const double dx=x2-x1, dy=y2-y1;
+	if(dx==0 || dy==0)	return nums;
+	for(long i=0;i<n;i++)	// Filter NaNs and Infs
+	{
+		pt.r = (x->vthr(i)-x1)/dx;	pt.c = (y->vthr(i)-y1)/dy;
 		if(mgl_isbad(pt.r) || mgl_isbad(pt.c))	continue;
 		pt.id = i;    pts.push_back(pt);
-
-		min_r = std::min(min_r, pt.r);
-		min_c = std::min(min_c, pt.c);
-		max_r = std::max(max_r, pt.r);
-		max_c = std::max(max_c, pt.c);
 	}
 
 	std::vector<Triad> triads;
-
 	static const double float_eps = std::numeric_limits<float>::epsilon();
-	Dupex grid_step(float_eps*std::max((max_r - min_r), std::max(std::abs(max_r), std::abs(min_r))), 
-			float_eps * std::max((max_c - min_c), std::max(std::abs(max_c), std::abs(min_c))));
-
+	Dupex grid_step(float_eps, float_eps);
 	const size_t original_size = pts.size();
 
 	if(pts.size() >= 3u && 0. < grid_step.r && 0. < grid_step.c) {
@@ -534,7 +528,7 @@ HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y)
 		if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) {
 			// Error occured. It may be caused by degenerated dataset. Well, let's try to increment rounding grid step.
 			// Why 4? Why not. There are no particular reasons for this.
-			grid_step.r *= 4.; 
+			grid_step.r *= 4.;
 			grid_step.c *= 4.;
 
 			out.clear();
@@ -543,12 +537,11 @@ HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y)
 			de_duplicate(pts, out, grid_step);
 
 			if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) {
-				// Last try. Let's assume uniform points distribution and use range / sqrt(pts.size()) * 2 as epsilon. 
+				// Last try. Let's assume uniform points distribution and use range / sqrt(pts.size()) * 2 as epsilon.
 				// It removes a 3/4 of points in optimal case but in the worst case it merges all points to the one.
 				const double density = 1. + floor(0.5 + std::sqrt(static_cast<double>(pts.size())));
-				grid_step.r = (max_r - min_r) / density * 2.;
-				grid_step.c = (max_c - min_c) / density * 2.;
-  				
+				grid_step.r = grid_step.c = 2/density;
+
 				out.clear();
 				de_duplicate(pts, out, grid_step);
 
@@ -777,3 +770,69 @@ long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff)
 	return m;
 }
 //-----------------------------------------------------------------------------
+void MGL_NO_EXPORT mgl_ifs_2d_point(HCDT A, mreal& x, mreal& y, mreal amax)
+{
+	long i, n=A->GetNy();
+	mreal r = amax*mgl_rnd(), sum_prob = 0, x1;
+	for(i=0;i<n;i++)
+	{
+		sum_prob += A->v(6,i);
+		if(r<sum_prob)	break;
+	}
+	x1= A->v(0,i)*x + A->v(1,i)*y + A->v(4,i);
+	y = A->v(2,i)*x + A->v(3,i)*y + A->v(5,i);	x = x1;
+}
+HMDT MGL_EXPORT mgl_data_ifs_2d(HCDT A, long n, long skip)
+{
+	if(!A || A->GetNx()<7 || n<1)	return 0;	// incompatible dimensions
+	mreal amax=0;
+	for(long i=0; i<A->GetNy(); i++)	amax += A->v(6,i);
+	if(amax<=0)	return 0;
+
+	mglData *f = new mglData(2,n);
+	mreal x = 0, y = 0;
+	for(long i=0; i<skip; i++)	mgl_ifs_2d_point(A, x, y,amax);
+	for(long i=0; i<n; i++)
+	{
+		mgl_ifs_2d_point(A, x, y, amax);
+		f->a[2*i] = x;	f->a[2*i+1] = y;
+	}
+	return f;
+}
+uintptr_t MGL_EXPORT mgl_data_ifs_2d_(uintptr_t *d, long *n, long *skip)
+{	return uintptr_t(mgl_data_ifs_2d(_DT_,*n,*skip));	}
+//-----------------------------------------------------------------------------
+void MGL_NO_EXPORT mgl_ifs_3d_point(HCDT A, mreal& x, mreal& y, mreal& z, mreal amax)
+{
+	int i, n=A->GetNy();
+	mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1;
+	for (i=0; i<n; i++)
+	{
+		sum_prob += A->v(12,i);
+		if(r < sum_prob)  break;
+	}
+	x1= A->v(0,i)*x + A->v(1,i)*y + A->v(2,i)*z + A->v(9,i);
+	y1= A->v(3,i)*x + A->v(4,i)*y + A->v(5,i)*z + A->v(10,i);
+	z = A->v(6,i)*x + A->v(7,i)*y + A->v(8,i)*z + A->v(11,i);
+	x = x1;	y = y1;
+}
+HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip)
+{
+	if(!A || A->GetNx()<13 || n<1)	return 0;   // incompatible dimensions
+	mreal amax = 0;
+	for(int i=0; i<A->GetNy(); i++)	amax += A->v(12,i);
+	if(amax <= 0) return 0;
+
+	mglData *f = new mglData(3,n);
+	mreal x = 0, y = 0, z = 0;
+	for(long i=0; i<skip; i++)	mgl_ifs_3d_point(A, x, y, z, amax);
+	for(long i=0; i<n; i++)
+	{
+		mgl_ifs_3d_point(A, x, y, z, amax);
+		f->a[3*i] = x;	f->a[3*i+1] = y;	f->a[3*i+2] = z;
+	}
+	return f;
+}
+uintptr_t MGL_EXPORT mgl_data_ifs_3d_(uintptr_t *d, long *n, long *skip)
+{   return uintptr_t(mgl_data_ifs_3d(_DT_,*n,*skip));   }
+//-----------------------------------------------------------------------------
diff --git a/src/data.cpp b/src/data.cpp
index aca5500..c6927af 100644
--- a/src/data.cpp
+++ b/src/data.cpp
@@ -1887,15 +1887,16 @@ long MGL_EXPORT mgl_data_get_nz_(uintptr_t *d)	{	return _DA_(d)->GetNz();	}
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_data_join(HMDT d, HCDT v)
 {
+	if(!d || !v)	return;
 	long nx=d->nx, ny=d->ny, nz=d->nz, k=nx*ny*nz;
 	const mglData *mv = dynamic_cast<const mglData *>(v);
 	long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(), m = vx*vy*vz;
 
-	if(nx==vx && ny==vy && (nz>1 || vz>1))	d->nz += vz;
+	if(nx==vx && ny==vy && ny>1)	d->nz += vz;
 	else
 	{
 		ny *= nz;	vy *= vz;
-		if(nx==vx && (ny>1 || vy>1))
+		if(nx==vx && nx>1)
 		{	d->nz = 1;	d->ny = ny+vy;	}
 		else
 		{	d->ny = d->nz = 1;	d->nx = k+m;	}
@@ -1933,8 +1934,8 @@ mreal MGL_NO_EXPORT mgl_index_1(mreal v, HCDT dat)
 {
 	long mx=dat->GetNx();
 	mreal d,d1=0,d2=mx-1,v1,v2;
-	v1 = mgl_data_spline(dat,d1,0,0);
-	v2 = mgl_data_spline(dat,d2,0,0);
+	v1 = dat->value(d1,0,0);
+	v2 = dat->value(d2,0,0);
 	long count=0;
 
 	const mreal eps = MGL_EPSILON-1.;
@@ -1944,7 +1945,7 @@ mreal MGL_NO_EXPORT mgl_index_1(mreal v, HCDT dat)
 	do
 	{
 		d = count<10?(d2-d1)*(v-v1)/(v2-v1)+d1:(d1+d2)/2;	count++;
-		register mreal val = mgl_data_spline(dat,d,0,0);
+		register mreal val = dat->value(d,0,0);
 //		if(fabs(val-v)<acx)	break;
 		if(val==v || d2-d<eps)	break;
 		if((v1-v)*(val-v)<0)	{	v2=val;	d2=d;	}	else	{	v1=val;	d1=d;	}
@@ -1961,7 +1962,7 @@ void MGL_EXPORT mgl_data_refill_x(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mrea
 	for(long i=0;i<nx;i++)
 	{
 		register mreal u = mgl_index_1(x1+dx*i,xdat);
-		register mreal d = mgl_data_spline(vdat,u,0,0);
+		register mreal d = vdat->value(u,0,0);
 		if(sl<0)	for(long j=0;j<nn;j++)	dat->a[i+j*nx] = d;
 		else	dat->a[i+sl*nx] = d;
 	}
@@ -2019,7 +2020,7 @@ void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mr
 						v = 2.f*(d1x*yy - d1y*xx)/qv;
 						if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)	continue;	// second root bad
 					}
-					i0 = ii+nx*jj;	s = mgl_data_spline(vdat,i+u,j+v,0);
+					i0 = ii+nx*jj;	s = vdat->value(i+u,j+v,0);
 					if(sl<0)	for(long k=0;k<nz;k++)	dat->a[i0+k*nn] = s;
 					else	dat->a[i0+sl*nn] = s;
 				}
@@ -2036,7 +2037,7 @@ void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mr
 #pragma omp parallel for collapse(2)
 		for(long j=0;j<ny;j++)	for(long i=0;i<nx;i++)
 		{
-			register mreal d = mgl_data_spline(vdat,u.a[i],v.a[j],0);
+			register mreal d = vdat->value(u.a[i],v.a[j],0);
 			register long i0=i+nx*j;
 			if(sl<0)	for(long k=0;k<nz;k++)	dat->a[i0+k*nn] = d;
 			else	dat->a[i0+sl*nn] = d;
@@ -2057,9 +2058,9 @@ void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, H
 			mreal xx = x1+(x2-x1)*i/(nx-1.),dxx,dxy,dxz,vx,dx=0,dd;
 			mreal yy = y1+(y2-y1)*j/(ny-1.),dyx,dyy,dyz,vy,dy=0;
 			mreal zz = z1+(z2-z1)*k/(nz-1.),dzx,dzy,dzz,vz,dz=0;
-			vx = mgl_data_spline_ext(xdat,dx,dy,dz,&dxx,&dxy,&dxz);
-			vy = mgl_data_spline_ext(ydat,dx,dy,dz,&dyx,&dyy,&dyz);
-			vz = mgl_data_spline_ext(zdat,dx,dy,dz,&dzx,&dzy,&dzz);
+			vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz);
+			vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz);
+			vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz);
 			long count=0;
 			do	// use Newton method to find root
 			{
@@ -2068,11 +2069,11 @@ void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, H
 				dx += ((dyz*dzy-dyy*dzz)*(xx-vx)+(dxy*dzz-dxz*dzy)*(yy-vy)+(dxz*dyy-dxy*dyz)*(zz-vz))/dd;
 				dy += ((dyx*dzz-dyz*dzx)*(xx-vx)+(dxz*dzx-dxx*dzz)*(yy-vy)+(dxx*dyz-dxz*dyx)*(zz-vz))/dd;
 				dz += ((dyy*dzx-dyx*dzy)*(xx-vx)+(dxx*dzy-dxy*dzx)*(yy-vy)+(dxy*dyx-dxx*dyy)*(zz-vz))/dd;
-				vx = mgl_data_spline_ext(xdat,dx,dy,dz,&dxx,&dxy,&dxz);
-				vy = mgl_data_spline_ext(ydat,dx,dy,dz,&dyx,&dyy,&dyz);
-				vz = mgl_data_spline_ext(zdat,dx,dy,dz,&dzx,&dzy,&dzz);
+				vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz);
+				vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz);
+				vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz);
 			}	while(fabs(xx-vx)>acx && fabs(yy-vy)>acy && fabs(zz-vz)>acz);	// this valid for linear interpolation
-			dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:mgl_data_spline(vdat,dx,dy,dz);
+			dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:vdat->value(dx,dy,dz);
 		}
 	else
 	{
@@ -2086,7 +2087,7 @@ void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, H
 		for(long i=0;i<nz;i++)	w.a[i] = mgl_index_1(z1+dz*i,zdat);
 #pragma omp parallel for collapse(3)
 		for(long k=0;k<nz;k++)	for(long j=0;j<ny;j++)	for(long i=0;i<nx;i++)
-			dat->a[i+nx*(j+ny*k)] = mgl_data_spline(vdat,u.a[i],v.a[j],w.a[k]);
+			dat->a[i+nx*(j+ny*k)] = vdat->value(u.a[i],v.a[j],w.a[k]);
 	}
 }
 //-----------------------------------------------------------------------------
@@ -2108,7 +2109,7 @@ HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int
 		for(long i=0;i<idat->GetNN();i++)
 		{
 			mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;
-			r->a[i] = mgl_isnum(x*y*z)?mgl_data_linear(dat, x,y,z):NAN;;
+			r->a[i] = mgl_isnum(x*y*z)?dat->linear(x,y,z):NAN;;
 		}
 	return r;
 }
diff --git a/src/data_ex.cpp b/src/data_ex.cpp
index 2a6a92c..a719d85 100644
--- a/src/data_ex.cpp
+++ b/src/data_ex.cpp
@@ -165,7 +165,7 @@ MGL_NO_EXPORT void *mgl_resize(void *par)
 	for(long i0=t->id;i0<t->n;i0+=mglNumThr)
 	{
 		register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
-		b[i0] = mgl_data_spline(dat, c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]);
+		b[i0] = dat->value(c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]);
 	}
 	return 0;
 }
@@ -706,8 +706,8 @@ MGL_NO_EXPORT void *mgl_hist_2(void *par)
 	for(long i=t->id;i<nn;i+=mglNumThr)
 	{
 		register mreal x = d*(i%(nx*ns)), y = d*((i/(nx*ns))%(ny*ns)), z = d*(i/(nx*ny*ns*ns));
-		register mreal f = sp ? mgl_data_spline(a,x,y,z) : mgl_data_linear(a,x,y,z), w=1;
-		if(c)	w = sp ? mgl_data_spline(c,x,y,z) : mgl_data_linear(c,x,y,z);
+		register mreal f = sp ? a->value(x,y,z) : a->linear(x,y,z), w=1;
+		if(c)	w = sp ? c->value(x,y,z) : c->linear(x,y,z);
 		if(mgl_isnan(f) || mgl_isnan(w))	continue;
 		register long k = long(n*(f-v[0])/(v[1]-v[0]));
 		if(k>=0 && k<n)
diff --git a/src/data_gr.cpp b/src/data_gr.cpp
index 82a4beb..d8fbda8 100644
--- a/src/data_gr.cpp
+++ b/src/data_gr.cpp
@@ -81,7 +81,7 @@ void MGL_EXPORT mgl_datac_refill_gr_(uintptr_t *gr, uintptr_t *d, uintptr_t *xda
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt)
 {
-	if(vdat && vdat->GetNN()!=d->GetNN())	return;	// incompatible dimesions
+	if(vdat && vdat->GetNN()!=d->GetNN())	return;	// incompatible dimensions
 	if(wdat && wdat->GetNN()!=d->GetNN())	return;
 	gr->SaveState(opt);
 	std::wstring s = d->s;	d->s = L"u";
@@ -106,7 +106,7 @@ void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *d, const char *eq, u
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_datac_fill_eq(HMGL gr, HADT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt)
 {
-	if(vdat && vdat->GetNN()!=d->GetNN())	return;	// incompatible dimesions
+	if(vdat && vdat->GetNN()!=d->GetNN())	return;	// incompatible dimensions
 	if(wdat && wdat->GetNN()!=d->GetNN())	return;
 	gr->SaveState(opt);
 	std::wstring s = d->s;	d->s = L"u";
diff --git a/src/data_io.cpp b/src/data_io.cpp
index 6929912..5834e72 100644
--- a/src/data_io.cpp
+++ b/src/data_io.cpp
@@ -301,7 +301,7 @@ std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns)
 		{	snprintf(buf,512,"## %s\n",dc->id.c_str());	out += buf;	}
 		for(long i=0;i<ny;i++)
 		{
-			for(long j=0;j<nx-1;j++)	
+			for(long j=0;j<nx-1;j++)
 			{	snprintf(buf,512,"%g\t",d->v(j,i,k));	out += buf;	}
 			snprintf(buf,512,"%g\n",d->v(nx-1,i,k));	out += buf;
 		}
@@ -344,8 +344,7 @@ MGL_NO_EXPORT char *mgl_read_gz(gzFile fp)
 //-----------------------------------------------------------------------------
 int MGL_EXPORT mgl_data_read(HMDT d, const char *fname)
 {
-	long l=1,m=1,k=1;
-	long nb,i;
+	long l=1,m=1,k=1,i;
 	gzFile fp = gzopen(fname,"r");
 	if(!fp)
 	{
@@ -353,7 +352,7 @@ int MGL_EXPORT mgl_data_read(HMDT d, const char *fname)
 		return	false;
 	}
 	char *buf = mgl_read_gz(fp);
-	nb = strlen(buf);	gzclose(fp);
+	long nb = strlen(buf);	gzclose(fp);
 
 	bool first=false;
 	register char ch;
@@ -399,6 +398,63 @@ int MGL_EXPORT mgl_data_read_(uintptr_t *d, const char *fname,int l)
 {	char *s=new char[l+1];		memcpy(s,fname,l);	s[l]=0;
 	int r = mgl_data_read(_DT_, s);	delete []s;		return r;	}
 //-----------------------------------------------------------------------------
+int MGL_EXPORT mgl_data_scan_file(HMDT d,const char *fname, const char *templ)
+{
+	// first scan for all "%g"
+	char *buf=new char[strlen(templ)+1],*s=buf;
+	strcpy(buf,templ);
+	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<const char *> bufs;
+	gzFile fp = gzopen(fname,"r");
+	if(!fp)
+	{
+		if(!d->a)	mgl_data_create(d, 1,1,1);
+		return	false;
+	}
+	s = mgl_read_gz(fp);	gzclose(fp);
+	if(*s)	bufs.push_back(s);
+	for(long i=0;s[i];i++)	if(s[i]=='\n')
+	{
+		while(s[i+1]=='\n')	i++;
+		s[i]=0;	i++;
+		if(s[i])	bufs.push_back(s+i);
+		else	break;
+	}
+	// parse lines and collect data
+	size_t nx=strs.size(), ny=bufs.size();
+	if(ny<1)
+	{
+		if(!d->a)	mgl_data_create(d, 1,1,1);
+		return	false;
+	}
+	d->Create(nx,ny);
+	for(size_t j=0;j<ny;j++)
+	{
+		const char *c = bufs[j];
+		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);
+		}
+	}
+	free(s);	return true;
+}
+int MGL_EXPORT mgl_data_scan_file_(uintptr_t *d,const char *fname, const char *templ,int l,int m)
+{	char *s=new char[l+1];		memcpy(s,fname,l);	s[l]=0;
+	char *t=new char[m+1];		memcpy(t,templ,m);	t[m]=0;
+	int r = mgl_data_scan_file(_DT_, s,t);	delete []s;	delete []t;	return r;	}
+//-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_data_create(HMDT d,long mx,long my,long mz)
 {
 	d->nx = mx>0 ? mx:1;	d->ny = my>0 ? my:1;	d->nz = mz>0 ? mz:1;
diff --git a/src/def_font.cc b/src/def_font.cc
index 4497e52..ef161da 100644
--- a/src/def_font.cc
+++ b/src/def_font.cc
@@ -1,4 +1,4 @@
-const long mgl_numg=411, mgl_cur=243136;
+const unsigned long mgl_numg=411, mgl_cur=243136;
 const float mgl_fact=35.7143;
 long mgl_gen_fnt[411][6] = {
 	{0x21,166,41,0,39,164},
diff --git a/src/eval.cpp b/src/eval.cpp
index 7e0db3b..e0d611c 100644
--- a/src/eval.cpp
+++ b/src/eval.cpp
@@ -501,13 +501,11 @@ double MGL_LOCAL_CONST stp(double a)	{return a>0 ? 1:0;}
 double MGL_LOCAL_CONST arg(double a,double b)	{	return atan2(b,a);	}
 double MGL_LOCAL_CONST mgz1(double)			{return NAN;}	// NOTE I think NAN value is more correct here than 0
 double MGL_LOCAL_CONST mgz2(double,double)	{return NAN;}	// NOTE I think NAN value is more correct here than 0
-#ifdef WIN32
-double MGL_LOCAL_CONST asinh(double x)	{	return log(x+sqrt(x*x+1.));	}
-double MGL_LOCAL_CONST acosh(double x)	{	return x>1 ? log(x+sqrt(x*x-1.)) : NAN;	}
-double MGL_LOCAL_CONST atanh(double x)	{	return fabs(x)<1 ? log((1.+x)/(1.-x))/2 : NAN;	}
-double MGL_LOCAL_CONST fmin(double a,double b)	{	return a > b ? b : a;	}
-double MGL_LOCAL_CONST fmax(double a,double b)	{	return a > b ? a : b;	}
-#endif
+double MGL_LOCAL_CONST mgl_asinh(double x)	{	return log(x+sqrt(x*x+1.));	}
+double MGL_LOCAL_CONST mgl_acosh(double x)	{	return x>1 ? log(x+sqrt(x*x-1.)) : NAN;	}
+double MGL_LOCAL_CONST mgl_atanh(double x)	{	return fabs(x)<1 ? log((1.+x)/(1.-x))/2 : NAN;	}
+double MGL_LOCAL_CONST mgl_fmin(double a,double b)	{	return a > b ? b : a;	}
+double MGL_LOCAL_CONST mgl_fmax(double a,double b)	{	return a > b ? a : b;	}
 //-----------------------------------------------------------------------------
 typedef double (*func_1)(double);
 typedef double (*func_2)(double, double);
@@ -519,7 +517,7 @@ static const mreal z2[EQ_SIN-EQ_LT] = {3,3,3,3,0,3,3,0,0,0,0,0,NAN,3,3,3,3
 	,0,0,0,0,0,0,0,0,0
 #endif
 };
-static const func_2 f2[EQ_SIN-EQ_LT] = {clt,cgt,ceq,cor,cand,add,sub,mul,del,ipw,pow,fmod,llg,arg,hypot,fmax,fmin
+static const func_2 f2[EQ_SIN-EQ_LT] = {clt,cgt,ceq,cor,cand,add,sub,mul,del,ipw,pow,fmod,llg,arg,hypot,mgl_fmax,mgl_fmin
 #if MGL_HAVE_GSL
 	,gsl_sf_bessel_Jnu,gsl_sf_bessel_Ynu,
 	gsl_sf_bessel_Inu,gsl_sf_bessel_Knu,
@@ -529,7 +527,7 @@ static const func_2 f2[EQ_SIN-EQ_LT] = {clt,cgt,ceq,cor,cand,add,sub,mul,del,ipw
 #endif
 };
 static const func_1 f1[EQ_SN-EQ_SIN] = {sin,cos,tan,asin,acos,atan,sinh,cosh,tanh,
-			asinh,acosh,atanh,sqrt,exp,log,log10,sgn,stp,floor,fabs
+			mgl_asinh,mgl_acosh,mgl_atanh,sqrt,exp,log,log10,sgn,stp,floor,fabs
 #if MGL_HAVE_GSL
 	,gsl_sf_dilog,gslEllEc,gslEllFc,gslAi,gslBi,gsl_sf_erf,
 	gsl_sf_expint_3,gsl_sf_expint_Ei,gsl_sf_expint_E1,gsl_sf_expint_E2,
diff --git a/src/evalp.cpp b/src/evalp.cpp
index 0499fa0..bfaed55 100644
--- a/src/evalp.cpp
+++ b/src/evalp.cpp
@@ -290,13 +290,11 @@ double MGL_LOCAL_CONST llg(double a,double b);//	{return log(a)/log(b);}
 double MGL_LOCAL_CONST gslEllE(double a,double b);//	{return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);}
 double MGL_LOCAL_CONST gslEllF(double a,double b);//	{return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);}
 double MGL_LOCAL_CONST gslLegP(double a,double b);//	{return gsl_sf_legendre_Pl(int(a),b);}
-#ifdef WIN32
-double MGL_LOCAL_CONST asinh(double x);
-double MGL_LOCAL_CONST acosh(double x);
-double MGL_LOCAL_CONST atanh(double x);
-double MGL_LOCAL_CONST fmin(double a,double b);
-double MGL_LOCAL_CONST fmax(double a,double b);
-#endif
+double MGL_LOCAL_CONST mgl_asinh(double x);
+double MGL_LOCAL_CONST mgl_acosh(double x);
+double MGL_LOCAL_CONST mgl_atanh(double x);
+double MGL_LOCAL_CONST mgl_fmin(double a,double b);
+double MGL_LOCAL_CONST mgl_fmax(double a,double b);
 //-----------------------------------------------------------------------------
 // It seems that standard wcstombs() have a bug. So, I replace by my own.
 void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size)
@@ -546,9 +544,9 @@ HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std::v
 			if(!nm.compare(L"asin"))		return mglApplyFunc(str, arg, head, asin);
 			else if(!nm.compare(L"acos"))	return mglApplyFunc(str, arg, head, acos);
 			else if(!nm.compare(L"atan"))	return mglApplyFunc(str, arg, head, atan);
-			else if(!nm.compare(L"asinh"))	return mglApplyFunc(str, arg, head, asinh);
-			else if(!nm.compare(L"acosh"))	return mglApplyFunc(str, arg, head, acosh);
-			else if(!nm.compare(L"atanh"))	return mglApplyFunc(str, arg, head, atanh);
+			else if(!nm.compare(L"asinh"))	return mglApplyFunc(str, arg, head, mgl_asinh);
+			else if(!nm.compare(L"acosh"))	return mglApplyFunc(str, arg, head, mgl_acosh);
+			else if(!nm.compare(L"atanh"))	return mglApplyFunc(str, arg, head, mgl_atanh);
 			else if(!nm.compare(L"arg"))
 			{
 				if(n>0)	return mglApplyOper(str.substr(n+1),str.substr(0,n),arg, head, atan2);
@@ -668,9 +666,9 @@ HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std::v
 			if(!nm.compare(L"mod") && n>0)
 				return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, fmod);
 			else if(!nm.compare(L"min") && n>0)
-				return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, fmin);
+				return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, mgl_fmin);
 			else if(!nm.compare(L"max") && n>0)
-				return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, fmax);
+				return mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, mgl_fmax);
 		}
 		else if(!nm.compare(L"int"))	return mglApplyFunc(str, arg, head, floor);
 		else if(!nm.compare(L"random"))
diff --git a/src/exec.cpp b/src/exec.cpp
index 6213155..daa56a1 100644
--- a/src/exec.cpp
+++ b/src/exec.cpp
@@ -2797,55 +2797,14 @@ 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 MGL_NO_EXPORT mgls_scanfile(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);
-			}
-		}
+		d->ScanFile(a[1].s.c_str(), a[2].s.c_str());
 	}
 	else res = 1;	return res;
 }
@@ -3086,6 +3045,48 @@ int MGL_NO_EXPORT mgls_pde(mglGraph *gr, long , mglArg *a, const char *k, const
 	else res = 1;	return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_pde_adv(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+	int res=0;
+	if(k[0]=='d' && a[0].d->temp)	return 5;
+	if(k[1]=='d' && a[1].d->temp)	return 5;
+	mglData *d = dynamic_cast<mglData *>(a[0].d), *f = dynamic_cast<mglData *>(a[1].d);
+	mglDataC *c = dynamic_cast<mglDataC *>(a[0].d);
+	if(d && f)
+	{
+		mglDataC r;
+		if(!strcmp(k,"ddsdd"))
+			r = gr->APDEc(a[2].s.c_str(), *(a[3].d), *(a[4].d), 0.1,100,opt);
+		else if(!strcmp(k,"ddsddn"))
+			r = gr->APDEc(a[2].s.c_str(), *(a[3].d), *(a[4].d), a[5].v,100,opt);
+		else if(!strcmp(k,"ddsddnn"))
+			r = gr->APDEc(a[2].s.c_str(), *(a[3].d), *(a[4].d), a[5].v,a[6].v,opt);
+		else res = 1;
+		if(res==0)	{	*d = r.Abs();	*f = r.Arg();	}
+	}
+	else if(d)
+	{
+		if(!strcmp(k,"dsdd"))
+			*d = gr->APDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), 0.1,100,opt);
+		else if(!strcmp(k,"dsddn"))
+			*d = gr->APDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,100,opt);
+		else if(!strcmp(k,"dsddnn"))
+			*d = gr->APDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt);
+		else res = 1;
+	}
+	else if(c)
+	{
+		if(!strcmp(k,"dsdd"))
+			*c = gr->APDEc(a[1].s.c_str(), *(a[2].d), *(a[3].d), 0.1,100,opt);
+		else if(!strcmp(k,"dsddn"))
+			*c = gr->APDEc(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,100,opt);
+		else if(!strcmp(k,"dsddnn"))
+			*c = gr->APDEc(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt);
+		else res = 1;
+	}
+	else res = 1;	return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_qo2d(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
 	int res=0;
@@ -3379,6 +3380,37 @@ int MGL_NO_EXPORT mgls_version(mglGraph *gr, long , mglArg *a, const char *k, co
 	else res = 1;	return res;
 }
 //-----------------------------------------------------------------------------
+int mgls_ifs2d(mglGraph *, long, mglArg *a, const char *k, const char *)
+{
+	mglData *fx = dynamic_cast<mglData*>(a[0].d);
+	mglData *fy = dynamic_cast<mglData*>(a[1].d);
+	if(!fx)	return 1;
+	int res = 0;
+	if (!strcmp(k, "ddn"))	fx->Set(mglIFS2d(*(a[1].d), mgl_int(a[2].v)));
+	else if (!strcmp(k, "dddn") && fy)
+	{
+		mglData f(mglIFS2d(*(a[2].d), mgl_int(a[3].v)));
+		fx->Set(f.SubData(0));	fy->Set(f.SubData(1));
+	}
+	else if (!strcmp(k, "ddnn"))	fx->Set(mglIFS2d(*(a[1].d), mgl_int(a[2].v), mgl_int(a[3].v)));
+	else if (!strcmp(k, "dddnn") && fy)
+	{
+		mglData f(mglIFS2d(*(a[2].d), mgl_int(a[3].v), mgl_int(a[4].v)));
+		fx->Set(f.SubData(0));	fy->Set(f.SubData(1));
+	}
+	else res = 1;	return res;
+}
+//-----------------------------------------------------------------------------
+int mgls_ifs3d(mglGraph *, long, mglArg *a, const char *k, const char *)
+{
+	mglData *f = dynamic_cast<mglData*>(a[0].d);
+	if(!f)	return 1;
+	int res = 0;
+	if (!strcmp(k, "ddn"))	f->Set(mglIFS3d(*(a[1].d), mgl_int(a[2].v)));
+	else if (!strcmp(k, "ddnn"))	f->Set(mglIFS3d(*(a[1].d), mgl_int(a[2].v), mgl_int(a[3].v)));
+	else res = 1;	return res;
+}
+//-----------------------------------------------------------------------------
 mglCommand mgls_base_cmd[] = {
 	{"addlegend","Add legend entry","addlegend 'txt' 'fmt'", mgls_addlegend,15},
 	{"addto","Add data or number","addto Var Dat|Var num", mgls_addto ,3},
@@ -3386,6 +3418,7 @@ mglCommand mgls_base_cmd[] = {
 	{"alpha","Switch on/off transparency","alpha [val]", mgls_alpha ,2},
 	{"alphadef","Set default transparency","alphadef val", mgls_alphadef ,2},
 	{"ambient","Set ambient light brightness","ambient val", mgls_ambient ,2},
+	{"apde","Solve PDE using advanced method (X-Y only)","apde Res 'ham' IniRe IniIm [dz k0]", mgls_pde_adv ,4},
 	{"arc","Draw angle arc","arc x0 y0 x1 y1 a ['fmt']|x0 y0 z0 x1 y1 a ['fmt']|x0 y0 z0 xr yr zr x1 y1 z1 a ['fmt']", mgls_arc ,13},
 	{"area","Draw area plot for 1D data","area Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_area ,7},
 	{"arrowsize","Set size of arrows","arrowsize val", mgls_arrowsize ,2},
@@ -3494,7 +3527,6 @@ mglCommand mgls_base_cmd[] = {
 	{"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},
-	{"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},
@@ -3507,6 +3539,8 @@ mglCommand mgls_base_cmd[] = {
 	{"hist","Create histogram (distribution) of data values","hist Res Dat num v1 v2 [nsub]|Res Dat Wdat num v1 v2 [nsub]", mgls_hist ,4},
 	{"idset","Set column id for data","idset Dat 'ids'", mgls_idset ,3},
 	{"if","Conditional operator","if val|Dat ['cond']", 0, 6},
+	{"ifs2d", "Computes the attractor of an IFS", "ifs2d F A n [skip]|Fx Fy A n [skip]", mgls_ifs2d, 4},
+	{"ifs3d", "Computes the attractor of an IFS for 3d case", "ifs3d F A n [skip]", mgls_ifs3d, 4},
 	{"import","Import data from PNG picture","import Dat 'fname' 'scheme' [v1 v2]", mgls_import ,4},
 	{"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},
@@ -3586,6 +3620,7 @@ mglCommand mgls_base_cmd[] = {
 	{"rotatetext","Set to auto rotate text or not","rotatetext val", mgls_rotatetext ,15},
 	{"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},
+	{"scanfile","Get fromated data from file","scanfile Dat 'fname 'templ'", mgls_scanfile ,4},
 	{"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},
 	{"sinfft","Sin-Fourier transform at some direction","sinfft Dat 'dir'", mgls_sinfft ,16},
diff --git a/src/fit.cpp b/src/fit.cpp
index d4f62e3..56cf1d6 100644
--- a/src/fit.cpp
+++ b/src/fit.cpp
@@ -194,7 +194,7 @@ mreal MGL_NO_EXPORT mgl_fit_base(mglFitData &fd, mreal *ini)
 	while ( status == GSL_CONTINUE && iter < 500 );
 
 	gsl_matrix *covar = gsl_matrix_alloc(m, m);
-#ifdef HAVE_GSL_2
+#ifdef MGL_HAVE_GSL2
 	gsl_matrix *J = gsl_matrix_alloc(s->fdf->n, s->fdf->p);
 	gsl_multifit_fdfsolver_jac(s, J);
 	gsl_multifit_covar (J, 0.0, covar);
diff --git a/src/font.cpp b/src/font.cpp
index 78c24b3..1fd685c 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -684,7 +684,7 @@ size_t mglFont::SaveBin(const char *fname)
 	FILE *fp = fopen(fname,"wb");
 	if(!fp)	return 0;
 	size_t sum=0;
-	fwrite(&numb,sizeof(long),1,fp);	sum += sizeof(long);
+	fwrite(&numb,sizeof(size_t),1,fp);	sum += sizeof(size_t);
 	fwrite(fact,sizeof(float),4,fp);	sum += sizeof(float)*4;
 	fwrite(Buf,sizeof(short),numb,fp);	sum += sizeof(short)*numb;
 	size_t len = glyphs.size();
@@ -702,13 +702,13 @@ bool mglFont::LoadBin(const char *base, const char *path)
 	FILE *fp = fopen(str,"rb");		if(!fp)	return false;
 	size_t s, len;
 	bool res = true;
-	s = fread(&numb,sizeof(long),1,fp);
+	s = fread(&numb,sizeof(size_t),1,fp);
 	if(s<1)	res = false;
 	s = fread(fact,sizeof(float),4,fp);
 	if(s<4)	res = false;
 	Buf = new short[numb];
 	s = fread(Buf,sizeof(short),numb,fp);
-	if(s<size_t(numb))	res = false;
+	if(s<numb)	res = false;
 	s = fread(&len,sizeof(size_t),1,fp);
 	if(s<1)	res = false;
 	if(res)
diff --git a/src/parser.cpp b/src/parser.cpp
index 7d5070a..49aa1b7 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -22,13 +22,6 @@
 #include "mgl2/canvas_cf.h"
 #include "mgl2/base.h"
 //-----------------------------------------------------------------------------
-#ifdef WIN32
-#include <io.h>
-wchar_t *wcstokw32(wchar_t *wcs, const wchar_t *delim)	{	return wcstok(wcs,delim);	}
-#define wcstok(a,b,c) wcstokw32(a,b)
-#else
-#include <unistd.h>
-#endif
 MGL_EXPORT void (*mgl_ask_func)(const wchar_t *, wchar_t *)=0;
 void MGL_EXPORT mgl_ask_gets(const wchar_t *quest, wchar_t *res)
 {	printf("%ls\n",quest);	if(!fgetws(res,1024,stdin))	*res=0;	}
diff --git a/src/pde.cpp b/src/pde.cpp
index 079dee0..b99338c 100644
--- a/src/pde.cpp
+++ b/src/pde.cpp
@@ -25,6 +25,166 @@
 const double GAMMA=0.1;	///< value for damping
 HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head);
 //-----------------------------------------------------------------------------
+//
+//		Advanced PDE series in 2D case
+//
+//-----------------------------------------------------------------------------
+// Solve equation dx/dy = func(p,x,y,|u|)[u] where p=d/dx. There are no assumptions about form of func().
+HADT MGL_EXPORT mgl_pde_adv_c(HMGL gr, const char *func, HCDT ini_re, HCDT ini_im, mreal dt, mreal k0, const char *opt)
+{
+	mreal gamma = gr->SaveState(opt);	if(mgl_isnan(gamma))	gamma = 20;
+	mglPoint Min=gr->Min, Max=gr->Max;
+	long nx=ini_re->GetNx(), nt = long((Max.y-Min.y)/dt)+1;
+	if(nx<2 || nt<2 || Max.x==Min.x){	gr->SetWarn(mglWarnLow,"PDE");	return 0;	}	// Too small data
+	if(ini_im->GetNx() != nx)		{	gr->SetWarn(mglWarnDim,"PDE");	return 0;	}	// Wrong dimensions
+
+	mglDataC *res=new mglDataC(nx, nt);
+	mglDataC u(nx);	u.s = L"u";
+	mglDataV x(nx,nx), y(nx,nx), r(nx,nx);
+	mglDataW p(nx,nx);	p.s = L"p";
+	x.s = L"x";	y.s = L"y";	r.s=L"#$mgl";
+	const mreal dp = 2*M_PI/(Max.x-Min.x), dd = k0*dt/2;
+	x.Fill(Min.x,Max.x,'x');	p.Freq(dp/k0,'y');
+	std::vector<mglDataA*> list;
+	list.push_back(&x);	list.push_back(&y);	list.push_back(&p);	list.push_back(&r);	list.push_back(&u);
+
+	dual *a = new dual[2*nx];	memset(a,0,2*nx*sizeof(dual));	// Add "damping" area
+	dual *f = new dual[2*nx];	memset(f,0,2*nx*sizeof(dual));	// Effective "spectrum"
+#pragma omp parallel for
+	for(long i=0;i<nx;i++)	// Initial conditions
+		a[i+nx/2] = dual(ini_re->v(i), ini_im->v(i));
+	double *dmp = new double[2*nx];	memset(dmp,0,2*nx*sizeof(double));
+#pragma omp parallel for
+	for(long i=0;i<2*nx;i++)	// dumping
+	{
+		if(i<nx/2)		dmp[i] += gamma*mgl_ipow((nx/2-i)/mreal(nx/2),2);
+		if(i>3*nx/2)	dmp[i] += gamma*mgl_ipow((i-3*nx/2-1)/mreal(nx/2),2);
+	}
+	HADT ham;
+	for(long k=0;k<nt;k++)
+	{
+		y.Fill(k*dt);
+		memcpy(u.a,a+nx/2,nx*sizeof(dual));
+		memcpy(res->a+k*nx,a+nx/2,nx*sizeof(dual));
+		ham = mglFormulaCalcC(func, list);
+		memset(f,0,2*nx*sizeof(dual));
+		const long i1=nx/2, i2=3*nx/2-1;
+#pragma omp parallel for
+		for(long j=0;j<nx;j++)
+		{
+			long jp = j<nx-1?j+1:0;
+			dual h1=dual(0,dd)*ham->a[nx*j], h2=dual(0,dd)*ham->a[nx-1+nx*j];
+			dual g1=(h1+dual(0,dd)*ham->a[nx*jp])/mreal(2), g2=(h2+dual(0,dd)*ham->a[nx-1+nx*jp])/mreal(2);
+			mreal k1=M_PI*2*j/nx, k2 = M_PI*(2*j+1)/nx;
+			for(long i=0;i<i1;i++)
+			{
+				f[2*j] += a[i]*exp(h1+dual(0,i*k1));
+				f[2*j+1] += a[i]*exp(g1+dual(0,i*k2));
+			}
+			for(long i=i1;i<i2;i++)
+			{
+				dual hh = ham->a[i-i1+nx*j];
+				f[2*j] += a[i]*exp(dual(0,dd)*hh+dual(0,i*k1));
+				f[2*j+1] += a[i]*exp(dual(0,dd)*(hh+ham->a[i-i1+nx*jp])/mreal(2)+dual(0,i*k2));
+			}
+			for(long i=i2;i<2*nx;i++)
+			{
+				f[2*j] += a[i]*exp(h2+dual(0,i*k1));
+				f[2*j+1] += a[i]*exp(g2+dual(0,i*k2));
+			}
+		}
+		memset(a,0,2*nx*sizeof(dual));
+#pragma omp parallel for
+		for(long i=0;i<2*nx;i++)
+		{
+			register long ii=i-i1;
+			if(ii<0)	ii=0;	if(ii>nx-1)	ii=nx-1;
+			double kk=M_PI*2*i/nx;
+			for(long j=0;j<nx;j++)
+			{
+				dual h1 = ham->a[ii+nx*j], g1 = (h1+ham->a[ii+nx*(j<nx-1?j+1:0)])/mreal(2);
+				a[i] += f[2*j]*exp(dual(0,dd)*h1-dual(0,kk*j));
+				a[i] += f[2*j+1]*exp(dual(0,dd)*g1-dual(0,kk*(j+0.5)));
+			}
+			a[i] *= exp(-dmp[i]*dt)/mreal(2*nx);
+		}
+		delete ham;
+	}
+	delete []a;	delete []f;	delete []dmp;
+	gr->LoadState();	return res;
+}
+//-----------------------------------------------------------------------------
+HMDT MGL_EXPORT mgl_pde_adv(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt)
+{
+	HADT res = mgl_pde_adv_c(gr,ham,ini_re,ini_im,dz,k0,opt);
+	HMDT out = mgl_datac_abs(res);	delete res;	return out;
+}
+//-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_pde_adv_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	char *o=new char[lo+1];	memcpy(o,opt,lo);	o[lo]=0;
+	uintptr_t res = uintptr_t(mgl_pde_adv_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));
+	delete []o;	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_pde_adv_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	char *o=new char[lo+1];	memcpy(o,opt,lo);	o[lo]=0;
+	uintptr_t res = uintptr_t(mgl_pde_adv(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));
+	delete []o;	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
+/*HADT MGL_EXPORT mgl_pde_adv_3d_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt)
+{
+	mreal gamma = gr->SaveState(opt);	if(mgl_isnan(gamma))	gamma = GAMMA;
+	mglPoint Min=gr->Min, Max=gr->Max;
+	long nx=ini_re->GetNx(), ny=ini_re->GetNy(), nz = long((Max.z-Min.z)/dz)+1;
+	if(nx<2 || nz<2 || Max.x==Min.x)			// Too small data
+	{	gr->SetWarn(mglWarnLow,"PDE");	return 0;	}
+	if(ini_im->GetNx()*ini_im->GetNy() != nx*ny)// Wrong dimensions
+	{	gr->SetWarn(mglWarnDim,"PDE");	return 0;	}
+	mglDataC *res=new mglDataC(nz, nx, ny);
+
+	mglDataV x(nx,ny), y(nx,ny), z, r(nx,ny);
+	mglDataW p(nx,ny), q(nx,ny);
+	x.s = L"x";	y.s = L"y";	p.s = L"p";	q.s = L"q";	z.s = L"z";	r.s=L"#$mgl";
+	//z.Fill(f->zz);
+	mreal dx = (Max.x-Min.x)/(nx-1), dy = ny>1?(Max.y-Min.y)/(ny-1):0;
+	mreal dp = M_PI/(Max.x-Min.x), dq = M_PI/(Max.y-Min.y);
+	double dd = k0*dz;
+	x.Fill(Min.x,Max.x,'x');	p.Freq(dp/k0,'x');
+	y.Fill(Min.y,Max.y,'y');	q.Freq(dq/k0,'y');
+
+	ddual *a = new ddual[4*nx*ny];	// Add "damping" area
+	ddual *f = new ddual[4*nx*ny];	// Effective "spectrum"
+	memset(a,0,4*nx*ny*sizeof(ddual));
+	memset(f,0,4*nx*ny*sizeof(ddual));
+#pragma omp parallel for collapse(2)
+	for(long j=0;j<ny;j++)	for(long i=0;i<nx;i++)	// Initial conditions
+	{
+		register long i0 = i+nx/2+2*nx*(j+ny/2);
+		a[i0] = dual(ini_re->v(i,j), ini_im->v(i,j));
+		res->a[nz*(i+nx*j)] = a[i0];
+	}
+	double *dmp = new double[4*nx*ny];
+	memset(dmp,0,4*nx*ny*sizeof(double));
+#pragma omp parallel for collapse(2)
+	for(long j=0;j<2*ny;j++)	for(long i=0;i<2*nx;i++)	// step 1
+	{
+		register long i0 = i+2*nx*j;
+		if(i<nx/2)		dmp[i0] += gamma*mgl_ipow((nx/2-i)/(nx/2.),2);
+		if(i>3*nx/2)	dmp[i0] += gamma*mgl_ipow((i-3*nx/2-1)/(nx/2.),2);
+		if(j<ny/2)		dmp[i0] += gamma*mgl_ipow((ny/2-j)/(ny/2.),2);
+		if(j>3*ny/2)	dmp[i0] += gamma*mgl_ipow((j-3*ny/2-1)/(ny/2.),2);
+	}
+	ddual *Hdat = new ddual[nx*nx*ny*ny];
+	for(long k=1;k<nz;k++)
+	{
+	}
+}*/
+//-----------------------------------------------------------------------------
+//
+//		Simplified PDE series
+//
+//-----------------------------------------------------------------------------
 struct mgl_pde_ham
 {
 	ddual *a,*hxy,*hxv,*huv,*huy;
@@ -205,6 +365,22 @@ HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im
 	HMDT out = mgl_datac_abs(res);	delete res;	return out;
 }
 //-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_pde_solve_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	char *o=new char[lo+1];	memcpy(o,opt,lo);	o[lo]=0;
+	uintptr_t res = uintptr_t(mgl_pde_solve_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));
+	delete []o;	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	char *o=new char[lo+1];	memcpy(o,opt,lo);	o[lo]=0;
+	uintptr_t res = uintptr_t(mgl_pde_solve(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));
+	delete []o;	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
+//
+//		ODE series
+//
+//-----------------------------------------------------------------------------
 struct mglOdeTxt	{	long n;	HMEX *eq;	const char *var;	};
 void MGL_NO_EXPORT mgl_txt_func(const mreal *x, mreal *dx, void *par)
 {
@@ -268,6 +444,10 @@ HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *p
 	return res;
 }
 //-----------------------------------------------------------------------------
+//
+//		Common functions for quasioptical calculations
+//
+//-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_ray3d(const mreal *in, mreal *out, void *par)
 {
 	mglFormula *eqs = (mglFormula *)par;
@@ -289,6 +469,11 @@ HMDT MGL_EXPORT mgl_ray_trace(const char *ham, mreal x0, mreal y0, mreal z0, mre
 	return res;
 }
 //-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int l)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	uintptr_t res = uintptr_t(mgl_ray_trace(s, *x0,*y0,*z0, *px,*py,*pz, *dt,*tmax));
+	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
 struct mgl_ap
 {
 	double x0,y0,z0,x1,y1,z1,x2,y2,z2;	// vectors {l, g1, g2}
@@ -495,8 +680,13 @@ HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT r
 	HMDT out = mgl_datac_abs(res);	delete res;	return out;
 }
 //-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int l)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	uintptr_t res = uintptr_t(mgl_qo2d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy)));
+	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
 //
-//		QO2d series
+//		QO3d series
 //
 //-----------------------------------------------------------------------------
 struct mgl_qo3d_ham
@@ -713,6 +903,15 @@ HMDT MGL_EXPORT mgl_qo3d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT r
 	HMDT out = mgl_datac_abs(res);	delete res;	return out;
 }
 //-----------------------------------------------------------------------------
+uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int l)
+{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
+	uintptr_t res = uintptr_t(mgl_qo3d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy), _DM_(zz)));
+	delete []s;	return res;	}
+//-----------------------------------------------------------------------------
+//
+//		mglJacobian series
+//
+//-----------------------------------------------------------------------------
 MGL_NO_EXPORT void *mgl_jacob2(void *par)
 {
 	mglThreadD *t=(mglThreadD *)par;
@@ -820,28 +1019,6 @@ HMDT MGL_EXPORT mgl_jacobian_3d(HCDT x, HCDT y, HCDT z)
 	return r;
 }
 //-----------------------------------------------------------------------------
-uintptr_t MGL_EXPORT mgl_pde_solve_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)
-{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
-	char *o=new char[lo+1];	memcpy(o,opt,lo);	o[lo]=0;
-	uintptr_t res = uintptr_t(mgl_pde_solve_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));
-	delete []o;	delete []s;	return res;	}
-uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)
-{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
-	char *o=new char[lo+1];	memcpy(o,opt,lo);	o[lo]=0;
-	uintptr_t res = uintptr_t(mgl_pde_solve(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));
-	delete []o;	delete []s;	return res;	}
-uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int l)
-{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
-	uintptr_t res = uintptr_t(mgl_ray_trace(s, *x0,*y0,*z0, *px,*py,*pz, *dt,*tmax));
-	delete []s;	return res;	}
-uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int l)
-{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
-	uintptr_t res = uintptr_t(mgl_qo2d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy)));
-	delete []s;	return res;	}
-uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int l)
-{	char *s=new char[l+1];	memcpy(s,ham,l);	s[l]=0;
-	uintptr_t res = uintptr_t(mgl_qo3d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy), _DM_(zz)));
-	delete []s;	return res;	}
 uintptr_t MGL_EXPORT mgl_jacobian_2d_(uintptr_t* x, uintptr_t* y)
 {	return uintptr_t(mgl_jacobian_2d(_DA_(x), _DA_(y)));	}
 uintptr_t MGL_EXPORT mgl_jacobian_3d_(uintptr_t* x, uintptr_t* y, uintptr_t* z)
diff --git a/src/pixel.cpp b/src/pixel.cpp
index 0427ef7..82ef44c 100644
--- a/src/pixel.cpp
+++ b/src/pixel.cpp
@@ -65,7 +65,7 @@ void mglCanvas::SetSize(int w,int h,bool clf)
 
 	InPlot(0,1,0,1,false);
 	if(clf || (Quality&4))	Clf();
-	else	// NOTE: no scaling for text (a bit complicated)
+	else	// No clearing. So, need to scale
 	{
 #if MGL_HAVE_PTHREAD
 		pthread_mutex_lock(&mutexPnt);
@@ -73,8 +73,17 @@ void mglCanvas::SetSize(int w,int h,bool clf)
 #elif MGL_HAVE_OMP
 		omp_set_lock(&lockClf);
 #endif
+		const long m = long(Prm.size());
+		double dd = dx>dy?dy:dx;
+#pragma omp parallel for	// Scale text
+		for(long i=0;i<m;i++)	if(Prm[i].type==4)
+		{
+			mglPnt &q = Pnt[Prm[i].n1];
+			Prm[i].p *=dd;
+			q.u *= dd;	q.v *= dd;
+		}
 		const long n = long(Pnt.size());
-#pragma omp parallel for
+#pragma omp parallel for	// Scale coordinates
 		for(long i=0;i<n;i++)
 		{
 			mglPnt &q = Pnt[i];
@@ -1326,11 +1335,12 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 		x1=x1>d->x1?x1:d->x1;	x2=x2<d->x2?x2:d->x2;
 		y1=y1>d->y1?y1:d->y1;	y2=y2<d->y2?y2:d->y2;
 		if(x1>x2 || y1>y2)	return;
-
+		const float V=(pw-1)*(pw-1)/4,S=(1-pw)/2;
+		
 		for(long j=y1;j<=y2;j++)	for(long i=x1;i<=x2;i++)
 		{
 			register float dx=i-q.x, dy=j-q.y, v=dx*dx+dy*dy;
-			register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+			register int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 			cs[3] = ca*sum/255;
 			pnt_plot(i,j,q.z+1,cs,oi);
 		}
@@ -1352,6 +1362,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 		x1=x1>d->x1?x1:d->x1;	x2=x2<d->x2?x2:d->x2;
 		y1=y1>d->y1?y1:d->y1;	y2=y2<d->y2?y2:d->y2;
 		if(x1>x2 || y1>y2)	return;
+		const float V=(pw-1)*(pw-1)/4,S=(1-pw)/2;
 
 		switch(type)
 		{
@@ -1361,17 +1372,17 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = (dx-ss)*(dx-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dy)-ss;	v = (dx+ss)*(dx+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dy)-ss;	v = dx*dx+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = (dy-ss)*(dy-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = (dy+ss)*(dy+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = dy*dy+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1382,9 +1393,9 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = dx*dx+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = dy*dy+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1395,18 +1406,18 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = (dx-ss)*(dx-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dy)-ss;	v = (dx+ss)*(dx+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = (dy-ss)*(dy-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = (dy+ss)*(dy+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 
 				u = fabs(dx+dy)-2*ss;	v = dx-dy;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx-dy)-2*ss;	v = dx+dy;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
@@ -1418,9 +1429,9 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dx+dy)-2*ss;	v = dx-dy;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx-dy)-2*ss;	v = dx+dy;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1431,7 +1442,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				u = fabs(dy)-ss;	if(u<0)	u=0;
 				v = fabs(dx)-ss;	if(v<0)	v=0;	v = u*u+v*v;
-				register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				register int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1442,13 +1453,13 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = (dx-ss)*(dx-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dy)-ss;	v = (dx+ss)*(dx+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = (dy-ss)*(dy-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx)-ss;	v = (dy+ss)*(dy+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1459,7 +1470,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				u = fabs(dx-dy)-ss;	if(u<0)	u=0;
 				v = fabs(dx+dy)-ss;	if(v<0)	v=0;	v = u*u+v*v;
-				register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				register int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1470,13 +1481,13 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dx+dy)-ss;	v = (dx-dy-ss)*(dx-dy-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx+dy)-ss;	v = (dx-dy+ss)*(dx-dy+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx-dy)-ss;	v = (dx+dy-ss)*(dx+dy-ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(dx-dy)-ss;	v = (dx+dy+ss)*(dx+dy+ss)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1487,11 +1498,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy+ss/2)-ss/2;	v = dx*dx+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.87*dx+0.5*dy-ss/2)-ss/2;	v = (0.5*dx-0.87*dy)*(0.5*dx-0.87*dy)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(-0.87*dx+0.5*dy-ss/2)-ss/2;	v = (0.5*dx+0.87*dy)*(0.5*dx+0.87*dy)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1502,11 +1513,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = dx*dx+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.87*dx+0.5*dy)-ss;	v = (0.5*dx-0.87*dy)*(0.5*dx-0.87*dy)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(-0.87*dx+0.5*dy)-ss;	v = (0.5*dx+0.87*dy)*(0.5*dx+0.87*dy)+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1521,11 +1532,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				{
 					register int sum=0;
 					u = fabs(dx)-ss;	v = dy+ss/2;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dx+0.83*dy)-0.9*ss;	v = 0.83*dx-0.55*dy+0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dx-0.83*dy)-0.9*ss;	v = 0.83*dx+0.55*dy-0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				}
 				pnt_plot(i,j,q.z+1,cs,oi);
@@ -1537,11 +1548,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dx)-ss;	v = dy+ss/2;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dx+0.83*dy)-0.9*ss;	v = 0.83*dx-0.55*dy+0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dx-0.83*dy)-0.9*ss;	v = 0.83*dx+0.55*dy-0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1556,11 +1567,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				{
 					register int sum=0;
 					u = fabs(dx)-ss;	v = dy-ss/2;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dx+0.83*dy)-0.9*ss;	v = 0.83*dx-0.55*dy-0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dx-0.83*dy)-0.9*ss;	v = 0.83*dx+0.55*dy+0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				}
 				pnt_plot(i,j,q.z+1,cs,oi);
@@ -1572,11 +1583,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dx)-ss;	v = dy-ss/2;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dx+0.83*dy)-0.9*ss;	v = 0.83*dx-0.55*dy-0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dx-0.83*dy)-0.9*ss;	v = 0.83*dx+0.55*dy+0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1591,11 +1602,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				{
 					register int sum=0;
 					u = fabs(dy)-ss;	v = dx-ss/2;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dy+0.83*dx)-0.9*ss;	v = 0.83*dy-0.55*dx-0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dy-0.83*dx)-0.9*ss;	v = 0.83*dy+0.55*dx+0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				}
 				pnt_plot(i,j,q.z+1,cs,oi);
@@ -1607,11 +1618,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = dx-ss/2;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dy+0.83*dx)-0.9*ss;	v = 0.83*dy-0.55*dx-0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dy-0.83*dx)-0.9*ss;	v = 0.83*dy+0.55*dx+0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1626,11 +1637,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				{
 					register int sum=0;
 					u = fabs(dy)-ss;	v = dx+ss/2;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dy+0.83*dx)-0.9*ss;	v = 0.83*dy-0.55*dx+0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					u = fabs(0.55*dy-0.83*dx)-0.9*ss;	v = 0.83*dy+0.55*dx-0.55*ss;	v = v*v+(u<0?0:u*u);
-					sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+					sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 					sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				}
 				pnt_plot(i,j,q.z+1,cs,oi);
@@ -1642,11 +1653,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 				register float dx=i-q.x, dy=j-q.y, v,u;
 				register int sum=0;
 				u = fabs(dy)-ss;	v = dx+ss/2;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dy+0.83*dx)-0.9*ss;	v = 0.83*dy-0.55*dx+0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				u = fabs(0.55*dy-0.83*dx)-0.9*ss;	v = 0.83*dy+0.55*dx-0.55*ss;	v = v*v+(u<0?0:u*u);
-				sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1656,7 +1667,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 			{
 				register float dx=i-q.x, dy=j-q.y, v;
 				v = hypot(dx,dy)-ss;	v=v<0?0:v*v;
-				register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				register int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1666,7 +1677,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 			{
 				register float dx=i-q.x, dy=j-q.y, v;
 				v = hypot(dx,dy)-ss;	v=v*v;
-				register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				register int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				cs[3] = ca*sum/255;
 				pnt_plot(i,j,q.z+1,cs,oi);
 			}
@@ -1676,7 +1687,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 			{
 				register float dx=i-q.x, dy=j-q.y, v;
 				v = hypot(dx,dy)-ss;	v=v*v;
-				register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));
+				register int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));
 				v = dx*dx+dy*dy;
 				sum += v<(2*pw-1)*(2*pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-2*pw)/2));
 				sum = sum>255?255:sum;	cs[3] = ca*sum/255;
diff --git a/src/prim.cpp b/src/prim.cpp
index d62c086..ec80c87 100644
--- a/src/prim.cpp
+++ b/src/prim.cpp
@@ -83,7 +83,9 @@ void MGL_EXPORT mgl_curve(HMGL gr, double x1, double y1, double z1, double dx1,
 {
 	static int cgid=1;	gr->StartGroup("Curve",cgid++);
 	if(mgl_isnan(z1) || mgl_isnan(z2))	z1=z2=2*gr->Max.z-gr->Min.z;
-	mglPoint p1(x1,y1,z1), p2(x2,y2,z2), d1(dx1,dy1,dz1), d2(dx2,dy2,dz2), a,b,p=p1,nn(NAN);
+	const mglPoint p1(x1,y1,z1), p2(x2,y2,z2),nn(NAN);
+	const mglPoint d1(3*dx1,3*dy1,3*dz1), d2(3*dx2,3*dy2,3*dz2);	// NOTE use d->3*d to be exact as Bezier curve
+	mglPoint a,b,p=p1;
 	a = 3*(p2-p1)-d2-2*d1;	b = d1+d2-2*(p2-p1);
 	n = (n<2) ? 2 : n;
 	gr->SetPenPal(pen);
@@ -99,8 +101,8 @@ void MGL_EXPORT mgl_curve(HMGL gr, double x1, double y1, double z1, double dx1,
 		if(i==1)	gr->arrow_plot(k2,k1,gr->Arrow1);
 		if(i==n-1)	gr->arrow_plot(k1,k2,gr->Arrow2);
 	}
-	gr->AddActive(gr->AddPnt(p1+d1,gr->CDef,nn,-1,3),1);
-	gr->AddActive(gr->AddPnt(p2-d2,gr->CDef,nn,-1,3),3);
+	gr->AddActive(gr->AddPnt(p1+d1/3,gr->CDef,nn,-1,3),1);
+	gr->AddActive(gr->AddPnt(p2-d2/3,gr->CDef,nn,-1,3),3);
 	gr->AddActive(k1,2);	gr->EndGroup();
 }
 //-----------------------------------------------------------------------------
diff --git a/src/vect.cpp b/src/vect.cpp
index 1e3c23a..9ef80fa 100644
--- a/src/vect.cpp
+++ b/src/vect.cpp
@@ -516,12 +516,11 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
 		pp[k].x = x.Spline1(dif,u,0,0);	f = ax.Spline1(u,v,0)/dif.x;
 		pp[k].y = y.Spline1(dif,v,0,0);	g = ay.Spline1(u,v,0)/dif.x;
 		pp[k].z = zVal;
-		if(mgl_isbad(f+g))	end = true;
+		if(mgl_isbad(f+g))	break;
 		else	for(long m=0;m<k-1;m+=10)	// determines encircle
 			if(mgl_anorm((pp[k]-pp[m])/dx)<acc)	end = true;
-		if(end)	break;
 		h = hypot(f,g);	pp[k].c = gr->GetC(ss,s*h);
-		if(h<1e-5)	break;	// stationary point
+		if(end || h<1e-5)	break;	// stationary point
 		if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)	k++;
 		// find next point by midpoint method
 		h+=1;	ff[0]=f*dt/h;	gg[0]=g*dt/h;
@@ -550,12 +549,11 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
 		xx = ax.Spline1(u,v,0);	yy = ay.Spline1(u,v,0);
 		det = xv*yu-xu*yv;	f = (yy*xv-xx*yv)/det;	g = (xx*yu-yy*xu)/det;
 		pp[k].z = zVal;
-		if(mgl_isbad(f+g))	end = true;
+		if(mgl_isbad(f+g))	break;
 		else	for(long m=0;m<k-1;m+=10)	// determines encircle
 			if(mgl_anorm((pp[k]-pp[m])/dx)<acc)	end = true;
-		if(end)	break;
 		h = hypot(f,g);	pp[k].c = gr->GetC(ss,s*h);
-		if(h<1e-5)	break;	// stationary point
+		if(end || h<1e-5)	break;	// stationary point
 		if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1)	k++;
 		// find next point by midpoint method
 		h+=1;	ff[0]=f*dt/h;	gg[0]=g*dt/h;
diff --git a/src/volume.cpp b/src/volume.cpp
index f7b3ca0..a6090a5 100644
--- a/src/volume.cpp
+++ b/src/volume.cpp
@@ -285,34 +285,34 @@ void MGL_NO_EXPORT mgl_surf3ca_gen(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
 		if(b && c)	for(size_t i=kk1;i<kk.size();i++)
 		{
 			mglPoint &u = kk[i];
-			u.c = gr->AddPnt(nboth ? mglPoint(mgl_data_linear(x,u.x,0,0),mgl_data_linear(y,u.y,0,0),mgl_data_linear(z,u.z,0,0)) : 
-							mglPoint(mgl_data_linear(x,u.x,u.y,u.z),mgl_data_linear(y,u.x,u.y,u.z),mgl_data_linear(z,u.x,u.y,u.z)),
-					gr->GetC(ss,mgl_data_linear(c,u.x,u.y,u.z)),
+			u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : 
+					mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),
+					gr->GetC(ss,c->linear(u.x,u.y,u.z)),
 					mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l),
-					gr->GetA(mgl_data_linear(b,u.x,u.y,u.z)));
+					gr->GetA(b->linear(u.x,u.y,u.z)));
 		}
 		else if(c)	for(size_t i=kk1;i<kk.size();i++)
 		{
 			mglPoint &u = kk[i];
-			u.c = gr->AddPnt(nboth ? mglPoint(mgl_data_linear(x,u.x,0,0),mgl_data_linear(y,u.y,0,0),mgl_data_linear(z,u.z,0,0)) : 
-							mglPoint(mgl_data_linear(x,u.x,u.y,u.z),mgl_data_linear(y,u.x,u.y,u.z),mgl_data_linear(z,u.x,u.y,u.z)),
-						gr->GetC(ss,mgl_data_linear(c,u.x,u.y,u.z)),
-						mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l));
+			u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : 
+					mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),
+					gr->GetC(ss,c->linear(u.x,u.y,u.z)),
+					mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l));
 		}
 		else if(b)	for(size_t i=kk1;i<kk.size();i++)
 		{
 			mglPoint &u = kk[i];
-			u.c = gr->AddPnt(nboth ? mglPoint(mgl_data_linear(x,u.x,0,0),mgl_data_linear(y,u.y,0,0),mgl_data_linear(z,u.z,0,0)) : 
-							mglPoint(mgl_data_linear(x,u.x,u.y,u.z),mgl_data_linear(y,u.x,u.y,u.z),mgl_data_linear(z,u.x,u.y,u.z)),
+			u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : 
+					mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),
 					cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l),
-					gr->GetA(mgl_data_linear(b,u.x,u.y,u.z)));
+					gr->GetA(b->linear(u.x,u.y,u.z)));
 		}
 		else	for(size_t i=kk1;i<kk.size();i++)
 		{
 			mglPoint &u = kk[i];
-			u.c = gr->AddPnt(nboth ? mglPoint(mgl_data_linear(x,u.x,0,0),mgl_data_linear(y,u.y,0,0),mgl_data_linear(z,u.z,0,0)) : 
-							mglPoint(mgl_data_linear(x,u.x,u.y,u.z),mgl_data_linear(y,u.x,u.y,u.z),mgl_data_linear(z,u.x,u.y,u.z)),
-						cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l));
+			u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) : 
+					mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),
+					cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l));
 		}
 		
 		if(k>0)	mgl_surf3_plot(gr,n,m,kx1,kx2,ky1,ky2,kz,kk,wire);
diff --git a/src/window.cpp b/src/window.cpp
index 835c304..1f0001b 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -23,6 +23,9 @@ mglCanvasWnd::mglCanvasWnd() : mglCanvas()
 {
 	Setup();	LoadFunc=0;	FuncPar=0;	DrawFunc=0;	ClickFunc=0;
 	GG = 0;		NumFig = 0;	CurFig = -1;
+#if MGL_HAVE_PTHR_WIDGET
+	mutex=0;
+#endif
 }
 //-----------------------------------------------------------------------------
 mglCanvasWnd::~mglCanvasWnd()	{	if(GG) free(GG);	}
@@ -201,6 +204,12 @@ void MGL_EXPORT mgl_get_last_mouse_pos_(uintptr_t *gr, mreal *x, mreal *y, mreal
 	mglPoint p;	if(g)	p=g->GetMousePos();
 	*x=p.x;	*y=p.y;	*z=p.z;	}
 //-----------------------------------------------------------------------------
+#if MGL_HAVE_PTHR_WIDGET
+void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex)
+{	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
+	if(g)	g->mutex = mutex;	}
+#endif
+//-----------------------------------------------------------------------------
 //
 //	mglDraw class handling
 //
@@ -229,18 +238,12 @@ int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p)
 	return func ? func(&g) : 0;
 }
 //-----------------------------------------------------------------------------
-#if MGL_HAVE_PTHREAD
-MGL_NO_EXPORT void *mgl_draw_calc(void *p)
-{
-	((mglDraw *)p)->Calc();	return 0;
-}
-//-----------------------------------------------------------------------------
-void MGL_EXPORT mgl_draw_thr(void *p)
+MGL_EXPORT void *mgl_draw_calc(void *p)
 {
+#if MGL_HAVE_PTHR_WIDGET
 	mglDraw *d = (mglDraw *)p;
-	if(!d || d->running)	return;
-	pthread_create(&(d->thr),0,mgl_draw_calc,d);
-	pthread_detach(d->thr);
-}
+	d->Calc();	d->running = false;
 #endif
+	return 0;
+}
 //-----------------------------------------------------------------------------
diff --git a/texinfo/CMakeLists.txt b/texinfo/CMakeLists.txt
index 2b268ae..97819de 100644
--- a/texinfo/CMakeLists.txt
+++ b/texinfo/CMakeLists.txt
@@ -1,6 +1,6 @@
 configure_file(${MathGL_SOURCE_DIR}/texinfo/version.texi.in ${MathGL_BINARY_DIR}/texinfo/version.texi)
 
-set(MGL_EXTRA light)
+set(MGL_EXTRA light pendelta)
 set(MGL_PNG alpha area aspect axial axis barh bars belt boxplot
 	box boxs candle chart cloud colorbar combined cones conta contd
 	contfa contf contf_xyz cont contv cont_xyz curvcoor cut dat_diff
@@ -10,7 +10,8 @@ set(MGL_PNG alpha area aspect axial axis barh bars belt boxplot
 	several_light solve stem step stereo stfa style surf3a surf3c surf3ca surf3
 	surfa surfc surfca surf table tape tens ternary textmark text ticks tile tiles
 	torus traj triangulation triplot tube type0 type1 type2 vect vecta venn
-	projection5 mask correl refill ohlc ode indirect)
+	projection5 mask correl refill ohlc ode indirect
+	pulse scanfile bifurcation lamerey pmap ifs2d ifs3d )
 set(MGL_PNG_N )
 set(MGL_PNG_S )
 set(MGL_PNG_J )
@@ -44,6 +45,8 @@ foreach(SAMPLE ${MGL_PNG})
 		COMMAND mgl_example -kind=${SAMPLE} -mini
 		DEPENDS mgl_example
 		WORKING_DIRECTORY ${MGL_OUT}/small )
+		
+		
 if(MGL_HAVE_DOC_JSON)
 	set(MGL_PNG_J ${MGL_PNG_J} ${MGL_OUT}/json/${SAMPLE}.json)
 	add_custom_command(OUTPUT ${MGL_OUT}/json/${SAMPLE}.json
@@ -78,12 +81,12 @@ set(list_texi_files_ru overview_ru.texi example_ru.texi ex_mgl_ru.texi parse_ru.
 
 add_custom_command(OUTPUT ${MGL_OUT}/mathgl_en.info
 	COMMAND ${findmi} ${MGL_TEX}/mathgl_en.texi
-	DEPENDS ${list_texi_files_en} mathgl_en.texi ${MGL_PNG_N}
+	DEPENDS ${list_texi_files_en} mathgl_en.texi #${MGL_PNG_N}
 	WORKING_DIRECTORY ${MGL_OUT}
 )
 add_custom_command(OUTPUT ${MGL_OUT}/mathgl_ru.info
 	COMMAND ${findmi} ${MGL_TEX}/mathgl_ru.texi
-	DEPENDS ${list_texi_files_ru} mathgl_ru.texi ${MGL_PNG_N}
+	DEPENDS ${list_texi_files_ru} mathgl_ru.texi #${MGL_PNG_N}
 	WORKING_DIRECTORY ${MGL_OUT}
 )
 
diff --git a/texinfo/core_en.texi b/texinfo/core_en.texi
index 4a7a4f0..92f29e3 100644
--- a/texinfo/core_en.texi
+++ b/texinfo/core_en.texi
@@ -18,7 +18,7 @@ Some of MathGL features will appear only in novel versions. To test used MathGL
 @deftypefnx {Method on @code{mglGraph}} @code{bool} CheckVersion (@code{const char *}ver) static
 @deftypefnx {C function} @code{int} mgl_check_version (@code{const char *}ver)
 @end ifclear
-Return nonzero if MathGL version is appropriate for required by @var{ver}, i.e. if major version is the same and minor version is greater or equal to one in @var{ver}.
+Return zero if MathGL version is appropriate for required by @var{ver}, i.e. if major version is the same and minor version is greater or equal to one in @var{ver}.
 @end deftypefn
 
 @menu
@@ -323,6 +323,15 @@ Gets default name @var{id} as filename for saving (in FLTK window for example).
 @end deftypefn
 @end ifclear
 
+ at anchor{pendelta}
+ at deftypefn {MGL command} {} pendelta @code{val}
+ at ifclear UDAV
+ at deftypefnx {Method on @code{mglGraph}} @code{void} SetPenDelta (@code{double} val)
+ at deftypefnx {C function} @code{void} mgl_pen_delta (@code{HMGL} gr, @code{double} val)
+ at end ifclear
+Changes the blur around lines and text (default is 1). For @var{val}>1 the text and lines are more sharped. For @var{val}<1 the text and lines are more blurred.
+ at end deftypefn
+
 @c ==================================================================
 @external{}
 @node Cutting, Font settings, Default sizes, Graphics setup
@@ -1162,10 +1171,11 @@ Functions in this group save or give access to produced picture. So, usually the
 @anchor{setsize}
 @deftypefn {MGL command} {} setsize @code{w h}
 @ifclear UDAV
- at deftypefnx {Method on @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height)
+ at deftypefnx {Method on @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height, @code{bool} clear=@code{true})
 @deftypefnx {C function} @code{void} mgl_set_size (@code{HMGL} gr, @code{int} width, @code{int} height)
+ at deftypefnx {C function} @code{void} mgl_scale_size (@code{HMGL} gr, @code{int} width, @code{int} height)
 @end ifclear
-Sets size of picture in pixels. This function @strong{must be} called before any other plotting because it completely remove picture contents.
+Sets size of picture in pixels. This function @strong{should be} called before any other plotting because it completely remove picture contents if @var{clear}=@code{true}. Function just clear pixels and scale all primitives if @var{clear}=@code{false}.
 @end deftypefn
 
 @ifclear UDAV
@@ -2495,6 +2505,46 @@ These functions draw the tube with variable radius @var{r}[i] along the curve be
 These functions draw surface which is result of curve @{@var{r}, @var{z}@} rotation around axis. If string @var{pen} contain symbols @samp{x} or @samp{z} then rotation axis will be set to specified direction (default is @samp{y}). If string @var{pen} have symbol @samp{#} then wire plot is produced. If string @var{pen} have symbol @samp{.} then plot by dots is produced. See also @ref{plot}, @ref{axial}. @sref{Torus sample}
 @end deftypefn
 
+ at anchor{lamerey}
+ at deftypefn {MGL command} {} lamerey @code{x0} ydat ['stl'='']
+ at deftypefnx {MGL command} {} lamerey @code{x0} 'y(x)' ['stl'='']
+ at ifclear UDAV
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {C function} @code{void} mgl_lamerey_dat (@code{HMGL} gr, @code{double} x0, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {C function} @code{void} mgl_lamerey_str (@code{HMGL} gr, @code{double} x0, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
+ at end ifclear
+These functions draw Lamerey diagram for mapping x_new = y(x_old) starting from point @var{x0}. String @var{stl} may contain line style, symbol @samp{v} for drawing arrows, symbol @samp{~} for disabling first segment. Option @code{value} set the number of segments to be drawn (default is 20). See also @ref{plot}, @ref{fplot}, @ref{bifurcation}, @ref{pmap}. @sref{Lamerey sample}
+ at end deftypefn
+
+ at anchor{bifurcation}
+ at deftypefn {MGL command} {} bifurcation @code{dx} ydat ['stl'='']
+ at deftypefnx {MGL command} {} bifurcation @code{dx} 'y(x)' ['stl'='']
+ at ifclear UDAV
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {C function} @code{void} mgl_bifurcation_dat (@code{HMGL} gr, @code{double} dx, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {C function} @code{void} mgl_bifurcation_str (@code{HMGL} gr, @code{double} dx, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
+ at end ifclear
+These functions draw bifurcation diagram for mapping x_new = y(x_old). Parameter @var{dx} set the accuracy along x-direction. String @var{stl} set color. Option @code{value} set the number of stationary points (default is 1024). See also @ref{plot}, @ref{fplot}, @ref{lamerey}. @sref{Bifurcation sample}
+ at end deftypefn
+
+ at anchor{pmap}
+ at deftypefn {MGL command} {} pmap ydat sdat ['stl'='']
+ at deftypefnx {MGL command} {} pmap xdat ydat sdat ['stl'='']
+ at deftypefnx {MGL command} {} pmap xdat ydat zdat sdat ['stl'='']
+ at ifclear UDAV
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Method on @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {C function} @code{void} mgl_pmap (@code{HMGL} gr, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {C function} @code{void} mgl_pmap_xy (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {C function} @code{void} mgl_pmap_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} z, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
+ at end ifclear
+These functions draw Poincare map for curve @{@var{x}, @var{y}, @var{z}@} at surface @var{s}=0. Basically, it show intersections of the curve and the surface. String @var{stl} set the style of marks. See also @ref{plot}, @ref{mark}, @ref{lamerey}. @sref{Pmap sample}
+ at end deftypefn
+
+
 @c ##################################################################
 @external{}
 @node 2D plotting, 3D plotting, 1D plotting, MathGL core
diff --git a/texinfo/core_ru.texi b/texinfo/core_ru.texi
index d6eebab..31777bc 100644
--- a/texinfo/core_ru.texi
+++ b/texinfo/core_ru.texi
@@ -18,7 +18,7 @@
 @deftypefnx {Метод класса @code{mglGraph}} @code{bool} CheckVersion (@code{const char *}ver) static
 @deftypefnx {Функция С} @code{int} mgl_check_version (@code{const char *}ver)
 @end ifclear
-Возвращает ненулевое значение если версия MathGL подходит для требуемой в @var{ver}, т.е. если номер основной версии совпадает и "подверсия" больше или равна указанной в @var{ver}.
+Возвращает нулевое значение если версия MathGL подходит для требуемой в @var{ver}, т.е. если номер основной версии совпадает и "подверсия" больше или равна указанной в @var{ver}.
 @end deftypefn
 
 @menu
@@ -314,6 +314,15 @@ MGL не требует создания данного типа объекто
 @end deftypefn
 @end ifclear
 
+ at anchor{pendelta}
+ at deftypefn {Команда MGL} {} pendelta @code{val}
+ at ifclear UDAV
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} SetPenDelta (@code{double} val)
+ at deftypefnx {Функция С} @code{void} mgl_pen_delta (@code{HMGL} gr, @code{double} val)
+ at end ifclear
+Изменяет размытие около линий и текста (по умолчанию 1). Для @var{val}>1 текст и линии более резкие. Для @var{val}<1 текст и линии более размытые.
+ at end deftypefn
+
 @c ==================================================================
 @external{}
 @node Cutting, Font settings, Default sizes, Graphics setup
@@ -1115,10 +1124,11 @@ Ternary -- специальный тип графика для 3 зависим
 @anchor{setsize}
 @deftypefn {Команда MGL} {} setsize @code{w h}
 @ifclear UDAV
- at deftypefnx {Метод класса @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height)
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height, @code{bool} clear=@code{true})
 @deftypefnx {Функция С} @code{void} mgl_set_size (@code{HMGL} gr, @code{int} width, @code{int} height)
+ at deftypefnx {Функция С} @code{void} mgl_scale_size (@code{HMGL} gr, @code{int} width, @code{int} height)
 @end ifclear
-Изменяет размер картинки в пикселях. Функция должна вызываться @strong{перед} любыми функциями построения потому что полностью очищает содержимое рисунка.
+Изменяет размер картинки в пикселях. Функция должна вызываться @strong{перед} любыми функциями построения потому что полностью очищает содержимое рисунка при @var{clear}=@code{true}. Функция только очищает растровый рисунок и масштабирует примитивы при @var{clear}=@code{false}.
 @end deftypefn
 
 
@@ -2404,6 +2414,45 @@ Draw bitmap (logo) along whole axis range, which can be changed by @ref{Command
 
 
 
+ at anchor{lamerey}
+ at deftypefn {Команда MGL} {} lamerey @code{x0} ydat ['stl'='']
+ at deftypefnx {Команда MGL} {} lamerey @code{x0} 'y(x)' ['stl'='']
+ at ifclear UDAV
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Функция С} @code{void} mgl_lamerey_dat (@code{HMGL} gr, @code{double} x0, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {Функция С} @code{void} mgl_lamerey_str (@code{HMGL} gr, @code{double} x0, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
+ at end ifclear
+Функции рисуют диаграмму Ламерея для точечного отображения x_new = y(x_old) начиная с точки @var{x0}. Строка @var{stl} может содержать стиль линии, символ @samp{v} для стрелок, символ @samp{~} для исключения первого сегмента. Опция @code{value} задает число сегментов для рисования (по умолчанию 20). См. также @ref{plot}, @ref{fplot}, @ref{bifurcation}, @ref{pmap}. @sref{Lamerey sample}
+ at end deftypefn
+
+ at anchor{bifurcation}
+ at deftypefn {Команда MGL} {} bifurcation @code{dx} ydat ['stl'='']
+ at deftypefnx {Команда MGL} {} bifurcation @code{dx} 'y(x)' ['stl'='']
+ at ifclear UDAV
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Функция С} @code{void} mgl_bifurcation_dat (@code{HMGL} gr, @code{double} dx, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {Функция С} @code{void} mgl_bifurcation_str (@code{HMGL} gr, @code{double} dx, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
+ at end ifclear
+Функции рисуют бифуркационную диаграмму (диаграмму удвоения периода) для точечного отображения x_new = y(x_old). Параметр @var{dx} задает точность по оси x. Строка @var{stl} задает цвет. Опция @code{value} задает число учитываемых стационарных точек (по умолчанию 1024). См. также @ref{plot}, @ref{fplot}, @ref{lamerey}. @sref{Bifurcation sample}
+ at end deftypefn
+
+ at anchor{pmap}
+ at deftypefn {Команда MGL} {} pmap ydat sdat ['stl'='']
+ at deftypefnx {Команда MGL} {} pmap xdat ydat sdat ['stl'='']
+ at deftypefnx {Команда MGL} {} pmap xdat ydat zdat sdat ['stl'='']
+ at ifclear UDAV
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Метод класса @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
+ at deftypefnx {Функция С} @code{void} mgl_pmap (@code{HMGL} gr, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {Функция С} @code{void} mgl_pmap_xy (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
+ at deftypefnx {Функция С} @code{void} mgl_pmap_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} z, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
+ at end ifclear
+Функции рисуют отображение Пуанкаре для кривой @{@var{x}, @var{y}, @var{z}@} при условии @var{s}=0. Проще говоря, рисуются точки пересечения кривой и поверхности. Строка @var{stl} задает стиль маркеров. См. также @ref{plot}, @ref{mark}, @ref{lamerey}. @sref{Pmap sample}
+ at end deftypefn
+
 
 @c ##################################################################
 @external{}
diff --git a/texinfo/data_en.texi b/texinfo/data_en.texi
index 7c0a0d8..d2b7a1b 100644
--- a/texinfo/data_en.texi
+++ b/texinfo/data_en.texi
@@ -329,7 +329,7 @@ Delete rows which values are equal to next row for given column @var{idx}.
 @deftypefnx {C function} @code{void} mgl_data_join (@code{HMDT} dat, @code{HCDT} vdat)
 @deftypefnx {C function} @code{void} mgl_datac_join (@code{HADT} dat, @code{HCDT} vdat)
 @end ifclear
-Join data cells from @var{vdat} to @var{dat}. At this, function increase @var{dat} sizes according following: z-size for 3D data arrays arrays with equal x-,y-sizes; or y-size for 2D data arrays with equal x-sizes; or x-size otherwise.
+Join data cells from @var{vdat} to @var{dat}. At this, function increase @var{dat} sizes according following: z-size for data arrays arrays with equal x-,y-sizes; or y-size for data arrays with equal x-sizes; or x-size otherwise.
 @end deftypefn
 
 
@@ -428,6 +428,13 @@ Allocates memory and copies the data from the @code{std::vector<T>} array.
 Allocates memory and scanf the data from the string.
 @end deftypefn
 
+
+ at deftypefn {Method on @code{mglData}} @code{void} SetList (@code{long} n, ...)
+Allocate memory and set data from variable argument list of @emph{double} values. Note, you need to specify decimal point @samp{.} for integer values! For example, the code @code{SetList(2,0.,1.);} is correct, but the code @code{SetList(2,0,1);} is incorrect.
+ at end deftypefn
+
+
+
 @deftypefn {Method on @code{mglData}} @code{void} Link (@code{mglData &}from)
 @deftypefnx {Method on @code{mglData}} @code{void} Link (@code{mreal *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
 @deftypefnx {C function} @code{void} mgl_data_link (@code{HMDT} dat, @code{mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
@@ -641,6 +648,15 @@ Join data arrays from several text files. The file names are determined by funct
 Join data arrays from several text files which filenames satisfied the template @var{templ} (for example, @var{templ}=@code{"t_*.dat"}). The data load one-by-one in the same slice if @var{as_slice}=@code{false} or as slice-by-slice if @var{as_slice}=@code{true}.
 @end deftypefn
 
+ at anchor{scanfile}
+ at deftypefn {MGL command} {} scanfile @sc{dat} 'fname' 'templ'
+ at ifclear UDAV
+ at deftypefnx {Method on @code{mglData}} @code{bool} ScanFile (@code{const char *}fname, @code{const char *}templ)
+ at deftypefnx {C function} @code{int} mgl_data_scan_file (@code{HMDT} dat, @code{const char *}fname, @code{const char *}templ)
+ at end ifclear
+Read file @var{fname} line-by-line and scan each line for numbers according the template @var{templ}. The numbers denoted as @samp{%g} in the template. @sref{Saving and scanning file}
+ at end deftypefn
+
 @anchor{save}
 @deftypefn {MGL command} {} save dat 'fname'
 @ifclear UDAV
@@ -648,9 +664,14 @@ Join data arrays from several text files which filenames satisfied the template
 @deftypefnx {C function} @code{void} mgl_data_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
 @deftypefnx {C function} @code{void} mgl_datac_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
 @end ifclear
-Saves the whole data array (for @var{ns}=@code{-1}) or only @var{ns}-th slice to text file.
+Saves the whole data array (for @var{ns}=@code{-1}) or only @var{ns}-th slice to the text file @var{fname}.
 @end deftypefn
 
+ at deftypefn {MGL command} {} save 'str' 'fname' ['mode'='a']
+Saves the string @var{str} to the text file @var{fname}. For parameter @var{mode}=@samp{a} will append string to the file (default); for @var{mode}=@samp{w} will overwrite the file. @sref{Saving and scanning file}
+ at end deftypefn
+
+
 @anchor{readhdf}
 @deftypefn {MGL command} {} readhdf @sc{dat} 'fname' 'dname'
 @ifclear UDAV
@@ -663,7 +684,7 @@ Reads data array named @var{dname} from HDF5 or HDF4 file. This function does no
 @end deftypefn
 
 @anchor{savehdf}
- at deftypefn {MGL command} {} savehdf dat 'fname' 'dname'
+ at deftypefn {MGL command} {} savehdf dat 'fname' 'dname' [@code{rewrite}=@code{off}]
 @ifclear UDAV
 @deftypefnx {Method on @code{mglDataA}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
 @deftypefnx {C function} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
@@ -916,6 +937,16 @@ Gets array of arguments of the data.
 @end deftypefn
 @end ifclear
 
+ at anchor{pulse}
+ at deftypefn {MGL command} {} pulse @sc{res} dat 'dir'
+ at ifclear UDAV
+ at deftypefnx {Method on @code{mglData}} @code{mglData} Pulse (@code{const char *}dir) @code{const}
+ at deftypefnx {C function} @code{HMDT} mgl_data_pulse (@code{HCDT} dat, @code{const char *}dir)
+ at end ifclear
+Find pulse properties along direction @var{dir}: pulse maximum (in column 0) and its position (in column 1), pulse width near maximum (in column 3) and by half height (in column 2), energy in first pulse (in column 4). NAN values are used for widths if maximum is located near the edges. Note, that there is uncertainty for complex data. Usually one should use square of absolute value (i.e. |dat[i]|^2) for them. So, MathGL don't provide this function for complex data arrays. However, C fun [...]
+ at end deftypefn
+
+
 @c ------------------------------------------------------------------
 @external{}
 @node Data changing, Interpolation, Make another data, Data processing
@@ -1215,6 +1246,19 @@ Prints string @var{txt} as message.
 Prints value of number @var{val} as message.
 @end deftypefn
 
+ at anchor{print}
+ at deftypefn {MGL command} {} print dat
+ at deftypefnx {MGL command} {} print 'txt'
+ at deftypefnx {MGL command} {} print val
+The same as @ref{info} but immediately print to stdout.
+ at end deftypefn
+
+ at anchor{echo}
+ at deftypefn {MGL command} {} echo dat
+Prints all values of the data array @var{dat} as message.
+ at end deftypefn
+
+
 @cindex GetNx
 @cindex GetNy
 @cindex GetNz
@@ -1589,10 +1633,42 @@ Prepare coefficients for global cubic spline interpolation.
 @deftypefnx {Global function} @code{dual} mglGSplineC (@code{const mglDataA &}coef, @code{mreal} dx, @code{dual *}d1=@code{0}, @code{dual *}d2=@code{0})
 @deftypefnx {C function} @code{mreal} mgl_gspline (@code{HCDT} coef, @code{mreal} dx, @code{mreal *}d1, @code{mreal *}d2)
 @deftypefnx {C function} @code{dual} mgl_gsplinec (@code{HCDT} coef, @code{mreal} dx, @code{dual *}d1, @code{dual *}d2)
-Evaluate global cubic spline (and its 1st and 2nd derivatives @var{d1}, @var{d2} if they are not @code{NULL}) using prepared coefficients @var{coef} at point @var{dx}+ at var{x0} (where @var{x0} is 1st element of data @var{x} provided to @code{mglGSpline*Init()} function). 
+Evaluate global cubic spline (and its 1st and 2nd derivatives @var{d1}, @var{d2} if they are not @code{NULL}) using prepared coefficients @var{coef} at point @var{dx}+ at var{x0} (where @var{x0} is 1st element of data @var{x} provided to @code{mglGSpline*Init()} function).
+ at end deftypefn
+
+ at end ifclear
+
+
+ at anchor{ifs2d}
+ at deftypefn {MGL command} {} ifs2d @sc{res} dat @code{num} [@code{skip=20}]
+ at ifclear UDAV
+ at deftypefnx {Global function} @code{mglData} mglIFS2d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
+ at deftypefnx {C function} @code{HMDT} mgl_data_ifs_2d (@code{HCDT} dat, @code{long} num, @code{long} skip)
+ at end ifclear
+Computes @var{num} points @{x[i]=res[0,i], y[i]=res[1,i]@} for fractal using iterated function system. Matrix @var{dat} is used for generation according the formulas
+ at verbatim
+x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[4,i];
+y[i+1] = dat[2,i]*x[i] + dat[3,i]*y[i] + dat[5,i];
+ at end verbatim
+Value @code{dat[6,i]} is used as weight factor for i-th row of matrix @var{dat}. At this first @var{skip} iterations will be omitted. Data array @var{dat} must have x-size greater or equal to 7. @sref{IFS sample}
 @end deftypefn
 
+ at anchor{ifs3d}
+ at deftypefn {MGL command} {} ifs3d @sc{res} dat @code{num} [@code{skip=20}]
+ at ifclear UDAV
+ at deftypefnx {Global function} @code{mglData} mglIFS3d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
+ at deftypefnx {C function} @code{HMDT} mgl_data_ifs_3d (@code{HCDT} dat, @code{long} num, @code{long} skip)
 @end ifclear
+Computes @var{num} points @{x[i]=res[0,i], y[i]=res[1,i], z[i]=res[2,i]@} for fractal using iterated function system. Matrix @var{dat} is used for generation according the formulas
+ at verbatim
+x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[2,i]*z[i] + dat[9,i];
+y[i+1] = dat[3,i]*x[i] + dat[4,i]*y[i] + dat[5,i]*z[i] + dat[10,i];
+z[i+1] = dat[6,i]*x[i] + dat[7,i]*y[i] + dat[8,i]*z[i] + dat[10,i];
+ at end verbatim
+Value @code{dat[12,i]} is used as weight factor for i-th row of matrix @var{dat}. At this first @var{skip} iterations will be omitted. Data array @var{dat} must have x-size greater or equal to 13. @sref{IFS sample}
+ at end deftypefn
+
+
 
 @c ------------------------------------------------------------------
 @external{}
diff --git a/texinfo/data_ru.texi b/texinfo/data_ru.texi
index 8299764..ab64604 100644
--- a/texinfo/data_ru.texi
+++ b/texinfo/data_ru.texi
@@ -327,7 +327,7 @@ a_ij^new = a_i^old where j=0... at var{n1}. Соответственно, для @v
 @deftypefnx {Функция С} @code{void} mgl_data_join (@code{HMDT} dat, @code{HCDT} vdat)
 @deftypefnx {Функция С} @code{void} mgl_datac_join (@code{HADT} dat, @code{HCDT} vdat)
 @end ifclear
-Объединяет данные из массива @var{vdat} с данными массива @var{dat}. При этом, функция увеличивает размер массива @var{dat}: в z-направлении для 3D массивов с одинаковыми размерами по x и y; в y-направлении для 2D массивов с одинаковыми размерами по x; в x-направлении в остальных случаях.
+Объединяет данные из массива @var{vdat} с данными массива @var{dat}. При этом, функция увеличивает размер массива @var{dat}: в z-направлении для массивов с одинаковыми размерами по x и y; в y-направлении для массивов с одинаковыми размерами по x; в x-направлении в остальных случаях.
 @end deftypefn
 
 @c ------------------------------------------------------------------
@@ -424,6 +424,12 @@ a_ij^new = a_i^old where j=0... at var{n1}. Соответственно, для @v
 Выделяет память и сканирует массив данных из строки.
 @end deftypefn
 
+
+ at deftypefn {Method on @code{mglData}} @code{void} SetList (@code{long} n, ...)
+Allocate memory and set data from variable argument list of @emph{double} values. Note, you need to specify decimal point @samp{.} for integer values! For example, the code @code{SetList(2,0.,1.);} is correct, but the code @code{SetList(2,0,1);} is incorrect.
+ at end deftypefn
+
+
 @deftypefn {Метод класса @code{mglData}} @code{void} Link (@code{mglData &}from)
 @deftypefnx {Метод класса @code{mglData}} @code{void} Link (@code{mreal *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
 @deftypefnx {Функция С} @code{void} mgl_data_link (@code{HMDT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
@@ -549,10 +555,10 @@ a_ij^new = a_i^old where j=0... at var{n1}. Соответственно, для @v
 @end deftypefn
 
 @anchor{gspline}
- at deftypefn {MGL command} {} gspline dat xdat vdat [sl=-1]
+ at deftypefn {Команда MGL} {} gspline dat xdat vdat [sl=-1]
 @ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} RefillGS (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
- at deftypefnx {C function} @code{void} mgl_data_refill_gs (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
+ at deftypefnx {Функция С} @code{void} mgl_data_refill_gs (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
 @end ifclear
 Заполняет значениями глобального кубического сплайна для массива @var{v} в точках @var{x}=@code{X[i]}, где @code{X} равномерно распределен в диапазоне [@var{x1}, at var{x2}] и имеет такой же размер как и заполняемый массив. Если параметр @var{sl} равен 0 или положительный, то изменятся будет только @var{sl}-ый срез.
 @end deftypefn
@@ -637,6 +643,15 @@ a_ij^new = a_i^old where j=0... at var{n1}. Соответственно, для @v
 Объединяет данные из нескольких текстовых файлов, чьи имена удовлетворяют шаблону @var{templ} (например, @var{templ}=@code{"t_*.dat"}). Данные загружаются один за другим в один и тот же срез данных (при @var{as_slice}=@code{false}) или срез-за-срезом (при @var{as_slice}=@code{true}).
 @end deftypefn
 
+ at anchor{scanfile}
+ at deftypefn {Команда MGL} {} scanfile @sc{dat} 'fname' 'templ'
+ at ifclear UDAV
+ at deftypefnx {Метод класса @code{mglData}} @code{bool} ScanFile (@code{const char *}fname, @code{const char *}templ)
+ at deftypefnx {Функция С} @code{int} mgl_data_scan_file (@code{HMDT} dat, @code{const char *}fname, @code{const char *}templ)
+ at end ifclear
+Читает файл @var{fname} построчно и каждую строку сканирует на соответствие шаблону @var{templ}. Полученные числа (обозначаются как @samp{%g} в шаблоне) сохраняются. @sref{Saving and scanning file}
+ at end deftypefn
+
 @anchor{save}
 @deftypefn {Команда MGL} {} save dat 'fname'
 @ifclear UDAV
@@ -647,6 +662,10 @@ a_ij^new = a_i^old where j=0... at var{n1}. Соответственно, для @v
 Сохраняет весь массив данных при @var{ns}=@code{-1} или только @var{ns}-ый срез в текстовый файл.
 @end deftypefn
 
+ at deftypefn {Команда MGL} {} save 'str' 'fname' ['mode'='a']
+Сохраняет строку @var{str} в файл @var{fname}. Для параметра @var{mode}=@samp{a} происходит добавление строки (по умолчанию): для  @var{mode}=@samp{w} файл будет перезаписан. @sref{Saving and scanning file}
+ at end deftypefn
+
 @anchor{readhdf}
 @deftypefn {Команда MGL} {} readhdf @sc{dat} 'fname' 'dname'
 @ifclear UDAV
@@ -659,7 +678,7 @@ a_ij^new = a_i^old where j=0... at var{n1}. Соответственно, для @v
 @end deftypefn
 
 @anchor{savehdf}
- at deftypefn {Команда MGL} {} savehdf dat 'fname' 'dname'
+ at deftypefn {Команда MGL} {} savehdf dat 'fname' 'dname' [@code{rewrite}=@code{off}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglDataA}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
 @deftypefnx {Функция С} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
@@ -906,6 +925,15 @@ res_k = \sum_ij how(x_i,y_j,z_k) a_ij/ \sum_ij a_ij
 @end deftypefn
 @end ifclear
 
+ at anchor{pulse}
+ at deftypefn {Команда MGL} {} pulse @sc{res} dat 'dir'
+ at ifclear UDAV
+ at deftypefnx {Метод класса @code{mglData}} @code{mglData} Pulse (@code{const char *}dir) @code{const}
+ at deftypefnx {Функция С} @code{HMDT} mgl_data_pulse (@code{HCDT} dat, @code{const char *}dir)
+ at end ifclear
+Находит параметры импульса вдоль направления @var{dir}: максимальное значение (в колонке 0), его положение (в колонке 1), ширина по параболлической аппроксимации (в колонке 3) и по полувысоте (в колонке 2), энергию около максимума (в колонке 4). NAN значения используются для ширин если максимум расположен вблизи границ массива. Отмечу, что для комплексных массивов есть неопределенность определения параметров. Обычно следует использовать квадрат абсолютного значения амплитуды (т.е. |dat[i [...]
+ at end deftypefn
+
 @c ------------------------------------------------------------------
 @external{}
 @node Data changing, Interpolation, Make another data, Data processing
@@ -1205,6 +1233,19 @@ These functions change the data in some direction like differentiations, integra
 Печатает значение числа @var{val} как сообщение.
 @end deftypefn
 
+ at anchor{print}
+ at deftypefn {Команда MGL} {} print dat
+ at deftypefnx {Команда MGL} {} print 'txt'
+ at deftypefnx {Команда MGL} {} print val
+Аналогично @ref{info}, но сразу выводит в stdout.
+ at end deftypefn
+
+ at anchor{echo}
+ at deftypefn {Команда MGL} {} echo dat
+Печатает все значения массива @var{dat} как сообщение.
+ at end deftypefn
+
+
 @cindex GetNx
 @cindex GetNy
 @cindex GetNz
@@ -1499,12 +1540,12 @@ These functions change the data in some direction like differentiations, integra
 @end deftypefn
 
 @anchor{ode}
- at deftypefn {MGL command} {} ode @sc{res} 'df' 'var' ini [@code{dt=0.1 tmax=10}]
+ at deftypefn {Команда MGL} {} ode @sc{res} 'df' 'var' ini [@code{dt=0.1 tmax=10}]
 @ifclear UDAV
 @deftypefnx {Global function} @code{mglData} mglODE (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
- at deftypefnx {C function} @code{HMDT} mgl_ode_solve_str (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
- at deftypefnx {C function} @code{HMDT} mgl_ode_solve (@code{void (*}df at code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax)
- at deftypefnx {C function} @code{HMDT} mgl_ode_solve_ex (@code{void (*}df at code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax, @code{void (*}bord at code{)(mreal *x, const mreal *xprev, void *par)})
+ at deftypefnx {Функция С} @code{HMDT} mgl_ode_solve_str (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
+ at deftypefnx {Функция С} @code{HMDT} mgl_ode_solve (@code{void (*}df at code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax)
+ at deftypefnx {Функция С} @code{HMDT} mgl_ode_solve_ex (@code{void (*}df at code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax, @code{void (*}bord at code{)(mreal *x, const mreal *xprev, void *par)})
 @end ifclear
 Решает систему обыкновенных дифференциальных уравнений dx/dt = df(x). Функции @var{df} могут быть заданны строкой с разделенными ';' формулами (аргумент @var{var} задает символы для переменных x[i]) или указателем на функцию, которая заполняет @code{dx} по заданным значениям @code{x}. Параметры @var{ini}, @var{dt}, @var{tmax} задают начальные значения, шаг и максимальное время интегрирования. Результат -- массив с размером @{@var{n} * int(@var{tmax}/@var{dt}+1)@}.
 @end deftypefn
@@ -1581,6 +1622,35 @@ These functions change the data in some direction like differentiations, integra
 
 @end ifclear
 
+ at anchor{ifs2d}
+ at deftypefn {Команда MGL} {} ifs2d @sc{res} dat @code{num} [@code{skip=20}]
+ at ifclear UDAV
+ at deftypefnx {Global function} @code{mglData} mglIFS2d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
+ at deftypefnx {Функция С} @code{HMDT} mgl_data_ifs_2d (@code{HCDT} dat, @code{long} num, @code{long} skip)
+ at end ifclear
+Находит @var{num} точек @{x[i]=res[0,i], y[i]=res[1,i]@} фрактала с использованием итерационной системы функций (IFS). Матрица @var{dat} используется для генерации в соответствии с формулами
+ at verbatim
+x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[4,i];
+y[i+1] = dat[2,i]*x[i] + dat[3,i]*y[i] + dat[5,i];
+ at end verbatim
+Значение @code{dat[6,i]} -- весовой коэффициент для i-ой строки матрицы @var{dat}. Первые @var{skip} итераций будут опущены. Массив @var{dat} должен иметь размер по x больше или равный 7. @sref{IFS sample}
+ at end deftypefn
+
+ at anchor{ifs3d}
+ at deftypefn {Команда MGL} {} ifs3d @sc{res} dat @code{num} [@code{skip=20}]
+ at ifclear UDAV
+ at deftypefnx {Global function} @code{mglData} mglIFS3d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
+ at deftypefnx {Функция С} @code{HMDT} mgl_data_ifs_3d (@code{HCDT} dat, @code{long} num, @code{long} skip)
+ at end ifclear
+Находит @var{num} точек @{x[i]=res[0,i], y[i]=res[1,i], z[i]=res[2,i]@} фрактала с использованием итерационной системы функций (IFS). Матрица @var{dat} используется для генерации в соответствии с формулами
+ at verbatim
+x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[2,i]*z[i] + dat[9,i];
+y[i+1] = dat[3,i]*x[i] + dat[4,i]*y[i] + dat[5,i]*z[i] + dat[10,i];
+z[i+1] = dat[6,i]*x[i] + dat[7,i]*y[i] + dat[8,i]*z[i] + dat[10,i];
+ at end verbatim
+Значение @code{dat[6,i]} -- весовой коэффициент для i-ой строки матрицы @var{dat}. Первые @var{skip} итераций будут опущены. Массив @var{dat} должен иметь размер по x больше или равный 13. @sref{IFS sample}
+ at end deftypefn
+
 @c ------------------------------------------------------------------
 @external{}
 @node Evaluate expression, Special data classes, Global functions, Data processing
diff --git a/texinfo/ex_mgl_en.texi b/texinfo/ex_mgl_en.texi
index 035913e..918c67c 100644
--- a/texinfo/ex_mgl_en.texi
+++ b/texinfo/ex_mgl_en.texi
@@ -883,6 +883,9 @@ Basically, you can put this text after the script. Note, that you need to termin
 * Tube sample::
 * Tape sample::
 * Torus sample::
+* Lamerey sample::
+* Bifurcation sample::
+* Pmap sample::
 @end menu
 
 
@@ -1384,7 +1387,7 @@ plot xc yc z 'k':tape xc yc z 'zg':tape xc yc z 'zg#'
 
 @c ------------------------------------------------------------------
 @external{}
- at node Torus sample, , Tape sample, 1D samples
+ at node Torus sample, Lamerey sample, Tape sample, 1D samples
 @subsection Torus sample
 @nav{}
 
@@ -1406,6 +1409,61 @@ torus y1 y2 '#'
 
 @pfig{torus, Example of Torus()}
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Lamerey sample, Bifurcation sample, Torus sample, 1D samples
+ at subsection Lamerey sample
+ at nav{}
+
+Function @ref{lamerey} draw Lamerey diagram. The sample code is:
+ at verbatim
+subplot 1 1 0 '<_':title 'Lamerey sample'
+axis:xlabel '\i x':ylabel '\bar{\i x} = 2 \i{x}'
+fplot 'x' 'k='
+fplot '2*x' 'b'
+
+lamerey 0.00097 '2*x' 'rv~';size 2
+lamerey -0.00097 '2*x' 'rv~';size 2
+ at end verbatim
+
+ at pfig{lamerey, Example of Lamerey()}
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Bifurcation sample, Pmap sample, Lamerey sample, 1D samples
+ at subsection Bifurcation sample
+ at nav{}
+
+Function @ref{bifurcation} draw Bifurcation diagram for logistic map. The sample code is:
+ at verbatim
+subplot 1 1 0 '<_':title 'Bifurcation sample'
+ranges 0 4 0 1:axis
+bifurcation 0.005 'x*y*(1-y)' 'r'
+ at end verbatim
+
+ at pfig{bifurcation, Example of Bifurcation()}
+
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Pmap sample, , Bifurcation sample, 1D samples
+ at subsection Pmap sample
+ at nav{}
+
+Function @ref{pmap} draw Poincare map -- show intersections of the curve and the surface. The sample code is:
+ at verbatim
+subplot 1 1 0 '<_^':title 'Poincare map sample'
+ode r 'cos(y)+sin(z);cos(z)+sin(x);cos(x)+sin(y)' 'xyz' [0.1,0,0] 0.1 100
+rotate 40 60:copy x r(0):copy y r(1):copy z r(2)
+ranges x y z
+axis:plot x y z 'b':fsurf '0'
+xlabel '\i x' 0:ylabel '\i y' 0:zlabel '\i z'
+
+pmap x y z z 'b#o'
+ at end verbatim
+
+ at pfig{pmap, Example of Pmap()}
+
 
 @c ------------------------------------------------------------------
 @external{}
@@ -1815,6 +1873,7 @@ Basically, you can put this text after the script. Note, that you need to termin
 * ContF projection sample::
 * TriPlot and QuadPlot::
 * Dots sample::
+* IFS sample::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -2009,7 +2068,7 @@ contfz {sum c 'z'} '' -1
 
 @c ------------------------------------------------------------------
 @external{}
- at node TriPlot and QuadPlot, Axial sample, ContF projection sample, 3D samples
+ at node TriPlot and QuadPlot, Dots sample, ContF projection sample, 3D samples
 @subsection TriPlot and QuadPlot
 @nav{}
 
@@ -2046,7 +2105,7 @@ tricont t xt yt zt 'B'
 
 @c ------------------------------------------------------------------
 @external{}
- at node Dots sample, , TriPlot and QuadPlot, 3D samples
+ at node Dots sample, IFS sample, TriPlot and QuadPlot, 3D samples
 @subsection Dots sample
 @nav{}
 
@@ -2067,6 +2126,38 @@ box:tens x y z x ' .'
 
 @pfig{dots, Example of Dots()}
 
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node IFS sample, , Dots sample, 3D samples
+ at subsection IFS sample
+ at nav{}
+
+Commands @ref{ifs2d} and @ref{ifs3d} generate points for fractals using iterated function system in 2d and 3d cases correspondingly. The sample codes are:
+ at verbatim
+list A [0.33,0,0,0.33,0,0,0.2] [0.33,0,0,0.33,0.67,0,0.2] [0.33,0,0,0.33,0.33,0.33,0.2]\
+       [0.33,0,0,0.33,0,0.67,0.2] [0.33,0,0,0.33,0.67,0.67,0.2]
+ifs2d fx fy A 100000
+subplot 1 1 0 '<_':title 'IFS 2d sample'
+ranges fx fy:axis
+plot fx fy 'r#o ';size 0.05
+ at end verbatim
+
+ at pfig{ifs2d, Example of IFS fractal (2d case).}
+
+ at verbatim
+list A [0,0,0,0,.18,0,0,0,0,0,0,0,.01] [.85,0,0,0,.85,.1,0,-0.1,0.85,0,1.6,0,.85]\
+        [.2,-.2,0,.2,.2,0,0,0,0.3,0,0.8,0,.07] [-.2,.2,0,.2,.2,0,0,0,0.3,0,0.8,0,.07]
+ifs3d f A 100000
+title 'IFS 3d sample':rotate 50 60
+ranges f(0) f(1) f(2):axis:box
+dots f(0) f(1) f(2) 'G#o';size 0.05
+ at end verbatim
+
+ at pfig{ifs3d, Example of IFS fractal (3d case).}
+
+
+
 @c ------------------------------------------------------------------
 @external{}
 @node Vector field samples, Hints, 3D samples, Examples
@@ -2262,11 +2353,13 @@ In this section I've included some small hints and advices for the improving of
 * Nonlinear fitting hints::
 * PDE solving hints::
 * Drawing phase plain::
-* MGL parser using::
+* Pulse properties::
+* Using MGL parser::
 * Using options::
 * ``Templates''::
 * Stereo image::
 * Reduce memory usage::
+* Saving and scanning file::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -2689,17 +2782,17 @@ subplot 3 3 2:text 0.5 0.5 'Hist and\n{}MultiPlot\n{}sample' 'a' -3
 
 Nonlinear fitting is rather simple. All that you need is the data to fit, the approximation formula and the list of coefficients to fit (better with its initial guess values). Let me demonstrate it on the following simple example. First, let us use sin function with some random noise:
 @verbatim
-new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'
+new dat 100 '0.4*rnd+0.1+sin(2*pi*x)'
 new in 100 '0.3+sin(2*pi*x)'
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
+title 'Fitting sample':yrange -2 2:box:axis:plot dat 'k. '
 @end verbatim
 
 The next step is the fitting itself. For that let me specify an initial values @var{ini} for coefficients @samp{abc} and do the fitting for approximation formula @samp{a+b*sin(c*x)}
 @verbatim
-list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini
+list ini 1 1 3:fit res dat 'a+b*sin(c*x)' 'abc' ini
 @end verbatim
 Now display it
 @verbatim
@@ -2713,10 +2806,10 @@ NOTE! the fitting results may have strong dependence on initial values for coeff
 
 The full sample code for nonlinear fitting is:
 @verbatim
-new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'
+new dat 100 '0.4*rnd+0.1+sin(2*pi*x)'
 new in 100 '0.3+sin(2*pi*x)'
-list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
+list ini 1 1 3:fit res dat 'a+b*sin(c*x)' 'abc' ini
+title 'Fitting sample':yrange -2 2:box:axis:plot dat 'k. '
 plot res 'r':plot in 'b'
 text -0.9 -1.3 'fitted:' 'r:L'
 putsfit 0 -1.8 'y = ' 'r'
@@ -2782,7 +2875,7 @@ text 0.7 -0.05 'central ray'
 
 @c ------------------------------------------------------------------
 @external{}
- at node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+ at node Drawing phase plain, Pulse properties, PDE solving hints, Hints
 @subsection Drawing phase plain
 @nav{}
 
@@ -2819,8 +2912,43 @@ next
 
 @c ------------------------------------------------------------------
 @external{}
- at node MGL parser using, Using options, Drawing phase plain, Hints
- at subsection MGL parser using
+ at node Pulse properties, Using MGL parser, Drawing phase plain, Hints
+ at subsection Pulse properties
+ at nav{}
+
+There is common task in optics to determine properties of wave pulses or wave beams. MathGL provide special function @ref{pulse} which return the pulse properties (maximal value, center of mass, width and so on). Its usage is rather simple. Here I just illustrate it on the example of Gaussian pulse, where all parameters are obvious.
+ at verbatim
+subplot 1 1 0 '<_':title 'Pulse sample'
+# first prepare pulse itself
+new a 100 'exp(-6*x^2)'
+
+# get pulse parameters
+pulse b a 'x'
+
+# positions and widths are normalized on the number of points. So, set proper axis scale.
+ranges 0 a.nx-1 0 1
+axis:plot a # draw pulse and axis
+
+# now visualize found pulse properties
+define m a.max # maximal amplitude
+# approximate position of maximum
+line b(1) 0 b(1) m 'r='
+# width at half-maximum (so called FWHM)
+line b(1)-b(3)/2 0  b(1)-b(3)/2 m 'm|'
+line b(1)+b(3)/2 0  b(1)+b(3)/2 m 'm|'
+line 0 0.5*m a.nx-1 0.5*m 'h'
+# parabolic approximation near maximum
+new x 100 'x'
+plot b(0)*(1-((x-b(1))/b(2))^2) 'g'
+ at end verbatim
+
+ at pfig{pulse, Example of determining of pulse properties.}
+
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Using MGL parser, Using options, Pulse properties, Hints
+ at subsection Using MGL parser
 @nav{}
 
 MGL scripts can contain loops, conditions and user-defined functions. Below I show very simple example of its usage:
@@ -2846,7 +2974,7 @@ next
 
 @c ------------------------------------------------------------------
 @external{}
- at node Using options, ``Templates'', MGL parser using, Hints
+ at node Using options, ``Templates'', Using MGL parser, Hints
 @subsection Using options
 @nav{}
 
@@ -2925,7 +3053,7 @@ subplot 2 1 1:rotate 50 60-1:box:surf a
 
 @c ------------------------------------------------------------------
 @external{}
- at node Reduce memory usage, , Stereo image, Hints
+ at node Reduce memory usage, Saving and scanning file, Stereo image, Hints
 @subsection Reduce memory usage
 @nav{}
 
@@ -2939,6 +3067,39 @@ for $1 0 1000
 next
 @end verbatim
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Saving and scanning file, , Reduce memory usage, Hints
+ at subsection Scanning file
+ at nav{}
+
+MathGL have possibilities to write textual information into file with variable values by help of @ref{save} command. This is rather useful for generating an ini-files or preparing human-readable textual files. For example, lets create some textual file
+ at verbatim
+subplot 1 1 0 '<_':title 'Save and scanfile sample'
+list a 1 -1 0
+save 'This is test: 0 -> ',a(0),' q' 'test.txt' 'w'
+save 'This is test: 1 -> ',a(1),' q' 'test.txt'
+save 'This is test: 2 -> ',a(2),' q' 'test.txt'
+ at end verbatim
+It contents look like
+ at verbatim
+This is test: 0 -> 1 q
+This is test: 1 -> -1 q
+This is test: 2 -> 0 q
+ at end verbatim
+Note, that I use option @samp{w} at first call of @code{save} to overwrite the contents of the file.
+
+Let assume now that you want to read this values (i.e. [[0,1],[1,-1],[2,0]]) from the file. You can use @ref{scanfile} for that. The desired values was written using template @samp{This is test: %g -> %g q}. So, just use
+ at verbatim
+scanfile a 'test.txt' 'This is test: %g -> %g'
+ at end verbatim
+and plot it to for assurance
+ at verbatim
+ranges a(0) a(1):axis:plot a(0) a(1) 'o'
+ at end verbatim
+
+Note, I keep only the leading part of template (i.e. @samp{This is test: %g -> %g} instead of @samp{This is test: %g -> %g q}), because there is no important for us information after the second number in the line.
+
 @c ==================================================================
 
 @external{}
diff --git a/texinfo/ex_mgl_ru.texi b/texinfo/ex_mgl_ru.texi
index 9c71b5c..ddc3186 100644
--- a/texinfo/ex_mgl_ru.texi
+++ b/texinfo/ex_mgl_ru.texi
@@ -883,6 +883,9 @@ Basically, you can put this text after the script. Note, that you need to termin
 * Tube sample::
 * Tape sample::
 * Torus sample::
+* Lamerey sample::
+* Bifurcation sample::
+* Pmap sample::
 @end menu
 
 
@@ -1384,7 +1387,7 @@ plot xc yc z 'k':tape xc yc z 'zg':tape xc yc z 'zg#'
 
 @c ------------------------------------------------------------------
 @external{}
- at node Torus sample, , Tape sample, 1D samples
+ at node Torus sample, Lamerey sample, Tape sample, 1D samples
 @subsection Torus sample
 @nav{}
 
@@ -1406,6 +1409,61 @@ torus y1 y2 '#'
 
 @pfig{torus, Example of Torus()}
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Lamerey sample, Bifurcation sample, Torus sample, 1D samples
+ at subsection Lamerey sample
+ at nav{}
+
+Function @ref{lamerey} draw Lamerey diagram. The sample code is:
+ at verbatim
+subplot 1 1 0 '<_':title 'Lamerey sample'
+axis:xlabel '\i x':ylabel '\bar{\i x} = 2 \i{x}'
+fplot 'x' 'k='
+fplot '2*x' 'b'
+
+lamerey 0.00097 '2*x' 'rv~';size 2
+lamerey -0.00097 '2*x' 'rv~';size 2
+ at end verbatim
+
+ at pfig{lamerey, Example of Lamerey()}
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Bifurcation sample, Pmap sample, Lamerey sample, 1D samples
+ at subsection Bifurcation sample
+ at nav{}
+
+Function @ref{bifurcation} draw Bifurcation diagram for logistic map. The sample code is:
+ at verbatim
+subplot 1 1 0 '<_':title 'Bifurcation sample'
+ranges 0 4 0 1:axis
+bifurcation 0.005 'x*y*(1-y)' 'r'
+ at end verbatim
+
+ at pfig{bifurcation, Example of Bifurcation()}
+
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Pmap sample, , Bifurcation sample, 1D samples
+ at subsection Pmap sample
+ at nav{}
+
+Function @ref{pmap} draw Poincare map -- show intersections of the curve and the surface. The sample code is:
+ at verbatim
+subplot 1 1 0 '<_^':title 'Poincare map sample'
+ode r 'cos(y)+sin(z);cos(z)+sin(x);cos(x)+sin(y)' 'xyz' [0.1,0,0] 0.1 100
+rotate 40 60:copy x r(0):copy y r(1):copy z r(2)
+ranges x y z
+axis:plot x y z 'b':fsurf '0'
+xlabel '\i x' 0:ylabel '\i y' 0:zlabel '\i z'
+
+pmap x y z z 'b#o'
+ at end verbatim
+
+ at pfig{pmap, Example of Pmap()}
+
 
 @c ------------------------------------------------------------------
 @external{}
@@ -1814,6 +1872,7 @@ Basically, you can put this text after the script. Note, that you need to termin
 * ContF projection sample::
 * TriPlot and QuadPlot::
 * Dots sample::
+* IFS sample::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -2008,7 +2067,7 @@ contfz {sum c 'z'} '' -1
 
 @c ------------------------------------------------------------------
 @external{}
- at node TriPlot and QuadPlot, Axial sample, ContF projection sample, 3D samples
+ at node TriPlot and QuadPlot, Dots sample, ContF projection sample, 3D samples
 @subsection TriPlot and QuadPlot
 @nav{}
 
@@ -2045,7 +2104,7 @@ tricont t xt yt zt 'B'
 
 @c ------------------------------------------------------------------
 @external{}
- at node Dots sample, , TriPlot and QuadPlot, 3D samples
+ at node Dots sample, IFS sample, TriPlot and QuadPlot, 3D samples
 @subsection Dots sample
 @nav{}
 
@@ -2066,6 +2125,39 @@ box:tens x y z x ' .'
 
 @pfig{dots, Example of Dots()}
 
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node IFS sample, , Dots sample, 3D samples
+ at subsection IFS sample
+ at nav{}
+
+Commands @ref{ifs2d} and @ref{ifs3d} generate points for fractals using iterated function system in 2d and 3d cases correspondingly. The sample codes are:
+ at verbatim
+list A [0.33,0,0,0.33,0,0,0.2] [0.33,0,0,0.33,0.67,0,0.2] [0.33,0,0,0.33,0.33,0.33,0.2]\
+       [0.33,0,0,0.33,0,0.67,0.2] [0.33,0,0,0.33,0.67,0.67,0.2]
+ifs2d fx fy A 100000
+subplot 1 1 0 '<_':title 'IFS 2d sample'
+ranges fx fy:axis
+plot fx fy 'r#o ';size 0.05
+ at end verbatim
+
+ at pfig{ifs2d, Example of IFS fractal (2d case).}
+
+ at verbatim
+list A [0,0,0,0,.18,0,0,0,0,0,0,0,.01] [.85,0,0,0,.85,.1,0,-0.1,0.85,0,1.6,0,.85]\
+        [.2,-.2,0,.2,.2,0,0,0,0.3,0,0.8,0,.07] [-.2,.2,0,.2,.2,0,0,0,0.3,0,0.8,0,.07]
+ifs3d f A 100000
+title 'IFS 3d sample':rotate 50 60
+ranges f(0) f(1) f(2):axis:box
+dots f(0) f(1) f(2) 'G#o';size 0.05
+ at end verbatim
+
+ at pfig{ifs3d, Example of IFS fractal (3d case).}
+
+
+
+
 @c ------------------------------------------------------------------
 @external{}
 @node Vector field samples, Hints, 3D samples, Examples
@@ -2261,11 +2353,13 @@ In this section I've included some small hints and advices for the improving of
 * Nonlinear fitting hints::
 * PDE solving hints::
 * Drawing phase plain::
-* MGL parser using::
+* Pulse properties::
+* Using MGL parser::
 * Using options::
 * ``Templates''::
 * Stereo image::
 * Reduce memory usage::
+* Saving and scanning file::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -2688,17 +2782,17 @@ subplot 3 3 2:text 0.5 0.5 'Hist and\n{}MultiPlot\n{}sample' 'a' -3
 
 Nonlinear fitting is rather simple. All that you need is the data to fit, the approximation formula and the list of coefficients to fit (better with its initial guess values). Let me demonstrate it on the following simple example. First, let us use sin function with some random noise:
 @verbatim
-new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'
+new dat 100 '0.4*rnd+0.1+sin(2*pi*x)'
 new in 100 '0.3+sin(2*pi*x)'
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
+title 'Fitting sample':yrange -2 2:box:axis:plot dat 'k. '
 @end verbatim
 
 The next step is the fitting itself. For that let me specify an initial values @var{ini} for coefficients @samp{abc} and do the fitting for approximation formula @samp{a+b*sin(c*x)}
 @verbatim
-list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini
+list ini 1 1 3:fit res dat 'a+b*sin(c*x)' 'abc' ini
 @end verbatim
 Now display it
 @verbatim
@@ -2712,10 +2806,10 @@ NOTE! the fitting results may have strong dependence on initial values for coeff
 
 The full sample code for nonlinear fitting is:
 @verbatim
-new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'
+new dat 100 '0.4*rnd+0.1+sin(2*pi*x)'
 new in 100 '0.3+sin(2*pi*x)'
-list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
+list ini 1 1 3:fit res dat 'a+b*sin(c*x)' 'abc' ini
+title 'Fitting sample':yrange -2 2:box:axis:plot dat 'k. '
 plot res 'r':plot in 'b'
 text -0.9 -1.3 'fitted:' 'r:L'
 putsfit 0 -1.8 'y = ' 'r'
@@ -2781,7 +2875,7 @@ text 0.7 -0.05 'central ray'
 
 @c ------------------------------------------------------------------
 @external{}
- at node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+ at node Drawing phase plain, Pulse properties, PDE solving hints, Hints
 @subsection Drawing phase plain
 @nav{}
 
@@ -2816,10 +2910,47 @@ next
 @pfig{ode, Example of ODE solving and phase plain drawing.}
 
 
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Pulse properties, Using MGL parser, Drawing phase plain, Hints
+ at subsection Pulse properties
+ at nav{}
+
+There is common task in optics to determine properties of wave pulses or wave beams. MathGL provide special function @ref{pulse} which return the pulse properties (maximal value, center of mass, width and so on). Its usage is rather simple. Here I just illustrate it on the example of Gaussian pulse, where all parameters are obvious.
+ at verbatim
+subplot 1 1 0 '<_':title 'Pulse sample'
+# first prepare pulse itself
+new a 100 'exp(-6*x^2)'
+
+# get pulse parameters
+pulse b a 'x'
+
+# positions and widths are normalized on the number of points. So, set proper axis scale.
+ranges 0 a.nx-1 0 1
+axis:plot a # draw pulse and axis
+
+# now visualize found pulse properties
+define m a.max # maximal amplitude
+# approximate position of maximum
+line b(1) 0 b(1) m 'r='
+# width at half-maximum (so called FWHM)
+line b(1)-b(3)/2 0  b(1)-b(3)/2 m 'm|'
+line b(1)+b(3)/2 0  b(1)+b(3)/2 m 'm|'
+line 0 0.5*m a.nx-1 0.5*m 'h'
+# parabolic approximation near maximum
+new x 100 'x'
+plot b(0)*(1-((x-b(1))/b(2))^2) 'g'
+ at end verbatim
+
+ at pfig{pulse, Example of determining of pulse properties.}
+
+
+
 @c ------------------------------------------------------------------
 @external{}
- at node MGL parser using, Using options, Drawing phase plain, Hints
- at subsection MGL parser using
+ at node Using MGL parser, Using options, Pulse properties, Hints
+ at subsection Using MGL parser
 @nav{}
 
 MGL scripts can contain loops, conditions and user-defined functions. Below I show very simple example of its usage:
@@ -2845,7 +2976,7 @@ next
 
 @c ------------------------------------------------------------------
 @external{}
- at node Using options, ``Templates'', MGL parser using, Hints
+ at node Using options, ``Templates'', Using MGL parser, Hints
 @subsection Using options
 @nav{}
 
@@ -2924,7 +3055,7 @@ subplot 2 1 1:rotate 50 60-1:box:surf a
 
 @c ------------------------------------------------------------------
 @external{}
- at node Reduce memory usage, , Stereo image, Hints
+ at node Reduce memory usage, Saving and scanning file, Stereo image, Hints
 @subsection Reduce memory usage
 @nav{}
 
@@ -2938,6 +3069,39 @@ for $1 0 1000
 next
 @end verbatim
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Saving and scanning file, , Reduce memory usage, Hints
+ at subsection Scanning file
+ at nav{}
+
+MathGL have possibilities to write textual information into file with variable values by help of @ref{save} command. This is rather useful for generating an ini-files or preparing human-readable textual files. For example, lets create some textual file
+ at verbatim
+subplot 1 1 0 '<_':title 'Save and scanfile sample'
+list a 1 -1 0
+save 'This is test: 0 -> ',a(0),' q' 'test.txt' 'w'
+save 'This is test: 1 -> ',a(1),' q' 'test.txt'
+save 'This is test: 2 -> ',a(2),' q' 'test.txt'
+ at end verbatim
+It contents look like
+ at verbatim
+This is test: 0 -> 1 q
+This is test: 1 -> -1 q
+This is test: 2 -> 0 q
+ at end verbatim
+Note, that I use option @samp{w} at first call of @code{save} to overwrite the contents of the file.
+
+Let assume now that you want to read this values (i.e. [[0,1],[1,-1],[2,0]]) from the file. You can use @ref{scanfile} for that. The desired values was written using template @samp{This is test: %g -> %g q}. So, just use
+ at verbatim
+scanfile a 'test.txt' 'This is test: %g -> %g'
+ at end verbatim
+and plot it to for assurance
+ at verbatim
+ranges a(0) a(1):axis:plot a(0) a(1) 'o'
+ at end verbatim
+
+Note, I keep only the leading part of template (i.e. @samp{This is test: %g -> %g} instead of @samp{This is test: %g -> %g q}), because there is no important for us information after the second number in the line.
+
 @c ==================================================================
 
 @external{}
diff --git a/texinfo/example_en.texi b/texinfo/example_en.texi
index b4cd402..ceb404a 100644
--- a/texinfo/example_en.texi
+++ b/texinfo/example_en.texi
@@ -90,7 +90,7 @@ In this case the programmer has more freedom in selecting the window libraries (
 @item
 @emph{Using FLTK or Qt widgets provided by MathGL}
 
-Here one can use a set of standard widgets which support export to many file formats, copying to clipboard, handle mouse and so on. 
+Here one can use a set of standard widgets which support export to many file formats, copying to clipboard, handle mouse and so on.
 @end itemize
 
 MathGL drawing can be created not only by object oriented languages (like, C++ or Python), but also by pure C or Fortran-like languages. The usage of last one is mostly identical to usage of classes (except the different function names). But there are some differences. C functions must have argument HMGL (for graphics) and/or HMDT (for data arrays) which specifies the object for drawing or manipulating (changing). Fortran users may regard these variables as integer. So, firstly the user  [...]
@@ -103,6 +103,7 @@ Let me consider the aforesaid in more detail.
 * Drawing to file::
 * Animation::
 * Drawing in memory::
+* Draw and calculate::
 * Using QMathGL::
 * MathGL and PyQt::
 * MathGL and MPI::
@@ -138,7 +139,7 @@ Here callback function @code{sample} is defined. This function does all drawing.
 gcc test.cpp -lmgl-qt -lmgl
 @end verbatim
 
-Alternatively you can create yours own class inherited from class @code{mglDraw} and re-implement the function @code{Draw()} in it:
+Alternatively you can create yours own class inherited from @ref{mglDraw class} and re-implement the function @code{Draw()} in it:
 @verbatim
 #include <mgl2/qt.h>
 class Foo : public mglDraw
@@ -258,97 +259,7 @@ int sample(mglGraph *gr)
 @end verbatim
 First, the function creates a frame by calling @code{NewFrame()} for rotated axes and draws the bounding box.  The function @code{EndFrame()} @strong{must be} called after the frame drawing! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
 
-Note, that such kind of animation is rather slow and not well suitable for visualization of running calculations. For the last case one can use @code{Update()} function. The most simple case for doing this is running yours calculations firstly in separate thread and later start MathGL window (QT or FLTK) creation.
- at verbatim
-#include <mgl2/window.h>
-mglWindow *gr=NULL;
-void *calc(void *)
-{
-  mglPoint pnt;
-  for(int i=0;i<10;i++)   // do calculation
-  {
-    sleep(2);             // which can be very long
-    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    if(gr)            // be sure that window is ready
-    {
-      gr->Clf();      // make new drawing
-      gr->Line(mglPoint(),pnt,"Ar2");
-      char str[10] = "i=0";  str[2] = '0'+i;
-      gr->Puts(mglPoint(),str);
-      gr->Update();   // update window
-    }
-  }
-  exit(0);
-}
-int main(int argc,char **argv)
-{
-  static pthread_t thr;
-  // first run yours routine in separate thread
-  pthread_create(&thr,0,calc,0);
-  pthread_detach(thr);
-  gr = new mglWindow;
-  gr->Run();  return 0;
-}
- at end verbatim
-Note, that such method looks as not working for GLUT windows due to limitation of @code{glutMainLoop()} function.
-
-Another ways use built-in MathGL feature to run a member function @code{mglDraw::Calc()} separate thread, which work only if pthread support is enabled. For this, you just need to use @code{mglDraw} class and reimplement its @code{Calc()} method.
- at verbatim
-#include <mgl2/window.h>
-class Foo : public mglDraw
-{
-  mglPoint pnt;  // some result of calculation
-public:
-  mglWindow *Gr;  // graphics to be updated
-  int Draw(mglGraph *gr);
-  void Calc();
-} foo;
-//-----------------------------------------------------
-void Foo::Calc()
-{
-  for(int i=0;i<30;i++)   // do calculation
-  {
-    sleep(2);             // which can be very long
-    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    Gr->Update();         // update window
-  }
-}
-//-----------------------------------------------------
-int Foo::Draw(mglGraph *gr)
-{
-  gr->Line(mglPoint(),pnt,"Ar2");
-  gr->Box();
-  return 0;
-}
-//-----------------------------------------------------
-int main(int argc,char **argv)
-{
-  mglWindow gr(&foo,"MathGL examples");
-  foo.Gr = &gr;   foo.Run();
-  return gr.Run();
-}
- at end verbatim
-
-Finally, you can put the event-handling loop in separate instead of yours code by using @code{RunThr()} function instead of @code{Run()} one. Unfortunately, such method work well only for FLTK windows and only if pthread support was enabled. Such limitation come from the Qt requirement to be run in the primary thread only. The sample code will be:
- at verbatim
-#include <mgl2/fltk.h>
-int main(int argc,char **argv)
-{
-  mglFLTK gr("test");     // create window
-  gr.RunThr();            // run event loop in separate thread
-  for(int i=0;i<10;i++)   // do calculation
-  {
-    sleep(1);             // which can be very long
-    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    gr.Clf();             // make new drawing
-    gr.Line(mglPoint(),pnt,"Ar2");
-    char str[10] = "i=0"; str[2] = '0'+i;
-    gr.Puts(mglPoint(),str);
-    gr.Update();          // update window when you need it
-  }
-  return 0;   // finish calculations and close the window
-}
- at end verbatim
+Note, that animation can be also done as visualization of running calculations (see @ref{Draw and calculate}).
 
 Pictures with @strong{animation can be saved in file(s)} as well. You can: export in animated GIF, or save each frame in separate file (usually JPEG) and convert these files into the movie (for example, by help of ImageMagic). Let me show both methods.
 
@@ -405,7 +316,7 @@ Finally, you can use @code{mglconv} tool for doing the same with MGL scripts (@p
 
 @c ------------------------------------------------------------------
 @external{}
- at node Drawing in memory, Using QMathGL, Animation, Basic usage
+ at node Drawing in memory, Draw and calculate, Animation, Basic usage
 @subsection Drawing in memory
 @nav{}
 
@@ -464,7 +375,111 @@ void MyWidget::paintEvent(QPaintEvent *)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Using QMathGL, MathGL and PyQt, Drawing in memory, Basic usage
+ at node Draw and calculate, Using QMathGL, Drawing in memory, Basic usage
+ at subsection Draw and calculate
+ at nav{}
+
+MathGL can be used to draw plots in parallel with some external calculations. The simplest way for this is the usage of @ref{mglDraw class}. At this you should enable pthread for widgets by setting @code{enable-pthr-widget=ON} at configure stage (it is set by default).
+First, you need to inherit you class from @code{mglDraw} class, define virtual members @code{Draw()} and @code{Calc()} which will draw the plot and proceed calculations. You may want to add the pointer @code{mglWnd *wnd;} to window with plot for interacting with them. Finally, you may add any other data or member functions. The sample class is shown below
+ at verbatim
+class myDraw : public mglDraw
+{
+	mglPoint pnt;	// some variable for changeable data
+	long i;			// another variable to be shown
+	mglWnd *wnd;	// external window for plotting
+public:
+	myDraw(mglWnd *w=0) : mglDraw()	{	wnd=w;	}
+	void SetWnd(mglWnd *w)	{	wnd=w;	}
+	int Draw(mglGraph *gr)
+	{
+		gr->Line(mglPoint(),pnt,"Ar2");
+		char str[16];	snprintf(str,15,"i=%ld",i);
+		gr->Puts(mglPoint(),str);
+		return 0;
+	}
+	void Calc()
+	{
+		for(i=0;;i++)	// do calculation
+		{
+			long_calculations();// which can be very long
+			Check();	// check if need pause
+			pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+			if(wnd)	wnd->Update();
+		}
+	}
+} dr;
+ at end verbatim
+There is only one issue here. Sometimes you may want to pause calculations to view result carefully, or save state, or change something. So, you need to provide a mechanism for pausing. Class @code{mglDraw} provide function @code{Check();} which check if toolbutton with pause is pressed and wait until it will be released. This function should be called in a "safety" places, where you can pause the calculation (for example, at the end of time step). Also you may add call @code{exit(0);} a [...]
+Finally, you need to create a window itself and run calculations.
+ at verbatim
+int main(int argc,char **argv)
+{
+	mglFLTK gr(&dr,"Multi-threading test");	// create window
+	dr.SetWnd(&gr);	// pass window pointer to yours class
+	dr.Run();	// run calculations
+	gr.Run();	// run event loop for window
+	return 0;
+}
+ at end verbatim
+
+Note, that you can reach the similar functionality without using @code{mglDraw} class (i.e. even for pure C code).
+ at verbatim
+mglFLTK *gr=NULL;	// pointer to window
+void *calc(void *)	// function with calculations
+{
+	mglPoint pnt;	// some data for plot
+	for(long i=0;;i++)		// do calculation
+	{
+		long_calculations();	// which can be very long
+		pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+		if(gr)
+		{
+			gr->Clf();			// make new drawing
+			// draw something
+			gr->Line(mglPoint(),pnt,"Ar2");
+			char str[16];	snprintf(str,15,"i=%ld",i);
+			gr->Puts(mglPoint(),str);
+			// don't forgot to update window
+			gr->Update();
+		}
+	}
+}
+int main(int argc,char **argv)
+{
+	static pthread_t thr;
+	pthread_create(&thr,0,calc,0);	// create separate thread for calculations
+	pthread_detach(thr);			// and detach it
+	gr = new mglFLTK;	// now create window
+	gr->Run();			// and run event loop
+	return 0;
+}
+ at end verbatim
+This sample is exactly the same as one with @code{mglDraw} class, but it don't have functionality for pausing calculations. If you need it then you have to create global mutex (like @code{pthread_mutex_t *mutex = pthread_mutex_init(&mutex,NULL);}), set it to window (like @code{gr->SetMutex(mutex);}) and periodically check it at calculations (like @code{pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex);}).
+
+Finally, you can put the event-handling loop in separate instead of yours code by using @code{RunThr()} function instead of @code{Run()} one. Unfortunately, such method work well only for FLTK windows and only if pthread support was enabled. Such limitation come from the Qt requirement to be run in the primary thread only. The sample code will be:
+ at verbatim
+int main(int argc,char **argv)
+{
+	mglFLTK gr("test");
+	gr.RunThr();	// <-- need MathGL version which use pthread for widgets
+	mglPoint pnt;	// some data
+	for(int i=0;i<10;i++)	// do calculation
+	{
+		long_calculations();// which can be very long
+		pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+		gr.Clf();			// make new drawing
+		gr.Line(mglPoint(),pnt,"Ar2");
+		char str[10] = "i=0";	str[3] = '0'+i;
+		gr->Puts(mglPoint(),str);
+		gr.Update();		// update window
+	}
+	return 0;	// finish calculations and close the window
+}
+ at end verbatim
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Using QMathGL, MathGL and PyQt, Draw and calculate, Basic usage
 @subsection Using QMathGL
 @nav{}
 
@@ -1611,6 +1626,9 @@ void mgls_prepare1d(HMDT y, HMDT y1=0, HMDT y2=0, HMDT x1=0, HMDT x2=0)
 * Tube sample::
 * Tape sample::
 * Torus sample::
+* Lamerey sample::
+* Bifurcation sample::
+* Pmap sample::
 @end menu
 
 
@@ -2227,7 +2245,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Torus sample, , Tape sample, 1D samples
+ at node Torus sample, Lamerey sample, Tape sample, 1D samples
 @subsection Torus sample
 @nav{}
 
@@ -2254,6 +2272,74 @@ int sample(mglGraph *gr)
 
 @pfig{torus, Example of Torus()}
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Lamerey sample, Bifurcation sample, Torus sample, 1D samples
+ at subsection Lamerey sample
+ at nav{}
+
+Function @ref{lamerey} draw Lamerey diagram. The sample code is:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_");
+  gr->Title("Lamerey sample");
+  gr->Axis(); gr->Label('x',"\\i x");
+  gr->Label('y',"\\bar{\\i x} = 2 \\i{x}");
+  gr->FPlot("x","k=");  gr->FPlot("2*x","b");
+  gr->Lamerey( 0.00097,"2*x","rv~");
+  gr->Lamerey(-0.00097,"2*x","rv~");
+}
+ at end verbatim
+
+ at pfig{lamerey, Example of Lamerey()}
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Bifurcation sample, Pmap sample, Lamerey sample, 1D samples
+ at subsection Bifurcation sample
+ at nav{}
+
+Function @ref{bifurcation} draw Bifurcation diagram for logistic map. The sample code is:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_");
+  gr->Title("Bifurcation sample");
+  gr->SetRanges(0,4,0,1);   gr->Axis();
+  gr->Bifurcation(0.005,"x*y*(1-y)","r");
+}
+ at end verbatim
+
+ at pfig{bifurcation, Example of Bifurcation()}
+
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Pmap sample, , Bifurcation sample, 1D samples
+ at subsection Pmap sample
+ at nav{}
+
+Function @ref{pmap} draw Poincare map -- show intersections of the curve and the surface. The sample code is:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_^");
+  gr->Title("Poincare map sample");
+  mglData ini(3);	ini[0]=0.1;
+  mglData r(mglODE("cos(y)+sin(z);cos(z)+sin(x);cos(x)+sin(y)","xyz",ini,0.1,100));
+  mglData x(r.SubData(0)),y(r.SubData(1)), z(r.SubData(2));
+  gr->Rotate(40,60);  gr->SetRanges(x,y,z);
+  gr->Axis(); gr->FSurf("0"); gr->Plot(x,y,z,"b");
+  gr->Label('x',"\\i x",0);   gr->Label('y',"\\i y",0);   gr->Label('z',"\\i z",0);
+  gr->Pmap(x,y,z,z, "b#o");
+}
+ at end verbatim
+
+ at pfig{pmap, Example of Pmap()}
+
+
+
 
 @c ------------------------------------------------------------------
 @external{}
@@ -2782,6 +2868,7 @@ void mgls_prepare3d(HMDT a, HMDT b=0)
 * ContF projection sample::
 * TriPlot and QuadPlot::
 * Dots sample::
+* IFS sample::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -3062,7 +3149,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Dots sample, , TriPlot and QuadPlot, 3D samples
+ at node Dots sample, IFS sample, TriPlot and QuadPlot, 3D samples
 @subsection Dots sample
 @nav{}
 
@@ -3097,6 +3184,49 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
+ at node IFS sample, , Dots sample, 3D samples
+ at subsection IFS sample
+ at nav{}
+
+Commands @ref{ifs2d} and @ref{ifs3d} generate points for fractals using iterated function system in 2d and 3d cases correspondingly. The sample codes are:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  mglData A;
+  A.SetList(35, 0.33,0.,0.,0.33,0.,0.,0.2, 0.33,0.,0.,0.33,0.67,0.,0.2, 0.33,0.,0.,0.33,0.33,0.33,0.2,
+                0.33,0.,0.,0.33,0.,0.67,0.2, 0.33,0.,0.,0.33,0.67,0.67,0.2);
+  A.Rearrange(7);
+  mglData f(mglIFS2d(A,100000));
+  gr->SubPlot(1,1,0,"<_");
+  gr->Title("IFS 2d sample");
+  gr->SetRanges(f.SubData(0), f.SubData(1));
+  gr->Axis(); gr->Plot(f.SubData(0), f.SubData(1),"r#o ","size 0.05");
+}
+ at end verbatim
+
+ at pfig{ifs2d, Example of IFS fractal (2d case).}
+
+ at verbatim
+int sample(mglGraph *gr)
+{
+  mglData A;
+  A.SetList(52, 0.,0.,0.,0.,.18,0.,0.,0.,0.,0.,0.,0.,.01, .85,0.,0.,0.,.85,.1,0.,-0.1,0.85,0.,1.6,0.,.85,
+                .2,-.2,0.,.2,.2,0.,0.,0.,0.3,0.,0.8,0.,.07, -.2,.2,0.,.2,.2,0.,0.,0.,0.3,0.,0.8,0.,.07);
+  A.Rearrange(13);
+  mglData f(mglIFS3d(A,100000));
+  gr->Title("IFS 3d sample");
+  gr->SetRanges(f.SubData(0), f.SubData(1), f.SubData(2));
+  gr->Rotate(50,60);  gr->Axis(); gr->Box();
+  gr->Dots(f.SubData(0), f.SubData(1), f.SubData(2),"G#o","size 0.05");
+}
+ at end verbatim
+
+ at pfig{ifs3d, Example of IFS fractal (3d case).}
+
+
+
+ at c ------------------------------------------------------------------
+ at external{}
 @node Vector field samples, Hints, 3D samples, Examples
 @section Vector field samples
 @nav{}
@@ -3363,11 +3493,13 @@ In this section I've included some small hints and advices for the improving of
 * Nonlinear fitting hints::
 * PDE solving hints::
 * Drawing phase plain::
-* MGL parser using::
+* Pulse properties::
+* Using MGL parser::
 * Using options::
 * ``Templates''::
 * Stereo image::
 * Reduce memory usage::
+* Saving and scanning file::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -3894,14 +4026,14 @@ int sample(mglGraph *gr)
 
 Nonlinear fitting is rather simple. All that you need is the data to fit, the approximation formula and the list of coefficients to fit (better with its initial guess values). Let me demonstrate it on the following simple example. First, let us use sin function with some random noise:
 @verbatim
-  mglData rnd(100), in(100); //data to be fitted and ideal data
-  gr->Fill(rnd,"0.4*rnd+0.1+sin(2*pi*x)");
+  mglData dat(100), in(100); //data to be fitted and ideal data
+  gr->Fill(dat,"0.4*rnd+0.1+sin(2*pi*x)");
   gr->Fill(in,"0.3+sin(2*pi*x)");
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(dat, "k. ");
   gr->Axis(); gr->Plot(in, "b");
   gr->Puts(mglPoint(0, 2.2), "initial: y = 0.3+sin(2\\pi x)", "b");
 @end verbatim
@@ -3910,7 +4042,7 @@ The next step is the fitting itself. For that let me specify an initial values @
 @verbatim
   mreal ini[3] = {1,1,3};
   mglData Ini(3,ini);
-  mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
+  mglData res = gr->Fit(dat, "a+b*sin(c*x)", "abc", Ini);
 @end verbatim
 Now display it
 @verbatim
@@ -3925,16 +4057,16 @@ The full sample code for nonlinear fitting is:
 @verbatim
 int sample(mglGraph *gr)
 {
-  mglData rnd(100), in(100);
-  gr->Fill(rnd,"0.4*rnd+0.1+sin(2*pi*x)");
+  mglData dat(100), in(100);
+  gr->Fill(dat,"0.4*rnd+0.1+sin(2*pi*x)");
   gr->Fill(in,"0.3+sin(2*pi*x)");
   mreal ini[3] = {1,1,3};
   mglData Ini(3,ini);
 
-  mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
+  mglData res = gr->Fit(dat, "a+b*sin(c*x)", "abc", Ini);
 
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(dat, "k. ");
   gr->Axis();   gr->Plot(res, "r"); gr->Plot(in, "b");
   gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
   gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
@@ -4016,7 +4148,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+ at node Drawing phase plain, Pulse properties, PDE solving hints, Hints
 @subsection Drawing phase plain
 @nav{}
 
@@ -4057,8 +4189,42 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node MGL parser using, Using options, Drawing phase plain, Hints
- at subsection MGL parser using
+ at node Pulse properties, Using MGL parser, Drawing phase plain, Hints
+ at subsection Pulse properties
+ at nav{}
+
+There is common task in optics to determine properties of wave pulses or wave beams. MathGL provide special function @ref{pulse} which return the pulse properties (maximal value, center of mass, width and so on). Its usage is rather simple. Here I just illustrate it on the example of Gaussian pulse, where all parameters are obvious.
+ at verbatim
+void sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_");  gr->Title("Pulse sample");
+  // first prepare pulse itself
+  mglData a(100); gr->Fill(a,"exp(-6*x^2)");
+  // get pulse parameters
+  mglData b(a.Pulse('x'));
+  // positions and widths are normalized on the number of points. So, set proper axis scale.
+  gr->SetRanges(0, a.nx-1, 0, 1);
+  gr->Axis(); gr->Plot(a);  // draw pulse and axis
+  // now visualize found pulse properties
+  double m = b[0];  // maximal amplitude
+  // approximate position of maximum
+  gr->Line(mglPoint(b[1],0), mglPoint(b[1],m),"r=");
+  // width at half-maximum (so called FWHM)
+  gr->Line(mglPoint(b[1]-b[3]/2,0), mglPoint(b[1]-b[3]/2,m),"m|");
+  gr->Line(mglPoint(b[1]+b[3]/2,0), mglPoint(b[1]+b[3]/2,m),"m|");
+  gr->Line(mglPoint(0,m/2), mglPoint(a.nx-1,m/2),"h");
+  // parabolic approximation near maximum
+  char func[128];	sprintf(func,"%g*(1-((x-%g)/%g)^2)",b[0],b[1],b[2]);
+  gr->FPlot(func,"g");
+}
+ at end verbatim
+
+ at pfig{pulse, Example of determining of pulse properties.}
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Using MGL parser, Using options, Pulse properties, Hints
+ at subsection Using MGL parser
 @nav{}
 
 Sometimes you may prefer to use MGL scripts in yours code. It is simpler (especially in comparison with C/Fortran interfaces) and provide faster way to plot the data with annotations, labels and so on. Class @code{mglParse} (@pxref{mglParse class} parse MGL scripts in C++. It have also the corresponding interface for C/Fortran.
@@ -4117,7 +4283,7 @@ int sample(HMGL gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Using options, ``Templates'', MGL parser using, Hints
+ at node Using options, ``Templates'', Using MGL parser, Hints
 @subsection Using options
 @nav{}
 
@@ -4208,7 +4374,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Reduce memory usage, , Stereo image, Hints
+ at node Reduce memory usage, Saving and scanning file, Stereo image, Hints
 @subsection Reduce memory usage
 @nav{}
 
@@ -4225,6 +4391,43 @@ int sample(mglGraph *gr)
 }
 @end verbatim
 
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Saving and scanning file, , Reduce memory usage, Hints
+ at subsection Scanning file
+ at nav{}
+
+MathGL have possibilities to write textual information into file with variable values. In MGL script you can use @ref{save} command for that. However, the usual @code{printf();} is simple in C/C++ code. For example, lets create some textual file
+ at verbatim
+FILE *fp=fopen("test.txt","w");
+fprintf(fp,"This is test: 0 -> 1 q\n");
+fprintf(fp,"This is test: 1 -> -1 q\n");
+fprintf(fp,"This is test: 2 -> 0 q\n");
+fclose(fp);
+ at end verbatim
+It contents look like
+ at verbatim
+This is test: 0 -> 1 q
+This is test: 1 -> -1 q
+This is test: 2 -> 0 q
+ at end verbatim
+
+Let assume now that you want to read this values (i.e. [[0,1],[1,-1],[2,0]]) from the file. You can use @ref{scanfile} for that. The desired values was written using template "This is test: %g -> %g q\n". So, just use
+ at verbatim
+mglData a;
+a.ScanFile("test.txt","This is test: %g -> %g");
+ at end verbatim
+and plot it to for assurance
+ at verbatim
+gr->SetRanges(a.SubData(0), a.SubData(1));
+gr->Axis();	gr->Plot(a.SubData(0),a.SubData(1),"o");
+ at end verbatim
+
+Note, I keep only the leading part of template (i.e. "This is test: %g -> %g" instead of "This is test: %g -> %g q\n"), because there is no important for us information after the second number in the line.
+
+
+
 @c ==================================================================
 @external{}
 @node FAQ, , Hints, Examples
@@ -4322,6 +4525,16 @@ gr->Axis();
 gr->WriteFrame("fname.eps");
 @end verbatim
 
+ at item Why I couldn't use name @samp{I} for variable?
+MathGL support C99 standard, where @samp{I} is reserved for imaginary unit. If you still need this name, then just use
+ at verbatim
+#undef I
+ at end verbatim
+after including MathGL header files.
+
+ at item How I can create MPEG video from plots?
+You can save each frame into JPEG with names like @samp{frame0001.jpg}, @samp{frame0002.jpg}, ... Later you can use ImageMagic to convert them into MPEG video by command @code{convert frame*.jpg movie.mpg}. See also @ref{MPEG}.
+
 @end table
 
 @external{}
diff --git a/texinfo/example_ru.texi b/texinfo/example_ru.texi
index ac99b44..2fca8a2 100644
--- a/texinfo/example_ru.texi
+++ b/texinfo/example_ru.texi
@@ -101,6 +101,7 @@ call mgl_delete_graph(gr);
 * Drawing to file::
 * Animation::
 * Drawing in memory::
+* Draw and calculate::
 * Using QMathGL::
 * MathGL and PyQt::
 * MathGL and MPI::
@@ -256,98 +257,7 @@ int sample(mglGraph *gr)
 @end verbatim
 First, the function creates a frame by calling @code{NewFrame()} for rotated axes and draws the bounding box.  The function @code{EndFrame()} @strong{must be} called after the frame drawing! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
 
-Note, that such kind of animation is rather slow and not well suitable for visualization of running calculations. For the last case one can use @code{Update()} function. The most simple case for doing this is running yours calculations firstly in separate thread and later start MathGL window (QT or FLTK) creation.
- at verbatim
-#include <mgl2/window.h>
-mglWindow *gr=NULL;
-void *calc(void *)
-{
-  mglPoint pnt;
-  for(int i=0;i<10;i++)   // do calculation
-  {
-    sleep(2);             // which can be very long
-    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    if(gr)            // be sure that window is ready
-    {
-      gr->Clf();      // make new drawing
-      gr->Line(mglPoint(),pnt,"Ar2");
-      char str[10] = "i=0";  str[2] = '0'+i;
-      gr->Puts(mglPoint(),str);
-      gr->Update();   // update window
-    }
-  }
-  exit(0);
-}
-int main(int argc,char **argv)
-{
-  static pthread_t thr;
-  // first run yours routine in separate thread
-  pthread_create(&thr,0,calc,0);
-  pthread_detach(thr);
-  gr = new mglWindow;
-  gr->Run();  return 0;
-}
- at end verbatim
-Note, that such method looks as not working for GLUT windows due to limitation of @code{glutMainLoop()} function.
-
-Another ways use built-in MathGL feature to run a member function @code{mglDraw::Calc()} separate thread, which work only if pthread support is enabled. For this, you just need to use @code{mglDraw} class and reimplement its @code{Calc()} method.
- at verbatim
-#include <mgl2/window.h>
-class Foo : public mglDraw
-{
-  mglPoint pnt;  // some result of calculation
-public:
-  mglWindow *Gr;  // graphics to be updated
-  int Draw(mglGraph *gr);
-  void Calc();
-} foo;
-//-----------------------------------------------------
-void Foo::Calc()
-{
-  for(int i=0;i<30;i++)   // do calculation
-  {
-    sleep(2);             // which can be very long
-    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    Gr->Update();         // update window
-  }
-}
-//-----------------------------------------------------
-int Foo::Draw(mglGraph *gr)
-{
-  gr->Line(mglPoint(),pnt,"Ar2");
-  gr->Box();
-  return 0;
-}
-//-----------------------------------------------------
-int main(int argc,char **argv)
-{
-  mglWindow gr(&foo,"MathGL examples");
-  foo.Gr = &gr;   foo.Run();
-  return gr.Run();
-}
- at end verbatim
-
-Finally, you can put the event-handling loop in separate instead of yours code by using @code{RunThr()} function instead of @code{Run()} one. Unfortunately, such method work well only for FLTK windows and only if pthread support was enabled. Such limitation come from the Qt requirement to be run in the primary thread only. The sample code will be:
- at verbatim
-#include <mgl2/fltk.h>
-int main(int argc,char **argv)
-{
-  mglFLTK gr("test");     // create window
-  gr.RunThr();            // run event loop in separate thread
-  for(int i=0;i<10;i++)   // do calculation
-  {
-    sleep(1);             // which can be very long
-    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    gr.Clf();             // make new drawing
-    gr.Line(mglPoint(),pnt,"Ar2");
-    char str[10] = "i=0"; str[2] = '0'+i;
-    gr.Puts(mglPoint(),str);
-    gr.Update();          // update window when you need it
-  }
-  return 0;   // finish calculations and close the window
-}
- at end verbatim
-
+Note, that animation can be also done as visualization of running calculations (see @ref{Draw and calculate}).
 
 Pictures with @strong{animation can be saved in file(s)} as well. You can: export in animated GIF, or save each frame in separate file (usually JPEG) and convert these files into the movie (for example, by help of ImageMagic). Let me show both methods.
 
@@ -404,7 +314,7 @@ Finally, you can use @code{mglconv} tool for doing the same with MGL scripts (@p
 
 @c ------------------------------------------------------------------
 @external{}
- at node Drawing in memory, Using QMathGL, Animation, Basic usage
+ at node Drawing in memory, Draw and calculate, Animation, Basic usage
 @subsection Drawing in memory
 @nav{}
 
@@ -463,7 +373,112 @@ void MyWidget::paintEvent(QPaintEvent *)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Using QMathGL, MathGL and PyQt, Drawing in memory, Basic usage
+ at node Draw and calculate, Using QMathGL, Drawing in memory, Basic usage
+ at subsection Draw and calculate
+ at nav{}
+
+MathGL can be used to draw plots in parallel with some external calculations. The simplest way for this is the usage of @ref{mglDraw class}. At this you should enable pthread for widgets by setting @code{enable-pthr-widget=ON} at configure stage (it is set by default).
+First, you need to inherit you class from @code{mglDraw} class, define virtual members @code{Draw()} and @code{Calc()} which will draw the plot and proceed calculations. You may want to add the pointer @code{mglWnd *wnd;} to window with plot for interacting with them. Finally, you may add any other data or member functions. The sample class is shown below
+ at verbatim
+class myDraw : public mglDraw
+{
+	mglPoint pnt;	// some variable for changeable data
+	long i;			// another variable to be shown
+	mglWnd *wnd;	// external window for plotting
+public:
+	myDraw(mglWnd *w=0) : mglDraw()	{	wnd=w;	}
+	void SetWnd(mglWnd *w)	{	wnd=w;	}
+	int Draw(mglGraph *gr)
+	{
+		gr->Line(mglPoint(),pnt,"Ar2");
+		char str[16];	snprintf(str,15,"i=%ld",i);
+		gr->Puts(mglPoint(),str);
+		return 0;
+	}
+	void Calc()
+	{
+		for(i=0;;i++)	// do calculation
+		{
+			long_calculations();// which can be very long
+			Check();	// check if need pause
+			pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+			if(wnd)	wnd->Update();
+		}
+	}
+} dr;
+ at end verbatim
+There is only one issue here. Sometimes you may want to pause calculations to view result carefully, or save state, or change something. So, you need to provide a mechanism for pausing. Class @code{mglDraw} provide function @code{Check();} which check if toolbutton with pause is pressed and wait until it will be released. This function should be called in a "safety" places, where you can pause the calculation (for example, at the end of time step). Also you may add call @code{exit(0);} a [...]
+Finally, you need to create a window itself and run calculations.
+ at verbatim
+int main(int argc,char **argv)
+{
+	mglFLTK gr(&dr,"Multi-threading test");	// create window
+	dr.SetWnd(&gr);	// pass window pointer to yours class
+	dr.Run();	// run calculations
+	gr.Run();	// run event loop for window
+	return 0;
+}
+ at end verbatim
+
+Note, that you can reach the similar functionality without using @code{mglDraw} class (i.e. even for pure C code).
+ at verbatim
+mglFLTK *gr=NULL;	// pointer to window
+void *calc(void *)	// function with calculations
+{
+	mglPoint pnt;	// some data for plot
+	for(long i=0;;i++)		// do calculation
+	{
+		long_calculations();	// which can be very long
+		pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+		if(gr)
+		{
+			gr->Clf();			// make new drawing
+			// draw something
+			gr->Line(mglPoint(),pnt,"Ar2");
+			char str[16];	snprintf(str,15,"i=%ld",i);
+			gr->Puts(mglPoint(),str);
+			// don't forgot to update window
+			gr->Update();
+		}
+	}
+}
+int main(int argc,char **argv)
+{
+	static pthread_t thr;
+	pthread_create(&thr,0,calc,0);	// create separate thread for calculations
+	pthread_detach(thr);			// and detach it
+	gr = new mglFLTK;	// now create window
+	gr->Run();			// and run event loop
+	return 0;
+}
+ at end verbatim
+This sample is exactly the same as one with @code{mglDraw} class, but it don't have functionality for pausing calculations. If you need it then you have to create global mutex (like @code{pthread_mutex_t *mutex = pthread_mutex_init(&mutex,NULL);}), set it to window (like @code{gr->SetMutex(mutex);}) and periodically check it at calculations (like @code{pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex);}).
+
+Finally, you can put the event-handling loop in separate instead of yours code by using @code{RunThr()} function instead of @code{Run()} one. Unfortunately, such method work well only for FLTK windows and only if pthread support was enabled. Such limitation come from the Qt requirement to be run in the primary thread only. The sample code will be:
+ at verbatim
+int main(int argc,char **argv)
+{
+	mglFLTK gr("test");
+	gr.RunThr();	// <-- need MathGL version which use pthread for widgets
+	mglPoint pnt;	// some data
+	for(int i=0;i<10;i++)	// do calculation
+	{
+		long_calculations();// which can be very long
+		pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
+		gr.Clf();			// make new drawing
+		gr.Line(mglPoint(),pnt,"Ar2");
+		char str[10] = "i=0";	str[3] = '0'+i;
+		gr->Puts(mglPoint(),str);
+		gr.Update();		// update window
+	}
+	return 0;	// finish calculations and close the window
+}
+ at end verbatim
+
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Using QMathGL, MathGL and PyQt, Draw and calculate, Basic usage
 @subsection Using QMathGL
 @nav{}
 
@@ -1600,6 +1615,9 @@ void mgls_prepare1d(HMDT y, HMDT y1=0, HMDT y2=0, HMDT x1=0, HMDT x2=0)
 * Tube sample::
 * Tape sample::
 * Torus sample::
+* Lamerey sample::
+* Bifurcation sample::
+* Pmap sample::
 @end menu
 
 
@@ -2215,7 +2233,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Torus sample, , Tape sample, 1D samples
+ at node Torus sample, Lamerey sample, Tape sample, 1D samples
 @subsection Torus sample
 @nav{}
 
@@ -2242,6 +2260,72 @@ int sample(mglGraph *gr)
 
 @pfig{torus, Example of Torus()}
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Lamerey sample, Bifurcation sample, Torus sample, 1D samples
+ at subsection Lamerey sample
+ at nav{}
+
+Function @ref{lamerey} draw Lamerey diagram. The sample code is:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_");
+  gr->Title("Lamerey sample");
+  gr->Axis(); gr->Label('x',"\\i x");
+  gr->Label('y',"\\bar{\\i x} = 2 \\i{x}");
+  gr->FPlot("x","k=");  gr->FPlot("2*x","b");
+  gr->Lamerey( 0.00097,"2*x","rv~");
+  gr->Lamerey(-0.00097,"2*x","rv~");
+}
+ at end verbatim
+
+ at pfig{lamerey, Example of Lamerey()}
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Bifurcation sample, Pmap sample, Lamerey sample, 1D samples
+ at subsection Bifurcation sample
+ at nav{}
+
+Function @ref{bifurcation} draw Bifurcation diagram for logistic map. The sample code is:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_");
+  gr->Title("Bifurcation sample");
+  gr->SetRanges(0,4,0,1);   gr->Axis();
+  gr->Bifurcation(0.005,"x*y*(1-y)","r");
+}
+ at end verbatim
+
+ at pfig{bifurcation, Example of Bifurcation()}
+
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Pmap sample, , Bifurcation sample, 1D samples
+ at subsection Pmap sample
+ at nav{}
+
+Function @ref{pmap} draw Poincare map -- show intersections of the curve and the surface. The sample code is:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_^");
+  gr->Title("Poincare map sample");
+  mglData ini(3);	ini[0]=0.1;
+  mglData r(mglODE("cos(y)+sin(z);cos(z)+sin(x);cos(x)+sin(y)","xyz",ini,0.1,100));
+  mglData x(r.SubData(0)),y(r.SubData(1)), z(r.SubData(2));
+  gr->Rotate(40,60);  gr->SetRanges(x,y,z);
+  gr->Axis(); gr->FSurf("0"); gr->Plot(x,y,z,"b");
+  gr->Label('x',"\\i x",0);   gr->Label('y',"\\i y",0);   gr->Label('z',"\\i z",0);
+  gr->Pmap(x,y,z,z, "b#o");
+}
+ at end verbatim
+
+ at pfig{pmap, Example of Pmap()}
+
 
 @c ------------------------------------------------------------------
 @external{}
@@ -2770,6 +2854,7 @@ void mgls_prepare3d(HMDT a, HMDT b=0)
 * ContF projection sample::
 * TriPlot and QuadPlot::
 * Dots sample::
+* IFS sample::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -3050,7 +3135,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Dots sample, , TriPlot and QuadPlot, 3D samples
+ at node Dots sample, IFS sample, TriPlot and QuadPlot, 3D samples
 @subsection Dots sample
 @nav{}
 
@@ -3085,6 +3170,48 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
+ at node IFS sample, , Dots sample, 3D samples
+ at subsection IFS sample
+ at nav{}
+
+Commands @ref{ifs2d} and @ref{ifs3d} generate points for fractals using iterated function system in 2d and 3d cases correspondingly. The sample codes are:
+ at verbatim
+int sample(mglGraph *gr)
+{
+  mglData A;
+  A.SetList(35, 0.33,0.,0.,0.33,0.,0.,0.2, 0.33,0.,0.,0.33,0.67,0.,0.2, 0.33,0.,0.,0.33,0.33,0.33,0.2,
+                0.33,0.,0.,0.33,0.,0.67,0.2, 0.33,0.,0.,0.33,0.67,0.67,0.2);
+  A.Rearrange(7);
+  mglData f(mglIFS2d(A,100000));
+  gr->SubPlot(1,1,0,"<_");
+  gr->Title("IFS 2d sample");
+  gr->SetRanges(f.SubData(0), f.SubData(1));
+  gr->Axis(); gr->Plot(f.SubData(0), f.SubData(1),"r#o ","size 0.05");
+}
+ at end verbatim
+
+ at pfig{ifs2d, Example of IFS fractal (2d case).}
+
+ at verbatim
+int sample(mglGraph *gr)
+{
+  mglData A;
+  A.SetList(52, 0.,0.,0.,0.,.18,0.,0.,0.,0.,0.,0.,0.,.01, .85,0.,0.,0.,.85,.1,0.,-0.1,0.85,0.,1.6,0.,.85,
+                .2,-.2,0.,.2,.2,0.,0.,0.,0.3,0.,0.8,0.,.07, -.2,.2,0.,.2,.2,0.,0.,0.,0.3,0.,0.8,0.,.07);
+  A.Rearrange(13);
+  mglData f(mglIFS3d(A,100000));
+  gr->Title("IFS 3d sample");
+  gr->SetRanges(f.SubData(0), f.SubData(1), f.SubData(2));
+  gr->Rotate(50,60);  gr->Axis(); gr->Box();
+  gr->Dots(f.SubData(0), f.SubData(1), f.SubData(2),"G#o","size 0.05");
+}
+ at end verbatim
+
+ at pfig{ifs3d, Example of IFS fractal (3d case).}
+
+
+ at c ------------------------------------------------------------------
+ at external{}
 @node Vector field samples, Hints, 3D samples, Examples
 @section Vector field samples
 @nav{}
@@ -3351,11 +3478,13 @@ In this section I've included some small hints and advices for the improving of
 * Nonlinear fitting hints::
 * PDE solving hints::
 * Drawing phase plain::
-* MGL parser using::
+* Using MGL parser::
+* Pulse properties::
 * Using options::
 * ``Templates''::
 * Stereo image::
 * Reduce memory usage::
+* Saving and scanning file::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -3880,14 +4009,14 @@ int sample(mglGraph *gr)
 
 Nonlinear fitting is rather simple. All that you need is the data to fit, the approximation formula and the list of coefficients to fit (better with its initial guess values). Let me demonstrate it on the following simple example. First, let us use sin function with some random noise:
 @verbatim
-  mglData rnd(100), in(100); //data to be fitted and ideal data
-  gr->Fill(rnd,"0.4*rnd+0.1+sin(2*pi*x)");
+  mglData dat(100), in(100); //data to be fitted and ideal data
+  gr->Fill(dat,"0.4*rnd+0.1+sin(2*pi*x)");
   gr->Fill(in,"0.3+sin(2*pi*x)");
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(dat, "k. ");
   gr->Axis(); gr->Plot(in, "b");
   gr->Puts(mglPoint(0, 2.2), "initial: y = 0.3+sin(2\\pi x)", "b");
 @end verbatim
@@ -3896,7 +4025,7 @@ The next step is the fitting itself. For that let me specify an initial values @
 @verbatim
   mreal ini[3] = {1,1,3};
   mglData Ini(3,ini);
-  mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
+  mglData res = gr->Fit(dat, "a+b*sin(c*x)", "abc", Ini);
 @end verbatim
 Now display it
 @verbatim
@@ -3911,16 +4040,16 @@ The full sample code for nonlinear fitting is:
 @verbatim
 int sample(mglGraph *gr)
 {
-  mglData rnd(100), in(100);
-  gr->Fill(rnd,"0.4*rnd+0.1+sin(2*pi*x)");
+  mglData dat(100), in(100);
+  gr->Fill(dat,"0.4*rnd+0.1+sin(2*pi*x)");
   gr->Fill(in,"0.3+sin(2*pi*x)");
   mreal ini[3] = {1,1,3};
   mglData Ini(3,ini);
 
-  mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
+  mglData res = gr->Fit(dat, "a+b*sin(c*x)", "abc", Ini);
 
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(dat, "k. ");
   gr->Axis();   gr->Plot(res, "r"); gr->Plot(in, "b");
   gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
   gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
@@ -4002,7 +4131,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+ at node Drawing phase plain, Pulse properties, PDE solving hints, Hints
 @subsection Drawing phase plain
 @nav{}
 
@@ -4043,8 +4172,42 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node MGL parser using, Using options, Drawing phase plain, Hints
- at subsection MGL parser using
+ at node Pulse properties, Using MGL parser, Drawing phase plain, Hints
+ at subsection Pulse properties
+ at nav{}
+
+There is common task in optics to determine properties of wave pulses or wave beams. MathGL provide special function @ref{pulse} which return the pulse properties (maximal value, center of mass, width and so on). Its usage is rather simple. Here I just illustrate it on the example of Gaussian pulse, where all parameters are obvious.
+ at verbatim
+void sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"<_");  gr->Title("Pulse sample");
+  // first prepare pulse itself
+  mglData a(100); gr->Fill(a,"exp(-6*x^2)");
+  // get pulse parameters
+  mglData b(a.Pulse('x'));
+  // positions and widths are normalized on the number of points. So, set proper axis scale.
+  gr->SetRanges(0, a.nx-1, 0, 1);
+  gr->Axis(); gr->Plot(a);  // draw pulse and axis
+  // now visualize found pulse properties
+  double m = b[0];  // maximal amplitude
+  // approximate position of maximum
+  gr->Line(mglPoint(b[1],0), mglPoint(b[1],m),"r=");
+  // width at half-maximum (so called FWHM)
+  gr->Line(mglPoint(b[1]-b[3]/2,0), mglPoint(b[1]-b[3]/2,m),"m|");
+  gr->Line(mglPoint(b[1]+b[3]/2,0), mglPoint(b[1]+b[3]/2,m),"m|");
+  gr->Line(mglPoint(0,m/2), mglPoint(a.nx-1,m/2),"h");
+  // parabolic approximation near maximum
+  char func[128];	sprintf(func,"%g*(1-((x-%g)/%g)^2)",b[0],b[1],b[2]);
+  gr->FPlot(func,"g");
+}
+ at end verbatim
+
+ at pfig{pulse, Example of determining of pulse properties.}
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Using MGL parser, Using options, Pulse properties, Hints
+ at subsection Using MGL parser
 @nav{}
 
 Sometimes you may prefer to use MGL scripts in yours code. It is simpler (especially in comparison with C/Fortran interfaces) and provide faster way to plot the data with annotations, labels and so on. Class @code{mglParse} (@pxref{mglParse class} parse MGL scripts in C++. It have also the corresponding interface for C/Fortran.
@@ -4101,7 +4264,7 @@ int sample(HMGL gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Using options, ``Templates'', MGL parser using, Hints
+ at node Using options, ``Templates'', Using MGL parser, Hints
 @subsection Using options
 @nav{}
 
@@ -4192,7 +4355,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
- at node Reduce memory usage, , Stereo image, Hints
+ at node Reduce memory usage, Saving and scanning file, Stereo image, Hints
 @subsection Reduce memory usage
 @nav{}
 
@@ -4209,6 +4372,40 @@ int sample(mglGraph *gr)
 }
 @end verbatim
 
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Saving and scanning file, , Reduce memory usage, Hints
+ at subsection Scanning file
+ at nav{}
+
+MathGL have possibilities to write textual information into file with variable values. In MGL script you can use @ref{save} command for that. However, the usual @code{printf();} is simple in C/C++ code. For example, lets create some textual file
+ at verbatim
+FILE *fp=fopen("test.txt","w");
+fprintf(fp,"This is test: 0 -> 1 q\n");
+fprintf(fp,"This is test: 1 -> -1 q\n");
+fprintf(fp,"This is test: 2 -> 0 q\n");
+fclose(fp);
+ at end verbatim
+It contents look like
+ at verbatim
+This is test: 0 -> 1 q
+This is test: 1 -> -1 q
+This is test: 2 -> 0 q
+ at end verbatim
+
+Let assume now that you want to read this values (i.e. [[0,1],[1,-1],[2,0]]) from the file. You can use @ref{scanfile} for that. The desired values was written using template "This is test: %g -> %g q\n". So, just use
+ at verbatim
+mglData a;
+a.ScanFile("test.txt","This is test: %g -> %g");
+ at end verbatim
+and plot it to for assurance
+ at verbatim
+gr->SetRanges(a.SubData(0), a.SubData(1));
+gr->Axis();	gr->Plot(a.SubData(0),a.SubData(1),"o");
+ at end verbatim
+
+Note, I keep only the leading part of template (i.e. "This is test: %g -> %g" instead of "This is test: %g -> %g q\n"), because there is no important for us information after the second number in the line.
+
 @c ==================================================================
 @external{}
 @node FAQ, , Hints, Examples
@@ -4311,6 +4508,16 @@ gr->Axis();
 gr->WriteFrame("fname.eps");
 @end verbatim
 
+ at item Почему у меня не получается использовать имя @samp{I} для переменной?
+MathGL поддерживает стандарт C99, в котором имя @samp{I} зарезервированно для мнимой единицы. Если Вам все таки нужно это имя для переменной, то поместите
+ at verbatim
+#undef I
+ at end verbatim
+сразу после включения заголовочных файлов MathGL.
+
+ at item Как мне создать MPEG видео по графикам?
+Вам следует сохранить каждый кадр в файл JPEG с именем типа @samp{frame0001.jpg}, @samp{frame0002.jpg}, ... Далее используйте ImageMagic для конвертации этих файлов в видео формата MPEG с помощью команды @code{convert frame*.jpg movie.mpg}. См. также @ref{MPEG}.
+
 @end table
 
 @external{}
diff --git a/texinfo/overview_en.texi b/texinfo/overview_en.texi
index dede3b2..9416ac8 100644
--- a/texinfo/overview_en.texi
+++ b/texinfo/overview_en.texi
@@ -77,7 +77,7 @@ MathGL can be installed in 4 different ways.
 @item
 Compile from sources. The cmake build system is useded in the library. To run it, one should execute commands: @code{cmake .} twice, after it @code{make} and @code{make install} with root/sudo rights. Sometimes after installation you may need to update the library list -- just execute @code{ldconfig} with root/sudo rights.
 
-There are several additional options which are switched off by default. They are: @code{enable-fltk, enable-glut, enable-qt} for ebabling FLTK, GLUT and/or Qt windows; @code{enable-jpeg, enable-gif, enable-hdf5} and so on for enabling corresponding file formats; @code{enable-all} for enabling all additional features. For using @code{double} as base internal data type use option @code{enable-double}. For enabling language interfaces use @code{enable-python, enable-octave} or @code{enable- [...]
+There are several additional options which are switched off by default. They are: @code{enable-fltk, enable-glut, enable-qt4, enable-qt5} for ebabling FLTK, GLUT and/or Qt windows; @code{enable-jpeg, enable-gif, enable-hdf5} and so on for enabling corresponding file formats; @code{enable-all} for enabling all additional features. For using @code{double} as base internal data type use option @code{enable-double}. For enabling language interfaces use @code{enable-python, enable-octave} or  [...]
 
 There is known bug for building in MinGW -- you need to manually add linker option @code{-fopenmp} (i.e. @code{CMAKE_EXE_LINKER_FLAGS:STRING='-fopenmp'} and @code{CMAKE_SHARED_LINKER_FLAGS:STRING='-fopenmp'}) if you enable OpenMP support (i.e. if @code{enable-openmp=ON}).
 
@@ -88,7 +88,7 @@ Use a precompiled binary. There are binaries for MinGW (platform Win32). For a p
 Install precompiled versions from standard packages (RPM, deb, DevPak and so on).
 @end enumerate
 
-Note, you can download the latest sources (which can be not stable) from sourceforge.net SVN by command 
+Note, you can download the latest sources (which can be not stable) from sourceforge.net SVN by command
 @verbatim
 svn checkout http://svn.code.sf.net/p/mathgl/code/mathgl-2x mathgl-code
 @end verbatim
@@ -129,7 +129,7 @@ Basically plot is done. But I decide to add yellow (@samp{y} color, see @ref{Col
 @verbatim
         gr.Cont(dat,"y");	// plot yellow contour lines
 @end verbatim
-This demonstrate one of base MathGL concept (see, @ref{General concepts}) -- ``new drawing never clears things drawn already''. So, you can just consequently call different plotting functions to obtain ``combined'' plot. For example, if one need to draw axis then he can just call one more plotting function 
+This demonstrate one of base MathGL concept (see, @ref{General concepts}) -- ``new drawing never clears things drawn already''. So, you can just consequently call different plotting functions to obtain ``combined'' plot. For example, if one need to draw axis then he can just call one more plotting function
 @verbatim
         gr.Axis();			// draw axis
 @end verbatim
@@ -194,19 +194,30 @@ set @var{str} as argument $1 for script;
 ...
 @item @strong{-9} @var{str}
 set @var{str} as argument $9 for script;
+ at item @strong{-L} @var{loc}
+set locale to @var{loc};
+ at item @strong{-s} @var{fname}
+set MGL script for setting up the plot;
+ at item @strong{-h}
+print help message.
+ at end itemize
+Additionally @code{mglconv} have following options:
+ at itemize
 @item @strong{-A} @var{val}
 add @var{val} into the list of animation parameters;
 @item @strong{-C} @var{v1}:@var{v2}[:@var{dv}]
 add values from @var{v1} ot @var{v2} with step @var{dv} (default is 1) into the list of animation parameters;
- at item @strong{-L} @var{loc}
-set locale to @var{loc};
 @item @strong{-o} @var{name}
 set output file name;
- at item @strong{-h}
-print help message.
+ at item @strong{-n}
+disable default output (script should save results by itself);
+ at item @strong{-S} @var{val}
+set set scaling factor for @ref{setsize};
+ at item @strong{-q} @var{val}
+set @ref{quality} for output (val=0...9).
 @end itemize
 
-Additionally you can create animated GIF file or a set of JPEG files with names @samp{frameNNNN.jpg} (here @samp{NNNN} is frame index). Values of the parameter @code{$0} for making animation can be specified inside the script by comment @code{##a val} for each value @code{val} (one comment for one value) or by option(s) @samp{-A val}. Also you can specify a cycle for animation by comment @code{##c v1 v2 dv} or by option @code{-C v1:v2:dv}. In the case of found/specified animation paramet [...]
+Also you can create animated GIF file or a set of JPEG files with names @samp{frameNNNN.jpg} (here @samp{NNNN} is frame index). Values of the parameter @code{$0} for making animation can be specified inside the script by comment @code{##a val} for each value @code{val} (one comment for one value) or by option(s) @samp{-A val}. Also you can specify a cycle for animation by comment @code{##c v1 v2 dv} or by option @code{-C v1:v2:dv}. In the case of found/specified animation parameters, too [...]
 
 
 MathGL also provide another simple tool @code{mgl.cgi} which parse MGL script from CGI request and send back produced PNG file. Usually this program should be placed in @code{/usr/lib/cgi-bin/}. But you need to put this program by yourself due to possible security issues and difference of Apache server settings.
@@ -223,7 +234,9 @@ My special thanks to my wife for the patience during the writing of this library
 @item
 I'm thankful to my coauthors D. Kulagin and M. Vidassov for help in developing MathGL.
 @item
-I'm thankful to D. Eftaxiopoulos, V. Lipatov and S.M. Plis for making binary packages for Linux.
+I'm thankful to Diego Sejas Viscarra for developing mgltex, contribution to fractal generation and fruitful suggestions.
+ at item
+I'm thankful to D. Eftaxiopoulos, D. Haley, V. Lipatov and S.M. Plis for making binary packages for Linux.
 @item
 I'm thankful to S. Skobelev, C. Mikhailenko, M. Veysman, A. Prokhorov, A. Korotkevich, V. Onuchin, S.M. Plis, R. Kiselev, A. Ivanov, N. Troickiy and V. Lipatov for fruitful comments.
 @item
diff --git a/texinfo/overview_ru.texi b/texinfo/overview_ru.texi
index 3570dbb..4d998fe 100644
--- a/texinfo/overview_ru.texi
+++ b/texinfo/overview_ru.texi
@@ -77,7 +77,7 @@ MathGL это ...
 @item
 Скомпилировать библиотеку непосредственно из исходных файлов. С библиотекой поставляется файлы для системы сборки CMake. Для его запуска достаточно в командной строке выполнить 3 команды: сначала @code{cmake .} дважды, далее @code{make} и, наконец, с правами суперпользователя @code{make install}. Иногда после компиляции библиотеки может потребоваться обновление списка библиотека в системе -- выполните команду @code{ldconfig} с правами суперпользователя.
 
-Есть несколько дополнительных опций, которые по умолчанию отключены. К их числу относятся: @code{enable-fltk, enable-glut, enable-qt} для поддержки FLTK, GLUT и/или Qt окон; @code{enable-jpeg, enable-gif, enable-hdf5} для поддержки соответствующих форматов; @code{enable-all} для включения всех возможностей. Для использования типа @code{double} для внутреннего хранения данных используйте опцию @code{enable-double}. Для создания интерфейсов к другим языкам (кроме С/Фортран/MGL) используйте [...]
+Есть несколько дополнительных опций, которые по умолчанию отключены. К их числу относятся: @code{enable-fltk, enable-glut, enable-qt4, enable-qt5} для поддержки FLTK, GLUT и/или Qt окон; @code{enable-jpeg, enable-gif, enable-hdf5} для поддержки соответствующих форматов; @code{enable-all} для включения всех возможностей. Для использования типа @code{double} для внутреннего хранения данных используйте опцию @code{enable-double}. Для создания интерфейсов к другим языкам (кроме С/Фортран/MGL [...]
 
 При сборке с помощью MinGW необходимо дополнительно установить опцию сборки @code{-fopenmp} (т.е. @code{CMAKE_EXE_LINKER_FLAGS:STRING='-fopenmp'} и @code{CMAKE_SHARED_LINKER_FLAGS:STRING='-fopenmp'}) если включена поддержка OpenMP (@code{enable-openmp=ON}).
 
@@ -131,7 +131,7 @@ Basically plot is done. But I decide to add yellow (@samp{y} color, see @ref{Col
 @verbatim
         gr.Cont(dat,"y");	// plot yellow contour lines
 @end verbatim
-This demonstrate one of base MathGL concept (see, @ref{General concepts}) -- ``new drawing never clears things drawn already''. So, you can just consequently call different plotting functions to obtain ``combined'' plot. For example, if one need to draw axis then he can just call one more plotting function 
+This demonstrate one of base MathGL concept (see, @ref{General concepts}) -- ``new drawing never clears things drawn already''. So, you can just consequently call different plotting functions to obtain ``combined'' plot. For example, if one need to draw axis then he can just call one more plotting function
 @verbatim
         gr.Axis();			// draw axis
 @end verbatim
@@ -196,19 +196,30 @@ set @var{str} as argument $1 for script;
 ...
 @item @strong{-9} @var{str}
 set @var{str} as argument $9 for script;
+ at item @strong{-L} @var{loc}
+set locale to @var{loc};
+ at item @strong{-s} @var{fname}
+set MGL script for setting up the plot;
+ at item @strong{-h}
+print help message.
+ at end itemize
+Additionally @code{mglconv} have following options:
+ at itemize
 @item @strong{-A} @var{val}
 add @var{val} into the list of animation parameters;
 @item @strong{-C} @var{v1}:@var{v2}[:@var{dv}]
 add values from @var{v1} ot @var{v2} with step @var{dv} (default is 1) into the list of animation parameters;
- at item @strong{-L} @var{loc}
-set locale to @var{loc};
 @item @strong{-o} @var{name}
 set output file name;
- at item @strong{-h}
-print help message.
+ at item @strong{-n}
+disable default output (script should save results by itself);
+ at item @strong{-S} @var{val}
+set set scaling factor for @ref{setsize};
+ at item @strong{-q} @var{val}
+set @ref{quality} for output (val=0...9).
 @end itemize
 
-Additionally you can create animated GIF file or a set of JPEG files with names @samp{frameNNNN.jpg} (here @samp{NNNN} is frame index). Values of the parameter @code{$0} for making animation can be specified inside the script by comment @code{##a val} for each value @code{val} (one comment for one value) or by option(s) @samp{-A val}. Also you can specify a cycle for animation by comment @code{##c v1 v2 dv} or by option @code{-C v1:v2:dv}. In the case of found/specified animation paramet [...]
+Also you can create animated GIF file or a set of JPEG files with names @samp{frameNNNN.jpg} (here @samp{NNNN} is frame index). Values of the parameter @code{$0} for making animation can be specified inside the script by comment @code{##a val} for each value @code{val} (one comment for one value) or by option(s) @samp{-A val}. Also you can specify a cycle for animation by comment @code{##c v1 v2 dv} or by option @code{-C v1:v2:dv}. In the case of found/specified animation parameters, too [...]
 
 
 MathGL also provide another simple tool @code{mgl.cgi} which parse MGL script from CGI request and send back produced PNG file. Usually this program should be placed in @code{/usr/lib/cgi-bin/}. But you need to put this program by yourself due to possible security issues and difference of Apache server settings.
@@ -226,7 +237,9 @@ MathGL also provide another simple tool @code{mgl.cgi} which parse MGL script fr
 @item
 Я благодарен моим соавторам Д. Кулагину и М. Видассову за помощь в разработке MathGL.
 @item
-Я благодарен D. Eftaxiopoulos, В. Липатову и С. Плису за создание бинарных пакетов для Linux.
+Я благодарен Diego Sejas Viscarra за разработку mgltex, вклад в генерацию фракталов и продуктивные предложения и обсуждения.
+ at item
+Я благодарен D. Eftaxiopoulos, D. Haley, В. Липатову и С. Плису за создание бинарных пакетов для Linux.
 @item
 Я благодарен С. Скобелеву, К. Михайленко, М. Вейсману, A. Прохорову, A. Короткевичу, В. Онучину, С. Плису, Р. Киселеву, A. Иванову, Н. Троицкому and В. Липатову за продуктивные предложения и обсуждения.
 @item
diff --git a/texinfo/symbols_en.texi b/texinfo/symbols_en.texi
index bd7c026..00e102b 100644
--- a/texinfo/symbols_en.texi
+++ b/texinfo/symbols_en.texi
@@ -237,6 +237,8 @@ string continuation symbol on next line for @ref{MGL scripts}.
 @item ~
 disable drawing of tick labels for @ref{axis} and @ref{colorbar};
 
+disable first segment in @ref{lamerey};
+
 one of mask for face filling (see @ref{Color scheme}).
 
 @item 0,1,2,3,4,5,6,7,8,9
@@ -461,7 +463,7 @@ place text centering on vertical direction for @ref{text}.
 @item v
 one of marks (see @ref{Line styles});
 
-set to draw vectors on flow threads for @ref{flow}.
+set to draw vectors on flow threads for @ref{flow} and on segments for @ref{lamerey}.
 
 @item W
 bright gray color (see @ref{Color styles}).
diff --git a/texinfo/symbols_ru.texi b/texinfo/symbols_ru.texi
index bd7c026..00e102b 100644
--- a/texinfo/symbols_ru.texi
+++ b/texinfo/symbols_ru.texi
@@ -237,6 +237,8 @@ string continuation symbol on next line for @ref{MGL scripts}.
 @item ~
 disable drawing of tick labels for @ref{axis} and @ref{colorbar};
 
+disable first segment in @ref{lamerey};
+
 one of mask for face filling (see @ref{Color scheme}).
 
 @item 0,1,2,3,4,5,6,7,8,9
@@ -461,7 +463,7 @@ place text centering on vertical direction for @ref{text}.
 @item v
 one of marks (see @ref{Line styles});
 
-set to draw vectors on flow threads for @ref{flow}.
+set to draw vectors on flow threads for @ref{flow} and on segments for @ref{lamerey}.
 
 @item W
 bright gray color (see @ref{Color styles}).
diff --git a/texinfo/version_hist.txt b/texinfo/version_hist.txt
index 370b144..a1087f1 100644
--- a/texinfo/version_hist.txt
+++ b/texinfo/version_hist.txt
@@ -1,3 +1,5 @@
+2.3.4 Released 11 February 2015
+2.3.3 Released 01 June 2015
 2.3.2 Released 2 February 2015
 2.3.1 Released 21 October 2014
 2.3 Released 7 August 2014
@@ -45,5 +47,5 @@
 1.0 	Released 2 April 2007
 
 0.9		Last beta version of the MathGL library. Released 2 March 2007
-0.8.1	Released 19 Febriary 2007
+0.8.1	Released 19 February 2007
 0.8.0	First public release (24 January 2007)
diff --git a/texinfo/web_en.texi b/texinfo/web_en.texi
index 9288b53..967c477 100644
--- a/texinfo/web_en.texi
+++ b/texinfo/web_en.texi
@@ -52,8 +52,8 @@ Generally, MathGL is GPL library. However, you can use LGPL license for MathGL c
 
 @strong{Latest news}
 @itemize
- at item @emph{1 June 2015.}
-New version (v. at value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, speeding up and bugfixes, which denoted @ref{News, here}.
+ at item @emph{13 February 2016.}
+New version (v. at value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes, which denoted @ref{News, here}.
 @item @emph{7 August 2014.}
 New version (v.2.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
 @end itemize
@@ -75,6 +75,36 @@ Javascript interface was developed with support of @url{http://www.datadvance.ne
 
 @itemize
 
+ at item @strong{13 February 2016.}
+New version (v.2.3.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes:
+ at itemize @bullet
+ at item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
+
+ at item Add @ref{pmap} plot for Poincare map.
+ at item Add @ref{lamerey} plot for Lamerey diagram.
+ at item Add @ref{bifurcation} plot for Bifurcation diagram.
+ at item Add @ref{ifs2d} and @ref{ifs3d} functions for fractal generation using iterated function system (thanks to Diego Sejas Viscarra).
+
+ at item Add @ref{pulse} function for determining pulse parameters.
+ at item Add @ref{scanfile} function for getting formated data from textual file.
+ at item Add mglData::SetList() function for setting data from variable argument list of double values.
+ at item Add @ref{echo} command for printing the content of data.
+ at item Add @ref{print} command for print messages to stdout immediately.
+ at item Add @ref{pendelta} function for changing size of blur area around lines, marks, glyphs, ...
+
+ at item Allow MGL command @ref{save} to write/append strings to a file.
+ at item Add option to rewrite file in @ref{savehdf} command.
+ at item Add option to @ref{setsize} for scaling primitives without its erasing.
+
+ at item Add callback functions to mglQt, mglFLTK, and extend @ref{mglDraw class} for simpler drawing in parallel with calculation (see @ref{Draw and calculate}).
+ at item Force set focus for editor in UDAV.
+ at item Add line numbers to UDAV editor. Cyan number denote current line, red numbers denote lines with errors.
+ at item Disable mouse wheel for zooming in UDAV by default.
+
+ at item @strong{INCOMPATIBLE} Scale internally d1,d2 arguments in @ref{curve} to be exactly the same as Bezier curve (P0=p1, P1=d1+p1, P2=p2-d2, P3=p2).
+ at item Other minor improvements, bugfixes and compatibility changes
+ at end itemize
+
 @item @strong{1 June 2015.}
 New version (v.2.3.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, speeding up and bugfixes:
 @itemize @bullet
@@ -112,7 +142,6 @@ New version (v.2.3.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} i
 @item Other minor improvements, bugfixes and compatibility changes
 @end itemize
 
-
 @item @strong{2 February 2015.}
 New version (v.2.3.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
@@ -406,7 +435,7 @@ There are samples for @ref{1D data plotting, 1D arrays}, @ref{2D data plotting,
 @sfig{hist, Making histogram}
 @sfig{fit, Nonlinear fitting hints}
 @sfig{pde, PDE solving hints}
- at sfig{parser, MGL parser using}
+ at sfig{parser, Using MGL parser}
 
 @external{}
 
@@ -419,19 +448,23 @@ There are samples for @ref{1D data plotting, 1D arrays}, @ref{2D data plotting,
 You may download current version of MathGL for following configurations:
 @itemize @bullet
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.tar.gz,source} file with cmake build system.
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.tar.gz, Source} file with cmake build system.
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.i686.7z,Win32 GPL} binaries for MinGW (build for i686)
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.i686.7z,Win32 GPL} binaries for MinGW (build for i686).
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.i686.7z,Win32 LGPL} binaries for MinGW (build for i686, no GSL and HDF5 support)
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.i386.7z,Win32 LGPL} binaries for MinGW (build for i386, no GSL and HDF5 support).
+ at item
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.Win10-mingw.i386.7z,Win32 GPL} binaries for MinGW (build for i386). This should work on Windows 8 and Windows 10.
 @c @item
 @c @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-win64.7z,Win64 LGPL} binaries for MSVS 2010 (no GSL and HDF5 support)
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.eng.pdf,PDF} documentation in English
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.eng.pdf,PDF} documentation in English.
+ at item
+ at uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}@value{MINVER}.7z, UDAV and utilities} with all required DLL files (build for i686).
+ at item
+ at uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}@value{MINVER}.Win10.7z, UDAV and utilities} with all required DLL files (build for i386). This should work on Windows 8 and Windows 10.
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}@value{MINVER}.7z, UDAV and utilities} with all required DLL files (build for i686)
- at c HTML documentation in English
- at c HTML documentation in Russian
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-doc-html-@value{VERSION}@value{MINVER}.7z, Archive} with HTML documentation and figures.
 @c @item
 @c @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features
 @end itemize
diff --git a/texinfo/web_ru.texi b/texinfo/web_ru.texi
index 58d1bc0..967c477 100644
--- a/texinfo/web_ru.texi
+++ b/texinfo/web_ru.texi
@@ -52,8 +52,8 @@ Generally, MathGL is GPL library. However, you can use LGPL license for MathGL c
 
 @strong{Latest news}
 @itemize
- at item @emph{1 June 2015.}
-New version (v. at value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, speeding up and bugfixes, which denoted @ref{News, here}.
+ at item @emph{13 February 2016.}
+New version (v. at value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes, which denoted @ref{News, here}.
 @item @emph{7 August 2014.}
 New version (v.2.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
 @end itemize
@@ -75,6 +75,36 @@ Javascript interface was developed with support of @url{http://www.datadvance.ne
 
 @itemize
 
+ at item @strong{13 February 2016.}
+New version (v.2.3.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes:
+ at itemize @bullet
+ at item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
+
+ at item Add @ref{pmap} plot for Poincare map.
+ at item Add @ref{lamerey} plot for Lamerey diagram.
+ at item Add @ref{bifurcation} plot for Bifurcation diagram.
+ at item Add @ref{ifs2d} and @ref{ifs3d} functions for fractal generation using iterated function system (thanks to Diego Sejas Viscarra).
+
+ at item Add @ref{pulse} function for determining pulse parameters.
+ at item Add @ref{scanfile} function for getting formated data from textual file.
+ at item Add mglData::SetList() function for setting data from variable argument list of double values.
+ at item Add @ref{echo} command for printing the content of data.
+ at item Add @ref{print} command for print messages to stdout immediately.
+ at item Add @ref{pendelta} function for changing size of blur area around lines, marks, glyphs, ...
+
+ at item Allow MGL command @ref{save} to write/append strings to a file.
+ at item Add option to rewrite file in @ref{savehdf} command.
+ at item Add option to @ref{setsize} for scaling primitives without its erasing.
+
+ at item Add callback functions to mglQt, mglFLTK, and extend @ref{mglDraw class} for simpler drawing in parallel with calculation (see @ref{Draw and calculate}).
+ at item Force set focus for editor in UDAV.
+ at item Add line numbers to UDAV editor. Cyan number denote current line, red numbers denote lines with errors.
+ at item Disable mouse wheel for zooming in UDAV by default.
+
+ at item @strong{INCOMPATIBLE} Scale internally d1,d2 arguments in @ref{curve} to be exactly the same as Bezier curve (P0=p1, P1=d1+p1, P2=p2-d2, P3=p2).
+ at item Other minor improvements, bugfixes and compatibility changes
+ at end itemize
+
 @item @strong{1 June 2015.}
 New version (v.2.3.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, speeding up and bugfixes:
 @itemize @bullet
@@ -405,7 +435,7 @@ There are samples for @ref{1D data plotting, 1D arrays}, @ref{2D data plotting,
 @sfig{hist, Making histogram}
 @sfig{fit, Nonlinear fitting hints}
 @sfig{pde, PDE solving hints}
- at sfig{parser, MGL parser using}
+ at sfig{parser, Using MGL parser}
 
 @external{}
 
@@ -418,19 +448,23 @@ There are samples for @ref{1D data plotting, 1D arrays}, @ref{2D data plotting,
 You may download current version of MathGL for following configurations:
 @itemize @bullet
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.tar.gz,source} file with cmake build system.
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.tar.gz, Source} file with cmake build system.
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.i686.7z,Win32 GPL} binaries for MinGW (build for i686)
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.i686.7z,Win32 GPL} binaries for MinGW (build for i686).
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.i686.7z,Win32 LGPL} binaries for MinGW (build for i686, no GSL and HDF5 support)
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.i386.7z,Win32 LGPL} binaries for MinGW (build for i386, no GSL and HDF5 support).
+ at item
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.Win10-mingw.i386.7z,Win32 GPL} binaries for MinGW (build for i386). This should work on Windows 8 and Windows 10.
 @c @item
 @c @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-win64.7z,Win64 LGPL} binaries for MSVS 2010 (no GSL and HDF5 support)
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.eng.pdf,PDF} documentation in English
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.eng.pdf,PDF} documentation in English.
+ at item
+ at uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}@value{MINVER}.7z, UDAV and utilities} with all required DLL files (build for i686).
+ at item
+ at uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}@value{MINVER}.Win10.7z, UDAV and utilities} with all required DLL files (build for i386). This should work on Windows 8 and Windows 10.
 @item
- at uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}@value{MINVER}.7z, UDAV and utilities} with all required DLL files (build for i686)
- at c HTML documentation in English
- at c HTML documentation in Russian
+ at uref{http://downloads.sourceforge.net/mathgl/mathgl-doc-html-@value{VERSION}@value{MINVER}.7z, Archive} with HTML documentation and figures.
 @c @item
 @c @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features
 @end itemize
diff --git a/texinfo/widget_en.texi b/texinfo/widget_en.texi
index 09d618d..d9f5169 100644
--- a/texinfo/widget_en.texi
+++ b/texinfo/widget_en.texi
@@ -2,16 +2,16 @@
 @c ------------------------------------------------------------------
 @chapter Widget classes
 @nav{}
- at cindex mglWindow
+ at cindex mglWnd
 @cindex mglGLUT
 @cindex Fl_MathGL
 @cindex QMathGL
 @cindex window
 @cindex widgets
 
-There are set of ``window'' classes for making a window with MathGL graphics: @code{mglWindow}, @code{mglFLTK}, @code{mglQT} and @code{mglGLUT} for whole window, @code{Fl_MathGL} and @code{QMathGL} as widgets. All these classes allow user to show, rotate, export, and change view of the plot using keyboard. Most of them (except @code{mglGLUT}) also have toolbar and menu for simplifying plot manipulation. All window classes have mostly the same set of functions.
+There are set of ``window'' classes for making a window with MathGL graphics: @code{mglWindow}, @code{mglFLTK}, @code{mglQT} and @code{mglGLUT} for whole window, @code{Fl_MathGL} and @code{QMathGL} as widgets. All these classes allow user to show, rotate, export, and change view of the plot using keyboard. Most of them (except @code{mglGLUT}) also have toolbar and menu for simplifying plot manipulation. All window classes have mostly the same set of functions derived from @ref{mglWnd class}.
 
-For drawing you can use: @code{NULL} pointer if you'll update plot manually, global callback function of type @code{int draw(@code{HMGL} gr, @code{void *}p)} or @code{int draw(@code{mglGraph *}gr)}, or instance of class derived from @code{mglDraw} class. This class is defined in @code{#include <mgl2/window.h>} and have only 2 methods:
+For drawing you can use: @code{NULL} pointer if you'll update plot manually, global callback function of type @code{int draw(@code{HMGL} gr, @code{void *}p)} or @code{int draw(@code{mglGraph *}gr)}, or instance of class derived from @ref{mglDraw class}. Basically, this class have 2 main virtual methods:
 @verbatim
 class mglDraw
 {
@@ -22,8 +22,47 @@ public:
 @end verbatim
 You should inherit yours class from @code{mglDraw} and re-implement one or both functions for drawing.
 
+The window can be constructed using one of following classes (see @ref{Using MathGL window} for examples).
+
+ at deftypefn {Constructor on @code{mglFLTK}} {} mglFLTK (@code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Constructor on @code{mglFLTK}} {} mglFLTK (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
+ at deftypefnx {Constructor on @code{mglFLTK}} {} mglFLTK (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Constructor on @code{mglFLTK}} {} mglFLTK (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {C function} @code{HMGL} mgl_create_graph_fltk (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
+
+Creates a FLTK-based window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @ref{mglDraw class}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no an [...]
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglFLTK}} @code{int} RunThr ()
+ at deftypefnx {C function} @code{int} mgl_fltk_thr ()
+Run main loop for event handling in separate thread. Note, right now it work for FLTK windows only.
+ at end deftypefn
+
+
+ at deftypefn {Constructor on @code{mglQT}} {} mglQT (@code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Constructor on @code{mglQT}} {} mglQT (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
+ at deftypefnx {Constructor on @code{mglQT}} {} mglQT (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Constructor on @code{mglQT}} {} mglQT (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {C function} @code{HMGL} mgl_create_graph_qt (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
+
+Creates a FLTK-based window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @ref{mglDraw class}. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no an [...]
+ at end deftypefn
+
+
+ at deftypefn {Constructor on @code{mglGLUT}} {} mglGLUT (@code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Constructor on @code{mglGLUT}} {} mglGLUT (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
+ at deftypefnx {Constructor on @code{mglGLUT}} {} mglGLUT (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Constructor on @code{mglGLUT}} {} mglGLUT (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {C function} @code{HMGL} mgl_create_graph_glut (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
+
+Creates a GLUT-based window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @code{mglDraw} class. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no a [...]
+
+There are some keys handles for manipulating by the plot: 'a', 'd', 'w', 's' for the rotating; ',', '.' for viewing of the previous or next frames in the list; 'r' for the switching of transparency; 'f' for the switching of lightning; 'x' for hiding (closing) the window.
+ at end deftypefn
+
 @menu
-* mglWindow class::
+* mglWnd class::
+* mglDraw class::
 * Fl_MathGL class::
 * QMathGL class::
 * wxMathGL class::
@@ -32,107 +71,96 @@ You should inherit yours class from @code{mglDraw} and re-implement one or both
 
 @c ------------------------------------------------------------------
 @external{}
- at node mglWindow class, Fl_MathGL class, , Widget classes
- at section mglWindow class
+ at node mglWnd class, mglDraw class, , Widget classes
+ at section mglWnd class
 @nav{}
- at cindex mglWindow
+ at cindex mglWnd
 @cindex window
 @c @cindex mglDraw
 
-This class is derived from mglGraph class (see @ref{MathGL core}). It is defined in @code{#include <mgl2/window.h>} and provide methods for handling window with MathGL graphics. Similar classes are exist for QT and FLTK widget libraries: @code{mglQT} in @code{#include <mgl2/qt.h>}, @code{mglFLTK} in @code{#include <mgl2/fltk.h>}.
+This class is abstract class derived from mglGraph class (see @ref{MathGL core}). It is defined in @code{#include <mgl2/wnd.h>} and provide base methods for handling window with MathGL graphics. Inherited classes are exist for QT and FLTK widget libraries: @code{mglQT} in @code{#include <mgl2/qt.h>}, @code{mglFLTK} in @code{#include <mgl2/fltk.h>}.
 
- at deftypefn {Constructor on @code{mglWindow}} {} mglWindow (@code{const char *}title=@code{"MathGL"})
- at deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{int} kind=@code{0}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
- at deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"}, @code{int} kind=@code{0})
- at deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"}, @code{int} kind=@code{0})
- at deftypefnx {C function} @code{HMGL} mgl_create_graph_qt (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
- at deftypefnx {C function} @code{HMGL} mgl_create_graph_fltk (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
- at deftypefnx {C function} @code{HMGL} mgl_create_graph_glut (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
-
-Creates a window for plotting. Parameter @var{draw} sets a pointer to drawing function (this is the name of function) or instance of @code{mglDraw} class. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. Note, that @var{draw} can be @code{NULL} for displaying static bitmaps only (no animation or [...]
 
-There are some keys handles for manipulating by the plot: 'a', 'd', 'w', 's' for the rotating; ',', '.' for viewing of the previous or next frames in the list; 'r' for the switching of transparency; 'f' for the switching of lightning; 'x' for hiding (closing) the window.
- at end deftypefn
-
- at deftypefn {Method on @code{mglWindow}} @code{int} RunThr ()
- at deftypefnx {C function} @code{int} mgl_fltk_thr ()
-Run main loop for event handling in separate thread. Note, right now it work for FLTK windows only.
- at end deftypefn
-
- at deftypefn {Method on @code{mglWindow}} @code{int} Run ()
+ at deftypefn {Method on @code{mglWnd}} @code{int} Run ()
 @deftypefnx {C function} @code{int} mgl_qt_run ()
 @deftypefnx {C function} @code{int} mgl_fltk_run ()
 Run main loop for event handling. Usually it should be called in a separate thread or as last function call in @code{main()}.
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{void *}p)=@code{NULL})
- at deftypefnx {Method on @code{mglWindow}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{mglGraph *}gr))
- at deftypefnx {Method on @code{mglWindow}} @code{void} SetDrawFunc (@code{mglDraw *}obj)
+ at deftypefn {Method on @code{mglWnd}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{void *}p)=@code{NULL})
+ at deftypefnx {Method on @code{mglWnd}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{mglGraph *}gr))
+ at deftypefnx {Method on @code{mglWnd}} @code{void} SetDrawFunc (@code{mglDraw *}obj)
 @deftypefnx {C function} @code{void} mgl_wnd_set_func (@code{HMGL} gr, @code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par, @code{void} (*reload)(@code{void *}p))
 Set callback functions for drawing (@var{draw}) and data reloading (@var{reload}), or instance @var{obj} of a class derived from @code{mglDraw}.
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{void} SetClickFunc (@code{void} (*func)(@code{HMGL} gr, @code{void *}p))
+ at deftypefn {Method on @code{mglWnd}} @code{void} SetClickFunc (@code{void} (*func)(@code{HMGL} gr, @code{void *}p))
 @deftypefnx {C function} @code{void} mgl_set_click_func (@code{void} (*func)(@code{HMGL} gr, @code{void *}p))
 Set callback function @var{func} which will be called on mouse click.
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{void} ToggleAlpha ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} SetMutex(@code{pthread_mutex_t *}mutex)
+ at deftypefnx {C function} @code{void} mgl_wnd_set_mutex(@code{HMGL} gr, @code{pthread_mutex_t *}mutex)
+Set external mutex for lock/unlock external calculations by widget. This functions is called automatically at using @ref{mglDraw class}.
+ at end deftypefn
+
+
+ at deftypefn {Method on @code{mglWnd}} @code{void} ToggleAlpha ()
 @deftypefnx {C function} @code{void} mgl_wnd_toggle_alpha (@code{HMGL} gr)
 Switch on/off transparency but do not overwrite switches in user drawing function.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} ToggleLight ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} ToggleLight ()
 @deftypefnx {C function} @code{void} mgl_wnd_toggle_light (@code{HMGL} gr)
 Switch on/off lighting but do not overwrite switches in user drawing function.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} ToggleRotate ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} ToggleRotate ()
 @deftypefnx {C function} @code{void} mgl_wnd_toggle_rotate (@code{HMGL} gr)
 Switch on/off rotation by mouse. Usually, left button is used for rotation, middle button for shift, right button for zoom/perspective.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} ToggleZoom ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} ToggleZoom ()
 @deftypefnx {C function} @code{void} mgl_wnd_toggle_zoom (@code{HMGL} gr)
 Switch on/off zooming by mouse. Just select rectangular region by mouse and it will be zoomed in.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} ToggleNo ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} ToggleNo ()
 @deftypefnx {C function} @code{void} mgl_wnd_toggle_no (@code{HMGL} gr)
 Switch off all zooming and rotation and restore initial state.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} Update ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} Update ()
 @deftypefnx {C function} @code{void} mgl_wnd_update (@code{HMGL} gr)
 Update window contents. This is very useful function for manual updating the plot while long calculation was running in parallel thread.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} ReLoad ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} ReLoad ()
 @deftypefnx {C function} @code{void} mgl_wnd_reload (@code{HMGL} gr)
 Reload user data and update picture. This function also update number of frames which drawing function can create.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} Adjust ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} Adjust ()
 @deftypefnx {C function} @code{void} mgl_wnd_adjust (@code{HMGL} gr)
 Adjust size of bitmap to window size.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} NextFrame ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} NextFrame ()
 @deftypefnx {C function} @code{void} mgl_wnd_next_frame (@code{HMGL} gr)
 Show next frame if one.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} PrevFrame ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} PrevFrame ()
 @deftypefnx {C function} @code{void} mgl_wnd_prev_frame (@code{HMGL} gr)
 Show previous frame if one.
 @end deftypefn
- at deftypefn {Method on @code{mglWindow}} @code{void} Animation ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} Animation ()
 @deftypefnx {C function} @code{void} mgl_wnd_animation (@code{HMGL} gr)
 Run/stop slideshow (animation) of frames.
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{void} SetDelay (@code{double} dt)
+ at deftypefn {Method on @code{mglWnd}} @code{void} SetDelay (@code{double} dt)
 @deftypefnx {C function} @code{void} mgl_wnd_set_delay (@code{HMGL} gr, @code{double} dt)
 Sets delay for animation in seconds. Default value is 1 sec.
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{double} GetDelay ()
+ at deftypefn {Method on @code{mglWnd}} @code{double} GetDelay ()
 @deftypefnx {C function} @code{double} mgl_wnd_get_delay (@code{HMGL} gr)
 Gets delay for animation in seconds.
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{void} Setup (@code{bool} clfupd=@code{true}, @code{bool} showpos=@code{false})
+ at deftypefn {Method on @code{mglWnd}} @code{void} Setup (@code{bool} clfupd=@code{true}, @code{bool} showpos=@code{false})
 @deftypefnx {C function} @code{void} mgl_setup_window (@code{HMGL} gr, @code{bool} clfupd, @code{bool} showpos)
 Enable/disable flags for:
 @itemize @bullet
@@ -143,14 +171,60 @@ showing the last mouse click position in the widget.
 @end itemize
 @end deftypefn
 
- at deftypefn {Method on @code{mglWindow}} @code{mglPoint} LastMousePos ()
+ at deftypefn {Method on @code{mglWnd}} @code{mglPoint} LastMousePos ()
 @deftypefnx {C function} @code{void} mgl_get_last_mouse_pos (@code{HMGL} gr, @code{mreal *}x, @code{mreal *}y, @code{mreal *}z)
 Gets last position of mouse click.
 @end deftypefn
 
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node mglDraw class, Fl_MathGL class, mglWnd class, Widget classes
+ at section mglDraw class
+ at nav{}
+ at cindex mglDraw
+
+This class provide base functionality for callback drawing and running calculation in separate thread. It is defined in @code{#include <mgl2/wnd.h>}. You should make inherited class and implement virtual functions if you need it.
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{int} Draw (@code{mglGraph *}gr)
+This is callback drawing function, which will be called when any redrawing is required for the window. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. 
+ at end deftypefn
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{void} Reload ()
+This is callback function, which will be called if user press menu or toolbutton to reload data. 
+ at end deftypefn
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{void} Click ()
+This is callback function, which will be called if user click mouse. 
+ at end deftypefn
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{void} Calc ()
+This is callback function, which will be called if user start calculations in separate thread by calling @code{mglDraw::Run()} function. It should periodically call @code{mglDraw::Check()} function to check if calculations should be paused. 
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Run ()
+Runs @code{mglDraw::Calc()} function in separate thread. It also initialize @code{mglDraw::thr} variable and unlock @code{mglDraw::mutex}. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Cancel ()
+Cancels thread with calculations. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Pause ()
+Pauses thread with calculations by locking @code{mglDraw::mutex}. You should call @code{mglDraw::Continue()} to continue calculations. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Continue ()
+Continues calculations by unlocking @code{mglDraw::mutex}. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Continue ()
+Checks if calculations should be paused and pause it. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
 @c ------------------------------------------------------------------
 @external{}
- at node Fl_MathGL class, QMathGL class, mglWindow class, Widget classes
+ at node Fl_MathGL class, QMathGL class, mglDraw class, Widget classes
 @section Fl_MathGL class
 @nav{}
 @cindex Fl_MathGL
diff --git a/texinfo/widget_ru.texi b/texinfo/widget_ru.texi
index c14dde8..5066c58 100644
--- a/texinfo/widget_ru.texi
+++ b/texinfo/widget_ru.texi
@@ -2,16 +2,16 @@
 @c ------------------------------------------------------------------
 @chapter ``Оконные'' классы
 @nav{}
- at cindex mglWindow
+ at cindex mglWnd
 @cindex mglGLUT
 @cindex Fl_MathGL
 @cindex QMathGL
 @cindex window
 @cindex widgets
 
-Есть целый набор ``оконных'' классов для создания окон с графикой MathGL: @code{mglWindow} и @code{mglGLUT} для окон целиком, @code{Fl_MathGL} и @code{QMathGL} для виджетов. Все эти классы позволяют пользователю просмотривать, вращать, экспортировать рисунок. Большинство из них (кроме @code{mglGLUT}) имеют панель инструментов для упрощения изменения графика. Все оконные классы имеют схожий набор функций. Ниже приведен список классов с краткими комментариями.
+Есть целый набор ``оконных'' классов для создания окон с графикой MathGL: @code{mglWnd} и @code{mglGLUT} для окон целиком, @code{Fl_MathGL} и @code{QMathGL} для виджетов. Все эти классы позволяют пользователю просмотривать, вращать, экспортировать рисунок. Большинство из них (кроме @code{mglGLUT}) имеют панель инструментов для упрощения изменения графика. Все оконные классы имеют схожий набор функций. Ниже приведен список классов с краткими комментариями.
 
-Для рисования можно использовать: указатель @code{NULL} если планируется обновлять график вручную, глобальную функцию типа @code{int draw(@code{HMGL} gr, @code{void *}p)} или @code{int draw(@code{mglGraph *}gr)}, или экземпляр класса, производного от @code{mglDraw}. Этот класс определен в @code{#include <mgl2/window.h>} и имеет только 2 метода:
+Для рисования можно использовать: указатель @code{NULL} если планируется обновлять график вручную, глобальную функцию типа @code{int draw(@code{HMGL} gr, @code{void *}p)} или @code{int draw(@code{mglGraph *}gr)}, или экземпляр класса, производного от @ref{mglDraw class}. Этот класс определен в @code{#include <mgl2/wnd.h>} и имеет 2 основных виртуальных метода:
 @verbatim
 class mglDraw
 {
@@ -22,8 +22,50 @@ public:
 @end verbatim
 Вам следует наследовать свой класс от @code{mglDraw} и определить один или оба метода.
 
+Непосредственно окна можно создать используя один из следующих классов (см. @ref{Using MathGL window} для примеров).
+
+
+ at deftypefn {Конструктор класса @code{mglFLTK}} {} mglFLTK (@code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Конструктор класса @code{mglFLTK}} {} mglFLTK (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
+ at deftypefnx {Конструктор класса @code{mglFLTK}} {} mglFLTK (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Конструктор класса @code{mglFLTK}} {} mglFLTK (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Функция С} @code{HMGL} mgl_create_graph_fltk (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
+
+Создает FLTK окно для вывода графика. Параметр @var{draw} -- указатель (имя) функции рисования. Есть возможность создания нескольких кадров вначале (требует больше памяти) и их быстрая анимации в дальнейшем. В этом случае функция @var{draw} должна возвращать число кадров или ноль для рисования по запросу. Замечу, что @var{draw} может быть равна @code{NULL} для отображения статической (текущей) картинки. Параметр @var{title} задает заголовок окна. Параметр @var{par} содержит указатель на  [...]
+ at end deftypefn
+
+ at deftypefn {Метод класса @code{mglWnd}} @code{int} RunThr ()
+ at deftypefnx {Функция С} @code{int} mgl_fltk_thr ()
+Запускает цикл обработки сообщений в отдельном потоке. В данный момент работает только для окон FLTK.
+ at end deftypefn
+
+
+ at deftypefn {Конструктор класса @code{mglQT}} {} mglQT (@code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Конструктор класса @code{mglQT}} {} mglQT (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
+ at deftypefnx {Конструктор класса @code{mglQT}} {} mglQT (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Конструктор класса @code{mglQT}} {} mglQT (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Функция С} @code{HMGL} mgl_create_graph_qt (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
+
+Создает Qt окно для вывода графика. Параметр @var{draw} -- указатель (имя) функции рисования. Есть возможность создания нескольких кадров вначале (требует больше памяти) и их быстрая анимации в дальнейшем. В этом случае функция @var{draw} должна возвращать число кадров или ноль для рисования по запросу. Замечу, что @var{draw} может быть равна @code{NULL} для отображения статической (текущей) картинки. Параметр @var{title} задает заголовок окна. Параметр @var{par} содержит указатель на да [...]
+ at end deftypefn
+
+
+ at deftypefn {Конструктор класса @code{mglGLUT}} {} mglGLUT (@code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Конструктор класса @code{mglGLUT}} {} mglGLUT (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
+ at deftypefnx {Конструктор класса @code{mglGLUT}} {} mglGLUT (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Конструктор класса @code{mglGLUT}} {} mglGLUT (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+ at deftypefnx {Функция С} @code{HMGL} mgl_create_graph_glut (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
+
+Создает окно для вывода графика. Параметр @var{draw} -- указатель (имя) функции рисования. Есть возможность создания нескольких кадров вначале (требует больше памяти) и их быстрая анимации в дальнейшем. В этом случае функция @var{draw} должна возвращать число кадров или ноль для рисования по запросу. Замечу, что @var{draw} может быть равна @code{NULL} для отображения статической (текущей) картинки. Параметр @var{title} задает заголовок окна. Параметр @var{par} содержит указатель на данны [...]
+
+В окне просмотра можно использовать клавиши: 'a', 'd', 'w', 's' для вращения; ',', '.' для просмотра предыдущего и следующего кадров; 'r' для переключения прозрачности; 'f' для переключения оспещенности; 'x' для закрытия окна.
+ at end deftypefn
+
+
+
 @menu
-* mglWindow class::
+* mglWnd class::
+* mglDraw class::
 * Fl_MathGL class::
 * QMathGL class::
 * wxMathGL class::
@@ -32,107 +74,94 @@ public:
 
 @c ------------------------------------------------------------------
 @external{}
- at node mglWindow class, Fl_MathGL class, , Widget classes
- at section Класс mglWindow
+ at node mglWnd class, Fl_MathGL class, , Widget classes
+ at section Класс mglWnd
 @nav{}
- at cindex mglWindow
+ at cindex mglWnd
 @cindex window
 @c @cindex mglDraw
 
-Этот класс производный от класса mglGraph (см. @ref{MathGL core}). Он определен в @code{#include <mgl2/window.h>}. Класс содержит методы для создания и управления окном, содержащим графику MathGL. Похожий набор классов существует отдельно для каждой библиотеки виджетов: @code{mglQT} в @code{#include <mgl2/qt.h>}, @code{mglFLTK} в @code{#include <mgl2/fltk.h>}.
-
- at deftypefn {Конструктор класса @code{mglWindow}} {} mglWindow (@code{const char *}title=@code{"MathGL"})
- at deftypefnx {Конструктор класса @code{mglWindow}} {} mglWindow (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{int} kind=@code{0}, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p)=0)
- at deftypefnx {Конструктор класса @code{mglWindow}} {} mglWindow (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"}, @code{int} kind=@code{0})
- at deftypefnx {Конструктор класса @code{mglWindow}} {} mglWindow (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"}, @code{int} kind=@code{0})
- at deftypefnx {Функция С} @code{HMGL} mgl_create_graph_qt (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
- at deftypefnx {Функция С} @code{HMGL} mgl_create_graph_fltk (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
- at deftypefnx {Функция С} @code{HMGL} mgl_create_graph_glut (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par, @code{void} (*reload)(@code{HMGL} gr, @code{void *}p))
-
-Создает окно для вывода графика. Параметр @var{draw} -- указатель (имя) функции рисования. Есть возможность создания нескольких кадров вначале (требует больше памяти) и их быстрая анимации в дальнейшем. В этом случае функция @var{draw} должна возвращать число кадров или ноль для рисования по запросу. Замечу, что @var{draw} может быть равна @code{NULL} для отображения статической (текущей) картинки. Параметр @var{title} задает заголовок окна. Параметр @var{par} содержит указатель на данны [...]
+Это абстрактный класс производный от класса mglGraph (см. @ref{MathGL core}). Он определен в @code{#include <mgl2/wnd.h>}. Класс содержит методы для создания и управления окном, содержащим графику MathGL. Производные от него классы существует отдельно для каждой библиотеки виджетов: @code{mglQT} в @code{#include <mgl2/qt.h>}, @code{mglFLTK} в @code{#include <mgl2/fltk.h>}.
 
-В окне просмотра можно использовать клавиши: 'a', 'd', 'w', 's' для вращения; ',', '.' для просмотра предыдущего и следующего кадров; 'r' для переключения прозрачности; 'f' для переключения оспещенности; 'x' для закрытия окна.
- at end deftypefn
-
- at deftypefn {Метод класса @code{mglWindow}} @code{int} RunThr ()
- at deftypefnx {Функция С} @code{int} mgl_fltk_thr ()
-Запускает цикл обработки сообщений в отдельном потоке. В данный момент работает только для окон FLTK.
- at end deftypefn
-
- at deftypefn {Метод класса @code{mglWindow}} @code{int} Run ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{int} Run ()
 @deftypefnx {Функция С} @code{int} mgl_qt_run ()
 @deftypefnx {Функция С} @code{int} mgl_fltk_run ()
 Запускает цикл обработки сообщений. Обычно эта функция должна вызываться в отдельном потоке или последней функцией в @code{main()}.
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{void *}p)=@code{NULL})
- at deftypefnx {Метод класса @code{mglWindow}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{mglGraph *}gr))
- at deftypefnx {Метод класса @code{mglWindow}} @code{void} SetDrawFunc (@code{mglDraw *}obj)
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par=@code{NULL}, @code{void} (*reload)(@code{void *}p)=@code{NULL})
+ at deftypefnx {Метод класса @code{mglWnd}} @code{void} SetDrawFunc (@code{int} (*draw)(@code{mglGraph *}gr))
+ at deftypefnx {Метод класса @code{mglWnd}} @code{void} SetDrawFunc (@code{mglDraw *}obj)
 @deftypefnx {Функция С} @code{void} mgl_wnd_set_func (@code{HMGL} gr, @code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{void *}par, @code{void} (*reload)(@code{void *}p))
 Устанавливает функцию, которая будет вызвана при перерисовке (@var{draw}) и при повторной загрузке данных (@var{reload}), или объект @var{obj} класса, производного от @code{mglDraw}.
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{void} SetClickFunc (@code{void} (*func)(@code{HMGL} gr, @code{void *}p))
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} SetClickFunc (@code{void} (*func)(@code{HMGL} gr, @code{void *}p))
 @deftypefnx {Функция С} @code{void} mgl_set_click_func (@code{void} (*func)(@code{HMGL} gr, @code{void *}p))
 Устанавливает функцию, которая будет вызвана при щелчке мышью.
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{void} ToggleAlpha ()
+ at deftypefn {Method on @code{mglWnd}} @code{void} SetMutex(@code{pthread_mutex_t *}mutex)
+ at deftypefnx {C function} @code{void} mgl_wnd_set_mutex(@code{HMGL} gr, @code{pthread_mutex_t *}mutex)
+Устанавливает внешний mutex для блокировки/разблокировки внешних вычислений с помощью меню или кнопок окна. Функция вызывается автоматически при использовании @ref{mglDraw class}.
+ at end deftypefn
+
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} ToggleAlpha ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_toggle_alpha (@code{HMGL} gr)
 Включает/выключает прозрачность, но не перекрывает ее включение в пользовательской функции рисования.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} ToggleLight ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} ToggleLight ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_toggle_light (@code{HMGL} gr)
 Включает/выключает освещение, но не перекрывает его включение в пользовательской функции рисования.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} ToggleRotate ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} ToggleRotate ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_toggle_rotate (@code{HMGL} gr)
 Включает/выключает вращение мышкой. Нажатая левая кнопка используется для вращения, средняя для сдвига, правая для приближения/перспективы.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} ToggleZoom ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} ToggleZoom ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_toggle_zoom (@code{HMGL} gr)
 Включает/выключает приближение мышкой. Выделите прямоугольную область и она будет приближена.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} ToggleNo ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} ToggleNo ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_toggle_no (@code{HMGL} gr)
 Выключает вращение и приближение мышкой, а также восстанавливает исходный вид графика.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} Update ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} Update ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_update (@code{HMGL} gr)
 Обновляет содержимое окна. Функция полезна при ручном обновлении содержимого, пока долгий расчет идет в параллельном потоке.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} ReLoad ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} ReLoad ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_reload (@code{HMGL} gr)
 Перегружает данные и обновляет рисунок. Функция также обновляет число кадров, которое создает функция рисования.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} Adjust ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} Adjust ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_adjust (@code{HMGL} gr)
 Подгоняет размер рисунка под размер окна.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} NextFrame ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} NextFrame ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_next_frame (@code{HMGL} gr)
 Показывает следующий кадр, если он есть.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} PrevFrame ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} PrevFrame ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_prev_frame (@code{HMGL} gr)
 Показывает предыдущий кадр, если он есть.
 @end deftypefn
- at deftypefn {Метод класса @code{mglWindow}} @code{void} Animation ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} Animation ()
 @deftypefnx {Функция С} @code{void} mgl_wnd_animation (@code{HMGL} gr)
 Запускает/останавливает анимацию кадров.
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{void} SetDelay (@code{double} dt)
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} SetDelay (@code{double} dt)
 @deftypefnx {Функция С} @code{void} mgl_wnd_set_delay (@code{HMGL} gr, @code{double} dt)
 Задает задержку при анимации в секундах. По умолчанию интервал -- 1 секунда.
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{double} GetDelay ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{double} GetDelay ()
 @deftypefnx {Функция С} @code{double} mgl_wnd_get_delay (@code{HMGL} gr)
 Возвращает задержку при анимации в секундах.
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{void} Setup (@code{bool} clfupd=@code{true}, @code{bool} showpos=@code{false})
+ at deftypefn {Метод класса @code{mglWnd}} @code{void} Setup (@code{bool} clfupd=@code{true}, @code{bool} showpos=@code{false})
 @deftypefnx {Функция С} @code{void} mgl_setup_window (@code{HMGL} gr, @code{bool} clfupd, @code{bool} showpos)
 Включает/выключает:
 @itemize @bullet
@@ -143,14 +172,59 @@ public:
 @end itemize
 @end deftypefn
 
- at deftypefn {Метод класса @code{mglWindow}} @code{mglPoint} LastMousePos ()
+ at deftypefn {Метод класса @code{mglWnd}} @code{mglPoint} LastMousePos ()
 @deftypefnx {Функция С} @code{void} mgl_get_last_mouse_pos (@code{HMGL} gr, @code{mreal *}x, @code{mreal *}y, @code{mreal *}z)
 Возвращает положение щелчка мыши.
 @end deftypefn
 
 @c ------------------------------------------------------------------
 @external{}
- at node Fl_MathGL class, QMathGL class, mglWindow class, Widget classes
+ at node mglDraw class, Fl_MathGL class, mglWnd class, Widget classes
+ at section mglDraw class
+ at nav{}
+ at cindex mglDraw
+
+This class provide base functionality for callback drawing and running calculation in separate thread. It is defined in @code{#include <mgl2/wnd.h>}. You should make inherited class and implement virtual functions if you need it.
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{int} Draw (@code{mglGraph *}gr)
+This is callback drawing function, which will be called when any redrawing is required for the window. There is support of a list of plots (frames). So as one can prepare a set of frames at first and redraw it fast later (but it requires more memory). Function should return positive number of frames for the list or zero if it will plot directly. 
+ at end deftypefn
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{void} Reload ()
+This is callback function, which will be called if user press menu or toolbutton to reload data. 
+ at end deftypefn
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{void} Click ()
+This is callback function, which will be called if user click mouse. 
+ at end deftypefn
+
+ at deftypefn {Virtual method on @code{mglDraw}} @code{void} Calc ()
+This is callback function, which will be called if user start calculations in separate thread by calling @code{mglDraw::Run()} function. It should periodically call @code{mglDraw::Check()} function to check if calculations should be paused. 
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Run ()
+Runs @code{mglDraw::Calc()} function in separate thread. It also initialize @code{mglDraw::thr} variable and unlock @code{mglDraw::mutex}. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Cancel ()
+Cancels thread with calculations. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Pause ()
+Pauses thread with calculations by locking @code{mglDraw::mutex}. You should call @code{mglDraw::Continue()} to continue calculations. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Continue ()
+Continues calculations by unlocking @code{mglDraw::mutex}. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at deftypefn {Method on @code{mglDraw}} @code{void} Continue ()
+Checks if calculations should be paused and pause it. Function is present only if FLTK support for widgets was enabled.
+ at end deftypefn
+
+ at c ------------------------------------------------------------------
+ at external{}
+ at node Fl_MathGL class, QMathGL class, mglDraw class, Widget classes
 @section Класс Fl_MathGL
 @nav{}
 @cindex Fl_MathGL
diff --git a/todo.txt b/todo.txt
index 24dd1d8..2bef216 100644
--- a/todo.txt
+++ b/todo.txt
@@ -34,17 +34,18 @@
 2. Add manual shift of unrotated axis/tick labels.
 3. Centered curved text (see text2)
 
+4. Alternative algorithm for filled glyphs + user-defined glyphs.
+int DefineGlyph(const mglData &x, const mglData &y);
+void DrawGlyph(int id, mglPoint pos, double angle, double scale, const char *stl);
+
 5. Check lighting in OpenGL mode
 6. Add string manipulation -- {'str',val}=>str[val]; {'str',v1,v2}=>str.substr(v1,v2) [v1,v2 can be -1]; {'ch'+val'}=>char(ch+val)
 7. Improve z-order for rapidly oscillating surfaces
 8. Contour lines for bilinear interpolation (strong saddle-like faces)
 9. More accurate face cutting if one partially out of axis ranges
 
-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!!!}
 
@@ -56,27 +57,7 @@ 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"
+6. Update Qt and UDAV figures
 
 YY. Sample like http://pyxplot.org.uk/examples/05ap/02hlines/index.html using Stem()
 
diff --git a/udav/CMakeLists.txt b/udav/CMakeLists.txt
index 9ccc07b..4c80b36 100644
--- a/udav/CMakeLists.txt
+++ b/udav/CMakeLists.txt
@@ -1,4 +1,4 @@
-if(enable-qt)
+if(QT_ENABLED)
 
 configure_file(${MathGL_SOURCE_DIR}/udav/mgl.xml.in ${MathGL_BINARY_DIR}/udav/mgl.xml)
 
@@ -65,4 +65,4 @@ if(findupmdb)
 	install(FILES ${CMAKE_BINARY_DIR}/udav/mgl.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages/)
 	install(CODE "execute_process(COMMAND \"${findupmdb}\" \"${CMAKE_INSTALL_PREFIX}/share/mime\")")
 endif(findupmdb)
-endif(enable-qt)
+endif(QT_ENABLED)
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index 8b04bf1..9dca3b1 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,9 +1,6 @@
-
+include_directories(${GSL_INCLUDE_DIR})
 add_executable(make_pas make_pas.cpp)
 
-add_executable(make_bin make_bin.cpp)
-target_link_libraries(make_bin mgl)
-
 add_executable(mglconv mglconv.cpp)
 target_link_libraries(mglconv mgl)
 install(
@@ -19,7 +16,7 @@ install(
 	RUNTIME DESTINATION ${MGL_CGI_PATH}
 )
 
-if(enable-qt)
+if(QT_ENABLED)
 	add_executable(mglview mglview.cpp)
 	if(enable-qt5)
 		include(../cmake-qt5.txt)
@@ -35,4 +32,4 @@ if(enable-qt)
 		TARGETS mglview
 		RUNTIME DESTINATION bin
 	)
-endif(enable-qt)
+endif(QT_ENABLED)
diff --git a/utils/mglcgi.cpp b/utils/mglcgi.cpp
index a7ff4ad..befec30 100644
--- a/utils/mglcgi.cpp
+++ b/utils/mglcgi.cpp
@@ -18,7 +18,6 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include <locale.h>
-#include <unistd.h>
 #include "mgl2/mgl.h"
 //-----------------------------------------------------------------------------
 int MGL_LOCAL_CONST mgl_hex(char ch)
diff --git a/utils/mglconv.cpp b/utils/mglconv.cpp
index 14ae65e..9f6551c 100644
--- a/utils/mglconv.cpp
+++ b/utils/mglconv.cpp
@@ -18,7 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include <locale.h>
-#include <unistd.h>
+#include <getopt.h>
 #include "mgl2/mgl.h"
 void mgl_error_print(const char *Message, void *par);
 void mgl_ask_gets(const wchar_t *quest, wchar_t *res);
@@ -79,11 +79,11 @@ int main(int argc, char *argv[])
 				"\t...          ...\n"
 				"\t-9 str       set str as argument $9 for script\n"
 				"\t-L loc       set locale to loc\n"
-				"\t-s opt       set MGL script for setting up the plot\n"
+				"\t-s fname     set MGL script for setting up the plot\n"
 				"\t-S val       set scaling factor for images\n"
 				"\t-q val       set quality for output (val=0...9)\n"
 				"\t-o name      set output file name\n"
-				"\t-n           no manual output (script should save results by itself)\n"
+				"\t-n           no default output (script should save results by itself)\n"
 				"\t-A val       add animation value val\n"
 				"\t-C n1:n2:dn  add animation value in range [n1,n2] with step dn\n"
 				"\t-C n1:n2     add animation value in range [n1,n2] with step 1\n"
diff --git a/utils/mglview.cpp b/utils/mglview.cpp
index a34e55b..a005ceb 100644
--- a/utils/mglview.cpp
+++ b/utils/mglview.cpp
@@ -18,7 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include <locale.h>
-#include <unistd.h>
+#include <getopt.h>
 
 #include "mgl2/mgl.h"
 #include "mgl2/qt.h"
diff --git a/widgets/fltk.cpp b/widgets/fltk.cpp
index 53e159f..5516813 100644
--- a/widgets/fltk.cpp
+++ b/widgets/fltk.cpp
@@ -22,7 +22,6 @@
 #include <FL/Fl_Double_Window.H>
 #include <FL/fl_draw.H>
 #include <FL/Fl_File_Chooser.H>
-//#include <unistd.h>
 //-----------------------------------------------------------------------------
 #ifdef USE_GETTEXT
 #include <libintl.h>
@@ -53,6 +52,7 @@
 #include "xpm/ok.xpm"
 #include "xpm/wire.xpm"
 #include "xpm/stop.xpm"
+#include "xpm/pause.xpm"
 //-----------------------------------------------------------------------------
 Fl_Pixmap xpm_a1(alpha_xpm);
 Fl_Pixmap xpm_l1(light_xpm);
@@ -60,6 +60,7 @@ Fl_Pixmap xpm_z1(zoom_in_xpm);
 Fl_Pixmap xpm_s1(show_sl_xpm);
 Fl_Pixmap xpm_r1(rotate_xpm);
 Fl_Pixmap xpm_wire(wire_xpm);
+Fl_Pixmap xpm_pause(pause_xpm);
 //-----------------------------------------------------------------------------
 /// Class allows the window creation for displaying plot bitmap with the help of FLTK library
 /** NOTE!!! All frames are saved in memory. So animation with many frames require a lot memory and CPU time (for example, for mouse rotation).*/
@@ -335,9 +336,31 @@ void Fl_MGLView::setoff(int &val, Fl_Button *b, const char *txt)
 	//update();
 }
 //-----------------------------------------------------------------------------
+void Fl_MGLView::exec_pause()
+{
+#if MGL_HAVE_PTHR_WIDGET
+	pthread_mutex_t *mutex=0;
+	mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(FMGL->gr);
+	if(g && g->mutex)	mutex = g->mutex;
+	else
+	{
+		mglDraw *d=FMGL->get_class();
+		if(d)	mutex = &(d->mutex);
+	}
+	if(mutex)
+	{
+		if(pauseC)	pthread_mutex_lock(mutex);
+		else	pthread_mutex_unlock(mutex);
+	}
+#endif
+}
+//-----------------------------------------------------------------------------
+void MGL_NO_EXPORT mgl_pause_cb(Fl_Widget*, void* v)
+{	if(v)	((Fl_MGLView*)v)->toggle_pause();	}
+//-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_grid_cb(Fl_Widget*, void* v)
 {	if(v)	((Fl_MGLView*)v)->toggle_grid();	}
-//-------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_alpha_cb(Fl_Widget*, void* v)
 {	if(v)	((Fl_MGLView*)v)->toggle_alpha();	}
 void mglCanvasFL::ToggleAlpha()	{	mgl->toggle_alpha();	}
@@ -574,7 +597,7 @@ Fl_Menu_Item pop_graph[20] = {
 Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Window(xx,yy,ww,hh,lbl)
 {
 	Fl_Button *o;
-	grid = alpha = light = sshow = 0;	menu = 0;
+	grid = alpha = light = sshow = pauseC = 0;	menu = 0;
 	next = prev = reload = NULL;	delay = NULL;
 
 	Fl_Group *g = new Fl_Group(0,0,435,30);
@@ -610,7 +633,7 @@ Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Win
 	phi->tooltip(mgl_gettext("Phi angle (rotate in x*y plane)"));
 	g->end();	g->resizable(0);
 
-	g = new Fl_Group(0,0,30,260);
+	g = new Fl_Group(0,0,30,285);
 	o = new Fl_Button(1, 30, 25, 25);		o->tooltip(mgl_gettext("Shift the picture up"));
 	o->image(new Fl_Pixmap(up_1_xpm));		o->callback(mgl_su_cb,this);
 //	o->box(FL_PLASTIC_UP_BOX);	o->down_box(FL_PLASTIC_DOWN_BOX);
@@ -625,6 +648,7 @@ Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Win
 	o = new Fl_Button(1, 155, 25, 25);		o->tooltip(mgl_gettext("Shift the picture down"));
 	o->image(new Fl_Pixmap(down_1_xpm));	o->callback(mgl_sd_cb,this);
 
+
 	o = new Fl_Button(1, 185, 25, 25);		o->tooltip(mgl_gettext("Show previous frame in slideshow"));
 	o->image(new Fl_Pixmap(prev_sl_xpm));	o->callback(mgl_sprev_cb,this);
 	anim_bt = new Fl_Button(1, 210, 25, 25);	anim_bt->type(FL_TOGGLE_BUTTON);
@@ -632,6 +656,13 @@ Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Win
 	anim_bt->tooltip(mgl_gettext("Run/Stop slideshow (graphics animation)"));
 	o = new Fl_Button(1, 235, 25, 25);		o->tooltip(mgl_gettext("Show next frame in slideshow"));
 	o->image(new Fl_Pixmap(next_sl_xpm));	o->callback(mgl_snext_cb,this);
+
+#if MGL_HAVE_PTHR_WIDGET
+	pause_bt = new Fl_Button(1, 260, 25, 25);	pause_bt->type(FL_TOGGLE_BUTTON);
+	pause_bt->image(xpm_pause);	pause_bt->callback(mgl_pause_cb,this);
+	pause_bt->tooltip(mgl_gettext("Pause on/off calculations"));
+#endif
+
 	g->end();	g->resizable(0);
 
 	scroll = new Fl_Scroll(30, 30, 800, 600);
@@ -676,6 +707,7 @@ void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w)
 	m->add("Graphics/Reload data", "f9", mgl_oncemore_cb, w);
 	m->add("Graphics/Stop", "f7", mgl_stop_cb, w);
 	//TODO	m->add("Graphics/Copy graphics","+^c", mgl_copyimg_cb, w);
+	m->add("Graphics/Pause calc", "^t", mgl_pause_cb, w, FL_MENU_TOGGLE);
 
 	m->add("Graphics/Export/as PNG", "#p", mgl_export_png_cb, w);
 	m->add("Graphics/Export/as solid PNG", "#f", mgl_export_pngn_cb, w);
@@ -747,7 +779,7 @@ MGL_NO_EXPORT void *mgl_fltk_tmp(void *)
 //-----------------------------------------------------------------------------
 int MGL_EXPORT mgl_fltk_thr()		// NOTE: Qt couldn't be running in non-primary thread
 {
-#if MGL_HAVE_PTHREAD
+#if MGL_HAVE_PTHR_WIDGET
 	static pthread_t thr;
 	pthread_create(&thr,0,mgl_fltk_tmp,0);
 	pthread_detach(thr);
diff --git a/widgets/qt.cpp b/widgets/qt.cpp
index e371e45..485abe9 100644
--- a/widgets/qt.cpp
+++ b/widgets/qt.cpp
@@ -102,7 +102,7 @@ QMathGL::QMathGL(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
 	popup = 0;	grBuf = 0;	draw = 0;
 	phi = tet = per = 0;
 	x1 = y1 = ax1 = ay1 = 0;	x2 = y2 = ax2 = ay2 = 1;
-	alpha = light = zoom = rotate = grid = viewYZ = custZoom = custDraw = false;
+	alpha = light = zoom = rotate = grid = viewYZ = custZoom = custDraw = pause = false;
 	resize(600, 400);	mgl_set_flag(gr, true, MGL_CLF_ON_UPD);
 	timer = new QTimer(this);
 	timerRefr = new QTimer(this);	timerRefr->setInterval(100);
@@ -220,6 +220,30 @@ void QMathGL::setGrid(bool g)
 void QMathGL::setViewYZ(bool a)
 {	if(viewYZ!=a)	{	viewYZ = a;	emit viewYZChanged(a);	refresh();	}	}
 //-----------------------------------------------------------------------------
+void QMathGL::setPause(bool p)
+{
+#if MGL_HAVE_PTHR_WIDGET
+	if(pause!=p)
+	{
+		pthread_mutex_t *mutex=0;
+		mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(gr);
+		if(g && g->mutex)	mutex = g->mutex;
+		else
+		{
+			mglDraw *d=getClass();
+			if(d)	mutex = &(d->mutex);
+		}
+		if(mutex)
+		{
+			if(p)	pthread_mutex_lock(mutex);
+			else	pthread_mutex_unlock(mutex);
+		}
+		pause=p;
+		emit pauseChanged(p);
+	}
+#endif
+}
+//-----------------------------------------------------------------------------
 void QMathGL::setRotate(bool r)
 {
 	if(rotate!=r)
@@ -1066,18 +1090,19 @@ void mglCanvasQT::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p
 #include "xpm/zoom_out.xpm"
 #include "xpm/up_1.xpm"
 #include "xpm/stop.xpm"
+#include "xpm/pause.xpm"
 //-----------------------------------------------------------------------------
 #define TR	QObject::tr
 MGL_EXPORT QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&phi)
 {
 	QAction *a;
-	QMenu *o, *oo;
+	QMenu *o, *oo, *f;
 	QToolBar *bb;
 
 	QMenu *popup = new QMenu(Wnd);
 	// file menu
 	{
-		o = Wnd->menuBar()->addMenu(TR("&File"));
+		f = o = Wnd->menuBar()->addMenu(TR("&File"));
 		oo = new QMenu(TR("&Export as 2D ..."),Wnd);
 		oo->addAction(TR("PNG"), QMGL, SLOT(exportPNG()),Qt::ALT+Qt::Key_P);
 		oo->addAction(TR("solid PNG"), QMGL, SLOT(exportPNGs()),Qt::ALT+Qt::Key_F);
@@ -1272,6 +1297,19 @@ MGL_EXPORT QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, Q
 		a->setToolTip(TR("Show previous slide (Ctrl+,)."));
 		a->setShortcut(Qt::CTRL+Qt::Key_Comma);	o->addAction(a);		bb->addAction(a);
 	}
+#if MGL_HAVE_PTHR_WIDGET
+	{
+		bb = new QToolBar(TR("Calculations"),Wnd);
+		Wnd->addToolBar(Qt::LeftToolBarArea, bb);
+		a = new QAction(QPixmap(pause_xpm), TR("Pause calculation"), Wnd);
+		a->setCheckable(true);
+		Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setPause(bool)));
+		Wnd->connect(QMGL, SIGNAL(pauseChanged(bool)), a, SLOT(setChecked(bool)));
+//		Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(setPause()));
+		a->setToolTip(TR("Pause on/off calculations."));
+		f->addSeparator();	f->addAction(a);	bb->addAction(a);
+	}
+#endif
 
 	Wnd->menuBar()->addSeparator();
 	o = Wnd->menuBar()->addMenu(TR("&Help"));

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathgl.git



More information about the debian-science-commits mailing list