]> wagner.pp.ru Git - oss/fgis.git/commitdiff
First checked in version
authorVictor Wagner <vitus@wagner.pp.ru>
Tue, 31 Dec 2002 19:38:08 +0000 (19:38 +0000)
committerVictor Wagner <vitus@wagner.pp.ru>
Tue, 31 Dec 2002 19:38:08 +0000 (19:38 +0000)
288 files changed:
Makefile [new file with mode: 0644]
TODO [new file with mode: 0644]
colors/150color.clr [new file with mode: 0644]
colors/50grays.clr [new file with mode: 0644]
colors/aspect.clr [new file with mode: 0644]
colors/aspect8.clr [new file with mode: 0644]
colors/bw100.clr [new file with mode: 0644]
colors/bw17.clr [new file with mode: 0644]
colors/bw256.clr [new file with mode: 0644]
colors/bw256inv.clr [new file with mode: 0644]
colors/bw5.clr [new file with mode: 0644]
colors/bw64.clr [new file with mode: 0644]
colors/default.clr [new file with mode: 0644]
colors/digdoq.clr [new file with mode: 0644]
colors/drgbw.clr [new file with mode: 0644]
colors/drgclr.clr [new file with mode: 0644]
colors/ega.clr [new file with mode: 0644]
colors/fort.clr [new file with mode: 0644]
colors/lesson.clr [new file with mode: 0644]
colors/luse.clr [new file with mode: 0644]
colors/names.clr [new file with mode: 0644]
colors/pal100.clr [new file with mode: 0644]
colors/pal24.clr [new file with mode: 0644]
colors/pal255.clr [new file with mode: 0644]
colors/rainbow.clr [new file with mode: 0644]
colors/random.clr [new file with mode: 0644]
dll/Makefile [new file with mode: 0644]
dll/fgis.h [new file with mode: 0644]
dll/fgisCount.c [new file with mode: 0644]
dll/fgisEppCalc.c [new file with mode: 0644]
dll/fgisEppDraw.c [new file with mode: 0644]
dll/fgisEppEdit.c [new file with mode: 0644]
dll/fgisEppEdit.h [new file with mode: 0644]
dll/fgisInit.c [new file with mode: 0644]
dll/fgisInt.h [new file with mode: 0644]
dll/fgisMisc.c [new file with mode: 0644]
dll/fgisPalette.c [new file with mode: 0644]
dll/fgisPatterns.c [new file with mode: 0644]
dll/fgisPlanchet.c [new file with mode: 0644]
dll/fgisProjection.c [new file with mode: 0644]
dll/fgisRaster.c [new file with mode: 0644]
dll/fgisVector.c [new file with mode: 0644]
dll/patterns.n [new file with mode: 0644]
doc/.log [new file with mode: 0644]
doc/3rd.attempt [new file with mode: 0644]
doc/concepts.html [new file with mode: 0644]
doc/doc.formats [new file with mode: 0644]
doc/epu_doc.tex [new file with mode: 0644]
doc/layers.doc [new file with mode: 0644]
doc/levels.eps [new file with mode: 0644]
doc/levels.fig [new file with mode: 0644]
doc/levels.gif [new file with mode: 0644]
doc/levels.pbm [new file with mode: 0644]
doc/levels.xbm [new file with mode: 0644]
doc/lib_doc.tex [new file with mode: 0644]
doc/lib_doc.toc [new file with mode: 0644]
doc/object_concept [new file with mode: 0644]
doc/region.concept [new file with mode: 0644]
doc/visualisagion.concept [new file with mode: 0644]
epu/Makefile [new file with mode: 0644]
epu/bil2epp [new file with mode: 0755]
epu/bil2epp.c [new file with mode: 0644]
epu/border.c [new file with mode: 0644]
epu/centers.c [new file with mode: 0644]
epu/clip.c [new file with mode: 0644]
epu/cluster [new file with mode: 0755]
epu/cluster.c [new file with mode: 0644]
epu/dgt2gen [new file with mode: 0755]
epu/dgt2gen.c [new file with mode: 0644]
epu/eheader.c [new file with mode: 0644]
epu/extents.c [new file with mode: 0644]
epu/fill.c [new file with mode: 0644]
epu/intable [new file with mode: 0755]
epu/intable.c [new file with mode: 0644]
epu/mosaic.c [new file with mode: 0644]
epu/neighbours.c [new file with mode: 0644]
epu/outtab.c [new file with mode: 0644]
epu/outtable.c [new file with mode: 0644]
epu/outtable.h [new file with mode: 0644]
epu/outtable_func.c [new file with mode: 0644]
epu/points.tab [new file with mode: 0644]
epu/project [new file with mode: 0755]
epu/project.c [new file with mode: 0644]
epu/reclass1.c [new file with mode: 0644]
epu/tag2epp.c [new file with mode: 0644]
epu/window.c [new file with mode: 0644]
fgis.rc [new file with mode: 0644]
include/Makefile [new file with mode: 0644]
include/clr.h [new file with mode: 0644]
include/defpal.h [new file with mode: 0644]
include/dgt.h [new file with mode: 0644]
include/epp.h [new file with mode: 0644]
include/epp_err.h [new file with mode: 0644]
include/eppl.h [new file with mode: 0644]
include/eppl_ut.h [new file with mode: 0644]
include/getopt.h [new file with mode: 0644]
include/reclass.h [new file with mode: 0644]
include/regex.h [new file with mode: 0644]
lib/Makefile [new file with mode: 0644]
lib/TODO.lib [new file with mode: 0644]
lib/byteorder.c [new file with mode: 0644]
lib/clr.c [new file with mode: 0644]
lib/dgt_dist.c [new file with mode: 0644]
lib/dgt_input.c [new file with mode: 0644]
lib/dgt_iter.c [new file with mode: 0644]
lib/dgt_output.c [new file with mode: 0644]
lib/epp_cache.c [new file with mode: 0644]
lib/epp_input.c [new file with mode: 0644]
lib/epp_iter.c [new file with mode: 0644]
lib/epp_loaded.c [new file with mode: 0644]
lib/epp_output.c [new file with mode: 0644]
lib/epp_private.h [new file with mode: 0644]
lib/file_utils.c [new file with mode: 0644]
lib/gnu_lib/getopt.c [new file with mode: 0644]
lib/gnu_lib/getopt.h [new file with mode: 0644]
lib/gnu_lib/getopt1.c [new file with mode: 0644]
lib/gnu_lib/regex.c [new file with mode: 0644]
lib/gnu_lib/regex.h [new file with mode: 0644]
lib/lookup.c [new file with mode: 0644]
lib/overlay.c [new file with mode: 0644]
lib/reclass.tab.c [new file with mode: 0644]
lib/reclass.y [new file with mode: 0644]
lib/test/Makefile [new file with mode: 0644]
lib/test/recltest.c [new file with mode: 0644]
lib/test/test8.epp [new file with mode: 0644]
lib/test/test_epplib.c [new file with mode: 0644]
lib/test/testdata.dat [new file with mode: 0644]
maketar [new file with mode: 0755]
man/border.1 [new file with mode: 0644]
man/clip.1 [new file with mode: 0644]
man/cluster.1 [new file with mode: 0644]
man/eheader.1 [new file with mode: 0644]
man/extents.1 [new file with mode: 0644]
man/fgisRasterColorImage.n [new file with mode: 0644]
man/legend.n [new file with mode: 0644]
man/mosaic.1 [new file with mode: 0644]
man/neighbours.1 [new file with mode: 0644]
man/outtable.1 [new file with mode: 0644]
man/palette.n [new file with mode: 0644]
man/planchet.n [new file with mode: 0644]
man/projection.n [new file with mode: 0644]
man/raster.n [new file with mode: 0644]
man/reclass.1 [new file with mode: 0644]
man/window.1 [new file with mode: 0644]
pkgIndex.tcl [new file with mode: 0644]
symbols/alpha10.sym [new file with mode: 0644]
symbols/alpha6.sym [new file with mode: 0644]
symbols/digit25.sym [new file with mode: 0644]
symbols/digit6.sym [new file with mode: 0644]
symbols/fort10.sym [new file with mode: 0644]
symbols/gray5.sym [new file with mode: 0644]
symbols/luse6.sym [new file with mode: 0644]
symbols/misc14.sym [new file with mode: 0644]
symbols/misc16.sym [new file with mode: 0644]
symbols/misc25.sym [new file with mode: 0644]
symbols/misc3.sym [new file with mode: 0644]
symbols/misc8.sym [new file with mode: 0644]
symbols/tone10a.sym [new file with mode: 0644]
symbols/tone10b.sym [new file with mode: 0644]
symbols/tone10c.sym [new file with mode: 0644]
symbols/tone10d.sym [new file with mode: 0644]
symbols/tone5.sym [new file with mode: 0644]
symbols/tone6a.sym [new file with mode: 0644]
symbols/tone6b.sym [new file with mode: 0644]
tcl/admin.layer [new file with mode: 0644]
tcl/balloonhelp.tcl [new file with mode: 0644]
tcl/calculator.tcl [new file with mode: 0644]
tcl/combobox.tcl [new file with mode: 0644]
tcl/console.tcl [new file with mode: 0644]
tcl/draw.tcl [new file with mode: 0644]
tcl/getopt.tcl [new file with mode: 0644]
tcl/help.tcl [new file with mode: 0644]
tcl/hierarchy.tcl [new file with mode: 0644]
tcl/html_library.tcl [new file with mode: 0644]
tcl/hypermap [new file with mode: 0755]
tcl/layer.tcl [new file with mode: 0644]
tcl/legend.tcl [new file with mode: 0644]
tcl/lesras.lay [new file with mode: 0644]
tcl/mapview [new file with mode: 0755]
tcl/objects.tcl [new file with mode: 0644]
tcl/planchet.tcl [new file with mode: 0644]
tcl/progressbar.tcl [new file with mode: 0644]
tcl/tabnotebook.tcl [new file with mode: 0644]
tcl/tclIndex [new file with mode: 0644]
tcl/toolbar.tcl [new file with mode: 0644]
tcl/ventry.tcl [new file with mode: 0644]
tcl/viewer.tcl [new file with mode: 0644]
tcl/widget.tcl [new file with mode: 0644]
testdata/admin.epp [new file with mode: 0644]
testdata/admin.lay [new file with mode: 0644]
testdata/admin.leg [new file with mode: 0644]
testdata/admin_html.leg [new file with mode: 0644]
testdata/html/1.html [new file with mode: 0644]
testdata/html/10.html [new file with mode: 0644]
testdata/html/11.html [new file with mode: 0644]
testdata/html/12.html [new file with mode: 0644]
testdata/html/13.html [new file with mode: 0644]
testdata/html/14.html [new file with mode: 0644]
testdata/html/15.html [new file with mode: 0644]
testdata/html/16.html [new file with mode: 0644]
testdata/html/17.html [new file with mode: 0644]
testdata/html/18.html [new file with mode: 0644]
testdata/html/19.html [new file with mode: 0644]
testdata/html/2.html [new file with mode: 0644]
testdata/html/20.html [new file with mode: 0644]
testdata/html/21.html [new file with mode: 0644]
testdata/html/22.html [new file with mode: 0644]
testdata/html/23.html [new file with mode: 0644]
testdata/html/24.html [new file with mode: 0644]
testdata/html/25.html [new file with mode: 0644]
testdata/html/26.html [new file with mode: 0644]
testdata/html/27.html [new file with mode: 0644]
testdata/html/28.html [new file with mode: 0644]
testdata/html/29.html [new file with mode: 0644]
testdata/html/3.html [new file with mode: 0644]
testdata/html/30.html [new file with mode: 0644]
testdata/html/31.html [new file with mode: 0644]
testdata/html/32.html [new file with mode: 0644]
testdata/html/33.html [new file with mode: 0644]
testdata/html/34.html [new file with mode: 0644]
testdata/html/35.html [new file with mode: 0644]
testdata/html/36.html [new file with mode: 0644]
testdata/html/37.html [new file with mode: 0644]
testdata/html/38.html [new file with mode: 0644]
testdata/html/39.html [new file with mode: 0644]
testdata/html/4.html [new file with mode: 0644]
testdata/html/40.html [new file with mode: 0644]
testdata/html/41.html [new file with mode: 0644]
testdata/html/42.html [new file with mode: 0644]
testdata/html/43.html [new file with mode: 0644]
testdata/html/44.html [new file with mode: 0644]
testdata/html/45.html [new file with mode: 0644]
testdata/html/46.html [new file with mode: 0644]
testdata/html/47.html [new file with mode: 0644]
testdata/html/48.html [new file with mode: 0644]
testdata/html/49.html [new file with mode: 0644]
testdata/html/5.html [new file with mode: 0644]
testdata/html/50.html [new file with mode: 0644]
testdata/html/51.html [new file with mode: 0644]
testdata/html/52.html [new file with mode: 0644]
testdata/html/53.html [new file with mode: 0644]
testdata/html/54.html [new file with mode: 0644]
testdata/html/55.html [new file with mode: 0644]
testdata/html/56.html [new file with mode: 0644]
testdata/html/57.html [new file with mode: 0644]
testdata/html/58.html [new file with mode: 0644]
testdata/html/59.html [new file with mode: 0644]
testdata/html/6.html [new file with mode: 0644]
testdata/html/60.html [new file with mode: 0644]
testdata/html/61.html [new file with mode: 0644]
testdata/html/62.html [new file with mode: 0644]
testdata/html/63.html [new file with mode: 0644]
testdata/html/64.html [new file with mode: 0644]
testdata/html/65.html [new file with mode: 0644]
testdata/html/66.html [new file with mode: 0644]
testdata/html/67.html [new file with mode: 0644]
testdata/html/68.html [new file with mode: 0644]
testdata/html/69.html [new file with mode: 0644]
testdata/html/7.html [new file with mode: 0644]
testdata/html/70.html [new file with mode: 0644]
testdata/html/71.html [new file with mode: 0644]
testdata/html/72.html [new file with mode: 0644]
testdata/html/73.html [new file with mode: 0644]
testdata/html/74.html [new file with mode: 0644]
testdata/html/75.html [new file with mode: 0644]
testdata/html/76.html [new file with mode: 0644]
testdata/html/77.html [new file with mode: 0644]
testdata/html/78.html [new file with mode: 0644]
testdata/html/79.html [new file with mode: 0644]
testdata/html/8.html [new file with mode: 0644]
testdata/html/80.html [new file with mode: 0644]
testdata/html/81.html [new file with mode: 0644]
testdata/html/82.html [new file with mode: 0644]
testdata/html/83.html [new file with mode: 0644]
testdata/html/84.html [new file with mode: 0644]
testdata/html/85.html [new file with mode: 0644]
testdata/html/86.html [new file with mode: 0644]
testdata/html/9.html [new file with mode: 0644]
testdata/lesras.epp [new file with mode: 0755]
testdata/lesras.lay [new file with mode: 0644]
testdata/lesras.leg [new file with mode: 0644]
testdata/mkhtml.tcl [new file with mode: 0644]
testdata/pgrm.epp [new file with mode: 0755]
testdata/poger.epp [new file with mode: 0755]
testdata/soil_mo.clr [new file with mode: 0644]
testdata/soil_mo.epp [new file with mode: 0644]
testdata/soil_mo.leg [new file with mode: 0644]
testdata/test.prj [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..99bf0da
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,27 @@
+
+all: fgis.so epu doc
+
+fgis.so: dll/fgis.so
+       cp dll/fgis.so .
+
+dll/fgis.so: lib/libepp.a proj/libproj.a dll/*.c 
+       cd dll; make fgis.so
+
+lib/libepp.a:
+       cd lib; make
+
+proj/libproj.a:
+       cd proj; make
+
+epu: lib/libepp.a epu/*.[chy]
+       cd epu; make all
+clean:
+       for i in dll epu doc proj lib ; do make clean; done
+
+doc:
+       cd doc; make
+
+tar: 
+       ./maketar
+        
+       
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..a43c4e8
--- /dev/null
+++ b/TODO
@@ -0,0 +1,71 @@
+Near future
+
+Fgis tcl extension:
+
+1. Compile tcl extension for NT/Win 95
+
+2. Finish pattern handling
+
+3. Write drawing of patterned raster
+
+4. Write projection object
+
+5. Finish editing primitives
+
+6. Separate tk-dependent part from non-GUI part of C code.
+
+7. Develop initialization code for Win32
+
+Tcl scripts
+
+1. Invent interface to call EPU from within TCL
+
+2. Complete chart (choropleth) type of layer
+
+3. Write tag (point) type of layer
+
+4. Invent standartized interface to SQL databases (Postgres, Oracle,
+   ODBC for start)
+
+5. Write ``object'' layer  - collection of arbitrary Tk canvas items,
+   which are treated as layer and can be saved and loaded
+
+EPU
+
+1. Debug outtable
+
+2. Write projection conversion tool
+
+3. Write evaluate
+
+4. Do something with border and debug rasterize
+
+5. Write ppmtoepp and epptoppm converters
+
+6. Design and write RADIUS
+
+7. Design and write INTERPOLATE
+
+Distribution:
+
+1. Write top-level Makefile
+
+2. Provide example dataset
+
+3. Write installation program for Win32 binary distr.
+
+Documentation
+
+1. Fill holes in docs for already written commands
+
+2. Document layered structure of fGIS
+
+3. Translte epp_lib docs to English
+
+4. Complete (and translate to english) EPU manual
+
+IDEAS TO CONSIDER
+
+fGIS user environment should be able to store layers in RCS
+
+Invent and document vector format
diff --git a/colors/150color.clr b/colors/150color.clr
new file mode 100644 (file)
index 0000000..4bef0c9
--- /dev/null
@@ -0,0 +1,152 @@
+  0    0       0       0       BLACK\r
+  1    462     729     196     \r
+  2    533     847     219     \r
+  3    603     913     298     \r
+  4    678     964     388     \r
+  5    498     1000    749     LT. GREEN\r
+  6    196     729     462     \r
+  7    219     847     533     \r
+  8    298     913     603     \r
+  9    388     964     678     \r
+ 10    498     1000    749     \r
+ 11    0       729     0       \r
+ 12    0       796     0       \r
+ 13    0       862     0       \r
+ 14    0       929     0       \r
+ 15    0       1000    0       GREEN\r
+ 16    792     792     129     \r
+ 17    898     898     168     \r
+ 18    941     941     266     \r
+ 19    976     976     376     \r
+ 20    1000    1000    500     YELLOW\r
+ 21    1000    444     0       ORANGE\r
+ 22    1000    634     0       \r
+ 23    1000    730     0       \r
+ 24    1000    825     0       \r
+ 25    1000    904     0       \r
+ 26    729     462     196     \r
+ 27    847     533     219     \r
+ 28    913     603     298     \r
+ 29    964     678     388     \r
+ 30    1000    749     498     \r
+ 31    792     129     129     \r
+ 32    898     168     168     \r
+ 33    941     266     266     \r
+ 34    976     376     376     \r
+ 35    1000    498     498     \r
+ 36    729     0       0       \r
+ 37    796     0       0       DK. RED\r
+ 38    862     0       0       \r
+ 39    929     0       0       \r
+ 40    1000    0       0       RED\r
+ 41    650     215     215     DK. BROWN\r
+ 42    756     270     270     \r
+ 43    796     388     388     BROWN\r
+ 44    835     505     505     \r
+ 45    874     623     623     LT. BROWN\r
+ 46    650     215     650     \r
+ 47    756     270     756     \r
+ 48    796     388     796     \r
+ 49    835     505     835     \r
+ 50    874     623     874     \r
+ 51    0       729     729     DK. CYAN\r
+ 52    0       796     796     \r
+ 53    0       862     862     \r
+ 54    0       929     929     \r
+ 55    0       1000    1000    CYAN\r
+ 56    129     792     792     \r
+ 57    168     898     898     \r
+ 58    266     941     941     \r
+ 59    376     976     976     \r
+ 60    498     1000    1000    LT. CYAN\r
+ 61    215     650     650     \r
+ 62    270     756     756     \r
+ 63    388     796     796     \r
+ 64    505     835     835     \r
+ 65    623     874     874     \r
+ 66    0       0       929     DK. BLUE\r
+ 67    0       0       1000    BLUE\r
+ 68    298     576     996     \r
+ 69    196     678     996     \r
+ 70    98      819     996     LT. BLUE\r
+ 71    196     462     729     \r
+ 72    219     533     847     \r
+ 73    298     603     913     \r
+ 74    388     678     964     \r
+ 75    498     749     1000    \r
+ 76    462     196     729     DK. PURPLE\r
+ 77    533     219     847     \r
+ 78    603     298     913     PURPLE\r
+ 79    678     388     964     \r
+ 80    749     498     1000    LT. PURPLE\r
+ 81    729     0       729     DK. MAGENTA\r
+ 82    796     0       796     \r
+ 83    862     0       862     \r
+ 84    929     0       929     \r
+ 85    1000    0       1000    MAGENTA\r
+ 86    792     129     792     \r
+ 87    898     168     898     \r
+ 88    941     266     941     \r
+ 89    976     376     976     \r
+ 90    1000    498     1000    LT. MAGENTA\r
+ 91    1000    0       1000    \r
+ 92    240     1000    1000    \r
+ 93    500     1000    1000    \r
+ 94    750     1000    1000    \r
+ 95    750     750     1000    \r
+ 96    1000    500     1000    \r
+ 97    1000    750     1000    \r
+ 98    1000    1000    750     LT. YELLOW\r
+ 99    1000    1000    0       BT. YELLOW\r
+100    1000    793     587     \r
+101    750     1000    750     \r
+102    500     1000    500     \r
+103    627     313     0       \r
+104    730     63      63      \r
+105    627     313     0       \r
+106    1000    650     650     \r
+107    888     523     587     \r
+108    825     571     269     \r
+109    904     0       476     \r
+110    1000    857     888     \r
+111    0       0       0       BLACK\r
+112    492     492     492     DK. GRAY\r
+113    501     501     501     \r
+114    507     507     507     \r
+115    523     523     523     \r
+116    539     539     539     \r
+117    555     555     555     \r
+118    555     555     555     \r
+119    571     571     571     \r
+120    587     587     587     \r
+121    492     492     492     \r
+122    603     603     603     \r
+123    619     619     619     MD. GRAY\r
+124    634     634     634     \r
+125    666     666     666     \r
+126    682     682     682     \r
+127    698     698     698     \r
+128    714     714     714     \r
+129    730     730     730     \r
+130    746     746     746     \r
+131    746     746     746     \r
+132    873     873     873     \r
+133    761     761     761     \r
+134    777     777     777     \r
+135    793     793     793     \r
+136    809     809     809     \r
+137    825     825     825     \r
+138    841     841     841     \r
+139    857     857     857     \r
+140    873     873     873     LT. GRAY\r
+141    873     873     873     \r
+142    886     886     886     \r
+143    888     888     888     \r
+144    904     904     904     \r
+145    920     920     920     \r
+146    936     936     936     \r
+147    952     952     952     \r
+148    952     952     952     \r
+149    968     968     968     \r
+150    1000    1000    1000    WHITE\r
+255    1000    1000    1000    WHITE\r
diff --git a/colors/50grays.clr b/colors/50grays.clr
new file mode 100644 (file)
index 0000000..7624013
--- /dev/null
@@ -0,0 +1,52 @@
+0      0       0       0       BLACK\r
+1      0       0       0       BLACK\r
+2      3       3       3       \r
+3      31      31      31      \r
+4      156     156     156     \r
+5      478     478     478     \r
+6      482     482     482     \r
+7      494     494     494     \r
+8      509     509     509     \r
+9      525     525     525     \r
+10     533     533     533     \r
+11     541     541     541     \r
+12     545     545     545     \r
+13     576     576     576     \r
+14     592     592     592     \r
+15     603     603     603     \r
+16     507     507     507\r
+17     611     611     611\r
+18     623     623     623\r
+19     635     635     635\r
+20     666     666     666\r
+21     670     670     670\r
+22     674     674     674\r
+23     682     682     682\r
+24     701     701     701\r
+25     713     713     713\r
+26     733     733     733\r
+27     737     737     737\r
+28     741     741     741\r
+29     756     756     756\r
+30     772     772     772\r
+31     788     788     788\r
+32     800     800     800\r
+33     803     803     803\r
+34     807     807     807\r
+35     835     835     835\r
+36     850     850     850\r
+37     866     866     866\r
+38     870     870     870\r
+39     874     874     874\r
+40     886     886     886\r
+41     894     894     894\r
+42     909     909     909\r
+43     929     929     929\r
+44     933     933     933\r
+45     937     937     937\r
+46     964     964     964\r
+47     968     968     968\r
+48     980     980     980\r
+49     984     984     984\r
+50     1000    1000    1000\r
+255    1000    1000    1000\r
diff --git a/colors/aspect.clr b/colors/aspect.clr
new file mode 100644 (file)
index 0000000..9d8e885
--- /dev/null
@@ -0,0 +1,181 @@
+  0  726  726  726\r
+  1    0  407  298\r
+  2    0  423  290\r
+  3    0  439  282\r
+  4    0  454  274\r
+  5    0  470  266\r
+  6    0  486  258\r
+  7    0  501  250\r
+  8   11  509  243\r
+  9   23  517  235\r
+ 10   35  525  227\r
+ 11   47  533  219\r
+ 12   58  541  211\r
+ 13   70  549  203\r
+ 14   82  556  196\r
+ 15   98  564  188\r
+ 16  109  572  180\r
+ 17  121  580  172\r
+ 18  133  588  164\r
+ 19  145  596  156\r
+ 20  156  603  149\r
+ 21  168  611  141\r
+ 22  180  619  133\r
+ 23  196  627  125\r
+ 24  207  635  117\r
+ 25  219  643  109\r
+ 26  231  650  101\r
+ 27  243  658   94\r
+ 28  254  666   86\r
+ 29  266  674   78\r
+ 30  278  682   70\r
+ 31  294  690   62\r
+ 32  305  698   54\r
+ 33  317  705   47\r
+ 34  329  713   39\r
+ 35  341  721   31\r
+ 36  352  729   23\r
+ 37  364  737   15\r
+ 38  376  745    7\r
+ 39  392  752    0  \r
+ 40  407  756    0  \r
+ 41  427  764    0  \r
+ 42  447  772    0  \r
+ 43  466  780    0  \r
+ 44  486  788    0  \r
+ 45  505  796    0   \r
+ 46  521  803    0  \r
+ 47  541  811    0  \r
+ 48  560  819    0  \r
+ 49  580  827    0  \r
+ 50  600  835    0  \r
+ 51  619  843    0  \r
+ 52  635  850    0  \r
+ 53  654  858    0  \r
+ 54  674  866    0  \r
+ 55  694  874    0  \r
+ 56  713  882    0  \r
+ 57  733  890    0  \r
+ 58  752  898    0  \r
+ 59  768  905    0  \r
+ 60  788  913    0  \r
+ 61  807  921    0  \r
+ 62  827  929    0  \r
+ 63  847  937    0  \r
+ 64  866  945    0  \r
+ 65  882  952    0  \r
+ 66  901  960    0  \r
+ 67  921  968    0  \r
+ 68  941  976    0  \r
+ 69  960  984    0  \r
+ 70  980  992    0  \r
+ 71 1000 1000    0  \r
+ 72 1000  980    0  \r
+ 73 1000  960    0  \r
+ 74 1000  941    0  \r
+ 75 1000  921    0  \r
+ 76 1000  901    0  \r
+ 77 1000  882    0  \r
+ 78 1000  866    0  \r
+ 79 1000  847    0  \r
+ 80 1000  827    0  \r
+ 81 1000  807    0  \r
+ 82 1000  788    0  \r
+ 83 1000  768    0  \r
+ 84 1000  752    0  \r
+ 85 1000  733    0  \r
+ 86 1000  713    0  \r
+ 87 1000  694    0  \r
+ 88 1000  674    0  \r
+ 89 1000  654    0  \r
+ 90 1000  635    0  \r
+ 91 1000  619    0  \r
+ 92 1000  600    0  \r
+ 93 1000  580    0  \r
+ 94 1000  560    0  \r
+ 95 1000  541    0  \r
+ 96 1000  521    0  \r
+ 97 1000  505    0  \r
+ 98 1000  486    0  \r
+ 99 1000  466    0  \r
+100 1000  447    0  \r
+101 1000  427    0  \r
+102 1000  407    0  \r
+103 1000  392    0  \r
+104 1000  376   11\r
+105 1000  364   23\r
+106 1000  352   35\r
+107 1000  341   47\r
+108 1000  329   58\r
+109 1000  317   70\r
+110 1000  305   82\r
+111 1000  294   98\r
+112 1000  278  109\r
+113 1000  266  121\r
+114 1000  254  133\r
+115 1000  243  145\r
+116 1000  231  156\r
+117 1000  219  168\r
+118 1000  207  180\r
+119 1000  196  196\r
+120 1000  180  207\r
+121 1000  168  219\r
+122 1000  156  231\r
+123 1000  145  243\r
+124 1000  133  254\r
+125 1000  121  266\r
+126 1000  109  278\r
+127 1000   98  294\r
+128 1000   82  305\r
+129 1000   70  317\r
+130 1000   58  329\r
+131 1000   47  341\r
+132 1000   35  352\r
+133 1000   23  364\r
+134 1000   11  376\r
+135 1000    0  392\r
+136  988    0  400\r
+137  980    0  411\r
+138  968    0  419\r
+139  960    0  431\r
+140  952    0  439\r
+141  941    0  450\r
+142  933    0  458\r
+143  925    0  470\r
+144  913    0  478\r
+145  905    0  490\r
+146  898    0  498\r
+147  886    0  509\r
+148  878    0  517\r
+149  870    0  529\r
+150  858    0  537\r
+151  850    0  549\r
+152  682    0  674\r
+153  674    0  662\r
+154  662    0  647\r
+155  650    0  631\r
+156  643    0  619\r
+157  631    0  603\r
+158  623    0  592\r
+159  611    0  576\r
+160  600    0  560\r
+161  592    0  549\r
+162  580    0  533\r
+163  568    0  517\r
+164  560    0  505\r
+165  549    0  490\r
+166  541    0  478\r
+167  529    0  462\r
+168  549    0  447\r
+169  509    0  435\r
+170  498    0  419\r
+171  486    0  403\r
+172  478    0  392\r
+173  466    0  376\r
+174  458    0  364\r
+175  447    0  349\r
+176  435    0  333\r
+177  427    0  321\r
+178  415    0  305\r
+179  403    0  290\r
+180  396    0  278
\ No newline at end of file
diff --git a/colors/aspect8.clr b/colors/aspect8.clr
new file mode 100644 (file)
index 0000000..7eb7675
--- /dev/null
@@ -0,0 +1,256 @@
+  0  726  726  726\r
+  1    0    0  444\r
+  2    0  158  365\r
+  3    0  317  285\r
+  4  380  730    0\r
+  5 1000  825    0\r
+  6 1000  539    0\r
+  7 1000  285   15\r
+  8 1000  111  206\r
+  9 1000 1000 1000\r
+ 10 1000 1000 1000\r
+ 11 1000 1000 1000\r
+ 12 1000 1000 1000\r
+ 13 1000 1000 1000\r
+ 14 1000 1000 1000\r
+ 15 1000 1000 1000\r
+ 16    0    0    0\r
+ 17    0    0    0\r
+ 18    0    0    0\r
+ 19    0    0    0\r
+ 20    0    0    0\r
+ 21    0    0    0\r
+ 22    0    0    0\r
+ 23    0    0    0\r
+ 24    0    0    0\r
+ 25    0    0    0\r
+ 26    0    0    0\r
+ 27    0    0    0\r
+ 28    0    0    0\r
+ 29    0    0    0\r
+ 30    0    0    0\r
+ 31    0    0    0\r
+ 32    0    0    0\r
+ 33    0    0    0\r
+ 34    0    0    0\r
+ 35    0    0    0\r
+ 36    0    0    0\r
+ 37    0    0    0\r
+ 38    0    0    0\r
+ 39    0    0    0\r
+ 40    0    0    0\r
+ 41    0    0    0\r
+ 42    0    0    0\r
+ 43    0    0    0\r
+ 44    0    0    0\r
+ 45    0    0    0\r
+ 46    0    0    0\r
+ 47    0    0    0\r
+ 48    0    0    0\r
+ 49    0    0    0\r
+ 50    0    0    0\r
+ 51    0    0    0\r
+ 52    0    0    0\r
+ 53    0    0    0\r
+ 54    0    0    0\r
+ 55    0    0    0\r
+ 56    0    0    0\r
+ 57    0    0    0\r
+ 58    0    0    0\r
+ 59    0    0    0\r
+ 60    0    0    0\r
+ 61    0    0    0\r
+ 62    0    0    0\r
+ 63    0    0    0\r
+ 64    0    0    0\r
+ 65    0    0    0\r
+ 66    0    0    0\r
+ 67    0    0    0\r
+ 68    0    0    0\r
+ 69    0    0    0\r
+ 70    0    0    0\r
+ 71    0    0    0\r
+ 72    0    0    0\r
+ 73    0    0    0\r
+ 74    0    0    0\r
+ 75    0    0    0\r
+ 76    0    0    0\r
+ 77    0    0    0\r
+ 78    0    0    0\r
+ 79    0    0    0\r
+ 80    0    0    0\r
+ 81    0    0    0\r
+ 82    0    0    0\r
+ 83    0    0    0\r
+ 84    0    0    0\r
+ 85    0    0    0\r
+ 86    0    0    0\r
+ 87    0    0    0\r
+ 88    0    0    0\r
+ 89    0    0    0\r
+ 90    0    0    0\r
+ 91    0    0    0\r
+ 92    0    0    0\r
+ 93    0    0    0\r
+ 94    0    0    0\r
+ 95    0    0    0\r
+ 96    0    0    0\r
+ 97    0    0    0\r
+ 98    0    0    0\r
+ 99    0    0    0\r
+100    0    0    0\r
+101    0    0    0\r
+102    0    0    0\r
+103    0    0    0\r
+104    0    0    0\r
+105    0    0    0\r
+106    0    0    0\r
+107    0    0    0\r
+108    0    0    0\r
+109    0    0    0\r
+110    0    0    0\r
+111    0    0    0\r
+112    0    0    0\r
+113    0    0    0\r
+114    0    0    0\r
+115    0    0    0\r
+116    0    0    0\r
+117    0    0    0\r
+118    0    0    0\r
+119    0    0    0\r
+120    0    0    0\r
+121    0    0    0\r
+122    0    0    0\r
+123    0    0    0\r
+124    0    0    0\r
+125    0    0    0\r
+126    0    0    0\r
+127    0    0    0\r
+128    0    0    0\r
+129    0    0    0\r
+130    0    0    0\r
+131    0    0    0\r
+132    0    0    0\r
+133    0    0    0\r
+134    0    0    0\r
+135    0    0    0\r
+136    0    0    0\r
+137    0    0    0\r
+138    0    0    0\r
+139    0    0    0\r
+140    0    0    0\r
+141    0    0    0\r
+142    0    0    0\r
+143    0    0    0\r
+144    0    0    0\r
+145    0    0    0\r
+146    0    0    0\r
+147    0    0    0\r
+148    0    0    0\r
+149    0    0    0\r
+150    0    0    0\r
+151    0    0    0\r
+152    0    0    0\r
+153    0    0    0\r
+154    0    0    0\r
+155    0    0    0\r
+156    0    0    0\r
+157    0    0    0\r
+158    0    0    0\r
+159    0    0    0\r
+160    0    0    0\r
+161    0    0    0\r
+162    0    0    0\r
+163    0    0    0\r
+164    0    0    0\r
+165    0    0    0\r
+166    0    0    0\r
+167    0    0    0\r
+168    0    0    0\r
+169    0    0    0\r
+170    0    0    0\r
+171    0    0    0\r
+172    0    0    0\r
+173    0    0    0\r
+174    0    0    0\r
+175    0    0    0\r
+176    0    0    0\r
+177    0    0    0\r
+178    0    0    0\r
+179    0    0    0\r
+180    0    0    0\r
+181    0    0    0\r
+182    0    0    0\r
+183    0    0    0\r
+184    0    0    0\r
+185    0    0    0\r
+186    0    0    0\r
+187    0    0    0\r
+188    0    0    0\r
+189    0    0    0\r
+190    0    0    0\r
+191    0    0    0\r
+192    0    0    0\r
+193    0    0    0\r
+194    0    0    0\r
+195    0    0    0\r
+196    0    0    0\r
+197    0    0    0\r
+198    0    0    0\r
+199    0    0    0\r
+200    0    0    0\r
+201    0    0    0\r
+202    0    0    0\r
+203    0    0    0\r
+204    0    0    0\r
+205    0    0    0\r
+206    0    0    0\r
+207    0    0    0\r
+208    0    0    0\r
+209    0    0    0\r
+210    0    0    0\r
+211    0    0    0\r
+212    0    0    0\r
+213    0    0    0\r
+214    0    0    0\r
+215    0    0    0\r
+216    0    0    0\r
+217    0    0    0\r
+218    0    0    0\r
+219    0    0    0\r
+220    0    0    0\r
+221    0    0    0\r
+222    0    0    0\r
+223    0    0    0\r
+224    0    0    0\r
+225    0    0    0\r
+226    0    0    0\r
+227    0    0    0\r
+228    0    0    0\r
+229    0    0    0\r
+230    0    0    0\r
+231    0    0    0\r
+232    0    0    0\r
+233    0    0    0\r
+234    0    0    0\r
+235    0    0    0\r
+236    0    0    0\r
+237    0    0    0\r
+238    0    0    0\r
+239    0    0    0\r
+240    0    0    0\r
+241    0    0    0\r
+242    0    0    0\r
+243    0    0    0\r
+244    0    0    0\r
+245    0    0    0\r
+246    0    0    0\r
+247    0    0    0\r
+248    0    0    0\r
+249    0    0    0\r
+250    0    0    0\r
+251    0    0    0\r
+252    0    0    0\r
+253    0    0    0\r
+254    0    0    0\r
+255 1000 1000 1000\r
diff --git a/colors/bw100.clr b/colors/bw100.clr
new file mode 100644 (file)
index 0000000..bf5ffc9
--- /dev/null
@@ -0,0 +1,256 @@
+  0    0    0    0\r
+  1    0    0    0\r
+  2   15   15   15\r
+  3   15   15   15\r
+  4   31   31   31\r
+  5   47   47   47\r
+  6   47   47   47\r
+  7   63   63   63\r
+  8   79   79   79\r
+  9   79   79   79\r
+ 10   95   95   95\r
+ 11   95   95   95\r
+ 12  111  111  111\r
+ 13  126  126  126\r
+ 14  126  126  126\r
+ 15  142  142  142\r
+ 16  158  158  158\r
+ 17  158  158  158\r
+ 18  174  174  174\r
+ 19  174  174  174\r
+ 20  190  190  190\r
+ 21  206  206  206\r
+ 22  206  206  206\r
+ 23  222  222  222\r
+ 24  238  238  238\r
+ 25  238  238  238\r
+ 26  253  253  253\r
+ 27  269  269  269\r
+ 28  269  269  269\r
+ 29  285  285  285\r
+ 30  285  285  285\r
+ 31  301  301  301\r
+ 32  317  317  317\r
+ 33  317  317  317\r
+ 34  333  333  333\r
+ 35  349  349  349\r
+ 36  349  349  349\r
+ 37  365  365  365\r
+ 38  365  365  365\r
+ 39  380  380  380\r
+ 40  396  396  396\r
+ 41  396  396  396\r
+ 42  412  412  412\r
+ 43  428  428  428\r
+ 44  428  428  428\r
+ 45  444  444  444\r
+ 46  444  444  444\r
+ 47  460  460  460\r
+ 48  476  476  476\r
+ 49  476  476  476\r
+ 50  492  492  492\r
+ 51  507  507  507\r
+ 52  507  507  507\r
+ 53  523  523  523\r
+ 54  539  539  539\r
+ 55  539  539  539\r
+ 56  555  555  555\r
+ 57  555  555  555\r
+ 58  571  571  571\r
+ 59  587  587  587\r
+ 60  587  587  587\r
+ 61  603  603  603\r
+ 62  619  619  619\r
+ 63  619  619  619\r
+ 64  634  634  634\r
+ 65  634  634  634\r
+ 66  650  650  650\r
+ 67  666  666  666\r
+ 68  666  666  666\r
+ 69  682  682  682\r
+ 70  698  698  698\r
+ 71  698  698  698\r
+ 72  714  714  714\r
+ 73  714  714  714\r
+ 74  730  730  730\r
+ 75  746  746  746\r
+ 76  746  746  746\r
+ 77  761  761  761\r
+ 78  777  777  777\r
+ 79  777  777  777\r
+ 80  793  793  793\r
+ 81  809  809  809\r
+ 82  809  809  809\r
+ 83  825  825  825\r
+ 84  825  825  825\r
+ 85  841  841  841\r
+ 86  857  857  857\r
+ 87  857  857  857\r
+ 88  873  873  873\r
+ 89  888  888  888\r
+ 90  888  888  888\r
+ 91  904  904  904\r
+ 92  904  904  904\r
+ 93  920  920  920\r
+ 94  936  936  936\r
+ 95  936  936  936\r
+ 96  952  952  952\r
+ 97  968  968  968\r
+ 98  968  968  968\r
+ 99  984  984  984\r
+100 1000 1000 1000\r
+101    0    0    0\r
+102    0    0    0\r
+103    0    0    0\r
+104    0    0    0\r
+105    0    0    0\r
+106    0    0    0\r
+107    0    0    0\r
+108    0    0    0\r
+109    0    0    0\r
+110    0    0    0\r
+111    0    0    0\r
+112    0    0    0\r
+113    0    0    0\r
+114    0    0    0\r
+115    0    0    0\r
+116    0    0    0\r
+117    0    0    0\r
+118    0    0    0\r
+119    0    0    0\r
+120    0    0    0\r
+121    0    0    0\r
+122    0    0    0\r
+123    0    0    0\r
+124    0    0    0\r
+125    0    0    0\r
+126    0    0    0\r
+127    0    0    0\r
+128    0    0    0\r
+129    0    0    0\r
+130    0    0    0\r
+131    0    0    0\r
+132    0    0    0\r
+133    0    0    0\r
+134    0    0    0\r
+135    0    0    0\r
+136    0    0    0\r
+137    0    0    0\r
+138    0    0    0\r
+139    0    0    0\r
+140    0    0    0\r
+141    0    0    0\r
+142    0    0    0\r
+143    0    0    0\r
+144    0    0    0\r
+145    0    0    0\r
+146    0    0    0\r
+147    0    0    0\r
+148    0    0    0\r
+149    0    0    0\r
+150    0    0    0\r
+151    0    0    0\r
+152    0    0    0\r
+153    0    0    0\r
+154    0    0    0\r
+155    0    0    0\r
+156    0    0    0\r
+157    0    0    0\r
+158    0    0    0\r
+159    0    0    0\r
+160    0    0    0\r
+161    0    0    0\r
+162    0    0    0\r
+163    0    0    0\r
+164    0    0    0\r
+165    0    0    0\r
+166    0    0    0\r
+167    0    0    0\r
+168    0    0    0\r
+169    0    0    0\r
+170    0    0    0\r
+171    0    0    0\r
+172    0    0    0\r
+173    0    0    0\r
+174    0    0    0\r
+175    0    0    0\r
+176    0    0    0\r
+177    0    0    0\r
+178    0    0    0\r
+179    0    0    0\r
+180    0    0    0\r
+181    0    0    0\r
+182    0    0    0\r
+183    0    0    0\r
+184    0    0    0\r
+185    0    0    0\r
+186    0    0    0\r
+187    0    0    0\r
+188    0    0    0\r
+189    0    0    0\r
+190    0    0    0\r
+191    0    0    0\r
+192    0    0    0\r
+193    0    0    0\r
+194    0    0    0\r
+195    0    0    0\r
+196    0    0    0\r
+197    0    0    0\r
+198    0    0    0\r
+199    0    0    0\r
+200    0    0    0\r
+201    0    0    0\r
+202    0    0    0\r
+203    0    0    0\r
+204    0    0    0\r
+205    0    0    0\r
+206    0    0    0\r
+207    0    0    0\r
+208    0    0    0\r
+209    0    0    0\r
+210    0    0    0\r
+211    0    0    0\r
+212    0    0    0\r
+213    0    0    0\r
+214    0    0    0\r
+215    0    0    0\r
+216    0    0    0\r
+217    0    0    0\r
+218    0    0    0\r
+219    0    0    0\r
+220    0    0    0\r
+221    0    0    0\r
+222    0    0    0\r
+223    0    0    0\r
+224    0    0    0\r
+225    0    0    0\r
+226    0    0    0\r
+227    0    0    0\r
+228    0    0    0\r
+229    0    0    0\r
+230    0    0    0\r
+231    0    0    0\r
+232    0    0    0\r
+233    0    0    0\r
+234    0    0    0\r
+235    0    0    0\r
+236    0    0    0\r
+237    0    0    0\r
+238    0    0    0\r
+239    0    0    0\r
+240    0    0    0\r
+241    0    0    0\r
+242    0    0    0\r
+243    0    0    0\r
+244    0    0    0\r
+245    0    0    0\r
+246    0    0    0\r
+247    0    0    0\r
+248    0    0    0\r
+249    0    0    0\r
+250    0    0    0\r
+251    0    0    0\r
+252    0    0    0\r
+253    0    0    0\r
+254  396    0  278\r
+255 1000 1000 1000\r
diff --git a/colors/bw17.clr b/colors/bw17.clr
new file mode 100644 (file)
index 0000000..9241a46
--- /dev/null
@@ -0,0 +1,17 @@
+0 0 0 0\r
+1 42 42 42\r
+2 86 86 86\r
+3 133 133 133\r
+4 180 180 180\r
+5 231 231 231\r
+6 282 282 282\r
+7 341 341 341\r
+8 400 400 400\r
+9 462 462 462\r
+10 529 529 529\r
+11 600 600 600\r
+12 670 670 670\r
+13 749 749 749\r
+14 831 831 831\r
+15 917 917 917\r
+16 998 998 998
\ No newline at end of file
diff --git a/colors/bw256.clr b/colors/bw256.clr
new file mode 100644 (file)
index 0000000..abd765d
--- /dev/null
@@ -0,0 +1,257 @@
+  0    0    0    0\r
+  1    3    3    3\r
+  2    7    7    7\r
+  3   11   11   11\r
+  4   15   15   15\r
+  5   19   19   19\r
+  6   23   23   23\r
+  7   27   27   27\r
+  8   31   31   31\r
+  9   35   35   35\r
+ 10   39   39   39\r
+ 11   43   43   43\r
+ 12   47   47   47\r
+ 13   50   50   50\r
+ 14   54   54   54\r
+ 15   58   58   58\r
+ 16   62   62   62\r
+ 17   66   66   66\r
+ 18   70   70   70\r
+ 19   74   74   74\r
+ 20   78   78   78\r
+ 21   82   82   82\r
+ 22   86   86   86\r
+ 23   90   90   90\r
+ 24   94   94   94\r
+ 25   98   98   98\r
+ 26  101  101  101\r
+ 27  105  105  105\r
+ 28  109  109  109\r
+ 29  113  113  113\r
+ 30  117  117  117\r
+ 31  121  121  121\r
+ 32  125  125  125\r
+ 33  129  129  129\r
+ 34  133  133  133\r
+ 35  137  137  137\r
+ 36  141  141  141\r
+ 37  145  145  145\r
+ 38  149  149  149\r
+ 39  152  152  152\r
+ 40  156  156  156\r
+ 41  160  160  160\r
+ 42  164  164  164\r
+ 43  168  168  168\r
+ 44  172  172  172\r
+ 45  176  176  176\r
+ 46  180  180  180\r
+ 47  184  184  184\r
+ 48  188  188  188\r
+ 49  192  192  192\r
+ 50  196  196  196\r
+ 51  200  200  200\r
+ 52  203  203  203\r
+ 53  207  207  207\r
+ 54  211  211  211\r
+ 55  215  215  215\r
+ 56  219  219  219\r
+ 57  223  223  223\r
+ 58  227  227  227\r
+ 59  231  231  231\r
+ 60  235  235  235\r
+ 61  239  239  239\r
+ 62  243  243  243\r
+ 63  247  247  247\r
+ 64  250  250  250\r
+ 65  254  254  254\r
+ 66  258  258  258\r
+ 67  262  262  262\r
+ 68  266  266  266\r
+ 69  270  270  270\r
+ 70  274  274  274\r
+ 71  278  278  278\r
+ 72  282  282  282\r
+ 73  286  286  286\r
+ 74  290  290  290\r
+ 75  294  294  294\r
+ 76  298  298  298\r
+ 77  301  301  301\r
+ 78  305  305  305\r
+ 79  309  309  309\r
+ 80  313  313  313\r
+ 81  317  317  317\r
+ 82  321  321  321\r
+ 83  325  325  325\r
+ 84  329  329  329\r
+ 85  333  333  333\r
+ 86  337  337  337\r
+ 87  341  341  341\r
+ 88  345  345  345\r
+ 89  349  349  349\r
+ 90  352  352  352\r
+ 91  356  356  356\r
+ 92  360  360  360\r
+ 93  364  364  364\r
+ 94  368  368  368\r
+ 95  372  372  372\r
+ 96  376  376  376\r
+ 97  380  380  380\r
+ 98  384  384  384\r
+ 99  388  388  388\r
+100  392  392  392\r
+101  396  396  396\r
+102  400  400  400\r
+103  403  403  403\r
+104  407  407  407\r
+105  411  411  411\r
+106  415  415  415\r
+107  419  419  419\r
+108  423  423  423\r
+109  427  427  427\r
+110  431  431  431\r
+111  435  435  435\r
+112  439  439  439\r
+113  443  443  443\r
+114  447  447  447\r
+115  450  450  450\r
+116  454  454  454\r
+117  458  458  458\r
+118  462  462  462\r
+119  466  466  466\r
+120  470  470  470\r
+121  474  474  474\r
+122  478  478  478\r
+123  482  482  482\r
+124  486  486  486\r
+125  490  490  490\r
+126  494  494  494\r
+127  498  498  498\r
+128  501  501  501\r
+129  505  505  505\r
+130  509  509  509\r
+131  513  513  513\r
+132  517  517  517\r
+133  521  521  521\r
+134  525  525  525\r
+135  529  529  529\r
+136  533  533  533\r
+137  537  537  537\r
+138  541  541  541\r
+139  545  545  545\r
+140  549  549  549\r
+141  552  552  552\r
+142  556  556  556\r
+143  560  560  560\r
+144  564  564  564\r
+145  568  568  568\r
+146  572  572  572\r
+147  576  576  576\r
+148  580  580  580\r
+149  584  584  584\r
+150  588  588  588\r
+151  592  592  592\r
+152  596  596  596\r
+153  600  600  600\r
+154  603  603  603\r
+155  607  607  607\r
+156  611  611  611\r
+157  615  615  615\r
+158  619  619  619\r
+159  623  623  623\r
+160  627  627  627\r
+161  631  631  631\r
+162  635  635  635\r
+163  639  639  639\r
+164  643  643  643\r
+165  647  647  647\r
+166  650  650  650\r
+167  654  654  654\r
+168  658  658  658\r
+169  662  662  662\r
+170  666  666  666\r
+171  670  670  670\r
+172  674  674  674\r
+173  678  678  678\r
+174  682  682  682\r
+175  686  686  686\r
+176  690  690  690\r
+177  694  694  694\r
+178  698  698  698\r
+179  701  701  701\r
+180  705  705  705\r
+181  709  709  709\r
+182  713  713  713\r
+183  717  717  717\r
+184  721  721  721\r
+185  725  725  725\r
+186  729  729  729\r
+187  733  733  733\r
+188  737  737  737\r
+189  741  741  741\r
+190  745  745  745\r
+191  749  749  749\r
+192  752  752  752\r
+193  756  756  756\r
+194  760  760  760\r
+195  764  764  764\r
+196  768  768  768\r
+197  772  772  772\r
+198  776  776  776\r
+199  780  780  780\r
+200  784  784  784\r
+201  788  788  788\r
+202  792  792  792\r
+203  796  796  796\r
+204  800  800  800\r
+205  803  803  803\r
+206  807  807  807\r
+207  811  811  811\r
+208  815  815  815\r
+209  819  819  819\r
+210  823  823  823\r
+211  827  827  827\r
+212  831  831  831\r
+213  835  835  835\r
+214  839  839  839\r
+215  843  843  843\r
+216  847  847  847\r
+217  850  850  850\r
+218  854  854  854\r
+219  858  858  858\r
+220  862  862  862\r
+221  866  866  866\r
+222  870  870  870\r
+223  874  874  874\r
+224  878  878  878\r
+225  882  882  882\r
+226  886  886  886\r
+227  890  890  890\r
+228  894  894  894\r
+229  898  898  898\r
+230  901  901  901\r
+231  905  905  905\r
+232  909  909  909\r
+233  913  913  913\r
+234  917  917  917\r
+235  921  921  921\r
+236  925  925  925\r
+237  929  929  929\r
+238  933  933  933\r
+239  937  937  937\r
+240  941  941  941\r
+241  945  945  945\r
+242  949  949  949\r
+243  952  952  952\r
+244  956  956  956\r
+245  960  960  960\r
+246  964  964  964\r
+247  968  968  968\r
+248  972  972  972\r
+249  976  976  976\r
+250  980  980  980\r
+251  984  984  984\r
+252  988  988  988\r
+253  992  992  992\r
+254 1000 1000 1000\r
+255 1000 1000 1000\r
+\1a
\ No newline at end of file
diff --git a/colors/bw256inv.clr b/colors/bw256inv.clr
new file mode 100644 (file)
index 0000000..020b754
--- /dev/null
@@ -0,0 +1,256 @@
+  0 1000 1000 1000\r
+  1  997  997  997\r
+  2  993  993  993\r
+  3  989  989  989\r
+  4  985  985  985\r
+  5  981  981  981\r
+  6  977  977  977\r
+  7  974  974  974\r
+  8  970  970  970\r
+  9  966  966  966\r
+ 10  962  962  962\r
+ 11  958  958  958\r
+ 12  954  954  954\r
+ 13  950  950  950\r
+ 14  946  946  946\r
+ 15  942  942  942\r
+ 16  938  938  938\r
+ 17  934  934  934\r
+ 18  930  930  930\r
+ 19  926  926  926\r
+ 20  923  923  923\r
+ 21  919  919  919\r
+ 22  915  915  915\r
+ 23  911  911  911\r
+ 24  907  907  907\r
+ 25  903  903  903\r
+ 26  899  899  899\r
+ 27  895  895  895\r
+ 28  891  891  891\r
+ 29  887  887  887\r
+ 30  883  883  883\r
+ 31  879  879  879\r
+ 32  876  876  876\r
+ 33  872  872  872\r
+ 34  868  868  868\r
+ 35  864  864  864\r
+ 36  860  860  860\r
+ 37  856  856  856\r
+ 38  852  852  852\r
+ 39  848  848  848\r
+ 40  844  844  844\r
+ 41  840  840  840\r
+ 42  836  836  836\r
+ 43  832  832  832\r
+ 44  828  828  828\r
+ 45  825  825  825\r
+ 46  821  821  821\r
+ 47  817  817  817\r
+ 48  813  813  813\r
+ 49  809  809  809\r
+ 50  805  805  805\r
+ 51  801  801  801\r
+ 52  797  797  797\r
+ 53  793  793  793\r
+ 54  789  789  789\r
+ 55  785  785  785\r
+ 56  781  781  781\r
+ 57  777  777  777\r
+ 58  774  774  774\r
+ 59  770  770  770\r
+ 60  766  766  766\r
+ 61  762  762  762\r
+ 62  758  758  758\r
+ 63  754  754  754\r
+ 64  750  750  750\r
+ 65  746  746  746\r
+ 66  742  742  742\r
+ 67  738  738  738\r
+ 68  734  734  734\r
+ 69  730  730  730\r
+ 70  726  726  726\r
+ 71  723  723  723\r
+ 72  719  719  719\r
+ 73  715  715  715\r
+ 74  711  711  711\r
+ 75  707  707  707\r
+ 76  703  703  703\r
+ 77  699  699  699\r
+ 78  695  695  695\r
+ 79  691  691  691\r
+ 80  687  687  687\r
+ 81  683  683  683\r
+ 82  679  679  679\r
+ 83  676  676  676\r
+ 84  672  672  672\r
+ 85  668  668  668\r
+ 86  664  664  664\r
+ 87  660  660  660\r
+ 88  656  656  656\r
+ 89  652  652  652\r
+ 90  648  648  648\r
+ 91  644  644  644\r
+ 92  640  640  640\r
+ 93  636  636  636\r
+ 94  632  632  632\r
+ 95  628  628  628\r
+ 96  625  625  625\r
+ 97  621  621  621\r
+ 98  617  617  617\r
+ 99  613  613  613\r
+100  609  609  609\r
+101  605  605  605\r
+102  601  601  601\r
+103  597  597  597\r
+104  593  593  593\r
+105  589  589  589\r
+106  585  585  585\r
+107  581  581  581\r
+108  577  577  577\r
+109  574  574  574\r
+110  570  570  570\r
+111  566  566  566\r
+112  562  562  562\r
+113  558  558  558\r
+114  554  554  554\r
+115  550  550  550\r
+116  546  546  546\r
+117  542  542  542\r
+118  538  538  538\r
+119  534  534  534\r
+120  530  530  530\r
+121  526  526  526\r
+122  523  523  523\r
+123  519  519  519\r
+124  515  515  515\r
+125  511  511  511\r
+126  507  507  507\r
+127  503  503  503\r
+128  499  499  499\r
+129  495  495  495\r
+130  491  491  491\r
+131  487  487  487\r
+132  483  483  483\r
+133  479  479  479\r
+134  476  476  476\r
+135  472  472  472\r
+136  468  468  468\r
+137  464  464  464\r
+138  460  460  460\r
+139  456  456  456\r
+140  452  452  452\r
+141  448  448  448\r
+142  444  444  444\r
+143  440  440  440\r
+144  436  436  436\r
+145  432  432  432\r
+146  428  428  428\r
+147  425  425  425\r
+148  421  421  421\r
+149  417  417  417\r
+150  413  413  413\r
+151  409  409  409\r
+152  405  405  405\r
+153  401  401  401\r
+154  397  397  397\r
+155  393  393  393\r
+156  389  389  389\r
+157  385  385  385\r
+158  381  381  381\r
+159  377  377  377\r
+160  374  374  374\r
+161  370  370  370\r
+162  366  366  366\r
+163  362  362  362\r
+164  358  358  358\r
+165  354  354  354\r
+166  350  350  350\r
+167  346  346  346\r
+168  342  342  342\r
+169  338  338  338\r
+170  334  334  334\r
+171  330  330  330\r
+172  326  326  326\r
+173  323  323  323\r
+174  319  319  319\r
+175  315  315  315\r
+176  311  311  311\r
+177  307  307  307\r
+178  303  303  303\r
+179  299  299  299\r
+180  295  295  295\r
+181  291  291  291\r
+182  287  287  287\r
+183  283  283  283\r
+184  279  279  279\r
+185  276  276  276\r
+186  272  272  272\r
+187  268  268  268\r
+188  264  264  264\r
+189  260  260  260\r
+190  256  256  256\r
+191  252  252  252\r
+192  248  248  248\r
+193  244  244  244\r
+194  240  240  240\r
+195  236  236  236\r
+196  232  232  232\r
+197  228  228  228\r
+198  225  225  225\r
+199  221  221  221\r
+200  217  217  217\r
+201  213  213  213\r
+202  209  209  209\r
+203  205  205  205\r
+204  201  201  201\r
+205  197  197  197\r
+206  193  193  193\r
+207  189  189  189\r
+208  185  185  185\r
+209  181  181  181\r
+210  177  177  177\r
+211  174  174  174\r
+212  170  170  170\r
+213  166  166  166\r
+214  162  162  162\r
+215  158  158  158\r
+216  154  154  154\r
+217  150  150  150\r
+218  146  146  146\r
+219  142  142  142\r
+220  138  138  138\r
+221  134  134  134\r
+222  130  130  130\r
+223  126  126  126\r
+224  123  123  123\r
+225  119  119  119\r
+226  115  115  115\r
+227  111  111  111\r
+228  107  107  107\r
+229  103  103  103\r
+230   99   99   99\r
+231   95   95   95\r
+232   91   91   91\r
+233   87   87   87\r
+234   83   83   83\r
+235   79   79   79\r
+236   76   76   76\r
+237   72   72   72\r
+238   68   68   68\r
+239   64   64   64\r
+240   60   60   60\r
+241   56   56   56\r
+242   52   52   52\r
+243   48   48   48\r
+244   44   44   44\r
+245   40   40   40\r
+246   36   36   36\r
+247   32   32   32\r
+248   28   28   28\r
+249   25   25   25\r
+250   21   21   21\r
+251   17   17   17\r
+252   13   13   13\r
+253    9    9    9\r
+254    5    5    5\r
+255    0    0    0\r
diff --git a/colors/bw5.clr b/colors/bw5.clr
new file mode 100644 (file)
index 0000000..7e88da4
--- /dev/null
@@ -0,0 +1,5 @@
+0 0 0 0\r
+1 180 180 180\r
+2 400 400 400\r
+3 670 670 670\r
+4 1000 1000 1000\r
diff --git a/colors/bw64.clr b/colors/bw64.clr
new file mode 100644 (file)
index 0000000..a45048a
--- /dev/null
@@ -0,0 +1,64 @@
+ 0    0    0    0\r
+ 1   15   15   15\r
+ 2   31   31   31\r
+ 3   47   47   47\r
+ 4   62   62   62\r
+ 5   78   78   78\r
+ 6   94   94   94\r
+ 7  109  109  109\r
+ 8  125  125  125\r
+ 9  141  141  141\r
+10  156  156  156\r
+11  172  172  172\r
+12  188  188  188\r
+13  203  203  203\r
+14  219  219  219\r
+15  235  235  235\r
+16  250  250  250\r
+17  266  266  266\r
+18  282  282  282\r
+19  298  298  298\r
+20  313  313  313\r
+21  329  329  329\r
+22  345  345  345\r
+23  360  360  360\r
+24  376  376  376\r
+25  392  392  392\r
+26  407  407  407\r
+27  423  423  423\r
+28  439  439  439\r
+29  454  454  454\r
+30  470  470  470\r
+31  486  486  486\r
+32  501  501  501\r
+33  517  517  517\r
+34  533  533  533\r
+35  549  549  549\r
+36  564  564  564\r
+37  580  580  580\r
+38  596  596  596\r
+39  611  611  611\r
+40  627  627  627\r
+41  643  643  643\r
+42  658  658  658\r
+43  674  674  674\r
+44  690  690  690\r
+45  705  705  705\r
+46  721  721  721\r
+47  737  737  737\r
+48  752  752  752\r
+49  768  768  768\r
+50  784  784  784\r
+51  800  800  800\r
+52  815  815  815\r
+53  831  831  831\r
+54  847  847  847\r
+55  862  862  862\r
+56  878  878  878\r
+57  894  894  894\r
+58  909  909  909\r
+59  925  925  925\r
+60  941  941  941\r
+61  956  956  956\r
+62  972  972  972\r
+63 1000 1000 1000\r
diff --git a/colors/default.clr b/colors/default.clr
new file mode 100644 (file)
index 0000000..53ae720
--- /dev/null
@@ -0,0 +1,256 @@
+  0    0    0    0\r
+  1 1000    0    0\r
+  2    0 1000    0\r
+  3  650  650 1000\r
+  4 1000 1000    0\r
+  5 1000    0 1000\r
+  6    0 1000 1000\r
+  7  650  650  650\r
+  8 1000  650    0\r
+  9  650  317    0\r
+ 10    0  650    0\r
+ 11    0    0 1000\r
+ 12  650  650    0\r
+ 13  650    0  650\r
+ 14    0  650  650\r
+ 15  857  857  857\r
+ 16  587  587  587\r
+ 17    0  380  380\r
+ 18    0  539  539\r
+ 19    0  682  682\r
+ 20    0  841  841\r
+ 21    0 1000 1000\r
+ 22   95  809  984\r
+ 23  190  666  984\r
+ 24  285  571  984\r
+ 25  380  507  984\r
+ 26  492  492 1000\r
+ 27  365    0  365\r
+ 28  523    0  523\r
+ 29  682    0  682\r
+ 30  841    0  841\r
+ 31 1000    0 1000\r
+ 32  984   95  904\r
+ 33  984  190  825\r
+ 34  984  285  777\r
+ 35  984  380  746\r
+ 36 1000  492  746\r
+ 37    0    0  190\r
+ 38    0    0  380\r
+ 39    0    0  587\r
+ 40    0    0  793\r
+ 41    0    0 1000\r
+ 42  142   63  920\r
+ 43  269  126  857\r
+ 44  365  206  777\r
+ 45  444  269  714\r
+ 46  333  333  634\r
+ 47  190  190    0\r
+ 48  380  380    0\r
+ 49  587  587    0\r
+ 50  793  793    0\r
+ 51 1000 1000    0\r
+ 52  920  920   63\r
+ 53  857  857  126\r
+ 54  777  777  206\r
+ 55  714  714  269\r
+ 56  634  634  333\r
+ 57    0  190    0\r
+ 58    0  380    0\r
+ 59    0  587    0\r
+ 60    0  793    0\r
+ 61    0 1000    0\r
+ 62   63  904   63\r
+ 63  142  825  142\r
+ 64  238  746  238\r
+ 65  301  666  301\r
+ 66  396  587  396\r
+ 67  190    0    0\r
+ 68  380    0    0\r
+ 69  587    0    0\r
+ 70  793    0    0\r
+ 71 1000    0    0\r
+ 72  904   63   63\r
+ 73  825  142  142\r
+ 74  746  238  238\r
+ 75  666  301  301\r
+ 76  587  396  396\r
+ 77  238  746  746\r
+ 78  238  634  746\r
+ 79  238  523  746\r
+ 80  238  412  746\r
+ 81  238  285  746\r
+ 82  285  238  746\r
+ 83  412  238  746\r
+ 84  523  238  746\r
+ 85  634  238  746\r
+ 86  746  238  746\r
+ 87  746  238  634\r
+ 88  746  238  539\r
+ 89  746  238  444\r
+ 90  746  238  349\r
+ 91  746  238  253\r
+ 92  746  333  238\r
+ 93  746  444  238\r
+ 94  746  539  238\r
+ 95  746  634  238\r
+ 96  746  746  238\r
+ 97  634  746  238\r
+ 98  412  746  238\r
+ 99  238  746  285\r
+100  238  746  507\r
+101  238  746  746\r
+102  380  158    0\r
+103  587  238    0\r
+104  793  317    0\r
+105 1000  412    0\r
+106 1000  523  190\r
+107   79   79   79\r
+108  190  190  190\r
+109  285  285  285\r
+110  396  396  396\r
+111  492  492  492\r
+112  587  587  587\r
+113  682  682  682\r
+114  777  777  777\r
+115  888  888  888\r
+116  984  984  984\r
+117    0  492 1000\r
+118    0 1000 1000\r
+119  746  492    0\r
+120    0  841   15\r
+121  650    0  650\r
+122  698  396    0\r
+123  841  587  285\r
+124 1000  650  650\r
+125 1000  793  587\r
+126    0  793 1000\r
+127    0 1000  793\r
+128  380  380  380\r
+129 1000  238  238\r
+130 1000  650  317\r
+131  317  317 1000\r
+132    0  317 1000\r
+133 1000  317    0\r
+134  746  238    0\r
+135  746   79   79\r
+136    0    0    0\r
+137  857 1000  857\r
+138 1000 1000    0\r
+139 1000    0 1000\r
+140  650  650  650\r
+141 1000  492    0\r
+142 1000    0    0\r
+143  492 1000    0\r
+144    0  492    0\r
+145  317  698    0\r
+146    0    0 1000\r
+147    0  492 1000\r
+148    0 1000 1000\r
+149  746  492    0\r
+150    0  841    0\r
+151  650    0  650\r
+152  698  396    0\r
+153  841  587  285\r
+154 1000  650  650\r
+155 1000  793  587\r
+156    0  793 1000\r
+157    0 1000  793\r
+158  380  380  380\r
+159 1000  238  238\r
+160 1000  650  317\r
+161  317  317 1000\r
+162    0  317 1000\r
+163 1000  317    0\r
+164  746  238   15\r
+165  746   79   79\r
+166    0    0   15\r
+167  857  920 1000\r
+168 1000 1000    0\r
+169 1000    0 1000\r
+170  650  650  650\r
+171 1000  492    0\r
+172 1000    0    0\r
+173  492 1000    0\r
+174    0  492    0\r
+175  317  698    0\r
+176    0    0 1000\r
+177    0  492 1000\r
+178    0 1000 1000\r
+179  746  492    0\r
+180    0  841    0\r
+181  650    0  650\r
+182  698  396    0\r
+183  841  587  285\r
+184 1000  650  650\r
+185 1000  793  587\r
+186    0  793 1000\r
+187    0 1000  793\r
+188  380  380  380\r
+189 1000  238  238\r
+190 1000  650  317\r
+191  317  317 1000\r
+192    0  317 1000\r
+193 1000  317    0\r
+194  746  238   15\r
+195  746   79   79\r
+196    0    0    0\r
+197 1000  857  857\r
+198 1000 1000    0\r
+199 1000    0 1000\r
+200  650  650  650\r
+201 1000  492    0\r
+202 1000    0    0\r
+203  492 1000    0\r
+204    0  492    0\r
+205  317  698    0\r
+206    0    0 1000\r
+207    0  492 1000\r
+208    0 1000 1000\r
+209  746  492    0\r
+210    0  841   15\r
+211  650    0  650\r
+212  698  396    0\r
+213  841  587  285\r
+214 1000  650  650\r
+215 1000  793  587\r
+216    0  793 1000\r
+217    0 1000  793\r
+218  380  380  380\r
+219 1000  238  238\r
+220 1000  650  317\r
+221  317  317 1000\r
+222  746  238    0\r
+223  746   79   79\r
+224    0    0    0\r
+225 1000  857 1000\r
+226 1000 1000    0\r
+227 1000    0 1000\r
+228  650  650  650\r
+229 1000  492    0\r
+230 1000    0    0\r
+231  492 1000    0\r
+232    0  492    0\r
+233  317  698    0\r
+234    0    0 1000\r
+235    0  492 1000\r
+236    0 1000 1000\r
+237  746  492    0\r
+238    0  841    0\r
+239  650    0  650\r
+240  698  396    0\r
+241  841  587  285\r
+242 1000  650  650\r
+243 1000  793  587\r
+244    0  793 1000\r
+245    0 1000  793\r
+246  380  380  380\r
+247 1000  238  238\r
+248 1000  650  317\r
+249  317  317 1000\r
+250    0  317 1000\r
+251 1000  317    0\r
+252  746  238    0\r
+253  746   79   79\r
+254    0    0    0\r
+255 1000 1000 1000\r
diff --git a/colors/digdoq.clr b/colors/digdoq.clr
new file mode 100644 (file)
index 0000000..493d067
--- /dev/null
@@ -0,0 +1,256 @@
+  0    0    0    0\r
+  1  850    0    0\r
+  2    7    7    7\r
+  3   11   11   11\r
+  4   15   15   15\r
+  5   19   19   19\r
+  6   23   23   23\r
+  7   27   27   27\r
+  8   31   31   31\r
+  9   35   35   35\r
+ 10   39   39   39\r
+ 11   43   43   43\r
+ 12   47   47   47\r
+ 13   50   50   50\r
+ 14   54   54   54\r
+ 15   58   58   58\r
+ 16   62   62   62\r
+ 17   66   66   66\r
+ 18   70   70   70\r
+ 19   74   74   74\r
+ 20   78   78   78\r
+ 21   82   82   82\r
+ 22   86   86   86\r
+ 23   90   90   90\r
+ 24   94   94   94\r
+ 25   98   98   98\r
+ 26  101  101  101\r
+ 27  105  105  105\r
+ 28  109  109  109\r
+ 29  113  113  113\r
+ 30  117  117  117\r
+ 31  121  121  121\r
+ 32  125  125  125\r
+ 33  129  129  129\r
+ 34  133  133  133\r
+ 35  137  137  137\r
+ 36  141  141  141\r
+ 37  145  145  145\r
+ 38  149  149  149\r
+ 39  152  152  152\r
+ 40  156  156  156\r
+ 41  160  160  160\r
+ 42  164  164  164\r
+ 43  168  168  168\r
+ 44  172  172  172\r
+ 45  176  176  176\r
+ 46  180  180  180\r
+ 47  184  184  184\r
+ 48  188  188  188\r
+ 49  192  192  192\r
+ 50  196  196  196\r
+ 51  200  200  200\r
+ 52  203  203  203\r
+ 53  207  207  207\r
+ 54  211  211  211\r
+ 55  215  215  215\r
+ 56  219  219  219\r
+ 57  223  223  223\r
+ 58  227  227  227\r
+ 59  231  231  231\r
+ 60  235  235  235\r
+ 61  239  239  239\r
+ 62  243  243  243\r
+ 63  247  247  247\r
+ 64  250  250  250\r
+ 65  254  254  254\r
+ 66  258  258  258\r
+ 67  262  262  262\r
+ 68  266  266  266\r
+ 69  270  270  270\r
+ 70  274  274  274\r
+ 71  278  278  278\r
+ 72  282  282  282\r
+ 73  286  286  286\r
+ 74  290  290  290\r
+ 75  294  294  294\r
+ 76  298  298  298\r
+ 77  301  301  301\r
+ 78  305  305  305\r
+ 79  309  309  309\r
+ 80  313  313  313\r
+ 81  317  317  317\r
+ 82  321  321  321\r
+ 83  325  325  325\r
+ 84  329  329  329\r
+ 85  333  333  333\r
+ 86  337  337  337\r
+ 87  341  341  341\r
+ 88  345  345  345\r
+ 89  349  349  349\r
+ 90  352  352  352\r
+ 91  356  356  356\r
+ 92  360  360  360\r
+ 93  364  364  364\r
+ 94  368  368  368\r
+ 95  372  372  372\r
+ 96  376  376  376\r
+ 97  380  380  380\r
+ 98  384  384  384\r
+ 99  388  388  388\r
+100  392  392  392\r
+101  396  396  396\r
+102  400  400  400\r
+103  403  403  403\r
+104  407  407  407\r
+105  411  411  411\r
+106  415  415  415\r
+107  419  419  419\r
+108  423  423  423\r
+109  427  427  427\r
+110  431  431  431\r
+111  435  435  435\r
+112  439  439  439\r
+113  443  443  443\r
+114  447  447  447\r
+115  450  450  450\r
+116  454  454  454\r
+117  458  458  458\r
+118  462  462  462\r
+119  466  466  466\r
+120  470  470  470\r
+121  474  474  474\r
+122  478  478  478\r
+123  482  482  482\r
+124  486  486  486\r
+125  490  490  490\r
+126  494  494  494\r
+127  498  498  498\r
+128  501  501  501\r
+129  505  505  505\r
+130  509  509  509\r
+131  513  513  513\r
+132  517  517  517\r
+133  521  521  521\r
+134  525  525  525\r
+135  529  529  529\r
+136  533  533  533\r
+137  537  537  537\r
+138  541  541  541\r
+139  545  545  545\r
+140  549  549  549\r
+141  552  552  552\r
+142  556  556  556\r
+143  560  560  560\r
+144  564  564  564\r
+145  568  568  568\r
+146  572  572  572\r
+147  576  576  576\r
+148  580  580  580\r
+149  584  584  584\r
+150  588  588  588\r
+151  592  592  592\r
+152  596  596  596\r
+153  600  600  600\r
+154  603  603  603\r
+155  607  607  607\r
+156  611  611  611\r
+157  615  615  615\r
+158  619  619  619\r
+159  623  623  623\r
+160  627  627  627\r
+161  631  631  631\r
+162  635  635  635\r
+163  639  639  639\r
+164  643  643  643\r
+165  647  647  647\r
+166  650  650  650\r
+167  654  654  654\r
+168  658  658  658\r
+169  662  662  662\r
+170  666  666  666\r
+171  670  670  670\r
+172  674  674  674\r
+173  678  678  678\r
+174  682  682  682\r
+175  686  686  686\r
+176  690  690  690\r
+177  694  694  694\r
+178  698  698  698\r
+179  701  701  701\r
+180  705  705  705\r
+181  709  709  709\r
+182  713  713  713\r
+183  717  717  717\r
+184  721  721  721\r
+185  725  725  725\r
+186  729  729  729\r
+187  733  733  733\r
+188  737  737  737\r
+189  741  741  741\r
+190  745  745  745\r
+191  749  749  749\r
+192  752  752  752\r
+193  756  756  756\r
+194  760  760  760\r
+195  764  764  764\r
+196  768  768  768\r
+197  772  772  772\r
+198  776  776  776\r
+199  780  780  780\r
+200  784  784  784\r
+201  788  788  788\r
+202  792  792  792\r
+203  796  796  796\r
+204  800  800  800\r
+205  803  803  803\r
+206  807  807  807\r
+207  811  811  811\r
+208  815  815  815\r
+209  819  819  819\r
+210  823  823  823\r
+211  827  827  827\r
+212  831  831  831\r
+213  835  835  835\r
+214  839  839  839\r
+215  843  843  843\r
+216  847  847  847\r
+217  850  850  850\r
+218  854  854  854\r
+219  858  858  858\r
+220  862  862  862\r
+221  866  866  866\r
+222  870  870  870\r
+223  874  874  874\r
+224  878  878  878\r
+225  882  882  882\r
+226  886  886  886\r
+227  890  890  890\r
+228  894  894  894\r
+229  898  898  898\r
+230  901  901  901\r
+231  905  905  905\r
+232  909  909  909\r
+233  913  913  913\r
+234  917  917  917\r
+235  921  921  921\r
+236  925  925  925\r
+237  929  929  929\r
+238  933  933  933\r
+239  937  937  937\r
+240  941  941  941\r
+241  945  945  945\r
+242  949  949  949\r
+243  952  952  952\r
+244  956  956  956\r
+245  960  960  960\r
+246  964  964  964\r
+247  968  968  968\r
+248  972  972  972\r
+249  976  976  976\r
+250  980  980  980\r
+251  984  984  984\r
+252  988  988  988\r
+253  992  992  992\r
+254 1000 1000 1000\r
+255 1000 1000 1000\r
diff --git a/colors/drgbw.clr b/colors/drgbw.clr
new file mode 100644 (file)
index 0000000..e87a574
--- /dev/null
@@ -0,0 +1,256 @@
+  0    0    0    0\r
+  1 1000 1000 1000\r
+  2  380  380  380\r
+  3  439  439  439\r
+  4  349  349  349\r
+  5  894  894  894\r
+  6  474  474  474\r
+  7  411  411  411\r
+  8  862  862  862\r
+  9  764  764  764\r
+ 10  811  811  811\r
+ 11  781  781  781\r
+ 12  678  678  678\r
+ 13    0    0    0\r
+ 14    0    0    0\r
+ 15    0    0    0\r
+ 16    0    0    0\r
+ 17    0    0    0\r
+ 18    0    0    0\r
+ 19    0    0    0\r
+ 20    0    0    0\r
+ 21    0    0    0\r
+ 22    0    0    0\r
+ 23    0    0    0\r
+ 24    0    0    0\r
+ 25    0    0    0\r
+ 26    0    0    0\r
+ 27    0    0    0\r
+ 28    0    0    0\r
+ 29    0    0    0\r
+ 30    0    0    0\r
+ 31    0    0    0\r
+ 32    0    0    0\r
+ 33    0    0    0\r
+ 34    0    0    0\r
+ 35    0    0    0\r
+ 36    0    0    0\r
+ 37    0    0    0\r
+ 38    0    0    0\r
+ 39    0    0    0\r
+ 40    0    0    0\r
+ 41    0    0    0\r
+ 42    0    0    0\r
+ 43    0    0    0\r
+ 44    0    0    0\r
+ 45    0    0    0\r
+ 46    0    0    0\r
+ 47    0    0    0\r
+ 48    0    0    0\r
+ 49    0    0    0\r
+ 50    0    0    0\r
+ 51    0    0    0\r
+ 52    0    0    0\r
+ 53    0    0    0\r
+ 54    0    0    0\r
+ 55    0    0    0\r
+ 56    0    0    0\r
+ 57    0    0    0\r
+ 58    0    0    0\r
+ 59    0    0    0\r
+ 60    0    0    0\r
+ 61    0    0    0\r
+ 62    0    0    0\r
+ 63    0    0    0\r
+ 64    0    0    0\r
+ 65    0    0    0\r
+ 66    0    0    0\r
+ 67    0    0    0\r
+ 68    0    0    0\r
+ 69    0    0    0\r
+ 70    0    0    0\r
+ 71    0    0    0\r
+ 72    0    0    0\r
+ 73    0    0    0\r
+ 74    0    0    0\r
+ 75    0    0    0\r
+ 76    0    0    0\r
+ 77    0    0    0\r
+ 78    0    0    0\r
+ 79    0    0    0\r
+ 80    0    0    0\r
+ 81    0    0    0\r
+ 82    0    0    0\r
+ 83    0    0    0\r
+ 84    0    0    0\r
+ 85    0    0    0\r
+ 86    0    0    0\r
+ 87    0    0    0\r
+ 88    0    0    0\r
+ 89    0    0    0\r
+ 90    0    0    0\r
+ 91    0    0    0\r
+ 92    0    0    0\r
+ 93    0    0    0\r
+ 94    0    0    0\r
+ 95    0    0    0\r
+ 96    0    0    0\r
+ 97    0    0    0\r
+ 98    0    0    0\r
+ 99    0    0    0\r
+100    0    0    0\r
+101    0    0    0\r
+102    0    0    0\r
+103    0    0    0\r
+104    0    0    0\r
+105    0    0    0\r
+106    0    0    0\r
+107    0    0    0\r
+108    0    0    0\r
+109    0    0    0\r
+110    0    0    0\r
+111    0    0    0\r
+112    0    0    0\r
+113    0    0    0\r
+114    0    0    0\r
+115    0    0    0\r
+116    0    0    0\r
+117    0    0    0\r
+118    0    0    0\r
+119    0    0    0\r
+120    0    0    0\r
+121    0    0    0\r
+122    0    0    0\r
+123    0    0    0\r
+124    0    0    0\r
+125    0    0    0\r
+126    0    0    0\r
+127    0    0    0\r
+128    0    0    0\r
+129    0    0    0\r
+130    0    0    0\r
+131    0    0    0\r
+132    0    0    0\r
+133    0    0    0\r
+134    0    0    0\r
+135    0    0    0\r
+136    0    0    0\r
+137    0    0    0\r
+138    0    0    0\r
+139    0    0    0\r
+140    0    0    0\r
+141    0    0    0\r
+142    0    0    0\r
+143    0    0    0\r
+144    0    0    0\r
+145    0    0    0\r
+146    0    0    0\r
+147    0    0    0\r
+148    0    0    0\r
+149    0    0    0\r
+150    0    0    0\r
+151    0    0    0\r
+152    0    0    0\r
+153    0    0    0\r
+154    0    0    0\r
+155    0    0    0\r
+156    0    0    0\r
+157    0    0    0\r
+158    0    0    0\r
+159    0    0    0\r
+160    0    0    0\r
+161    0    0    0\r
+162    0    0    0\r
+163    0    0    0\r
+164    0    0    0\r
+165    0    0    0\r
+166    0    0    0\r
+167    0    0    0\r
+168    0    0    0\r
+169    0    0    0\r
+170    0    0    0\r
+171    0    0    0\r
+172    0    0    0\r
+173    0    0    0\r
+174    0    0    0\r
+175    0    0    0\r
+176    0    0    0\r
+177    0    0    0\r
+178    0    0    0\r
+179    0    0    0\r
+180    0    0    0\r
+181    0    0    0\r
+182    0    0    0\r
+183    0    0    0\r
+184    0    0    0\r
+185    0    0    0\r
+186    0    0    0\r
+187    0    0    0\r
+188    0    0    0\r
+189    0    0    0\r
+190    0    0    0\r
+191    0    0    0\r
+192    0    0    0\r
+193    0    0    0\r
+194    0    0    0\r
+195    0    0    0\r
+196    0    0    0\r
+197    0    0    0\r
+198    0    0    0\r
+199    0    0    0\r
+200    0    0    0\r
+201    0    0    0\r
+202    0    0    0\r
+203    0    0    0\r
+204    0    0    0\r
+205    0    0    0\r
+206    0    0    0\r
+207    0    0    0\r
+208    0    0    0\r
+209    0    0    0\r
+210    0    0    0\r
+211    0    0    0\r
+212    0    0    0\r
+213    0    0    0\r
+214    0    0    0\r
+215    0    0    0\r
+216    0    0    0\r
+217    0    0    0\r
+218    0    0    0\r
+219    0    0    0\r
+220    0    0    0\r
+221    0    0    0\r
+222    0    0    0\r
+223    0    0    0\r
+224    0    0    0\r
+225    0    0    0\r
+226    0    0    0\r
+227    0    0    0\r
+228    0    0    0\r
+229    0    0    0\r
+230    0    0    0\r
+231    0    0    0\r
+232    0    0    0\r
+233    0    0    0\r
+234    0    0    0\r
+235    0    0    0\r
+236    0    0    0\r
+237    0    0    0\r
+238    0    0    0\r
+239    0    0    0\r
+240    0    0    0\r
+241    0    0    0\r
+242    0    0    0\r
+243    0    0    0\r
+244    0    0    0\r
+245    0    0    0\r
+246    0    0    0\r
+247    0    0    0\r
+248    0    0    0\r
+249    0    0    0\r
+250    0    0    0\r
+251    0    0    0\r
+252    0    0    0\r
+253    0    0    0\r
+254    0    0    0\r
+255    0    0    0\r
diff --git a/colors/drgclr.clr b/colors/drgclr.clr
new file mode 100644 (file)
index 0000000..314a8f5
--- /dev/null
@@ -0,0 +1,256 @@
+   0    0    0    0\r
+   1  996  996  996\r
+   2    0  589  640\r
+   3  792    0   89\r
+   4  511  257  144\r
+   5  785  914  613\r
+   6  535  199  500\r
+   7  996  914    0\r
+   8  652  882  882\r
+   9  996  718  718\r
+  10  851  699  835\r
+  11  816  816  816\r
+  12  808  640  554\r
+  13    0    0    0\r
+  14    0    0    0\r
+  15    0    0    0\r
+  16    0    0    0\r
+  17    0    0    0\r
+  18    0    0    0\r
+  19    0    0    0\r
+  20    0    0    0\r
+  21    0    0    0\r
+  22    0    0    0\r
+  23    0    0    0\r
+  24    0    0    0\r
+  25    0    0    0\r
+  26    0    0    0\r
+  27    0    0    0\r
+  28    0    0    0\r
+  29    0    0    0\r
+  30    0    0    0\r
+  31    0    0    0\r
+  32    0    0    0\r
+  33    0    0    0\r
+  34    0    0    0\r
+  35    0    0    0\r
+  36    0    0    0\r
+  37    0    0    0\r
+  38    0    0    0\r
+  39    0    0    0\r
+  40    0    0    0\r
+  41    0    0    0\r
+  42    0    0    0\r
+  43    0    0    0\r
+  44    0    0    0\r
+  45    0    0    0\r
+  46    0    0    0\r
+  47    0    0    0\r
+  48    0    0    0\r
+  49    0    0    0\r
+  50    0    0    0\r
+  51    0    0    0\r
+  52    0    0    0\r
+  53    0    0    0\r
+  54    0    0    0\r
+  55    0    0    0\r
+  56    0    0    0\r
+  57    0    0    0\r
+  58    0    0    0\r
+  59    0    0    0\r
+  60    0    0    0\r
+  61    0    0    0\r
+  62    0    0    0\r
+  63    0    0    0\r
+  64    0    0    0\r
+  65    0    0    0\r
+  66    0    0    0\r
+  67    0    0    0\r
+  68    0    0    0\r
+  69    0    0    0\r
+  70    0    0    0\r
+  71    0    0    0\r
+  72    0    0    0\r
+  73    0    0    0\r
+  74    0    0    0\r
+  75    0    0    0\r
+  76    0    0    0\r
+  77    0    0    0\r
+  78    0    0    0\r
+  79    0    0    0\r
+  80    0    0    0\r
+  81    0    0    0\r
+  82    0    0    0\r
+  83    0    0    0\r
+  84    0    0    0\r
+  85    0    0    0\r
+  86    0    0    0\r
+  87    0    0    0\r
+  88    0    0    0\r
+  89    0    0    0\r
+  90    0    0    0\r
+  91    0    0    0\r
+  92    0    0    0\r
+  93    0    0    0\r
+  94    0    0    0\r
+  95    0    0    0\r
+  96    0    0    0\r
+  97    0    0    0\r
+  98    0    0    0\r
+  99    0    0    0\r
+ 100    0    0    0\r
+ 101    0    0    0\r
+ 102    0    0    0\r
+ 103    0    0    0\r
+ 104    0    0    0\r
+ 105    0    0    0\r
+ 106    0    0    0\r
+ 107    0    0    0\r
+ 108    0    0    0\r
+ 109    0    0    0\r
+ 110    0    0    0\r
+ 111    0    0    0\r
+ 112    0    0    0\r
+ 113    0    0    0\r
+ 114    0    0    0\r
+ 115    0    0    0\r
+ 116    0    0    0\r
+ 117    0    0    0\r
+ 118    0    0    0\r
+ 119    0    0    0\r
+ 120    0    0    0\r
+ 121    0    0    0\r
+ 122    0    0    0\r
+ 123    0    0    0\r
+ 124    0    0    0\r
+ 125    0    0    0\r
+ 126    0    0    0\r
+ 127    0    0    0\r
+ 128    0    0    0\r
+ 129    0    0    0\r
+ 130    0    0    0\r
+ 131    0    0    0\r
+ 132    0    0    0\r
+ 133    0    0    0\r
+ 134    0    0    0\r
+ 135    0    0    0\r
+ 136    0    0    0\r
+ 137    0    0    0\r
+ 138    0    0    0\r
+ 139    0    0    0\r
+ 140    0    0    0\r
+ 141    0    0    0\r
+ 142    0    0    0\r
+ 143    0    0    0\r
+ 144    0    0    0\r
+ 145    0    0    0\r
+ 146    0    0    0\r
+ 147    0    0    0\r
+ 148    0    0    0\r
+ 149    0    0    0\r
+ 150    0    0    0\r
+ 151    0    0    0\r
+ 152    0    0    0\r
+ 153    0    0    0\r
+ 154    0    0    0\r
+ 155    0    0    0\r
+ 156    0    0    0\r
+ 157    0    0    0\r
+ 158    0    0    0\r
+ 159    0    0    0\r
+ 160    0    0    0\r
+ 161    0    0    0\r
+ 162    0    0    0\r
+ 163    0    0    0\r
+ 164    0    0    0\r
+ 165    0    0    0\r
+ 166    0    0    0\r
+ 167    0    0    0\r
+ 168    0    0    0\r
+ 169    0    0    0\r
+ 170    0    0    0\r
+ 171    0    0    0\r
+ 172    0    0    0\r
+ 173    0    0    0\r
+ 174    0    0    0\r
+ 175    0    0    0\r
+ 176    0    0    0\r
+ 177    0    0    0\r
+ 178    0    0    0\r
+ 179    0    0    0\r
+ 180    0    0    0\r
+ 181    0    0    0\r
+ 182    0    0    0\r
+ 183    0    0    0\r
+ 184    0    0    0\r
+ 185    0    0    0\r
+ 186    0    0    0\r
+ 187    0    0    0\r
+ 188    0    0    0\r
+ 189    0    0    0\r
+ 190    0    0    0\r
+ 191    0    0    0\r
+ 192    0    0    0\r
+ 193    0    0    0\r
+ 194    0    0    0\r
+ 195    0    0    0\r
+ 196    0    0    0\r
+ 197    0    0    0\r
+ 198    0    0    0\r
+ 199    0    0    0\r
+ 200    0    0    0\r
+ 201    0    0    0\r
+ 202    0    0    0\r
+ 203    0    0    0\r
+ 204    0    0    0\r
+ 205    0    0    0\r
+ 206    0    0    0\r
+ 207    0    0    0\r
+ 208    0    0    0\r
+ 209    0    0    0\r
+ 210    0    0    0\r
+ 211    0    0    0\r
+ 212    0    0    0\r
+ 213    0    0    0\r
+ 214    0    0    0\r
+ 215    0    0    0\r
+ 216    0    0    0\r
+ 217    0    0    0\r
+ 218    0    0    0\r
+ 219    0    0    0\r
+ 220    0    0    0\r
+ 221    0    0    0\r
+ 222    0    0    0\r
+ 223    0    0    0\r
+ 224    0    0    0\r
+ 225    0    0    0\r
+ 226    0    0    0\r
+ 227    0    0    0\r
+ 228    0    0    0\r
+ 229    0    0    0\r
+ 230    0    0    0\r
+ 231    0    0    0\r
+ 232    0    0    0\r
+ 233    0    0    0\r
+ 234    0    0    0\r
+ 235    0    0    0\r
+ 236    0    0    0\r
+ 237    0    0    0\r
+ 238    0    0    0\r
+ 239    0    0    0\r
+ 240    0    0    0\r
+ 241    0    0    0\r
+ 242    0    0    0\r
+ 243    0    0    0\r
+ 244    0    0    0\r
+ 245    0    0    0\r
+ 246    0    0    0\r
+ 247    0    0    0\r
+ 248    0    0    0\r
+ 249    0    0    0\r
+ 250    0    0    0\r
+ 251    0    0    0\r
+ 252    0    0    0\r
+ 253    0    0    0\r
+ 254    0    0    0\r
+ 255    0    0    0\r
diff --git a/colors/ega.clr b/colors/ega.clr
new file mode 100644 (file)
index 0000000..ced8633
--- /dev/null
@@ -0,0 +1,17 @@
+  0    0    0    0 BLACK\r
+  1 1000    0    0 RED\r
+  2    0 1000    0 GREEN\r
+  3  666  666 1000 BLUE\r
+  4 1000 1000    0 YELLOW\r
+  5 1000    0 1000 VIOLET\r
+  6    0 1000 1000 CYAN\r
+  7  666  666  666 GRAY\r
+  8 1000  666    0 ORANGE\r
+  9  666  333    0 BROWN\r
+ 10    0  666    0 DK.GREEN\r
+ 11    0    0 1000 DK.BLUE\r
+ 12  666  666    0 DK.YELLOW\r
+ 13  666    0  666 DK.VIOLET\r
+ 14    0  666  666 DK.CYAN\r
+ 15 1000 1000 1000 WHITE\r
+\1a
\ No newline at end of file
diff --git a/colors/fort.clr b/colors/fort.clr
new file mode 100644 (file)
index 0000000..be6ec09
--- /dev/null
@@ -0,0 +1,12 @@
+  0    0    0    0\r
+  1 1000    0    0\r
+  2  666  666  666\r
+  3  333  701    0\r
+  4    0  800 1000\r
+  5  498 1000    0\r
+  6    0  498 1000\r
+  7  392  392  392\r
+  8    0    0    0\r
+  9 1000 1000 1000\r
+255 1000 1000 1000\r
+\1a
\ No newline at end of file
diff --git a/colors/lesson.clr b/colors/lesson.clr
new file mode 100644 (file)
index 0000000..d0f24b8
--- /dev/null
@@ -0,0 +1,17 @@
+  0    0    0    0\r
+  1 1000    0    0\r
+  2 1000 1000    0\r
+  3 1000  666  666\r
+  4    0  666    0\r
+  5  666  666    0\r
+  6    0  666  666\r
+  7  666    0  666\r
+  8  666  666  666\r
+  9 1000 1000    0\r
+ 10  333  666 1000\r
+ 11    0  666 1000\r
+ 12  333  666    0\r
+ 13  333  333  333\r
+ 14  666  666  666\r
+ 15 1000 1000 1000\r
+\1a
\ No newline at end of file
diff --git a/colors/luse.clr b/colors/luse.clr
new file mode 100644 (file)
index 0000000..ab29772
--- /dev/null
@@ -0,0 +1,11 @@
+0 0 0 0\r
+1 0 1000 0\r
+2 1000 1000 0\r
+3 500 500 0\r
+4 1000 0 1000\r
+5 500 0 500\r
+6 0 1000 1000\r
+7 0 500 500\r
+8 1000 1000 1000\r
+9 500 500 500\r
+\1a
\ No newline at end of file
diff --git a/colors/names.clr b/colors/names.clr
new file mode 100644 (file)
index 0000000..741b1dc
--- /dev/null
@@ -0,0 +1,25 @@
+  -1    0    0    0 BLACK\r
+  -1 1000 1000 1000 WHITE\r
+  -1    0  850    0 GREEN\r
+  -1  850    0    0 RED\r
+  -1    0    0  850 BLUE\r
+  -1 1000 1000    0 YELLOW\r
+  -1 1000    0 1000 MAGENTA\r
+  -1    0 1000 1000 CYAN\r
+  -1    0 1000    0 LT.GREEN\r
+  -1    0  498    0 DK.GREEN\r
+  -1    0    0  500 DK.BLUE\r
+  -1    0    0 1000 LT.BLUE\r
+  -1  500    0    0 DK.RED\r
+  -1 1000    0    0 LT.RED\r
+  -1  666  666  666 GRAY\r
+  -1  392  392  392 DK.GRAY\r
+  -1 1000  498    0 ORANGE\r
+  -1  333  701    0 OLIVE\r
+  -1  749  498    0 TAN\r
+  -1  666    0  666 PURPLE\r
+  -1  701  400    0 BROWN\r
+  -1  850  600  298 PEACH\r
+  -1 1000  666  666 PINK\r
+  -1 1000  800  600 SAND\r
+\r
diff --git a/colors/pal100.clr b/colors/pal100.clr
new file mode 100644 (file)
index 0000000..7aa71d3
--- /dev/null
@@ -0,0 +1,256 @@
+  0  600  600  600\r
+  1    0  396  396\r
+  2    0  549  549\r
+  3    0  698  698\r
+  4    0  847  847\r
+  5    0 1000 1000\r
+  6   98  819  996\r
+  7  196  678  996\r
+  8  298  576  996\r
+  9  396  517  996\r
+ 10  498  498 1000\r
+ 11  376    0  376\r
+ 12  533    0  533\r
+ 13  686    0  686\r
+ 14  843    0  843\r
+ 15 1000    0 1000\r
+ 16  996   98  909\r
+ 17  996  196  839\r
+ 18  996  298  788\r
+ 19  996  396  756\r
+ 20 1000  498  749\r
+ 21    0    0  196\r
+ 22    0    0  396\r
+ 23    0    0  596\r
+ 24    0    0  796\r
+ 25    0    0 1000\r
+ 26  152   66  929\r
+ 27  282  137  858\r
+ 28  380  207  788\r
+ 29  454  278  717\r
+ 30  349  349  647\r
+ 31  196  196    0\r
+ 32  396  396    0\r
+ 33  596  596    0\r
+ 34  796  796    0\r
+ 35 1000 1000    0\r
+ 36  929  929   66\r
+ 37  858  858  137\r
+ 38  788  788  207\r
+ 39  717  717  278\r
+ 40  647  647  349\r
+ 41    0  196    0\r
+ 42    0  396    0\r
+ 43    0  596    0\r
+ 44    0  796    0\r
+ 45    0 1000    0\r
+ 46   78  917   78\r
+ 47  156  839  156\r
+ 48  239  756  239\r
+ 49  317  678  317\r
+ 50  400  596  400\r
+ 51  196    0    0\r
+ 52  396    0    0\r
+ 53  596    0    0\r
+ 54  796    0    0\r
+ 55 1000    0    0\r
+ 56  917   78   78\r
+ 57  839  156  156\r
+ 58  756  239  239\r
+ 59  678  317  317\r
+ 60  596  400  400\r
+ 61  247  749  749\r
+ 62  247  635  749\r
+ 63  247  525  749\r
+ 64  247  415  749\r
+ 65  247  301  749\r
+ 66  301  247  749\r
+ 67  415  247  749\r
+ 68  525  247  749\r
+ 69  635  247  749\r
+ 70  749  247  749\r
+ 71  749  247  647\r
+ 72  749  247  549\r
+ 73  749  247  450\r
+ 74  749  247  352\r
+ 75  749  247  254\r
+ 76  749  349  247\r
+ 77  749  447  247\r
+ 78  749  549  247\r
+ 79  749  647  247\r
+ 80  749  749  247\r
+ 81  647  749  247\r
+ 82  423  749  247\r
+ 83  247  749  298\r
+ 84  247  749  521\r
+ 85  247  749  749\r
+ 86  396  164    0\r
+ 87  596  247    0\r
+ 88  796  329    0\r
+ 89 1000  415    0\r
+ 90 1000  529  196\r
+ 91   94   94   94\r
+ 92  200  200  200\r
+ 93  294  294  294\r
+ 94  400  400  400\r
+ 95  494  494  494\r
+ 96  592  592  592\r
+ 97  694  694  694\r
+ 98  792  792  792\r
+ 99  894  894  894\r
+100  992  992  992\r
+101    0  498 1000\r
+102    0 1000 1000\r
+103  749  498    0\r
+104    0  850   27\r
+105  666    0  666\r
+106  701  400    0\r
+107  850  600  298\r
+108 1000  666  666\r
+109 1000  800  600\r
+110    0  800 1000\r
+111    0 1000  800\r
+112  392  392  392\r
+113 1000  250  250\r
+114 1000  666  333\r
+115  333  333 1000\r
+116    0  333 1000\r
+117 1000  333    0\r
+118  749  250    0\r
+119  749   94   94\r
+120    0    0    0\r
+121 1000 1000 1000\r
+122 1000 1000    0\r
+123 1000    0 1000\r
+124  666  666  666\r
+125 1000  498    0\r
+126 1000    0    0\r
+127  498 1000    0\r
+128    0  498    0\r
+129  333  701    0\r
+130    0    0 1000\r
+131    0  498 1000\r
+132    0 1000 1000\r
+133  749  498    0\r
+134    0  850    0\r
+135  666    0  666\r
+136  701  400    0\r
+137  850  600  298\r
+138 1000  666  666\r
+139 1000  800  600\r
+140    0  800 1000\r
+141    0 1000  800\r
+142  392  392  392\r
+143 1000  250  250\r
+144 1000  666  333\r
+145  333  333 1000\r
+146    0  333 1000\r
+147 1000  333    0\r
+148  749  250   27\r
+149  749   94   94\r
+150    0    0   27\r
+151 1000 1000 1000\r
+152 1000 1000    0\r
+153 1000    0 1000\r
+154  666  666  666\r
+155 1000  498    0\r
+156 1000    0   11\r
+157  498 1000    0\r
+158    0  498    0\r
+159  333  701    0\r
+160    0    0 1000\r
+161    0  498 1000\r
+162    0 1000 1000\r
+163  749  498    0\r
+164    0  850    0\r
+165  666    0  666\r
+166  701  400    0\r
+167  850  600  298\r
+168 1000  666  666\r
+169 1000  800  600\r
+170    0  800 1000\r
+171    0 1000  800\r
+172  392  392  392\r
+173 1000  250  250\r
+174 1000  666  333\r
+175  333  333 1000\r
+176    0  333 1000\r
+177 1000  333    0\r
+178  749  250   27\r
+179  749   94   94\r
+180    0    0    0\r
+181 1000 1000 1000\r
+182 1000 1000    0\r
+183 1000    0 1000\r
+184  666  666  666\r
+185 1000  498    0\r
+186 1000    0    0\r
+187  498 1000    0\r
+188    0  498    0\r
+189  333  701    0\r
+190    0    0 1000\r
+191    0  498 1000\r
+192    0 1000 1000\r
+193  749  498    0\r
+194    0  850   27\r
+195  666    0  666\r
+196  701  400    0\r
+197  850  600  298\r
+198 1000  666  666\r
+199 1000  800  600\r
+200    0  800 1000\r
+201    0 1000  800\r
+202  392  392  392\r
+203 1000  250  250\r
+204 1000  666  333\r
+205  333  333 1000\r
+206  749  250    0\r
+207  749   94   94\r
+208    0    0   11\r
+209 1000 1000 1000\r
+210 1000 1000    0\r
+211 1000    0 1000\r
+212  666  666  666\r
+213 1000  498    0\r
+214 1000    0    0\r
+215  498 1000    0\r
+216    0  498    0\r
+217  333  701    0\r
+218    0    0 1000\r
+219    0  498 1000\r
+220    0 1000 1000\r
+221  749  498    0\r
+222    0  850    0\r
+223  666    0  666\r
+224  701  400    0\r
+225  850  600  298\r
+226 1000  666  666\r
+227 1000  800  600\r
+228    0  800 1000\r
+229    0 1000  800\r
+230  392  392  392\r
+231 1000  250  250\r
+232 1000  666  333\r
+233  333  333 1000\r
+234    0  333 1000\r
+235 1000  333    0\r
+236  749  250    0\r
+237  749   94   94\r
+238    0    0    0\r
+239 1000 1000 1000\r
+240 1000 1000    0\r
+241 1000    0 1000\r
+242  666  666  666\r
+243 1000  498    0\r
+244 1000   27    0\r
+245  498 1000    0\r
+246    0  498    0\r
+247  333  701    0\r
+248    0    0 1000\r
+249    0  498 1000\r
+250    0 1000 1000\r
+251  749  498    0\r
+252    0  850    0\r
+253  666    0  666\r
+254  701  400    0\r
+255    0    0    0\r
diff --git a/colors/pal24.clr b/colors/pal24.clr
new file mode 100644 (file)
index 0000000..580d5fa
--- /dev/null
@@ -0,0 +1,26 @@
+  0 1000 1000 1000  white\r
+  1    0 1000 1000  cyan\r
+  2 1000    0 1000  magenta\r
+  3 1000 1000    0  yellow\r
+  4    0    0    0  black\r
+  5  500 1000 1000  med. cyan\r
+  6 1000  500 1000  med. magenta\r
+  7 1000 1000  500  med. yellow\r
+  8  500  500  500  grey\r
+  9  750 1000 1000  lt. cyan\r
+ 10 1000  750 1000  lt. magenta\r
+ 11 1000 1000  750  lt. yellow\r
+ 12  750  750  750  lt. grey\r
+ 13  240  240  240  dark grey\r
+ 14  240 1000 1000  dark cyan\r
+ 15 1000 1000 1000  white\r
+ 16 1000    0    0  red\r
+ 17    0 1000    0  green\r
+ 18    0    0 1000  blue\r
+ 19 1000  500  500  med. red\r
+ 20  500 1000  500  med. green\r
+ 21  500  500 1000  med. blue\r
+ 22 1000  750  750  lt. red\r
+ 23  750 1000  750  lt. green\r
+ 24  750  750 1000  lt. blue\r
+\1a
\ No newline at end of file
diff --git a/colors/pal255.clr b/colors/pal255.clr
new file mode 100644 (file)
index 0000000..6b1e29d
--- /dev/null
@@ -0,0 +1,256 @@
+  0    0    0    0\r
+  1   62   62   62\r
+  2  129  129  129\r
+  3  196  196  196\r
+  4  262  262  262\r
+  5  329  329  329\r
+  6  396  396  396\r
+  7  462  462  462\r
+  8  529  529  529\r
+  9  596  596  596\r
+ 10  662  662  662\r
+ 11  729  729  729\r
+ 12  796  796  796\r
+ 13  862  862  862\r
+ 14  929  929  929\r
+ 15  996  996  996\r
+ 16    0    0    0\r
+ 17   62    0    0\r
+ 18  129    0    0\r
+ 19  196    0    0\r
+ 20  262    0    0\r
+ 21  329    0    0\r
+ 22  396    0    0\r
+ 23  462    0    0\r
+ 24  529    0    0\r
+ 25  596    0    0\r
+ 26  662    0    0\r
+ 27  729    0    0\r
+ 28  796    0    0\r
+ 29  862    0    0\r
+ 30  929    0    0\r
+ 31 1000    0    0\r
+ 32    0    0    0\r
+ 33   62    3    0\r
+ 34  129   15    0\r
+ 35  196   39    0\r
+ 36  262   70    0\r
+ 37  329  109    0\r
+ 38  396  156    0\r
+ 39  462  215    0\r
+ 40  529  282    0\r
+ 41  596  356    0\r
+ 42  662  443    0\r
+ 43  729  537    0\r
+ 44  796  639    0\r
+ 45  862  749    0\r
+ 46  929  870    0\r
+ 47 1000 1000    0\r
+ 48    0    0    0\r
+ 49    0   62    0\r
+ 50    0  129    0\r
+ 51    0  196    0\r
+ 52    0  262    0\r
+ 53    0  329    0\r
+ 54    0  396    0\r
+ 55    0  462    0\r
+ 56    0  529    0\r
+ 57    0  596    0\r
+ 58    0  662    0\r
+ 59    0  729    0\r
+ 60    0  796    0\r
+ 61    0  862    0\r
+ 62    0  929    0\r
+ 63    0 1000    0\r
+ 64    0    0    0\r
+ 65    0   62   62\r
+ 66    0  129  129\r
+ 67    0  196  196\r
+ 68    0  262  262\r
+ 69    0  329  329\r
+ 70    0  396  396\r
+ 71    0  462  462\r
+ 72    0  529  529\r
+ 73    0  596  596\r
+ 74    0  662  662\r
+ 75    0  729  729\r
+ 76    0  796  796\r
+ 77    0  862  862\r
+ 78    0  929  929\r
+ 79    0 1000 1000\r
+ 80    0    0    0\r
+ 81    0    0   62\r
+ 82    0    0  129\r
+ 83    0    0  196\r
+ 84    0    0  262\r
+ 85    0    0  329\r
+ 86    0    0  396\r
+ 87    0    0  462\r
+ 88    0    0  529\r
+ 89    0    0  596\r
+ 90    0    0  662\r
+ 91    0    0  729\r
+ 92    0    0  796\r
+ 93    0    0  862\r
+ 94    0    0  929\r
+ 95    0    0 1000\r
+ 96    0    0    0\r
+ 97   62    0   62\r
+ 98  129    0  129\r
+ 99  196    0  196\r
+100  262    0  262\r
+101  329    0  329\r
+102  396    0  396\r
+103  462    0  462\r
+104  529    0  529\r
+105  596    0  596\r
+106  662    0  662\r
+107  729    0  729\r
+108  796    0  796\r
+109  862    0  862\r
+110  929    0  929\r
+111 1000    0 1000\r
+112  372  121  121\r
+113  501  137  137\r
+114  643  137  137\r
+115  792  129  129\r
+116  898  168  168\r
+117  941  266  266\r
+118  976  376  376\r
+119 1000  498  498\r
+120  372  372  121\r
+121  501  501  137\r
+122  643  643  137\r
+123  792  792  129\r
+124  898  898  168\r
+125  941  941  266\r
+126  976  976  376\r
+127 1000 1000  498\r
+128  121  372  121\r
+129  137  501  137\r
+130  137  643  137\r
+131  129  792  129\r
+132  168  898  168\r
+133  266  941  266\r
+134  376  976  376\r
+135  498 1000  498\r
+136  121  372  372\r
+137  137  501  501\r
+138  137  643  643\r
+139  129  792  792\r
+140  168  898  898\r
+141  266  941  941\r
+142  376  976  976\r
+143  498 1000 1000\r
+144  121  121  372\r
+145  137  137  501\r
+146  137  137  643\r
+147  129  129  792\r
+148  168  168  898\r
+149  266  266  941\r
+150  376  376  976\r
+151  498  498 1000\r
+152  372  121  372\r
+153  501  137  501\r
+154  643  137  643\r
+155  792  129  792\r
+156  898  168  898\r
+157  941  266  941\r
+158  976  376  976\r
+159 1000  498 1000\r
+160  309  247  184\r
+161  435  317  203\r
+162  572  392  207\r
+163  729  462  196\r
+164  847  533  219\r
+165  913  603  298\r
+166  964  678  388\r
+167 1000  749  498\r
+168  247  309  184\r
+169  317  435  203\r
+170  392  572  207\r
+171  462  729  196\r
+172  533  847  219\r
+173  603  913  298\r
+174  678  964  388\r
+175  498 1000  749\r
+176  184  309  247\r
+177  203  435  317\r
+178  207  572  392\r
+179  196  729  462\r
+180  219  847  533\r
+181  298  913  603\r
+182  388  964  678\r
+183  498 1000  749\r
+184  184  247  309\r
+185  203  317  435\r
+186  207  392  572\r
+187  196  462  729\r
+188  219  533  847\r
+189  298  603  913\r
+190  388  678  964\r
+191  498  749 1000\r
+192  247  184  309\r
+193  317  203  435\r
+194  392  207  572\r
+195  462  196  729\r
+196  533  219  847\r
+197  603  298  913\r
+198  678  388  964\r
+199  749  498 1000\r
+200  298   98   98\r
+201  415  137  137\r
+202  533  176  176\r
+203  650  215  215\r
+204  756  270  270\r
+205  796  388  388\r
+206  835  505  505\r
+207  874  623  623\r
+208  298  298   98\r
+209  415  415  137\r
+210  533  533  176\r
+211  650  650  215\r
+212  756  756  270\r
+213  796  796  388\r
+214  835  835  505\r
+215  874  874  623\r
+216   98  298   98\r
+217  137  415  137\r
+218  176  533  176\r
+219  215  650  215\r
+220  270  756  270\r
+221  388  796  388\r
+222  505  835  505\r
+223  623  874  623\r
+224   98  298  298\r
+225  137  415  415\r
+226  176  533  533\r
+227  215  650  650\r
+228  270  756  756\r
+229  388  796  796\r
+230  505  835  835\r
+231  623  874  874\r
+232   98   98  298\r
+233  137  137  415\r
+234  176  176  533\r
+235  215  215  650\r
+236  270  270  756\r
+237  388  388  796\r
+238  505  505  835\r
+239  623  623  874\r
+240  298   98  298\r
+241  415  137  415\r
+242  533  176  533\r
+243  650  215  650\r
+244  756  270  756\r
+245  796  388  796\r
+246  835  505  835\r
+247  874  623  874\r
+248  396  196    0\r
+249  513  254    0\r
+250  627  313    0\r
+251  741  368    0\r
+252  854  427    0\r
+253  968  482    0\r
+254  996  541   82\r
+255  996  596  196\r
diff --git a/colors/rainbow.clr b/colors/rainbow.clr
new file mode 100644 (file)
index 0000000..43f4840
--- /dev/null
@@ -0,0 +1,257 @@
+  0    0    0    0\r
+  1  243    0  258\r
+  2  235    0  266\r
+  3  227    0  274\r
+  4  219    0  282\r
+  5  211    0  290\r
+  6  203    0  298\r
+  7  196    0  305\r
+  8  188    0  313\r
+  9  180    0  321\r
+ 10  172    0  329\r
+ 11  164    0  337\r
+ 12  156    0  345\r
+ 13  149    0  352\r
+ 14  141    0  360\r
+ 15  133    0  368\r
+ 16  125    0  376\r
+ 17  117    0  384\r
+ 18  109    0  392\r
+ 19  101    0  400\r
+ 20   94    0  407\r
+ 21   86    0  415\r
+ 22   78    0  423\r
+ 23   70    0  431\r
+ 24   62    0  439\r
+ 25   54    0  447\r
+ 26   47    0  454\r
+ 27   39    0  462\r
+ 28   31    0  470\r
+ 29   23    0  478\r
+ 30   15    0  486\r
+ 31    7    0  494\r
+ 32    0    0  501\r
+ 33    0   15  494\r
+ 34    0   31  486\r
+ 35    0   47  478\r
+ 36    0   62  470\r
+ 37    0   78  462\r
+ 38    0   94  454\r
+ 39    0  109  447\r
+ 40    0  125  439\r
+ 41    0  141  431\r
+ 42    0  156  423\r
+ 43    0  172  415\r
+ 44    0  188  407\r
+ 45    0  203  400\r
+ 46    0  219  392\r
+ 47    0  235  384\r
+ 48    0  250  376\r
+ 49    0  266  368\r
+ 50    0  282  360\r
+ 51    0  298  352\r
+ 52    0  313  345\r
+ 53    0  329  337\r
+ 54    0  345  329\r
+ 55    0  360  321\r
+ 56    0  376  313\r
+ 57    0  392  305\r
+ 58    0  407  298\r
+ 59    0  423  290\r
+ 60    0  439  282\r
+ 61    0  454  274\r
+ 62    0  470  266\r
+ 63    0  486  258\r
+ 64    0  501  250\r
+ 65   11  509  243\r
+ 66   23  517  235\r
+ 67   35  525  227\r
+ 68   47  533  219\r
+ 69   58  541  211\r
+ 70   70  549  203\r
+ 71   82  556  196\r
+ 72   98  564  188\r
+ 73  109  572  180\r
+ 74  121  580  172\r
+ 75  133  588  164\r
+ 76  145  596  156\r
+ 77  156  603  149\r
+ 78  168  611  141\r
+ 79  180  619  133\r
+ 80  196  627  125\r
+ 81  207  635  117\r
+ 82  219  643  109\r
+ 83  231  650  101\r
+ 84  243  658   94\r
+ 85  254  666   86\r
+ 86  266  674   78\r
+ 87  278  682   70\r
+ 88  294  690   62\r
+ 89  305  698   54\r
+ 90  317  705   47\r
+ 91  329  713   39\r
+ 92  341  721   31\r
+ 93  352  729   23\r
+ 94  364  737   15\r
+ 95  376  745    7\r
+ 96  392  752    0\r
+ 97  407  756    0\r
+ 98  427  764    0\r
+ 99  447  772    0\r
+100  466  780    0\r
+101  486  788    0\r
+102  505  796    0\r
+103  521  803    0\r
+104  541  811    0\r
+105  560  819    0\r
+106  580  827    0\r
+107  600  835    0\r
+108  619  843    0\r
+109  635  850    0\r
+110  654  858    0\r
+111  674  866    0\r
+112  694  874    0\r
+113  713  882    0\r
+114  733  890    0\r
+115  752  898    0\r
+116  768  905    0\r
+117  788  913    0\r
+118  807  921    0\r
+119  827  929    0\r
+120  847  937    0\r
+121  866  945    0\r
+122  882  952    0\r
+123  901  960    0\r
+124  921  968    0\r
+125  941  976    0\r
+126  960  984    0\r
+127  980  992    0\r
+128 1000 1000    0\r
+129 1000  980    0\r
+130 1000  960    0\r
+131 1000  941    0\r
+132 1000  921    0\r
+133 1000  901    0\r
+134 1000  882    0\r
+135 1000  866    0\r
+136 1000  847    0\r
+137 1000  827    0\r
+138 1000  807    0\r
+139 1000  788    0\r
+140 1000  768    0\r
+141 1000  752    0\r
+142 1000  733    0\r
+143 1000  713    0\r
+144 1000  694    0\r
+145 1000  674    0\r
+146 1000  654    0\r
+147 1000  635    0\r
+148 1000  619    0\r
+149 1000  600    0\r
+150 1000  580    0\r
+151 1000  560    0\r
+152 1000  541    0\r
+153 1000  521    0\r
+154 1000  505    0\r
+155 1000  486    0\r
+156 1000  466    0\r
+157 1000  447    0\r
+158 1000  427    0\r
+159 1000  407    0\r
+160 1000  392    0\r
+161 1000  376   11\r
+162 1000  364   23\r
+163 1000  352   35\r
+164 1000  341   47\r
+165 1000  329   58\r
+166 1000  317   70\r
+167 1000  305   82\r
+168 1000  294   98\r
+169 1000  278  109\r
+170 1000  266  121\r
+171 1000  254  133\r
+172 1000  243  145\r
+173 1000  231  156\r
+174 1000  219  168\r
+175 1000  207  180\r
+176 1000  196  196\r
+177 1000  180  207\r
+178 1000  168  219\r
+179 1000  156  231\r
+180 1000  145  243\r
+181 1000  133  254\r
+182 1000  121  266\r
+183 1000  109  278\r
+184 1000   98  294\r
+185 1000   82  305\r
+186 1000   70  317\r
+187 1000   58  329\r
+188 1000   47  341\r
+189 1000   35  352\r
+190 1000   23  364\r
+191 1000   11  376\r
+192 1000    0  392\r
+193  988    0  400\r
+194  980    0  411\r
+195  968    0  419\r
+196  960    0  431\r
+197  952    0  439\r
+198  941    0  450\r
+199  933    0  458\r
+200  925    0  470\r
+201  913    0  478\r
+202  905    0  490\r
+203  898    0  498\r
+204  886    0  509\r
+205  878    0  517\r
+206  870    0  529\r
+207  858    0  537\r
+208  850    0  549\r
+209  843    0  556\r
+210  831    0  568\r
+211  823    0  576\r
+212  815    0  588\r
+213  803    0  596\r
+214  796    0  607\r
+215  788    0  615\r
+216  776    0  627\r
+217  768    0  635\r
+218  760    0  647\r
+219  749    0  654\r
+220  741    0  666\r
+221  733    0  674\r
+222  721    0  686\r
+223  713    0  694\r
+224  705    0  705\r
+225  694    0  690\r
+226  682    0  674\r
+227  674    0  662\r
+228  662    0  647\r
+229  650    0  631\r
+230  643    0  619\r
+231  631    0  603\r
+232  623    0  592\r
+233  611    0  576\r
+234  600    0  560\r
+235  592    0  549\r
+236  580    0  533\r
+237  568    0  517\r
+238  560    0  505\r
+239  549    0  490\r
+240  541    0  478\r
+241  529    0  462\r
+242  549    0  447\r
+243  509    0  435\r
+244  498    0  419\r
+245  486    0  403\r
+246  478    0  392\r
+247  466    0  376\r
+248  458    0  364\r
+249  447    0  349\r
+250  435    0  333\r
+251  427    0  321\r
+252  415    0  305\r
+253  403    0  290\r
+254  396    0  278\r
+255 1000 1000 1000\r
+\1a
\ No newline at end of file
diff --git a/colors/random.clr b/colors/random.clr
new file mode 100644 (file)
index 0000000..763cc23
--- /dev/null
@@ -0,0 +1,256 @@
+  0    0    0    0\r
+  1 1000 1000 1000\r
+  2 1000    0 1000\r
+  3 1000 1000    0\r
+  4 1000    0 1000\r
+  5  666  666  666\r
+  6 1000  498    0\r
+  7 1000    0    0\r
+  8  498 1000    0\r
+  9    0  498    0\r
+ 10  333  701    0\r
+ 11    0    0 1000\r
+ 12    0  498 1000\r
+ 13    0 1000 1000\r
+ 14  749  498    0\r
+ 15    0  850    0\r
+ 16  666    0  666\r
+ 17  701  400    0\r
+ 18  850  600  298\r
+ 19 1000  666  666\r
+ 20 1000  800  600\r
+ 21    0  800 1000\r
+ 22    0 1000  800\r
+ 23  392  392  392\r
+ 24 1000  250  250\r
+ 25 1000  666  333\r
+ 26  333  333 1000\r
+ 27    0  333 1000\r
+ 28 1000  333   27\r
+ 29  749  250    0\r
+ 30  749   94   94\r
+ 31    0    0    0\r
+ 32 1000 1000 1000\r
+ 33 1000 1000    0\r
+ 34 1000    0 1000\r
+ 35  666  666  666\r
+ 36 1000  498    0\r
+ 37 1000    0    0\r
+ 38  498 1000    0\r
+ 39    0  498    0\r
+ 40  333  701    0\r
+ 41    0    0 1000\r
+ 42    0  498 1000\r
+ 43    0 1000 1000\r
+ 44  749  498    0\r
+ 45    0  850    0\r
+ 46  666    0  666\r
+ 47  701  400    0\r
+ 48  850  600  298\r
+ 49 1000  666  666\r
+ 50 1000  800  600\r
+ 51    0  800 1000\r
+ 52    0 1000  800\r
+ 53  392  392  392\r
+ 54 1000  250  250\r
+ 55 1000  666  333\r
+ 56  333  333 1000\r
+ 57    0  333 1000\r
+ 58 1000  333    0\r
+ 59  749  250    0\r
+ 60  749   94   94\r
+ 61    0    0    0\r
+ 62 1000 1000 1000\r
+ 63 1000 1000    0\r
+ 64 1000    0 1000\r
+ 65  666  666  666\r
+ 66 1000  498   11\r
+ 67 1000    0    0\r
+ 68  498 1000    0\r
+ 69    0  498    0\r
+ 70  333  701    0\r
+ 71    0    0 1000\r
+ 72    0    0 1000\r
+ 73    0  498 1000\r
+ 74    0 1000 1000\r
+ 75  749  498    0\r
+ 76    0  850   27\r
+ 77  666    0  666\r
+ 78  701  400    0\r
+ 79  850  600  298\r
+ 80 1000  666  666\r
+ 81 1000  800  600\r
+ 82    0  800 1000\r
+ 83    0 1000  800\r
+ 84  392  392  392\r
+ 85 1000  250  250\r
+ 86 1000  666  333\r
+ 87  333  333 1000\r
+ 88    0  333 1000\r
+ 89 1000  333    0\r
+ 90  749  250    0\r
+ 91 1000 1000    0\r
+ 92  749   94   94\r
+ 93 1000    0 1000\r
+ 94  666  666  666\r
+ 95 1000  498    0\r
+ 96 1000    0    0\r
+ 97  498 1000    0\r
+ 98    0  498   11\r
+ 99    0    0 1000\r
+100  333  701   27\r
+101    0  498 1000\r
+102    0 1000 1000\r
+103  749  498    0\r
+104    0  850   27\r
+105  666    0  666\r
+106  701  400    0\r
+107  850  600  298\r
+108 1000  666  666\r
+109 1000  800  600\r
+110    0  800 1000\r
+111    0 1000  800\r
+112  392  392  392\r
+113 1000  250  250\r
+114 1000  666  333\r
+115  333  333 1000\r
+116    0  333 1000\r
+117 1000  333    0\r
+118  749  250    0\r
+119  749   94   94\r
+120    0    0    0\r
+121 1000 1000 1000\r
+122 1000 1000    0\r
+123 1000    0 1000\r
+124  666  666  666\r
+125 1000  498    0\r
+126 1000    0    0\r
+127  498 1000    0\r
+128    0  498    0\r
+129  333  701    0\r
+130    0    0 1000\r
+131    0  498 1000\r
+132    0 1000 1000\r
+133  749  498    0\r
+134    0  850    0\r
+135  666    0  666\r
+136  701  400    0\r
+137  850  600  298\r
+138 1000  666  666\r
+139 1000  800  600\r
+140    0  800 1000\r
+141    0 1000  800\r
+142  392  392  392\r
+143 1000  250  250\r
+144 1000  666  333\r
+145  333  333 1000\r
+146    0  333 1000\r
+147 1000  333    0\r
+148  749  250   27\r
+149  749   94   94\r
+150    0    0   27\r
+151 1000 1000 1000\r
+152 1000 1000    0\r
+153 1000    0 1000\r
+154  666  666  666\r
+155 1000  498    0\r
+156 1000    0   11\r
+157  498 1000    0\r
+158    0  498    0\r
+159  333  701    0\r
+160    0    0 1000\r
+161    0  498 1000\r
+162    0 1000 1000\r
+163  749  498    0\r
+164    0  850    0\r
+165  666    0  666\r
+166  701  400    0\r
+167  850  600  298\r
+168 1000  666  666\r
+169 1000  800  600\r
+170    0  800 1000\r
+171    0 1000  800\r
+172  392  392  392\r
+173 1000  250  250\r
+174 1000  666  333\r
+175  333  333 1000\r
+176    0  333 1000\r
+177 1000  333    0\r
+178  749  250   27\r
+179  749   94   94\r
+180    0    0    0\r
+181 1000 1000 1000\r
+182 1000 1000    0\r
+183 1000    0 1000\r
+184  666  666  666\r
+185 1000  498    0\r
+186 1000    0    0\r
+187  498 1000    0\r
+188    0  498    0\r
+189  333  701    0\r
+190    0    0 1000\r
+191    0  498 1000\r
+192    0 1000 1000\r
+193  749  498    0\r
+194    0  850   27\r
+195  666    0  666\r
+196  701  400    0\r
+197  850  600  298\r
+198 1000  666  666\r
+199 1000  800  600\r
+200    0  800 1000\r
+201    0 1000  800\r
+202  392  392  392\r
+203 1000  250  250\r
+204 1000  666  333\r
+205  333  333 1000\r
+206  749  250    0\r
+207  749   94   94\r
+208    0    0   11\r
+209 1000 1000 1000\r
+210 1000 1000    0\r
+211 1000    0 1000\r
+212  666  666  666\r
+213 1000  498    0\r
+214 1000    0    0\r
+215  498 1000    0\r
+216    0  498    0\r
+217  333  701    0\r
+218    0    0 1000\r
+219    0  498 1000\r
+220    0 1000 1000\r
+221  749  498    0\r
+222    0  850    0\r
+223  666    0  666\r
+224  701  400    0\r
+225  850  600  298\r
+226 1000  666  666\r
+227 1000  800  600\r
+228    0  800 1000\r
+229    0 1000  800\r
+230  392  392  392\r
+231 1000  250  250\r
+232 1000  666  333\r
+233  333  333 1000\r
+234    0  333 1000\r
+235 1000  333    0\r
+236  749  250    0\r
+237  749   94   94\r
+238    0    0    0\r
+239 1000 1000 1000\r
+240 1000 1000    0\r
+241 1000    0 1000\r
+242  666  666  666\r
+243 1000  498    0\r
+244 1000   27    0\r
+245  498 1000    0\r
+246    0  498    0\r
+247  333  701    0\r
+248    0    0 1000\r
+249    0  498 1000\r
+250    0 1000 1000\r
+251  749  498    0\r
+252    0  850    0\r
+253  666    0  666\r
+254  701  400    0\r
+255 1000 1000 1000\r
diff --git a/dll/Makefile b/dll/Makefile
new file mode 100644 (file)
index 0000000..da04b2b
--- /dev/null
@@ -0,0 +1,47 @@
+CC=gcc
+FGIS_HOME=/usr/lib/fgis
+CFLAGS=-g -Wall -pedantic -fPIC\
+ -I/usr/openwin/include -I/usr/local/include -I../include \
+ -DFGIS_HOME=\"${FGIS_HOME}\"
+LDFLAGS=-L../lib -L/usr/openwin/lib -L/usr/local/lib
+LOADLIBES=-ldl -lm -lepp -lX11 -ltcl8.0 -ltk8.0
+
+OBJS=\
+fgisInit.o\
+fgisMisc.o\
+fgisPalette.o\
+fgisRaster.o\
+fgisPlanchet.o\
+fgisEppCalc.o\
+fgisEppDraw.o\
+fgisVector.o\
+fgisPatterns.o\
+fgisProjection.o
+SRC=\
+RCS/fgisInit.c,v\
+RCS/fgisMisc.c,v\
+RCS/fgisPalette.c,v\
+RCS/fgisRaster.c,v\
+RCS/fgisVector.c,v\
+RCS/fgisPlanchet.c,v\
+RCS/fgisEppCalc.c,v\
+RCS/fgisEppDraw.c,v\
+RCS/fgisVector.c,v\
+RCS/fgisPatterns.c,v\
+RCS/fgisProjection.c,v\
+RCS/fgis.h,v\
+RCS/fgisInt.h,v
+
+RCS/%,v : %
+       ci $<
+%.E : %.c
+       gcc ${CFLAGS} -E $< > $*
+all: fgis.so 
+fgis.so: ${OBJS} 
+#      cc -G ${OBJS} ../lib/*.o -o fgis.so -lm -ltcl8.0 -L/usr/local/lib 
+       gcc -shared -o fgis.so ${OBJS} ../lib/*.o  -lm -ltcl8.0
+rcs: ${SRC}
+test: fgis.so
+       echo load ./fgis.so|wish
+clean: 
+       rm -f ${OBJS} fgis.so
diff --git a/dll/fgis.h b/dll/fgis.h
new file mode 100644 (file)
index 0000000..06500b3
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef FGIS_H
+#define FGIS_H
+
+#include <tcl.h>
+#include <epp.h>
+#include <reclass.h>
+#include "fgisInt.h"
+
+
+#define CACHE_THRESHOLD 4000000L 
+/* maximum size of cache, allowed for raster files */
+
+#define MAX_PALETTE_SIZE 20480
+/* The size of palette file wihch never would be exceeded
+   (256 lines, 80 chars each - is it enough?)
+ */
+
+/* This header file contain all definition of routines,
+  which implements EPTcl commands. Neccessary for Eptcl_Init 
+ */
+
+void Fgis_DefDeleteProc(ClientData client_data);
+/* Empty command delete proc */
+
+/* Argument parsing and checking*/
+
+int Fgis_GetInt(Tcl_Interp *interp,int argc,char **argv,int index, 
+                int min, int max,int *result, char *name);
+/* Fetches int argument from argv array at index, checking for its presence,
+   format and range. Puts into result. name is descriptive name for errir
+   reporting 
+ */  
+int Fgis_GetLimits(Tcl_Interp *interp,char *list,double *X1,double *Y1,
+                   double *X2,double *Y2);
+/* Parses four element list of doubles, representing region on map or
+   window */
+int Fgis_CkArgs(Tcl_Interp *interp,int cond, char *cmd, char *msg);
+/*
+ * Palette - related procedures
+ */
+PATTERNS Fgis_GetPatterns(Tcl_Interp *interp,char *name);
+
+int Fgis_Palette(ClientData data,Tcl_Interp *interp,int argc,char **argv);
+/* palette object construction */
+
+int Fgis_PaletteObj(ClientData data,Tcl_Interp *interp,int argc,char **argv);
+/* Command procedure for palette object command */
+
+void Fgis_DeletePalette(ClientData data);
+/* all the same for pattern sets */
+int Fgis_CreatePatterns(ClientData data,Tcl_Interp *interp,int argc,char **argv);
+int Fgis_PatternObj(ClientData data,Tcl_Interp *interp, int argc, char **argv);
+void Fgis_DeletePatterns(ClientData data);
+/*
+ * Accessible from other modules Returns palette, corresponding with
+ * tcl command name in interp. Don't try to fool it, passing non palette-object
+ * command! Returns NULL and leaves message in interpreter in case of error. 
+ */
+PALETTE Fgis_GetPalette(Tcl_Interp *interp, char *name);
+/* Allows to fetch palette, if its Tcl name is given */
+
+/* Raster related stuff */
+
+int Fgis_Raster(ClientData data,Tcl_Interp *interp,int argc,char **argv);
+/* implements raster command */
+int Fgis_RasterObj(ClientData data,Tcl_Interp *interp,int argc, char **argv);
+/* implements object command of raster objects */
+
+void Fgis_DeleteRaster(ClientData data);
+/* delete proc for command raster - desroys global tables*/
+void Fgis_DeleteRasterObj(ClientData data);
+/* delete proc for raster object command - destroys raster itself*/
+
+RASTER_OBJECT Fgis_GetRaster(Tcl_Interp *interp, char *name);
+/* vector related stuff */
+
+int Fgis_Vector(ClientData data,Tcl_Interp *interp,int argc,char **argv);
+int Fgis_VectorObj(ClientData data,Tcl_Interp *interp,int argc,char **argv);
+void Fgis_DeleteVectorObj(ClientData data);
+
+/* projection object */
+int Fgis_Projection(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+int Fgis_ProjObject(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+void Fgis_DeleteProj(ClientData data);
+/* Drawing objects */
+
+int Fgis_RasterImage(ClientData data,Tcl_Interp* interp,int argc,
+ char **argv);
+
+
+/* Planchet methods */
+int Fgis_MapX(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+int Fgis_MapY(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+int Fgis_ScrY(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+int Fgis_ScrX(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+int Fgis_Fit(ClientData data,Tcl_Interp* interp,int argc, char **argv);
+
+/* Functions for access planchet from C code */
+double Fgis_AltX(Tcl_Interp *interp,char *planchet ,int x);
+double Fgis_AltY(Tcl_Interp *interp,char *planchet ,int y);
+int Fgis_PlanchetX(Tcl_Interp *interp, char *planchet ,double x);
+int Fgis_PlanchetY(Tcl_Interp *interp, char *planchet ,double y);
+int Fgis_ValidPlanchet(Tcl_Interp *interp, char *planchet);
+int Fgis_CreateObjectCommand(Tcl_Interp *interp,char *prefix,
+      Tcl_CmdProc *proc,ClientData data, Tcl_CmdDeleteProc deleteProc);
+/* handy defines */
+
+/* Makes dynamically allocante copy of string, using Tcl allocator */
+#define stralloc(x) (strcpy(Tcl_Alloc(strlen(x)+1),x))
+
+/* Body of non-implemented procedure. When it goes away, I would be
+  VERY happy*/
+#define NOT_YET {Tcl_SetResult(interp,"Not implemented yet",TCL_STATIC); return TCL_ERROR;}
+
+/* Set result and return error */
+#define ERROR_MESSAGE(msg,mode) {Tcl_SetResult(interp,msg,mode);return TCL_ERROR;}
+
+/* Set result and return success */
+#define RETURN(value,mode) {Tcl_SetResult(interp,value,mode);return TCL_OK;}
+/* Given raster object, returns EPP* */
+#define epp(x) (x->file->e)
+#endif
diff --git a/dll/fgisCount.c b/dll/fgisCount.c
new file mode 100644 (file)
index 0000000..26522cb
--- /dev/null
@@ -0,0 +1,34 @@
+#include <epp.h>
+#include <stdlib.h>
+#include <tcl.h>
+#include "fgisInt.h"
+#include "fgis.h"
+/*
+ * This file is part of fGIS C library
+ * fgisCount.c Various routines to perform area counting on rasters
+ */
+int count_to_array(Tcl_Interp *interp,RASTER_OBJECT raster,char *array /* here geomerty spec should be*/)
+{ EPP *e=epp(raster);
+  int *accumulate;
+  RECLASS r=raster->reclass;
+  int v,i,j,size=Fgis_RasterMax(raster)+1;
+  accumulate=calloc(ize,sizeof(int));
+/* loop should vary according to geometry specifications */
+  for (i=e->fr;i<e->lr;i++) 
+      for (j=e->fc;j<e->lc;j++) {
+        v=epp_get(e,j,i);
+        if (v!=e->offsite)) {
+          accumulate[r[v]]++;
+      }
+  }
+  for (i=0;i<size;i++) {  
+     if (accumulate[i]) {
+       char result[32],index[8];
+       Tcl_PrintDouble(interp,accumulate[i]*e->cell_area,result);
+       sprintf(index,"%d",i);
+       Tcl_SetVar2(interp,array.index,result)
+     }
+  }
+  free(accumulate)
+  return TCL_OK;
+}  
diff --git a/dll/fgisEppCalc.c b/dll/fgisEppCalc.c
new file mode 100644 (file)
index 0000000..2aa6c16
--- /dev/null
@@ -0,0 +1,161 @@
+#include <stdlib.h>
+#include <epp.h>
+#include <reclass.h>
+#include "fgisInt.h"
+#include "fgis.h"
+/*
+ * fgisEppCalc.c 
+ *
+ * Functions to deal with raster objects, which are not directly interfaces 
+ * TCL
+ */
+
+/* Some global variables are defined here */
+/* Default reclass - property of reclass command 
+   Something wrong with it. It should be allocated once, not upon each
+   intiialization of package
+ */
+RECLASS def_reclass;
+/* Points to list of all open rasters. This is good, becouse it would 
+   correctly handle access to open rasters from multiple interptreters
+ */
+XEPP *first_raster=NULL;
+RASTER_OBJECT firstobject=NULL;
+/*
+ * Returns maximal value of raster, using current reclass
+ *
+ */
+int Fgis_RasterMax(RASTER_OBJECT handle)
+{
+    EPP *e=epp(handle);
+    int max,i;
+    if(handle->reclass==def_reclass) 
+       max=e->max;
+    else { 
+       max=0;
+       for(i=e->min;i<=e->max;i++) 
+           if (i!=e->offsite&&handle->reclass[i]>max) 
+               max=handle->reclass[i];
+    }
+    return max;
+}
+
+/*
+ * Returns minimal value of raster, taking into account current reclass
+ *
+ */
+int Fgis_RasterMin(RASTER_OBJECT handle)
+{
+    EPP *e=epp(handle);
+    int min,i;
+    if(handle->reclass==def_reclass) 
+       min=e->min;
+    else { 
+       min=65535;
+       for(i=e->min;i<=e->min;i++) 
+       if (i!=e->offsite&&handle->reclass[i]<min) 
+           min=handle->reclass[i];
+    }
+    return min;
+}
+/*
+ * Reopens file in new mode. Returns 0 on success, non-zero on failure.
+ * If fails, file remains open in old mode.
+ */
+
+
+/*
+ * Creates new XEPP object from open EPP* object.
+ * 
+ */
+
+XEPP* Fgis_NewXEPP(EPP *file,char *filename) 
+{XEPP* xptr;
+
+    xptr=malloc(sizeof(XEPP));
+    xptr->e=file;
+    xptr->linkcount=1;
+    xptr->filename=stralloc(filename); 
+    xptr->next=first_raster;
+    xptr->editable=1;
+    first_raster=xptr;
+    return xptr;                
+}      
+/* 
+ * Opens existing epp file. If file already opened, returns pointer
+ * to it
+ */
+
+XEPP* Fgis_OpenXEPP(char *filename,EPP *(*openfunc)(char *))
+{
+ EPP* epp_ptr;
+ XEPP * xptr=first_raster;
+ RASTER_OBJECT obj;
+ int reclass_size;
+    while (xptr) {
+       if (!strcmp(xptr->filename,filename)) break;
+       xptr=xptr->next;
+    }
+    
+    if (!xptr) {
+       /* îÅÔ ÔÁËÏÇÏ × ÔÁÂÌÉÃÅ, ÏÔËÒÙ×ÁÅÍ ÎÏ×ÙÊ*/
+       epp_ptr=openfunc(filename);
+       if (!epp_ptr) {
+           return NULL;
+       }
+       xptr=Fgis_NewXEPP(epp_ptr,filename);
+        xptr->editable=(openfunc==load_epp); 
+
+     } else { 
+       (xptr->linkcount)++;
+        /* if it was open in read-only mode and now we want it to 
+           be read-write */  
+        if (!xptr->editable&&openfunc==load_epp) {
+            /* close it */
+            close_epp(xptr->e);
+            /* reopen for read-write */
+            xptr->e=load_epp(filename);
+            /* if failed, restore it back in readonly mode and return NULL*/
+            if (!xptr->e) {
+              xptr->e=open_epp(filename);
+              xptr->linkcount--;
+              return NULL;
+            }
+            /* fix reclass tables for all objects, which refers to this file*/
+            reclass_size=1<<(xptr->e->kind);
+            for (obj=firstobject;obj!=NULL;obj=obj->next) {
+               if (obj->file==xptr) {
+                 obj->reclass=realloc(obj->reclass,reclass_size*sizeof(short));
+               }
+            }  
+               
+        }
+     }
+    return xptr;
+
+}
+
+/*
+ * Gets rid of XEPP object (if only reference - deletes, otherwise
+ * decrements link count)
+ */ 
+
+void Fgis_CloseXEPP(XEPP* file)
+{   
+    file->linkcount--;
+    if(!file->linkcount) {
+    /* Remove it from list */
+       if (first_raster==file) {
+           first_raster=file->next;
+       } else {
+           XEPP* tmp=first_raster;
+           while (tmp->next!=file)
+               tmp=tmp->next;
+           tmp->next=file->next;
+        }
+       /* Close eppfile */
+       close_epp(file->e);
+       free(file->filename);
+       free(file);
+    }
+}
diff --git a/dll/fgisEppDraw.c b/dll/fgisEppDraw.c
new file mode 100644 (file)
index 0000000..7cd9017
--- /dev/null
@@ -0,0 +1,364 @@
+#include <tk.h>
+#include <tcl.h>
+#include <stdlib.h>
+#include <reclass.h>
+#include <epp.h>
+#include "fgis.h"
+#include "fgisInt.h"
+unsigned short int *border_buffer1, *border_buffer2, *bbuf_ptr1, *bbuf_ptr2;
+
+void init_border (int width, int offsite)
+{
+    int i;
+    border_buffer1 = (unsigned short int *)Tcl_Alloc (
+                (width + 1) * sizeof (unsigned short int));
+    border_buffer2 = (unsigned short int *)Tcl_Alloc (
+        (width + 1) * sizeof (unsigned  short int));
+    *border_buffer2 = offsite;
+    for (i = 0, bbuf_ptr1 = border_buffer1; i <= width; i++, bbuf_ptr1++)
+       *bbuf_ptr1 = offsite;
+}
+void new_border_row ()
+{
+    unsigned short int *tmp;
+    tmp = border_buffer1;
+    border_buffer1 = border_buffer2;
+    border_buffer2 = tmp;
+    bbuf_ptr1 = border_buffer1;
+    bbuf_ptr2 = border_buffer2;
+
+} int check_border (int class)
+{
+    *(++bbuf_ptr1) = class;
+    bbuf_ptr2++;
+    return *bbuf_ptr2 != class || *(bbuf_ptr1 - 1) !=
+      class || *(bbuf_ptr2 - 1) != class;
+}
+void done_border ()
+{
+    Tcl_Free ((char*)border_buffer1);
+    Tcl_Free ((char*)border_buffer2);
+}
+/*
+
+òÉÓÕÅÔ ÕËÁÚÁÎÎÙÊ ËÕÓÏË ÒÁÓÔÒÁ (× ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔÁÈ)
+*/ 
+
+int Fgis_MakePhotoImage (Tk_PhotoHandle imghandle,
+                       int xl, int yb, int xr, int yt,
+                       double XL, double XR, double YT, double YB,
+                       RASTER_OBJECT handle,
+                      int border,/* 0 - ÎÉÞÅÇÏ, 1, ÐÒÉ ÎÅÓÏ×ÐÁÄÅÎÉÉ
+                                    Ã×ÅÔÏ× ÐÏÓÌÅ ÒÅËÌÁÓÓÁ,
+                                    2 - ÐÒÉ ÎÅÓÏ×ÐÁÄÅÎÉÉ Ã×ÅÔÏ× 
+                                          ÂÁÚÏ×ÏÇÏ ÒÁÓÔÒÁ
+                                */
+                     PALETTE palette,
+                     int bordercolor,
+                     int mapmode       /* 0 - wrap (x&0xFF), -1 x>255?255:x,
+                                          >0 map
+                                        */
+                    )
+{
+    Tk_PhotoImageBlock block =
+    {NULL, 0, 1, 1000, 4,
+#ifdef LSB_FIRST
+     {2, 1, 0}
+#else
+     {1, 2, 3}
+#endif
+    };
+
+    EPP *e = epp (handle);
+    RECLASS r = handle->reclass;
+    int width = xr - xl, height = yb - yt;
+    int *irow, *rp;
+    int *pal;
+    int *coltab, *col;
+    double W_Alt = XR - XL, H_Alt = YB - YT;
+    int x, y, row, i, j, maxclass=0;
+    int max_base_class;
+    int base  ;
+/*
+   ÜÔÏ ÂÕÆÅÒ ÄÌÑ ÈÒÁÎÅÎÉÑ ÐÒÏÒÉÓÏ×ÁÎÎÏÊ ÓÔÒÏËÉ 
+ */
+    irow =(int *) Tcl_Alloc (width * sizeof (int));
+    max_base_class = epp_table_size (e) + 1;
+/*
+   íÁÓÓÉ× ×ÈÏÄÏ× × ÐÁÌÉÔÒÕ ÄÌÑ ËÌÁÓÓÏ× ÂÁÚÏ×ÏÇÏ ÒÁÓÔÒÁ 
+ */
+    pal = (int *)Tcl_Alloc(max_base_class * sizeof (int));
+    if (mapmode > 0)
+       maxclass = Fgis_RasterMax (handle);
+    for (i = 0; i < max_base_class; i++) {
+       int index;
+       index = r[i];
+       if (index > 255)
+           switch (mapmode) {
+           case 0:
+               index &= 0xFF;
+               break;          /*
+                                  wrap 
+                                */
+           case -1:
+               index = 255;
+               break;          /*
+                                  no wrap
+                                */
+           default:
+               index = index * mapmode / maxclass;
+               if (i == e->offsite)
+                   index = 255;
+              
+           }
+       pal[i] = palette[index];
+      if (i!= e->offsite) 
+       pal[i]|=0xff000000;
+    }  
+ /*
+   ÜÔÏ ÔÁÂÌÉÃÁ ÐÏÒÑÄËÏ×ÙÈ ÎÏÍÅÒÏ× ËÏÌÏÎÏË × epp-ÆÁÊÌÅ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÈ
+   ÐÉËÓÅÌÁÍ ÒÁÓÔÒÁ 
+ */
+    coltab =(int *) Tcl_Alloc (width * sizeof (int));
+    for (i = xl, col = coltab, j = 0; i < xr; i++, j++, col++) {
+       *col = epp_col (e, W_Alt * (j + 0.5) / width + XL);
+    }
+/*
+   úÁÐÏÌÎÉÍ ÔÅ ÐÏÌÑ ÓÔÒÕËÔÕÒÙ block, ËÏÔÏÒÙÅ ÍÙ ÎÅ ÍÏÇÌÉ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ 
+ */
+    block.pixelPtr = (unsigned char *) irow;
+    block.width = width;
+    block.pitch = width * sizeof (int);
+    if (border) {
+       if (border == 1)
+           init_border (width, r[e->offsite]);
+       else
+           init_border (width, e->offsite);
+    }
+    /* ðÏÞÉÓÔÉÍ image */
+    Tk_PhotoBlank(imghandle);
+    for (y = yt, i = 0; y < yb; y++, i++) {
+       row = epp_row (e, H_Alt * (i + 0.5) / height + YT);
+       if (border)
+           new_border_row ();
+       for (x = xl, j = 0, col = coltab, rp = irow; x < xr;
+               j++, col++, rp++, x++) {
+           base = epp_get (e, *col, row);
+           if (border) {
+               if (border == 1 ? check_border (r[base]) :
+                       check_border (base)) {
+                   *rp = bordercolor;
+                   continue;
+               }
+           }
+           *rp = pal[base];
+       }
+       Tk_PhotoPutBlock (imghandle, &block, xl, y, width, 1);
+    }
+    done_border ();
+    Tcl_Free ((char *)pal);
+    Tcl_Free ((char *)irow);
+    Tcl_Free ((char *)coltab);
+    return TCL_OK;
+
+}
+
+void Fgis_PlotPatterns(Tcl_Interp *interp,
+         char *bitmap_image,
+        int xl,int yb,int xr,int yt,
+        double XL, double XR,double YT,double YB,
+        RASTER_OBJECT handle,
+         int bordermode, PATTERNS patterns,XColor* color,int mapmode)
+{ /* NOT IMPLEMENTED YET */     
+} 
+void  Fgis_PlotSymbols(Tcl_Interp *interp,
+                char *bitmap_image,
+               int xl,int yb,int xr,int yt,
+               double XL,double XR,double  YT,double  YB,
+               RASTER_OBJECT handle,
+                PATTERNS patterns, XColor* color,
+               int mapmode)
+{ /*NOT IMPLEMENTED YET*/
+
+}
+/*
+ * Fgis_RasterImage
+ * - implementation of command fgisRasterColorImage and
+ * fgisRasterBWImage
+ */
+EXPORT(int, Fgis_RasterImage) (ClientData data, Tcl_Interp *interp, 
+      int argc, char **argv)
+{
+  int listc; char **listv; /* for parsing result of $planchet bbox $item */
+  Tk_PhotoHandle imghandle=NULL;
+  int colorplot=(int)data; /* how to distinguish between color and bw */
+  char *bitmap_image=NULL;
+  enum {PATTERNS_MODE,SYMBOLS_MODE} symbolmode=PATTERNS_MODE;
+  int mapmode=0;
+  int bordercolor=0;
+  int bordermode=((int)data)?0:1;
+  PATTERNS patterns=NULL;
+  PALETTE palette=default_palette;
+  RASTER_OBJECT raster;
+  int i;
+  int xl=0,yt=0,xr,yb,imgstartx,imgstarty;
+  double XL,YT,XR,YB; 
+  XColor *clr;
+  Tk_Window canvas=Tk_NameToWindow(interp,argv[2],Tk_MainWindow(interp));
+  
+  clr=Tk_GetColor(interp,canvas,"black");
+    if (Fgis_CkArgs(interp,argc<5,
+           argv[0],"raster planchet item ?options?"))
+     return TCL_ERROR;
+    if (!Fgis_ValidPlanchet(interp,argv[2]))     
+        return TCL_ERROR;
+    if (Tcl_VarEval(interp,argv[2]," bbox ",argv[3],NULL)!=TCL_OK) 
+        return TCL_ERROR;
+    if (Tcl_SplitList(interp,interp->result,&listc,&listv)!=TCL_OK) 
+        return TCL_ERROR;
+    imgstartx=atol(listv[0]);
+    imgstarty=atol(listv[1]);
+    xr=atol(listv[2]);
+    yb=atol(listv[3]);
+    XL=Fgis_AltX(interp,argv[2],imgstartx);
+    XR=Fgis_AltX(interp,argv[2],xr+1);
+    YT=Fgis_AltY(interp,argv[2],imgstarty);
+    YB=Fgis_AltY(interp,argv[2],yb+1);
+    xr-=imgstartx;
+    yb-=imgstarty;
+    Tcl_Free((char *)listv);
+    if (Tcl_VarEval(interp,argv[2]," itemcget ",argv[3]," -image",NULL)!=TCL_OK)
+        return TCL_ERROR;
+    if (colorplot) {    
+       imghandle=Tk_FindPhoto(interp,interp->result);
+       if (!imghandle) {
+          Tcl_AppendResult(interp,"No valid image for item ",argv[3],
+                      " in planchet ", argv[2],NULL);
+          return TCL_ERROR;
+       }   
+    } else {
+        if (interp->result)
+           bitmap_image=stralloc(interp->result);
+       else {   
+          Tcl_AppendResult(interp,"No valid image for item ",argv[3],
+                      " in planchet ", argv[2],NULL);
+          return TCL_ERROR;
+       }   
+    }  
+    raster=Fgis_GetRaster(interp,argv[1]);
+    if (!raster) {
+       Tcl_AppendResult(interp,argv[1]," is not valid raster",NULL);
+       return TCL_ERROR;
+    }   
+
+for(i=4;i<argc;i++) { 
+    if (!strcmp(argv[i],"-palette")&&colorplot) {
+       if(!(palette=Fgis_GetPalette(interp,argv[++i])))
+           return TCL_ERROR;
+    } else if (!strcmp(argv[i],"-patterns")&&!colorplot) {
+        if(!(patterns=Fgis_GetPatterns(interp,argv[++i])))
+          return TCL_ERROR;
+       symbolmode=PATTERNS_MODE;
+    } else if (!strcmp(argv[i],"-symbols")&&!colorplot) {
+       if (!(patterns=Fgis_GetPatterns(interp,argv[++i])))
+           return TCL_ERROR;
+       symbolmode=SYMBOLS_MODE;
+       bordermode=0;
+    } else if (!strcmp(argv[i],"-border")) { 
+        if (i<argc-1) {
+         i++;
+         if (!strcmp(argv[i],"base")) {
+             bordermode=2;
+         } else if (!strcmp(argv[i],"yes")) {
+             bordermode=1;
+         } else if (!strcmp(argv[i],"none")) {
+             bordermode=0;
+         } else if (argv[i][0]=='-') {
+         /* -border without parameter decrease i */
+             bordermode=1;
+             i--;
+        } else { 
+          Tcl_SetResult(interp,"Invalid border option. Should be one "
+                 "of none, yes, base",TCL_STATIC);
+           return TCL_ERROR;
+       }
+      }        else {
+          bordermode=1;
+      }          
+   } else
+   if (!strcmp(argv[i],"-color")) { 
+       clr=Tk_GetColor(interp,canvas,argv[++i]);
+       if (!clr) return TCL_ERROR;
+       /* What range have XColor fields? */
+       if (colorplot) {
+          bordercolor=((clr->red&0xff)<<16)|((clr->green&0xff)<<8)|
+                  (clr->blue&0xff);
+        }
+    } else
+    if (!strcmp(argv[i],"-map")) { 
+       if (mapmode) 
+           ERROR_MESSAGE("Duplicate color remapping specification",TCL_STATIC);
+       i++;
+       if (!strcmp(argv[i],"wrap")) {
+          mapmode=0;
+       } else 
+       if (!strcmp(argv[i],"none")) {
+          mapmode=-1;
+       } else 
+       if (Fgis_GetInt(interp, argc, argv, ++i, 0, 256, &mapmode,
+           "color index") !=TCL_OK) {
+         return TCL_ERROR;
+       }   
+    } else
+    if (!strcmp(argv[i],"-update")) {
+        double X1,Y1,X2,Y2;
+        int x1,y1,x2,y2;
+        if (++i==argc)
+           ERROR_MESSAGE("List of four doubles expected",TCL_STATIC);
+        if (Fgis_GetLimits(interp,argv[i],&X1,&Y1,&X2,&Y2)!=TCL_OK)
+           return TCL_ERROR;
+        x1=Fgis_PlanchetX(interp,argv[2],X1)-imgstartx;
+        x2=Fgis_PlanchetX(interp,argv[2],X2)-imgstartx;
+        if (x2<x1) {
+           int t;
+           t=x1;x1=x2;x2=t;
+        }
+        if (x1>0) {xl=x1;XL=Fgis_AltX(interp,argv[2],x1+imgstartx);}
+        if (x2<xr) {xr=x2;XR=Fgis_AltX(interp,argv[2],x2+1+imgstartx);}
+        y1=Fgis_PlanchetY(interp,argv[2],Y1)-imgstarty;
+        y2=Fgis_PlanchetY(interp,argv[2],Y2)-imgstarty;
+        if (y2<y1) {
+           int t;
+           t=y1;y1=y2;y2=t;
+        }
+        if (y1>0) {yt=y1;YT=Fgis_AltY(interp,argv[2],y1+imgstarty);}
+        if (y2<yb) {yb=y2;YB=Y2;Fgis_AltY(interp,argv[2],y2+1+imgstarty);}
+    } else {
+       Tcl_ResetResult(interp);
+       Tcl_AppendResult(interp,"Invalid option.\"",argv[i],
+        "\" Should be one of -border, -bordercolor, -map, ",
+          NULL);
+       if (colorplot) 
+          Tcl_AppendResult(interp,"-palette",NULL);
+       else
+          Tcl_AppendResult(interp,"-patterns, -symbols",NULL);
+       Tcl_AppendResult(interp,", -update",NULL);
+       return TCL_ERROR;
+    }    
+         
+}
+
+if (colorplot) {
+  Fgis_MakePhotoImage(imghandle,xl,yb,xr,yt,XL,XR,YT,YB,raster,bordermode,
+                 palette,bordercolor,mapmode);
+} else 
+if (symbolmode==PATTERNS_MODE) {
+  Fgis_PlotPatterns(interp,bitmap_image,xl,yb,xr,yt,XL,XR,YT,YB,raster,
+   bordermode, patterns,clr,mapmode);
+} else {
+  Fgis_PlotSymbols(interp,bitmap_image,xl,yb,xr,yt,XL,XR,YT,YB,raster,
+    patterns, clr, mapmode);
+}    
+return TCL_OK;
+}
diff --git a/dll/fgisEppEdit.c b/dll/fgisEppEdit.c
new file mode 100644 (file)
index 0000000..f390ce8
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * High - level editing operations for fGIS raster editor
+ * 
+ *
+ */
+#include <stdlib.h>
+#include <math.h>
+#include <tcl.h>
+#include <epp.h>
+char *mapErrorExplanation[]={NULL,
+   "Coordinates outside physical borders of file",
+   "Raster is not editable",
+   "File read error",
+   "File write error",
+   "Memory exhaused",
+   "File access denied",
+   "File not found",
+   "File doesn't conform format",
+   "File creation error",
+ };
+/*
+ * Checks if given EPP file is open in read-write mode and
+ * given value is good class value for it.
+ * Should be called each time when one of drawing routines from
+ * this file is about to be called.
+ * Returns TCL_ERROR and leaves error message in interp->result
+ */
+int Fgis_RasterEditable(Tcl_Interp *interp,EPP *epp,char *rastername,int value)
+{ if (!(epp->mode&MAP_LOADED)) {
+    Tcl_AppendResult(interp,"Raster ",rastername," is read-only",NULL);
+    return TCL_ERROR;
+  }
+  if (value>=(1<<epp->kind)) {
+      Tcl_SetResult(interp,"Value too large for this raster",TCL_STATIC);
+      return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+/*
+ * Modifies given cell.
+ * Return value: 0 on success, nonzero if error
+ * Side effects: modifies raster if arguments are good
+ *               leaves error message in interp->result, if they are bad
+ */
+int Fgis_DrawCell(Tcl_Interp *interp,EPP* epp,double x,double y, int value)
+{
+  map_error=0;
+  epp_put(epp,epp_col(epp,x),epp_row(epp,y),value);
+  if (map_error) {
+    Tcl_SetResult(interp,mapErrorExplanation[map_error],TCL_STATIC);
+    map_error=0;
+    return TCL_ERROR;   
+  }
+  return TCL_OK;
+}
+
+/*
+ * Draws circle with center in given point and radius given in
+ * map units
+ *
+ */
+int Fgis_DrawCircle(Tcl_Interp *interp,EPP* epp,double x,double y,double r,
+     int value)
+{
+ return TCL_OK;
+}
+
+/*
+ * Draws circle with center in given point and radius given in
+ * raster cells 
+ *
+ */
+int Fgis_DrawCircleInt(Tcl_Interp *interp, EPP *epp, double x, double y,
+    int r, int value)
+{
+ return TCL_OK;
+}
+/*
+ * Draws filled rectangle
+ *
+ *
+ */
+
+int Fgis_DrawBox(Tcl_Interp *interp, EPP *epp, double x1, double y1,
+  double x2, double y2, int value)
+{int i,
+     row1=epp_row(epp,y1),
+     row2=epp_row(epp,y2),
+     col1=epp_col(epp,x1),
+     col2=epp_col(epp,x2);
+  if (row1<epp->fr) row1=epp->fr;
+  if (row2>=epp->lr) row2=epp->lr-1;
+  if (row1>row2) {
+    Tcl_SetResult(interp,mapErrorExplanation[ME_POINT_OUTSIDE],TCL_STATIC);
+    return TCL_ERROR;
+  }
+  map_error=0;
+  for (i=row1;i<=row2;i++) {
+    epp_putline(epp,col1,col2,i,value);
+    if (map_error) {
+       Tcl_SetResult(interp,mapErrorExplanation[map_error],TCL_STATIC);
+       map_error=0;
+       return TCL_ERROR;
+    }
+  }
+  return TCL_OK;
+}
+/*
+ *  Draws rectangular frame with width, given in pixels
+ *
+ *
+ */
+
+int Fgis_DrawFrame(Tcl_Interp *interp, EPP *epp, double x1, double y1,
+  double x2, double y2, int width, int value)
+{
+ return TCL_OK;
+}
+/*
+ * Draws polyline
+ *
+ */
+int Fgis_DrawLine(Tcl_Interp *interp, EPP *epp, int pointc, double *pointv,
+  int width,  int value)
+{
+
+ return TCL_OK;
+}
+
+/*
+ * Draws filled polygon
+ *
+ */
+int Fgis_DrawPolygon(Tcl_Interp *interp, EPP *epp, int pointc, double *pointv,
+  int value)
+{
+
+ return TCL_OK;
+}
+/*
+ * Fills area of raster until encounters different class than in starting
+ * point. Takes into account four neighbours (left, right, top, bottom)
+ *
+ */
+int Fgis_Fill4(Tcl_Interp *interp, EPP *epp, double x, double y, int value)
+{
+
+ return TCL_OK;
+}
+
+/*
+ * Fills area of raster until encounters given class 
+ * Takes into account four neighbours (left, right, top, bottom)
+ *
+ */
+int Fgis_Fill4Until(Tcl_Interp *interp, EPP *epp, double x, double y, 
+ int value, int stopValue)
+{
+ return TCL_OK;
+
+}
+/*
+ * Fills area of raster until encounters different class than in starting
+ * point. Takes into account eight neighbours (left, right, top, bottom
+ * and four diagonals)
+ */
+int Fgis_Fill8(Tcl_Interp *interp, EPP *epp, double x, double y, int value)
+{
+ return TCL_OK;
+}
+
+/*
+ * Fills area of raster until encounters given class 
+ * Takes into account eight neighbours (left, right, top, bottom 
+ * and four diagonals)
+ */
+int Fgis_Fill8Until(Tcl_Interp *interp, EPP *epp, double x, double y,
+ int value, int stopValue)
+{
+ return TCL_OK;
+
+}  
+
diff --git a/dll/fgisEppEdit.h b/dll/fgisEppEdit.h
new file mode 100644 (file)
index 0000000..e366d14
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef FGIS_EDIT_H
+#define FGIS_EDIT_H
+extern char *mapErrorExplanation[];
+
+int Fgis_RasterEditable(Tcl_Interp *interp,EPP *epp,char *rastername,int value);
+int Fgis_DrawCell(Tcl_Interp *interp,EPP* epp,double x,double y, int value);
+
+int Fgis_DrawCircle(Tcl_Interp *interp,EPP* epp,double x,double y,double r,
+     int value);
+int Fgis_DrawCircleInt(Tcl_Interp *interp, EPP *epp, double x, double y,
+    int r, int value);
+int Fgis_DrawBox(Tcl_Interp *interp, EPP *epp, double x1, double y1,
+  double x2, double y2, int value);
+int Fgis_DrawFrame(Tcl_Interp *interp, EPP *epp, double x1, double y1,
+  double x2, double y2, int width, int value);
+int Fgis_DrawLine(Tcl_Interp *interp, EPP *epp, int pointc, double *pointv,
+  int width,  int value);
+int Fgis_DrawPolygon(Tcl_Interp *interp, EPP *epp, int pointc, double *pointv,
+  int value);
+int Fgis_Fill4(Tcl_Interp *interp, EPP *epp, double x, double y, int value);
+int Fgis_Fill4Until(Tcl_Interp *interp, EPP *epp, double x, double y, 
+ int value, int stopValue);
+int Fgis_Fill8(Tcl_Interp *interp, EPP *epp, double x, double y, int value);
+int Fgis_Fill8Until(Tcl_Interp *interp, EPP *epp, double x, double y,
+ int value, int stopValue);
+#endif
diff --git a/dll/fgisInit.c b/dll/fgisInit.c
new file mode 100644 (file)
index 0000000..59f2fd5
--- /dev/null
@@ -0,0 +1,126 @@
+/* 
+ *fgisInit.c - 
+ *initialization procedure for Fgis package
+ * Copyright (C) by SoftWeyr, 1997
+ */
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+  
+#include <tcl.h>
+#include <tk.h>
+#include "fgis.h"
+
+int check_for_rc(Tcl_Interp *interp,char *home,char *path);
+/* Global variables */
+\f
+/* 
+ * Initialization procedure for Environmental Planning Tcl extension
+ * Return value TCL_OK if success
+ * Side effects:
+ * defines commands raster vector palette fgisPlanchet_mapx fgisPlanchet_mapy
+ * fgisPlanchet_scrx fgisPlanchet_scry fgisPlanchet_fit defaultpalette
+ * defines default (1:1) reclass table
+ * defines fGIS_HOME variable to directory, containing fgis.rc
+ *     Directories are searched in following order
+ *     FGIS_HOME as defined in Makefile
+ *     ~/lib/fgis
+ * executes fgis.rc
+ */
+EXPORT(int, Fgis_Init)(Tcl_Interp *interp)
+{
+  char *fGIS_HOME;
+  char buffer[1024];
+/* Defining commands */ 
+   
+/* Palette objects */
+    if (!Tcl_CreateCommand(interp,"palette",Fgis_Palette,NULL,
+           Fgis_DefDeleteProc)) 
+       return TCL_ERROR;
+    if (!Tcl_CreateCommand(interp,"defaultpalette",Fgis_PaletteObj,
+       (ClientData)default_palette,Fgis_DeletePalette))
+       return TCL_ERROR;
+/* Pattern objects */
+    if (!Tcl_CreateCommand(interp,"patterns",Fgis_CreatePatterns,
+          NULL,Fgis_DefDeleteProc))
+        return TCL_ERROR;
+/* Raster objects */
+    if (!Tcl_CreateCommand(interp,"raster",Fgis_Raster,
+            NULL,Fgis_DeleteRaster)) 
+       return TCL_ERROR;
+/* Vector objects */
+    if (!Tcl_CreateCommand(interp,"vector",Fgis_Vector,NULL,Fgis_DefDeleteProc))
+       return TCL_ERROR;
+  /* Tk dependent fgis commands. Should eventually go into separate package*/
+  /* Object Drawing */
+   if (!Tcl_CreateCommand(interp,"fgisRasterColorImage",Fgis_RasterImage,
+       (ClientData)1,Fgis_DefDeleteProc)) return TCL_ERROR;
+   if (!Tcl_CreateCommand(interp,"fgisRasterBWImage",Fgis_RasterImage,
+      NULL,Fgis_DefDeleteProc)) return TCL_ERROR;
+  /* planchet widget subcommands, written on C */    
+    if (!Tcl_CreateCommand(interp,"fgisPlanchet_mapx",Fgis_MapX,NULL,
+       Fgis_DefDeleteProc))
+       return TCL_ERROR;
+    if (!Tcl_CreateCommand(interp,"fgisPlanchet_mapy",Fgis_MapY,NULL,
+            Fgis_DefDeleteProc))
+
+       return TCL_ERROR;
+    if (!Tcl_CreateCommand(interp,"fgisPlanchet_scrx",Fgis_ScrX,NULL,
+            Fgis_DefDeleteProc))
+       return TCL_ERROR;
+    if (!Tcl_CreateCommand(interp,"fgisPlanchet_scry",Fgis_ScrY,NULL,
+        Fgis_DefDeleteProc))
+       return TCL_ERROR;
+    if (!Tcl_CreateCommand(interp,"fgisPlanchet_fit",Fgis_Fit,NULL,
+        Fgis_DefDeleteProc))
+       return TCL_ERROR;
+    if (!Tcl_CreateCommand(interp,"projection",Fgis_Projection,NULL,
+        Fgis_DefDeleteProc))
+       return TCL_ERROR;
+     
+    /* Searching for fgis.rc and executing it */
+    /* First, check if fGIS_HOME already set */
+    if ((fGIS_HOME=Tcl_GetVar(interp,"fGIS_HOME",TCL_GLOBAL_ONLY))==NULL) {
+         fGIS_HOME=buffer;
+         /* Check if compilied in default is valid */ 
+         if (!check_for_rc(interp,fGIS_HOME,FGIS_HOME)&&
+#ifdef __unix__
+             !check_for_rc(interp,fGIS_HOME,"/usr/local/lib/fgis")&&
+             !check_for_rc(interp,fGIS_HOME,"/usr/lib/fgis")&&
+             !check_for_rc(interp,fGIS_HOME,"~/fgis")
+#else 
+             !check_for_rc(interp,fGIS_HOME,"C:/FGIS") &&
+             !check_for_rc(interp,fGIS_HOME,"C:/Program Files/fGIS") &&
+             !check_for_rc(interp,fGIS_HOME,"C:/TCL/LIB/fGIS") 
+#endif
+            ) {
+                 Tcl_SetResult(interp,"Cannot determine fGIS home directory",
+                         TCL_STATIC); 
+                 return TCL_ERROR;
+         };
+        Tcl_SetVar(interp,"fGIS_HOME",fGIS_HOME,TCL_GLOBAL_ONLY);
+    }
+       
+    if (Tcl_EvalFile(interp,FGIS_HOME "/fgis.rc")!=TCL_OK) {
+            Tcl_SetResult(interp,"Error in initialization file",TCL_STATIC); 
+            return TCL_ERROR;
+    }
+    /* Providing package for Tcl versions, which supports it */
+#if (TCL_MAJOR_VERSION>7)||((TCL_MAJOR_VERSION==7)&&(TCL_MINOR_VERSION>=5))
+    Tcl_PkgProvide(interp,"Fgis","0.1");
+#endif
+    return TCL_OK;
+}
+
+int check_for_rc (Tcl_Interp *interp,char *home,char *path)
+{ char buffer[1024];
+  int result;
+  sprintf(buffer,"file readable [file join {%s} fgis.rc]",path);
+  Tcl_Eval(interp,buffer);
+  if (Tcl_GetInt(interp,interp->result,&result)==TCL_OK&& result) {
+      strcpy(home,path);
+      return 1;
+  }
+  return 0;
+}  
diff --git a/dll/fgisInt.h b/dll/fgisInt.h
new file mode 100644 (file)
index 0000000..4a1caaa
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef FGISINT_H
+#define FGISINT_H
+#include <epp.h>
+#include <tcl.h>
+#include <reclass.h>
+typedef int *PALETTE;
+extern PALETTE default_palette;
+
+/* raster related types and variables*/
+
+
+typedef struct XEPP { int linkcount; /*Count of links */
+                      char *filename; /* name of raster file */
+                      struct XEPP* next; /* to chain all open rasters 
+                                           into list*/
+                      EPP *e;
+                      int editable;
+                      } XEPP;
+typedef struct RASTER_OBJECT { XEPP *file;
+                                RECLASS reclass;
+                                struct RASTER_OBJECT *next;
+                              } *RASTER_OBJECT ;
+
+extern XEPP *first_raster; /* This pointer intentionally made global.
+                              even if there are serveral Tcl interpreters,
+                              they all should share same list of open rasters*/
+extern RASTER_OBJECT firstobject;
+
+#define MAX_PATTERN_SIZE (32*256)
+
+
+typedef struct PATTERNS { struct PATTERNS *next; /* patterns are linked in order
+                                                    to be re-used */
+                          char *name;
+                          int width,height;
+                          unsigned int bits[MAX_PATTERN_SIZE];
+                        } *PATTERNS;
+#define patternSize(width,height) ((height*256)*sizeof(int)+sizeof (struct PATTERNS)-MAX_PATTERN_SIZE*sizeof(int)) 
+
+
+extern PATTERNS def_patterns;
+
+int Fgis_RasterMin(RASTER_OBJECT handle);
+
+int Fgis_RasterMax(RASTER_OBJECT handle);
+
+void Fgis_CloseXEPP(XEPP *file);
+
+XEPP* Fgis_OpenXEPP(char *filename,EPP *(*openfunc)(char *));
+
+XEPP* Fgis_NewXEPP(EPP* file, char *filename);
+
+
+#define FGIS_INVALID_RECLASS ((RECLASS)0x1)
+#define MAX_EPP_CLASS 65535
+
+/* EXPORT macro to cope with ugly Win32 DDLs */
+#ifdef WIN32
+#   if defined(_MSC_VER)
+#      define EXPORT(a,b) __declspec(dllexport) a b
+#      define DllEntryPoint DllMain
+#   else
+#      if defined(__BORLANDC__)
+#          define EXPORT(a,b) a _export b
+#      else
+#          define EXPORT(a,b) a b
+#      endif
+#   endif
+#else  /* ! WIN32 */
+#   define EXPORT(a,b) a b
+#endif /* WIN32 */
+#endif
diff --git a/dll/fgisMisc.c b/dll/fgisMisc.c
new file mode 100644 (file)
index 0000000..1056177
--- /dev/null
@@ -0,0 +1,133 @@
+#include <tcl.h>
+#include <stdlib.h>
+#include <string.h>
+#include "fgis.h"
+/*
+ * Utility functions, I need to program fgis
+ * Copyright (c) Softweyr, 1997
+ */
+/* 
+ * If passed condition is true, puts standard error message, appended
+ * by msg argument to interp->result. 
+ * Returns cond
+ * 
+ */
+int Fgis_CkArgs(Tcl_Interp *interp,int cond,char *cmd, char *msg)
+{ static char buffer[256]="Wrong # args. Should be ";
+  if (cond) {
+   Tcl_ResetResult(interp); 
+   Tcl_AppendResult(interp,buffer,cmd," ",msg,NULL);
+  }
+  return cond;
+}
+/*
+ * Get integer value from command argument and checks it for valid range.
+ * ARGUMENTS:
+ *     interp: Tcl interpreter to leave error message
+ *     argc, argv - command arguments
+ *     index - position of argument in question in argv
+ *     min, max - range limits
+ *     name - string name of parameter to report errors more clearly
+ * RETURNS:
+ *    TCL_OK on success, TCL_ERROR on failure
+ * SIDE EFFECTS: 
+ *    Places read integer in location, specified by result 
+ */
+
+int Fgis_GetInt(Tcl_Interp *interp,int argc,char **argv,int index, 
+                int min, int max,int *result, char *name)
+{ 
+    int tmp;/* Temporary place to hold result */
+    char msg[1024]; /* place to format error messages */
+
+    if (index==argc) {
+       Tcl_SetResult(interp, "Integer value expected",TCL_STATIC);
+       return TCL_ERROR;
+    }    
+    
+     if (Tcl_GetInt(interp,argv[index],&tmp)!=TCL_OK)
+       return TCL_ERROR;
+     if (tmp<=min||tmp>=max) {
+       sprintf(msg,"Invalid %s: %d. Should be between %d and %d",
+               name,tmp,min,max);
+       Tcl_SetResult(interp,msg,TCL_VOLATILE);
+       return TCL_ERROR;
+     }
+     *result=tmp;
+     return TCL_OK;
+}     
+char *inttostr(long src,char *dest)
+{ sprintf(dest,"%ld",src);
+  return dest;
+}
+\f
+/*
+ * Searches for free command name with given prefix and creates command
+ * with it. Places name of command into interp->result 
+ * Returns TCL_OK on success, TCL_ERROR otherwise
+ */
+int Fgis_CreateObjectCommand(Tcl_Interp *interp,char *prefix,
+           Tcl_CmdProc *proc,ClientData data,Tcl_CmdDeleteProc deleteProc)
+             
+{   int num=0;
+    static char token[30],*numstart;
+    Tcl_CmdInfo info;
+    strcpy(token,prefix);
+    numstart=token+strlen(prefix); 
+    while (1) {
+      inttostr(num,numstart);
+      if (Tcl_GetCommandInfo(interp,token,&info)) num++; else break; 
+    }
+    Tcl_SetResult(interp,token,TCL_VOLATILE);
+    if (!Tcl_CreateCommand(interp,token,proc,data,deleteProc)) {
+         (*deleteProc)(data); return TCL_ERROR;
+    } else {
+       return TCL_OK;
+    }
+}
+
+\f
+/*
+ *  Standard TclDeleteProc for commads, which have no ClientData 
+ *  Does nothing, successifully
+ */
+EXPORT(void, Fgis_DefDeleteProc)(ClientData clientdata)
+{
+}
+\f
+/*
+ * Fgis_GetLimits - parses four-element list of doubles, putting them
+ * into four specified global variables
+ * ARGUMENTS: interp - Tcl interpreter to return error
+ *            list - string to parse
+ *            X1,Y1,X2,Y2 - double variables to put results
+ * RETURNS: TCL_OK on success, TCL_ERROR otherwise
+ * SIDE EFFECTS: Fills four double variables
+ */
+int Fgis_GetLimits(Tcl_Interp *interp,char *list,double *X1,double *Y1,
+                   double *X2,double *Y2)
+{
+    int no_error;/* Temporary flag, to pass success around Tcl_Free */
+    int listc; char **listv; /* for TclSplitList */
+    double x1,y1,x2,y2; /* Temporary place for results to avoid overriding if
+                       error occurs */
+                       
+    if(Tcl_SplitList(interp,list,&listc,&listv)==TCL_ERROR) 
+     return TCL_ERROR;
+    if (listc!=4) { 
+    Tcl_SetResult(interp,"Invalid limits list",TCL_STATIC);
+    Tcl_Free((char *)listv); 
+    return TCL_ERROR;
+    }
+    no_error = (Tcl_GetDouble(interp,listv[0],&x1)==TCL_OK) &&
+            (Tcl_GetDouble(interp,listv[1],&y1)==TCL_OK) &&
+            (Tcl_GetDouble(interp,listv[2],&x2)==TCL_OK) &&
+            (Tcl_GetDouble(interp,listv[3],&y2)==TCL_OK);
+    Tcl_Free((char*)listv);
+    if (no_error) {
+       *X1=x1; *Y1=y1; *X2=x2; *Y2=y2;
+       return TCL_OK;
+    } else {
+       return TCL_ERROR;
+    }   
+} 
diff --git a/dll/fgisPalette.c b/dll/fgisPalette.c
new file mode 100644 (file)
index 0000000..d6e129d
--- /dev/null
@@ -0,0 +1,272 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <tcl.h>
+#include "fgis.h"
+/* 
+ * fgisclr.c - palette handling for Fgis
+ * Copyringht (C) by SoftWeyr, 1997
+ */
+/*
+ * Global variables
+ */
+
+/*
+ *# Default palette array 
+ */
+int defarray[]={
+#include "defpal.h"
+};
+
+PALETTE default_palette=defarray;
+/*
+ * Creates new palette. Optionally fills from existing palette. If no existing
+ * palette supplied, all colors will be white
+ */
+
+PALETTE new_palette(PALETTE copy_from) 
+{ PALETTE new_p= (PALETTE)Tcl_Alloc(256*sizeof(int));
+  if (copy_from) {
+    memcpy(new_p,copy_from,256*sizeof(int));
+  } else { 
+    int i,*c;
+    for (i=0,c=new_p;i<256;i++)
+      *(c++)=0xffffff;
+  }
+  return new_p;
+}
+/*
+ * Parses string, containing pallette in EPPL7 file format EPPL7 
+ */
+PALETTE parse_palette(Tcl_Interp *interp,char *string)
+{ PALETTE pal;
+  int index,r,g,b;
+  char *start=string,*end, line[80];
+  pal=new_palette(default_palette);
+  /* ASSIGNMENT INSIDE IF */ 
+  while (( end=strchr(start,'\n'))) {
+    int n=(end-start);
+    if (n==0) continue; /*won't bother with empty lines */
+    if (n>79) n=79;
+    strncpy(line,start,n);
+    start=end+1; 
+    if (sscanf(line,"%d %d %d %d",&index,&r,&g,&b)!=4) { 
+        Tcl_Free((char *)pal); 
+        return NULL;
+    }
+    if (index>255||index<0) 
+        continue;
+    pal[index]=(r*255/1000)<<16|(g*255/1000)<<8|(b*255/1000);
+  } ;
+  return pal;
+}
+/*
+ * Returns index entry of palette in form #RRGGBB
+ *
+ */
+
+
+char *Xcolor_string(PALETTE palette,int index)
+{ int value;
+  static char buffer[24];
+  if(index>=0&&index<255)
+      value=palette[index]; 
+  else 
+      value=palette[255];
+  sprintf(buffer,"#%06x",value);
+  return buffer;
+}
+/*
+ * parses RGB specification in form #RRGGBB.
+ * Returns integer value or 0x1000000 in case of error.
+ */
+int ParseRGB(Tcl_Interp *interp,char *spec)
+{  int val;char *endptr;
+   val= strtol(spec+1,&endptr,16);
+    if ((*endptr)||(spec[0]!='#')||(strlen(spec)!=7)) { 
+       Tcl_SetResult(interp,"Only #RRGGBB color specification is supported",
+           TCL_STATIC);
+        return 0x1000000;
+    }
+    return val;
+} 
+/*
+ * Implements "palette" fgis command.
+ * input - argv[1] subcommand, argv[2] parameter, if required.
+ *   subcommands:
+ *   read filename
+ *   parse string
+ *   copy palettename
+ *   blank
+ * Returns (in interp result) - name of newly created palette
+ * Side effects: defines new Tcl command to handle this palette
+ */
+EXPORT(int, Fgis_Palette)(ClientData data,Tcl_Interp *interp,int argc,char **argv)
+{ PALETTE pal; 
+  if (argc<2) { 
+       Tcl_SetResult(interp,"Wrong # of args. Should be palette command ?arg?",
+           TCL_STATIC); return TCL_ERROR; 
+  }
+  if (!strcmp(argv[1],"read")) { 
+    Tcl_Channel f; /* no comments */
+    int size; /* return value from Tcl_Read. its size,yes but used just for
+                 error checking */
+    char buf[MAX_PALETTE_SIZE];/* place to hold readed file */
+
+    if (Fgis_CkArgs(interp,argc!=3,argv[0]," read filename")) return TCL_ERROR;
+    f=Tcl_OpenFileChannel(interp,argv[2],"r",0666);
+    if (!f) return TCL_ERROR;
+    size=Tcl_Read(f,buf,MAX_PALETTE_SIZE);
+    Tcl_Close(interp,f); 
+    if (size==-1) {return TCL_ERROR;}
+    if (!(pal=parse_palette(interp,buf))) return TCL_ERROR;
+  } else if (!strcmp(argv[1],"parse")) {
+   if (Fgis_CkArgs(interp,argc!=3,argv[0]," parse string")) return TCL_ERROR;
+   if (!(pal=parse_palette(interp,argv[2]))) {
+     return TCL_ERROR;
+   }
+  } else if (!strcmp(argv[1],"set")) {
+     int listc,i;char **listv;
+     if (Fgis_CkArgs(interp,argc!=3,argv[0]," set list")) return TCL_ERROR;
+     pal=new_palette(default_palette);
+     if (TCL_ERROR==Tcl_SplitList(interp,argv[2],&listc,&listv))
+       return TCL_ERROR;
+     for (i=0;i<listc;i++) {
+       pal[i]=ParseRGB(interp,listv[i]);
+       if (pal[i]==0x1000000) { Tcl_Free((char *)listv);return TCL_ERROR;}
+     }
+     Tcl_Free((char *)listv);
+  } else if (!strcmp(argv[1],"copy")) {
+    PALETTE oldpal; 
+    if (Fgis_CkArgs(interp,argc!=3,argv[0]," copy palettename")) return TCL_ERROR;
+    oldpal=Fgis_GetPalette(interp,argv[2]);
+    if (oldpal==NULL)
+       return TCL_ERROR;
+    pal=new_palette(oldpal);
+  } else if (!strcmp(argv[1],"blank")) {
+    if (Fgis_CkArgs(interp,argc!=2,argv[0]," blank")) return TCL_ERROR;
+    pal=new_palette(NULL);
+  } else { 
+   char buffer[255];
+   sprintf(buffer,"Wrong option %s. Should be one of read parse set blank copy",
+            argv[1]);    
+    Tcl_SetResult(interp,buffer,TCL_VOLATILE);
+    return TCL_ERROR;
+  }
+  return Fgis_CreateObjectCommand(interp,"palette",Fgis_PaletteObj,
+        (ClientData)pal, Fgis_DeletePalette);
+}
+/*
+ * Obtain PALETTE pointer from name of command.
+ * Returns NULL in case of error.
+ */
+
+EXPORT(PALETTE, Fgis_GetPalette)(Tcl_Interp *interp, char *name)
+{
+    Tcl_CmdInfo info;char buffer[255]="Invalid palette: ";
+    if (!Tcl_GetCommandInfo(interp,name,&info)) return NULL;
+    if (info.proc!=&Fgis_PaletteObj) {
+       strcat(buffer,name);
+       Tcl_SetResult(interp,buffer,TCL_VOLATILE);
+       return NULL;
+    }
+    return (PALETTE)(info.clientData);
+}
+
+/*
+ * implements palette object command;
+ * Arguments argv[1]- subcommand argv[i] - parameters
+ * Checks subcommand and calls appropriate function
+ */
+
+EXPORT(int, Fgis_PaletteObj)(ClientData data,Tcl_Interp *interp,int argc,char **argv)
+{
+  
+  PALETTE clr=(PALETTE)data;  
+  char buffer[255];
+  int read_only=0;
+  /* default palette supposed to be in readonly memory */
+  read_only=clr==default_palette;
+  /* prepare command name for error message */
+  strcpy(buffer,argv[0]);
+  if (Fgis_CkArgs(interp,argc<2,argv[0]," command ?args?"))
+        return TCL_ERROR;
+  if (!strcmp(argv[1],"print")) {
+    int i;
+    if (Fgis_CkArgs(interp,argc!=2,argv[0]," print"))
+       return TCL_ERROR;
+    for (i=0;i<256;i++) {
+      sprintf(buffer,"%3d %4d %4d %4d\n", i,
+        (clr[i]>>16)*1000/255,
+        ((clr[i]>>8) & 0xFF)*1000/255,
+        (clr[i] & 0xff)*1000/255);
+      Tcl_AppendResult(interp,buffer,NULL);
+    }
+    return TCL_OK;
+  } else
+  if (!strcmp(argv[1],"get")) { 
+     int index;
+     if (Fgis_CkArgs(interp,argc!=3,argv[0],
+               " get index"))
+            return TCL_ERROR;
+     if (Tcl_GetInt(interp,argv[2],&index)==TCL_ERROR) return TCL_ERROR;
+     if (index<0||index>255) {
+        Tcl_SetResult(interp,"#ffffff",TCL_STATIC);
+     } else { 
+        Tcl_SetResult(interp,Xcolor_string(clr,index),TCL_VOLATILE);
+     }
+     return TCL_OK;              
+  }
+  else 
+  if (!strcmp(argv[1],"set")) {
+    int index,RGB;
+       if (read_only) {
+         Tcl_AppendResult(interp,argv[0]," is read only",NULL);
+         return TCL_ERROR;
+       }
+   if (Fgis_CkArgs(interp,argc!=4,argv[0],
+            " set index color"))
+      return TCL_ERROR;
+   if (Tcl_GetInt(interp,argv[2],&index)==TCL_ERROR) return TCL_ERROR; 
+   if (index<0||index>255) { 
+       Tcl_SetResult(interp, "Palette index must be from 0 to 255",
+           TCL_STATIC);
+       return TCL_ERROR;
+   }
+   if ((RGB=ParseRGB(interp,argv[3]))>0xFFFFFF) return TCL_ERROR;
+   clr[index]=RGB;
+   return TCL_OK;
+  }
+  else
+  if (!strcmp(argv[1],"list")) {
+   int i; 
+   if (Fgis_CkArgs(interp,argc!=2,argv[0]," list")) 
+     return TCL_ERROR; 
+   for(i=0;i<256;i++)
+   { Tcl_AppendElement(interp,Xcolor_string(clr,i));
+   }
+   return TCL_OK;
+  }
+  else 
+  if (!strcmp(argv[1],"delete")) {
+   if (Fgis_CkArgs(interp,argc!=2,argv[0]," delete")) return TCL_ERROR;
+   if (read_only) {
+    Tcl_AppendResult(interp,buffer," is read only",NULL);
+    return TCL_ERROR;
+   }
+   Tcl_DeleteCommand(interp,argv[0]);
+   return TCL_OK;
+  }
+  else
+  { Tcl_SetResult(interp,"Wrong option. Should be one of print, get, set, "
+      " list, delete", TCL_STATIC);
+    return TCL_ERROR;
+  } 
+ return TCL_OK;
+}
+
+EXPORT(void, Fgis_DeletePalette)(ClientData data)
+{
+ if (data == default_palette) return;
+ Tcl_Free((char *)data);
+}
diff --git a/dll/fgisPatterns.c b/dll/fgisPatterns.c
new file mode 100644 (file)
index 0000000..2f24267
--- /dev/null
@@ -0,0 +1,402 @@
+#include <tcl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "fgis.h"
+struct { struct PATTERNS* next;
+         char *name;
+         int width;
+         int height;
+         int bits[1];
+       } empty_patterns={NULL,"empty",0,0,{0}};
+
+/* WARNING - this is internal function from tkImgBmap.c which is
+   used here. It might not be exported from tk80.dll on Windows
+   and might changed in future releases. It is prototyped in
+   tkInt.h, but I prefer declare it explicitely in order to put this
+   warning comment here */
+char * TkGetBitmapData(Tcl_Interp *interp, char *string,
+        char *filename, int *widthPtr, int *heightPtr,
+          int *hotXPtr, int *hotYPtr);
+
+PATTERNS def_patterns=(PATTERNS)&empty_patterns;
+PATTERNS first_patterns=(PATTERNS)&empty_patterns;
+
+/* Forward declarations of functions from this file*/
+PATTERNS Fgis_ParsePatterns(Tcl_Interp *interp,char *patterns);
+PATTERNS new_patterns(int width,int height,char *name);
+void print_patterns(Tcl_Interp *interp,PATTERNS ptn) ;
+void make_xbm(Tcl_Interp *interp,int index,PATTERNS data,int width,
+           int height, int frame);
+int parse_xbm(Tcl_Interp *interp,int index,char *data,PATTERNS ptn); 
+
+
+
+EXPORT(PATTERNS, Fgis_GetPatterns)(Tcl_Interp *interp,char *name)
+{
+  if (name==NULL||name[0]=='\0') {
+      return def_patterns;
+  } else {
+    Tcl_CmdInfo info;char buffer[255]="Invalid pattern set name: ";
+    if (!Tcl_GetCommandInfo(interp,name,&info)) return NULL;
+    if (info.proc!=&Fgis_PatternObj) {
+       strcat(buffer,name);
+       Tcl_SetResult(interp,buffer,TCL_VOLATILE);
+       return NULL;
+    }
+    return (PATTERNS)(info.clientData);
+  }
+}
+/*
+ * Implementation of ``patterns'' command
+ *
+ */
+EXPORT(int, Fgis_CreatePatterns)(ClientData clientData, Tcl_Interp *interp, int argc,
+       char **argv)
+{    PATTERNS ptn;
+     if (Fgis_CkArgs(interp,argc<2,argv[0],"command ?arg?")) {
+        return TCL_ERROR;
+     }
+    if (!strcmp(argv[1],"read")) {
+       FILE *f;
+       int size;
+       char *s;
+       if (Fgis_CkArgs(interp,argc!=3,argv[0],"read filename")) {
+          return TCL_ERROR;
+       } 
+       if (!(f=fopen(argv[2],"rb"))) {
+           Tcl_AppendResult(interp,"Cannot open ",argv[2],": ",
+                  Tcl_PosixError(interp),NULL);
+           return TCL_ERROR;
+       }
+       fseek(f,0,SEEK_END);
+       size=ftell(f);
+       fseek(f,0,SEEK_SET);
+       s=Tcl_Alloc(size+1);
+       fread(s,1,size,f);
+       fclose(f);
+       *(s+size)=0;
+       if (!(ptn=Fgis_ParsePatterns(interp,s))) {
+          Tcl_Free(s);
+          return TCL_ERROR;
+       }  
+       Tcl_Free(s); 
+    } else if (!strcmp(argv[1],"set")) {
+       if (Fgis_CkArgs(interp,argc!=3,argv[0],"read string")) {
+          return TCL_ERROR;
+       } 
+       if (!(ptn=Fgis_ParsePatterns(interp,argv[2])))
+          return TCL_ERROR;
+    } else if (!strcmp(argv[1],"blank")) {
+       int sizex,sizey;
+       if (Fgis_CkArgs(interp,argc<3||argc>4,argv[0],"blank sizex ?sizey?")) {
+          return TCL_ERROR;
+       }
+       if (Tcl_GetInt(interp,argv[2],&sizex)!=TCL_OK) {
+          return TCL_ERROR;
+       }
+       if (argc==4) {
+          if (Tcl_GetInt(interp,argv[3],&sizey)!=TCL_OK) {
+              return TCL_ERROR;
+          }
+       } else {
+          sizey=sizex;
+       }
+       if (sizex<0||sizex>32||sizey<0||sizey>32) {
+          Tcl_SetResult(interp,"pattern size should be in range 0 - 32",
+                TCL_STATIC);
+          return TCL_ERROR;
+       }
+       ptn=new_patterns(sizex,sizey,NULL);
+    } else if (!strcmp(argv[1],"copy")) {
+       PATTERNS old;
+       int size;
+       if (!(old=Fgis_GetPatterns(interp,argv[2]))) {
+          return TCL_ERROR;
+       }
+       ptn=new_patterns(old->width,old->height,old->name);
+       memmove(ptn,old,size);
+    } else {
+        Tcl_AppendResult(interp,"Wrong option. Should be one of ",
+           " set, read, copy, blank",NULL);
+        return TCL_ERROR;
+    }
+    return Fgis_CreateObjectCommand(interp,"pattern",Fgis_PatternObj,
+         (ClientData)ptn,Fgis_DeletePatterns);
+
+}
+
+/*
+ * Deletes pattern
+ *
+ */
+EXPORT(void, Fgis_DeletePatterns)(ClientData data) {
+  PATTERNS ptn=(PATTERNS) data;
+  if (ptn->name) Tcl_Free(ptn->name);
+  Tcl_Free((char *)ptn);
+}
+/*
+ * Implementation of pattern object command.
+ *
+ */
+EXPORT(int, Fgis_PatternObj)(ClientData data,Tcl_Interp *interp, int argc, char **argv)
+{ if (Fgis_CkArgs(interp,argc<=1,argv[0],"option ?arg?")) { 
+    return TCL_ERROR;
+  }
+  if (!strcmp(argv[1],"print")) {
+     if (Fgis_CkArgs(interp,argc!=2,argv[0],"print")) 
+         return TCL_ERROR; 
+     print_patterns(interp,(PATTERNS)data);
+  } else if (!strcmp(argv[1],"set")) {
+      int index;
+      if (Fgis_CkArgs(interp,argc!=4,argv[0],"set index dataString")) {
+         return TCL_ERROR;
+      }
+      if (Tcl_GetInt(interp,argv[2],&index)!=TCL_OK) {
+         return TCL_ERROR;
+      }
+      if (index<0||index>255) {
+         Tcl_SetResult(interp,"pattern index should be in 0..255 range",
+             TCL_STATIC);
+         return TCL_ERROR;
+      }
+      if (!parse_xbm(interp,index,argv[3],(PATTERNS)data)) {
+        return TCL_ERROR;
+      }
+   } else if (!strcmp(argv[1],"get")) {
+      int i,index,width,height,frame=0;
+      if (Fgis_CkArgs(interp,argc<3,argv[0],"index ?-width n?  ?-height n? ?-frame bool?")) {
+         return TCL_ERROR;
+      }
+      if (Tcl_GetInt(interp,argv[2],&index)!=TCL_OK) {
+         return TCL_ERROR;
+      }
+      if (index<0||index>255) {
+         Tcl_SetResult(interp,"pattern index should be in 0..255 range",
+             TCL_STATIC);
+         return TCL_ERROR;
+      }
+      i=3;
+      width=((PATTERNS)data)->width;
+      height=((PATTERNS)data)->height;
+      while (i<argc-1) {
+         if (!strcmp(argv[i],"-width")) {
+           if (Tcl_GetInt(interp,argv[i+1],&width)!=TCL_OK) return TCL_ERROR; 
+         } else if (!strcmp(argv[i],"-height")) {
+           if (Tcl_GetInt(interp,argv[i+1],&height)!=TCL_OK) return TCL_ERROR; 
+         } else if (!strcmp(argv[i],"-frame")) {
+           if (Tcl_GetBoolean(interp,argv[i+1],&height)!=TCL_OK) return TCL_ERROR; 
+         } else {
+            Tcl_SetResult(interp,"invalid option. Should be one of -width -height -frame",TCL_STATIC);              
+            return TCL_ERROR;
+         }
+         i+=2;
+     }
+     if (i!=argc) {
+        Tcl_SetResult(interp,"option without argument",TCL_STATIC);
+        return TCL_ERROR;
+     }
+         make_xbm(interp,index,(PATTERNS)data,width,height,frame);
+  } else if (!strcmp(argv[1],"name")) {
+     PATTERNS p = (PATTERNS) data;
+     if (Fgis_CkArgs(interp,argc>3,argv[0],"name ?new name?")) {
+        return TCL_ERROR;
+     }
+     if (argc==3) {
+        int len; 
+        if (p->name) Tcl_Free(p->name);
+        len = strlen(argv[2]);
+        p->name=Tcl_Alloc(len>80?81:len+1);
+        strncpy(p->name,argv[2],80);
+        if (len>80) p->name[80]=0;
+     }  
+     Tcl_SetResult(interp,p->name,TCL_VOLATILE); 
+  } else if (!strcmp(argv[1],"delete")) {
+     if (Fgis_CkArgs(interp,argc!=2,argv[0],"delete")) return TCL_ERROR;
+     Tcl_DeleteCommand(interp,argv[0]); 
+  } else {
+      Tcl_SetResult(interp,"invalid option. Should be one of name, print, get, set, delete",TCL_STATIC);         
+      return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+/*
+ * Parses string, which looks like content of EPPL symbol file and
+ * returns PATTERNS structure (or NULL, if there was parsing error)
+ *
+ */
+PATTERNS Fgis_ParsePatterns(Tcl_Interp *interp, char *str) {
+   PATTERNS ptn;
+   char namebuf[256]="";
+   char hex[9] = {0,0,0,0,0,0,0,0,0};
+   char *next_line,*p;
+   char *name;
+   int block_size,index, old_index;
+   unsigned int *bitptr;
+   int width,height;
+
+   Tcl_SetResult(interp,"Invalid pattern file",TCL_STATIC); 
+   if (sscanf(str,"%d %d%[^\n]",&width,&height,namebuf)<=2) {
+      return NULL;
+   }
+   if (width<-32||width>-1||height<-32||height>-1) {
+      return NULL;
+   }
+   width=-width;
+   height=-height;
+   name=namebuf+strlen(namebuf)-1;
+   while (name>=namebuf&&isspace(*name)) name--;
+   *(++name)=0;
+   next_line =strchr(str,'\n');
+   if (!next_line) return NULL;
+   name=namebuf;
+   while(*name&&isspace(*name))name++;
+   
+   ptn=new_patterns(width,height,name);
+   block_size=width<=16?4:8; 
+   while (*next_line&&*(++next_line)) {
+       while(*next_line&&isspace(*next_line)) next_line++;
+       if (!*next_line) break;
+       p=next_line;
+       index=strtol(next_line,&p,10);
+       if (!isspace(*p)) {
+          Fgis_DeletePatterns((ClientData)ptn);
+          return NULL;
+       }
+       p++;  
+       if (index != old_index) {
+          bitptr=ptn->bits+index*height;
+          old_index = index;
+       } 
+       while (*p&&*p!='\n' && *p!='\r') { 
+         strncpy(hex,p,block_size);
+         p+=block_size;
+         *(bitptr++)=strtol(hex,NULL,16);
+       }
+       next_line=p;
+   }
+   Tcl_ResetResult(interp);
+   return ptn;         
+}
+
+PATTERNS new_patterns(int width,int height,char *name) {
+ PATTERNS p=(PATTERNS)Tcl_Alloc(patternSize(width,height));
+ char *name_ptr=NULL;
+  
+ if (name && *name) {
+      name_ptr=Tcl_Alloc(strlen(name)+1);
+      strcpy(name_ptr,name); 
+ }
+ p->width=width;
+ p->height=height;
+ p->next=NULL;
+ p->name=name_ptr;
+ memset(&p->bits,0,sizeof(int)*height*256);
+ return p;
+} 
+/*
+   Puts in interp->result printable representation of pattern set
+   ptn in EPPL symbol file format
+ */
+void print_patterns(Tcl_Interp *interp,PATTERNS ptn) 
+{ int i,j,l;char *name="";
+  unsigned int *a,*b;
+  char buffer[256],num[9];
+  char *fmt=ptn->width>16?"%08X":"%04X";
+  int d=ptn->width>16?8:4;
+  if (ptn->name) name=ptn->name;
+  sprintf(buffer,"%3d %3d %s\n",-ptn->width,-ptn->height,name); 
+  Tcl_AppendResult(interp,buffer,NULL);
+  for (i=0,a=ptn->bits;i<=255;i++,a+=ptn->height) {
+    /* Check if pattern is empty */
+    unsigned int sum=0;
+    for (j=0,b=a;j<ptn->height;j++,b++) sum|=*b;
+    if (!sum) continue;
+    /* print pattern */ 
+    sprintf(buffer,"%3d ",i);
+    for (j=0,l=0,b=a;j<ptn->height;j++,b++) {
+      sprintf(num,fmt,*b);
+      strcat(buffer,num);
+      l+=d;
+      if (l>=64) {
+        l=0;
+        Tcl_AppendResult(interp,buffer,"\n",NULL);
+        buffer[4]=0;
+      }
+    }
+    if (l) Tcl_AppendResult(interp,buffer,"\n",NULL);
+  } 
+}
+/*
+  Parses xbm file given by data argiment and replaces by it pattern N
+  index in pattern set ptn
+  returns 0 and leaves error message in interp if something goes wrong.
+*/ 
+int parse_xbm(Tcl_Interp *interp,int index,char *data,PATTERNS ptn) {
+char *bitmap,*b;
+int width,height,hotX,hotY;
+int mask,  i,j, bm; 
+unsigned int *p; 
+   bitmap = TkGetBitmapData(interp, data, NULL, &width, &height,
+   &hotX, &hotY);
+   if (!bitmap) return 0;
+   if (width!=ptn->width || height!=ptn->height) {
+       ckfree(bitmap);
+       Tcl_SetResult(interp,"bitmap size doesn't match pattern size",
+           TCL_STATIC);
+       return 0;
+   }
+   b=bitmap;
+   /*Now copy bitmap data into patterns structure*/
+   for (i=0,p=ptn->bits+index*ptn->height;i<ptn->height;i++,p++) {
+      *p=0;
+      for(j=0,mask=1<<(ptn->width-1), bm=1;j<ptn->width;j++,mask>>=1) {
+         if (*b&bm) *p|=mask;
+         bm<<=1;
+         if (bm>0x80) {
+           b++; bm=1;
+         }
+      }
+      if (bm!=1) b++;
+   }
+   ckfree(bitmap);
+   return 1;      
+}
+void make_xbm(Tcl_Interp *interp, int index,PATTERNS data,int width,
+      int height, int frame)
+{ char buffer[256];
+  int i,j,row,bit;
+  unsigned int mask, *bitp, current;
+  int value;
+  sprintf(buffer,"#define pattern_width %d\n#define pattern_height %d\n"
+   "static char pattern_bits[] = {\n",width,height);
+  Tcl_AppendResult(interp,buffer,NULL);
+  for (i=0,row=33;i<height;i++,row++,bitp++) {
+    if (row>=data->height) {
+        row=0;
+        bitp=data->bits+(index*(data->height));
+    }
+    current=*bitp;
+    value=0;
+    for (j=0,mask=0,bit=1;j<width;j++,mask>>=1) {
+       if (!mask) {
+          mask=1<<(data->width-1);
+       }
+       if (current & mask) value|=bit;
+        
+       if ((bit<<=1)==0x100) {
+          sprintf(buffer," 0x%02x,",value);
+          Tcl_AppendResult(interp,buffer,NULL);
+          bit=1;
+          value=0;
+       }
+    }
+    if (bit==1) {
+      Tcl_AppendResult(interp,"\n",NULL);
+    } else {
+      sprintf(buffer,"0x%02x,\n",value);
+      Tcl_AppendResult(interp,buffer,NULL);
+    }    
+  }
+  Tcl_AppendResult(interp,"};\n",NULL); 
+}
diff --git a/dll/fgisPlanchet.c b/dll/fgisPlanchet.c
new file mode 100644 (file)
index 0000000..c194bd4
--- /dev/null
@@ -0,0 +1,255 @@
+#include <tk.h>
+#include <stdlib.h>
+#include <math.h>
+#include "fgis.h"
+/* 
+ * fgisPlanchet.c - coordinate recalculating commands for planchet widget,
+ * implemented in C
+ * Copyright (c) by softweyr
+ */
+
+/* internal converting function */
+
+/* 
+ *    Fills x1 y1 x2 y2 with limits of planchet coordinate system
+ *    Returns TCL_OK on success
+ */
+int Fgis_GetPlanchetLimits(Tcl_Interp *interp,char *planchet,
+             double *x1,double *y1,double *x2, double *y2)
+{
+ char *list;
+ list=Tcl_GetVar2(interp,planchet,"limits",TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
+ if (!list) return TCL_ERROR;
+ return Fgis_GetLimits(interp,list,x1,y1,x2,y2);
+}
+
+int Fgis_GetPlanchetWidth(Tcl_Interp *interp,char *planchet)
+{
+  Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
+  if (p==NULL) return 0;
+ return Tk_ReqWidth(p);
+}
+int Fgis_GetPlanchetHeight(Tcl_Interp *interp,char *planchet)
+{
+  
+  Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
+  if (p==NULL) return 0;
+  return Tk_ReqHeight(p);
+}
+
+
+/* 
+ * Returns alternative (map) x, given planchet  x in pixels
+ * No error checking - fast, for internal use. In case of error returns 0
+ *
+ */
+double Fgis_AltX(Tcl_Interp *interp,char *planchet,int x)
+{double X1,Y1,X2,Y2,result;
+ int width=Fgis_GetPlanchetWidth(interp,planchet);
+ if (!width||Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+   return 0.0;
+ result= (x*(X2-X1)/width+X1);
+ return result;
+}
+
+/* 
+ * Returns alternative (map) y, given planchet  y in pixels
+ * No error checking - fast, for internal use. In case of error returns 0
+ *
+ */
+double Fgis_AltY(Tcl_Interp *interp,char *planchet,int y)
+{double X1,Y1,X2,Y2,result;
+ int height=Fgis_GetPlanchetHeight(interp,planchet);
+ if (!height||Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)
+       ==TCL_ERROR)
+   return 0.0;
+ result= ((height-y)*(Y2-Y1)/height+Y1);
+ return result;
+}
+
+/*
+ * Returns planchet x coordinate in pixels, given alternative (map) coordinate
+ */
+int Fgis_PlanchetX(Tcl_Interp *interp,char *planchet,double x)
+{double X1,Y1,X2,Y2;
+ if (Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+     return 0;
+ return floor((x-X1)/(X2-X1)*Fgis_GetPlanchetWidth(interp,planchet));
+}
+
+
+/*
+ * Returns planchet y coordinate in pixels, given alternative (map) coordinate
+ */
+int Fgis_PlanchetY(Tcl_Interp *interp,char *planchet,double y)
+{double X1,Y1,X2,Y2;
+ if (Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR) 
+  return 0;
+ return floor((y-Y2)/(Y1-Y2)*Fgis_GetPlanchetHeight(interp,planchet));
+}
+
+/*
+ * Tcl commands to deal with coordinates. These commands duplicates
+ * functionality of quick-and-dirty ones above, but adds more error-cheking
+ * and eliminates duplication in Tk data structures access
+ */
+
+/* 
+ * Tcl command fgisPlanchet_mapx implementation
+ */
+EXPORT (int, Fgis_MapX)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
+{ char result [255];
+  int x,width;
+  double X1,Y1,X2,Y2; 
+  Tk_Window p;
+  if (argc!=3) {
+     sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
+     Tcl_SetResult(interp,result,TCL_VOLATILE);
+     return TCL_ERROR;
+  } 
+  p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
+  if (!p) return TCL_ERROR;
+  if (Tk_GetPixels(interp,p,argv[2],&x)==TCL_ERROR) return TCL_ERROR;
+  if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+    return TCL_ERROR;
+  width=Tk_ReqWidth(p);
+  if (width==0) {
+      sprintf(result,"Planchet %s is not mapped",argv[1]);
+      Tcl_SetResult(interp,result,TCL_VOLATILE);
+      return TCL_ERROR;
+  }
+  Tcl_PrintDouble(interp,(x*(X2-X1)/width+X1),result);
+  Tcl_SetResult(interp,result,TCL_VOLATILE);
+  return TCL_OK; 
+}
+
+/* 
+ * Tcl command fgisPlanchet_mapy implementation
+ */
+EXPORT(int, Fgis_MapY)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
+{ char result [255];
+  int y,height;
+  double X1,Y1,X2,Y2; 
+  Tk_Window p;
+  if (argc!=3) {
+     sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
+     Tcl_SetResult(interp,result,TCL_VOLATILE);
+     return TCL_ERROR;
+  } 
+  p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
+  if (!p) return TCL_ERROR;
+  if (Tk_GetPixels(interp,p,argv[2],&y)==TCL_ERROR) return TCL_ERROR;
+  if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+    return TCL_ERROR;
+  height=Tk_ReqHeight(p);
+  if (height==0) {
+      sprintf(result,"Planchet %s is not mapped",argv[1]);
+      Tcl_SetResult(interp,result,TCL_VOLATILE);
+      return TCL_ERROR;
+  }
+  Tcl_PrintDouble(interp,((height-y)*(Y2-Y1)/height+Y1),result);
+  Tcl_SetResult(interp,result,TCL_VOLATILE);
+  return TCL_OK; 
+}
+
+/* 
+ * Tcl command fgisPlanchet_scrx implementation
+ */
+EXPORT(int, Fgis_ScrX)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
+{ char result [255];
+  int width;
+  double x,X1,Y1,X2,Y2; 
+  Tk_Window p;
+  if (argc!=3) {
+     sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
+     Tcl_SetResult(interp,result,TCL_VOLATILE);
+     return TCL_ERROR;
+  } 
+  p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
+  if (!p) return TCL_ERROR;
+  if (Tcl_GetDouble(interp,argv[2],&x)==TCL_ERROR) return TCL_ERROR;
+  if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+    return TCL_ERROR;
+  width=Tk_ReqWidth(p);
+  if (width==0) {
+      sprintf(result,"Planchet %s is not mapped",argv[1]);
+      Tcl_SetResult(interp,result,TCL_VOLATILE);
+      return TCL_ERROR;
+  }
+  sprintf(result,"%d",(int)floor((x-X1)/(X2-X1)*width));
+  Tcl_SetResult(interp,result,TCL_VOLATILE);
+  return TCL_OK; 
+}
+
+/* 
+ * Tcl command fgisPlanchet_scry implementation
+ */
+EXPORT(int, Fgis_ScrY)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
+{ char result [255];
+  int height;
+  double y,X1,Y1,X2,Y2; 
+  Tk_Window p;
+  if (argc!=3) {
+     sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
+     Tcl_SetResult(interp,result,TCL_VOLATILE);
+     return TCL_ERROR;
+  } 
+  p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
+  if (!p) return TCL_ERROR;
+  if (Tcl_GetDouble(interp,argv[2],&y)==TCL_ERROR) return TCL_ERROR;
+  if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+    return TCL_ERROR;
+  height=Tk_ReqHeight(p);
+  if (height==0) {
+      sprintf(result,"Planchet %s is not mapped",argv[1]);
+      Tcl_SetResult(interp,result,TCL_VOLATILE);
+      return TCL_ERROR;
+  }
+  sprintf(result,"%d",(int)floor((y-Y2)/(Y1-Y2)*height));
+  Tcl_SetResult(interp,result,TCL_VOLATILE);
+  return TCL_OK; 
+}
+
+EXPORT(int, Fgis_Fit)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
+{ char result [255];
+  double xrel,yrel,x,y,X1,Y1,X2,Y2; 
+  if (argc!=4) {
+     sprintf(result,"Wrong # args. Should be %s planchet x y",argv[0]);
+     Tcl_SetResult(interp,result,TCL_VOLATILE);
+     return TCL_ERROR;
+  } 
+  if (Tcl_GetDouble(interp,argv[2],&x)==TCL_ERROR) return TCL_ERROR;
+  if (Tcl_GetDouble(interp,argv[3],&y)==TCL_ERROR) return TCL_ERROR;
+  if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
+    return TCL_ERROR;
+  xrel=(x-X1)/(X2-X1);
+  yrel=(y-Y1)/(Y2-Y1);
+  if (yrel>0.0 && yrel<1.0 && xrel>0.0 && yrel<1.0)  
+     Tcl_SetResult(interp,"1",TCL_STATIC);
+  else
+     Tcl_SetResult(interp,"0",TCL_STATIC);
+  return TCL_OK; 
+}
+
+/*
+ * Checks if given window is really planchet and coordinate system
+ * is defined. returns 0 on failure, 1 on success
+ */
+
+int Fgis_ValidPlanchet(Tcl_Interp *interp,char *planchet)
+{ double a;
+    Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
+    if (!p) return 0;
+    if (Tk_GetUid("Canvas")!=Tk_Class(p)) {
+      Tcl_AppendResult(interp,planchet," is not Planchet window",NULL);
+      return 0;
+    }
+    if (Fgis_GetPlanchetLimits(interp,planchet,&a,&a,&a,&a)!=TCL_OK) {
+        Tcl_AppendResult(interp,planchet," has no coordinate system defined",
+               NULL);
+        return 0;
+    }
+    return 1;
+}    
+
diff --git a/dll/fgisProjection.c b/dll/fgisProjection.c
new file mode 100644 (file)
index 0000000..9407ecb
--- /dev/null
@@ -0,0 +1,25 @@
+#include <math.h>
+#include <tcl.h>
+#include "fgis.h"
+
+/*
+ * fgisProjection - definition for projection handling objects
+ * Copyright (c) SoftWeyr,1997
+ *
+ */
+
+
+EXPORT(int, Fgis_ProjectionObj)(ClientData data,Tcl_Interp *interp,int
+argc, char **argv) {
+ return TCL_ERROR;
+}
+
+EXPORT(void,Fgis_DeleteProjection)(ClientData data) {
+
+}
+
+EXPORT(int, Fgis_Projection)(ClientData data,Tcl_Interp *interp,int argc, char **argv)
+{
+ Tcl_SetResult(interp,"Projection objects not implemented",TCL_STATIC);
+ return TCL_ERROR;
+}
diff --git a/dll/fgisRaster.c b/dll/fgisRaster.c
new file mode 100644 (file)
index 0000000..ddd5215
--- /dev/null
@@ -0,0 +1,998 @@
+/* This is an implementation for EPP handling in fgis*/
+#include <stdlib.h>
+#include <tcl.h>
+#include <epp.h>
+#include <string.h>
+#include <strings.h>
+#include <reclass.h>
+#include <math.h>
+#include <eppl_ut.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include "fgis.h"
+#include "fgisInt.h"
+#include "fgisEppEdit.h"
+/*
+ * Declaration 
+ * 
+ */
+
+
+int Fgis_CreateNewRaster(ClientData data,Tcl_Interp *interp,
+     int argc,char **argv);
+
+
+typedef int (Fgis_CmdProc)(RASTER_OBJECT handle,Tcl_Interp *interp,
+                          int argc, char **argv); 
+Fgis_CmdProc  SaveRaster, ReturnBaseRaster,
+      ReturnCellValue, ReturnLimits, RasterComments, ChangeReclass,
+      ReturnRow, ReturnCol, DumpReclass, ReturnBPP, OffsiteValue,
+      XLeft, XRight, YTop, YBottom, 
+      ShiftCoords, ListClasses, CountClass, FindUnused, CalcExtents,
+      SetRasterCache, GetMinValue, GetMaxValue, CellUnit,
+      ModifyCell, PlotLine, PlotFrame, PlotBox, PlotContour, FillContour,
+      PlotCircle, ReturnCell, ReturnCellLimits, 
+      CountContour, CountTranssect;
+
+RECLASS Fgis_ListToReclass(Tcl_Interp *interp,char *list,RECLASS src,int size);
+RECLASS Fgis_ParseReclass(Tcl_Interp *interp,char *program,RECLASS src,int size);
+
+
+int DumpReclassToList(Tcl_Interp *interp,RECLASS reclass,int size);
+int DumpReclassToProgram(Tcl_Interp *interp,RASTER_OBJECT handle);
+/*
+ * Cleans up global data, used by raster objects. Probably, should also
+ * clean up all existing raster objects (?)
+ */
+
+EXPORT(void, Fgis_DeleteRaster)(ClientData table)
+{ 
+}
+/*
+ * parses standard raster options -reclass and -table.
+ * Returns pointer to reclass on success, NULL if option is not one of these 
+ * and FGIS_INVALID_RECLASS 
+ * if there was error parsing option argument.
+ */
+RECLASS Fgis_StdRasterOptions(Tcl_Interp *interp, int size, char **arg) 
+{ RECLASS table;
+   if (!strcmp(*arg,"-reclass")) {
+      table=Fgis_ParseReclass(interp,*(arg+1),create_reclass_table(size),size);
+   } else if (!strcmp(*arg,"-table")) {
+      table=Fgis_ListToReclass(interp,*(arg+1),create_reclass_table(size),size);
+   } else return NULL;
+   if (!table) 
+     return FGIS_INVALID_RECLASS;
+   else 
+     return table;
+}
+
+/*
+ * Implements raster Tcl command - various ways to create new raster object
+ * (deals itself with existing raster files and calls CreateNewRaster for new
+ * ones.
+ */
+
+EXPORT(int, Fgis_Raster)(ClientData data,Tcl_Interp *interp,
+                   int argc,
+                   char **argv)
+{ 
+ RASTER_OBJECT curfile;
+ XEPP* xptr;
+ int reclass_size;
+ EPP *(*openfunc)(char *)=open_epp;
+    if (Fgis_CkArgs(interp,argc<2,argv[0],"?mode? filename ?options?")) { 
+       return TCL_ERROR;
+    }
+    if (!strcmp(argv[1],"load")) {
+       argc--;
+       argv++;
+       openfunc=load_epp;
+    } else if (!strcmp(argv[1],"new")){
+       return Fgis_CreateNewRaster(data,interp,argc-2,argv+2);
+    }
+    if (Fgis_CkArgs(interp,argc!=2&&argc!=4,argv[0],"filename ?options?")) {
+      return TCL_ERROR;
+    }
+    /* Open file, or get pointer to existing one */
+    xptr=Fgis_OpenXEPP(argv[1],open_epp);   
+     if (!xptr) {
+        if (map_error==ME_NO_FILE||map_error==ME_CREATE_ERROR) {
+          Tcl_AppendResult(interp,"Cannot open ",argv[1],": ",
+                Tcl_PosixError(interp),NULL);
+        } else {
+          Tcl_AppendResult(interp,"Invalid epp file:",argv[1],NULL);
+        }
+        return TCL_ERROR;
+     }
+    /* Create reclass table with size of epp_max, if file is not loaded,
+       or 1<<kind if it is loaded. 8-bit files always have 
+       256-element reclass table, becouse some old software can
+       create epp files with non-correct max-min */
+     
+     if (xptr->editable) {
+       reclass_size=1<<(xptr->e->kind);
+     } else {
+       reclass_size=xptr->e->kind==8?256:epp_table_size(xptr->e);
+     }  
+      
+    /* Allocate new raster object */
+    curfile=malloc(sizeof(struct RASTER_OBJECT));
+    curfile->file=xptr;
+    if (argc>2) { 
+      /* If there is reclass option, parse it */ 
+      curfile->reclass=Fgis_StdRasterOptions(interp,reclass_size,argv+2);
+      if (!(curfile->reclass)||curfile->reclass==FGIS_INVALID_RECLASS) {
+          curfile->reclass=NULL;
+          Fgis_CloseXEPP(curfile->file);
+          return TCL_ERROR;
+      }
+    } else {
+      /* otherwise create empty reclass */
+      curfile->reclass=create_reclass_table(reclass_size);
+    }
+     curfile->next=firstobject;
+     firstobject=curfile; 
+     return Fgis_CreateObjectCommand(interp,"raster",Fgis_RasterObj,
+           (ClientData)curfile, Fgis_DeleteRasterObj);
+}
+     
+/*
+ * Creates new raster object. returns TCL_ERROR if file already exists
+ *
+ */
+
+EXPORT(int, Fgis_CreateNewRaster)(ClientData data,Tcl_Interp *interp,int argc,
+                         char **argv)
+{ struct stat BUF;
+  RECLASS table=NULL,t1;
+  int i,width=0,height=0,offsite=-1,explicit_limits=0;
+  EPP *e,*pattern=NULL;
+  XEPP *xptr;
+  double X1,Y1,X2,Y2;
+  RASTER_OBJECT object;
+  int bits=16;
+  char filename[1024];
+   strcpy(filename,argv[1]);   
+   /* checking file existence */
+    if (stat(filename,&BUF)||errno!=ENOENT) {
+       Tcl_AppendResult(interp,"File ",filename," already exists",NULL);
+        return TCL_ERROR;
+    }
+ /* Option parsing loop */
+    for(i=0;i<argc;i++) { 
+       if (!strcmp(argv[i],"-like")) { 
+           RASTER_OBJECT p;
+            if (!(p=Fgis_GetRaster(interp,argv[++i]))) 
+               return TCL_ERROR;
+            pattern=epp(p);
+       } else if (!strcmp(argv[i],"-width")) { 
+           if (Fgis_GetInt(interp,argc,argv,++i,0,32767,&width,"raster width")
+                  !=TCL_OK)
+               return TCL_ERROR; 
+       } else if (!strcmp(argv[i],"-height")) { 
+           if (Fgis_GetInt(interp,argc,argv,++i,0,32767,&height,
+                   "raster height")!=TCL_OK)
+               return TCL_ERROR;
+       } else if (!strcmp(argv[i],"-offsite")) { 
+           if (Fgis_GetInt(interp,argc,argv,++i,0,65535,&offsite,
+                   "offsite value")!=TCL_OK)
+               return TCL_ERROR;
+        } else if (!strcmp(argv[i],"-8bit")) {
+           bits=8;
+            if (table) {
+              table=realloc(table,256*sizeof(short));
+            }
+       } else if (!strcmp(argv[i],"-limits")) {
+           if (++i==argc) 
+                ERROR_MESSAGE("List of four reals expected",TCL_STATIC);
+           if (Fgis_GetLimits(interp,argv[i],&X1,&Y1,&X2,&Y2)==TCL_ERROR) 
+                return TCL_ERROR;
+            explicit_limits=1;
+        } else if ((t1=Fgis_StdRasterOptions(interp,1<<bits,argv+i))) {
+           if (table) {
+             Tcl_SetResult(interp, "Duplicate reclass specification", 
+                    TCL_STATIC);
+             free(table);
+             if (t1!=FGIS_INVALID_RECLASS) free(t1);
+             return TCL_ERROR;
+           }
+           if (t1==FGIS_INVALID_RECLASS) return TCL_ERROR;
+           table=t1;
+           i++;
+        } else {
+            if (table) free(table);
+            ERROR_MESSAGE("Wrong option. Must be one of -like -width"
+                 "-height -offsite -limits -8bit -reclass -table",TCL_STATIC);
+        }
+    }
+     Create16bit=bits==16;
+
+    if (bits==8&&offsite>255&&offsite!=65535)  {
+         if (table) free(table);
+        ERROR_MESSAGE("Invalid offsite for 8-bit file",TCL_STATIC);
+    }
+
+    if(offsite<0) {
+      if (bits==8) 
+           offsite=255; 
+       else 
+         offsite=65535;
+    }   
+    if (!pattern) {  
+       if (!width || !height) {
+            if (table) free(table);
+           ERROR_MESSAGE("Raster size is not specified",TCL_STATIC);
+        }
+       if (!explicit_limits||X1==X2||Y1==Y2) { 
+           X1=0;X2=width;Y1=height;Y2=0;
+       }
+       e=creat_epp(filename,1,1,width,height,X1,Y1,X2,Y2,100,0,offsite);
+       if (!e) {
+           if (table) free(table);
+           Tcl_AppendResult(interp,"Error creating file ",filename,":",
+             Tcl_PosixError(interp),NULL);
+           return TCL_ERROR;
+        } 
+    } else { 
+       if (width || height) {
+             if (table) free(table);
+           ERROR_MESSAGE("Raster size is specified twice",TCL_STATIC);
+        }
+       if (explicit_limits) {
+            if (table) free(table); 
+           ERROR_MESSAGE("Coordinate system is specified twice",TCL_STATIC);
+        }
+       e=creat_epp_as(filename,pattern);
+       if (!e) {
+           if (table) free(table);
+           Tcl_AppendResult(interp,"Error creating file ",filename,":",
+             Tcl_PosixError(interp),NULL);
+           return TCL_ERROR;
+        } 
+       e->offsite=offsite;
+    } 
+    /* Fill entire raster with offsite value */
+    /* And load it into memory to make editable */
+    load_new_epp(e);
+    /* Now create raster object around it */
+     xptr=Fgis_NewXEPP(e,filename);
+     xptr->editable=1;
+     object=malloc(sizeof (struct RASTER_OBJECT));
+     object->file=xptr;
+     if (!table) {
+        object->reclass=create_reclass_table(1<<e->kind);
+     } else {
+        object->reclass=table;
+     }
+     object->next=firstobject;
+     firstobject=object;
+     return  Fgis_CreateObjectCommand(interp,"raster",Fgis_RasterObj,
+          (ClientData)object, Fgis_DeleteRasterObj);
+}
+
+/*
+ * Fgis_GetRaster
+ * returns pointer to raster object, associated with tcl command
+ *
+ *
+ */
+EXPORT(RASTER_OBJECT, Fgis_GetRaster)(Tcl_Interp *interp, char *name)
+{
+    Tcl_CmdInfo info;char buffer[255]="Invalid palette: ";
+    if (!Tcl_GetCommandInfo(interp,name,&info)) return NULL;
+    if (info.proc!=&Fgis_RasterObj) {
+       strcat(buffer,name);
+       Tcl_SetResult(interp,name,TCL_VOLATILE);
+       return NULL;
+    }
+    return (RASTER_OBJECT)(info.clientData); 
+}
+
+
+/* 
+ *  
+ *  Fgis_DeleteRasterObj - deletes raster object, associated with
+ *  command. Called as Tcl_CmdDeleteProc, but not for base rasters.
+ *
+ */
+
+EXPORT(void, Fgis_DeleteRasterObj)(ClientData data)
+{ RASTER_OBJECT r=(RASTER_OBJECT)data;
+  RASTER_OBJECT prev;
+  /* Remove it from list */
+  if (firstobject==r) { 
+      firstobject=r->next;
+  } else {
+    for (prev=firstobject;prev->next!=r;prev=prev->next);
+    prev->next=r->next;
+  } 
+  Fgis_CloseXEPP(r->file);
+  free(r->reclass);
+  free(r);
+}  
+/*
+ * Fgis_RasterObj - implementation of object command for rasters.
+ * mostly calls some procedure according to first argument. But few commands,
+ * which returns info of object itself, rather then of raster or reclass,
+ * are inlined, as well as delete command.
+ */
+EXPORT(int, Fgis_RasterObj)(ClientData data,Tcl_Interp *interp, int argc, char **argv)
+{   
+    RASTER_OBJECT object=(RASTER_OBJECT)data;
+
+    if (Fgis_CkArgs(interp,argc<2,argv[0], " option ?args?"))
+       return TCL_ERROR;
+   
+    /* Checking for valid options*/
+    /* delete */
+    if (!strcmp(argv[1],"delete")) {
+       if (Fgis_CkArgs(interp,argc!=2,argv[0], "delete"))
+           return TCL_ERROR;
+       Tcl_DeleteCommand(interp,argv[0]);
+       return TCL_OK;
+     /* filename */
+    } else if (!strcmp(argv[1],"filename")) {
+      if (Fgis_CkArgs(interp,argc!=2,argv[0],
+            " filename"))
+         return TCL_ERROR;
+        RETURN(object->file->filename,TCL_VOLATILE);
+     /*load */
+    } else if (!strcmp(argv[1],"cell")) {
+        return ReturnCell(object,interp,argc,argv);
+    } else if (!strcmp(argv[1],"save")) {
+        return SaveRaster(object,interp,argc,argv);
+    } else if (!strcmp(argv[1],"bpp"))  {
+        return ReturnBPP(object,interp,argc,argv);
+    } else if (!strcmp(argv[1],"cache")) {
+        return SetRasterCache(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"get")) {
+       return ReturnCellValue(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"limits")) {
+       return ReturnLimits(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"comment")) {
+       return RasterComments(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"reclass")) {
+       return ChangeReclass(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"offsite")) {
+       return OffsiteValue(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"row")) {
+       return ReturnRow(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"col")) {
+       return ReturnCol(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"put")) {
+       return ModifyCell(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"line")) {
+       return PlotLine(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"frame")) {
+       return PlotFrame(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"box")) {
+       return PlotBox(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"fill")) {
+       return FillContour(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"circle")) {
+       return PlotCircle(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"classes")) {
+       return ListClasses(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"count")) {
+       return CountClass(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"unused")) {
+       return FindUnused(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"extents")) {
+       return CalcExtents(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"celllimits")) {
+       return ReturnCellLimits(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"xleft")) {
+       return XLeft(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"xright")) {
+       return XRight(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"ytop")) {
+       return YTop(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"ybottom")) {
+       return YBottom(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"shift")) {
+       return ShiftCoords(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"max")) {
+       return GetMaxValue(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"min")) {
+       return GetMinValue(object,interp,argc,argv);
+    }else if (!strcmp(argv[1],"unit")) {
+       return CellUnit(object,interp,argc,argv);
+    }else {
+       Tcl_SetResult(interp,"Invalid option. Should be one of "
+                   "box bpp cache circle classes col comment count delete "
+                   "extents filename fill first_row first_col frame get " 
+                    "limits line load max min " 
+                    "polygon put reclass row save shift transect unused unit"
+                    "xleft xright ybottom ytop",TCL_STATIC); 
+       return TCL_ERROR;
+    } 
+}
+int SaveRaster (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+  NOT_YET 
+
+
+int ReturnCellValue (RASTER_OBJECT data, Tcl_Interp *interp, int argc,
+   char **argv)
+{   char buffer[10]; 
+    EPP *e=data->file->e;
+    double X,Y;
+    int value;
+
+    if (Fgis_CkArgs(interp,(argc != 4&&!(argc==5&&!strcmp(argv[4],"-base"))),
+         argv[0],"get x y ?-base?")) return TCL_ERROR;
+    if (Tcl_GetDouble(interp,argv[2],&X)!=TCL_OK)
+        return TCL_ERROR;
+    if (Tcl_GetDouble(interp,argv[3],&Y)!=TCL_OK)
+        return TCL_ERROR;
+    value= epp_get(e,epp_col(e,X),epp_row(e,Y)); 
+    sprintf(buffer,"%d",argc!=5?data->reclass[value]:value);
+    RETURN(buffer,TCL_VOLATILE);  
+}
+
+int ReturnLimits (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    char buffer[255];
+    EPP *e=epp(data);
+
+    if (Fgis_CkArgs(interp,argc!=2,argv[0],"limits"))
+        return TCL_ERROR;
+    Tcl_PrintDouble(interp,e->XLeft,buffer);
+    Tcl_AppendElement(interp,buffer);
+    Tcl_PrintDouble(interp,e->YBottom,buffer);
+    Tcl_AppendElement(interp,buffer);
+    Tcl_PrintDouble(interp,e->XRight,buffer);
+    Tcl_AppendElement(interp,buffer);
+    Tcl_PrintDouble(interp,e->YTop,buffer);
+    Tcl_AppendElement(interp,buffer);
+    return TCL_OK;
+}
+int RasterComments (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+ EPP *e=epp(data);
+
+ switch (argc) {
+ case 3: /* set comment */
+        if (!data->file->editable)
+         ERROR_MESSAGE("Raster is read-only.",TCL_STATIC);
+        setcomment(e,argv[2]);
+         /* NO BREAK HERE */ 
+ case 2: /* return comment */
+        RETURN(getcomment(e),TCL_VOLATILE);
+ default:{
+          Tcl_AppendResult(interp,"Wrong #args. Should be ",
+                 argv[0], " comment ?string?",NULL);
+         return TCL_ERROR;
+        }
+ }
+} 
+int OffsiteValue (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{ 
+    EPP *e=epp(data);
+    char result[7];
+    int new_offsite;
+    
+    switch (argc) {
+    case 3: /*set new offsite value*/
+               if (!data->file->editable);
+                       ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+               if (Fgis_GetInt(interp,argc,argv,2,-1,
+                      (1<<e->kind)-1,&new_offsite,"offsite value")!=TCL_OK) 
+                  return TCL_ERROR;
+              if (new_offsite<0) new_offsite=65535;
+              e->offsite=new_offsite;
+             /* NO BREAK HERE!!*/
+   case 2: /* return offsite value */
+           sprintf(result,"%d",data->reclass[e->offsite]);
+           RETURN(result,TCL_VOLATILE);
+  default: Tcl_AppendResult(interp,
+            "Wrong # args. Should be ",argv[0]," offsite ?value?",NULL);
+          return TCL_ERROR;
+  }       
+}
+
+int CellUnit (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    EPP *e=epp(data);
+    static char *units[]={"undefined","ft","m","km","mile","ha","acre",NULL};
+    EPPHEADER h;
+
+    get_epp_header(e,&h);
+    if (h.area_unit>6) h.area_unit=0;
+    if (argc==3) { 
+       char **u;
+       if (!data->file->editable)
+          ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+       for(u=units;*u&&strcmp(*u,argv[2]);u++);
+       if (!*u) { 
+          Tcl_SetResult(interp,"Wrong area unit. should be one of: ",
+                    TCL_STATIC);
+          for(u=units;*u;u++)
+                Tcl_AppendResult(interp,*u," ",NULL);
+          return TCL_ERROR;
+       }
+       h.area_unit=u-units;
+       change_epp_header(e,h); 
+    } else if (Fgis_CkArgs(interp,argc!=2,argv[0],
+               " unit ?new-unit?")) {
+       return TCL_ERROR;
+    }  
+    RETURN(units[(int)h.area_unit],TCL_STATIC);
+}
+
+int GetMaxValue (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    char result[255];
+
+    if (Fgis_CkArgs(interp,argc!=2,argv[0],"max"))
+       return TCL_ERROR;
+    sprintf(result,"%d",Fgis_RasterMax(data));
+    RETURN(result,TCL_VOLATILE);
+}
+
+int GetMinValue (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    char result[255];
+
+    if (Fgis_CkArgs(interp,argc!=2,argv[0],"min"))
+       return TCL_ERROR;
+    sprintf(result,"%d",Fgis_RasterMin(data));
+    RETURN(result,TCL_VOLATILE);
+}
+
+int ReturnBPP (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    EPP *e=epp(data);
+    if (Fgis_CkArgs(interp,argc!=2,argv[0],"bpp"))
+       return TCL_ERROR;
+    RETURN(e->kind==8?"8":"16",TCL_STATIC);
+}
+
+int ReturnCell (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+  EPP *e=epp(data);
+  char result[32];
+  if (Fgis_CkArgs(interp,argc!=2&&!(argc==3&&!strcmp(argv[2],"-area")),argv[0],
+          "cell ?-area?"))
+       return TCL_ERROR;
+  if (argc==3) { 
+     Tcl_PrintDouble(interp,e->cell_area,result);
+  } else {
+     Tcl_PrintDouble(interp,fabs(e->XRight-e->XLeft)/(e->lc-e->fc),result);
+  } 
+  RETURN(result,TCL_VOLATILE);
+}
+int ReturnCellLimits (RASTER_OBJECT data, Tcl_Interp *interp,
+       int argc, char **argv)
+{
+  EPP *e=epp(data);
+  char result[7];
+  if (Fgis_CkArgs(interp,argc!=2,argv[0],"celllimits"))
+    return TCL_ERROR;
+  sprintf(result,"%d",e->fc);
+  Tcl_AppendElement(interp,result);
+  sprintf(result,"%d",e->lr-1);
+  Tcl_AppendElement(interp,result);
+  sprintf(result,"%d",e->lc-1);
+  Tcl_AppendElement(interp,result);
+  sprintf(result,"%d",e->fr);
+  Tcl_AppendElement(interp,result);
+  return TCL_OK;
+}
+
+int XLeft (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+   EPP *e=epp(data);
+   char result[64];
+   if (argc==3) {
+      EPPHEADER h;
+      double tmp;
+      if (!data->file->editable)
+          ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+      if (Tcl_GetDouble(interp,argv[2],&tmp)!=TCL_OK) 
+          return TCL_ERROR;
+      get_epp_header(e,&h);
+      h.fcx=tmp;
+      e->XLeft=tmp;
+      change_epp_header(e,h);
+   } else if (argc!=2) {
+     Tcl_AppendResult(interp,"Wrong # args. Should be", argv[0]," ",
+            argv[1]," ?value?", NULL);
+ }     
+ Tcl_PrintDouble(interp,e->XLeft,result);
+ RETURN(result,TCL_VOLATILE);
+} 
+int XRight (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+   EPP *e=epp(data);
+   char result[64];
+   if (argc==3) {
+      EPPHEADER h;
+      double tmp;
+      if (!data->file->editable)
+          ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+      if (Tcl_GetDouble(interp,argv[2],&tmp)!=TCL_OK) 
+          return TCL_ERROR;
+      get_epp_header(e,&h);
+      h.lcx=tmp;
+      e->XRight=tmp;
+      change_epp_header(e,h);
+   } else if (argc!=2) {
+     Tcl_AppendResult(interp,"Wrong # args. Should be", argv[0]," ",
+            argv[1]," ?value?", NULL);
+ }     
+ Tcl_PrintDouble(interp,e->XRight,result);
+ RETURN(result,TCL_VOLATILE);
+} 
+int YTop (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+   EPP *e=epp(data);
+   char result[64];
+   if (argc==3) {
+      EPPHEADER h;
+      double tmp;
+      if (!data->file->editable)
+          ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+      if (Tcl_GetDouble(interp,argv[2],&tmp)!=TCL_OK) 
+          return TCL_ERROR;
+      get_epp_header(e,&h);
+      h.fry=tmp;
+      e->YTop=tmp;
+      change_epp_header(e,h);
+   } else if (argc!=2) {
+     Tcl_AppendResult(interp,"Wrong # args. Should be", argv[0]," ",
+            argv[1]," ?value?", NULL);
+ }     
+ Tcl_PrintDouble(interp,e->YTop,result);
+ RETURN(result,TCL_VOLATILE);
+} 
+int YBottom (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+   EPP *e=epp(data);
+   char result[64];
+   if (argc==3) {
+      EPPHEADER h;
+      double tmp;
+      if (!data->file->editable)
+          ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+      if (Tcl_GetDouble(interp,argv[2],&tmp)!=TCL_OK) 
+          return TCL_ERROR;
+      get_epp_header(e,&h);
+      h.lry=tmp;
+      e->YBottom=tmp;
+      change_epp_header(e,h);
+   } else if (argc!=2) {
+     Tcl_AppendResult(interp,"Wrong # args. Should be", argv[0]," ",
+            argv[1]," ?value?", NULL);
+ }     
+ Tcl_PrintDouble(interp,e->YBottom,result);
+ RETURN(result,TCL_VOLATILE);
+} 
+
+int ShiftCoords (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    EPP *e=epp(data);
+    EPPHEADER h;
+    double dx,dy;
+    if (Fgis_CkArgs(interp,argc!=4,argv[0], "shift dx dy")) {
+      return TCL_ERROR;
+    }  
+    
+    if (!data->file->editable)
+       ERROR_MESSAGE("Raster is read-only",TCL_STATIC);
+    if (Tcl_GetDouble(interp,argv[2],&dx)!=TCL_OK)
+       return TCL_ERROR;
+    if (Tcl_GetDouble(interp,argv[3],&dy)!=TCL_OK)
+       return TCL_ERROR;
+    get_epp_header(e,&h);
+    h.fcx=e->XLeft+=dx;
+    h.lcx=e->XRight+=dx;
+    h.fry=e->YTop+=dy;
+    h.lry=e->YBottom+=dy;
+    change_epp_header(e,h);
+    return TCL_OK;
+}  
+
+int ChangeReclass(RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    RECLASS tmp;
+    EPP *e=epp(data);
+    if (argc==2) 
+      return DumpReclassToList(interp,data->reclass,epp_table_size(e));
+    if (!strcmp(argv[2],"-table")) { 
+        if (Fgis_CkArgs(interp,(argc!=4), argv[0],"reclass -table list")) {
+           return TCL_ERROR;
+        }
+       tmp=Fgis_ListToReclass(interp,argv[3],data->reclass,
+               epp_table_size(e));
+    } else
+    if (!strcmp(argv[2],"-statements")) { 
+       if (Fgis_CkArgs(interp,argc!=3, argv[0], "reclass -statements")) {
+            return TCL_ERROR;
+        }          
+       return DumpReclassToProgram(interp,data);
+    } else { 
+       if (Fgis_CkArgs(interp,argc!=3, argv[0], " reclass ?option? arg")) {
+            return TCL_ERROR;
+        }          
+       tmp=Fgis_ParseReclass(interp,argv[2],data->reclass,epp_table_size(e));
+    }
+    if(!tmp) return TCL_ERROR; 
+    free(data->reclass);
+    data->reclass=tmp;
+    return TCL_OK;
+}
+
+int ReturnRow (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    EPP *e=epp(data);
+    char result[7];
+    int row;
+    double Y;
+    if (Fgis_CkArgs(interp,argc != 3, argv[0],"row y")) {
+       return TCL_ERROR;
+    }
+    if (Tcl_GetDouble(interp,argv[2],&Y)!=TCL_OK) return TCL_ERROR;
+    row=epp_row(e,Y);
+    if (row<e->fr||row>=e->lr) 
+       ERROR_MESSAGE("Y coordinate outside file boundaries",TCL_STATIC);
+    sprintf(result,"%d",row);
+    RETURN(result,TCL_VOLATILE);
+}
+int ReturnCol (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    EPP *e=epp(data);
+    char result[7];
+    int col;
+    double X;
+    if (Fgis_CkArgs(interp,argc != 3,argv[0],"col x")) {
+       return TCL_ERROR;
+    }
+    if (Tcl_GetDouble(interp,argv[2],&X)!=TCL_OK) return TCL_ERROR;
+    col=epp_col(e,X);
+    if (col<e->fc||col>=e->lc) 
+       ERROR_MESSAGE("X coordinate outside file boundaries",TCL_STATIC);
+    sprintf(result,"%d",col);
+    RETURN(result,TCL_VOLATILE);
+}
+
+int SetRasterCache (RASTER_OBJECT data, Tcl_Interp *interp, int argc, 
+    char **argv)
+{ 
+EPP *e=epp(data);
+char result[7];
+
+if (Fgis_CkArgs(interp,argc>3,argv[0],"cache ?cache-size?")) {
+   return TCL_ERROR;
+}   
+if (argc==2) {
+    if (e->mode&MAP_LOADED) 
+      RETURN("loaded",TCL_STATIC);
+   /* Otherwise cache size would be returned, as it is done after change */   
+} else { 
+   int newsize;
+   if (e->mode&MAP_LOADED) {
+      Tcl_AppendResult(interp,argv[0]," already loaded into memory",NULL);
+      return TCL_ERROR;
+   }
+   if (Fgis_GetInt(interp,argc,argv,2,-1,CACHE_THRESHOLD/
+           (e->width*(e->kind>>3)),
+           &newsize,"cache size")!=TCL_OK) return TCL_ERROR;
+   set_epp_cache(e,newsize);
+}
+sprintf(result,"%d",e->cache_size); 
+RETURN(result,TCL_VOLATILE);
+}
+/*
+# $raster put value x y 
+# modifies raster (if modifiable). Value should be specified in
+# terms of base raster, not of current raster object.
+#
+*/
+int ModifyCell (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{ EPP *e=epp(data);
+  int row,col,value;
+  double X,Y;
+  if (Fgis_CkArgs(interp,argc!=5,argv[0]," put value x y")) {
+    return TCL_ERROR;
+  }
+  if (!(e->mode&MAP_LOADED)) {
+     Tcl_AppendResult(interp,"Raster \"",argv[0],"\" is read-only",NULL);
+     return TCL_ERROR;
+  }
+  if (Tcl_GetInt(interp,argv[2],&value)==TCL_ERROR) {
+     return TCL_ERROR;
+  }
+  if (Tcl_GetDouble(interp,argv[3],&X)==TCL_ERROR) {
+     return TCL_ERROR;
+  }
+  if (Tcl_GetDouble(interp,argv[4],&Y)==TCL_ERROR) {
+     return TCL_ERROR;
+  }
+  if (value<0||value>=MAX_EPP_CLASS) {
+    Tcl_AppendResult(interp,"Value ",argv[2]," is out of range",NULL);
+    return TCL_ERROR;
+  }
+  row=epp_row(e,Y);
+  col=epp_col(e,X);
+  if (row<e->fr||row>=e->lr||col<e->fc||col>=e->lc) {
+    Tcl_AppendResult(interp,"Point ",argv[3],",",argv[4]," is out of physical"
+           " boundaries of file", NULL);
+    return TCL_ERROR;
+  }
+  /* If we have value, which does't fit to 8 */
+  if (value>=(1<<e->kind)) {
+     Tcl_AppendResult(interp,"Value ",argv[2]," doesn't fit into raster ",
+           argv[0],NULL);
+     return TCL_ERROR;
+  }
+  epp_put(e,col,row,value);
+  return TCL_OK;  
+}
+int PlotLine (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+    NOT_YET
+int PlotFrame (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+    NOT_YET
+int PlotBox (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+    NOT_YET
+int FillContour (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+   NOT_YET
+int PlotCircle (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+   NOT_YET
+
+int ListClasses (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+{
+    int value,i;
+    char result[7];
+    EPP *e=epp(data);
+    if( Fgis_CkArgs(interp,argc!=3,argv[0]," classes value")) {
+       return TCL_ERROR;
+    }   
+    if (Fgis_GetInt(interp,argc,argv,2,0,65535,&value,"cell value")!=TCL_OK)
+        return TCL_ERROR;
+    
+    for(i=e->min;i<=e->max;i++)
+       if ((i!=e->offsite)&&(data->reclass[i]==value)) { 
+           sprintf(result,"%d",i);
+           Tcl_AppendElement(interp,result);
+        }
+    return TCL_OK; 
+}
+int CountClass (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+  NOT_YET
+int FindUnused (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+  NOT_YET
+int CalcExtents (RASTER_OBJECT data, Tcl_Interp *interp, int argc, char **argv)
+   NOT_YET
+
+#define LIST_ERROR(msg,mode) { Tcl_Free((char *)listv);free(table);\
+                Tcl_SetResult(interp,msg,mode);\
+                return NULL;}
+      
+RECLASS Fgis_ListToReclass(Tcl_Interp *interp,char *list,RECLASS src,int size)
+{ 
+    int listc,i,index,value;
+    char **listv;
+    RECLASS table;
+
+    if (Tcl_SplitList(interp,list,&listc,&listv)!=TCL_OK)
+       return NULL;
+    table=memcpy(malloc((size+1)*sizeof(short int)),
+           src,
+           (size+1)*sizeof(short int));
+
+    for(i=0;i<listc;i++) { 
+       int pairc; char **pairv;
+       if (Tcl_SplitList(interp,listv[i],&pairc,&pairv)!=TCL_OK||pairc!=2)
+           LIST_ERROR("Each element of list shold be pair of integers",
+                   TCL_STATIC);
+       if (Tcl_GetInt(interp,pairv[0],&index)!=TCL_OK||
+               Tcl_GetInt(interp,pairv[1],&value)!=TCL_OK)
+           LIST_ERROR("Integer value expected",TCL_STATIC);
+       if (index<=size&&index>=0) 
+           table[index]=value; 
+    }
+    return table;
+}
+
+unsigned char *reclass_program;
+
+static int get_prog_char()
+{ 
+    return *(reclass_program++);
+}
+
+RECLASS Fgis_ParseReclass(Tcl_Interp *interp,char *program,RECLASS src,int size)
+{  
+    RECLASS table;
+    reclass_program = (unsigned char *) program;
+    table=memcpy(malloc((size+1)*sizeof(short int)),
+           src,
+           (size+1)*sizeof(short int));
+    table = parse_statements(size,table, get_prog_char);
+    if (!table) {
+       Tcl_SetResult (interp, "Error in reclass statements", TCL_STATIC);
+    }
+    return table;
+}
+
+
+
+int DumpReclassToList(Tcl_Interp *interp,RECLASS reclass,int size)
+{ 
+    int i;
+    char result[15];
+
+    for (i=0;i<=size;i++) { 
+       if (reclass[i]!=i) { 
+           sprintf(result,"%d %d",i,reclass[i]);
+           Tcl_AppendElement(interp,result);
+       }
+    }
+    return TCL_OK;
+}
+struct STATEMENT {int newclass;
+                  char *list;
+                  int lastclass;
+                  int rangestart;
+                 }; 
+
+char *addtostring(char *source,char separator,int class)
+{
+    char tmp[10];
+    sprintf(tmp,"%c%d",separator,class);
+    if(!source) 
+       return strcpy(malloc(strlen(tmp)+1),tmp);
+    else 
+       return strcat(realloc(source,strlen(source)+strlen(tmp)+1),tmp);
+
+}
+
+void add_class(struct STATEMENT *stmt,int class)
+{
+    if (!(stmt->list)) {
+        stmt->list=addtostring(NULL,'=',class);
+        stmt->rangestart=stmt->lastclass=class;
+    } else
+    if ((stmt->lastclass==class-1)||
+           ((class==stmt->newclass+1)&&(stmt->lastclass==class-2))) {
+        stmt->lastclass=class;
+    } else { 
+        if (stmt->lastclass!=stmt->rangestart)
+           stmt->list=addtostring(stmt->list,':',stmt->lastclass);
+        stmt->list=addtostring(stmt->list,' ',class);
+        stmt->rangestart=stmt->lastclass=class;
+    }
+}
+int DumpReclassToProgram(Tcl_Interp *interp,RASTER_OBJECT data)
+{
+    int max=Fgis_RasterMax(data)+1,i;
+    struct STATEMENT *p,*cur;
+    EPP *e=epp(data);
+    RECLASS r=data->reclass;
+    p=malloc(max*sizeof(struct STATEMENT));
+    memset(p,0,max*sizeof(struct STATEMENT));
+    for(i=0;i<max;i++)p[i].newclass=i;
+    for(i=0;i<=e->max;i++) { 
+       if(i!=e->offsite&&r[i]!=i)
+           add_class(p+r[i],i);
+    }
+    for(i=0,cur=p;i<max;i++,cur++) {
+       if (cur->list) {
+           char n[7];
+           if (cur->lastclass!=cur->rangestart)
+               cur->list=addtostring(cur->list,':',cur->lastclass);
+           sprintf(n,"%d",cur->newclass);
+           Tcl_AppendResult(interp,n,cur->list,"\n",NULL);
+           free(cur->list);
+       }
+    }   
+    free(p);
+    return TCL_OK;
+}
diff --git a/dll/fgisVector.c b/dll/fgisVector.c
new file mode 100644 (file)
index 0000000..c49791c
--- /dev/null
@@ -0,0 +1,12 @@
+
+/* This is an implementation for DGT handling in EP tcl*/
+#include <stdlib.h>
+#include <tcl.h>
+#include <epp.h>
+#include "fgis.h"
+
+EXPORT(int, Fgis_Vector)(ClientData data,Tcl_Interp *interp,int argc, char **argv)
+{
+  Tcl_SetResult(interp,"Vector objects not implemented",TCL_STATIC);
+  return TCL_ERROR;
+}
diff --git a/dll/patterns.n b/dll/patterns.n
new file mode 100644 (file)
index 0000000..34870f3
--- /dev/null
@@ -0,0 +1,13 @@
+
+patterns set - ÓÏÚÄÁÔØ ÎÁÂÏÒ ÛÔÒÉÈÏ×ÏË ÉÚ ÓÔÒÏËÉ
+patterns read - ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ÛÔÒÉÈÏ×ÏË
+
+patternName print  - ×ÙÄÁÔØ ÎÁÂÏÒ ÛÔÒÉÈÏ×ÏË × ×ÉÄÅ, ÐÒÉÅÍÌÅÍÏÍ ÄÌÑ patterns set
+patternName get index ?-width n? ?-height n? ?frame -boolean? - ×ÏÚ×ÒÁÝÁÅÔ 
+ÚÁÄÁÎÎÕÀ ÛÔÒÉÈÏ×ËÕ ËÁË xbm. ðÏ ÕÍÏÌÞÁÎÉÀ Ó ÒÏÄÎÙÍ ÒÁÚÍÅÒÏÍ ÛÔÒÉÈÏ×ËÉ. åÓÌÉ ÚÁÄÁÎÙ width É height,
+ ÐÒÑÍÏÕÇÏÌØÎÉË ÕËÁÚÁÎÎÏÇÏ ÒÁÚÍÅÒÁ.
+patternName set index string
+  ÉÚÍÅÎÑÅÔ ÕËÁÚÁÎÎÕÀ ÛÔÒÉÈÏ×ËÕ. string ÓÏÄÅÒÖÉÔ ÄÁÎÎÙÅ × xbm ÆÏÒÍÁÔÅ
+  ÐÒÁ×ÉÌØÎÏÇÏ ÒÁÚÍÅÒÁ
+
+
diff --git a/doc/.log b/doc/.log
new file mode 100644 (file)
index 0000000..eceff34
--- /dev/null
+++ b/doc/.log
@@ -0,0 +1,40 @@
+This is TeX, Version 3.14159 (C version 6.1) (format=latex 96.11.10)  29 JAN 1998 13:46
+**epu_doc
+(/usr/lib/texmf/texmf/tex/latex/tools/.tex
+! Interruption.
+l.1 
+    %%
+? 
+LaTeX2e <1996/06/01>
+File ignored)
+*\bye
+! Undefined control sequence.
+<*> \bye
+        
+? 
+
+*\end
+! Interruption.
+<*> 
+    \end
+? 
+
+*\end
+! TeX capacity exceeded, sorry [parameter stack size=60].
+\end #1->
+         \csname end#1\endcsname \@checkend {#1}\expandafter \endgroup \if@e...
+<*> \end
+        
+If you really absolutely need more capacity,
+you can ask a wizard to enlarge me.
+
+Here is how much of TeX's memory you used:
+ 4 strings out of 10942
+ 52 string characters out of 72781
+ 40742 words of memory out of 262141
+ 2948 multiletter control sequences out of 9500
+ 3640 words of font info for 14 fonts, out of 150000 for 255
+ 14 hyphenation exceptions out of 607
+ 60i,0n,61p,82b,7s stack positions out of 300i,40n,60p,3000b,4000s
+No pages of output.
diff --git a/doc/3rd.attempt b/doc/3rd.attempt
new file mode 100644 (file)
index 0000000..0258900
--- /dev/null
@@ -0,0 +1,282 @@
+
+÷ ÄÁÎÎÏÍ ÔÅËÓÔÅ ÐÒÅÄÌÁÇÁÅÔÓÑ ÎÏ×ÙÊ ÐÏÄÈÏÄ Ë ÐÒÅÄÓÔÁ×ÌÅÎÉÀ 
+ÐÒÏÓÔÒÁÎÓÔ×ÅÎÎÏÊ ÉÎÆÏÒÍÁÃÉÉ. ïΠÎÅ ÓÏ×ÓÅÍ ÎÏ×ÙÊ. íÎÏÇÉÅ ÓÕÝÅÓÔ×ÕÀÝÉÅ
+çéó, ÏÓÏÂÅÎÎÏ ÏÒÉÅÎÔÉÒÏ×ÁÎÎÙÅ ÎÁ ÏÂÒÁÂÏÔËÕ ÓÎÉÍËÏ×, ÎÅÑ×ÎÏ ÉÓÐÏÌØÚÕÀÔ
+ÅÇÏ. îÏ ÎÉËÔÏ ÅÝÅ ÎÅ ÐÙÔÁÌÓÑ × Ñ×ÎÏÍ ×ÉÄÅ ÓÆÏÒÍÕÌÉÒÏ×ÁÔØ ÅÇÏ É ÐÏËÁÚÁÔØ
+ÅÇÏ ÄÏÓÔÁÔÏÞÎÏÓÔØ ÄÌÑ ÂÏÌØÛÉÎÓÔ×Á çéó-ÚÁÄÁÞ.
+
+1. ïÐÒÅÄÅÌÅÎÉÅ
+  îÁÚÏ×ÅÍ ËÁÒÔÏÊ ÆÕÎËÃÉÀ ÏÔ ËÏÏÒÄÉÎÁÔ, ÏÐÒÅÄÅÌÅÎÎÕÀ ÎÁ ÎÅËÏÔÏÒÏÍ
+  ÐÏÄÍÎÏÖÅÓÔ×Å ÐÏ×ÅÒÈÎÏÓÔÉ ÚÅÍÎÏÇÏ ÛÁÒÁ É ÐÒÉÎÉÍÁÀÝÕÀ ÌÉÂÏ ÞÉÓÌÏ×ÙÅ
+  (×ÅÝÅÓÔ×ÅÎÎÙÅ) ÚÎÁÞÅÎÉÑ, ÌÉÂÏ ÚÎÁÞÅÎÉÑ ÉÚ ËÁËÏÇÏ-ÔÏ ËÏÎÅÞÎÏÇÏ ÍÎÏÖÅÓÔ×Á.
+
+  ðÏÞÅÍÕ ÜÔÏÇÏ ÄÏÓÔÁÔÏÞÎÏ?
+  1. ïÂÌÁÓÔØ ÏÐÒÅÄÅÌÅÎÉÑ ÍÏÖÅÔ ÂÙÔØ ÌÉÂÏ ÎÅÐÒÅÒÙ×ÎÙÍ ÕÞÁÓÔËÏÍ ÔÅÒÒÉÔÏÒÉÉ,
+    ÅÓÌÉ ÎÁÓ ÉÎÔÅÒÅÓÕÅÔ ÆÅÎÏÍÅÎ, ÉÍÅÀÝÉÊ ÐÌÏÝÁÄÎÕÀ ÐÒÉÒÏÄÕ,
+    ÌÉÂÏ ÍÎÏÖÅÓÔ×ÏÍ ÌÉÎÉÊ (ÄÏÒÏÖÎÁÑ ÓÅÔØ, ÒÅÞÎÁÑ ÓÅÔØ), ÌÉÂÏ ËÏÎÅÞÎÙÍ 
+ÍÎÏÖÅÓÔ×ÏÍ ÉÚÏÌÉÒÏ×ÁÎÎÙÈ ÔÏÞÅË (ÎÁÓÅÌÅÎÎÙÅ ÐÕÎËÔÙ, ÔÏÞËÉ ÏÐÒÏÂÏ×ÁÎÉÑ).
+
+   ïÞÅ×ÉÄÎÏ, ÞÔÏ ×ÓÅ ÓÕÝÅÓÔ×ÕÀÝÉÅ ÓÐÏÓÏÂÙ ËÁÒÔÏÇÒÁÆÉÞÅÓËÏÇÏ ÉÚÏÂÒÁÖÅÎÉÑ
+   ÐÏÚ×ÏÌÑÀÔ ÉÚÏÂÒÁÚÉÔØ ÏÂßÅËÔÙ, ÏÔÎÏÓÑÝÉÅÓÑ Ë ÏÄÎÏÊ ÉÚ ÔÒÅÈ ÜÔÉÈ ÇÒÕÐÐ.
+
+  2. ìÀÂÏÊ ÐÁÒÁÍÅÔÒ, ËÏÔÏÒÙÊ ÍÙ ÍÏÖÅÍ ÉÚÏÂÒÁÚÉÔØ  ÎÁ ËÁÒÔÅ, ÌÉÂÏ 
+   ËÏÌÉÞÅÓÔ×ÅÎÎÙÊ, ÌÉÂÏ ËÁËÉÍ-ÔÏ ÏÂÒÁÚÏÍ ËÌÁÓÓÉÆÉÃÉÒÏ×ÁÎ. åÓÌÉ ÍÙ ÒÁÓÓÍÏÔÒÉÍ
+   ËÌÁÓÓÉÆÉËÁÃÉÀ ËÁË ËÏÎÅÞÎÏÅ ÍÎÏÖÅÓÔ×Ï ËÌÁÓÓÏ×, ÔÏ ÓÔÁÎÅÔ ÏÞÅ×ÉÄÎÏ, ÞÔÏ
+   ×ÓÅ ËÁÒÔÙ ËÁÞÅÓÔ×ÅÎÎÙÈ ÐÒÉÚÎÁËÏ× (ÐÏÞ×ÅÎÎÙÅ, ÒÁÓÔÉÔÅÌØÎÙÅ É ÄÁÖÅ ÁÄÍÉÎÉÓÔÒÁ-
+   ÔÉ×ÎÏÅ ÒÁÊÏÎÉÒÏ×ÁÎÉÅ) ÐÏÐÁÄÁÀÔ ÐÏÄ ÎÁÛÅ ÏÐÒÅÄÅÌÅÎÉÅ.
+
+åÄÉÎÓÔ×ÅÎÎÏÅ × ÎÁÛÅÍ ÏÐÒÅÄÅÌÅÎÉÉ, ÞÔÏ ÍÏÖÅÔ ×ÏÚÍÕÔÉÔØ ÞÅÌÏ×ÅËÁ, ÐÒÉ×ÙËÛÅÇÏ
+ÒÁÂÏÔÁÔØ Ó ÂÕÍÁÖÎÙÍÉ ËÁÒÔÁÍÉ, ÜÔÏ ÔÏ, ÞÔÏ ÍÙ ÐÏÚ×ÏÌÑÅÍ ËÁÒÔÅ ÉÚÏÂÒÁÖÁÔØ ÔÏÌØËÏ
+ÏÄÉΠÐÏËÁÚÁÔÅÌØ, × ÔÏ ×ÒÅÍÑ ËÁË ÎÁ ÂÕÍÁÖÎÙÈ ËÁÒÔÁÈ ÏÂÙÞÎÏ ÏÄÎÏ×ÒÅÍÅÎÎÏ
+ÉÚÏÂÒÁÖÁÅÔÓÑ ÎÅÓËÏÌØËÏ ÔÅÍÁÔÉÞÅÓËÉ ÓÈÏÄÎÙÈ ÐÏËÁÚÁÔÅÌÅÊ, ÎÅ ÓÞÉÔÁÑ 
+ÏÂÝÅÇÅÏÇÒÁÆÉÞÅÓËÏÊ ÓÉÔÕÁÃÉÉ. 
+
+íÙ ÎÁÍÅÒÅÎÎÏ ÉÄÅÍ ÎÁ ÜÔÏ ÏÇÒÁÎÉÞÅÎÉÅ, ÐÏÓËÏÌØËÕ ÏÎÏ ÏÂÌÅÇÞÁÅÔ ÄÁÌØÎÅÊÛÕÀ
+ÒÁÂÏÔÕ Ó ËÁÒÔÁÍÉ. òÁÚÄÅÌÉ× ËÁÖÄÕÀ ÉÓÈÏÄÎÕÀ ËÁÒÔÕ ÎÁ ÎÅÓËÏÌØËÏ ÓÌÏÅ×,
+ËÁÖÄÙÊ ÉÚ ËÏÔÏÒÙÈ ÏÔ×ÅÞÁÅÔ ÔÏÌØËÏ ÚÁ ÏÄÉΠÐÏËÁÚÁÔÅÌØ, ÍÙ ÐÏÌÕÞÁÅÍ ÐÏÌÎÕÀ
+Ó×ÏÂÏÄÕ ÐÒÉ ÐÏÓÔÒÏÅÎÉÉ ÐÒÏÉÚ×ÏÄÎÙÈ ËÁÒÔ. íÙ ÍÏÖÅÍ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÒÉ 
+ÁÎÁÌÉÚÅ ÌÀÂÙÅ ÐÏËÁÚÁÔÅÌÉ, ÎÅ ÏÂÒÁÝÁÑ ×ÎÉÍÁÎÉÅ ÎÁ ÔÏ, ËÁËÉÍ ÐÕÔÅÍ 
+ÜÔÁ ÉÎÆÏÒÍÁÃÉÑ ÐÏÌÕÞÅÎÁ. ÷ÓÅ ËÁÒÔÙ Õ ÎÁÓ ÎÅÚÁ×ÉÓÉÍÙ É ÒÁ×ÎÏÐÒÁ×ÎÙ.
+
+2. ôÏÞÎÏÓÔØ ËÁÒÔÙ.
+
+ìÀÂÁÑ ÉÎÆÏÒÍÁÃÉÑ Ï ÒÅÁÌØÎÏ ÓÕÝÅÓÔ×ÕÀÝÉÈ ÏÂßÅËÔÁÈ ÉÍÅÅÔ ÏÇÒÁÎÉÞÅÎÎÕÀ ÔÏÞÎÏÓÔØ.
+ðÏÜÔÏÍÕ ÎÕÖÎÏ ××ÅÓÔÉ ÓÐÏÓÏ ÏÃÅÎËÉ ÔÏÞÎÏÓÔÉ ËÁÒÔ. 
+õ ÐÒÏÂÌÅÍÙ ÔÏÞÎÏÓÔÉ ËÁÒÔÙ ÅÓÔØ Ä×Å ÓÔÏÒÏÎÙ:
+ 1. ôÏÞÎÏÓÔØ ÏÐÒÅÄÅÌÅÎÉÑ ËÏÏÒÄÉÎÁÔ
+ 2. ôÏÞÎÏÓÔØ ÉÎÆÏÒÍÁÃÉÉ Ï ÚÎÁÞÅÎÉÉ ËÁÒÔÙ.
+
+ôÏÞÎÏÓÔØ ÏÐÒÅÄÅÌÅÎÉÑ ËÏÏÒÄÉÎÁÔ ÜË×É×ÁÌÅÎÔÎÁ ÔÏÞÎÏÓÔÉ ÐÒÏ×ÅÄÅÎÉÑ
+ËÏÎÔÕÒÏ× ÉÓÈÏÄÎÏÊ ËÁÒÔÙ É ÏÂÙÞÎÏ ÎÅ ÐÒÅ×ÙÛÁÅÔ 1-2 ÍÍ × ÍÁÓÛÔÁÂÅ ÉÓÈÏÄÎÏÊ
+ËÁÒÔÙ. ïÐÒÅÄÅÌÅÎÎÙÅ ÐÏÇÒÅÛÎÏÓÔÉ ×ÎÏÓÉÔ É ××ÏÄ ËÁÒÔ × ÍÁÛÉÎÕ, ÎÏ ÏÎÉ
+ÏÂÙÞÎÏ ÎÁ ÐÏÒÑÄÏË ÍÅÎØÛÅ.
+
+÷ ËÁÞÅÓÔ×Å ÏÃÅÎËÉ ËÏÏÒÄÉÎÁÔÎÏÊ ÔÏÞÎÏÓÔÉ ËÁÒÔÙ ÍÙ ÂÕÄÅÍ ÉÓÐÏÌØÚÏ×ÁÔØ
+ÐÒÏÓÔÒÁÎÓÔ×ÅÎÎÏÅ ÒÁÚÒÅÛÅÎÉÅ. üÔÏ ÍÉÎÉÍÁÌØÎÏÅ ÒÁÓÓÔÏÑÎÉÅ ÍÅÖÄÕ ÔÏÞËÁÍÉ
+× ËÏÔÏÒÙÈ ËÁÒÔÁ ÍÏÖÅÔ ÉÍÅÔØ ÒÁÚÌÉÞÎÙÅ ÚÎÁÞÅÎÉÅ. ôÅ ËÏÍÕ ÐÒÉÈÏÄÉÌÏÓØ
+ÒÁÂÏÔÁÔØ Ó ÏÔÓËÁÎÉÒÏ×ÁÎÎÙÍÉ ÉÚÏÂÒÁÖÅÎÉÑÍÉ ÓÒÁÚÕ ÚÁÍÅÔÑÔ ÓÈÏÄÓÔ×Ï 
+ÜÔÏÇÏ ÐÏÎÑÔÉÑ Ó ÒÁÚÒÅÛÅÎÉÅÍ ÒÁÓÔÒÏ×ÏÇÏ ÉÚÏÂÒÁÖÅÎÉÑ. üÔÏ ÄÅÊÔÓ×ÉÔÅÌØÎÏ
+ÏÄÎÏ É ÔÏ ÖÅ ÐÏÎÑÔÉÅ, ÐÏÓËÏÌØËÕ ÄÌÑ ÈÒÁÎÅÎÉÑ ËÁÒÔ ÉÓÐÏÌØÚÕÅÔÓÑ ÒÁÓÔÒÏ×ÙÊ
+ÆÏÒÍÁÔ.
+
+þÔÏ ËÁÓÁÅÔÓÑ ÔÏÞÎÏÓÔÉ ÚÎÁÞÎÅÎÉÊ, ÔÏ ÔÕÔ ×ÏÐÒÏÓ ÂÏÌÅÅ ÓÌÏÖÎÙÊ. 
+äÁÔØ ÆÏÒÍÁÌÉÚÏ×ÁÎÎÕÀ ÏÃÅÎËÕ ÔÏÞÎÏÓÔÉ ËÌÁÓÓÉÆÉËÁÃÉÉ ÎÅÌØÚÑ, ÅÓÌÉ ÔÏÌØËÏ
+ÜÔÁ ËÌÁÓÓÉÆÉËÁÃÉÑ ÎÅ ÐÏÌÕÞÅÎÁ × ÒÅÚÕÌØÔÁÔÅ ËÁËÏÇÏ-ÌÉÂÏ ÓÔÁÔÉÓÔÉÞÅÓËÏÇÏ
+ÍÅÔÏÄÁ.
+
+ôÅÏÒÉÑ ÔÏÞÎÏÓÔÉ ÉÚÍÅÒÅÎÉÊ ËÏÌÉÞÅÓÔ×ÅÎÎÙÈ ÐÏËÁÚÁÔÅÌÅÊ É ÔÏÞÎÏÓÔÉ 
+ÉÎÔÅÒÐÏÌÑÃÉÉ, ÎÁÐÒÏÔÉ×, ÈÏÒÏÛÏ ÒÁÚÒÁÂÏÔÁÎÁ.
+
+ëÒÏÍÅ ÔÏÇÏ ÓÕÝÅÓÔ×ÕÅÔ ÔÏÞÎÏÓÔØ ÐÒÅÄÓÔÁ×ÌÅÎÉÑ ÞÉÓÅÌ × ËÏÍÐØÀÔÅÒÅ.
+
+ðÏÜÔÏÍÕ ÄÌÑ ËÁÒÔ ËÏÌÉÞÅÓÔ×ÅÎÎÙÈ ÐÁÒÁÍÅÔÒÏ× ËÒÏÍÅ ÒÁÚÒÅÛÅÎÉÑ ÉÓÐÏÌØÚÕÅÔÓÑ
+ÐÏÎÑÔÉÅ Z-ÔÏÞÎÏÓÔÉ - ÍÉÎÉÍÁÌØÎÁÑ ÒÁÚÎÉÃÁ ÍÅÖÄÕ ÚÎÁÞÅÎÉÑÍÉ ËÁÒÔÙ,
+ÐÒÉ ËÏÔÏÒÙÈ ÜÔÉ ÚÎÁÞÅÎÉÑ ÓÞÉÔÁÀÔÓÑ ÎÅÒÁ×ÎÙÍÉ. Z-ÔÏÞÎÏÓÔØ ÜÔÏ
+
+3. çÄÅ ÖÅ ËÏÎÔÕÒ?
+
+÷Ï ×ÓÅÍ ×ÙÛÅÉÚÌÏÖÅÎÎÏÍ ÞÅÌÏ×ÅË ÐÒÉ×ÙËÛÉÊ ÒÁÂÏÔÁÔØ Ó ËÁÒÔÁÍÉ ÎÅ ÎÁÊÄÅÔ
+ÏÄÎÏÇÏ ×ÁÖÎÏÇÏ ÐÏÎÑÔÉÑ --- ËÏÎÔÕÒÁ. åÇÏ ÚÄÅÓØ ÄÅÊÓÔ×ÉÔÅÌØÎÏ ÎÅÔ.
+
+ëÏÎÔÕÒ ÜÔÏ Ó×ÑÚÎÏÅ ÍÎÏÖÅÓÔ×Ï ÔÏÞÅË, × ËÏÔÏÒÙÈ ËÁÒÔÁ ÉÍÅÅÔ ÏÄÉÎÁËÏ×ÏÅ ÚÎÁÞÅÎÉÅ.
+åÓÌÉ ÍÙ ÒÁÓÓÍÏÔÒÉÍ ËÁÒÔÕ ËÏÌÉÞÅÓÔ×ÅÎÎÏÇÏ ÐÏËÁÚÁÔÅÌÑ, ËÏÔÏÒÁÑ ÏÂÙÞÎÏ
+ÉÚÏÂÒÁÖÁÅÔÓÑ Ó ÐÏÍÏÝØÀ ÐÏÓÌÏÊÎÏÊ ÒÁÓËÒÁÓËÉ, ÔÏ ÍÙ Õ×ÉÄÉÍ, ÞÔÏ
+ËÏÎÔÕÒ ÚÄÅÓØ - ÏÂÌÁÓÔØ × ËÏÔÏÒÏÊ ÚÎÁÞÅÎÉÑ ÐÏËÁÚÁÔÅÌÑ ÚÁËÌÀÞÅÎÙ × ÏÐÒÅÄÅÌÅÎÎÏÍ
+ÉÎÔÅÒ×ÁÌÅ - ÏÔ ÏÄÎÏÊ ÉÚÏÌÉÎÉÉ ÄÏ ÓÏÓÅÄÎÅÊ. åÓÌÉ ÍÙ ÉÚÍÅÎÉÍ ÇÒÁÎÉÃÙ
+ÉÎÔÅÒ×ÁÌÏ×, ÉÚÍÅÎÉÔÓÑ É ×ÓÑ ËÏÎÔÕÒÎÁÑ ÓÅÔØ, ÈÏÔÑ ÓÁÍÁ ËÁÒÔÁ, ÔÏ ÅÓÔØ
+ÐÒÏÓÔÒÁÎÓÔ×ÅÎÎÏÅ ÒÁÓÐÒÅÄÅÌÅÎÉÅ ÚÎÁÞÅÎÉÊ ÐÏËÁÚÁÔÅÌÑ, ÏÓÔÁÌÁÓØ ÐÒÅÖÎÅÊ.
+
+äÌÑ ËÁÒÔ ËÌÁÓÓÉÆÉËÁÃÉÊ ËÏÎÔÕÒ --- ×ÅÝØ ÂÏÌÅÅ ÕÓÔÏÊÞÉ×ÁÑ. ïΠÍÏÖÅÔ
+ÉÚÍÅÎÉÔØÓÑ ÅÓÌÉ ÐÏ ËÁËÉÍ-ÔÏ ÐÒÉÞÉÎÁÍ ÉÚÍÅÎÉÔÓÑ ËÌÁÓÓÉÆÉËÁÃÉÑ ÌÉÂÏ
+ÎÁÛÉ ÚÎÁÎÉÑ Ï ÔÅÒÒÉÔÏÒÉÉ. 
+
+ðÏÜÔÏÍÕ ÄÌÑ ÜÔÉÈ ËÁÒÔ ×ÏÚÍÏÖÎÁ ÒÁÂÏÔÁ ÎÁ ÕÒÏ×ÎÅ ËÏÎÔÕÒÏ×. ÷ ÏÓÎÏ×ÎÏÍ
+ÏÐÅÒÁÃÉÉ Ó ËÏÎÔÕÒÁÍÉ ÜÔÏ ÉÈ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏÅ ÒÅÄÁËÔÉÒÏ×ÁÎÉÅ, ËÏÔÏÒÏÅ
+Ó ÔÏÞËÉ ÚÒÅÎÉÑ ÆÕÎËÃÉÏÎÁÌØÎÏÊ ËÁÒÔÙ ÏÚÎÁÞÁÅÔ: ÍÙ ×ÙÄÅÌÑÅÍ ËÁËÕÀ-ÔÏ ÇÒÕÐÐÕ
+ÔÏÞÅË (ÎÁÐÒÉÍÅÒ, ÎÁÒÉÓÏ×Á× ÚÁÍËÎÕÔÕÀ ÌÉÎÉÀ) É ÇÏ×ÏÒÉÍ: ÚÎÁÞÅÎÉÅ ËÁÒÔÙ
+× ÜÔÉÈ ÔÏÞËÁÈ ÔÅÐÅÒØ ÂÕÄÅÔ ÔÁËÏÅ-ÔÏ.
+
+ïÞÅ×ÉÄÎÏ, ÜÔÏÊ ÏÐÅÒÁÃÉÅÊ ÎÁÄÏ ÐÏÌØÚÏ×ÁÔØÓÑ Ó ÏÓÔÏÒÏÖÎÏÓÔØÀ, ÏÓÔÁ×É×
+ÅÇÏ ÄÌÑ ÜÔÁÐÏ× ÐÅÒ×ÉÞÎÏÇÏ ××ÏÄÁ ÉÎÆÏÒÍÁÃÉÉ É ÅÅ ÏÂÎÏ×ÌÅÎÉÑ.
+
+4. ïÐÅÒÁÃÉÉ Ó ËÁÒÔÁÍÉ.
+
+ôÅÐÅÒØ ÐÅÒÅÊÄÅÍ Ë ÔÏÍÕ, ÄÌÑ ÞÅÇÏ ×ÓÅ ÜÔÏ ÚÁÔÅ×ÁÌÏÓØ - Ë ÏÐÅÒÁÃÉÑÍ ÁÎÁÌÉÚÁ
+ËÁÒÔ.
+
+éÈ ÍÏÖÎÏ ÓÒÁÚÕ ÒÁÚÄÅÌÉÔØ ÎÁ Ä×Å ÂÏÌØÛÉÅ ÇÒÕÐÐÙ:
+1) ëÏÇÄÁ ÎÁÍ × ÒÅÚÕÌØÔÁÔÅ ÎÕÖÎÏ ÐÏÌÕÞÉÔØ ËÁÒÔÕ
+2) ëÏÇÄÁ × ÒÅÚÕÌØÔÁÔÅ ÍÙ ÐÏÌÕÞÁÅÍ ËÁËÕÀ-ÔÏ ÓÕÍÍÁÒÎÕÀ ÉÎÆÏÒÍÁÃÉÀ
+  (ÏÂÙÞÎÏ × ÆÏÒÍÅ ÔÁÂÌÉÃÙ).
+
+ïÇÒÁÎÉÞÉÍÓÑ ÐÏËÁ ÐÅÒ×ÏÊ ÇÒÕÐÐÏÊ ÏÐÅÒÁÃÉÊ.
+
+1. úÁÞÁÓÔÕÀ, ÞÔÏÂÙ ÐÏÌÕÞÉÔØ ÉÎÔÅÒÅÓÕÀÝÉÊ ÎÁÓ ÐÏËÁÚÁÔÅÌØ × ËÁËÏÊ-ÔÏ
+ÔÏÞËÅ, ÎÁÍ
+ÄÏÓÔÁÔÏÞÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÔÏÌØËÏ ÚÎÁÞÅÎÉÑ ÎÅËÏÔÏÒÙÈ ÄÒÕÇÉÈ ÐÏËÁÚÁÔÅÌÅÊ
+× ÔÏÊ ÖÅ ÔÏÞËÅ.
+
+îÁÐÒÉÍÅÒ, ÄÌÑ ÒÁÓÞÅÔÁ ÐÏÔÅÎÃÉÁÌØÎÏÊ ÜÒÏÚÉÉ ÎÁÍ ÎÕÖÎÙ Ó×ÅÄÅÎÉÑ Ï
+ÍÅÈÁÎÉÞÅÓËÏÍ ÓÏÓÔÁ×Å ÐÏÞ×, ÕËÌÏÎÁÈ, ÄÌÉÎÅ ÓËÌÏÎÏ×, ÎÁÐÏÞ×ÅÎÎÏÍ ÐÏËÒÏ×Å
+É Ô.Ä. åÓÌÉ ×ÓÅ ÜÔÉ ÄÁÎÎÙÅ ÅÓÔØ Õ ÎÁÓ × ×ÉÄÅ ËÁÒÔ, ÔÏ ÐÒÉÍÅÎÉ×
+ÉÚ×ÅÓÔÎÏÅ ÕÒÁ×ÎÅÎÉÅ Ë ËÁÖÄÏÊ ÔÏÞËÅ ÔÅÒÒÉÔÏÒÉÉ, ÍÙ ÐÏÌÕÞÉÍ ÎÏ×ÕÀ ËÁÒÔÕ.
+
+ôÒÁÄÉÃÉÏÎÎÏ × ÄÌÑ ÜÔÏÇÏ ÓÎÁÞÁÌÁ ÎÁËÌÁÄÙ×ÁÀÔ ÄÒÕÇ ÎÁ ÄÒÕÇÁ ×ÓÅ ÉÓÈÏÄÎÙÅ
+ËÁÒÔÙ É ÐÏÌÕÞÁÀÔ ÓÅÔËÕ ÍÉÎÉÍÁÌØÎÙÈ ËÏÎÔÕÒÏ×, × ËÏÔÏÒÙÈ ×ÓÅ ÉÓÈÏÄÎÙÅ
+ÐÏËÁÚÁÔÅÌÉ ÏÄÎÏÒÏÄÎÙ, Á ÐÏÔÏÍ ÄÌÑ ËÁÖÄÏÇÏ ÔÁËÏÇÏ ËÏÎÔÕÒÁ ÒÁÓÞÉÔÙ×ÁÀÔ
+ÉÔÏÇÏ×ÙÊ ÐÏËÁÚÁÔÅÌØ.
+
+åÓÌÉ ÖÅ ÍÙ ×ÙÐÏÌÎÉÍ ÒÁÓÓÞÅÔ ÄÌÑ ËÁÖÄÏÊ ÔÏÞËÉ ËÁÒÔÙ (Á ÉÈ ËÏÎÅÞÎÏÅ ÞÉÓÌÏ,
+ÐÏÓËÏÌØËÕ ×ÓÅ ÉÓÈÏÄÎÙÅ ËÁÒÔÙ ÉÍÅÀÔ ËÏÎÅÞÎÏÅ ÒÁÚÒÅÛÅÎÉÅ), ÔÏ
+ÉÔÏÇÏ×ÙÅ ËÏÎÔÕÒÁ ÏÂÒÁÚÕÀÔÓÑ ÓÁÍÉ, ËÁË ÇÒÕÐÐÙ ÔÏÞÅË ÇÄÅ ×ÙÞÉÓÌÅÎÎÙÊ
+ÐÏËÁÚÁÔÅÌØ ÉÍÅÅÔ ÏÄÉÎÁËÏ×ÙÅ ÚÎÁÞÅÎÉÑ.
+
+íÁÔÅÍÁÔÉÞÅÓËÉ ÜÔÏ ÏÐÉÓÙ×ÁÅÔÓÑ ÐÏÎÑÔÉÅÍ ÆÕÎËÃÉÏÎÁÌÁ - ÏÐÅÒÁÃÉÉ,
+ËÏÔÏÒÁÑ ÐÏ ÎÅÓËÏÌØËÉÍ ÉÓÈÏÄÎÙÍ ÆÕÎËÃÉÑÍ ÓÔÒÏÉÔ ÒÅÚÕÌØÔÉÒÕÀÝÕÀ.
+
+ó ÐÒÁËÔÉÞÅÓËÏÊ ÔÏÞËÉ ÚÒÅÎÉÑ ÐÒÏ×ÅÓÔÉ ×ÙÞÉÓÌÅÎÉÑ × ÎÅÓËÏÌØËÉÈ ÍÉÌÌÉÏÎÁÈ
+ÔÏÞÅË ÇÏÒÁÚÄÏ ÂÙÓÔÒÅÅ, ÞÅÍ ×ÙÞÉÓÌÑÔØ ÐÅÒÅÓÅÞÅÎÉÑ ÓÏÔÅΠËÏÎÔÕÒÏ×.
+
+2. éÎÏÇÄÁ ÄÌÑ ×ÙÞÉÓÌÅÎÉÑ ÚÎÁÞÅÎÉÑ ÐÏËÁÚÁÔÅÌÑ × ÔÏÞËÅ ÎÁÍ ÎÕÖÎÁ
+ ÉÎÆÏÒÍÁÃÉÑ Ï ÎÅËÏÔÏÒÏÊ ÏËÒÅÓÔÎÏÓÔÉ ÜÔÏÊ ÔÏÞËÅ (ÔÅÏÒÅÔÉÞÅÓËÉ -
+× ÂÅÓËÏÎÅÞÎÏ ÍÁÌÏÊ, ÎÁ ÐÒÁËÔÉËÅ - ÎÅ ÍÅÎØÛÅ ÒÁÚÒÅÛÅÎÉÑ ËÁÒÔÙ)
+ëÌÁÓÓÉÞÅÓËÉÊ ÐÒÉÍÅÒ ÔÁËÏÊ ÚÁÄÁÞÉ - ÎÁÈÏÖÄÅÎÉÅ ÕËÌÏÎÏ× ÐÏ
+ÇÉÐÓÏÍÅÔÒÉÞÅÓËÏÊ ËÁÒÔÅ. äÒÕÇÏÊ, ÓÔÏÌØ ÖÅ ÈÁÒÁËÔÅÒÎÙÊ ÐÒÉÍÅÒ - ÔÅËÓÔÕÒÁ
+ÉÚÏÂÒÁÖÅÎÉÑ ÎÁ ÁÜÒÏÆÏÔÏÓÎÉÍËÅ.
+
+3. é, ÎÁËÏÎÅÃ, ÉÎÏÇÄÁ ÎÁÍ ÎÕÖÎÙ ÕÄÁÌÅÎÎÙÅ ÔÏÞËÉ, ÏÂÌÁÄÁÀÝÉÅ
+ÏÐÒÅÄÅÌÅÎÎÙÍÉ Ó×ÏÊÓÔ×ÁÍÉ. îÁÐÒÉÍÅÒ, ×Ï ÍÎÏÇÉÈ ÚÁÄÁÞÁÈ ÒÁÚÍÅÝÅÎÉÑ 
+ÎÁÓ ÉÎÔÅÒÅÓÕÅÔ ÒÁÓÓÔÏÑÎÉÅ ÄÏ ÂÌÉÖÁÊÛÅÊ ÄÏÒÏÇÉ, ÐÒÉ ÐÏÓÔÒÏÅÎÉÉ
+ËÁÒÔ ÈÉÍÉÞÅÓËÏÇÏ ÓÏÓÔÁ×Á ÎÁÓ ÉÎÔÅÒÅÓÕÀÔ ÎÅÓËÏÌØËÏ ÂÌÉÖÁÊÛÉÈ ÔÏÞÅË
+ÏÐÒÏÂÏ×ÏÁÎÉÑ.
+
+éÎÔÅÒÅÓÎÏÊ ÔÅÍÏÊ ÄÌÑ ÉÓÓÌÅÄÏ×ÁÎÉÑ Ñ×ÌÑÅÔÓÑ ×ÏÚÍÏÖÎÏÓÔØ ËÏÍÐÏÚÉÃÉÉ
+ÆÕÎËÃÉÏÎÁÌÏ×, ÐÏÓËÏÌØËÕ ÒÁÂÏÔÁ Ó ËÏÍÐÏÚÉÃÉÑÍÉ ÆÕÎËÃÉÏÎÁÌÏ×
+ÐÏÚ×ÏÌÑÅÔ ÓÞÉÔÁÔØ ÓÌÏÖÎÙÅ ÍÏÄÅÌÉ ÚÁ ÏÄÉΠÐÒÏÈÏÄ, ÂÅÚ ÓÏÚÄÁÎÉÑ
+ÓÌÏÖÎÙÈ ÐÒÏÍÅÖÕÔÏÞÎÙÈ ËÁÒÔ.
+
+ïÞÅ×ÉÄÎÏ, Ë ÏÐÅÒÁÃÉÑÍ 1-Ê ÇÒÕÐÐÙ ËÏÍÐÏÚÉÃÉÑ ÐÒÉÍÅÎÉÍÁ ×ÓÅÇÄÁ
+z=f(g(x)) ÐÏÓÞÉÔÁÔØ ÎÅ ÓÌÏÖÎÅÅ ÞÅÍ y=g(x) z=f(y).
+
+óÌÏÖÎÅÅ Ó ÏÐÅÒÁÃÉÑÍÉ ×ÔÏÒÏÊ ÇÒÕÐÐÙ, ÐÏÓËÏÌØËÕ ÅÓÌÉ × ×ÙÞÉÓÌÅÎÉÉ 
+f(x) ÕÞÁÓÔ×ÕÀÔ ÚÎÁÞÅÎÉÑ g(x+dx) ÉÈ ÎÁÄÏ ×ÙÞÉÓÌÉÔØ ÚÁÒÁÎÅÅ, Á ÅÓÌÉ
+É ÏÎÉ ÔÒÅÂÕÀÔ ÏËÒÅÓÔÎÏÓÔÉ... óÒÁ×ÎÉÔÅ, ÎÁÐÒÉÍÅÒ, Ó ÆÏÒÍÕÌÏÊ ×ÔÏÒÏÊ
+ÐÒÏÉÚ×ÏÄÎÏÊ ÓÌÏÖÎÏÊ ÆÕÎËÃÉÉ.
+
+åÓÌÉ ÖÅ ÒÅÞØ ÉÄÅÔ Ï ÎÅÌÏËÁÌØÎÙÈ ÏÐÅÒÁÃÉÑÈ, ÔÁËÉÈ ËÁË ÂÕÆÅÒÉÚÁÃÉÑ
+É ÉÎÔÅÒÐÏÌÑÃÉÑ, ÂÅÚ ÓÏÈÒÁÎÅÎÉÑ ÐÒÏÍÅÖÕÔÏÞÎÙÈ ÒÅÚÕÌØÔÁÔÏ× × ×ÉÄÅ
+ËÁÒÔ ×ÉÄÉÍÏ ÎÅ ÏÂÏÊÔÉÓØ.
+
+
+÷ÉÚÕÁÌÉÚÁÃÉÑ ËÁÒÔ É ÍÅÔÁÄÁÎÎÙÅ.
+
+äÁÔØ ÓÔÒÏÇÏÅ ÍÁÔÅÍÁÔÉÞÅÓËÏÅ ÏÐÒÅÄÅÌÅÎÉÅ ËÁÒÔÙ ËÏÎÅÞÎÏ ÈÏÒÏÛÏ, ÎÏ
+ÉÓÓÌÅÄÏ×ÁÔÅÌÉ ÐÒÉ×ÙËÌÉ ×ÉÄÅÔØ ËÁÒÔÕ ÐÅÒÅÄ ÇÌÁÚÁÍÉ. 
+
+üÔÏ ËÁË ÒÁÚ ÔÏ, ÞÅÇÏ ÎÅ ÐÏÚ×ÏÌÑÀÔ ÓÕÝÅÓÔ×ÕÀÝÉÅ çéó. ÷ ÎÉÈ ÓÏÚÄÁÎÉÅ
+ËÁÒÔÏÇÒÁÆÉÞÅÓËÏÊ ËÏÍÐÏÚÉÃÉÉ ÎÁ ÜËÒÁÎÅ ÉÌÉ ÎÁ ÂÕÍÁÇÅ - ÄÌÉÔÅÌØÎÙÊ
+É ÓÌÏÖÎÙÊ ÐÒÏÃÅÓÓ, ÓÏ×ÅÒÛÅÎÎÏ ÎÅ Ó×ÑÚÁÎÎÙÊ Ó ÓÏÂÓÔ×ÅÎÎÏ ÐÒÏÓÔÒÁÎÓÔ×ÅÎÎÙÍ
+ÁÎÁÌÉÚÏÍ É ÍÏÄÅÌÉÒÏ×ÁÎÉÅÍ. 
+
+äÁ, ÓÔÁÄÉÑ ÄÉÚÁÊÎÁ ÎÅÏÂÈÏÄÉÍÁ, ËÏÇÄÁ ×Ù ÇÏÔÏ×ÉÔÅ ËÁÒÔÕ ÄÌÑ ÐÕÂÌÉËÁÃÉÉ,
+ÎÏ ×ÏÚÍÏÖÎÏÓÔØ ÂÙÓÔÒÏ Õ×ÉÄÅÔØ ÒÅÚÕÌØÔÁÔ ËÁËÏÊ-ÔÏ ÏÐÅÒÁÃÉÉ × ÂÏÌÅÅ
+ÍÅÎÅÅ ÁÄÅË×ÁÔÎÙÈ ËÁÒÔÏÇÒÁÆÉÞÅÓËÉÈ ÚÎÁËÁÈ ÍÏÖÅÔ ÉÚÂÁ×ÉÔØ ÏÔ ÍÎÏÖÅÓÔ×Á
+ÏÛÉÂÏË.
+
+æÕÎËÃÉÏÎÁÌØÎÙÅ ËÁÒÔÙ ÍÏÇÕÔ ÐÏÍÏÞØ É ÚÄÅÓØ.
+ðÏÓËÏÌØËÕ ËÁÖÄÁÑ ËÁÒÔÁ Õ ÎÁÓ ÏÔÏÂÒÁÖÁÅÔ ÒÏ×ÎÏ ÏÄÉΠÐÏËÁÚÁÔÅÌØ,
+ÍÙ ÍÏÖÅÍ Ó×ÑÚÁÔØ ÓÐÏÓÏ ËÁÒÔÏÇÒÁÆÉÞÅÓËÏÇÏ ÉÚÏÂÒÁÖÅÎÉÑ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ
+Ó ÍÎÏÖÅÓÔ×ÏÍ ÚÎÁÞÅÎÉÊ ËÁÒÔÙ. (×Ï ÍÎÏÇÉÈ ÏÂÌÁÓÔÑÈ ÎÁÕË Ï ÚÅÍÌÅ ÜÔÏ
+ÕÖÅ É ÔÁË ÓÄÅÌÁÎÏ - ÓÕÝÅÓÔ×ÕÀÔ ÓÔÁÎÄÁÒÔÎÙÅ Ã×ÅÔÁ ÄÌÑ ÔÉÐÏ× ÐÏÞ× ÉÌÉ
+ÇÅÏÈÒÏÎÏÌÏÇÉÞÅÓËÉÈ ÜÐÏÈ).
+
+ðÏÓÌÅ ÜÔÏÇÏ, ÐÏÓÔÒÏÉ× ËÁÒÔÕ ÍÙ ÍÏÖÅÍ ÎÅÍÅÄÌÅÎÎÏ ÅÅ ÉÚÏÂÒÁÚÉÔØ × 
+ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÈ ÕÓÌÏ×ÎÙÈ ÚÎÁËÁÈ, Á ÚÁÄÁÞÁ ÄÉÚÁÊÎÁ ËÁÒÔÏÇÒÁÆÉÞÅÓËÏÊ
+ËÏÍÐÏÚÉÃÉÉ ÒÁÓÐÁÄÁÅÔÓÑ ÎÁ ÓÏÚÄÁÎÉÅ ÎÁÂÏÒÁ ÚÎÁËÏ× ÄÌÑ ËÁÖÄÏÇÏ
+ÐÏËÁÚÁÔÅÌÑ É ÉÚÏÂÒÁÖÅÎÉÅ ÎÁ ÏÄÎÏÍ ÌÉÓÔÅ ÔÅÈ ÓÌÏÅ×, ËÏÔÏÒÙÅ ÔÅÍÁÔÉÞÅÓËÉ
+ÉÎÔÅÒÅÓÎÏ ÒÁÓÓÍÁÔÒÉ×ÁÔØ ×ÍÅÓÔÅ, ÔÁË , ÞÔÏÂÙ ÏÎÉ ÎÅ ÍÅÛÁÌÉ ÄÒÕÇ ÄÒÕÇÕ.
+
+íÁÓÛÔÁÂÎÙÊ ÒÑÄ ÉÌÉ ÉÅÒÁÒÈÉÑ ÒÅÇÉÏÎÏ×.
+
+äÁÌÅËÏ ÎÅ ×ÓÅÇÄÁ ÒÁÂÏÔÁ Ó ËÁÒÔÁÍÉ Ó×ÏÄÉÔÓÑ Ë ÒÁÂÏÔÅ Ó ÏÄÎÏÊ É ÔÏÊ ÖÅ 
+ÔÅÒÒÉÔÏÒÉÅÊ. äÏÓÔÁÔÏÞÎÏ ÞÁÓÔÏ ÐÒÉÈÏÄÉÔÓÑ ÉÍÅÔØ ÄÅÌÏ Ó ÉÅÒÁÒÈÉÅÊ
+ÍÁÓÛÔÁÂÏ× É ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÅÊ ÅÊ ÉÅÒÁÒÈÉÅÊ ÔÅÒÒÉÔÏÒÉÊ.
+
+ðÒÉ ÜÔÏÍ ÉÓÐÏÌØÚÕÅÍÙÅ ËÁÒÔÏÇÒÁÆÉÞÅÓËÉÅ ÐÒÏÅËÃÉÉ É ËÌÁÓÓÉÆÉËÁÃÉÉ
+ËÁÞÅÓÔ×ÅÎÎÙÈ ÐÏËÁÚÁÔÅÌÅÊ (ÐÏÞ×, ÒÁÓÔÉÔÅÌØÎÏÓÔÉ É Ô.Ä.) ÚÁËÏÎÏÍÅÒÎÏ
+ÍÅÎÑÀÔÓÑ Ó ÉÚÍÅÎÅÎÅÍ ÍÁÓÛÔÁÂÁ.
+
+äÁÌÅËÏ ÎÅ ×ÓÅÇÄÁ ÎÁ ÎÕÖÎÏÍ ÍÁÓÛÔÁÂÎÏÍ ÕÒÏ×ÎÅ ÅÓÔØ ×ÓÑ ÎÅÏÂÈÏÄÉÍÁÑ
+ÉÎÆÏÒÍÁÃÉÑ. ðÏÜÔÏÍÕ ÞÁÓÔÏ ×ÏÚÎÉËÁÅÔ ÚÁÄÁÞÁ ÌÉÂÏ ÓÏÂÒÁÔØ ËÁÒÔÕ
+ÉÚ ÂÏÌÅÅ ËÒÕÐÎÏÍÁÓÛÔÁÂÎÙÈ ËÕÓËÏ×, Ó ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÅÊ ÇÅÎÅÒÁÌÉÚÁÃÉÅÊ,
+ÌÉÂÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÆÒÁÇÍÅÎÔ ÂÏÌÅÅ ÍÅÌËÏÍÁÓÛÔÁÂÎÏÊ ËÁÒÔÙ. ðÏÔÅÒÑ ÔÏÞÎÏÓÔÉ
+ÔÕÔ ÎÅÉÚÂÅÖÎÁ, ÎÏ ÞÁÓÔÏ ÌÕÞÛÅ ÎÅÔÏÞÎÙÅ ÄÁÎÎÙÅ, ÞÅÍ ÎÉËÁËÉÈ.
+
+ðÏÜÔÏÍÕ ÍÙ ××ÏÄÉÍ ËÏÎÃÅÐÃÉÀ ÒÅÇÉÏÎÁ. òÅÇÉÏΠÜÔÏ ÇÒÕÐÐÁ ËÁÒÔ ÎÁ ÏÄÎÕ
+É ÔÕ ÖÅ ÔÅÒÒÉÔÏÒÉÀ. ÷ÓÅ ËÁÒÔÙ ÒÅÇÉÏÎÁ ÉÍÅÀÔ ÏÄÎÕ É ÔÕ ÖÅ ËÏÏÒÄÉÎÁÔÎÕÀ
+ÓÉÓÔÅÍÕ (ËÁÒÔÏÇÒÁÆÉÞÅÓËÕÀ ÐÒÏÅËÃÉÀ) ÎÏ ÍÏÇÕÔ ÒÁÚÌÉÞÁÔØÓÑ ÐÏ ÒÁÚÒÅÛÅÎÉÀ.
+ðÏÓÌÅÄÎÅÅ ÎÅ ÍÅÛÁÅÔ ÓÏ×ÍÅÓÔÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÉÈ × ÁÎÁÌÉÚÅ. 
+äÌÑ ÔÏÇÏ ÞÔÏÂÙ ÉÓÐÏÌØÚÏ×ÁÔØ ËÁÒÔÕ ÉÚ ÄÒÕÇÏÇÏ ÒÅÇÉÏÎÁ ×ÍÅÓÔÅ Ó ËÁÒÔÁÍÉ
+ÔÅËÕÝÅÇÏ, ÅÅ ÎÁÄÏ ÓËÏÐÉÒÏ×ÁÔØ × ÜÔÏÔ ÒÅÇÉÏÎ. ðÒÉ ÜÔÏÍ ÏÎÁ ÂÕÄÅÔ
+Á×ÔÏÍÁÔÉÞÅÓËÉ ÐÒÅÏÂÒÁÚÏ×ÁÎÁ × ÎÕÖÎÕÀ ÐÒÏÅËÃÉÀ, ÎÏ ÓÏÈÒÁÎÉÔ Ó×ÏÅ ÏÒÉÇÉÎÁÌØÎÏÅ
+ÒÁÚÒÅÛÅÎÉÅ É ÌÅÇÅÎÄÕ. åÅ ÇÅÎÅÒÁÌÉÚÁÃÉÑ (ÕÍÅÎØÛÅÎÉÅ ÒÁÚÒÅÛÅÎÉÑ) É
+ÐÅÒÅËÌÁÓÓÉÆÉËÁÃÉÑ ÌÅÇÅÎÄÙ - ÄÅÌÏ ÐÏÌØÚÏ×ÁÔÅÌÑ.
+
+òÅÇÉÏÎÙ ÉÍÅÀÔ ÉÅÒÁÒÈÉÞÅÓËÕÀ ÓÉÓÔÅÍÕ ÓÏÐÏÄÞÉÎÅÎÉÑ. ðÏËÁÖÅÍ, ÞÔÏ ÜÔÏ
+ÔÁËÏÅ ÎÁ ÐÒÉÍÅÒÅ ÁÄÍÉÎÉÓÔÒÁÔÉ×ÎÏÇÏ ÄÅÌÅÎÉÑ òÏÓÓÉÉ.
+
+òÅÇÉÏΠ×ÅÒÈÎÅÇÏ ÕÒÏ×ÎÑ - òÏÓÓÉÑ × ÃÅÌÏÍ. èÁÒÁËÔÅÒÎÏÅ ÒÁÚÒÅÛÅÎÉÅ 1-2ËÍ,
+ ÐÒÏÅËÃÉÑ ÓËÏÒÅÅ ×ÓÅÇÏ ËÏÎÉÞÅÓËÁÑ.
+÷ ÜÔÏÔ ÒÅÇÉÏΠ×ÈÏÄÑÔ 86 ÐÏÄÒÅÇÉÏÎÏ× - ÁÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÈ ÏÂÌÁÓÔÅÊ.
+òÁÚÒÅÛÅÎÉÅ × ÎÉÈ ÏÔ 500 ÄÏ 100 Í, Á ÐÒÏÅËÃÉÑ ÍÏÖÅÔ ÂÙÔØ ËÏÎÉÞÅÓËÏÊ,
+ËÏÓÏÊ ÁÚÉÍÕÔÁÌØÎÏÊ ÉÌÉ UTM(çÁÕÓÓÁ), × ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ ÒÁÚÍÅÒÏ× ÏÂÌÁÓÔÉ.
+
+åÓÌÉ ÄÅÌÅÎÉÅ ÏÄÎÏÇÏ ÒÅÇÉÏÎÁ ÓÒÁÚÕ ÎÁ 86 ÞÁÓÔÅÊ ËÁÖÅÔÓÑ ÓÌÉÛËÏÍ ÍÅÌËÉÍ,
+ÍÏÖÎÏ ××ÅÓÔÉ ÐÒÏÍÅÖÕÔÏÞÎÙÊ ÕÒÏ×ÅÎØ ÜËÏÎÏÍÉÞÅÓËÉÈ ÒÁÊÏÎÏ×.
+
+ëÁÖÄÁÑ ÏÂÌÁÓÔØ ÓÏÓÔÏÉÔ ÉÚ ÒÁÊÏÎÏ×. ðÒÉ ÎÁÌÉÞÉÉ ÉÓÈÏÄÎÙÈ ÄÁÎÎÙÈ
+ÍÏÖÎÏ ××ÅÓÔÉ ÅÝÅ É ÐÏÄÒÅÇÉÏÎÙ ÄÌÑ ÒÁÊÏÎÏ× - ÏÔÄÅÌØÎÙÅ ÈÏÚÑÊÓÔ×Á Ó
+ÒÁÚÒÅÛÅÎÉÅÍ ÐÏÒÑÄËÁ ÍÅÔÒÏ× (ÍÁÓÛÔÁ 1:5000 - 1:10000)
+
+óÉÓÔÅÍÁ ÐÏÚ×ÏÌÑÅÔ ÐÅÒÅÊÔÉ ÎÁ ÓÏÓÅÄÎÉÊ ÕÒÏ×ÅÎØ × ÜÔÏÊ ÉÅÒÁÒÈÉÉ - ÌÉÂÏ
+ÐÏÄÎÑÔØÓÑ ××ÅÒÈ × ÏÂßÅÍÌÀÝÉÊ ÒÅÇÉÏÎ, ÌÉÂÏ, ×ÙÂÒÁ× ÎÕÖÎÙÊ ÐÏÄÒÅÇÉÏÎ
+ÎÁ ÓÐÅÃÉÁÌØÎÏÊ ËÁÒÔÅ (× ÄÁÎÎÏÍ ÓÌÕÞÁÅ ÁÄÍÉÎÉÓÔÒÁÔÉ×ÎÏÊ) ÐÅÒÅÊÔÉ
+× ÎÅÇÏ.
+
+ðÒÉ ËÏÐÉÒÏ×ÁÎÉÉ ËÁÒÔÙ Ó ÎÉÖÎÅÇÏ ÕÒÏ×ÎÑ ÎÁ ×ÅÒÈÎÉÊ, ÏÎÁ ËÏÐÉÒÕÅÔÓÑ
+ÃÅÌÉËÏÍ, Á ×ÏÔ ÐÒÉ ÏÂÒÁÔÎÏÍ ËÏÐÉÒÏ×ÁÎÉÉ ×ÏÚÎÉËÁÅÔ ÚÁÄÁÞÁ ×ÙÒÅÚÁÎÉÑ
+ÎÕÖÎÏÇÏ ËÕÓËÁ. ïÄÉΠÉÚ ×ÏÚÍÏÖÎÙÈ ÐÕÔÅÊ ÅÅ ÒÅÛÅÎÉÑ - ÉÍÅÔØ × ËÁÖÄÏÍ
+ÒÅÇÉÏÎÅ ÓÐÅÃÉÁÌØÎÕÀ ËÁÒÔÕ (×ÉÄÉÍÏ, ÔÕ ÖÅ, ËÏÔÏÒÁÑ ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ
+ÐÏÉÓËÁ ÓÕÂÒÅÇÉÏÎÏ×), ÏÂÌÁÓÔØ ÏÐÒÅÄÅÌÅÎÉÑ ËÏÔÏÒÏÊ ÓÏ×ÐÁÄÁÅÔ ÓÏ ×ÓÅÊ
+ÔÅÒÒÉÔÏÒÉÅÊ ÒÅÇÉÏÎÁ, É ÐÏÌØÚÏ×ÁÔØÓÑ ÅÊ ËÁË ÍÁÓËÏÊ.
+
+ðÒÉÎÃÉÐÙ ÐÏÓÔÒÏÅÎÉÑ ÓÉÓÔÅÍÙ
+
+óÉÓÔÅÍÁ ÓÔÒÏÉÔÓÑ ×ÏËÒÕÇ ×ØÀÅÒÁ/ÒÅÄÁËÔÏÒÁ ËÁÒÔ.
+üÔÏÔ ×ØÀÅÒ/ÒÅÄÁËÔÏÒ ÕÍÅÅÔ ×Ù×ÏÄÉÔØ ËÁÒÔÙ ÂÏÌÅÅ-ÍÅÎÅÅ ×ÓÅÍÉ
+ÓÕÝÅÓÔ×ÕÀÝÉÍÉ ÓÐÏÓÏÂÁÍÉ ËÁÒÔÏÇÒÁÆÉÞÅÓËÏÇÏ ÉÚÏÂÒÁÖÅÎÉÑ, × ÔÏÍ ÞÉÓÌÅ
+ÎÁÐÒÉÍÅÒ ÓÌÏÊ ÛÔÒÉÈÏ×ËÁÍÉ ÐÏ×ÅÒÈ ÓÌÏÑ Ã×ÅÔÏ×.
+
+ïÔËÒÙÔØ ÄÌÑ ÒÅÄÁËÔÉÒÏ×ÁÎÉÑ × ËÁÖÄÙÊ ËÏÎËÒÅÔÎÙÊ ÍÏÍÅÎÔ ÍÏÖÎÏ ÔÏÌØËÏ ÏÄÉÎ
+ÓÌÏÊ. 
+
+ðÒÉ ÔÙËÁÎØÅ ÍÙÛØÀ × ÏËÏΠËÁÒÔÙ ÏÂÙÞÎÏ × ËÁËÏÍ-ÔÏ ÄÒÕÇÏÍ ÏËÎÅ 
+ÐÏËÁÚÙ×ÁÅÔÓÑ ÚÎÁÞÅÎÉÅ ÐÏ ÎÅËÏÔÏÒÙÍ ×ÙÂÒÁÎÎÙÍ ËÁÒÔÁÍ (×ÓÅ ×ÉÄÉÍÙÅ +
+ÔÅ ËÏÔÏÒÙÅ ÐÏÌØÚÏ×ÁÔÅÌØ ÕËÁÚÁÌ Ñ×ÎÏ) × ÜÔÏÊ ÔÏÞËÅ.
+
+íÅÎÀ ÓÉÓÔÅÍÙ ÐÏÚ×ÏÌÑÅÔ ×ÙÐÏÌÎÉÔØ ÌÀÂÙÅ ÏÐÅÒÁÃÉÉ ÁÎÁÌÉÚÁ, ÐÅÒÅÈÏÄ
+ÍÅÖÄÕ ÒÅÇÉÏÎÁÍÉ É Ô.Ð. åÓÌÉ × ÒÅÚÕÌØÔÁÔÅ ÏÐÅÒÁÃÉÉ ÏÂÒÁÂÏÔËÉ ËÁÒÔ
+ÓÏÚÄÁÎÁ ÒÏ×ÎÏ ÏÄÎÁ ÎÏ×ÁÑ ËÁÒÔÁ, ÔÏ ÏÎÁ ÚÁÍÅÝÁÅÔ × ÏËÎÅ ×ØÀÅÒÁ ÔÕ,
+ËÏÔÏÒÁÑ ÂÙÌÁ ×Ù×ÅÄÅÎÁ Ã×ÅÔÏÍ (ÓÌÕÞÁÊ ÓÉÎÈÒÏÎÎÏÇÏ ×ÙÐÏÌÎÅÎÉÑ).
+÷ÓÅ ÏÐÅÒÁÃÉÉ, ËÏÔÏÒÙÅ ÐÏÌØÚÏ×ÁÔÅÌØ ÍÏÖÅÔ ÐÒÏÉÚ×ÅÓÔÉ ÉÚ ÍÅÎÀ ÓÉÓÔÅÍÙ
+ÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÉÚ ÐÒÏÇÒÁÍÍÙ ÎÁ Tcl, ×ËÌÀÞÁÑ ÔÁËÉÅ ËÁË ÒÉÓÏ×ÁÎÉÅ
+ÔÏÞËÉ ÉÌÉ ÌÉÎÉÉ × ÒÅÄÁËÔÏÒÅ
+
+á×ÔÏÍÁÔÉÞÅÓËÁÑ ÁËÔÕÁÌÉÚÁÃÉÑ ËÁÒÔ.
+
+äÌÑ ËÁÒÔ ÓÏÚÄÁÎÎÙÈ × ÒÅÚÕÌØÔÁÔÅ ÏÐÅÒÁÃÉÊ ÏÂÒÁÂÏÔËÉ ÈÒÁÎÉÔÓÑ
+ËÏÍÁÎÄÁ, ÓÏÚÄÁ×ÛÁÑ ËÁÒÔÕ, É ÓÐÉÓÏË ÉÓÈÏÄÎÙÈ ËÁÒÔ. ðÒÉ ×ÉÚÕÁÌÉÚÁÃÉÉ
+ÜÔÏÊ ËÁÒÔÙ ÐÒÏ×ÅÒÑÅÔÓÑ, ÎÅ ÂÙÌÉ ÌÉ ÉÚÍÅÎÅÎÙ ËÁËÉÅ-ÔÏ ÉÚ ÉÓÈÏÄÎÙÈ
+ËÁÒÔ, É ÅÓÌÉ ÄÁ, ÐÒÅÄÌÁÇÁÅÔÓÑ ÐÏ×ÔÏÒÉÔØ ÇÅÎÅÒÁÃÉÀ ËÁÒÔÙ. 
+
diff --git a/doc/concepts.html b/doc/concepts.html
new file mode 100644 (file)
index 0000000..08dc673
--- /dev/null
@@ -0,0 +1,360 @@
+<HTML>
+<HEAD>
+<TITLE>
+f(GIS) concepts
+</TITLE>
+</HEAD>
+<BODY>
+<H1><FONT SIZE=+3><I>f(</I></FONT><FONT SIZE=+2><B>GIS</B></FONT><FONT SIZE=+3><I>)</I></FONT>
+    concepts</H1>
+
+<!-- CONTENTS NUMBERED NESTED --><OL>
+<LI><A HREF="#toc_section0">Data model</A>
+<OL>
+<LI><A HREF="#toc_section1">Functional model</A>
+<LI><A HREF="#toc_section2">Layer classification</A>
+<LI><A HREF="#toc_section3">Implementation of data model</A>
+<LI><A HREF="#toc_section4">Regions and chartographic projection</A>
+</OL>
+<LI><A HREF="#toc_section5">Program design</A>
+<OL>
+<LI><A HREF="#toc_section6">Layer as Tcl object</A>
+<LI><A HREF="#toc_section7">Planchet - object for displaying maps</A>
+<LI><A HREF="#toc_section8">Low level objects</A>
+<LI><A HREF="#toc_section9">GIS operation</A>
+<LI><A HREF="#toc_section10">Utilities</A>
+<LI><A HREF="#toc_section11">Data access library</A>
+</OL>
+</OL>
+<!-- END CONTENT -->
+
+
+
+<A NAME="toc_section0"></A><H3>Data model</H3>
+
+GIS is a software system for processing spatial data. So, adequate model
+of spatial phenomena is most important thing for GIS. 
+<P>
+It should provide way to represent spatial phenomena in computer memory,
+allow to perform desired operation on this representation and let user
+see the results in form, he used to. Ideally, GIS system should hide
+complicated issues of internal data storage from user as well as text
+processor hides questions of font rendering or kerning or SQL database
+hides actual file layout and search technologies, providing simple,
+but powerful relational operations instead.
+<P>
+Many modern
+GIS systems, especially vector based, like ARC/Info, try to 
+represent map of spatial phenomena rather than spatial phenomena
+itself. It leads to overcomplication of storage format and processing
+algorithms, and makes user worry about such technical things as polygon
+topology, which are completely irrelevant to his problem (say geology
+or soil science), as font rendering hints and kerning is irrelevant to
+contents of article, typesetted with some partcular font. Maps are
+tool for analyse spatial data, widely used, but no more than tool.
+GIS system should deal with them, becouse it is neccesary to use
+existing data, which are represented on maps, and present results to
+user in understandable form of maps, but while processing data we should
+take into account properties of actual phenomena, rather then properties
+of chartographic representation like polygons.
+<P>
+<A NAME="toc_section1"></A><H4>Functional model</H4>
+
+In f(GIS) we use term <I>layer</I> to denote computer representation of
+spatial phenomena. We define layer as function which maps geographical
+coordinates to value of some property. Closest analogue of our
+<I>layer</I> is <I>spatial variable</I> in geostatistics.
+<P>
+Layer values can be either real numbers or elements of some finite sets.
+If you want to study more complicated spatial phenomena, it is better
+to describe it as set of layers rather then individual layer with
+structured value. Obvoisly you'll not need values of all attributes in
+question for all desired calculations, and separating them makes your
+actions more clear.
+<P>
+Becouse layers are defined as functions it is theoretically possible to
+apply well develped mathematical apparatus of functional analysis to
+them.
+
+<A NAME=layerclass></A>
+<A NAME="toc_section2"></A><H4>Layer classification</H4>
+Layers can be classified by their area of definition and their set of
+values. By area of definition we can distinguish between:
+
+<DL>
+<DT> Two-dimensional layers
+<DD> which are defined on some contineous area.
+  It is most frequently used type of layers for physical geography. 
+  Relief and soil type are perfect examples of such layers. Area of
+  definition of two-dimensional layers is usially finite, limited by
+  boundaries of study area or by availability of data. Areas which are
+  outside of area of definition are called <I>offsite</I> areas.
+<DT> One-dimensional layers
+<DD>  are defined on set of lines within study area. Examples of such
+   layers are hydrography or railroad network.
+<DT> Zero-dimensional layers
+<DD> are defined on set of separate points. This layers can be used
+  for store information about sampling points or weather station
+networks.
+</DL> 
+
+By the set of values layers can be classified to:
+<DL>
+<DT>Numeric layers
+<DD> whose values belong to some contineous interval on numeric axis,
+for example relief layers, which have any value between lowest and
+highest altitude in the study area.
+<DT>Classification layers
+<DD>which have finite set of values. f(GIS) allows to use arbitrary
+strings as elements of such set. Soil map which has names of soil series
+as values can be used as an example.
+</DL>
+
+This simple classification covers all theoretically important types of
+layers. Dealing with implementation we'll have to classify layers
+further, for example, according to source of thematic data. But for 
+data analysis it is not significant whether data are stored in disk
+file or come from some data asquition system on the fly. It is only
+important to know type of values and whether they are defined for
+any point of study area or not.
+
+<A NAME="toc_section3"></A><H4>Implementation of data model</H4>
+
+Spatial phenomena seldom can be expressed by some mathematical equation.
+Even if they can, finding of this equation is usially aim of analysis,
+not a starting point. So, we need to store values of layers in any
+point they are defined. Raster is natural way to store data for 
+two-dimensional layers.<P>
+<FONT SIZE=-2> (Raster is just big matrix of numeric values, stored 
+in special format to reduce storage space. If raster is used in GIS
+processing, it should be known, how to find row and column numbers given
+real word coordinates and vice versa)</FONT>
+<P>
+f(GIS) uses raster data format developed for EPPL7 GIS system. This
+format have several advantages - it is compressed and allows random
+access at the same time and it is able to deal with very fine
+resolution. For example Landscape map of exUSSR with spatial resolution
+(raster cell size) 500m and more than 3000 distinct kinds of landscapes
+occupies about 9MB of disk space. Due  to such properties of data
+format, it is advisable to work with raster cell size significantly less
+then known accuracy of data. Resolution of maps can be compatible with
+resolution of your scanner and printer - modern processors are powerful
+enough to bear it, so raster doesn't mean loss of precession.
+<P>
+This data format is able to hold values in range 0..65535. While it is
+always sufficient for classification layers, it can look that for
+numeric layers it is better to use real numbers. But data always have
+finite accuracy, which is usially less than 1/65535 of total range,
+and even if we can take measurements with larger precession, we should
+take into account spatial variability within one raster cell.
+<P>
+For example, if we have map of relief of Russia with 500 meter cell, 
+we need to represent range from -28 (Caspian coast) to 5642 (Elbrus)
+meters above sea level. Thus smallest usable unit is about 10 cm.
+Some points' altitude may be measured with more accuracy (for example,
+triangualtion points), but each raster cell represents 500x500 meters
+square which always would have more than 10cm of variability.
+Even if value of our layer should have more precession in some part
+of its range, we could use non-linear (for instance logarithmic) mapping
+of raster cell values to layer values.
+<P>
+But even with compression, raster files occupy significant storage
+space. So, we should avoid duplication of them if possible. Thus we 
+introduce concept of <I>reclass tables</I>. Reclass table maps values
+of raster cell to another set of integer in arbitrary order. Don't mix
+reclass table with mapping function which is used for convert raster
+cell values to real units of numeric layer. For example if we have
+statistical data of populations by county and want to create population 
+them as map, we can use reclass table over county map. Several counties
+with different names, which have distinct values in county map raster,
+can be mapped to same class in population density map if their population
+density is same.
+<P>
+Point layer is just list of triplets &lt; X, Y, Value &gt;.  Typically
+point layer doesn't contain more than few thousands of points, so there
+is no need to optimize performance or storage space.
+<P>
+Natural storage form of one-dimensional layer is vector format. 
+It is most questionable area in current fGIS design. There are a lot of
+advantages of EPPL7 vector format (compactness, speed of processing),
+but it have only one drawback, which overcomes them all - it can
+associate only one value with whole vector object (polyline). But
+if we are talking about the function, defined on set of lines, whe
+should be prepared that this function (stream depth for instance) would
+vary from one end of line to other. 
+<P>
+It is also a question how intersections and joints of lines should
+be stored/interpreted, becouse most interesting network analysis
+algorithmes require ability to cross joints and intersections.
+<P>
+
+<A NAME="toc_section4"></A><H4>Regions and chartographic projection</H4>
+
+Study area usially have hierarchical structure. For example Russia
+can be subdivided to administrative regions, which consists of
+districts. United States consists  of states, which are divided into
+counties. Often study is concerned only with one of such hierarchy
+levels, but there are opposite examples. 
+<P>
+Each hierarchy level have its typical data accuracy (which is rough 
+representation of map scale in GIS world, becouse GIS maps can be
+arbitrarily scaled, but only certain scale range make sense for
+particular data accuracy), chartographic projection (especially
+significant for large areas like whole country or continent).
+On thematic maps like soils or vegetation, different classifications
+can be used in different scales.
+<P>
+So, f(GIS) uses concept of <I>regions</I>. Region is set of layers,
+which cover almost same territory, have exactly same projection and
+simular spatial resolution. Regions can be nested, i.e. region of 
+Russia can have several subregions of administrative regions, which
+have subregions of districts etc. In this case there should be <i>base
+layer</i>
+which have subregion names as values. When copiing data between regions
+f(GIS) authomatically performs neccessary projection and resolution
+ conversion using base layer as reference. Classification conversion,
+if neccessary, should be performed by user, becouse it requires
+knowledge in problem area.
+
+<A NAME="toc_section5"></A><H3>Program design</H3>
+f(GIS) is designed as set of extensions to Tcl programming language
+and set of independent utilities, which perform most time consuming
+raster and vector processing tasks. Thus long operations can be launched
+in background as separate while user continues to view/analyze data in 
+main program.
+<P>
+From users point of view, fGIS is Tcl application which allows him
+to operate with set of layers from GUI as well as from Tcl command line.
+It is essential design constraing that there should be no operation,
+which can be performed from GUI, but couldn't be from Tcl script. There
+should be way to automate everything. Other way around is enusred by
+very nature of Tcl. Nothing prevent user, which have direct access to
+Tcl interpreter from creating new button or menu item and binding any
+Tcl command to it. 
+<P>
+From programmers point of view, fGIS consists of several abstraction
+levels, all available for extension and modification. And I think that
+every fGIS user can eventually become programmer, if he discoveres need
+to implement some, just invented, data analysis algorithm, or customize
+graphical user interface to his needs. Relationship between fGIS
+abstraction levels is shown on this figure.
+<P>
+<IMG SRC=levels.gif ALIGN=center>
+<P>
+<A NAME="toc_section6"></A><H4>Layer as Tcl object</H4>
+Layers in fGIS behave like objects in object-oriented programming
+language. Once created with <B>layer</b> command they become tcl
+commands itself (i.e. name of layer can be used as Tcl command),
+just like Tk widget. Options of layer command allow to manipulate
+properties of layer and store layer definition to file. This file
+is just Tcl script which creates neccessary subobjects and invokes
+appropriate command to create layer.
+<P>Layer have following properties
+<DL>
+<DT>It can return value by coordinates
+<DD> It is why whole thing is about
+<DT> It can one or more ways to draw itself
+<DD> Raster layer can be drawn in opaque colors, so only offsite area is
+transparent or using transparent monochrome patterns, thus allowing to
+overlay one raster over another. In most existing raster GIS, like
+Idrisi only vector or point layers can be overlayed over raster. 
+In f(GIS) <B>any</B> 
+layer can be drawn as overlay
+<DT> It has underlying data source
+<DD> Data source for layers typically consist of some object which can
+ return integer value given coordinate (raster file, combined with
+reclass table, for example) and <i>legend table</i> or <i>map
+function</i> which maps values of underlying raster object to
+thematically meaningful values.
+<DT> It has visualization parameters
+<DD> visualization fo layer is controlled by several parameters such as
+color palette, pattern set, flag, indicating if boundaries between
+classes are drawn or not. All these parameters can be changed
+interactively.
+<DT> It has metadata
+<DD> Metadata for layer typically include layer title, units in which
+its values are managed, spatial resolution and value precession.
+Chartographic projection is property of region rather than layer.
+</DL> 
+
+Besides layer types described <A HREF=#layerclass>above</A> fGIS have
+<I>object</I> layer type. This layer type can consist of any objects
+allowed in Tcl canvas - lines, arcs, polygons, images with only one
+thematic value for each object. This type is primarily for annotation
+purposes, but also can be used as substitute for vector layers, while
+later are not developed
+<P>
+<A NAME="toc_section7"></A><H4>Planchet - object for displaying maps</H4>
+Another type of object which is essential for fGIS user is
+<i>planchet</I>. It is Tk widget like canvas (and actially derived from
+canvas) which has chartographic projection and real-world coordinates.
+It is used for displaying layers and picking points on them. Becouse
+it has real-world coordinates and physical size on the screen, it always
+knows its scale. When scale is changed (via zoom or window resize operation),
+all layers currently displayed on planchet are redrawn appropriately.
+<P>
+Planchet also have <i>look feature</I>. If right mouse button is pressed
+on some point in planchet, it displays values of several layers in this
+point in pop-up window.
+<P>
+There can be also &quot;friend widgets&quot; like status line which
+display current coordinates if mouse is over planchet or zoom/unzoom
+buttons which change its state depending of current state of planchet.
+<P>
+<A NAME="toc_section8"></A><H4>Low level objects</H4>
+
+There are additional objects like rasters, palettes and pattern sets.
+But user seldom need to operate on them directly. They are primarily
+for developers of new layer types.
+
+<A NAME="toc_section9"></A><H4>GIS operation</H4>
+GIS operation like calculationg buffer zones or computing new layer
+from several existing are performed by separate <A
+HREF=#epu>utilities</a> running in background. For user convinience
+there are tcl procedures which take one or more layer names as arguments
+and call appropriate utility.
+<P>
+Example of such procedure is interregion copy command, which tooks
+layer name and name of target region, determines projections and calls
+projection conversion program.
+<P>
+In some cases such procedures need to perform sufficient preprocessing
+of user-supplied arguments 
+<A NAME="toc_section10"></A><H4>Utilities</H4>
+
+GIS processing utilities are more general than fGIS. They use just
+data files and user-supplied arguments. So they can be used separately
+from fGIS, for example by users of EPPL7 GIS. Utilities are designed
+for batch environment, so they use exit codes to report status and
+stdin/stdout to recieve and return values which are not fit in command
+line. Important concept of these utilities is that user shouldn't worry
+about raster cell size. All utilites which operate on several raster
+files are able to deal with files with different cell sizes as long
+as there is non-empty intersection in terms of real-world coordinates.
+
+<A NAME="toc_section11"></A><H4>Data access library</H4>
+
+Both low-level Tcl objects (rasters, vectors) and utilites use common
+C library to access data files. This library provides appropriately
+high-level framework for those who want implement own data analysis
+ algorithmes. For example it includes iterator routines, which recieve
+user-written function and open raster file and perform this function
+on every cell of given file. While library operates primarily in terms
+of raster cells (which can be important for cellular automata
+algorithmes, which need to distinguish between ``this cell'' and
+``neighbouring cell'') it provides ways to process files with different
+cell sizes simulateously.
+
+
+</BODY>
+</HTML> 
+
+
+
+
+
+
+
+
+
diff --git a/doc/doc.formats b/doc/doc.formats
new file mode 100644 (file)
index 0000000..5f62da2
--- /dev/null
@@ -0,0 +1,37 @@
+ æÁÊÌ ÏÐÉÓÁÎÉÑ ÒÅÇÉÏÎÁ
+îÁÚÙ×ÁÅÔÓÑ .region
+ÉÌÉ REGION × Windows ×ÅÒÓÉÉ
+
+óÏÄÅÒÖÉÔ ÓÌÅÄÕÀÝÕÀ ÉÎÆÏÒÍÁÃÉÀ
+
+1. NAME "îÁÚ×ÁÎÉÅ ÒÅÇÉÏÎÁ"
+   CYRILLIC ÉÍÑ ËÏÄÉÒÏ×ËÉ 
+2. PROJECTION ÎÁÚ×ÁÎÉÅ
+   ....   
+   END
+ïÐÉÓÁÎÉÅ ÐÒÏÅËÃÉÉ × ÆÏÒÍÁÔÅ, ÓÏ×ÐÁÄÁÀÝÅÍ Ó ARC/Info.
+3. SHOW ÓÐÉÓÏË ËÁÒÔ
+ éÍÅÎÁ ËÁÒÔ, ËÏÔÏÒÙÅ ×Ù×ÏÄÑÔÓÑ ÐÒÉ ×ÈÏÄÅ × ÄÁÎÎÙÊ ÒÅÇÉÏÎ.
+4  DATABASE ÉÍÑ ÂÁÚÙ ÄÁÎÎÙÈ
+5. MAP ÉÍÑ ÆÁÊÌÁ
+éÍÑ ÒÁÓÔÒÁ, ÉÓÐÏÌØÚÕÅÍÏÇÏ ÄÌÑ ÐÅÒÅÈÏÄÁ Ë ÒÅÇÉÏÎÁÍ ÓÌÅÄÕÀÝÅÇÏ ÕÒÏ×ÎÑ
+6. SUBREGIONS
+ËÌÁÓÓ ÉÍÑ ËÁÔÁÌÏÇÁ
+...
+ÉÌÉ SUBREGIONS QUERY sql-ÚÁÐÏÒÏÓ
+æÁÊÌ ÏÐÉÓÁÎÉÑ ËÁÒÔÙ
+
+NAME ÉÍÑ
+[GROUP ÉÍÑ ÇÒÕÐÐÙ ËÁÒÔ]
+[CYRILLIC ÉÍÑ ËÏÄÉÒÏ×ËÉ]
+INFO
+ÎÅÓÔÒÕËÔÕÒÉÒÏ×ÁÎÎÑÊ ÔÅËÓÔ
+ENDINFO
+RASTER ÉÍÑ ÆÁÊÌÁ
+RECLASS [QUERY sql- ÚÁÐÒÏÓ|FILE ÉÍÑ|\nÓÐÉÓÏË ÏÐÅÒÁÔÏÒÏ×]
+[RECALC ×ÙÒÁÖÅÎÉÅ \n[CCT\nÔÁÂÌÉÃÁ ÉÎÔÅÒ×ÁÌÏ×|INTERVAL ÞÉÓÌÏ] 
+|LEGEND [FILE ÉÍÑ|QUERY sql-ÚÁÐÒÏÓ|\nÔÅËÓÔ ÌÅÇÅÄÙ]
+PALETTE [ÉÍÑ ÆÁÊÌÁ|\n ÓÐÉÓÏË ÏÐÉÓÁÎÉÊ Ã×ÅÔÏ×]
+[SYMBOLS/PATTERNS [BORDER]] ÓÐÉÓÏË ÏÐÉÓÁÎÉÊ ÛÔÒÉÈÏ×ÏË
+COMPANIONS ÓÐÉÓÏË ÉÍÅΠËÁÒÔ - ÉÍÅÎÁ ËÁÒÔ, ËÏÔÏÒÙÅ ÎÁÄÏ ×Ù×ÏÄÉÔØ, ÅÓÌÉ
+ÕËÁÚÁÎÎÁÑ ×Ù×ÏÄÉÔÓÑ ËÁË ÏÓÎÏ×ÎÁÑ 
diff --git a/doc/epu_doc.tex b/doc/epu_doc.tex
new file mode 100644 (file)
index 0000000..7f4f896
--- /dev/null
@@ -0,0 +1,181 @@
+\documentclass{article}
+\usepackage{russian,academy}
+\title{Environmental planning utilities\\òÕËÏ×ÏÄÓÔ×Ï ÐÏÌØÚÏ×ÁÔÅÌÑ}
+\author{÷.â.~÷ÁÇÎÅÒ}
+\newcommand{\obsoletes}[1]{\par úÁÍÅÎÑÅÔ ËÏÍÁÎÄÙ EPPL7: {\bf #1}\par}
+\begin{document}
+\maketitle
+\section*{÷×ÅÄÅÎÉÅ}
+
+Environmental planning utilities (ÄÁÌÅÅ EPU)~--- ÎÁÂÏÒ ÐÒÏÇÒÁÍÍ, ×ÙÐÏÌÎÑÀÝÉÈ
+ÐÒÉÍÅÒÎÏ ÔÅ ÖÅ ÏÐÅÒÁÃÉÉ, ÞÔÏ É ËÏÍÁÎÄÙ çéó EPPL7. ïÓÎÏ×ÎÙÍ ÍÏÔÉ×ÏÍ ÉÈ
+ÒÁÚÒÁÂÏÔËÉ ÂÙÌÏ ÐÒÅÏÄÏÌÅÎÉÅ ÎÅËÏÔÏÒÙÈ ÏÇÒÁÎÉÞÅÎÉÊ EPPL7 ×ÅÒÓÉÉ 3.0,
+Ó×ÑÚÁÎÎÙÈ Ó 16-ÂÉÔÎÏÊ ÁÒÈÉÔÅËÔÏÒÏÊ ÜÔÏÊ ÐÒÏÇÒÁÍÍÙ, É ÏÂÅÓÐÅÞÅÎÉÅ ×ÏÚÍÏÖÎÏÓÔÉ
+ÒÁÂÏÔÙ Ó ÆÁÊÌÁÍÉ EPPL7 × ÓÒÅÄÅ UNIX.
+
+EPPL7 ÒÁÓÛÉÆÒÏ×Ù×ÁÅÔÓÑ ËÁË
+Environmental Planning Programming Language. ë ÓÏÖÁÌÅÎÉÀ × ÑÚÙËÅ EPPL7 
+ÎÅ È×ÁÔÁÅÔ ÓÔÒÕËÔÕÒ ÕÐÒÁ×ÌÅÎÉÑ, ÐÅÒÅÍÅÎÎÙÈ É ÄÒÕÇÉÈ ÐÏÌÅÚÎÙÈ ËÏÎÓÔÒÕÔÃÉÊ,
+× ÓÉÌÕ ÞÅÇÏ ÏΠÎÅ ÐÒÉÇÏÄÅΠÄÌÑ ÓÅÒØÅÚÎÏÇÏ ÐÒÏÇÒÁÍÍÉÒÏ×ÁÎÉÑ.
+
+ðÏÜÔÏÍÕ, ÐÒÉ ÒÁÚÒÁÂÏÔËÅ EPU ÂÙÌÏ ÒÅÛÅÎÏ ÎÅ ÐÙÔÁÔØÓÑ ×ÏÓÐÒÏÉÚ×ÅÓÔÉ ËÏÎÃÅÐÃÉÀ
+ÏÒÉÇÉÎÁÌÁ, Á ÒÁÚÒÁÂÏÔÁÔØ ÎÁÂÏÒ ÏÔÄÅÌØÎÙÈ ËÏÍÁÎÄÎÏ-ÓÔÒÏÞÎÙÈ ÕÔÉÌÉÔ, 
+×ÙÐÏÌÎÑÀÝÉÈ ÏÓÎÏ×ÎÙÅ çéó ÏÐÅÒÁÃÉÉ, ÞÔÏ ÐÏÚ×ÏÌÉÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÄÌÑ ÒÅÛÅÎÉÑ
+ËÏÎËÒÅÔÎÙÈ ÚÁÄÁÞ ÕÖÅ ÓÕÝÅÓÔ×ÕÀÝÉÅ ÒÁÚ×ÉÔÙÅ ÓËÒÉÐÔÏ×ÙÅ ÑÚÙËÉ (shell, tcl, perl).
+
+÷ÙÄÅÌÅÎÉÅ ÜÔÉÈ ÏÐÅÒÁÃÉÊ × ÏÔÄÅÌØÎÙÅ ÐÒÏÇÒÁÍÍÙ ÉÍÅÅÔ ÅÝÅ É ÔÏ ÐÒÅÉÍÕÝÅÓÔ×Ï,
+ÞÔÏ ÜÔÉ ÏÐÅÒÁÃÉÉ, ÏÂÙÞÎÏ ÚÁÎÉÍÁÀÝÉÅ ÍÎÏÇÏ ×ÒÅÍÅÎÉ, ÍÏÇÕÔ ÂÙÔØ ÚÁÐÕÝÅÎÙ
+ËÁË ÐÁÒÁÌÌÅÌØÎÙÅ ÐÒÏÃÅÓÓÙ, ÎÅÚÁ×ÉÓÉÍÏ ÏÔ ÔÏÇÏ, ÐÏÄÄÅÒÖÉ×ÁÀÔÓÑ ÌÉ ÏÐÅÒÁÃÉÏÎÎÏÊ
+ÓÉÓÔÅÍÏÊ ÍÎÏÇÏÎÉÔÅ×ÙÅ ÐÒÏÇÒÁÍÍÙ.
+
+õÔÉÌÉÔÙ ÒÁÚÒÁÂÁÔÙ×ÁÌÉÓØ Ó ÕÞÅÔÏÍ ÔÒÅÂÏ×ÁÎÉÑ ÍÁËÓÉÍÁÌØÎÏÊ ÐÅÒÅÎÏÓÉÍÏÓÔÉ,
+É ÔÅÏÒÅÔÉÞÅÓËÉ ÄÏÌÖÎÙ ËÏÍÐÉÌÉÒÏ×ÁÔØÓÑ É ×ÙÐÏÌÎÑÔØÓÑ ÎÁ ÌÀÂÏÊ 32 É ÂÏÌÅÅ
+ÒÁÚÒÑÄÎÏÊ ÐÌÁÔÆÏÒÍÅ (DOS DPMI, Windows NT, Unix, VMS). ÷ ÎÁÓÔÏÑÝÅÅ ×ÒÅÍÑ
+ÏÎÉ ÂÙÌÉ ÐÒÏÔÅÓÔÉÔÏ×ÁÎÙ ÎÁ ÐÌÁÔÆÏÒÍÁÈ DOS/DOS4GW, Linux i386 É Solaris Sparc,
+ÞÔÏ ÐÏÚ×ÏÌÑÅÔ ÕÔ×ÅÒÖÄÁÔØ ÞÔÏ ÏÎÉ ÎÅÚÁ×ÉÓÉÍÙ ÏÔ ÐÏÒÑÄËÁ ÂÁÊÔÏ× × ÐÒÏÃÅÓÓÏÒÅ.
+÷ÅÒÏÑÔÎÅÅ ×ÓÅÇÏ, × ÕÔÉÌÉÔÁÈ É ÉÓÐÏÌØÚÕÅÍÙÈ ÂÉÂÌÉÏÔÅËÁÈ ÓÕÝÅÓÔ×ÕÀÔ ÍÅÓÔÁ,
+ËÏÔÏÒÙÅ ÐÏÔÏÒÅÂÕÀÔ ÐÒÁ×ËÉ ÐÒÉ ÐÅÒÅÈÏÄÅ Ë 64-ÒÁÚÒÑÄÎÏÊ ÁÒÈÉÔÅËÔÕÒÅ.
+
+÷ Ó×ÑÚÉ Ó ÔÅÍ, ÞÔÏ EPU ÉÎÔÅÎÓÉ×ÎÏ ÉÓÐÏÌØÚÕÀÔ ÏÐÅÒÁÃÉÉ Ó ÐÌÁ×ÁÀÝÅÊ ÚÁÐÑÔÏÊ,
+ÍÙ ÎÅ ÒÅËÏÍÅÎÄÕÅÍ ËÏÍÐÉÌÉÒÏ×ÁÔØ ÉÈ ÐÒÉ ÐÏÍÏÝÉ DJGPP ×ÅÒÓÉÊ 1.x É 2.0x,
+ÐÏÓËÏÌØËÕ ÜÔÏÔ ËÏÍÐÉÌÑÔÏÒ ÉÍÅÅÔ ÛÉÒÏËÏ ÉÚ×ÅÓÔÎÙÅ ÐÒÏÂÌÅÍÙ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ
+ÓÏÐÒÏÃÅÓÓÏÒÁ. 
+
+\section{ëÏÎÃÅÐÃÉÑ EPU}
+
+EPU ÒÁÂÏÔÁÀÔ ÐÒÅÉÍÕÝÅÓÔ×ÅÎÎÏ Ó ÒÁÓÔÒÏ×ÙÍÉ ËÁÒÔÁÍÉ. ÷ ÏÔÌÉÞÉÅ ÏÔ ÂÏÌØÛÉÎÓÔ×Á
+ÄÒÕÇÉÈ ÒÁÓÔÒÏ×ÙÈ çéó, ÓÞÉÔÁÅÔÓÑ ÞÔÏ ÒÁÓÔÒÏ×ÁÑ ËÁÒÔÁ Ñ×ÌÑÅÔÓÑ ÍÏÄÅÌØÀ ÎÅËÏÊ
+ÃÅÌÏÞÉÓÌÅÎÎÏÊ ÉÌÉ ×ÅÝÅÓÔ×ÅÎÎÏÊ ÆÕÎËÃÉÉ ÏÔ ËÏÏÒÄÉÎÁÔ, É ÒÁÚÍÅÒ ÑÞÅÊËÉ ÒÁÓÔÒÁ
+ÎÅ Ñ×ÌÑÅÔÓÑ ÓÕÝÅÓÔ×ÅÎÎÙÍ ÄÌÑ ÂÏÌØÛÉÎÓÔ×Á ÏÐÅÒÁÃÉÊ, ÈÏÔÑ ÉÍÅÎÎÏ ÏΠÓÌÕÖÉÔ
+ÏÓÎÏ×ÎÏÊ ÍÅÒÏÊ ÔÏÞÎÏÓÔÉ.
+
+ðÏÜÔÏÍÕ, ×ÓÅ ÐÒÏÇÒÁÍÍÙ EPU, ÏÂÒÁÂÁÂÙ×ÁÀÝÉÅ ÎÅÓËÏÌØËÏ ×ÈÏÄÎÙÈ ÆÁÊÌÏ×, ÐÏÚ×ÏÌÑÀÔ
+ÉÓÐÏÌØÚÏ×ÁÔØ ÆÁÊÌÙ, ËÏÏÒÄÉÎÁÔÙ ÒÁÍËÉ É ÒÁÚÍÅÒ ÑÞÅÊËÉ ËÏÔÏÒÙÈ ÎÅ ÓÏ×ÐÁÄÁÀÔ%
+\footnote{åÓÌÉ ËÁËÁÑ-ÌÉÂÏ ÉÚ ÕÔÉÌÉÔ ÏÔËÁÚÙ×ÁÅÔÓÑ ×ÏÓÐÒÉÎÉÍÁÔØ ÔÁËÉÅ ÆÁÊÌÙ,
+ÛÌÉÔÅ bug-report.}.
+ðÒÏÓÔÒÁÎÓÔ×ÅÎÎÏÅ ÓÏÏÔ×ÅÔÓÔ×ÉÅ ÍÅÖÄÕ ÆÁÊÌÁÍÉ ÐÒÉ ÜÔÏÍ ÕÓÔÁÎÁ×ÌÉ×ÁÅÔÓÑ ÐÏ
+ÍÉÒÏ×ÙÍ ËÏÏÒÄÉÎÁÔÁÍ (ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ ËÏÏÒÄÉÎÁÔÙ × ÔÅÒÍÉÎÏÌÏÇÉÉ EPPL7). 
+
+áÎÁÌÏÇÉÞÎÏ, ÚÎÁÞÅÎÉÅ offsite (ÎÅÔ ÄÁÎÎÙÈ) ÐÒÁËÔÉÞÅÓËÉ ×ÓÅÇÄÁ ÐÒÉÎÉÍÁÅÔÓÑ
+×Ï ×ÎÉÍÁÎÉÅ, ÈÏÔÑ ÏÔÄÅÌØÎÙÅ ÕÔÉÌÉÔÙ ÍÏÇÕÔ ÉÍÅÔØ ÓÐÅÃÉÁÌØÎÙÊ ËÌÀÞ, 
+ÐÏÚ×ÏÌÑÀÝÉÊ ÎÅ ÕÞÉÔÙ×ÁÔØ offsite.
+
+ëÁÒÔÙ EPPL7 ÍÏÖÎÏ ÒÁÚÄÅÌÉÔØ ÎÁ Ä×Á ËÌÁÓÓÁ~--- ËÁÒÔÙ ËÏÌÉÞÅÓÔ×ÅÎÎÙÈ ×ÅÌÉÞÉÎ
+(ÃÉÆÒÏ×ÙÅ ÍÏÄÅÌÉ) É ËÁÒÔÙ ËÌÁÓÓÉÆÉËÁÃÉÊ, ÞÉÓÌÏ×ÙÅ ÚÎÁÞÅÎÉÑ ËÌÁÓÓÏ× ËÏÔÏÒÙÈ
+ÎÅ ÉÍÅÀÔ ÄÒÕÇÏÇÏ ÓÍÙÓÌÁ, ËÒÏÍÅ ËÁË ÉÎÄÅËÓÙ ÔÅËÓÔÏ×ÙÈ ÚÎÁÞÅÎÉÊ × ÌÅÇÅÎÄÅ.
+
+æÏÒÍÁÔ ÆÁÊÌÏ× EPPL7 ÎÅ ÐÏÚ×ÏÌÑÅÔ ×Ï ×ÓÅÈ ÓÌÕÞÁÑÈ ÈÒÁÎÉÔØ ÓÅÍÁÎÔÉÞÅÓËÏÅ 
+ÚÎÁÞÅÎÉÅ Ó ÔÒÅÂÕÅÍÏÊ ÔÏÞÎÏÓÔØÀ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ × ÆÁÊÌÅ ÄÁÎÎÙÈ, ÐÏÓËÏÌØËÕ
+ÄÉÁÐÁÚÏΠ×ÏÚÍÏÖÎÙÈ ÚÎÁÞÅÎÉÊ ÆÁÊÌÏ× ÏÇÒÁÎÉÞÅΠËÏÒÏÔËÉÍ ÂÅÚÚÎÁËÏ×ÙÍ ÃÅÌÙÍ
+(0--65535). ðÏÜÔÏÍÕ ÔÅ ÐÒÏÇÒÁÍÍÙ EPU, ËÏÔÏÒÙÅ ×ÙÐÏÌÎÑÀÔ ÍÁÔÅÍÁÔÉÞÅÓËÉÅ ÏÐÅÒÁÃÉÉ
+ÎÁÄ ÚÎÁÞÅÎÉÑÍÉ ËÁÒÔÙ, ÐÏÚ×ÏÌÑÀÔ ÚÁÄÁÔØ ÍÁÓÛÔÁÂÎÙÊ ËÏÜÆÆÉÃÉÅÎÔ É ÓÍÅÝÅÎÉÅ
+ÎÕÌÅ×ÏÇÏ ËÌÁÓÓÁ.
+
+÷ÏÚÍÏÖÎÏÓÔÉ EPU ÐÏ ÒÁÂÏÔÅ Ó ×ÅËÔÏÒÎÙÍÉ ÆÁÊÌÁÍÉ EPPL7 ÓÕÝÅÓÔ×ÅÎÎÏ ÏÇÒÁÎÉÞÅÎÙ.
+üÔÏ Ó×ÑÚÁÎÏ × ÏÓÎÏ×ÎÏÍ Ó ÔÅÍ, ÞÔÏ ÐÒÅÄÐÏÌÁÇÁÅÔÓÑ × ÄÁÌØÎÅÊÛÅÍ ÐÅÒÅÊÔÉ
+ÏÔ ÆÏÒÍÁÔÁ DGT Ë ÂÏÌÅÅ ÇÉÂËÏÍÕ ×ÅËÔÏÒÎÏÍÕ ÆÏÒÍÁÔÕ fGIS.
+
+ðÏ ×ÏÚÍÏÖÎÏÓÔÉ, ÍÙ ÓÔÁÒÁÌÉÓØ ÏÂßÅÄÉÎÉÔØ ÆÕÎËÃÉÉ ÎÅÓËÏÌØËÉÈ ËÏÍÁÎÄ EPPL7
+× ÅÄÉÎÕÀ ÕÔÉÌÉÔÕ, ÔÁË ËÁË ÜÔÏ ÉÎÏÇÄÁ ÐÏÚ×ÏÌÑÅÔ ÄÏÂÉÔØÓÑ ÎÏ×ÏÇÏ ËÁÞÅÓÔ×Á.
+
+éÚ ÕÔÉÌÉÔ EPU ÎÁÍÅÒÅÎÎÏ ÉÓËÌÀÞÅÎÁ ×ÓÑËÁÑ ÉÎÔÅÒÁËÔÉ×ÎÏÓÔØ, ÐÏÓËÏÌØËÕ
+ÏÎÉ ÏÒÉÅÎÔÉÒÏ×ÁÎÙ ÎÁ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÉÚ ÓËÒÉÐÔÏ×.
+\section{õÔÉÌÉÔÙ EPU}
+\subsection{border}\label{border}
+\obsoletes{BORDER (×ÁÒÉÁÎÔ Ó ÓÏÚÄÁÎÉÅÍ {\tt dgt}-ÆÁÊÌÁ)}
+ðÏ ÚÁÄÁÎÎÏÍÕ ÒÁÓÔÒÏ×ÏÍÕ ÆÁÊÌÕ ÓÏÚÄÁÅÔ ×ÅËÔÏÒÎÙÊ ÆÁÊÌ, × ËÏÔÏÒÏÍ ÏÔÒÉÓÏ×Ù×ÁÅÔ
+ÇÒÁÎÉÃÙ ÍÅÖÄÕ ËÌÁÓÓÁÍÉ ÉÓÈÏÄÎÏÇÏ ÒÁÓÔÒÁ. ðÏ ÕÍÏÌÞÁÎÉÀ, ÇÒÁÎÉÃÁ ÏÔÒÉÓÏ×Ù×ÁÅÔÓÑ
+ÔÏÞÎÏ, × ÒÅÚÕÌØÔÁÔÅ ÞÅÇÏ ÌÉÎÉÑ ÐÒÉ ÂÏÌØÛÏÍ Õ×ÅÌÉÞÅÎÉÉ ×ÙÇÌÑÄÉÔ ËÁË ÓÔÕÐÅÎÞÁÔÁÑ.
+
+ðÁÒÁÍÅÔÒ tolerance ÐÏÚ×ÏÌÑÅÔ ÕÐÒÁ×ÌÑÔØ ÓÇÌÁÖÉ×ÁÎÉÅÍ ÌÉÎÉÊ. 
+
+ëÁË É ×Ï ×ÓÅÈ ÏÓÔÁÌØÎÙÈ ÕÔÉÌÉÔÁÈ EPU, ÏÂÌÁÓÔØ ÌÅÖÁÛÁÑ ÚÁ ÐÒÅÄÅÌÁÍÉ ÒÁÍËÉ
+ËÁÒÔÙ ÓÞÉÔÁÅÔÓÑ offsite. ðÏÜÔÏÍÕ × ÔÅÈ ÍÅÓÔÁÈ ÇÄÅ onsite-ËÌÁÓÓÙ ×ÐÏÌÔÎÕÀ
+ÐÒÉÌÅÇÁÀÔ Ë ÒÁÍËÅ, ÏÔÒÉÓÏ×Ù×ÁÅÔÓÑ ÇÒÁÎÉÃÁ. ôÁËÏÅ ÐÏ×ÅÄÅÎÉÅ ÎÅ ×ÓÅÇÄÁ ÖÅÌÁÔÅÌØÎÏ,
+ÐÏÜÔÏÍÕ ÅÇÏ ÍÏÖÎÏ ÏÔËÌÀÞÉÔØ.
+
+{\bf æÏÒÍÁÔ ×ÙÚÏ×Á:}
+
+{\tt
+  \bf border \rm\it ËÌÀÞÉ ÉÍÑ ÆÁÊÌÁ\rm
+}
+
+{\bf ëÌÀÞÉ:}
+\begin{description}
+\item[-\%] ÷ ÐÒÏÃÅÓÓÅ ÒÁÂÏÔÙ ×Ù×ÏÄÉÔØ ÎÁ stdout ÐÒÏÃÅÎÔ ÏÂÒÁÂÏÔÁÎÎÏÊ ËÁÒÔÙ.
+\item[-l] óÏÚÄÁÔØ ÍÅÔËÉ ÐÏÌÉÇÏÎÏ×. (ÐÏËÁ ÎÅ ÎÁÐÉÓÁÎÏ)
+\item[-m] ðÏÄÁ×ÉÔØ ÒÉÓÏ×ÁÎÉÅ ÇÒÁÎÉà×ÄÏÌØ ÒÁÍËÉ ËÁÒÔÙ
+\item[-o ÉÍÑ ÆÁÊÌÁ] úÁÄÁÔØ ÉÍÑ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ. åÓÌÉ ÎÅ ÚÁÄÁÎÏ, ÉÍÑ ×ÙÈÏÄÎÏÇÏ
+      ÆÁÊÌÁ ÄÅÌÁÅÔÓÑ ÉÚ ÉÍÅÎÉ ×ÈÏÄÎÏÇÏ ÚÁÍÅÎÏÊ ÒÁÓÛÉÒÅÎÉÑ {\tt .epp} ÎÁ {\tt .dgt}
+\item[-t ÞÉÓÌÏ] úÁÄÁÔØ ÚÎÁÞÅÎÉÅ tolerance. üÔÏ ÚÎÁÞÅÎÉÅ ÚÁÄÁÅÔÓÑ × ÑÞÅÊËÁÈ
+ ÉÓÈÏÄÎÏÇÏ ÒÁÓÔÒÁ É ÉÍÅÅÔ ÓÍÙÓÌ ÍÁËÓÉÍÁÌØÎÏÊ ÄÌÉÎÙ ÏÔÒÅÚËÁ, ÏÂÒÁÂÁÔÙ×ÁÅÍÏÊ
+ÁÌÇÏÒÉÔÍÏÍ ÓÇÌÁÖÉ×ÁÎÉÑ. ÷ ÂÏÌØÛÉÎÓÔ×Å ÓÌÕÞÁÅ× ÚÎÁÞÅÎÉÅ 3 ÄÁÅÔ ÕÄÏ×ÌÅÔ×ÏÒÉÔÅÌØÎÙÅ
+ÒÅÚÕÌØÔÁÔÙ.
+\end{description}
+
+\subsection{classify}\label{classify}
+\obsoletes{RECLASS}
+óÏÚÄÁÅÔ ÎÏ×ÕÀ ÒÁÓÔÒÏ×ÕÀ ËÁÒÔÕ ÐÏ ÏÄÎÏÊ ÉÌÉ ÎÅÓËÏÌØËÉÍ ÓÔÁÒÙÍ, ÉÓÐÏÌØÚÕÑ
+ÚÁÄÁÎÎÙÊ ÎÁÂÏÒ ÐÒÁ×ÉÌ. ÷ ÏÔÌÉÞÉÅ ÏÔ ËÏÍÁÎÄÙ RECLASS EPPL7 ÏÐÅÒÉÒÕÅÔ ÎÅ
+Ó ÞÉÓÌÏ×ÙÍÉ ÚÎÁÞÅÎÉÑÍÉ ËÌÁÓÓÏ×, Á Ó ÔÅËÓÔÁÍÉ ÌÅÇÅÎÄÙ. ðÒÅÄÎÁÚÎÁÞÅÎÁ
+× ÏÓÎÏ×ÎÏÍ ÄÌÑ ËÁÒÔ ËÌÁÓÓÉÆÉËÁÃÉÊ, × ÏÔÌÉÞÉÉ ÏÔ evaluate (ÒÁÚÄÅÌ~% 
+\ref{evaluate}), ÐÒÅÄÎÁÚÎÁÞÅÎÎÏÊ × ÏÓÎÏ×ÎÏÍ ÄÌÑ ÃÉÆÒÏ×ÙÈ ÍÏÄÅÌÅÊ.
+
+\subsection{cluster}\label{cluster}
+\obsoletes{CLUSTER, RASTERIZE}
+óÏÚÄÁÅÔ ÎÏ×ÕÀ ËÁÒÔÕ, ÚÎÁÞÅÎÉÑ ËÌÁÓÓÏ× ËÏÔÏÒÏÊ ÐÒÅÄÓÔÁ×ÌÑÀÔ ÓÏÂÏÊ 
+ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÙÅ ÎÏÍÅÒÁ ÒÅÇÉÏÎÏ× ÉÓÈÏÄÎÏÊ ËÁÒÔÙ. ÷ ÏÔÌÉÞÉÅ ÏÔ ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÅÊ
+ËÏÍÁÎÄÙ EPPL7, ÇÒÁÎÉÃÁÍÉ ÒÅÇÉÏÎÏ× ÍÏÇÕÔ ÂÙÔØ ÎÅ ÔÏÌØËÏ ÌÉÎÉÉ ÏÐÒÅÄÅÌÅÎÎÏÇÏ
+ËÌÁÓÓÁ, ÎÏ É ÐÅÒÅÈÏÄÙ ÍÅÖÄÕ ËÌÁÓÓÁÍÉ. üÔÁ ÖÅ ÕÔÉÌÉÔÁ ×ÙÐÏÌÎÑÅÔ ÒÁÓÔÅÒÉÚÁÃÉÀ
+×ÅËÔÏÒÎÏÇÏ ÆÁÊÌÁ. 
+
+
+\subsection{dgt2gen}\label{dgt2gen}
+\obsoletes{EXPORT DGT$\bigarrowleft$ARC Generate}
+ëÏÎ×ÅÒÔÉÒÕÅÔ ×ÅËÔÏÒÎÙÊ ÆÁÊÌ EPPL7 × ÆÁÊÌ × ÆÏÒÍÁÔÅ, ÐÒÉÇÏÄÎÏÍ ÄÌÑ
+ËÏÍÁÎÄÙ GENERATE ARC/Info. óÏÚÄÁÅÔ Ä×Á ÆÁÊÌÁ Ó ÒÁÓÛÉÒÅÎÉÑÍÉ {\tt .gen} É
+{\tt gpn} ÓÏÏÔ×ÅÔÓ×ÅÎÎÏ, ÓÏÄÅÒÖÁÝÉÅ ÌÉÎÉÉ É ÔÏÞËÉ ÉÓÈÏÄÎÏÇÏ ÆÁÊÌÁ. 
+ðÏ ÕÍÏÌÞÁÎÉÀ ÜÔÉ ÆÁÊÌÙ ÉÍÅÀÔ ÉÍÑ ÓÏ×ÐÁÄÁÀÝÅÅ Ó ÉÍÅÎÅÍ ÉÓÈÏÄÎÏÇÏ ÆÁÊÌÁ É
+ËÏÎÃÙ ÓÔÒÏË × ÓÔÉÌÅ UNIX. ëÌÀÞ {\bf -r} ÐÏÚ×ÏÌÑÅÔ ÇÅÎÅÒÉÒÏ×ÁÔØ ËÏÎÃÙ ÓÔÒÏË
+× ÓÔÉÌÅ MS-DOS, ÞÔÏ ÎÅÏÂÈÏÄÉÍÏ ÄÌÑ PC ARC/Info ×ÅÒÓÉÊ ÄÏ 3.5.
+{\bf ëÌÀÞÉ}
+\begin{description}
+\item[-v] ÷ ÐÒÏÃÅÓÓÅ ÒÁÂÏÔÙ ÐÏËÁÚÙ×ÁÔØ, ÓËÏÌØËÏ ÌÉÎÉÊ É ÔÏÞÅË ËÏÎ×ÅÒÔÉÒÏ×ÁÎÏ.
+\item[-o ÉÍÑ ÆÁÊÌÁ] ÚÁÄÁÔØ ÉÍÑ ÄÌÑ ×ÙÈÏÄÎÙÈ ÆÁÊÌÏ× 
+\item[-r] çÅÎÅÒÉÒÏ×ÁÔØ ËÏÎÃÙ ÓÔÒÏË × ÓÔÉÌÅ MS-DOS
+\end{description}
+\subsection{eheader}\label{eheader}
+
+\obsoletes{HEADER, MAPLIST, ALIGN}
+íÏÄÉÆÉÃÉÒÕÅÔ É/ÉÌÉ ÐÏËÁÚÙ×ÁÅÔ ÉÎÆÏÒÍÁÃÉÀ ÉÚ ÚÁÇÏÌÏ×ËÁ ÒÁÓÔÒÏ×ÙÈ É ×ÅËÔÏÒÎÙÈ
+ÆÁÊÌÏ× EPPL7.
+
+\subsection{evaluate}\label{evaluate}
+\obsoletes{EVALUATE, MOVING, JUMPING, BORDER, EDGE, NEIGHBOR}
+\subsection{extents}\label{extents}
+çÅÎÅÒÉÒÕÅÔ ÔÁÂÌÉÃÕ ÐÒÅÄÅÌÏ× ËÏÏÒÄÉÎÁÔ ÄÌÑ ËÁÖÄÏÇÏ ÉÚ ËÌÁÓÓÏ×, ×ÓÔÒÅÞÁÀÝÉÈÓÑ
+× ÆÁÊÌÅ.
+\subsection{fill}\label{fill}
+\obsoletes{FILL}
+\subsection{intable}\label{intable}
+\obsoletes{INTABLE}
+çÅÎÅÒÉÒÕÅÔ ÎÏ×ÙÊ ÆÁÊÌ ÎÁ ÏÓÎÏ×ÁÎÉÉ ÎÅÓËÏÌØËÉÈ ÓÔÁÒÙÈ É ÔÁÂÌÉÃÙ ÓÏÏÔ×ÅÔÓÔ×ÉÑ.
+\subsection{mosaic}\label{mosaic}
+\obsoletes{MOSAIC}ÍÛÍ
+ïÂßÅÄÉÎÑÅÔ ÎÅÓËÏÌØËÏ ËÁÒÔ × ÏÄÎÕ.
+\subsection{neighbours}\label{neighbours}
+çÅÎÅÒÉÒÕÅÔ ÔÁÂÌÉÃÕ ÓÏÓÅÄÓÔ× ËÌÁÓÓÏ× × ÕËÁÚÁÎÎÏÊ ËÁÒÔÅ.
+\subsection{outtable}\label{outtable}
+\obsoletes{OUTTABLE}
+\subsection{reclass1}\label{reclass1}
+\obsoletes{RECLASS (ÏÄÎÏÆÁÊÌÏ×ÙÊ)}
+óÏÚÄÁÅÔ ÎÏ×ÕÀ ËÁÒÔÕ ÎÁ ÂÁÚÅ ÎÁÂÏÒÁ ÐÒÁ×ÉÌ Ó ÓÉÎÔÁËÓÉÓÏÍ ÜË×É×ÁÌÅÎÔÙÍ
+ËÏÍÁÎÄÅ RECLASS EPPL7. 
+\subsection{transform}\label{transform}
+\obsoletes{RESAMPLE, RESCALE, FILL}
+ðÒÅÏÂÒÁÚÕÅÔ ËÁÒÔÕ ÉÚ ÏÄÎÏÊ ËÏÏÒÄÉÎÁÔÎÏÊ ÓÉÓÔÅÍÙ × ÄÒÕÇÕÀ É/ÉÌÉ ÍÅÎÑÅÔ
+ÒÁÚÍÅÒ ÑÞÅÊËÉ.
+\subsection{window}\label{window}
+\obsoletes{window}
+÷ÙÒÅÚÁÅÔ ÆÒÁÇÍÅÎÔ ÉÚ ËÁÒÔÙ.
+\end{document}
diff --git a/doc/layers.doc b/doc/layers.doc
new file mode 100644 (file)
index 0000000..babf47f
--- /dev/null
@@ -0,0 +1,91 @@
+Guidelines to impliment layers
+
+New types of layer can be defined in fgis using
+
+layer typedef command
+
+They should implement following commands
+
+1. info option
+  Obligatory
+  Returns boolean value indicating that certain operation
+  are supported by this layer.
+  Required options are
+
+   opaque - layer could be displayed as base layer in planchet
+   lookable - layer could be inserted in planchet look list
+   legend - legend of this layer can be drawn by drawlegend command
+   limits - layer have working limits command
+   numeric - values of layer are subject of arithmetic operations
+   dimension - returns 0 if layer defined on the set of point,
+             1 on set of lines (i.e. vector file)
+             2 on continuous area (i.e. raster)
+   reclass - if it is raster layer, returns true if counting operation
+             should use reclass table otherwise can return anything
+2. dump
+  Obligatory
+  Returns TCL script which can be used to reimplement this layer
+  using layer load command.
+  This script would be executed at global level with value of
+  variable fgisLayerName set to desired name of this layer.
+  All objects which could be neccessary for existance of layer
+  (i.e. legends, palettes, pattern sets) should be recreated
+  by this script. (it is assumed that all neccessary files exist
+  in same locations)
+
+3. value x y ?flag?
+   If lookable is true
+  Returns value of layer at given point 
+k
+  Flag can be one of following
+  -raw - return value
+  -list - return two-element list consisting of layer title and value
+  -titled -return string as you like to appear in look window
+           presumable results of
+           [join [$layer value $x $y -list] ": "]
+  If layer is not defined in given point, this command should return
+  empty string.
+
+4.show planchet mode
+  obligatory
+  should record information that layer is visible in specified planchet
+  and optionally create certain items in this planchet which are persistent.
+  These items should have same tag as layer name (may be among other tags)
+  mode is either -base or -overlay
+5.hide planchet 
+  obligatory
+  removes information that layer is visible in planchet. It is up to
+  planchet to remove all related items
+6.redraw planchet
+  obligatory
+  Do all neccessary things to redraw itself in planchet, including
+  deletion of items which are no more applicable.
+  
+7.configure option arg ?option arg?
+  obligatory
+  changes properties of layer and issues redraw command for all planchets,
+  where layer is currently visible, if this changes can affect view
+
+8. legclasses
+  if [$layer info legend] is true
+   returns list of classes, which should be drawn by drawlegend
+9 sample canvas index x y ?mode? 
+  if [$layer info legend] is true
+  given index from list returned from legclasses, canvas and coordinates
+  should draw sample of itself. All items constituting this sample should
+  have tag $layername$index
+  mode is either -base or -overlay
+10 legtext index 
+  if [$layer info legend] is true
+  returns text to draw near the sample
+11 title 
+12 subtitle
+   Returns string to draw as title or subtitle of legend
+13 expand list
+   given list of two-element lists
+   rasterclass area  
+   return list of two-element lists
+   value area.
+14 delete
+   Obligatory - destroys itself 
+
diff --git a/doc/levels.eps b/doc/levels.eps
new file mode 100644 (file)
index 0000000..7840c8e
--- /dev/null
@@ -0,0 +1,147 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: levels.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu Jul  9 23:48:13 1998
+%%For: vitus@wagner (Victor Wagner,,,135-46-61,)
+%Magnification: 1.00
+%%Orientation: Landscape
+%%BoundingBox: 0 0 277 263
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-57.0 -161.0 translate
+ 90 rotate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 612 m 0 0 l 792 0 l 792 612 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 3900 975 m 5700 975 l 5700 1575 l 3900 1575 l cp gs col-1 s gr 
+% Polyline
+n 5250 2175 m 7050 2175 l 7050 2850 l 5250 2850 l cp gs col-1 s gr 
+% Polyline
+n 2700 2100 m 4500 2100 l 4500 2775 l 2700 2775 l cp gs col-1 s gr 
+% Polyline
+n 2700 3000 m 4500 3000 l 4500 3525 l 2700 3525 l cp gs col-1 s gr 
+% Polyline
+n 3525 3900 m 6300 3900 l 6300 4500 l 3525 4500 l cp gs col-1 s gr 
+% Polyline
+n 3525 4950 m 6300 4950 l 6300 5550 l 3525 5550 l cp gs col-1 s gr 
+30.000 slw
+% Polyline
+n 4800 4500 m 4800 4950 l gs col-1 s gr 
+% Polyline
+n 3900 3525 m 3900 3900 l gs col-1 s gr 
+% Polyline
+n 5925 2850 m 5925 3900 l gs col-1 s gr 
+% Polyline
+n 3900 2775 m 3900 3000 l gs col-1 s gr 
+% Polyline
+n 4350 1575 m 4350 2100 l gs col-1 s gr 
+% Polyline
+n 5550 1575 m 5550 2175 l gs col-1 s gr 
+% Polyline
+n 3600 4950 m 3600 4725 l 3375 4725 l 3375 3525 l gs col-1 s gr 
+7.500 slw
+% Polyline
+ [66.7] 0 sd
+n 4500 3375 m 5625 2850 l gs col-1 s gr  [] 0 sd
+/Times-Roman ff 180.00 scf sf
+4725 1350 m
+gs 1 -1 sc (Data files) dup sw pop 2 div neg 0 rm  col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+6075 2625 m
+gs 1 -1 sc (Utilities) dup sw pop 2 div neg 0 rm  col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+3600 2550 m
+gs 1 -1 sc (Low-level Tcl objects) dup sw pop 2 div neg 0 rm  col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+3600 3375 m
+gs 1 -1 sc (Layers) dup sw pop 2 div neg 0 rm  col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+4800 4350 m
+gs 1 -1 sc (User-level Tcl commands) dup sw pop 2 div neg 0 rm  col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+4725 5400 m
+gs 1 -1 sc (Graphic user interface) dup sw pop 2 div neg 0 rm  col-1 sh gr
+$F2psEnd
+rs
diff --git a/doc/levels.fig b/doc/levels.fig
new file mode 100644 (file)
index 0000000..c16b10a
--- /dev/null
@@ -0,0 +1,56 @@
+#FIG 3.1
+Portrait
+Center
+Inches
+1200 2
+6 2700 2100 4500 2775
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        2700 2100 4500 2100 4500 2775 2700 2775 2700 2100
+4 1 -1 0 0 0 12 0.0000 4 180 1680 3600 2550 Low-level Tcl objects\001
+-6
+6 5250 2175 7050 2850
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        5250 2175 7050 2175 7050 2850 5250 2850 5250 2175
+4 1 -1 0 0 0 12 0.0000 4 135 615 6075 2625 Utilities\001
+-6
+6 2700 3000 4500 3525
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        2700 3000 4500 3000 4500 3525 2700 3525 2700 3000
+4 1 -1 0 0 0 12 0.0000 4 180 525 3600 3375 Layers\001
+-6
+6 3525 3900 6300 4500
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        3525 3900 6300 3900 6300 4500 3525 4500 3525 3900
+4 1 -1 0 0 0 12 0.0000 4 135 1980 4800 4350 User-level Tcl commands\001
+-6
+6 3525 4950 6300 5550
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        3525 4950 6300 4950 6300 5550 3525 5550 3525 4950
+4 1 -1 0 0 0 12 0.0000 4 180 1695 4725 5400 Graphic user interface\001
+-6
+6 3900 300 5700 900
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        3900 300 5700 300 5700 900 3900 900 3900 300
+4 1 -1 0 0 0 12 0.0000 4 135 750 4725 675 Data files\001
+-6
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        4800 4500 4800 4950
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        3900 3525 3900 3900
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        5925 2850 5925 3900
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        3900 2775 3900 3000
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 4
+        3600 4950 3600 4725 3375 4725 3375 3525
+2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 0 0 2
+        4500 3375 5625 2850
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+        3900 1200 6225 1200 6225 1800 3900 1800 3900 1200
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        4200 1800 4200 2100
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        5775 1800 5775 2175
+2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+        4875 900 4875 1200
+4 1 -1 0 0 0 12 0.0000 4 180 1485 5025 1575 Data access library\001
diff --git a/doc/levels.gif b/doc/levels.gif
new file mode 100644 (file)
index 0000000..c4b1bb7
Binary files /dev/null and b/doc/levels.gif differ
diff --git a/doc/levels.pbm b/doc/levels.pbm
new file mode 100644 (file)
index 0000000..bc95db4
--- /dev/null
@@ -0,0 +1,3300 @@
+P1
+# CREATOR: XV Version 3.10a  Rev: 12/29/94
+311 371
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 
+1 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 
+1 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 
+0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 
+0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 1 
+0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 
+0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 0 1 1 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 0 0 0 0 
+0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 
+1 0 0 0 0 0 1 0 1 1 0 0 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 
+0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 0 0 
+1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 
+0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 
+0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 
+0 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 
+0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 
+1 0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 0 1 1 0 0 0 
+0 1 1 1 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 0 1 1 1 
+0 0 0 1 1 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 
+1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 
+0 0 0 0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 
+1 0 0 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 
+0 0 0 1 1 0 0 0 1 1 1 0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 1 1 1 1 0 0 1 
+1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 
+1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 
+0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 
+0 0 1 1 0 1 0 1 1 0 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 0 1 1 
+1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 1 0 1 1 0 0 1 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 
+0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 
+1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 
+0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 1 0 0 0 1 1 0 0 1 0 1 0 0 0 
+0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 
+0 1 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 1 
+1 1 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 0 1 0 0 0 1 1 
+1 0 0 0 1 1 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 
+1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 0 0 0 
+1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 
+1 1 1 1 0 0 1 1 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 
+1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 1 
+0 0 1 1 1 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 0 
+0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 0 0 1 1 0 0 1 0 
+1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 
+0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 
+0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 0 1 1 0 0 
+1 0 1 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 
+1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 
+0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 1 0 0 1 1 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1 0 0 1 0 0 1 
+1 1 1 0 0 1 0 1 1 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 
+0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 
+0 0 0 1 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 
+0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 
+0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 
+1 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 1 
+0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 
+0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 1 0 
+0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0 
+1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 
+0 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 1 1 1 1 0 1 
+1 0 0 1 1 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 
+0 0 1 1 1 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 0 0 0 1 1 
+0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 0 0 1 1 1 1 0 0 1 1 0 0 1 0 1 1 1 1 1 
+0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 
+1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 
+0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 1 1 0 0 
+1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 
+0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 
+0 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 
+1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 
+0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 
+1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 
+1 1 1 0 0 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 0 0 
+0 1 1 0 1 0 1 1 1 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 1 1 0 0 
+1 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
\ No newline at end of file
diff --git a/doc/levels.xbm b/doc/levels.xbm
new file mode 100644 (file)
index 0000000..c0ce86a
--- /dev/null
@@ -0,0 +1,1209 @@
+#define levels.xbm_width 311
+#define levels.xbm_height 371
+static unsigned char levels.xbm_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x20, 0x0d, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00,
+   0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x42, 0x80, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x82, 0xcc, 0x33, 0xb8, 0x89, 0xe1, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x82, 0x92, 0x48, 0x10, 0x49, 0x92,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x82, 0x9c, 0x70,
+   0x10, 0xc9, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x42, 0x92, 0x48, 0x10, 0x49, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x62, 0x92, 0x48, 0x10, 0xc9, 0x94, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3f, 0x2c, 0xb3, 0x90, 0x9f, 0x73,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xc0, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20,
+   0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x20, 0xc8, 0x3c, 0x03, 0x86, 0x61, 0x18, 0x8e, 0x83, 0xe6,
+   0x34, 0xd3, 0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x28, 0x89, 0x04, 0x49, 0x92, 0x24,
+   0x49, 0x82, 0x24, 0x99, 0x64, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0xc8, 0x09, 0x07,
+   0x4e, 0x10, 0x3c, 0xc3, 0x80, 0x24, 0x09, 0x27, 0x1a, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20,
+   0x24, 0x89, 0x04, 0x49, 0x10, 0x04, 0x0c, 0x83, 0x24, 0x89, 0x24, 0x0a,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x20, 0x26, 0x89, 0x04, 0x49, 0x92, 0x4c, 0x49, 0x82, 0x24,
+   0x89, 0x24, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0xf0, 0xc3, 0x32, 0x0b, 0x96, 0x61, 0x38,
+   0xc7, 0xc1, 0xef, 0x1c, 0x7b, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x0c,
+   0x00, 0x80, 0xe1, 0x0f, 0x0c, 0xc0, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x42, 0x00,
+   0x00, 0x00, 0x08, 0x00, 0x00, 0x21, 0x09, 0x08, 0x80, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x01, 0x08, 0x80,
+   0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x42, 0xc0, 0xdc, 0x06, 0x88, 0x99, 0x19, 0x01,
+   0xc1, 0x08, 0x8c, 0x33, 0x86, 0x79, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x42, 0x20, 0x49, 0x02, 0x48,
+   0x92, 0x24, 0x01, 0x21, 0x09, 0x92, 0x24, 0x49, 0x12, 0x09, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x42, 0x20,
+   0x59, 0xf3, 0xc9, 0xd3, 0x3c, 0x01, 0x21, 0x08, 0x92, 0x24, 0x4f, 0x10,
+   0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80,
+   0x73, 0xd0, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x42, 0x20, 0x51, 0x01, 0x48, 0x50, 0x04, 0x01, 0x21, 0x08, 0x92,
+   0x24, 0x41, 0x10, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x42, 0x24, 0xb1, 0x00, 0xc8, 0x64, 0x4c, 0x01,
+   0x21, 0x09, 0x92, 0x24, 0x53, 0x12, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0x20, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xe2, 0xc7, 0x90, 0x00, 0x9c,
+   0x23, 0xb8, 0x83, 0xc3, 0x1c, 0x8c, 0x23, 0x8e, 0x61, 0x07, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x9f, 0xf6,
+   0x63, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x21, 0x91, 0x24, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x21, 0x91, 0x24, 0xf2, 0x0c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x91, 0x24, 0x12, 0x30, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x33, 0x91, 0x24,
+   0x32, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x1e, 0xfe, 0xcf, 0xe7, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0c, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0x66, 0xa6, 0x39, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x90, 0x24,
+   0xc9, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x20, 0xe0, 0x34, 0x4f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x20, 0x90, 0x14, 0x41, 0x30, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x92, 0x18, 0x53, 0x24, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x63, 0x09,
+   0xee, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc3,
+   0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x20, 0x04, 0x00, 0x00, 0x10,
+   0x00, 0x00, 0x42, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x20, 0x04,
+   0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x20, 0xc4, 0x31, 0x0d, 0x10, 0x33, 0x33, 0x02, 0x82, 0x11, 0x18,
+   0xa6, 0x4d, 0x1b, 0xa6, 0xe1, 0x38, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x20, 0x24, 0x49, 0x06, 0x90, 0x24, 0x49, 0x02,
+   0x42, 0x12, 0x24, 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x20, 0x64, 0x78, 0xe2, 0x93,
+   0xa7, 0x79, 0x02, 0x42, 0x10, 0x04, 0x49, 0x92, 0x24, 0x4e, 0x92, 0x0c,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x20, 0x84,
+   0x09, 0x02, 0x90, 0xa0, 0x08, 0x02, 0x42, 0x10, 0x04, 0x49, 0x92, 0x24,
+   0x49, 0x92, 0x30, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x60, 0x26, 0x99, 0x02, 0x90, 0xc9, 0x98, 0x02, 0x42, 0x12, 0x24,
+   0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0xc0, 0xe3, 0x70, 0x07, 0x38, 0x47, 0x70, 0x07,
+   0x87, 0x39, 0x18, 0xe6, 0xf6, 0x6d, 0xf6, 0x66, 0x1d, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x5c,
+   0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x66, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x42, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x9a, 0x79, 0x9c,
+   0x31, 0xd8, 0x38, 0xa6, 0xb1, 0xe6, 0x99, 0x3e, 0x86, 0x61, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xe1,
+   0x4c, 0x92, 0x24, 0x49, 0x90, 0x24, 0xc9, 0x20, 0x49, 0x24, 0x13, 0x49,
+   0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x41, 0x84, 0x93, 0x24, 0x09, 0x90, 0x0c, 0x4f, 0x20, 0x49,
+   0x3c, 0x11, 0x4e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x42, 0x44, 0x92, 0x24, 0x09, 0x90, 0x30,
+   0x41, 0x20, 0x49, 0x04, 0x11, 0x49, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x66, 0x44, 0x92, 0x24,
+   0x49, 0x90, 0x24, 0x53, 0x20, 0x49, 0x4c, 0x11, 0x49, 0x32, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x3c,
+   0x8e, 0x75, 0xee, 0x33, 0x60, 0x1d, 0xee, 0xf0, 0x9b, 0xb9, 0x13, 0x96,
+   0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/doc/lib_doc.tex b/doc/lib_doc.tex
new file mode 100644 (file)
index 0000000..fb4a8b3
--- /dev/null
@@ -0,0 +1,1196 @@
+\documentclass{report}
+\usepackage[koi8-r]{inputenc}
+\usepackage[russian]{babel}
+\newcommand{\function}[1]{\par\smallskip{\raggedright\setlength{\hangindent}{2cm}\noindent\tt #1\par} \smallskip}
+\newcommand{\var}[2]{\par\smallskip{\setlength{\hangindent}{1cm}\noindent\tt#1\rm~--- #2\par} \smallskip}
+\textwidth=6.3in
+\oddsidemargin=0.5in
+\title{âÉÂÌÉÏÔÅËÁ ÄÌÑ ÒÁÂÏÔÙ\\ Ó ÆÁÊÌÁÍÉ EPPL7.\\òÕËÏ×ÏÄÓÔ×Ï ÐÒÏÇÒÁÍÍÉÓÔÁ}
+\author{÷.â.~÷ÁÇÎÅÒ}
+\makeindex
+\begin{document}
+\maketitle
+\tableofcontents
+\chapter*{÷×ÅÄÅÎÉÅ}\addcontentsline{toc}{chapter}{÷×ÅÄÅÎÉÅ}
+
+âÉÂÌÉÏÔÅËÁ ÐÒÅÄÎÁÚÎÁÞÅÎÁ ÄÌÑ ÒÁÂÏÔÙ Ó ×ÅËÔÏÒÎÙÍÉ É ÒÁÓÔÒÏ×ÙÍÉ
+ÆÁÊÌÁÍÉ EPPL7 ÉÚ ÐÒÏÇÒÁÍÍ ÎÁ ÑÚÙËÅ C. âÉÂÌÉÏÔÅËÁ ÒÁÓÞÉÔÁÎÁ ÎÁ 
+ÒÁÂÏÔÕ × 32-ÒÁÚÒÑÄÎÏÊ ÓÒÅÄÅ. ÷ ÐÒÉÎÃÉÐÅ ÎÅÂÏÌØÛÉÅ ÐÒÏÇÒÁÍÍÙ
+ÓÐÏÓÏÂÎÙ ÒÁÂÏÔÁÔØ É × 16-ÒÁÚÒÑÄÎÏÊ ÓÒÅÄÅ, ÎÏ ÐÏÓËÏÌØËÕ ÓÐÅÃÉÁÌØÎÙÈ
+ÍÅÒ ÄÌÑ ÜÔÏÇÏ ÎÅ ÐÒÉÎÉÍÁÌÏÓØ, ÒÁÂÏÔÁ × ÍÏÄÅÌÑÈ ÐÁÍÑÔÉ Compact, Large
+É Huge ÎÅ ÇÁÒÁÎÔÉÒÕÅÔÓÑ.
+
+÷ ÂÉÂÌÉÏÔÅËÁÈ ÐÒÅÄÕÓÍÏÔÒÅΠËÏÄ ÄÌÑ ÒÁÂÏÔÙ ÎÁ ÐÒÏÃÅÓÓÏÒÁÈ Ó 
+ÐÒÑÍÙÍ ÐÏÒÑÄËÏÍ ÂÁÊÔ (MSB First), ÈÏÔÑ ÏΠÐÏËÁ ÎÅ ÏÔÔÅÓÔÉÒÏ×ÁÎ.
+
+ôÅÍ ÎÅ ÍÅÎÅÅ ÎÅ ÒÅËÏÍÅÎÄÕÅÔÓÑ ÉÓÐÏÌØÚÏ×ÁÔØ ÞÉÔÁÔØ ÆÁÊÌÙ EPPL7 ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ,
+ÔÁË ËÁË ÐÒÉ ÜÔÏÍ ÐÒÉÄÅÔÓÑ ÏÂÒÁÝÁÔØ ×ÎÉÍÁÎÉÅ ÎÁ ÐÏÒÑÄÏË ÂÁÊÔÏ× × ÓÌÏ×Å.
+
+ðÏÓËÏÌØËÕ ÏÒÉÇÉÎÁÌØÎÙÊ ÐÁËÅÔ EPPL7 ÒÁÂÏÔÁÌ ÐÏÄ DOS, ×ÓÅ ÅÇÏ ÆÁÊÌÙ,
+ÈÒÁÎÑÝÉÅÓÑ × Ä×ÏÉÞÎÏÍ ÆÏÒÍÁÔÅ ÉÓÐÏÌØÚÕÀÔ ÐÏÒÑÄÏË ÂÁÊÔÏ× ÐÒÏÃÅÓÓÏÒÁ Intel~---
+ÍÌÁÄÛÉÊ ÂÁÊÔ ÐÅÒ×ÙÍ. 
+
+
+âÉÂÌÉÏÔÅËÉ ÎÅ ÉÓÐÏÌØÚÕÀÔ ÓÉÓÔÅÍÎÙÈ ×ÙÚÏ×Ï× É ÂÉÂÌÉÏÔÅÞÎÙÈ ÆÕÎËÃÉÊ,
+ÓÐÅÃÉÆÉÞÎÙÈ ÄÌÑ UNIX\footnote{úÁ ÉÓËÌÀÞÅÎÉÅÍ ÕÔÉÌÉÔ ÄÌÑ ÒÁÂÏÔÙ Ó ÆÁÊÌÏ×ÏÊ
+ÓÉÓÔÅÍÏÊ É ÏÂÒÁÂÏËÉ ÐÒÅÒÙ×ÁÎÉÑ ÐÒÏÇÒÁÍÍÙ. üÔÉ ÆÕÎËÃÉÉ ÌÏËÁÌÉÚÏ×ÁÎÙ
+× ÍÏÄÕÌÅ {\tt file\_utils.c} É ÏÐÉÓÁÎÙ × ÇÌÁ×Å \ref{utils}}.
+
+ðÒÉ ÒÁÚÒÁÂÏÔËÅ ÂÉÂÌÉÏÔÅË ÐÒÅÄÐÏÌÁÇÁÌÏÓØ, ÞÔÏ ÔÉР{\tt long int} ÉÍÅÅÔ
+ÒÁÚÍÅÒ 32 ÂÉÔÁ, {\tt short int}~--- 16 ÂÉÔ É {\tt double}~--- 64 ÂÉÔÁ,
+× ÆÏÒÍÁÔÅ, ÕÄÏ×ÌÅÔ×ÏÒÑÀÝÅÍ ÓÔÁÎÄÁÒÔÕ IEEE.
+
+\chapter{ìÏÇÉÞÅÓËÁÑ ÍÏÄÅÌØ ÆÁÊÌÏ× ÄÁÎÎÙÈ}
+\section{òÁÓÔÒ}
+
+ôÅÏÒÅÔÉÞÅÓËÉ, ÒÁÓÔÒÏ×ÁÑ ËÁÒÔÁ Ñ×ÌÑÅÔÓÑ ÆÕÎËÃÉÅÊ ÏÔ ËÏÏÒÄÉÎÁÔ,
+ÚÎÁÞÅÎÉÑ ËÏÔÏÒÏÊ Ñ×ÌÑÀÔÓÑ ÞÉÓÌÁÍÉ ÉÌÉ ÜÌÅÍÅÎÔÁÍÉ ÎÅËÏÔÏÒÏÇÏ
+ËÏÎÅÞÎÏÇÏ ÍÎÏÖÅÓÔ×Á, ÏÐÒÅÄÅÌÅÎÎÏÊ ×ÎÕÔÒÉ ÎÅËÏÔÏÒÏÊ ÇÅÏÍÅÔÒÉÞÅÓËÏÊ
+ÆÉÇÕÒÙ ÎÁ ÄÅËÁÒÔÏ×ÏÊ ËÏÏÒÄÉÎÁÔÎÏÊ ÐÌÏÝÁÄÉ.
+
+ðÒÁËÔÉÞÅÓËÉ ËÁË ÏÂÌÁÓÔØ ÏÐÒÅÄÅÌÅÎÉÑ, ÔÁË É ÏÂÌÁÓÔØ ÚÎÁÞÅÎÉÊ
+Ë×ÁÎÔÕÀÔÓÑ, Á ÃÅÌØÀ  ÂÉÂÌÉÏÔÅËÉ Ñ×ÌÑÅÔÓÑ ×ÏÚÍÏÖÎÏÓÔØ
+ÐÒÏÉÚ×ÏÌØÎÙÍ ÏÂÒÁÚÏÍ ÚÁÄÁ×ÁÔØ ÚÎÁÞÅÎÉÑ ÒÁÓÔÒÁ × ÌÀÂÏÊ ÎÕÖÎÏÊ ÔÏÞËÅ.
+
+
+ðÏÜÔÏÍÕ, ÒÁÓÔÒÏ×ÙÅ ÆÁÊÌÙ EPPL7 (epp) ÒÁÓÓÍÁÔÒÉ×ÁÀÔÓÑ ËÁË ÂÏÌØÛÁÑ ÍÁÔÒÉÃÁ
+ËÏÒÏÔËÉÈ (16-ÂÉÔ) ÃÅÌÙÈ. òÁÚÍÅÒÙ ÍÁÔÒÉÃÙ ÍÏÇÕÔ ÄÏÓÔÉÇÁÔØ $30000\times30000$
+Á ÚÎÁÞÅÎÉÑ - ÐÒÉÎÉÍÁÔØ ÌÀÂÏÅ ÚÎÁÞÅÎÉÅ, ÄÏÐÕÓÔÉÍÏÅ ÄÌÑ ÔÉÐÁ
+{\tt unsigned short} Ô.Å. 0--65535.
+
+óÏÏÔ×ÅÔÓÔ×ÉÅ ÍÅÖÄÕ ×ÅÝÅÓÔ×ÅÎÎÙÍÉ ËÁÒÔÏÇÒÁÆÉÞÅÓËÉÍÉ
+ËÏÏÒÄÉÎÁÔÁÍÉ É ÃÅÌÏÞÉÓÌÅÎÙÍÉ ÉÎÄÅËÓÁÍÉ × ÍÁÔÒÉÃÅ (ÒÑÄÁÍÉ É ËÏÌÏÎËÁÍÉ)
+ÈÒÁÎÉÔÓÑ × ÚÁÇÏÌÏ×ËÅ epp-ÆÁÊÌÁ, É × ÂÉÂÌÉÏÔÅËÅ ÐÒÅÄÕÓÍÏÔÒÅÎÙ ÆÕÎËÃÉÉ 
+ÄÌÑ ÐÅÒÅÓÞÅÔÁ ÏÄÎÉÈ × ÄÒÕÇÉÅ. 
+
+îÏÍÅÒÁ ÒÑÄÏ×/ËÏÌÏÎÏË × ÆÁÊÌÅ ÎÅ ÏÂÑÚÁÔÅÌØÎÏ ÎÁÞÉÎÁÀÔÓÑ Ó ÅÄÉÎÉÃÙ.
+äÌÑ ÎÉÈ ÄÏÐÕÓÔÉÍÙ ÌÀÂÙÅ ÚÎÁÞÅÎÉÑ × ÄÉÁÐÁÚÏÎÅ -32767--+32767.
+
+üÔÏ ÐÏÚ×ÏÌÑÅÔ × ÆÁÊÌÅ, ÐÏËÒÙ×ÁÀÝÅÍ ÎÅÂÏÌØÛÎÏÊ ÕÞÁÓÔÏË ÔÅÒÒÉÔÏÒÉÉ ÉÍÅÔØ
+ÓÏ×ÍÅÓÔÉÍÏÓÔØ Ó Â\`ÏÌØÛÉÍ ÆÁÊÌÏÍ ÎÅ ÔÏÌØËÏ ÐÏ ÁÌØÔÅÒÎÁÔÉ×ÎÙÍ ËÏÏÒÄÉÎÁÔÁÍ,
+ÎÏ É ÐÏ ÎÏÍÅÒÁÍ ÒÑÄÏ×/ËÏÌÏÎÏË. 
+
+ïÂÙÞÎÏ ÑÞÅÊËÉ × ÆÁÊÌÅ Ë×ÁÄÒÁÔÎÙÅ, ÈÏÔÑ ×ÓÅ ÐÒÏÃÅÄÕÒÙ ÂÉÂÌÉÏÔÅËÉ
+ÂÕÄÕÔ ËÏÒÒÅËÔÎÏ ÒÁÂÏÔÁÔØ Ó ÆÁÊÌÁÍÉ, × ËÏÔÏÒÙÈ ÒÁÚÍÅÒÙ ÑÞÅÊËÉ ÐÏ ×ÅÒÔÉËÁÌÉ
+É ÐÏ ÇÏÒÉÚÏÎÔÁÌÉ ÒÁÚÌÉÞÎÙ.
+
+úÎÁÞÅÎÉÅ ÐÌÏÝÁÄÉ ÑÞÅÊËÉ ×ÍÅÓÔÅ Ó ÒÁÚÍÅÒÎÏÓÔØÀ (Ë×ÁÄÒÁÔÎÙÅ ÍÅÔÒÙ, ÆÕÔÙ,
+ÇÅËÔÁÒÙ É ÄÒ.) ÈÒÁÎÉÔÓÑ × ÚÁÇÏÌÏ×ËÅ ÆÁÊÌÁ. ìÉÎÅÊÎÙÅ ÅÄÉÎÉÃÙ ÁÌØÔÅÒÎÔÁÔÉ×ÎÙÈ
+ËÏÏÒÄÉÎÁÔ ÎÉÇÄÅ ÎÅ ÏÐÉÓÙ×ÁÀÔÓÑ, ÎÏ ÄÌÑ ÓÏ×ÍÅÓÔÉÍÏÓÔÉ ÎÅ ÒÅËÏÍÅÎÄÕÅÔÓÑ
+ÉÓÐÏÌØÚÏ×ÁÔØ ÎÉËÁËÉÈ ÅÄÉÎÉàËÒÏÍÅ ÍÅÔÒÏ× ÉÌÉ ÇÒÁÄÕÓÏ× (ÅÓÌÉ ÆÁÊÌ ÈÒÁÎÉÔÓÑ
+× ÇÅÏÇÒÁÆÉÞÅÓËÉÈ ËÏÏÒÄÉÎÁÔÁÈ). 
+
+ðÒÉ ÜÔÏÍ ÐÌÏÝÁÄØ ÑÞÅÊËÉ ÍÏÖÎÏ ÐÅÒÅ×ÅÓÔÉ × ÄÒÕÇÉÅ ÅÄÉÎÉÃÙ, ÓÏÏÔ×ÅÔÓÔ×ÅÎÎÏ
+ÉÚÍÅÎÉ× ËÏÄ ÒÁÚÍÅÒÎÏÓÔÉ, ÄÌÑ ÔÏÇÏ ÞÔÏÂÙ ÐÏÌÕÞÉÔØ ÂÏÌÅÅ ÕÄÏÂÏÞÉÔÁÅÍÙÅ ÞÉÓÌÁ
+ÐÒÉ ÒÁÓÓÞÅÔÅ ÐÌÏÝÁÄÅÊ.
+
+ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÍÎÏÖÅÓÔ×Á ÚÎÁÞÅÎÉÊ ËÁÒÔÙ × ÍÎÏÖÅÓÔ×Ï ÚÎÁÞÅÎÉÊ (ËÌÁÓÓÏ×)
+epp-ÆÁÊÌÁ ÔÒÁÄÉÃÉÏÎÎÏ ÓÞÉÔÁÅÔÓÑ ÆÕÎËÃÉÅÊ ÌÅÇÅÎÄÙ, É ÎÁÈÏÄÉÔÓÑ ÚÁ
+ÐÒÅÄÅÌÁÍÉ ÆÏÒÍÁÔÁ epp, Á, ÓÌÅÄÏ×ÁÔÅÌØÎÏ É ÄÁÎÎÏÊ ÂÉÂÌÉÏÔÅËÉ.
+
+ðÏÓËÏÌØËÕ ÍÁÔÒÉÃÁ ×ÓÅÇÄÁ ÐÒÑÍÏÕÇÏÌØÎÁ, Á ÏÂÌÁÓÔØ ÏÐÒÅÄÅÌÅÎÉÑ ËÁÒÔÙ~---
+ÎÅ ×ÓÅÇÄÁ, ÐÒÅÄÕÓÍÏÔÒÅÎÏ ÓÐÅÃÉÁÌØÎÏÅ ÚÎÁÞÅÎÉÅ, ÎÁÚÙ×ÁÅÍÏÅ offsite.
+
+ðÒÉ ÞÔÅÎÉÉ epp-ÆÁÊÌÁ ÐÒÅÄÐÏÌÁÇÁÅÔÓÑ, ÞÔÏ ÒÁÚÍÅÒÙ ÅÇÏ ÂÅÓËÏÎÅÞÎÙ, ÎÏ
+ÐÏÐÙÔËÁ ÐÒÏÞÉÔÁÔØ ÅÇÏ ÜÌÅÍÅÎÔ ÚÁ ÐÒÅÌÁÍÉ ÒÅÁÌØÎÏÇÏ ÆÁÊÌÁ ÐÒÉ×ÏÄÉÔ
+Ë ×ÏÚ×ÒÁÔÕ ÚÎÁÞÅÎÉÑ offsite, ËÏÔÏÒÏÅ ÏÚÎÁÞÁÅÔ, ÞÔÏ × ÄÁÎÎÏÊ ÔÏÞËÅ 
+ÚÎÁÞÅÎÉÅ ÎÅ ÏÐÒÅÄÅÌÅÎÏ. úÎÁÞÅÎÉÅ offsite Ó×ÏÅ ÄÌÑ ËÁÖÄÏÊ ËÁÒÔÙ. ïÎÏ 
+ÈÒÁÎÉÔÓÑ × ÚÁÇÏÌÏ×ËÅ ÆÁÊÌÁ É × ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÅÍ ÐÏÌÅ ÓÔÒÕËÔÕÒÙ ÄÁÎÎÙÈ,
+ÉÓÐÏÌØÚÕÅÍÏÊ ÄÌÑ ÄÏÓÔÕÐÁ Ë ÆÁÊÌÕ.
+
+âÏÌØÛÁÑ ÞÁÓÔØ ÁÌÇÏÒÉÔÍÏ×, ÉÓÐÏÌØÚÕÅÍÙÈ ÄÌÑ ÇÅÎÅÒÁÃÉÉ ÒÁÓÔÒÏ×ÙÈ ËÁÒÔ ÉÌÉ
+ÄÌÑ ÉÈ ÁÎÁÌÉÚÁ, ÎÅ ÚÁ×ÉÓÉÔ ÏÔ ÐÏÒÑÄËÁ ÏÂÈÏÄÁ ÑÞÅÅË ËÁÒÔÙ, ÈÏÔÑ É ÔÒÅÂÕÅÔ
+ÐÏÌÎÏÇÏ ÉÈ ÐÅÒÅÂÏÒÁ. ÷ ÜÔÉÈ ÓÌÕÞÁÑÈ ÒÅËÏÍÅÎÄÕÅÔÓÑ ÉÓÐÏÌØÚÏ×ÁÔØ 
+{\it ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÙÊ}
+ÐÅÒÅÂÏÒ ÐÏ ÓÔÒÏËÁÍ, ËÁË ÓÁÍÙÊ ÜËÏÎÏÍÉÞÎÙÊ ÐÏ ÐÁÍÑÔÉ.
+
+äÒÕÇÏÊ ÒÁÓÐÒÏÓÔÒÁÎÅÎÎÙÊ ×ÁÒÉÁÎÔ ÄÏÓÔÕÐÁ, ÜÔÏ ËÏÇÄÁ ÐÒÉ ÏÂÒÁÂÏÔËÉ ËÏÎËÒÅÔÎÏÊ
+ÑÞÅÊËÉ ÒÁÓÔÒÁ ÔÒÅÂÕÅÔÓÑ ÉÎÆÏÒÍÁÃÉÑ Ï ÚÎÁÞÅÎÉÑÈ, ÓÏÄÅÒÖÁÝÉÈÓÑ × ÓÏÓÅÄÎÉÈ ÑÞÅÊËÁÈ.
+
+÷ ÜÔÏÍ ÒÅÖÉÍÅ ÄÏÓÔÕРˠËÁÖÄÏÊ ÓÔÒÏËÅ ÒÁÓÔÒÁ ÔÒÅÂÕÅÔÓÑ ÎÅÓËÏÌØËÏ ÒÁÚ~---
+ÓÎÁÞÁÌÁ ÐÒÉ ÏÂÒÁÂÏÔËÅ ÏÄÎÏÊ ÉÌÉ ÎÅÓËÏÌØËÉÈ ÐÒÅÄÙÄÕÝÉÈ ÓÔÒÏË, ÐÏÔÏÍ ÐÒÉ ÏÂÒÁÂÏÔËÅ
+ÓÁÍÏÊ ÜÔÏÊ ÓÔÒÏËÉ, É ÎÁËÏÎÅÃ, ÐÒÉ ÏÂÒÁÂÏÔËÅ ÓÌÅÄÕÀÝÉÈ ÓÔÒÏË. äÌÑ ÔÁËÉÈ ÓÉÔÕÁÃÉÊ
+ÒÅÁÌÉÚÏ×ÁΠ{\it ËÜÛÉÒÏ×ÁÎÎÙÊ} ÄÏÓÔÕÐ, ÐÒÉ ËÏÔÏÒÏÍ ÎÅÓËÏÌØËÏ ÓÔÒÏË × 
+ÒÁÓÐÁËÏ×ÁÎÎÏÍ ×ÉÄÅ ÈÒÁÎÑÔÓÑ × ÐÁÍÑÔÉ.
+
+é, ÎÁËÏÎÅÃ, ÄÌÑ ÔÁËÉÈ ÐÒÉÌÏÖÅÎÉÊ ËÁË ÉÎÔÅÒÁËÔÉ×ÎÙÅ ÒÅÄÁËÔÏÒÙ, ÒÅÁÌÉÚÏ×ÁΠ
+{\it ÐÒÑÍÏÊ ÄÏÓÔÕРÎÁ ÞÔÅÎÉÅ/ÚÁÐÉÓØ}. üÔÏÔ ÓÐÏÓÏ ÄÏÓÔÕÐÁ ÓÕÝÅÓÔ×ÅÎÎÏ ÍÅÄÌÅÎÎÅÅ,
+ÞÅÍ ËÜÛÉÒÏ×ÁÎÎÙÊ, ÐÏÓËÏÌØËÕ ÓÔÒÏËÉ epp-ÆÁÊÌÁ ÈÒÁÎÑÔÓÑ × ÐÁÍÑÔÉ ×
+ÕÐÁËÏ×ÁÎÎÏÍ ×ÉÄÅ.
+
+äÌÑ ÕÐÒÏÝÅÎÉÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÐÅÒÅÂÏÒÁ ÑÞÅÅË ÓÕÝÅÓÔ×ÕÀÔ ÆÕÎËÃÉÉ-% 
+{\it ÉÔÅÒÁÔÏÒÙ}, ËÏÔÏÒÙÅ ÐÏÌÕÞÁÀÔ × ËÁÞÅÓÔ×Å ÐÁÒÁÍÅÔÒÁ ÆÕÎËÃÉÀ É
+ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏ ÐÒÉÍÅÎÑÀÔ ÅÅ ËÏ ×ÓÅÍ ÑÞÅÊËÁÍ ÆÁÊÌÁ.
+
+
+\section{÷ÅËÔÏÒ}
+
+÷ÅËÔÏÒÎÙÅ ÆÁÊÌÙ EPPL7 (dgt) ÐÒÅÄÓÔÁ×ÌÑÀÔ ÓÏÂÏÊ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÓÔØ 
+ÏÂßÅËÔÏ×~--- ÌÉÎÉÊ É ÔÏÞÅË. 
+
+õÓÔÁÎÏ×ÌÅÎÉÅ ÓÏÏÔ×ÅÓÔ×ÉÑ ÍÅÖÄÕ ÏÂßÅËÔÏÍ É ËÏÏÒÄÉÎÁÔÁÍÉ ÐÒÅÄÓÔÁ×ÌÑÅÔ 
+ÄÌÑ ÎÉÈ ÓÕÝÅÓÔ×ÅÎÎÏ ÂÏÌÅÅ ÓÌÏÖÎÕÀ ÚÁÄÁÞÕ, ÞÅÍ ÕÓÔÁÎÏ×ÌÅÎÉÅ 
+ÓÏÏÔ×ÅÔÓÔ×ÉÑ ÍÅÖÄÕ ËÏÏÒÄÉÎÁÔÁÍÉ É ËÌÁÓÓÁÍÉ ÒÁÓÔÒÁ.
+
+äÌÑ ÂÏÌØÛÉÎÓÔ×Á ÓÐÏÓÏÂÏ× ÏÂÒÁÂÏËÉ ×ÅËÔÏÒÎÙÈ ÆÁÊÌÏ× ÔÏÖÅ ÄÏÓÔÁÔÏÞÎÏ
+ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÐÅÒÅÂÏÒÁ ÏÂßÅËÔÏ×. 
+
+÷ ÔÅÈ ÓÌÕÞÁÑÈ, ËÏÇÄÁ ÔÒÅÂÕÅÔÓÑ, ÎÁÐÒÉÍÅÒ, ÐÅÒÅÂÏÒ ×ÓÅÈ ÐÁÒ ÏÂßÅËÔÏ×,
+ÍÏÖÎÏ ÚÁÇÒÕÚÉÔØ ×ÅËÔÏÒÎÙÊ ÆÁÊÌ × ÐÁÍÑÔØ.
+
+äÌÑ ×ÅËÔÏÒÎÙÈ ÆÁÊÌÏ× ÔÏÖÅ ÓÕÝÅÓÔ×ÕÀÔ ÉÔÅÒÁÔÏÒÙ, ÐÏÚ×ÏÌÑÀÝÉÅ ÐÒÉÍÅÎÉÔØ
+ÐÅÒÅÄÁÎÎÕÀ ÆÕÎËÃÉÀ ËÏ ×ÓÅÍ ÌÉÎÉÑÍ, ËÏ ×ÓÅÍ ÔÏÞËÁÍ ÉÌÉ ×ÏÏÂÝÅ ËÏ
+×ÓÅÍ ÏÂßÅËÔÁÍ × ÆÁÊÌÅ.
+
+ìÏÇÉÞÅÓËÁÑ ÓÔÒÕËÔÕÒÁ ×ÅËÔÏÒÎÏÇÏ ÆÁÊÌÁ EPPL7 ÔÁËÏ×Á:
+
+÷ ÅÇÏ ÚÁÇÏÌÏ×ËÅ ÏÐÒÅÄÅÌÑÅÔÓÑ ÐÒÑÍÏÕÇÏÌØÎÁÑ ÏÂÌÁÓÔØ × ËÁÒÔÏÇÒÁÆÉÞÅÓËÉÈ
+(ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ) ËÏÏÒÄÉÎÁÔÁÈ, ËÏÔÏÒÕÀ ÐÏËÒÙ×ÁÅÔ ÆÁÊÌ.
+
+÷ÎÕÔÒÉ ÆÁÊÌÁ ×ÓÅ ËÏÏÒÄÉÎÁÔÙ ÈÒÁÎÑÔÓÑ ×Ï ×ÎÕÔÒÅÎÎÉÈ ÅÄÉÎÉÃÁÈ, ÄÌÑ ËÏÔÏÒÙÈ
+×ÓÅÇÄÁ ÎÉÖÎÑÑ É ÌÅ×ÁÑ ÇÒÁÎÉÃÙ ÆÁÊÌÁ ÉÍÅÀÔ ÚÎÁÞÅÎÉÅ $-32767$, Á ×ÅÒÈÎÑÑ
+É ÐÒÁ×ÁÑ~--- $+32767$. üÔÏ ÏÂÅÓÐÅÞÉ×ÁÅÔ ÍÁËÓÉÍÁÌØÎÏ ×ÏÚÍÏÖÎÕÀ ÔÏÞÎÏÓÔØ
+É ËÏÍÐÁËÔÎÏÓÔØ, ÎÏ ÐÒÉ×ÏÄÉÔ Ë ÐÒÏÂÌÅÍÁÍ ÐÒÉ ÒÁÓÞÅÔÅ ÒÁÓÓÔÏÑÎÉÊ É ÕÇÌÏ×, 
+É ÐÒÉÍÅÎÅÎÉÉ ÄÒÕÇÉÈ ÆÕÎËÃÉÊ ÁÎÁÌÉÔÉÞÅÓËÏÊ ÇÅÏÍÅÔÒÉÉ, ÐÏÓËÏÌØËÕ ×ÅÌÉÞÉÎÁ
+ÅÄÉÎÉÞÎÏÇÏ ÏÔÒÅÚËÁ ÐÏ ÏÓÉ $X$ É ÐÏ ÏÓÉ $Y$ ÎÅ ÓÏ×ÐÁÄÁÀÔ. 
+
+÷ÓÅ ÏÂßÅËÔÙ × ×ÅËÔÏÒÎÏÍ ÆÁÊÌÅ ÉÍÅÀÔ ÃÅÌÏÞÉÓÌÅÎÎÙÊ (32-ÂÉÔÎÙÊ) ÉÄÅÎÔÉÆÉËÁÔÏÒ.
+îÅÄÏÐÕÓÔÉÍÙÍ ÚÎÁÞÅÎÉÅÍ ÄÌÑ ÉÄÅÎÔÉÆÉËÁÔÏÒÁ ÏÂßÅËÔÁ Ñ×ÌÑÅÔÓÑ 0, ÐÏÓËÏÌØËÕ
+ÔÏÞËÁ Ó ÎÕÌÅ×ÙÍÉ ËÏÏÒÄÉÎÁÔÁÍÉ É ÎÕÌÅ×ÙÍ ÉÄÅÎÔÉÆÉËÁÔÏÒÏÍ ÉÓÐÏÌØÚÕÅÔÓÑ ËÁË
+ÐÒÉÚÎÁË ËÏÎÃÁ ÆÁÊÌÁ.
+
+÷ÅËÔÏÒÎÙÊ ÆÁÊÌ EPPL7 ÍÏÖÅÔ ÈÒÁÎÉÔØ Ä×Á ÔÉÐÁ ÏÂßÅËÔÏ×: ÌÉÎÉÉ É ÔÏÞËÉ.
+
+ôÏÞËÁ ÉÍÅÅÔ Ä×Å ËÏÏÒÄÉÎÁÔÙ É ÉÄÅÎÔÉÆÉËÁÔÏÒ.
+
+äÌÑ ÌÉÎÉÉ ÈÒÁÎÉÔÓÑ ÉÄÅÎÔÉÆÉËÁÔÏÒ, ËÏÏÒÄÉÎÁÔÙ ÍÉÎÉÍÁÌØÎÏÇÏ ÐÒÑÍÏÕÇÏÌØÎÉËÁ,
+ÚÁËÌÀÞÁÀÝÅÇÏ × ÓÅÂÅ ÌÉÎÉÀ, ÞÉÓÌÏ ÔÏÞÅË É ÎÁÂÏÒ ÐÁÒ ËÏÏÒÄÉÎÁÔ.
+
+ëÏÌÉÞÅÓÔ×Ï ÔÏÞÅË × ÌÉÎÉÉ ÎÅ ÍÏÖÅÔ ÐÒÅ×ÙÛÁÔØ 500.
+
+æÕÎËÃÉÉ ÂÉÂÌÉÏÔÅËÉ ÚÁÂÏÔÑÔÓÑ Ï ÔÏÍ, ÞÔÏÂÙ ËÏÏÒÄÉÎÁÔÙ ÏÂßÅÍÌÀÝÅÇÏ 
+ÐÒÑÍÏÕÇÏÌØÎÉËÁ (ÍÁÓËÉ ÌÉÎÉÉ) ÂÙÌÉ ËÏÒÒÅËÔÎÙÍÉ.
+
+\chapter{æÕÎËÃÉÉ ÄÏÓÔÕÐÁ Ë epp ÆÁÊÌÁÍ}
+
+æÕÎËÃÉÉ ÐÅÒÅÍÅÎÎÙÅ, ÎÅÏÂÈÏÄÉÍÙÅ ÄÌÑ ÄÏÓÔÕÐÁ Ë epp-ÆÁÊÌÁÍ
+ÏÐÉÓÁÎÙ × ÆÁÊÌÅ {\tt epp.h}. ÷ ÎÅÍ ÏÐÉÓÁÎÁ ÓÔÒÕËÔÕÒÁ ÄÁÎÎÙÈ
+{\tt EPP}, ÈÒÁÎÑÝÁÑ ÉÎÆÏÒÍÁÃÉÀ Ï ÏÔËÒÙÔÏÍ epp-ÆÁÊÌÅ. 
+
+÷ÎÕÔÒÅÎÎÅÅ ÕÓÔÒÏÊÓÔ×Ï ÜÔÏÊ ÓÔÒÕËÔÕÒÙ ÏÐÉÓÁÎÏ × ÒÁÚÄÅÌÅ \ref{EPP-internals}.
+
+ðÒÁËÔÉÞÅÓËÉ ÌÅÚÔØ ×ÎÕÔÒØ ÜÔÏÊ ÓÔÒÕËÔÕÒÙ ÐÒÉ ÐÒÏÇÒÁÍÍÉÒÏ×ÁÎÉÉ
+ÐÒÉËÌÁÄÎÙÈ ÚÁÄÁÞ ÎÅÔ ÎÅÏÂÈÏÄÉÍÏÓÔÉ. ÷ÓÑ ÒÁÂÏÔÁ Ó ÎÅÊ ÐÒÏÉÚ×ÏÄÉÔÓÑ
+Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÊ ÂÉÂÌÉÏÔÅËÉ.
+
+üÔÁ ÓÔÒÕËÔÕÒÁ ÄÁÎÎÙÈ ÈÒÁÎÉÔ ÎÁÉÂÏÌÅÅ ÓÕÝÅÓÔ×ÅÎÎÕÀ ÉÎÆÏÒÍÁÃÉÀ ÉÚ
+ÚÁÇÏÌÏ×ËÁ EPP-ÆÁÊÌÁ. úÎÁÞÅÎÉÑ ÔÅÈ ÐÏÌÅÊ ËÏÔÏÒÙÅ ÎÅ ÈÒÁÎÑÔÓÑ × ÜÔÏÊ
+ÓÔÒÕËÔÕÒÅ, ÍÏÖÎÏ ÐÒÏÞÉÔÁÔØ ÉÌÉ ÉÚÍÅÎÉÔØ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÊ, ÏÐÉÓÁÎÎÙÈ
+× ÒÁÚÄÅÌÅ \ref{EPPHEADER}.
+
+\section{ðÏÌÑ ÓÔÒÕËÔÕÒÙ EPP}\index{EPP}
+÷ ÜÔÏÍ ÒÁÚÄÅÌÅ ÏÐÉÓÁÎÙ ÔÏÌØËÏ ÔÅ ÐÏÌÑ, ÚÎÁÞÅÎÉÑ ËÏÔÏÒÙÈ ÄÏÓÔÁÔÏÞÎÏ
+ÞÁÓÔÏ ÉÓÐÏÌØÚÕÀÔÓÑ ÐÒÉ ÒÅÁÌÉÚÁÃÉÉ ÐÒÉËÌÁÄÎÙÈ ÁÌÇÏÒÉÔÍÏ×. ïÓÔÁÌØÎÙÅ
+ÐÏÌÑ É ÐÒÉÎÃÉÐÙ ÒÁÂÏÔÙ Ó ÎÉÍÉ ÏÐÉÓÁÎÙ × ÒÁÚÄÅÌÅ \ref{EPP-internals}. 
+÷ÓÅ ÐÏÌÑ, ÐÒÏ ËÏÔÏÒÙÅ ÎÅ ÓËÁÚÁÎÏ ÏÂÒÁÔÎÏÇÏ, ÍÏÖÎÏ ÔÏÌØËÏ ÞÉÔÁÔØ.
+äÌÑ ÉÈ ÉÚÍÅÎÅÎÉÑ ÉÓÐÏÌØÚÕÊÔÅ ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÅ ÆÕÎËÃÉÉ, ÐÏÓËÏÌØËÕ
+ÉÚÍÅÎÅÎÉÅ ÚÎÁÞÅÎÉÊ ÎÅËÏÔÏÒÙÈ ÐÏÌÅÊ ÍÏÖÅÔ ÐÏÔÒÅÂÏ×ÁÔØ ÓÏÇÌÁÓÏ×ÁÎÎÏÇÏ
+ÉÚÍÅÎÅÎÉÑ ËÁËÉÈ-ÔÏ ÄÒÕÇÉÈ.
+
+\index{EPP!fc}\index{EPP!lc}\index{EPP!fr}\index{EPP!lr}%
+\index{fr}\index{lr}\index{fc}\index{lc}\index{shift_epp}%
+\var{int fr,lr,fc,lc}{ îÏÍÅÒÁ ÐÅÒ×ÏÊ ÓÔÒÏËÉ É ËÏÌÏÎËÉ, Á ÔÁËÖÅ ÚÎÁÞÅÎÉÑ
+ÎÁ ÅÄÉÎÉÃÕ ÂÏÌØÛÅ ÐÏÓÌÅÄÎÅÊ ÓÔÒÏËÉ É ËÏÌÏÎËÉ. îÁ ÅÄÉÎÉÃÕ ÂÏÌØÛÅ ÏÎÉ
+ÐÏÔÏÍÕ, ÞÔÏ × ÜÔÏÍ ÓÌÕÞÁÅ ËÏÎÓÔÒÕËÃÉÉ {\tt lc $-$ fc} É {\tt lr $-$ fr}
+ÄÁÀÔ ËÏÌÉÞÅÓÔ×Ï ÓÔÒÏË É ËÏÌÏÎÏË × ÆÁÊÌÅ. äÌÑ ÉÚÍÅÎÅÎÉÑ ÉÓÐÏÌØÚÕÅÔÓÑ ÆÕÎËÃÉÑ
+{\tt shift\_epp} }
+
+\index{EPP!Xleft}\index{EPP!YBottom}\index{EPP!XRight}\index{EPP!YTop}
+\index{XLeft!EPP}\index{YBottom!EPP}\index{XRight!EPP}\index{YTop!EPP}
+\var{double Xleft,YBottom,XRight,YTop}{ ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ (ËÁÒÏÇÒÁÆÉÞÅÓËÉÅ)
+ËÏÏÒÄÉÎÁÔÙ ÇÒÁÎÉàËÁÒÔÙ.}
+
+\index{EPP!offsite}\index{offsite}%
+\var{int offsite}{ ÚÎÁÞÅÎÉÅ offsite. åÓÌÉ ÆÁÊÌ ÏÔËÒÙÔ ÎÁ ÚÁÐÉÓØ, ÜÔÏ
+ ÚÎÁÞÅÎÉÅ ÍÏÖÎÏ ÍÅÎÑÔØ.}
+
+\index{EPP!cell_area}\index{cell_area}%
+\var{double cell\_area}{ ÐÌÏÝÁÄØ ÑÞÅÊËÉ × ÅÄÉÎÉÃÁÈ, ÕËÁÚÁÎÎÙÈ × ÚÁÇÏÌÏ×ËÅ
+ÆÁÊÌÁ. óÍ. ÒÁÚÄÅÌ \ref{EPPHEADER}.}
+
+\index{EPP!kind}\index{kind}%
+\var{int kind}{ ËÏÌÉÞÅÓÔ×Ï ÂÉÔ ÎÁ ÑÞÅÊËÕ. íÏÖÅÔ ÐÒÉÎÉÍÁÔØ ÚÎÁÞÅÎÉÑ 8 ÉÌÉ 16.}
+
+
+éÎÆÏÒÍÁÃÉÑ ÉÚ ÚÁÇÏÌÏ×ËÁ ÆÁÊÌÁ epp, ËÏÔÏÒÁÑ ÎÅ ÐÏÐÁÌÁ × ×ÙÛÅÐÅÒÅÞÉÓÌÅÎÎÙÊ
+ÓÐÉÓÏË ÐÏÌÅÊ, × ÓÔÒÕËÔÕÒÅ EPP ÎÅ ÈÒÁÎÉÔÓÑ. äÌÑ ÒÁÂÏÔÙ Ó ÎÅÊ ÎÕÖÎÏ
+ÐÏÌÕÞÉÔØ ÐÏÌÎÕÀ ËÏÐÉÀ ÚÁÇÏÌÏ×ËÁ ÆÁÊÌÁ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ {\tt get\_epp\_header}%
+\index{get_epp_header}.
+
+\index{mode}\index{EPP!mode}\index{MAP_INPUT}\index{MAP_OUTPUT}
+\var{int mode}{ ÒÅÖÉÍ, × ËÏÔÏÒÏÍ ÏÔËÒÙÔ ÆÁÊÌ. ëÏÍÂÉÎÁÃÉÑ ËÏÎÓÔÁÎÔ
+{\tt MAP\_INPUT} É {\tt MAP\_OUTPUT}.}
+
+
+\section{ïÔËÒÙÔÉÅ ÆÁÊÌÁ É ÒÅÖÉÍÙ ÄÏÓÔÕÐÁ}
+
+\index{open_epp}%
+\function{EPP* open\_epp( char *filename );}
+
+ïÔËÒÙ×ÁÅÔ ÆÁÊÌ Ó ÉÍÅÎÅÍ {\tt filename} É ×ÏÚ×ÒÁÝÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ
+ÓÔÒÕËÔÕÒÕ EPP.  æÁÊÌ ÄÏÌÖÅΠÓÕÝÅÓÔ×Ï×ÁÔØ. òÅÖÉÍ ÏÔËÒÙÔÉÑ ÕÓÔÁÎÁ×ÌÉ×ÁÅÔÓÑ
+× {\tt MAP\_INPUT}.
+
+\index{fopen_epp}%
+\function{EPP* fopen\_epp(FILE *f);}
+ïÔËÒÙ×ÁÅÔ ÆÁÊÌ ÁÎÁÌÏÇÉÞÎÏ {\tt open\_epp}, ÎÏ ÐÏÌÕÞÁÅÔ × ËÁÞÅÓÔ×Å 
+ÐÁÒÁÍÅÒÁ ÎÅ ÉÍÑ, Á ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÒÕËÔÕÒÕ FILE. üÔÏ ÐÏÚ×ÏÌÑÅÔ 
+ÉÓÐÏÌØÚÏ×ÁÔØ ÄÌÑ ÐÅÒÅÄÁÞÉ ÒÁÓÔÒÏ×ÏÊ ÉÎÆÏÒÍÁÃÉÉ ÎÅ ÔÏÌØËÏ ÉÍÅÎÏ×ÁÎÎÙÅ 
+ÆÁÊÌÙ ÎÁ ÄÉÓËÅ. äÅÓËÒÉÐÔÏÒ ÆÁÊÌÁ f ÄÏÌÖÅΠÄÏÐÕÓËÁÔØ ÐÏÚÉÃÉÏÎÉÒÏ×ÁÎÉÅ.
+
+\index{creat_epp}
+\function{% 
+EPP *creat\_epp(char *pathname, int first\_col, int first\_row, int last\_col,
+               int last\_row, double AXLeft,double AYTop, double AXRight, 
+               double AYBottom, int scale, int base, int offsite);}
+
+
+óÏÚÄÁÅÔ ÎÏ×ÙÊ epp-ÆÁÊÌ É ÏÔËÒÙ×ÁÅÔ ÅÇÏ × ÒÅÖÉÍÅ {\tt MAP\_OUTPUT}.
+
+ðÒÉ ÓÏÚÄÁÎÉÉ ÆÁÊÌÁ ÕËÁÚÙ×ÁÀÔÓÑ ÅÇÏ ÒÁÚÍÅÒÙ, ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ ËÏÏÒÄÉÎÁÔÙ,
+ÚÎÁÞÅÎÉÅ offsite É ÚÎÁÞÅÎÉÑ ÐÏÌÅÊ ÚÁÇÏÌÏ×ËÁ {\tt base} É {\tt scale}.
+
+äÌÑ ÓÏÚÄÁÎÉÑ Åpp ÆÁÊÌÅ × ÕÖÅ ÏÔËÒÙÔÏÍ ÆÁÊÌÅ UNIX ÓÕÝÅÓÔ×ÕÅÔ ÆÕÎËÃÉÑ
+{\tt fcreat\_epp}\index{fcreat_epp}, ËÏÔÏÒÏÊ ×ÍÅÓÔÏ ÉÍÅÎÉ ÆÁÊÌÁ ÐÅÒÅÄÁÅÔÓÑ ÕËÁÚÁÔÅÌØ
+ÎÁ ÓÔÒÕËÔÕÒÕ {\tt FILE}.
+
+÷Ï ÍÎÏÇÉÈ ÓÌÕÞÁÑÈ ÎÕÖÎÏ ÓÏÚÄÁÔØ ×ÙÈÏÄÎÏÊ ÆÁÊÌ ÔÏÇÏ ÖÅ ÒÁÚÍÅÒÁ É Ó ÔÏÊ
+ÖÅ ËÏÏÒÄÉÎÁÔÎÏÊ ÓÉÓÔÅÍÏÊ, ÞÔÏ É ×ÈÏÄÎÏÊ. äÌÑ ÕÐÒÏÝÅÎÉÑ ÜÔÏÇÏ ÐÒÏÃÅÓÓÁ
+ÓÕÝÅÓÔ×ÕÅÔ ÆÕÎËÃÉÑ 
+\index{creat_epp_as}%
+\function{EPP *creat\_epp\_as(char *filename,EPP *pattern);}
+
+ËÏÔÏÒÁÑ ÓÏÚÄÁÅÔ ÆÁÊÌ, ËÏÐÉÒÕÑ ÂÏÌØÛÕÀ ÞÁÓÔØ ÉÎÆÏÒÍÁÃÉÉ ÚÁÇÏÌÏ×ËÁ ÉÚ
+ÕÖÅ ÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÆÁÊÌÁ, ÕËÁÚÁÔÅÌØ ÎÁ ËÏÔÏÒÙÊ ÐÅÒÅÄÁÅÔÓÑ ×
+ÐÁÒÁÍÅÔÒÅ {\tt pattern}. äÌÑ ÎÅÅ ÔÁËÖÅ ÓÕÝÅÓÔ×ÕÅÔ ÁÎÁÌÏÇ, ÐÏÌÕÞÁÀÝÉÊ
+ÎÅ ÉÍÑ, Á ÏÔËÒÙÔÙÊ ÆÁÊÌ.
+
+÷ÓÅ ÜÔÉ ÆÕÎËÃÉÉ ÐÏ ÕÍÏÌÞÁÎÉÀ ÓÏÚÄÁÀÔ 8-ÂÉÔÎÙÊ epp-ÆÁÊÌ. ôÏÞÎÅÅ,
+ËÏÌÉÞÅÓÔ×Ï ÂÉÔ ÏÐÒÅÄÅÌÑÅÔÓÑ ÚÎÁÞÅÎÉÅÍ ÇÌÏÂÁÌØÎÏÊ ÐÅÒÅÍÅÎÎÏÊ
+{\tt Create16bit}, ËÏÔÏÒÏÊ ÎÕÖÎÏ ÐÒÉÓ×ÏÉÔØ ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ ÄÌÑ
+ÔÏÇÏ, ÞÔÏÂÙ ÓÏÚÄÁ×ÁÌÉÓØ 16-ÂÉÔÎÙÅ ÆÁÊÌÙ
+
+\section{éÚÍÅÎÅÎÉÅ ÒÅÖÉÍÏ× ÄÏÓÔÕÐÁ}
+
+ðÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÄÁÎÎÏÊ ÂÉÂÌÉÏÔÅËÉ ÓÕÝÅÓÔ×ÕÀÝÉÊ ÆÁÊÌ ×ÓÅÇÄÁ ÏÔËÒÙ×ÁÅÔÓÑ
+× ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÞÔÅÎÉÑ, Á ÎÏ×ÙÊ~--- × ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ
+ÚÁÐÉÓÉ. äÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÐÏÌÕÞÉÔØ ÄÒÕÇÏÊ ÒÅÖÉÍ ÄÏÓÔÕÐÁ ÎÕÖÎÏ ÍÅÎÑÔØ ÒÅÖÉÍ
+ÄÏÓÔÕÐÁ Ñ×ÎÙÍ ÏÂÒÁÚÏÍ.
+
+\index{reset_epp}%
+\function{void reset\_epp(EPP *epp)}
+
+ðÅÒÅÏËÒÙ×ÁÅÔ ÄÌÑ ÞÔÅÎÉÑ ÆÁÊÌ, ÏÔËÒÙÔÙÊ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ.
+÷ÓÅ ÎÅÚÁÐÏÌÎÅÎÎÙÅ ÓÔÒÏËÉ ÚÁÐÏÌÎÑÀÔÓÑ offsite.
+
+\index{set_epp_cache}%
+\function{int set\_epp\_cache(EPP* epp, int lines);}
+
+óÏÚÄÁÅÔ ËÜÛ ÎÁ {\tt lines} ÓÔÒÏË. åÓÌÉ ËÜÛ ÒÁÎÅÅ ÓÕÝÅÓÔ×Ï×ÁÌ,
+ÉÚÍÅÎÑÅÔ ÅÇÏ ÒÁÚÍÅÒ. {\tt set\_epp\_cache(epp,0);} ÏÔÍÅÎÑÅÔ ËÜÛÉÒÏ×ÁÎÉÅ
+ÓÏ×ÓÅÍ.
+
+\index{load_epp}
+\function{int load\_epp(EPP* epp);}
+
+úÁÇÒÕÖÁÅÔ ÆÁÊÌ, ÏÔËÒÙÔÙÊ ÄÌÑ ÞÔÅÎÉÑ × ÐÁÍÑÔØ É ÍÅÎÑÅÔ ÅÇÏ ÒÅÖÉÍ
+ÎÁ {\tt MAP\_INPUT\verb!|!MAP\_OUTPUT}\index{MAP_INPUT},\index{MAP_OUTPUT}, Ô.Å. ÐÒÑÍÏÅ ÞÔÅÎÉÅ-ÚÁÐÉÓØ.
+
+\index{save_epp}
+\function{int save\_epp(EPP *epp);}
+
+ÓÏÈÒÁÎÑÅÔ ÉÚÍÅÎÅÎÉÑ × ÚÁÇÒÕÖÅÎÎÏÍ ÆÁÊÌÅ ÎÁ ÄÉÓË. óÔÁÒÏÅ ÓÏÄÅÒÖÉÍÏÅ
+ÐÒÉ ÜÔÏÍ ÔÅÒÑÅÔÓÑ.
+
+\index{save_epp_as}
+\function{int save\_epp\_as(EPP *epp,char *newname);}
+
+óÏÈÒÁÎÑÅÔ ÆÁÊÌ ÐÏÄ ÎÏ×ÙÍ ÉÍÅÎÅÍ. óÔÁÒÙÊ ÆÁÊÌ ÐÒÉ ÜÔÏÍ ÚÁËÒÙ×ÁÅÔÓÑ.
+
+\index{fsave_epp_as}
+\function{int fsave\_epp\_as(EPP *epp,FILE *f);}
+áÎÁÌÏÇÉÞÎÁ {\tt save\_epp\_as}, ÎÏ ÐÏÌÕÞÁÅÔ ÎÅ ÉÍÑ ÆÁÊÌÁ, Á ÕÖÅ ÏÔËÒÙÔÙÊ ÆÁÊÌ.
+
+æÕÎËÃÉÉ ÓÏÈÒÁÎÅÎÉÑ ÎÅ ÍÅÎÑÀÔ ÒÅÖÉÍÁ ÆÁÊÌÁ. ðÒÏÓÔÏ ÂÏÌØÛÅ ÎÅËÕÄÁ ÂÙÌÏ ÉÈ ÐÏÍÅÓÔÉÔØ.
+
+÷ÓÅ ÆÕÎËÃÉÉ ÓÏÈÒÁÎÅÎÉÑ É ÆÕÎËÃÉÑ {\tt load\_epp} ÐÏÓÌÅ ÏÂÒÁÂÏÔËÉ ËÁÖÄÏÊ
+ÓÔÒÏËÉ ×ÙÚÙ×ÁÀÔ ÆÕÎËÃÉÀ, ÎÁ ËÏÔÏÒÕÀ ÕËÁÚÙ×ÁÅÔ ÇÌÏÂÁÌØÎÁÑ ÐÅÒÅÍÅÎÎÁÑ \index{EndLineProc}%
+{\tt EndLineProc} (ÓÍ.~ÒÁÚÄÅÌ \ref{iterators}). åÅ ÒÅÚÕÌØÔÁÔ ÏÎÉ ÉÇÎÏÒÉÒÕÀÔ.
+
+\index{close_epp}
+\function{void close\_epp(EPP *epp);}
+
+úÁËÒÙ×ÁÅÔ ÆÁÊÌ. åÓÌÉ ÆÁÊÌ ÂÙÌ ÏÔËÒÙÔ ÎÁ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÕÀ ÚÁÐÉÓØ, ×ÓÅ ÉÚÍÅÎÅÎÉÑ
+ÓÏÈÒÁÎÑÀÔÓÑ, Á ÎÅÚÁÐÏÌÎÅÎÎÙÅ ÓÔÒÏËÉ ÚÁÐÏÌÎÑÀÔÓÑ offsite.
+
+åÓÌÉ ÆÁÊÌ ÂÙÌ ÚÁÇÒÕÖÅΠנÐÁÍÑÔØ, Á×ÔÏÍÁÔÉÞÅÓËÏÇÏ ÓÏÈÒÁÎÅÎÉÑ {\bf ÎÅ} ÐÒÏÉÚ×ÏÄÉÔÓÑ.
+\section{äÏÓÔÕРˠÑÞÅÊËÁÍ ÆÁÊÌÁ}
+ïÓÎÏ×ÎÙÍ ÓÐÏÓÏÂÏÍ ÄÏÓÔÕÐÁ Ë ÑÞÅÊËÁÍ ÆÁÊÌÁ Ñ×ÌÑÀÔÓÑ ÆÕÎËÃÉÉ
+
+\index{epp_get|textbf}%
+\function{int epp\_get(EPP* epp,int x,int y);}
+
+
+\index{epp_put|textbf}%
+\function{void epp\_put(EPP*epp,int x,int y,int value);}
+
+æÕÎËÃÉÑ {\tt epp\_get} ×ÏÚ×ÒÁÝÁÅÔ ÚÎÁÞÅÎÉÅ ÑÞÅÊËÉ Ó ÕËÁÚÁÎÎÙÍÉ ËÏÏÒÄÉÎÁÔÁÍÉ
+(×Ï ×ÎÕÔÒÅÎÎÉÈ ÅÄÉÎÉÃÁÈ ÆÁÊÌÁ) ÉÌÉ offsite, ÅÓÌÉ ÄÁÎÎÁÑ ÔÏÞËÁ ÎÁÈÏÄÉÔÓÑ
+ÚÁ ÐÒÅÄÅÌÁÍÉ ËÁÒÔÙ. 
+
+åÅ ÎÅÌØÚÑ ÐÒÉÍÅÎÉÔØ Ë ÆÁÊÌÕ, ÏÔËÒÙÔÏÍÕ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ, ÐÒÉ
+ÜÔÏÍ ×ÏÚÎÉËÁÅÔ ÏÛÉÂËÁ {\tt ME\_INVALID\_MODE}.
+
+ðÒÉ ÒÁÂÏÔÅ Ó ÆÁÊÌÏÍ ÏÔËÒÙÔÙÍ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÞÔÅÎÉÑ, ÏÐÒÁÛÉ×ÁÔØ
+ÑÞÅÊËÉ ÍÏÖÎÏ × ÌÀÂÏÍ ÐÏÒÑÄËÅ, ÎÏ ÏÂÒÁÝÅÎÉÅ Ë ÄÒÕÇÏÊ ÓÔÒÏËÅ 
+ÔÒÅÂÕÅÔ ÅÅ ÓÞÉÔÙ×ÁÎÉÑ Ó ÄÉÓËÁ É ÒÁÓÐÁËÏ×ËÉ.
+
+ðÒÉ ÒÁÂÏÔÅ Ó ËÜÛÉÒÏ×ÁÎÎÙÍ ÉÌÉ ÚÁÇÒÕÖÅÎÎÙÍ × ÐÁÍÑÔØ ÆÁÊÌÏÍ, ÔÅÍ ÂÏÌÅÅ
+ÍÏÖÎÏ ÏÂÒÁÝÁÔØÓÑ Ë ÅÇÏ ÑÞÅÊËÁÍ × ÐÒÏÉÚ×ÏÌØÎÏÍ ÐÏÒÑÄËÅ.
+
+æÕÎËÃÉÑ {\tt epp\_put} ÐÒÉ ÐÏÐÙÔËÅ ÉÚÍÅÎÉÔØ ÑÞÅÊËÕ ÚÁ ÐÒÅÄÅÌÁÍÉ
+ÆÁÊÌÁ ÇÅÎÅÒÉÒÕÅÔ ÏÛÉÂËÕ {\tt ME\_POINT\_OUTSIDE}.
+
+÷ ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ ÍÏÖÎÏ ÚÁÐÉÓÙ×ÁÔØ ÔÏÞËÉ ×ÎÕÔÒÉ ÔÅËÕÝÅÊ
+ÓÔÒÏËÉ × ÐÒÏÉÚ×ÏÌØÎÏÍ ÐÏÒÑÄËÅ, Á ÐÒÉ ÏÂÒÁÝÅÎÉÉ Ë ÓÔÒÏËÅ Ó ÎÏÍÅÒÏÍ, 
+ÂÏÌØÛÉÍ ÞÅÍ ÔÅËÕÝÁÑ, ÔÅËÕÝÁÑ ÓÔÒÏËÁ ÓÂÒÁÓÙ×ÁÅÔÓÑ ÎÁ ÄÉÓË, É ÄÁÌØÎÅÊÛÁÑ
+ÚÁÐÉÓØ × ÎÅÅ ÎÅ×ÏÚÍÏÖÎÁ. åÓÌÉ ÐÒÏÉÚÏÛÌÁ ÚÁÐÉÓØ × ÓÔÒÏËÕ Ó ÎÏÍÅÒÏÍ $n$,
+× ÔÏ ×ÒÅÍÑ ËÁË ÐÒÅÄÙÄÕÝÁÑ ÔÅËÕÝÁÑ ÓÔÒÏËÁ ÉÍÅÌÁ ÎÏÍÅÒ $m$, ÇÄÅ $m<n-1$,
+×ÓÅ ÓÔÒÏËÉ ÏÔ $m+1$ ÄÏ $n-1$ ÚÁÐÏÌÎÑÀÔÓÑ offsite.
+
+ðÏÐÙÔËÁ ÚÁÐÉÓÉ × ÓÔÒÏËÕ, ÕÖÅ ÚÁÐÉÓÁÎÎÕÀ ÎÁ ÄÉÓË, ×ÙÚÙ×ÁÅÔ ÏÛÉÂËÕ
+{\tt ME\_INVALID\_PUT}.
+
+÷ ÆÁÊÌÁÈ, ÚÁÇÒÕÖÅÎÎÙÈ × ÐÁÍÑÔØ, ÔÏ ÅÓÔØ ÄÏÓÔÕÐÎÙÈ É ÄÌÑ ÞÔÅÎÉÑ É ÄÌÑ
+ÚÁÐÉÓÉ, ÜÔÉÈ ÏÇÒÁÎÉÞÅÎÉÊ ÎÅÔ.
+
+äÌÑ ÓÐÅÃÉÁÌØÎÙÈ ÃÅÌÅÊ, ÐÒÅÉÍÕÝÅÓÔ×ÅÎÎÏ ÄÌÑ ÃÅÌÅÊ ×ÉÚÕÁÌÉÚÁÃÉÉ,
+ÒÅÁÌÉÚÏ×ÁÎÁ ÆÕÎËÃÉÑ
+
+\index{epp_get_line}%
+\function{unsigned short *epp\_get\_line(int x,int y);}
+
+×ÏÚ×ÒÁÝÁÀÝÁÑ ÔÅËÕÝÕÀ ÓÔÒÏËÕ ËÁË ÍÁÓÓÉ× {\tt unsigned short int}.
+ïÎÁ ×ÏÚ×ÒÁÝÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ ×ÎÕÔÒÅÎÎÉÊ ÂÕÆÅÒ ÓÔÒÕËÔÕÒÙ EPP, ÐÏÜÔÏÍÕ
+ÏÓ×ÏÂÏÖÄÁÔØ ÐÁÍÑÔØ ÎÅ ÎÕÖÎÏ. 
+
+ëÏÌÉÞÅÓÔ×Ï ÜÌÅÍÅÎÔÏ× ÍÁÓÓÉ×Á, ÉÍÅÀÝÉÈ ÏÓÍÙÓÌÅÎÎÙÅ ÚÎÁÞÅÎÉÑ, ×ÙÚÙ×ÁÀÝÁÑ
+ÐÒÏÇÒÁÍÍÁ ÄÏÌÖÎÁ ÏÐÒÅÄÅÌÉÔØ ÓÁÍÁ.
+
+ðÏÐÙÔËÁ ×ÙÚ×ÁÔØ ÜÔÕ ÆÕÎËÃÉÀ ÐÒÉ {\tt x $<$ epp-$>$fc} ÐÒÉ×ÏÄÉÔ Ë ÏÛÉÂËÅ
+{\tt ME\_POINT\_OUTSIDE}, Á ÆÕÎËÃÉÑ ×ÏÚ×ÒÁÝÁÅÔ {\tt NULL}.
+
+\section{éÔÅÒÁÔÏÒÙ}
+\label{iterators}
+
+\index{for_each_cell}%
+\function{int for\_each\_cell(EPP *epp,EPP\_ITER\_PROC action);}
+
+÷ÙÐÏÌÎÑÅÔ ÆÕÎËÃÉÀ {\tt action} ÄÌÑ ×ÓÅÈ ÎÅ-offsite ÑÞÅÅË ÓÕÝÅÓÔ×ÕÀÝÅÇÏ
+ÆÁÊÌÁ ÉÌÉ ÄÌÑ ×ÓÅÈ ÑÞÅÅË ÆÁÊÌÁ, ÏÔËÒÙÔÏÇÏ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ.
+÷ÏÚ×ÒÁÝÁÅÔ 0, ÅÓÌÉ ×ÙÐÏÌÎÅÎÉÅ ÚÁ×ÅÒÛÅÎÏ ÕÓÐÅÛÎÏ, -1 ÅÓÌÉ ×ÙÐÏÌÎÅÎÉÅ
+ÐÒÅÒ×ÁÎÏ × ÒÅÚÕÌØÔÁÔÅ ÎÅÎÕÌÅ×ÏÇÏ ÒÅÚÕÌØÔÁÔÁ {\tt EndLineProc}\index{EndLineProc} É -2,
+ÅÓÌÉ ×ÙÐÏÌÎÅÎÉÅ ÐÒÅÒ×ÁÎÏ ÓÁÍÏÊ ÆÕÎËÃÉÅÊ {\tt action}
+
+ôÉР{\tt EPP\_ITER\_PROC} ÏÐÒÅÄÅÌÅΠËÁË
+
+
+{\tt typedef int (*EPP\_ITER\_PROC)(int col, int row, int value);}
+
+
+ðÁÒÁÍÅÔÒÙ {\tt col} É {\tt row} ÐÅÒÅÄÁÀÔ ËÏÏÒÄÉÎÁÔÙ ÔÅËÕÝÅÊ ÔÏÞËÉ,
+ÐÁÒÁÍÅÔÒ {\tt value} ÓÏÄÅÒÖÉÔ ËÌÁÓÓ ÔÏÞËÉ ÄÌÑ ÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÆÁÊÌÁ É
+offsite ÄÌÑ ÓÏÚÄÁ×ÁÅÍÏÇÏ.
+
+÷ÏÚ×ÒÁÝÁÅÍÏÅ ÚÎÁÞÅÎÉÅ × ÓÌÕÞÁÅ ÓÏÚÄÁ×ÁÅÍÏÇÏ ÆÁÊÌÁ ÚÁÐÉÓÙ×ÁÅÔÓÑ × ÑÞÅÊËÕ.
+
+÷ ÓÌÕÞÁÅ ÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÆÁÊÌÁ ÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ÎÏÒÍÁÌØÎÏÍÕ
+ÓÏÓÔÏÑÎÉÀ, Á ÎÅÎÕÌÅ×ÏÅ ÐÒÉ×ÏÄÉÔ Ë ÐÒÅËÒÁÝÅÎÉÀ ÒÁÂÏÔÙ.
+
+\function{long count\_cells(EPP *epp, EPP\_ITER\_PROC condition);}
+
+÷ÏÚ×ÒÁÝÁÅÔ ËÏÌÉÞÅÓÔ×Ï ÑÞÅÅË × ÓÕÝÅÓÔ×ÕÀÝÅÍ ÆÁÊÌÅ, ÕÄÏ×ÌÅÔ×ÏÒÑÀÝÉÈ
+ÚÁÄÁÎÎÏÍÕ ÕÓÌÏ×ÉÀ. æÕÎËÃÉÑ {\tt condition} ÄÏÌÖÎÁ ×ÏÚ×ÒÁÝÁÔØ 0 ÄÌÑ
+ÑÞÅÅË, ËÏÔÏÒÙÅ ÕÓÌÏ×ÉÀ ÎÅ ÕÄÏ×ÌÅÔ×ÏÒÑÀÔ É ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ ÄÌÑ
+ÔÅÈ, ËÏÔÏÒÙÅ ÕÄÏ×ÌÅÔ×ÏÒÑÀÔ. ÷ ÓÌÕÞÁÅ ÐÒÅÒÙ×ÁÎÉÑ ÒÁÂÏÔÙ, ×ÏÚ×ÒÁÝÁÅÔ ÔÅ ÖÅ
+ËÏÄÙ, ÞÔÏ É {\tt for\_each\_cell}
+
+ðÁÒÁÍÅÔÒÙ, ÐÅÒÅÄÁ×ÁÅÍÙÅ ÆÕÎËÃÉÉ {\tt condition} ÔÁËÉÅ ÖÅ, ËÁË
+Õ {\tt action} × ÓÌÕÞÁÅ ÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÆÁÊÌÁ.
+
+éÔÅÒÁÔÏÒÙ ×ÙÐÏÌÎÑÀÔÓÑ ÄÏÓÔÁÔÏÞÎÏ ÄÏÌÇÏ, ÐÏÜÔÏÍÕ ÄÌÑ ÎÉÈ ÐÒÅÄÕÓÍÏÔÒÅÎ
+ÓÐÏÓÏ ×ÙÄÁÞÉ ÐÒÏÇÒÅÓÓ-ÉÎÄÉËÁÔÏÒÁ. åÓÌÉ ÇÌÏÂÁÌØÎÏÊ ÐÅÒÅÍÅÎÎÏÊ {\tt EndLineProc}%
+\index{EndLineProc|textbf}
+ÐÒÉÓ×ÏÅÎÏ ÚÎÁÞÅÎÉÅ, ÏÔÌÉÞÎÏÅ ÏÔ {\tt NULL}, ÔÏ ÆÕÎËÃÉÑ, ÎÁ ËÏÔÏÒÕÀ ÏÎÁ 
+ÕËÁÚÙ×ÁÅÔ, ×ÙÚÙ×ÁÅÔÓÑ ÐÏÓÌÅ ÏËÏÎÞÁÎÉÑ ÏÂÒÁÂÏÔËÉ ËÁÖÄÏÊ ÓÔÒÏËÉ ÆÁÊÌÁ.
+
+æÕÎËÃÉÑ ÐÏÌÕÞÁÅÔ ÔÒÉ ÃÅÌÙÈ ÐÁÒÁÍÅÔÒÁ:
+\var{row}{ ÎÏÍÅÒ ÓÔÒÏËÉ epp-ÆÁÊÌÁ, Ó ÕÞÅÔÏÍ ÚÎÁÞÅÎÉÑ ÐÏÌÑ {\tt fr}}
+\var{seqno}{ ÐÏÒÑÄËÏ×ÙÊ ÎÏÍÅÒ ÓÔÒÏËÉ (ÏÔ 1 ÄÏ {\tt lr-fr})}
+\var{total}{ ÏÂÝÅÅ ÞÉÓÌÏ ÓÔÒÏË × ÆÁÊÌÅ.}
+
+åÓÌÉ ÜÔÁ ÆÕÎËÃÉÑ ×ÏÚ×ÒÁÝÁÅÔ ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ, ÏÂÒÁÂÏÔËÁ ÆÁÊÌÁ ÐÒÅÒÙ×ÁÅÔÓÑ.
+
+ôÁËÉÍ ÏÂÒÁÚÏÍ ÐÒÏÓÔÅÊÛÁÑ ÆÕÎËÃÉÑ ÉÎÄÉËÁÃÉÉ ÐÒÏÇÒÅÓÓÁ (ÄÁÀÝÁÑ ÒÅÚÕÌØÔÁÔ,
+ÏÞÅÎØ ÐÏÈÏÖÉÊ ÎÁ ÐÏ×ÅÄÅÎÉÅ EPPL7 × ÁÎÁÌÏÇÉÞÎÏÊ ÓÉÔÕÁÃÉÉ), ×ÙÇÌÑÄÉÔ ÔÁË:
+
+\begin{verbatim}
+int show_progress(int row,int seqno,int total)
+{
+ fprintf(stderr,"\rProcessing row %d of %d",seqno,total);
+ fflush(stderr);
+ return 0;
+}
+\end{verbatim}
+\section{òÁÂÏÔÁ Ó ÚÁÇÏÌÏ×ËÏÍ epp-ÆÁÊÌÁ}
+\label{EPPHEADER}\index{EPPHEADER}
+úÁÇÏÌÏ×ÏË epp-ÆÁÊÌÁ ÉÍÅÅÔ ÓÌÅÄÕÀÝÕÀ ÓÔÒÕËÔÕÒÕ:
+\begin{verbatim}
+typedef struct EPPHEADER
+ { short int fr,lr,fc,lc;
+   double fry,lry,fcx,lcx;
+   short int kind;
+   short int base,scale;
+   unsigned short int offsite; 
+   double sfact;
+   long access_ptr;
+   unsigned short  minclass, maxclass;
+   char area_unit;
+   char coord_sys;                                   
+   char Reserved[6];
+   char date[16], time[8];
+   char comment[32];
+ } EPPHEADER;
+\end{verbatim}
+
+óÅÍÁÎÔÉËÁ ÜÔÉÈ ÐÏÌÅÊ ÓÌÅÄÕÀÝÁÑ:
+\var{fr,lr,fc,lc}{ ÓÏ×ÐÁÄÁÀÔ Ó ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÍÉ ÐÏÌÑÍÉ ÓÔÒÕËÔÕÒÙ {\tt EPP}}
+\var{fry,lry,fcx,lcx}{ ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ ËÏÏÒÄÉÎÁÔÙ}
+\var{kind}{ ËÏÌÉÞÅÓÔ×Ï ÂÉÔ ÎÁ ÑÞÅÊËÕ}
+\var{base,scale}{ ÔÁÊÎÁ, ÐÏËÒÙÔÁÑ ÍÒÁËÏÍ. ñ ÔÁË É ÎÅ ÓÍÏÇ ÕÑÓÎÉÔØ ÉÚ
+  ÄÏËÕÍÅÎÔÁÃÉÉ Ë EPPL7, ÞÔÏ ÜÔÉ ÐÏÌÑ ÄÅÌÁÀÔ, É ÎÅ ÚÎÁÀ, ËÁËÉÅ ËÏÍÁÎÄÙ EPPL,
+ ÎÅ ÓÞÉÔÁÑ {\tt HEADER} Ó ÎÉÍÉ ÒÁÂÏÔÁÀÔ.}
+\var{offsite}{ ÈÒÁÎÉÔ ÚÎÁÞÅÎÉÅ offsite.}
+\var{sfact}{ ÐÌÏÝÁÄØ ÑÞÅÊËÉ. óÍ. ÔÁËÖÅ ÐÏÌÅ {\tt area\_unit}}
+\var{access\_ptr}{ ÓÍÅÝÅÎÉÅ (× 128 ÂÁÊÔÏ×ÙÈ ÂÌÏËÁÈ) ÔÁÂÌÉÃÙ ÄÌÉΠÓÔÒÏË × ÆÁÊÌÅ}
+\var{minclass,maxclass}{ ÍÉÎÉÍÁÌØÎÙÊ É ÍÁËÓÉÍÁÌØÎÙÊ ËÌÁÓÓ × ÆÁÊÌÅ (ÎÅ ÓÞÉÔÁÑ
+offsite}
+\var{area\_unit}{ åÄÉÎÉÃÁ ÉÚÍÅÒÅÎÉÑ ÐÌÏÝÁÄÉ.}\index{area_unit}
+\var{coord\_sys}{ ÔÉРÐÒÏÅËÃÉÉ}\index{coord_sys}\index{EPPHEADER!coord_sys} 
+\var{date,time}{ ÄÁÔÁ É ×ÒÅÍÑ ÓÏÚÄÁÎÉÑ ÆÁÊÌÁ × ÔÅËÓÔÏ×ÏÍ ÆÏÒÍÁÔÅ.}
+\var{comment}{ ËÒÁÔËÉÊ ËÏÍÍÅÎÔÁÒÉÊ Ë ÆÁÊÌÕ (ÚÁÇÏÌÏ×ÏË ËÁÒÔÙ). úÎÁÞÅÎÉÅ
+ÜÔÏÇÏ ÐÏÌÑ EPPL7 ÚÁÐÒÁÛÉ×ÁÅÔ Õ ÐÏÌØÚÏ×ÁÔÅÌÑ ÐÒÉ ÓÏÚÄÁÎÉÉ ËÁÖÄÏÇÏ ÆÁÊÌÁ ËÁË
+``Description''} 
+
+÷ÏÚÍÏÖÎÙÅ ÚÎÁÞÅÎÉÑ ÅÄÉÎÉàÐÌÏÝÁÄÉ É ÔÉÐÏ× ÐÒÏÅËÃÉÉ ÏÐÉÓÁÎÙ ËÁË ËÏÎÓÔÁÎÔÙ × ÆÁÊÌÅ {\tt eppl.h},
+ËÏÔÏÒÙÊ ×ËÌÀÞÁÅÔÓÑ É ÆÁÊÌÏÍ {\tt epp.h} É ÆÁÊÌÏÍ {\tt dgt.h}
+\begin{description}
+\item[AREA\_NO\_UNIT] ðÌÏÝÁÄØ ÑÞÅÊËÉ ÎÅ ÏÐÒÅÄÅÌÅÎÁ; 
+\item[AREA\_SQ\_FOOT] ë×ÁÄÒÁÔÎÙÅ ÆÕÔÙ; 
+\item[AREA\_SQ\_METER] ë×ÁÄÒÁÔÎÙÅ ÍÅÔÒÙ; 
+\item[AREA\_SQ\_KM] ë×ÁÄÒÁÔÎÙÅ ËÉÌÏÍÅÔÒÙ; 
+\item[AREA\_SQ\_MILE] ë×ÁÄÒÁÔÎÙÅ ÍÉÌÉ (×ÉÄÉÍÏ, ÉÍÅÀÔÓÑ × ×ÉÄÕ ÁÎÇÌÉÊÓËÉÅ, Á ÎÅ
+ÍÏÒÓËÉÅ);
+\item[AREA\_HECTARE] çÅËÔÁÒÙ; 
+\item[AREA\_ACRE] áËÒÙ. 
+\end{description}
+
+ëÁË ×ÉÄÉÔÅ, ÍÉÌÌÉÍÅÔÒÙ ÎÅ ÐÒÅÄÕÓÍÏÔÒÅÎÙ.
+
+ëÏÌÉÞÅÓÔ×Ï ÔÉÐÏ× ÐÒÏÅËÃÉÊ ÏÞÅÎØ ÎÅ×ÅÌÉËÏ É ÐÏËÁÚÙ×ÁÅÔ ÏÒÉÅÎÔÁÃÉÀ EPPL7 ÎÁ
+ËÒÕÐÎÏÍÁÓÛÔÁÂÎÏÅ ËÁÒÔÏÇÒÁÆÉÒÏ×ÁÎÉÅ. 
+\begin{description}
+\item[COORD\_NONE] ëÏÏÒÄÉÎÁÔÎÁÑ ÓÉÓÔÅÍÁ ÎÅ ÏÐÒÅÄÅÌÅÎÁ (Ó×ÅÖÅÅ ÓËÁÎÅÒÎÏÅ
+ÉÚÏÂÒÁÖÅÎÉÅ);
+\item[COORD\_UTM] áÍÅÒÉËÁÎÓËÁÑ ÔÏÐÏÇÒÁÆÉÞÅÓËÁÑ ËÁÒÔÁ. (ÏÔ çÁÕÓÓÁ-ëÒÀÇÅÒÁ
+ÏÔÌÉÞÁÅÔÓÑ ÎÁ 0.2\%, ÎÏ ÏÔÌÉÞÁÅÔÓÑ.
+\item[COORD\_STPLANE] ðÒÏÅËÃÉÑ State Plane. éÓÐÏÌØÚÕÅÔÓÑ, ÓÕÄÑ ÐÏ ÎÁÚ×ÁÎÉÀ,
+ÄÌÑ ËÁÒÔ ÛÔÁÔÏ× óûá. 
+\item[COORD\_LL] çÅÏÇÒÁÆÉÞÅÓËÉÅ ËÏÏÒÄÉÎÁÔÙ.   
+\end{description}
+
+äÌÑ ÒÁÂÏÔÙ Ó ÜÔÏÊ ÉÎÆÏÒÍÁÃÉÅÊ ÐÒÅÄÕÓÍÏÔÒÅÎÙ ÓÌÅÄÕÀÝÉÅ ÆÕÎËÃÉÉ:
+\function{void get\_epp\_header(EPP* epp, EPPHEADER *h);}\index{get_epp_header|textbf}
+÷ÏÚ×ÒÁÝÁÅÔ ÚÁÇÏÌÏ×ÏË ÆÁÊÌÁ × ×ÉÄÅ ×ÙÛÅÏÐÉÓÁÎÎÏÊ ÓÔÒÕËÔÕÒÙ. éÓÐÏÌØÚÕÅÔÓÑ
+ÄÌÑ ÞÔÅÎÉÑ ÐÏÌÅÊ, Ë ËÏÔÏÒÙÍ ÎÅÔ ÂÏÌÅÅ ÕÄÏÂÎÏÇÏ ÄÏÓÔÕÐÁ.
+
+\function{char *getcomment(EPP *epp);}\index{getcomment}
+
+÷ÏÚ×ÒÁÝÁÅÔ ËÏÍÍÅÎÔÁÒÉÊ, ÏÂÒÅÚÁÑ ËÏÎÃÅ×ÙÅ ÐÒÏÂÅÌÙ. ÷ÏÚ×ÒÁÝÁÅÔ
+ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÁÔÉÞÅÓËÉÊ ÂÕÆÅÒ, ËÏÔÏÒÙÊ ÂÕÄÅÔ ÐÅÒÅÚÁÐÉÓÁΠÐÒÉ
+ÓÌÅÄÕÀÝÅÍ ÏÂÒÁÝÅÎÉÉ Ë ÜÔÏÊ ÆÕÎËÃÉÉ.
+
+\function{void change\_epp\_header(EPP* epp,EPPHEADER h);}\index{change_epp_header}
+
+ëÏÐÉÒÕÅÔ × ÚÁÇÏÌÏ×ÏË ÆÁÊÌÁ ÐÏÌÑ {\tt fcx, lcx, fry, lry, base, scale, offsite,
+sfact, coord\_sys, area\_unit, comment} ÉÚ ÐÅÒÅÄÁÎÎÏÊ ÓÔÒÕËÔÕÒÙ. ïÓÔÁÌØÎÙÅ
+ÐÏÌÑ ÏÓÔÁ×ÌÑÅÔ ËÁË ÂÙÌÉ.
+
+\function{void setcomment(EPP *epp,char *comment);}\index{set_comment}
+
+éÚÍÅÎÑÅÔ ÔÏÌØËÏ ËÏÍÍÅÎÔÁÒÉÊ. ÷ ÏÔÌÉÞÉÅ ÏÔ {\tt change\_epp\_header} ÎÅ
+ÔÒÅÂÕÅÔ, ÞÔÏÂÙ ÓÔÒÏËÁ ÂÙÌÁ ÄÏÐÏÌÎÅÎÁ ÐÒÏÂÅÌÁÍÉ ÄÏ 32 ÓÉÍ×ÏÌÏ×.
+åÅ ÁÒÕÇÕÍÅÎÔ~--- ÏÂÙÞÎÁÑ NULL-terminated ÓÔÒÏËÁ.
+
+
+
+\function{int shift\_epp(EPP* epp, int new\_fr, int new\_fc);}\index{shift_epp}
+
+éÚÍÅÎÑÅÔ ÚÎÁÞÅÎÉÑ ÐÏÌÅÊ {\tt fr} É {\tt fc}, É ÓÏÏÔ×ÅÔÓÔ×ÅÎÎÏ {\tt lr} É 
+{\tt lc}, ÐÏÓËÏÌØËÕ ÞÉÓÌÏ ÓÔÒÏË É ËÏÌÏÎÏË × ÆÁÊÌÅ ÐÏÍÅÎÑÔØ ÎÅÌØÚÑ.
+
+÷ÏÚ×ÒÁÝÁÅÔ ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ × ÓÌÕÞÁÅ ÕÓÐÅÈÁ ÉÌÉ 0, ÅÓÌÉ ËÁËÉÅ-ÔÏ
+ËÏÏÒÄÉÎÁÔÙ ÐÒÉ ÉÚÍÅÎÅÎÉÉ ×ÙÌÅÚÌÉ ÚÁ ÄÏÐÕÓÔÉÍÙÊ ÄÉÁÐÁÚÏÎ.
+
+\section{ðÅÒÅÓÞÅÔ ËÏÏÒÄÉÎÁÔ}
+\function{int epp\_row(EPP *epp,double y);}\index{epp_row}
+÷ÏÚ×ÒÁÝÁÅÔ ÎÏÍÅÒ ÓÔÒÏËÉ ÐÏ ÁÌØÔÅÒÎÁÔÉ×ÎÏÍÕ y.
+\function{int epp\_col(EPP *epp,double x);}\index{epp_col}
+CÏÏÔ×ÅÔÓÔ×ÅÎÎÏ, ÎÏÍÅÒ ËÏÌÏÎËÉ ÐÏ ÁÌØÔÅÒÎÁÔÉ×ÎÏÍÕ x.
+\function{double alt\_x(EPP *epp,int col);}\index{alt_x}
+÷ÏÚ×ÒÁÝÁÅÔ ÁÌØÔÅÒÔÁÎÔÉ×ÎÙÊ x ÕËÁÚÁÎÎÏÊ ËÏÌÏÎËÉ.
+\function{double alt\_y(EPP *epp,int row);}\index{alt_y}
+é ÁÌØÔÅÒÎÁÔÉ×ÎÙÊ y ÕËÁÚÁÎÎÏÊ ÓÔÒÏËÉ.
+
+üÔÉ Ä×Å ÆÕÎËÃÉÉ ×ÏÚ×ÒÁÝÁÀÔ ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ ËÏÏÒÄÉÎÁÔÙ ÐÒÁ×ÏÇÏ ×ÅÒÈÎÅÇÏ
+ÕÇÌÁ ÑÞÅÊËÉ. äÌÑ ÐÏÌÕÞÅÎÉÑ ËÏÏÒÄÉÎÁÔ ÃÅÎÔÒÁ ÑÞÅÊËÉ ÐÒÅÄÎÁÚÎÁÞÅÎÙ ÆÕÎËÃÉÉ:
+
+\function{double alt\_xc(EPP *epp,int col);}\index{alt_xc}
+\function{double alt\_yc(EPP *epp,int row);}\index{alt_yc}
+
+
+
+\section{îÁÌÏÖÅÎÉÅ ÆÁÊÌÏ×}
+
+òÁÓÔÒÏ×ÙÅ ÆÁÊÌÙ ÌÅÇËÏ ÎÁËÌÁÄÙ×ÁÔØ ÄÒÕÇ ÎÁ ÄÒÕÇÁ, ÅÓÌÉ Õ ÎÉÈ
+ÓÏ×ÐÁÄÁÅÔ ÒÁÚÍÅÒ ÑÞÅÊËÉ É ËÏÏÒÄÉÎÁÔÎÁÑ ÓÉÓÔÅÍÁ.
+
+äÌÑ ÐÒÏ×ÅÒËÉ ÜÔÉÈ ÕÓÌÏ×ÉÊ × ÂÉÂÌÉÏÔÅËÕ ×ËÌÀÞÅÎÁ ÆÕÎËÃÉÑ
+
+\function{int compare\_cell\_size(EPP *f1,EPP *f2);}\index{compare_cell_size}
+
+ÏÎÁ ×ÏÚ×ÒÁÝÁÅÔ 0 ÅÓÌÉ ÒÁÚÍÅÒÙ ÑÞÅÅË ÎÅÓÏ×ÍÅÓÔÉÍÙ É ÎÅÎÕÌÅ×ÏÊ ËÏÄ,
+ÅÓÌÉ ÆÁÊÌÙ ÍÏÖÎÏ ÎÁËÌÁÄÙ×ÁÔØ.
+
+÷ÔÏÒÏÅ ÕÓÌÏ×ÉÅ, ËÏÔÏÒÏÅ ÎÅÏÂÈÏÄÉÍÏ ÐÒÏ×ÅÒÉÔØ~--- ÓÏ×ÐÁÄÁÅÔ ÌÉ
+ÐÒÁ×ÉÌÏ ÐÅÒÅÓÞÅÔÁ ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔ × ÒÑÄÙ/ËÏÌÏÎËÉ.
+
+äÌÑ ÜÔÏÇÏ ÐÒÅÄÎÁÚÎÁÞÅÎÁ ÆÕÎËÃÉÑ 
+\function {int is\_aligned(EPP *f1,EPP *f2);}\index{is_aligned}
+
+ïÎÁ ×ÏÚ×ÒÁÝÁÅÔ ÎÅÎÕÌÅ×ÏÊ ËÏÄ, ÅÓÌÉ ÏÂÒÁÝÅÎÉÅ Ë {\tt epp\_get}\index{epp_get} 
+Ó ÏÄÉÎÁËÏ×ÙÍÉ ÁÒÇÕÍÅÎÔÁÍÉ ÄÌÑ ÏÂÏÉÈ ÆÁÊÌÏ× ×ÏÚ×ÒÁÝÁÅÔ
+ÉÎÆÏÒÍÁÃÉÀ Ï ÏÄÎÏÊ É ÔÏÊ ÖÅ ÔÏÞËÅ. 
+
+îÅÓÏ×ÐÁÄÅÎÉÅ ÒÁÍËÉ ÆÁÊÌÏ× ÎÅ ÉÇÒÁÅÔ ÎÉËÁËÏÊ ÒÏÌÉ, ÐÏÓËÏÌØËÕ {\tt epp\_get}
+ËÏÒÒÅËÔÎÏ ÏÂÒÁÂÁÔÙ×ÁÅÔ ÏÂÒÁÝÅÎÉÅ Ë ÔÏÞËÅ ÚÁ ÐÒÅÄÅÌÁÍÉ ÆÁÊÌÁ.
+
+åÓÌÉ {\tt compare\_cell\_size} ×ÏÚ×ÒÁÝÁÅÔ TRUE, Á {\tt is\_aligned}~---
+FALSE, ÔÏ ÆÁÊÌÙ ÍÏÇÕÔ ÂÙÔØ ×ÙÒÁ×ÎÅÎÙ ÐÕÔÅÍ ÉÚÍÅÎÅÎÉÑ ÎÏÍÅÒÁ ÐÅÒ×ÏÊ
+ÓÔÒÏËÉ É/ÉÌÉ ËÏÌÏÎËÉ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ {\tt shift\_epp}.
+
+åÓÌÉ ÖÅ ÎÅÏÂÈÏÄÉÍÏ ÓÏ×ÍÅÓÔÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÆÁÊÌÙ, Õ ËÏÔÏÒÙÈ ÎÅ
+ÓÏ×ÐÁÄÁÅÔ ÒÁÚÍÅÒ ÑÞÅÊËÉ, ÔÏ ÎÅÏÂÈÏÄÉÍÏ ÒÁÓÞÉÔÁÔØ É ÉÓÐÏÌØÚÏ×ÁÔØ 
+ÐÅÒÅÓÞÅÔÎÙÅ ËÏÜÆÆÉÃÉÅÎÔÙ.
+
+äÌÑ ÜÔÏÇÏ ÉÓÐÏÌØÚÕÀÔÓÑ ÆÕÎËÃÉÉ:
+
+\function{EPP\_LINK link\_epp(EPP *base,EPP *overlay);}\index{link_epp}\index{EPP_LINK}
+
+õÓÔÁÎÁ×ÌÉ×ÁÅÔ Ó×ÑÚØ ÍÅÖÄÕ ÆÁÊÌÁÍÉ. ÷ÏÚ×ÒÁÝÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ 
+ÓÔÒÕËÔÕÒÕ {\tt LINK\_BUFFER}, ÓÏÄÅÒÖÁÝÕÀ ÎÁÂÏÒ ÐÅÒÅÓÞÅÔÎÙÈ 
+ËÏÜÆÆÉÃÉÅÎÔÏ× ÉÌÉ {\tt NULL}, ÅÓÌÉ Ó×ÑÚØ ÕÓÔÁÎÏ×ÉÔØ ÎÅ×ÏÚÍÏÖÎÏ
+(ËÏÏÒÄÉÎÁÔÎÙÅ ÓÉÓÔÅÍÙ Ä×ÕÈ ÆÁÊÌÏ× ÉÍÅÀÔ ÐÒÏÔÉ×ÏÐÏÌÏÖÎÏ ÎÁÐÒÁ×ÌÅÎÎÙÅ
+ÏÓÉ).
+
+æÕÎËÃÉÉ:
+
+\function{int linked\_row(EPP\_LINK link,int row);}\index{linked_row}
+\function{int linked\_col(EPP\_LINK link,int col);}\index{linked_col}
+
+ÐÅÒÅÓÞÉÔÙ×ÁÀÔ ÒÑÄÙ/ËÏÌÏÎËÉ ÆÁÊÌÁ {\tt base} × ÒÑÄÙ/ËÏÌÏÎËÉ ÆÁÊÌÁ {\tt overlay} 
+
+
+\section{ðÒÏÞÅÅ}
+÷ ÎÅËÏÔÏÒÙÈ ÓÌÕÞÁÑÈ ÄÏ ÏËÏÎÞÁÎÉÑ ÓÏÚÄÁÎÉÑ ÆÁÊÌÁ ÎÅÌØÚÑ ÏÐÒÅÄÅÌÉÔØ,
+ÅÓÔØ ÌÉ × ÎÅÍ ËÌÁÓÓÙ Ó×ÙÛÅ 255. ÷ ÜÔÉÈ ÓÌÕÞÁÑÈ ÐÒÉÈÏÄÉÔÓÑ ×ÓÅÇÄÁ 
+ÓÏÚÄÁ×ÁÔØ 16-ÂÉÔÎÙÊ ÆÁÊÌ, Á ÐÏ ÏËÏÎÞÁÎÉÉ ÒÁÂÏÔÙ, ÅÓÌÉ $\mbox{max}\le 255$ ËÏÎ×ÅÒÔÉÒÏ×ÁÔØ
+ÅÇÏ × ×ÏÓØÍÉÂÉÔÎÙÊ. äÌÑ ÕÐÒÏÝÅÎÉÑ (É ÕÓËÏÒÅÎÉÑ) ÜÔÏÊ ÏÐÅÒÁÃÉÉ, 
+× ÂÉÂÌÉÏÔÅËÕ ×ËÌÀÞÅÎÁ ÆÕÎËÃÉÑ: 
+
+\function{int fast\_convert\_to\_8bit(EPP *source, char *filename);}%
+\index{fast_convert_to_8bit}
+
+üÔÁ ÆÕÎËÃÉÑ ÐÏÌÕÞÁÅÔ ÏÔËÒÙÔÙÊ ÎÁ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÕÀ ÚÁÐÉÓØ ÆÁÊÌ, 
+ÐÅÒÅÏÔËÒÙ×ÁÅÔ ÅÇÏ ÎÁ ÞÔÅÎÉÅ É ËÏÐÉÒÕÅÔ × ÎÏ×ÙÊ ÆÁÊÌ, ÕËÁÚÁÎÎÙÊ ËÁË filename.
+
+æÕÎËÃÉÑ ÒÁÂÏÔÁÅÔ
+ÔÁË ÂÙÓÔÒÏ, ËÁË ÔÏÌØËÏ ×ÏÚÍÏÖÎÏ, ÐÏÓËÏÌØËÕ ÉÓÐÏÌØÚÕÅÔ ÎÁÐÒÑÍÕÀ
+ÎÅËÏÔÏÒÙÅ ×ÏÚÍÏÖÎÏÓÔÉ ÂÉÂÌÉÏÔÅËÉ, ÎÅ ×ÙÎÅÓÅÎÎÙÅ × ÉÎÔÅÒÆÅÊÓ.
+
+äÌÑ Ó×ÅÄÅÎÉÑ ÞÉÔÁÔÅÌÅÊ, ÉÍÅÀÝÉÈ ÏÐÙÔ ÒÁÂÏÔÙ Ó epp-ÆÁÊÌÏÍ ÎÁ ÎÉÚËÏÍ
+ÕÒÏ×ÎÅ, ÕËÁÖÅÍ, ÞÔÏ ÚÁÐÁËÏ×ËÉ ÏÎÁ ÎÅ ×ÙÐÏÌÎÑÅÔ ×ÏÏÂÝÅ, Á ÒÁÓÐÁËÏ×Ù×ÁÅÔ
+ÔÏÌØËÏ ÍÌÁÄÛÉÅ 8 ÂÉÔ 16-ÂÉÔÎÏÇÏ ÆÁÊÌÁ.
+
+ðÏ ÏËÏÎÞÁÎÉÉ ÒÁÂÏÔÙ ÚÁËÒÙ×ÁÅÔ ÏÂÁ ÆÁÊÌÁ.
+
+\section{ïÂÒÁÂÏÔËÁ ÏÛÉÂÏË}
+
+âÏÌØÛÁÑ ÞÁÓÔØ ÆÕÎËÃÉÊ ÂÉÂÌÉÏÔÅËÉ ËÏÒÒÅËÔÎÏ ÏÂÒÁÂÁÔÙ×ÁÅÔ 
+ÏÛÉÂÏÞÎÙÅ ÓÉÔÕÁÃÉÉ. äÏÓÔÁÔÏÞÎÏ ÞÁÓÔÏ ÉÎÄÉËÁÔÏÒÏÍ ÏÛÉÂËÉ ÓÌÕÖÉÔ
+ÒÅÚÕÌØÔÁÔ, ×ÏÚ×ÒÁÝÁÅÍÙÊ ÆÕÎËÃÉÅÊ.
+
+óÕÝÅÓÔ×ÕÅÔ ÇÌÏÂÁÌØÎÁÑ ÐÅÒÅÍÅÎÎÁÑ {\tt map\_error}\index{map_error} × ËÏÔÏÒÕÀ ÐÏÍÅÝÁÅÔÓÑ
+ËÏÄ ÏÛÉÂËÉ. ÷ÏÚÍÏÖÎÙÅ ËÏÄÙ ÏÐÒÅÄÅÌÅÎÙ ËÁË ËÏÎÓÔÁÎÔÙ × ÆÁÊÌÅ {\tt epp\_err.h}.
+
+\var{ME\_OK}{ÏÐÅÒÁÃÉÑ ÚÁ×ÅÒÛÉÌÁÓØ ÕÓÐÅÛÎÏ.}
+\var{ME\_POINT\_OUTSIDE}{ðÏÐÙÔËÁ ÓÄÅÌÁÔØ {\tt epp\_put} ÚÁ ÐÒÅÄÅÌÁÍÉ ÆÁÊÌÁ.}
+\var{ME\_INVALID\_MODE}{ðÏÐÙÔËÁ ÞÉÔÁÔØ ËÁÒÔÕ, ÏÔËÒÙÔÕÀ × ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ
+ÚÁÐÉÓÉ, ÉÌÉ ÍÏÄÉÆÉÃÉÒÏ×ÁÔØ ËÁÒÔÕ, ÏÔËÒÙÔÕÀ × ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÞÔÅÎÉÑ}
+\var{ME\_READ\_ERROR}{ïÛÉÂËÁ ÓÉÓÔÅÍÎÏÇÏ ×ÙÚÏ×Á ÉÌÉ ÂÉÂÌÉÏÔÅÞÎÏÊ ÆÕÎËÃÉÉ ÐÒÉ
+ÞÔÅÎÉÉ Ó ÄÉÓËÁ. òÅËÏÍÅÎÄÕÅÔÓÑ ÐÏÓÍÏÔÒÅÔØ ÚÎÁÞÅÎÉÅ ÇÌÏÂÁÌØÎÏÊ ÐÅÒÅÍÎÎÏÊ {\tt errno}.}
+\var{ME\_WRITE\_ERROR}{ôÏ ÖÅ ÓÁÍÏÅ, ÎÏ ÐÒÉ ÚÁÐÉÓÉ.}
+\var{ME\_INVALID\_PUT}{ðÏÐÙÔËÁ ÉÚÍÅÎÉÔØ ÑÞÅÊËÕ, ÕÖÅ ÚÁÐÉÓÁÎÎÕÀ ÎÁ ÄÉÓË.}
+\var{ME\_OUT\_OF\_MEMORY}{îÅ È×ÁÔÉÌÏ ÐÁÍÑÔÉ ÄÌÑ ÒÁÚÍÅÝÅÎÉÑ ÎÅÏÂÈÏÄÉÍÙÈ ÓÔÒÕËÔÕÒ ÄÁÎÎÙÈ}
+\var{ME\_ACCESS\_DENIED}{îÅ ÕÄÁÌÏÓØ ÏÔËÒÙÔØ ÆÁÊÌ × ÔÒÅÂÕÅÍÏÍ ÒÅÖÉÍÅ}
+\var{ME\_NO\_FILE}{æÁÊÌ Ó ÕËÁÚÁÎÎÙÍ ÉÍÅÎÅÍ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ}
+\var{ME\_INVALID\_FILE}{æÁÊÌ ÎÅ Ñ×ÌÑÅÔÓÑ ÐÒÁ×ÉÌØÎÙÍ epp ÉÌÉ dgt ÆÁÊÌÏÍ}
+\var{ME\_CREATE\_ERROR}{ïÛÉÂËÁ ÓÏÚÄÁÎÉÑ ÆÁÊÌÁ, ÎÅ ÓÕÝÅÓÔ×ÕÅÔ ÐÕÔØ ÉÌÉ
+ ÎÅÄÏÐÕÓÔÉÍÏÅ ÉÍÑ. ðÏÄÒÏÂÎÏÓÔÉ~--- × ÓÉÓÔÅÍÎÏÊ ÐÅÒÅÍÅÎÎÏÊ {\tt errno}.}
+åÓÌÉ ÐÒÉ ËÁËÏÊ-ÔÏ ÏÐÅÒÁÃÉÉ {\tt map\_error} ÕÓÔÁÎÏ×ÌÅÎÁ × ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ,
+ÔÏ ÉÍÅÅÔ ÓÍÙÓÌ ÐÅÒÅÄ ÐÒÏÄÏÌÖÅÎÉÅÍ ÒÁÂÏÔÙ ÅÅ ÏÂÎÕÌÉÔØ. îÅËÏÔÏÒÙÅ ÆÕÎËÃÉÉ 
+ÂÉÂÌÉÏÔÅËÉ ÐÒÏ×ÅÒÑÀÔ ÅÇÏ ÐÏÓÌÅ ×ÙÚÏ×Á ÄÒÕÇÉÈ ÆÕÎËÃÉÊ, Á ÏÂÎÕÌÅÎÉÅ ÐÏÓÌÅ
+ÕÓÐÅÛÎÏÊ ÏÐÅÒÁÃÉÉ ÎÅ ÇÁÒÁÎÔÉÒÏ×ÁÎÏ.
+
+\chapter{æÕÎËÃÉÉ ÄÏÓÔÕÐÁ Ë ×ÅËÔÏÒÎÙÍ ÆÁÊÌÁÍ}
+
+æÕÎËÃÉÉ ÄÏÓÔÕÐÁ Ë ×ÅËÔÏÒÎÙÍ ÆÁÊÌÁÍ ÏÐÉÓÁÎÙ × ÚÁÇÏÌÏ×ÏÞÎÏÍ ÆÁÊÌÅ {\tt dgt.h}.
+÷ ÎÅÍ ÏÐÒÅÄÅÌÅÎÁ ÓÔÒÕËÔÕÒÁ {\tt DGT}, ÁÎÁÌÏÇÉÞÎÁÑ ÐÏ ÓÍÙÓÌÕ ÓÔÒÕËÔÕÒÅ {\tt EPP}.
+
+ðÏÓËÏÌØËÕ × ÚÁÇÏÌÏ×ËÅ ×ÅËÔÏÒÎÙÈ ÆÁÊÌÏ× ÎÉËÁËÏÊ ÉÎÆÏÒÍÁÃÉÉ ËÒÏÍÅ ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ
+ËÏÏÒÄÉÎÁÔ É ÔÉÐÁ ÐÒÏÅËÃÉÉ ÎÅ ÈÒÁÎÉÔÓÑ, ÓÐÏÓÏÂÏ× ÐÒÑÍÏÊ ÒÁÂÏÔÙ Ó ÚÁÇÏÌÏ×ËÏÍ
+ÎÅ ÐÒÅÄÕÓÍÏÔÒÅÎÏ.
+
+\section{TÉÐÙ ÄÁÎÎÙÈ}
+
+÷ ÏÔÌÉÞÉÅ ÏÔ ÒÁÓÔÒÏ×ÙÈ ÆÁÊÌÏ×, ÚÎÁÞÅÎÉÅÍ ËÏÔÏÒÙÈ × ÔÏÞËÅ Ñ×ÌÑÅÔÓÑ 
+ÏÂÙÞÎÏÅ ÃÅÌÏÅ ÞÉÓÌÏ, ×ÅËÔÏÒÎÙÅ ÆÁÊÌÙ ÈÒÁÎÑÔ ÄÏ×ÏÌØÎÏ ÓÌÏÖÎÙÅ ÏÂßÅËÔÙ.
+
+ðÒÉ×ÅÄÅÍ ÉÈ ÏÐÉÓÁÎÉÑ:
+\index{POINT}%
+\var{POINT}{óÔÒÕËÔÕÒÁ ÄÌÑ ÈÒÁÎÅÎÉÑ ËÏÏÒÄÉÎÁÔ ÔÏÞËÉ. éÍÅÅÔ Ä×Á ÐÏÌÑ
+ÔÉÐÁ {\tt signed short int}~--- {\tt x} É {\tt y}. îÅÓÍÏÔÒÑ ÎÁ ÓÈÏÖÅÓÔØ
+ÏÐÉÓÁÎÉÑ ÓÏ ÓÔÒÕËÔÕÒÏÊ {\tt XPoint}, ÐÏÐÙÔËÁ ÐÅÒÅÄÁÔØ ÍÁÓÓÉ× ÔÏÞÅË ÔÉÐÁ
+{\tt POINT} × ÆÕÎËÃÉÀ {tt XDrawLine} ÐÏÞÅÍÕ-ÔÏ Ë ÕÓÐÅÈÕ ÎÅ ÐÒÉ×ÏÄÉÔ}
+\index{DGT_ITEM}
+\var{DGT\_ITEM}{óÔÒÕËÔÕÒÁ ÄÌÑ ÈÒÁÎÅÎÉÑ ÉÎÆÏÒÍÁÃÉÉ Ï ×ÅËÔÏÒÎÏÍ ÏÂßÅËÔÅ~---
+ÐÏÌÉÌÉÎÉÉ ÉÌÉ ÔÏÞËÅ (ÎÅ ÐÕÔÁÔØ ÔÏÞËÕ-ÏÂßÅËÔ Ó ÔÏÞËÏÊ-ÕÚÌÏÍ ÌÉÎÉÉ)).
+åÅ ÐÏÌÑ:}
+\var{long int ID}{ 32-ÂÉÔÎÙÊ ÉÄÅÎÔÉÆÉËÁÔÏÒ ÏÂßÅËÔÁ.}
+\var{short int x1,y1}{ ÌÅ×ÙÊ ÎÉÖÎÉÊ ÕÇÏÌ ÍÁÓËÉ, ÅÓÌÉ ÏÂßÅËÔ~--- ÐÏÌÉÌÉÎÉÑ ÉÌÉ ËÏÏÒÄÉÎÁÔÙ
+ÔÏÞËÉ, ÅÓÌÉ ÏÂßÅËÔ~--- ÔÏÞËÁ.}
+\var{short int x2,y2}{ ÐÒÁ×ÙÊ ×ÅÒÈÎÉÊ ÕÇÏÌ ÍÁÓËÉ. õ ÔÏÞÅË~--- ÎÅ ÉÓÐÏÌØÚÕÅÔÓÑ.}
+\var{shott int npoints}{ ÞÉÓÌÏ ÕÚÌÏ× × ÌÉÎÉÉ. åÓÌÉ 0, ÔÏ ÏÂßÅËÔ~--- ÔÏÞËÁ, 
+ÏÔ 2 ÄÏ 500~--- ÐÏÌÉÌÉÎÉÑ, ÏÓÔÁÌØÎÙÅ ÚÎÁÞÅÎÉÑ ÎÅÄÏÐÕÓÔÉÍÙ.}
+\var{POINT s[500]}{ ÍÁÓÓÉ× ËÏÏÒÄÉÎÁÔ ÔÏÞÅË ÐÏÌÉÌÉÎÉÉ.}
+
+óÔÒÕËÔÕÒÁ {\tt DGT}\index{DGT|textbf} ÈÒÁÎÉÔ ×ÓÀ ÉÎÆÏÒÍÁÃÉÀ, ÎÅÏÂÈÏÄÉÍÕÀ ÐÒÉ ÒÁÂÏÔÅ Ó ×ÅËÔÏÒÎÙÍ
+ÆÁÊÌÏÍ. ðÒÏÇÒÁÍÍÉÓÔÕ ÉÍÅÅÔ ÓÍÙÓÌ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ ÞÉÔÁÔØ ÓÌÅÄÕÀÝÉÅ ÅÅ ÐÏÌÑ:
+\index{DGT!XLeft}\index{DGT!XRight}\index{DGT!YTop}\index{DGT!YBottom}%
+\index{XLeft!DGT}\index{XRight!DGT}\index{YTop!DGT}\index{YBottom!DGT}%
+\var{double XLeft,YBottom,XRight,YTop}{ ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ ËÏÏÒÄÉÎÁÔÙ ÇÒÁÎÉÃ
+ÆÁÊÌÁ.}
+\index{mode!DGT}%
+\var{int mode}{ òÅÖÉÍ ÄÏÓÔÕÐÁ. ëÏÍÂÉÎÁÃÉÑ ÔÅÈ ÖÅ ËÏÎÓÔÁÎÔ {\tt MAP\_INPUT} É
+{\tt MAP\_OUTPUT}, ÞÔÏ É ÐÏÌÅ {\tt mode} ÓÔÒÕËÔÕÒÙ {\tt EPP}.}
+\index{projection!DGT}%
+\var{unsigned char projection}{ôÉРËÏÏÒÄÉÎÁÔÎÏÊ ÓÉÓÔÅÍÙ. ÷ÏÚÍÏÖÎÙÅ ÚÎÁÞÅÎÉÑ
+ÏÐÉÓÁÎÙ × ÒÁÚÄÅÌÅ \ref{EPPHEADER}.}
+\var{DGT\_ITEM *buffer}{ âÕÆÅÒ ÄÌÑ ÈÒÁÎÅÎÉÑ ÔÅËÕÝÅÇÏ ÏÂßÅËÔÁ. ïÂÙÞÎÏ ÄÏÓÔÕÐ
+Ë ÜÔÏÊ ÓÔÒÕËÔÕÒÅ ×ÙÐÏÌÎÑÅÔÓÑ Ó ÐÏÍÏÝØÀ ÍÁËÒÏÓÏ×, ÏÐÉÓÁÎÎÙÈ × ÒÁÚÄÅÌÅ \ref{ItemMacros}.}
+\var{int eof}{ æÌÁÇ, ×ÙÓÔÁ×ÌÑÅÍÙÊ × ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ, ÅÓÌÉ ÐÒÏÞÉÔÁΠÐÒÉÚÎÁË
+ËÏÎÃÁ ÆÁÊÌÁ.}
+\var{int item\_no}{ ðÏÒÑÄËÏ×ÙÊ ÎÏÍÅÒ ÔÅËÕÝÅÇÏ ÏÂßÅËÔÁ}
+\section{ïÔËÒÙÔÉÅ ÆÁÊÌÁ}
+
+\index{open_dgt}%
+\function{DGT *open\_dgt(char *filename)}
+\index{fopen_dgt}%
+\function{DGT *fopen\_dgt(FILE *f)}
+
+ïÔËÒÙ×ÁÀÔ ÓÕÝÅÓÔ×ÕÀÝÉÊ ÆÁÊÌ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÞÔÅÎÉÑ. ÷ÏÚ×ÒÁÝÁÀÔ ÕËÁÚÁÄÅÌØ
+ÎÁ ÓÔÒÕËÔÕÒÕ {\tt DGT} ÉÌÉ {\tt NULL}, ÅÓÌÉ ÐÒÏÉÚÏÛÌÁ ÏÛÉÂËÁ.
+
+\index{creat_dgt}%
+\function{DGT *creat\_dgt(char *filename, double x\_left, double y\_bottom,
+double x\_right, double y\_top, unsigned char proj)}
+\index{fcreat_dgt}%
+\function{DGT *fcreat\_dgt(FILE *f,  double x\_left, double y\_bottom,
+double x\_right, double y\_top, unsigned char proj)}
+\index{mcreat_dgt}%
+\function{DGT *mcreat\_dgt(double x\_left, double y\_bottom,
+double x\_right, double y\_top, unsigned char proj)}
+
+óÏÚÄÁÀÔ ÆÁÊÌ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ. ðÏÌÕÞÁÀÔ × ËÁÞÅÓÔ×Å ÐÁÒÁÍÅÔÒÏ×
+ÐÒÅÄÅÌÙ ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔ É ÔÉРÐÒÏÅËÃÉÉ. 
+
+ïÓÏÂÏÅ ×ÎÉÍÁÎÉÅ ÓÔÏÉÔ ÏÂÒÁÔÉÔØ ÎÁ ÆÕÎËÃÉÀ {\tt mcreat\_dgt}, ËÏÔÏÒÁÑ
+ÓÏÚÄÁÅÔ ÐÕÓÔÏÊ ÆÁÊÌ × ÐÁÍÑÔÉ, ÏÔËÒÙÔÙÊ ÎÁ ÞÔÅÎÉÅ-ÚÁÐÉÓØ. ðÏÄÒÏÂÎÅÅ
+ÒÁÂÏÔÁ Ó ÆÁÊÌÁÍÉ × ÐÁÍÑÔÉ ÏÐÉÓÁÎÁ × ÒÁÚÄÅÌÅ \ref{dgtInMemory}
+
+äÌÑ ÏÔËÒÙÔÉÑ ÆÁÊÌÏ× Ó ÐÒÅÄÅÌÁÍÉ É ÐÒÏÅËÃÉÅÊ ÁÎÁÌÏÇÉÞÎÙÍÉ ÕÖÅ ÓÕÝÅÓÔ×ÕÀÝÅÍÕ
+ÆÁÊÌÕ, ÓÕÝÅÓÔ×ÕÀÔ ÆÕÎËÃÉÉ:
+
+\index{creat_dgt_as}%
+\function{DGT *creat\_dgt\_as(char *filename,DGT *pattern);}
+\index{fcreat_dgt_as}%
+\function{DGT *fcreat\_dgt\_as(FILE *f,DGT *pattern);}
+\index{mcreat_dgt_as}%
+\function{DGT *mcreat\_dgt\_as(DGT *pattern);}
+
+\section{óÍÅÎÁ ÒÅÖÉÍÁ É ÚÁËÒÙÔÉÅ ÆÁÊÌÁ}
+
+æÕÎËÃÉÑ
+\index{reset_dgt}%
+\function{void reset\_dgt(DGT* dgt);}
+ÄÅÌÁÅÔ ÔÅËÕÝÉÍ ÏÂßÅËÔÏÍ ÐÅÒ×ÙÊ. åÓÌÉ ÆÁÊÌ ÄÏ ÜÔÏÇÏ ÂÙÌ ÏÔËÒÙÔ × ÒÅÖÉÍÅ
+ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ, ÏΠÐÅÒÅÏÔËÒÙ×ÁÅÔÓÑ × ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ
+ÞÔÅÎÉÑ. 
+
+\index{load_dgt}%
+\function{int load\_dgt(DGT *dgt);}
+úÁÇÒÕÖÁÅÔ ÆÁÊÌ × ÐÁÍÑÔØ, ÄÅÌÁÑ ×ÏÚÍÏÖÎÙÍ ÐÒÑÍÏÊ ÄÏÓÔÕРÎÁ ÞÔÅÎÉÅ-ÚÁÐÉÓØ
+É ÍÎÏÇÉÅ ÄÒÕÇÉÅ ×ÏÚÍÏÖÎÏÓÔÉ, ÏÐÉÓÁÎÎÙÅ × ÒÁÚÄÅÌÅ \ref{dgtInMemory}
+
+\index{close_dgt}%
+\function{void close\_dgt(DGT *dgt);}
+úÁËÒÙ×ÁÅÔ ÆÁÊÌ, ÏÓ×ÏÂÏÖÄÁÑ ×ÓÀ ×ÙÄÅÌÅÎÎÕÀ ÐÏÄ ÎÅÇÏ ÐÁÍÑÔØ. éÚÍÅÎÅÎÉÑ
+× ÐÏÓÌÅÄÎÅÍ ÏÂßÅËÔÅ ÓÏÈÒÁÎÑÀÔÓÑ, ÅÓÌÉ ÆÁÊÌ ÂÙÌ ÏÔËÒÙÔ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ
+ÚÁÐÉÓÉ.
+
+\section{þÔÅÎÉÅ É ÚÁÐÉÓØ ÏÂßÅËÔÏ×}
+
+ðÏÓÌÅ ÏÔËÒÙÔÉÑ ÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÆÁÊÌÁ, ÐÅÒ×ÙÊ ÏÂßÅËÔ Á×ÔÏÍÁÔÉÞÅÓËÉ ÓÞÉÔÙ×ÁÅÔÓÑ
+× ÂÕÆÅÒ, É ÄÏÓÔÕÐÅΠӠÐÏÍÏÝØÀ ÍÁËÒÏÓÏ× ÄÌÑ ÒÁÂÏÔÙ Ó ÂÕÆÅÒÏÍ (ÓÍ. ÒÁÚÄÅÌ
+\ref{ItemMacros}).
+
+äÌÑ ÐÅÒÅÈÏÄÁ Ë ÓÌÅÄÕÀÝÅÍÕ ÏÂßÅËÔÕ ×ÙÚÙ×ÁÅÔÓÑ ÍÁËÒÏÓ
+\index{dgt_next}%
+\function{void dgt\_next(DGT *dgt);}
+
+÷ ÎÅËÏÔÏÒÙÈ ÓÌÕÞÁÑÈ ÕÄÏÂÎÏ ÒÁÂÏÔÁÔØ Ó ËÏÐÉÑÍÉ ÏÂßÅËÔÏ×, ÒÁÚÍÅÝÅÎÎÙÈ
+× ÄÉÎÁÍÉÞÅÓËÏÊ ÐÁÍÑÔÉ. ÷ ÜÔÏÍ ÓÌÕÞÁÅ ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ
+ÆÕÎËÃÉÀ
+
+\index{dgt_get}%
+\function{DGT\_ITEM *dgt\_get(DGT *dgt)}
+
+ëÏÔÏÒÁÑ ÒÁÚÍÅÝÁÅÔ ÔÅËÕÝÉÊ ÏÂßÅËÔ × ÐÁÍÑÔÉ, ÐÅÒÅÍÅÝÁÅÔÓÑ ÎÁ ÓÌÅÄÕÀÝÉÊ
+ÏÂßÅËÔ É ×ÏÚ×ÒÁÝÁÅÔ ÕËÁÚÁÔÅÌØ ËÏÐÉÀ ÏÂßÅËÔÁ, ÂÙ×ÛÉÊ ÔÅËÕÝÉÍ ÄÏ ÅÅ ×ÙÚÏ×Á.
+
+äÌÑ ÚÁÐÉÓÉ × ÆÁÊÌ ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÌÉÂÏ ÆÕÎËÃÉÀ
+
+\index{dgt_put}%
+\function{void dgt\_put(DGT *dgt, DGT\_ITEM *item);}
+ÌÉÂÏ ÍÏÄÉÆÉÃÉÒÏ×ÁÔØ ÔÅËÕÝÉÊ ÏÂßÅËÔ Ó ÐÏÍÏÝØÀ ÍÁËÒÏÓÏ× É ÆÕÎËÃÉÊ ÄÌÑ
+ÒÁÂÏÔÙ Ó ÔÅËÕÝÅÊ ÚÁÐÉÓØÀ É ÚÁÔÅÍ ×ÙÚ×ÁÔØ {\tt dgt\_next} ÄÌÑ ÐÅÒÅÈÏÄÁ
+Ë ÎÏ×ÏÍÕ ÏÂßÅËÔÕ.
+\section{éÔÅÒÁÔÏÒÙ}
+ðÏÓËÏÌØËÕ ×ÅËÔÏÒÎÙÅ ÆÁÊÌÙ ÈÒÁÎÑÔ Ä×Á ÔÉÐÁ ÏÂßÅËÔÏ×~--- ÌÉÎÉÉ É ÔÏÞËÉ,
+É ÔÏÌØËÏ ÏÞÅÎØ ÎÅÍÎÏÇÉÅ ÁÌÇÏÒÉÔÍÙ (× ÏÓÎÏ×ÎÏÍ ÔÒÁÎÓÆÏÒÍÁÃÉÑ ËÏÏÒÄÉÎÁÔ)
+ÚÁÔÒÁÇÉ×ÁÀÔ É ÔÅ É ÄÒÕÇÉÅ, ÏÐÒÅÄÅÌÅÎÙ ÉÔÅÒÁÔÏÒÙ:
+\index{for_each_line}%
+\function{for\_each\_line(DGT *dgt,void (*item\_proc)(DGT *dgt),
+ DGT *outstream);}
+\index{for_each_point}%
+\function{for\_each\_point(DGT *dgt,void (*item\_proc)(DGT *dgt),
+DGT *outstream);}
+
+ïÎÉ ×ÙÚÙ×ÁÀÔ ÕËÁÚÁÎÎÕÀ ÆÕÎËÃÉÀ ÔÏÌØËÏ ÄÌÑ ÌÉÎÉÊ ÉÌÉ ÔÏÞÅË ÆÁÊÌÁ.
+æÕÎËÃÉÉ ÐÅÒÅÄÁÅÔÓÑ ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÒÕËÔÕÒÕ {\tt DGT} × ÂÕÆÅÒÅ
+ËÏÔÏÒÏÊ ÎÁÈÏÄÉÔÓÑ ÏÂßÅËÔ.
+
+üÔÉ ÉÔÅÒÁÔÏÒÙ ÍÏÖÎÏ ÐÒÉÍÅÎÑÔØ Ë ÆÁÊÌÁÍ, ÏÔËÒÙÔÙÍ ÄÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ
+ÞÔÅÎÉÑ ÉÌÉ Ë ÆÁÊÌÁÍ ÚÁÇÒÕÖÅÎÎÙÍ × ÐÁÍÑÔØ.
+
+åÓÌÉ ÐÁÒÁÍÅÔÒ {\tt outstream} ÎÅ {\tt NULL}, ÔÏ × ÆÁÊÌ, ÎÁ ËÏÔÏÒÙÊ
+ÏΠÕËÁÚÙ×ÁÅÔ, ËÏÐÉÒÕÀÔÓÑ ×ÓÅ ÏÂßÅËÔÙ, ËÏÔÏÒÙÅ ÎÅ ÏÂÒÁÂÁÔÙ×ÁÌÉÓØ É
+ÏÂÒÁÂÏÔÁÎÎÙÅ ÏÂßÅËÔÙ.
+
+ôÏ ÅÓÔØ, ÎÁÐÒÉÍÅÒ, × ÓÌÕÞÁÅ {\tt for\_each\_line} ÔÏÞËÁ ÂÕÄÅÔ ÓËÏÐÉÒÏ×ÁÎÁ
+ÂÅÚ ÏÂÒÁÂÏÔËÉ, Á ÌÉÎÉÑ ÚÁÐÉÓÁÎÁ ÐÏÓÌÅ ÔÏÇÏ, ËÁË ÅÅ ÉÚÍÅÎÉÔ {\tt item\_proc}.
+
+ëÒÏÍÅ ÜÔÏÇÏ, ÓÕÝÅÓÔ×ÕÅÔ ÉÔÅÒÁÔÏÒ
+\index{for_each_item}
+\function{void for\_each\_item(DGT *dgt,void (*item\_proc)(DGT *dgt));}
+
+ËÏÔÏÒÙÊ ×ÙÐÏÌÎÑÅÔ ÐÅÒÅÄÁÎÎÕÀ ÆÕÎËÃÉÀ É ÄÌÑ ÌÉÎÉÊ É ÄÌÑ ÔÏÞÅË. 
+õ ÎÅÇÏ ÎÅÔ ÐÁÒÁÍÅÔÒÁ {\tt outstream}, ÔÁË ÞÔÏ ÅÓÌÉ ÎÕÖÎÏ ÚÁÐÉÓÁÔØ
+ÉÚÍÅÎÅÎÎÙÅ ÏÂßÅËÔÙ, {\tt item\_proc} ÄÏÌÖÎÁ Ï ÜÔÏÍ ÐÏÚÁÂÏÔÉÔØÓÑ ÓÁÍÁ.
+\section{òÁÂÏÔÁ Ó ÔÅËÕÝÉÍ ÏÂßÅËÔÏÍ}
+\label{ItemMacros}
+éÔÁË, ÎÕÖÎÁÑ ×ÁÍ ÌÉÎÉÑ (ÔÏÞËÁ) ÎÁÈÏÄÉÔÓÑ × ÂÕÆÅÒÅ ÓÔÒÕËÔÕÒÙ {\tt DGT}.
+þÔÏ ÍÏÖÎÏ ÄÅÌÁÔØ Ó ÎÅÊ ÄÁÌØÛÅ?
+
+÷Ï-ÐÅÒ×ÙÈ, ÎÕÖÎÏ ÕÍÅÔØ ÏÐÒÅÄÅÌÑÔØ, ÌÉÎÉÑ ÜÔÏ ÉÌÉ ÔÏÞËÁ.
+äÌÑ ÜÔÏÇÏ ÏÐÒÅÄÅÌÅÎÙ ÍÁËÒÏÓÙ:
+\index{dgt_is_line}%
+\function{int dgt\_is\_line(DGT *dgt)}
+\index{dgt_is_point}%
+\function{int dgt\_is\_point(DGT *dgt)}
+÷Ï-×ÔÏÒÙÈ, ÎÅÚÁ×ÉÓÉÍÏ ÏÔ ÔÏÇÏ, ÌÉÎÉÑ ÜÔÏ ÉÌÉ ÔÏÞËÁ,
+ÎÁÍ ÍÏÖÅÔ ÐÏÔÒÅÂÏ×ÁÔØÓÑ ÉÄÅÎÔÉÆÉËÁÔÏÒ ÏÂßÅËÔÁ.
+\index{dgt_id}%
+\function{long int dgt\_id(DGT *dgt)}
+÷-ÔÒÅÔØÉÈ, ËÏÏÒÄÉÎÁÔÙ ÔÏÞËÉ:
+\index{dgt_pointx}%
+\function{short int dgt\_pointx(DGT *dgt)}
+\index{dgt_pointy}%
+\function{short int dgt\_pointy(DGT *dgt)}
+ÉÌÉ ËÏÏÒÄÉÎÁÔÙ ÐÒÑÍÏÕÇÏÌØÎÉËÁ-ÍÁÓËÉ ÌÉÎÉÉ:
+\index{dgt_xl}%
+\function{short int dgt\_xl(DGT *dgt)}
+\index{dgt_yb}%
+\function{short int dgt\_yb(DGT *dgt)}
+\index{dgt_xr}%
+\function{short int dgt\_xr(DGT *dgt)}
+\index{dgt_yt}%
+\function{short int dgt\_yt(DGT *dgt)}
+÷-ÞÅÔ×ÅÒÔÙÈ, ËÏÌÉÞÅÓÔ×Ï ÔÏÞÅËÔ × ÌÉÎÉÉ:
+\index{dgt_line_len}%
+\function{short int dgt\_line\_len(DGT *dgt)}
+é, ÎÁËÏÎÅÃ, ËÏÏÒÄÉÎÁÔÙ $i$-ÔÏÇÏ ÕÚÌÁ ÌÉÎÉÉ:
+\index{dgt_nx}%
+\function{short int dgt\_nx(DGT *dgt,int i)}
+\index{dgt_ny}%
+\function{short int dgt\_ny(DGT *dgt,int i)}
+ïÂÒÁÔÉÔÅ ×ÎÉÍÁÎÉÅ, ÞÔÏ ÐÅÒ×ÁÑ ÔÏÞËÁ ÌÉÎÉÉ ÉÍÅÅÔ ÎÏÍÅÒ 0, Á ÐÏÓÌÅÄÎÑÑ~---
+{\tt dgt\_line\_len(dgt)-1}.
+
+ëÒÏÍÅ ÔÏÇÏ, ÉÎÏÇÄÁ ÕÄÏÂÎÅÅ ÐÏÌÕÞÉÔØ ÓÓÙÌËÕ ÎÁ ÔÏÞËÕ ÉÌÉ ÕÚÅÌ ÌÉÎÉÉ,
+ËÁË ÎÁ ÓÔÒÕËÔÕÒÕ {\tt POINT}. äÌÑ ÜÔÏÇÏ ÐÒÅÄÎÁÚÎÁÞÅÎÙ ÍÁËÒÏÓÙ:
+\index{dgt_node}%
+\function{POINT dgt\_node(DGT *dgt,int i)}
+\index{dgt_point}%
+\function{POINT dgt\_point(DGT *dgt)}
+
+åÓÌÉ ×ÁÍ ÐÏ ËÁËÉÍ-ÔÏ ÐÒÉÞÉÎÁÍ ÎÕÖÎÏ ÒÁÂÏÔÁÔØ ÎÅ ÓÏ ÓÔÒÕËÔÕÒÏÊ {\tt DGT},
+Á Ó ÏÔÄÅÌØÎÙÍ ÏÂßÅËÔÏÍ, ÒÁÚÍÅÝÅÎÎÙÍ × ÄÉÎÁÍÉÞÅÓËÏÊ ÐÁÍÑÔÉ, ÔÏ ÚÁÍÅÎÉÔÅ
+ÐÒÅÆÉËÓ {\tt dgt\_} ÎÁ ÐÒÅÆÉËÓ {\tt item\_} É × ËÁÞÅÓÔ×Å ÐÅÒ×ÏÇÏ 
+ÐÁÒÁÍÅÔÒÁ ÕËÁÚÙ×ÁÊÔÅ ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÒÕËÔÕÒÕ {\tt DGT\_ITEM}\index{DGT_ITEM}.
+
+ôÅÐÅÒØ ÍÙ ÍÏÖÅÍ ÐÒÏÞÉÔÁÔØ ÌÀÂÏÊ ÐÁÒÁÍÅÔÒ ÏÂßÅËÔÁ. ÷ÏÐÒÏÓ × ÔÏÍ, ËÁË ÅÇÏ
+ÉÚÍÅÎÉÔØ.
+
+ïÔ×ÅÔ ÐÅÒ×ÙÊ, ÐÁÒÁÄÏËÓÁÌØÎÙÊ: ÌÀÂÏÊ ÉÚ ×ÙÛÅÐÒÉ×ÅÄÅÎÎÙÈ ÍÁËÒÏÓÏ× (ËÒÏÍÅ
+{\tt dgt\_is\_line}\index{dgt_is_line} É {\tt dgt\_is\_point})\index{dgt_is_point} ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ × {\bf ÌÅ×ÏÊ}
+ÞÁÓÔÉ ÏÐÅÒÁÔÏÒÁ ÐÒÉÓ×ÁÉ×ÁÎÉÑ. 
+
+÷ÅÄØ ÜÔÏ ÎÅ ÆÕÎËÃÉÉ, Á ÍÁËÒÏÓÙ, ÄÁÀÝÉÅ ÄÏÓÔÕРˠÎÅËÏÔÏÒÙÍ ÐÏÌÑÍ ÓÔÒÕËÔÕÒÙ
+{\tt DGT\_ITEM}.
+
+ïÄÎÁËÏ ÔÁË ÐÏÓÔÕÐÁÔØ ÎÅ ÒÅËÏÍÅÎÄÕÅÔÓÑ. äÅÌÏ × ÔÏÍ, ÞÔÏ × ÔÁËÏÍ ÓÌÕÞÁÅ
+ÎÉÇÄÅ ÎÅ ÂÕÄÅÔ ÏÔÍÅÞÅÎÏ, ÞÔÏ ÏÂßÅËÔ ÉÚÍÅÎÅÎ, ÐÏÜÔÏÍÕ ÉÚÍÅÎÅÎÉÑ ÍÏÇÕÔ ÂÙÔØ
+ÎÅ ÓÏÈÒÁÎÅÎÙ. åÓÌÉ ÕÖ ÏÞÅÎØ ÈÏÞÅÔÓÑ, ÔÏ ÐÏÓÌÅ ÐÒÑÍÏÇÏ ÉÚÍÅÎÅÎÉÑ ÐÏÌÅÊ
+ÏÂßÅËÔÁ, ÉÓÐÏÌØÚÕÊÔÅ ÆÕÎËÃÉÀ
+
+\function{void dgt\_touch(DGT *dgt)}\index{dgt_touch}
+ÞÔÏÂÙ ÐÏÍÅÔÉÔØ ÏÂßÅËÔ ËÁË ÉÚÍÅÎÅÎÎÙÊ.
+
+îÏ ÌÕÞÛÅ ÐÏÌØÚÏ×ÁÔØÓÑ ÓÌÅÄÕÀÝÉÍÉ ÆÕÎËÃÉÑÍÉ:
+
+\function{void dgt\_set\_id(DGT *dgt,long int newID);}\index{dgt_set_id}
+õÓÔÁÎÁ×ÌÉ×ÁÅÔ ÉÄÅÎÔÉÆÉËÁÔÏÒ ÏÂßÅËÔÁ.
+\function{void dgt\_set\_point(DGT *dgt, int x, int y);}\index{dgt_set_point}
+úÁÄÁÅÔ ËÏÏÒÄÉÎÁÔÙ ÔÏÞËÉ É ÄÅÌÁÅÔ ÏÂßÅËÔ ÔÏÞËÏÊ. åÓÌÉ ×Ù ÈÏÔÉÔÅ ÓÏÈÒÁÎÉÔØ
+ÏÄÎÕ ËÏÏÒÄÉÎÁÔÕ, ×ÍÅÓÔÏ ÎÅÅ ÐÅÒÅÄÁÊÔÅ ËÏÎÓÔÁÎÔÕ {\tt KEEP\_OLD\_VALUE}%
+\index{KEEP_OLD_VALUE}
+\function{int dgt\_add\_node(DGT *dgt,int x,int y);}\index{dgt_add_node}
+äÏÂÁ×ÌÑÅÔ ÔÏÞËÕ × ËÏÎÅàÌÉÎÉÉ (ÉÌÉ ÓÏÚÄÁÅÔ ÐÅÒ×ÕÀ ÔÏÞËÕ É ÐÏÍÅÞÁÅÔ 
+ÏÂßÅËÔ ËÁË ÌÉÎÉÀ. ÷ÏÚ×ÒÁÝÁÅÔ 0 × ÓÌÕÞÁÅ, ÅÓÌÉ ×ÓÅ × ÐÏÒÑÄËÅ ÉÌÉ
+ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ, ÅÓÌÉ ÔÏÞËÕ ÄÏÂÁ×ÉÔØ ÎÅ×ÏÚÍÏÖÎÏ (ÕÖÅ ÅÓÔØ 500 ÔÏÞÅË).
+\function{int dgt\_ins\_node(DGT *dgt,int index,int x,int y)}\index{dgt_ins_node}
+÷ÓÔÁ×ÌÑÅÔ ÔÏÞËÕ × ÌÉÎÉÀ ÐÅÒÅÄ ÕÚÌÏÍ ÎÏÍÅÒ {\tt index}. ÷ÏÚ×ÒÁÝÁÅÔ 0,
+ÅÓÌÉ ×ÓÅ × ÐÏÒÑÄËÅ, 1 ÅÓÌÉ ÞÉÓÌÏ ÔÏÞÅË ÐÒÅ×ÙÓÉÔ 500, É 2 ÅÓÌÉ ÕÚÌÁ Ó ÔÁËÉÍ
+ÎÏÍÅÒÏÍ ÎÅÔ. 
+\function{int dgt\_mv\_node(DGT *dgt,int index,int x,int y)}\index{dgt_mv_node}
+íÅÎÑÅÔ ËÏÏÒÄÉÎÁÔÙ ÕËÁÚÁÎÎÏËÇÏ ÕÚÌÁ ÎÁ ÚÁÄÁÎÎÙÅ. ÷ÏÚ×ÒÁÝÁÅÔ 0, ÅÓÌÉ
+×ÓÅ × ÐÏÒÑÄËÅ É ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ, ÅÓÌÉ ÔÁËÏÇÏ ÕÚÌÁ ÎÅÔ.
+
+åÓÌÉ ×ÁÍ ÎÁÄÏ ÉÚÍÅÎÉÔØ ÔÏÌØËÏ ÏÄÎÕ ËÏÏÒÄÉÎÁÔÕ, ÐÅÒÅÄÁÊÔÅ ×ÍÅÓÔÏ ×ÔÏÒÏÊ
+ËÏÎÓÔÁÎÔÕ {\tt KEEP\_OLD\_VALUE}\index{KEEP_OLD_VALUE}.
+
+\function{int dgt\_rm\_node(DGT *dgt,int index)}\index{dgt_rm_node}
+õÄÁÌÑÅÔ ÕËÁÚÁÎÎÙÊ ÕÚÅÌ. ïÛÉÂËÁ ×ÏÚÎÉËÁÅÔ, ÅÓÌÉ ÜÔÏ ÂÙÌ ÐÒÅÄÐÏÓÌÅÄÎÉÊ ÕÚÅÌ
+× ÌÉÎÉÉ. (ëÏÒÒÅËÔÎÁÑ ÌÉÎÉÑ ÄÏÌÖÎÁ ÓÏÄÅÒÖÁÔØ ÎÅ ÍÅÎÅÅ Ä×ÕÈ ÕÚÌÏ×).
+
+é, ÎÁËÏÎÅÃ, ÒÁÚÒÅÚÁÎÉÅ ÌÉÎÉÊ.
+
+\function{int dgt\_split(DGT *dgt,int index)}\index{dgt_split}
+òÁÚÒÅÚÁÅÔ ÌÉÎÉÀ × ÕËÁÚÁÎÎÏÍ ÕÚÌÅ. ðÒÉ ÜÔÏÍ 
+ÕÚÅÌ ÄÕÂÌÉÒÕÅÔÓÑ É ÐÏÐÁÄÁÅÔ × ÏÂÅ ÐÏÌÏ×ÉÎËÉ. ôÅËÕÝÉÍ ÓÔÁÎÏ×ÉÔÓÑ È×ÏÓÔ ÌÉÎÉÉ,
+Á ÎÁÞÁÌÏ, ÅÓÌÉ ÆÁÊÌ ÂÙÌ ÏÔËÒÙÔ × ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÊ ÚÁÐÉÓÉ, ÓÂÒÁÓÙ×ÁÅÔÓÑ
+ÎÁ ÄÉÓË. üÔÏÊ ÆÕÎËÃÉÅÊ ÎÅÌØÚÑ ÐÏÌØÚÏ×ÁÔØÓÑ ÉÚ ÉÔÅÒÁÔÏÒÁ {\tt for\_each\_line}\index{for_each_line},
+ÅÓÌÉ ÏΠÐÒÉÍÅÎÑÅÔÓÑ Ë ÆÁÊÌÕ, ÏÔËÒÙÔÏÍÕ × ÒÅÖÉÍÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÞÔÅÎÉÑ.
+
+\function{int dgt\_cut\_segment(DGT *dgt,int index)}\index{dgt_cut_segment}
+òÁÚÒÅÚÁÅÔ ÌÉÎÉÀ, ÕÄÁÌÑÑ ÏÔÒÅÚÏË ÏÔ $n-1$ ÄÏ $n$-ÎÏÇÏ ÕÚÌÁ. ÷ÓÅ ÏÓÔÁÌØÎÏÅ
+× ÔÏÞÎÏÓÔÉ ËÁË × ÐÒÅÄÙÄÕÝÅÍ ÓÌÕÞÁÅ.
+
+ðÒÏÃÅÄÕÒÁ {\tt dgt\_next}\index{dgt_next} ÐÏÚÁÂÏÔÉÔÓÑ Ï ÎÅËÏÔÏÒÙÈ ÉÚ ÏÛÉÂÏË, ËÏÔÏÒÙÅ
+ÍÏÖÎÏ ÄÏÐÕÓÔÉÔØ ÐÒÉ ÒÅÄÁËÔÉÒÏ×ÁÎÉÉ ÏÂßÅËÔÁ.
+\begin{enumerate}
+\item íÁÓËÁ ÌÉÎÉÉ ÂÕÄÅÔ ÓËÏÒÒÅËÔÉÒÏ×ÁÎÁ.
+\item éÚ Ä×ÕÈ ÓÏÓÅÄÎÉÈ ÕÚÌÏ× Ó ÓÏ×ÐÁÄÁÀÝÉÍÉ ËÏÏÒÄÉÎÁÔÁÍÉ ÂÕÄÅÔ ÏÓÔÁ×ÌÅΠÏÄÉÎ.
+\item ìÉÎÉÉ ÉÚ ÏÄÎÏÊ ÔÏÞËÉ ÂÕÄÕÔ ×ÙÂÒÏÛÅÎÙ.
+\item ôÏÞËÁ Ó ÎÕÌÅ×ÙÍ ÉÄÅÎÔÉÆÉËÁÔÏÒÏÍ ÂÕÄÅÔ ×ÙÂÒÏÛÅÎÁ.
+\end{enumerate}
+
+\section{DGT-ÆÁÊÌÙ × ÐÁÍÑÔÉ}
+
+\label{dgtInMemory}
+÷ÅËÔÏÒÎÙÊ ÆÁÊÌ, ÚÁÇÒÕÖÅÎÎÙÊ × ÐÁÍÑÔØ, ÍÏÖÎÏ ÒÁÓÓÍÁÔÒÉ×ÁÔØ ËÁË ÍÁÓÓÉ×
+ÏÂßÅËÔÏ×. ðÏÓÌÅÄÏ×ÁÔÅÌØÎÙÊ ÄÏÓÔÕРÐÒÏÄÏÌÖÁÅÔ ÒÁÂÏÔÁÔØ, ÎÏ ÓÕÝÅÓÔ×ÕÀÔ
+ÆÕÎËÃÉÉ, ÐÏÚ×ÏÌÑÀÝÉÅ ÓÄÅÌÁÔØ ÔÅËÕÝÉÍ ÏÂßÅËÔÏÍ ÌÀÂÏÊ, ÎÅÚÁ×ÉÓÉÍÏ
+ÏÔ ÐÏÒÑÄËÁ É ÏÂÒÁÝÁÔØÓÑ Ë ÏÂßÅËÔÁÍ, ÎÅ ÄÅÌÁÑ ÉÈ ÔÅËÕÝÉÍÉ.
+
+ðÏÓÌÅÄÎÉÊ ÓÐÏÓÏ ÉÍÅÅÔ ÓÕÝÅÓÔ×ÅÎÎÙÊ ÎÅÄÏÓÔÁÔÏË~--- ÅÓÌÉ ×Ù ÈÏÔÉÔÅ
+ÉÚÍÅÎÉÔØ ÄÌÉÎÕ ÌÉÎÉÉ, ÔÏ ×ÁÍ ÐÒÉÄÅÔÓÑ ÓÁÍÏÍÕ ÐÏÚÁÂÏÔÉÔØÓÑ Ï ×ÙÄÅÌÅÎÉÉ
+ÐÁÍÑÔÉ ÐÏÄ ÎÏ×ÕÀ ÌÉÎÉÀ.
+
+éÔÁË, ÐÒÏÃÅÄÕÒÙ, ÓÐÅÃÉÆÉÞÎÙÅ ÄÌÑ ÆÁÊÌÁ × ÐÁÍÑÔÉ:
+
+\function{int dgt\_seek(DGT *dgt,int index);}\index{dgt_seek}
+
+äÅÌÁÅÔ ÔÅËÕÝÉÍ ÏÂßÅËÔ Ó ÕËÁÚÁÎÎÙÍ ÎÏÍÅÒÏÍ. (ÐÏÓÌÅ ÞÅÇÏ ÍÏÖÎÏ
+ÓÐÏËÏÊÎÏ ÅÇÏ ÍÅÎÑÔØ Ó ÐÏÍÏÝØÀ ÌÀÂÙÈ ÆÕÎËÃÉÊ É ÍÁËÒÏÓÏ× ÐÒÅÄÙÄÕÝÅÇÏ ÒÁÚÄÅÌÁ.)
+
+\function{DGT\_ITEM* dgt\_item\_ptr(DGT *dgt,int index);}\index{dgt_item_ptr}
+%
+÷ÏÚ×ÒÁÝÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ ÏÂßÅËÔ Ó ÕËÁÚÁÎÎÙÍ ÎÏÍÅÒÏÍ. äÌÑ ÄÏÓÔÕÐÁ
+Ë ÜÔÏÍÕ ÏÂßÅËÔÕ ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÍÁËÒÏÓÙ {\tt item\_\dots}.
+
+üÔÏÔ ÓÐÏÓÏ ÄÏÓÔÕÐÁ ÒÅËÏÍÅÎÄÕÅÔÓÑ ÉÓÐÏÌØÚÏ×ÁÔØ ËÁË ÄÏÓÔÕРÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ.
+÷ ËÒÁÊÎÅÍ ÓÌÕÞÁÅ, ÅÓÌÉ ÎÅÏÂÈÏÄÉÍÏ ÉÚÍÅÎÉÔØ ÎÅ ÔÅËÕÝÕÀ ÌÉÎÉÀ, ×ÏÓÐÏÌØÚÕÊÔÅÓØ
+ÆÕÎËÃÉÅÊ:
+\function{int dgt\_replace(DGT *dgt,int index,DGT\_ITEM* new\_item);}\index{dgt_replace}
+
+üÔÁ ÆÕÎËÃÉÑ ÐÏÌÕÞÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ ÄÉÎÁÍÉÞÅÓËÉ ÒÁÚÍÅÝÅÎÎÙÊ ÏÂßÅËÔ
+É ÐÏÍÅÝÁÅÔ ÅÇÏ × ÆÁÊÌ. äÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÓÜËÏÎÏÍÉÔØ ÐÁÍÑÔØ, 
+ÒÁÚÍÅÝÁÊÔÅ ÏÂßÅËÔ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ 
+\function{DGT\_ITEM *alloc\_item(DGT\_ITEM *item);}\index{alloc_item}
+üÔÁ ÆÕÎËÃÉÑ ÐÏÌÕÞÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ ÏÂßÅËÔ, ×ÙÄÅÌÑÅÔ ÐÁÍÑÔÉ ÒÏ×ÎÏ ÓÔÏÌØËÏ,
+ÓËÏÌØËÏ ÎÕÖÎÏ, ÞÔÏÂÙ ÒÁÚÍÅÓÔÉÔØ ÜÔÏÔ ÏÂßÅËÔ, É ËÏÐÉÒÕÅÔ ÅÇÏ ÔÕÄÁ.
+
+æÕÎËÃÉÉ ×ÓÔÁ×ËÉ ÏÂßÅËÔÁ × ÕËÁÚÁÎÎÏÍ ÍÅÓÔÅ × ÂÉÂÌÉÏÔÅËÅ ÎÅÔ.
+ðÒÉ ÄÏÂÁ×ÌÅÎÉÉ ÏÂßÅËÔÁ Ó ÐÏÍÏÝØÀ {\tt dgt\_put}\index{dgt_put} ÅÇÏ ÍÅÓÔÏ ÏÐÒÅÄÅÌÑÅÔÓÑ
+× ÓÏÏÔ×ÅÔÓÔ×ÉÉ Ó ÔÅËÕÝÉÍ ÐÏÒÑÄËÏÍ ÓÏÒÔÉÒÏ×ËÉ. åÓÌÉ ÐÏÒÑÄÏË ÓÏÒÔÉÒÏ×ËÉ
+×ÏÏÂÝÅ ÎÅ ÚÁÄÁ×ÁÌÓÑ, ÔÏ ÜÔÏ ÂÕÄÅÔ ÓÌÅÄÕÀÝÉÊ ÏÂßÅËÔ ÐÏÓÌÅ ÔÅËÕÝÅÇÏ,
+É ÏΠÓÔÁÎÅÔ ÔÅËÕÝÉÍ.
+
+ðÏÒÑÄÏË ÓÏÒÔÉÒÏ×ËÉ dgt ÆÁÊÌÁ × ÐÁÍÑÔÉ ÍÏÖÎÏ ÉÚÍÅÎÉÔØ ÐÒÉ 
+ÐÏÍÏÝÉ ÆÕÎËÃÉÉ 
+\function{void dgt\_sort(DGT *dgt,int (*compare\_func)(DGT\_ITEM* i1, DGT\_ITEM * i2));}\index{dgt_sort}
+
+æÕÎËÃÉÑ {\tt compare\_func} ÄÏÌÖÎÁ ×ÏÚ×ÒÁÝÁÔØ 1, ÅÓÌÉ i1 ÎÁÄÏ ÒÁÚÍÅÓÔÉÔØ
+ÐÏÚÖÅ, ÞÅÍ i2, -1 ÅÓÌÉ ÎÁÏÂÏÒÏÔ, É 0, ÅÓÌÉ ÐÏ ÄÁÎÎÏÍÕ ËÒÉÔÅÒÉÀ ÓÏÒÔÉÒÏ×ËÉ
+ÜÔÉ ÏÂßÅËÔÙ ÒÁ×ÎÙ.
+
+éÚÍÅÎÅÎÉÅ ËÒÉÔÅÒÉÑ ÓÏÒÔÉÒÏ×ËÉ ÐÒÉ ÕÖÅ ÚÁÇÒÕÖÅÎÎÏÍ ÆÁÊÌÅ ÐÒÉ×ÏÄÉÔ
+Ë ÅÇÏ ÐÅÒÅÓÏÒÔÉÒÏ×ËÅ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ {\tt qsort}.
+
+ðÏÜÔÏÍÕ ÌÕÞÛÅ ×ÙÚÙ×ÁÔØ {\tt dgt\_sort} {\bf ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ ÐÅÒÅÄ}{\tt load\_dgt}.
+
+
+÷ÙÚÏ× {\tt dgt\_sort(dgt,NULL)} ÐÒÉ×ÏÄÉÔ Ë ÏÔÍÅÎÅ ÓÏÒÔÉÒÏ×ËÉ. 
+ðÏÒÑÄÏË ÒÁÓÐÏÌÏÖÅÎÉÑ ÓÕÝÅÓÔ×ÕÀÝÉÈ ÏÂßÅËÔÏ× ÎÅ ÍÅÎÑÅÔÓÑ, ÎÏ ÎÏ×ÙÅ ÄÏÂÁ×ÌÑÅÍÙÅ
+ÏÂßÅËÔÙ ÂÕÄÕÔ ÒÁÓÐÏÌÁÇÁÔØÓÑ ÂÅÚ ÕÞÅÔÁ ÆÕÎËÃÉÉ ÓÏÒÔÉÒÏ×ËÉ.
+\section{òÁÂÏÔÁ Ó ËÏÏÒÄÉÎÁÔÁÍÉ}
+äÌÑ ÐÅÒÅÓÞÅÔÁ ËÏÏÒÄÉÎÁÔ ÉÚ ×ÎÕÔÒÅÎÎÅÇÏ ÐÒÅÄÓÔÁ×ÌÅÎÉÑ dgt-ÆÁÊÌÁ × 
+ÁÌØÔÅÒÎÁÔÉ×ÎÙÅ É ÏÂÒÁÔÎÏ ÐÒÉÍÅÎÑÀÔÓÑ ÆÕÎËÃÉÉ:
+\function{int dgt\_x(DGT* dgt,double x);}\index{dgt_x}
+\function{int dgt\_y(DGT* dgt,double y);}\index{dgt_y}
+
+\function{double real\_x(DGT* dgt,int x);}\index{real_x}
+\function{double real\_y(DGT* dgt,int y);}\index{real_y}
+äÏÓÔÁÔÏÞÎÏ ÞÁÓÔÏ ×ÏÚÎÉËÁÅÔ ÚÁÄÁÞÁ ÐÅÒÅÓÞÅÔÁ ÉÎÔÅÒ×ÁÌÏ×, ËÏÔÏÒÁÑ ÍÏÖÅÔ
+ÂÙÔØ ×ÙÐÏÌÎÅÎÁ Ó ÍÅÎØÛÉÍ ÞÉÓÌÏÍ ÏÐÅÒÁÃÉÊ, ÞÅÍ ×ÙÞÉÓÌÅÎÉÅ ÓÏÂÓÔ×ÅÎÎÏ
+ËÏÏÒÄÉÎÁÔ.
+äÌÑ ÜÔÏÇÏ ÏÐÒÅÄÅÌÅÎÙ ÆÕÎËÃÉÉ
+\function{double real\_dx(DGT *dgt,int dx);}\index{real_dx}
+\function{double real\_dy(DGT *dgt,int dy);}\index{real_dy}
+é, ÎÁËÏÎÅÃ, ×ÙÞÉÓÌÅÎÉÅ ÒÁÓÓÔÏÑÎÉÊ.
+\function{double dgt\_dist(DGT *dgt, int x1, int y1, int x2, int y2);}\index{dgt_dist}
+÷ÙÞÉÓÌÑÅÔ ÒÁÓÓÔÏÑÎÉÅ ÍÅÖÄÕ Ä×ÕÍÑ ÔÏÞËÁÍÉ ÚÁÄÁÎÎÙÍÉ ÐÁÒÁÍÉ ×ÎÕÔÒÅÎÎÉÈ
+ËÏÏÒÄÉÎÁÔ × ÅÄÉÎÉÃÁÈ ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔ.
+
+äÌÑ ×ÙÞÉÓÌÅÎÉÑ ÒÁÓÓÔÏÑÎÉÑ ÍÅÖÄÕ Ä×ÕÍÑ ÕÚÌÁÍÉ ÌÉÎÉÉ ÍÏÖÎÏ
+ÉÓÐÏÌØÚÏ×ÁÔØ ÆÕÎËÃÉÀ
+\function{double dgt\_pdist(DGT *dgt, POINT p1, POINT p2);}\index{dgt_pdist}
+
+÷Ï ÍÎÏÇÉÈ ÁÌÇÏÒÉÔÍÁÈ ÒÁÓÓÔÏÑÎÉÑ ÉÓÐÏÌØÚÕÀÔÓÑ ÔÏÌØËÏ ÄÌÑ ÓÒÁ×ÎÅÎÉÑ
+ÍÅÖÄÕ ÓÏÂÏÊ (É, ×ÏÚÍÏÖÎÏ, Ó ÎÅËÏÔÏÒÙÍÉ ËÏÎÓÔÁÎÔÁÍÉ).
+÷ ÜÔÉÈ ÓÌÕÞÁÑÈ ÍÏÖÎÏ ÉÚÂÅÖÁÔØ ÎÅ ÔÏÌØËÏ ÐÅÒÅ×ÏÄÁ ÒÁÓÓÔÏÑÎÉÑ × ÏÓÍÙÓÌÅÎÎÙÅ
+ÅÄÉÎÉÃÙ, ÎÏ É ÉÚ×ÌÅÞÅÎÉÑ ËÏÒÎÑ É Ó×ÅÓÔÉ ×ÓÅ ×ÙÞÉÓÌÅÎÉÑ Ë ÏÐÅÒÁÃÉÑÍ Ó
+ÃÅÌÙÍÉ.
+
+äÌÑ ÜÔÏÇÏ ÐÒÅÄÎÁÚÎÁÞÅÎÙ ÆÕÎËÃÉÉ 
+\function{long int sq\_dist(DGT *dgt,int x1, int y1, int x2, int y2);}\index{sq_dist}
+\function{long int sq\_pdist(DGT *dgt,POINT p1, POINT p2);}\index{sq_pdist}
+×ÙÞÉÓÌÑÀÝÉÅ Ë×ÁÄÒÁÔ ÒÁÓÓÔÏÑÎÉÑ ÍÅÖÄÕ ÔÏÞËÁÍÉ × ÎÅËÏÔÏÒÙÈ ÕÓÌÏ×ÎÙÈ ÅÄÉÎÉÃÁÈ.
+(ÉÚ×ÅÓÔÎÏ, ÞÔÏ Ë×ÁÄÒÁÔ ÐÒÉ $x>=0$~--- ÆÕÎËÃÉÑ ÍÏÎÏÔÏÎÎÁÑ).
+
+äÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÉÍÅÔØ ×ÏÚÍÏÖÎÏÓÔØ ÓÒÁ×ÎÉ×ÁÔØ ÒÅÚÕÌØÔÁÔÙ ÆÕÎËÃÉÉ {\tt sq\_dist}
+Ó ËÏÎÓÔÁÎÔÁÍÉ, ÚÁÄÁÎÎÙÍÉ ÉÚÎÁÞÁÌØÎÏ ËÁË ÒÁÓÓÔÏÑÎÉÑ × ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔÁÈ,
+ÉÓÐÏÌØÚÕÅÔÓÑ ÆÕÎËÃÉÑ 
+\function{long int sq\_const(DGT *dgt,double dist);}\index{sq_const}
+ïÎÁ ÐÅÒÅ×ÏÄÉÔ ÒÁÓÓÔÏÑÎÉÅ, ÚÁÄÁÎÎÏÅ × ÅÄÉÎÉÃÁÈ ÁÌØÔÅÒÎÁÔÉ×ÎÙÈ ËÏÏÒÄÉÎÁÔ,
+× ÕÓÌÏ×ÎÏÅ ÚÎÁÞÅÎÉÅ, ÁÎÁÌÏÇÉÞÎÏÅ ×ÏÚ×ÒÁÝÁÅÍÙÍ {\tt sq\_dist}
+
+ëÒÏÍÅ ÒÁÓÓÔÏÑÎÉÊ, ÎÅÓÏÏÔ×ÅÔÓÔ×ÉÅ ÅÄÉÎÉàËÏÏÒÄÉÎÁÔ ÐÏ ÏÓÑÍ ×ÌÉÑÅÔ É ÎÁ 
+ ÎÁ ×ÙÞÉÓÌÅÎÉÅ ÕÇÌÏ×. ðÏÜÔÏÍÕ × ÂÉÂÌÉÏÔÅËÕ ×ËÌÀÞÅÎÁ ÆÕÎËÃÉÑ
+
+\function{double dgt\_atan2(DGT *dgt,int dy, int dx);}\index{dgt_atan2}
+
+×ÙÞÉÓÌÑÀÝÁÑ ÁÒËÔÁÎÇÅÎÓ ÏÔÎÏÛÅÎÉÑ {$\Delta y\over \Delta x$} Ó ÐÏÐÒÁ×ËÏÊ ÎÁ ËÏÏÒÄÉÎÁÔÎÕÀ
+ÓÉÓÔÅÍÕ ÕËÁÚÁÎÎÏÇÏ ÆÁÊÌÁ. ÷ ÏÓÔÁÌØÎÏÍ ÅÅ ÄÅÊÓÔ×ÉÅ ÐÏÌÎÏÓÔØÀ ÜË×É×ÁÌÅÎÔÎÏ
+ÂÉÂÌÉÏÔÅÞÎÏÊ ÆÕÎËÃÉÉ {\tt atan2}.
+
+\chapter{æÕÎËÃÉÉ-ÕÔÉÌÉÔÙ}
+\label{utils}
+÷ ÂÉÂÌÉÏÔÅËÕ ×ËÌÀÞÅΠÒÑÄ ÆÕÎËÃÉÊ, ËÏÔÏÒÙÅ ÎÅ ÒÁÂÏÔÁÀÔ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ
+Ó ÆÁÊÌÁÍÉ EPPL7, ÎÏ ÐÏÌÅÚÎÙ ÐÒÉ ÎÁÐÉÓÁÎÉÉ ÍÁÌÅÎØËÉÈ ËÏÍÁÎÄÎÏ-ÓÔÒÏÞÎÙÈ
+ÐÒÏÇÒÁÍÍ ÄÌÑ ÒÁÂÏÔÙ Ó ÜÔÉÍÉ ÆÁÊÌÁÍÉ.
+
+÷ ÏÔÌÉÞÉÅ ÏÔ ÏÓÔÁÌØÎÏÊ ÂÉÂÌÉÏÔÅËÉ, ÜÔÉ ÆÕÎËÃÉÉ ÓÉÓÔÅÍÎÏ-ÚÁ×ÉÓÉÍÙ.
+ðÒÉ ÐÅÒÅÎÏÓÅ ÂÉÂÌÉÏÔÅËÉ × ÄÒÕÇÕÀ ÏÐÅÒÁÃÉÏÎÎÕÀ ÓÒÅÄÕ ÉÈ ÔÒÅÂÕÅÔÓÑ
+ÐÅÒÅÐÉÓÁÔØ ÐÏÌÎÏÓÔØÀ É ÍÏÖÅÔ ÂÙÔØ ÄÁÖÅ ÉÚÍÅÎÉÔØ ÉÈ ÎÁÂÏÒ.
+
+îÁÐÒÉÍÅÒ, ÓÔÁÎÄÁÒÔÎÙÅ ÂÉÂÌÉÏÔÅËÉ ÂÏÌØÛÉÎÓÔ×Á ËÏÍÐÉÌÑÔÏÒÏ× C ÐÏÄ DOS
+É Windows ÎÅ ×ËÌÀÞÁÀÔ ÆÕÎËÃÉÉ {\tt getopt}, ËÏÔÏÒÁÑ ÁËÔÉ×ÎÏ
+ÉÓÐÏÌØÚÕÅÔÓÑ × Environmental Planning Utilities.
+
+æÕÎËÃÉÉ ÜÔÏÊ ÇÒÕÐÐÙ ÏÐÉÓÁÎÙ × ÚÁÇÏÌÏ×ÏÞÎÏÍ ÆÁÊÌÅ {\tt <eppl\_ut.h>}.
+
+\section{ïÂÒÁÂÏÔËÁ ÉÍÅΠÆÁÊÌÏ×}
+
+\function{char *default\_ext(const char *name, const char *ext);}%
+\index{default_ext}
+
+ÐÒÏ×ÅÒÑÅÔ, ÏËÁÎÞÉ×ÁÅÔÓÑ ÌÉ ÉÍÑ ÆÁÊÌÁ ÎÁ ÕËÁÚÁÎÎÏÅ ÒÁÓÛÉÒÅÎÉÅ. 
+åÓÌÉ ÎÅÔ, ÔÏ ÄÏÂÁ×ÌÑÅÔ ÅÇÏ. 
+
+{\small \it ïÞÅ×ÉÄÎÏ, ÞÔÏ × ÆÁÊÌÏ×ÙÈ ÓÉÓÔÅÍÁÈ FAT É HPFS, ÇÄÅ ÎÅÓËÏÌØËÏ
+ÒÁÓÛÉÒÅÎÉÊ ÎÅÄÏÐÕÓÔÉÍÙ, ÜÔÁ ÆÕÎËÃÉÑ ÄÏÌÖÎÁ ÐÒÏ×ÅÒÑÔØ ÎÁÌÉÞÉÅ ÎÅ ÄÁÎÎÏÇÏ,
+Á ÌÀÂÏÇÏ ÒÁÓÛÉÒÅÎÉÑ.}
+
+\function{char *force\_ext(const char *name, const char *ext);}
+\index{force_ext}
+
+ÚÁÍÅÎÑÅÔ ÐÏÓÌÅÄÎÅÅ ÒÁÓÛÉÒÅÎÉÅ ÎÁ ÕËÁÚÁÎÎÏÅ, ÉÌÉ ÄÏÂÁ×ÌÑÅÔ ÜÔÏ ÒÁÓÛÉÒÅÎÉÅ,
+ÅÓÌÉ ÉÍÑ ÆÁÊÌÁ ÎÅ ÓÏÄÅÒÖÁÌÏ ÔÏÞËÉ.
+
+\function{char *last\_ext(const char *name);}
+\index{last_ext}
+ ÷ÏÚ×ÒÁÝÁÅÔ ÐÏÓÌÅÄÎÅÅ ÒÁÓÛÉÒÅÎÉÅ ÆÁÊÌÁ ÉÌÉ {\tt NULL}, ÅÓÌÉ Õ ÆÁÊÌÁ
+ÎÅÔ ÒÁÓÛÉÒÅÎÉÑ.
+
+÷ÓÅ ÜÔÉ ÔÒÉ ÆÕÎËÃÉÉ ×ÏÚ×ÒÁÝÁÀÔ ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÁÔÉÞÅÓËÉÊ ÂÕÆÅÒ, 
+ËÏÔÏÒÙÊ ÂÕÄÅÔ ÐÅÒÅÚÁÐÉÓÁΠÐÒÉ ÓÌÅÄÕÀÝÅÍ ÏÂÒÁÝÅÎÉÉ Ë ÎÉÍ.
+
+\function{FILE *lookup\_file(const~char~*name, const~char~*sufux,
+const~char~*dir);}
+\index{lookup_file}
+
+éÝÅÔ ÆÁÊÌ Ó ÕËÁÚÁÎÎÙÍÉ ÉÍÅÎÅÍ × ÔÅËÕÝÅÊ ÄÉÒÅËÔÏÒÉÉ, × ÅÅ ÐÏÄÄÉÒÅËÔÏÒÉÉ
+{\tt dir}, ÅÓÌÉ ÔÁËÏ×ÁÑ ÉÍÅÅÔÓÑ É × ÐÏÄÄÉÒÅËÔÏÒÉÉ {\tt dir} 
+ÓÉÓÔÅÍÎÏÊ ÂÉÂÌÉÏÔÅÞÎÏÊ ÄÉÒÅËÔÏÒÉÉ {\tt /usr/local/lib/fgis}.
+
+÷ÏÚ×ÒÁÝÁÅÔ ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÒÕËÔÕÒÕ {\tt FILE}. æÁÊÌ ÏÔËÒÙ×ÁÅÔÓÑ 
+ÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ.
+
+æÕÎËÃÉÑ ÐÒÅÄÎÁÚÎÁÞÅÎÁ ÄÌÑ ÐÏÉÓËÁ ×ÓÐÏÍÏÇÁÔÅÌØÎÙÈ ÆÁÊÌÏ×, ÔÁËÉÈ ËÁË
+ÐÁÌÉÔÒÙ É ÛÔÒÉÈÏ×ËÉ.
+
+\section{ðÒÏÇÒÅÓÓ-ÉÎÄÉËÁÔÏÒ}
+
+÷ ÂÉÂÌÉÏÔÅËÕ ÔÁËÖÅ ×ËÌÀÞÅÎÁ ÓÔÁÎÄÁÒÔÎÁÑ ÆÕÎËÃÉÑ ×Ù×ÏÄÁ ÓÏÏÂÝÅÎÉÑ
+{\tt Processing row ... of ...}.
+
+\function{int show\_progress(int rowno,int seqno,int nrows);}
+\index{show_progress}%
+ïÎÁ ×Ù×ÏÄÉÔ ÜÔÏ ÓÁËÒÁÍÅÎÔÁÌØÎÏÅ ÓÏÏÂÝÅÎÉÅ ÎÁ {\tt stderr}.
+ëÒÏÍÅ ÜÔÏÇÏ, ÄÁÎÎÁÑ ÆÕÎËÃÉÑ ÏÂÒÁÂÁÔÙ×ÁÅÔ {\tt SIGINT}, 
+ÐÏÜÔÏÍÕ ÐÒÅÒÙ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ ÐÏ Ctrl-C ÐÒÉ×ÏÄÉÔ Ë ËÏÒÒÅËÔÎÏÍÕ 
+ÅÅ ÚÁ×ÅÒÛÅÎÉÀ.
+
+ïÎÁ ÉÍÅÅÔ ÁÎÁÌÏÇ
+
+\function{int show\_percent(int rowno,int seqno,int nrows);}\index{show_percent}
+ËÏÔÏÒÙÊ ×Ù×ÏÄÉÔ ÓÏÏÂÝÅÎÉÅ ×ÉÄÁ {\tt 99.9\% completed}.
+÷ ÏÔÌÉÞÉÅ ÏÔ {\tt show\_progress} ÜÔÁ ÆÕÎËÃÉÑ ÍÏÖÅÔ 
+ÉÓÐÏÌØÚÏ×ÁÔØÓÑ É ÄÌÑ dgt-ÆÁÊÌÏ×. ëÒÏÍÅ ÔÏÇÏ, ÎÁ ÂÏÌØÛÉÈ ÆÁÊÌÁÈ
+ÏÎÁ ÎÅÓËÏÌØËÏ ÜËÏÎÏÍÉÔ ×ÒÅÍÑ, ÐÏÓËÏÌØËÕ ÐÙÔÁÅÔÓÑ ×ÙÚÙ×ÁÔØ
+ÍÅÄÌÅÎÎÙÅ ÏÐÅÒÁÃÉÉ ××ÏÄÁ-×Ù×ÏÄÁ, ÔÏÌØËÏ ÅÓÌÉ ÅÓÔØ ÐÒÏÇÒÅÓÓ 
+ÐÏ ËÒÁÊÎÅÊ ÍÅÒÅ ÎÁ 0.1\%, ÞÔÏ ÍÏÖÅÔ ÓÏÓÔÁ×ÌÑÔØ ÄÏ 30 ÓÔÒÏË.
+
+÷ ÔÏ ÖÅ ×ÒÅÍÑ ÄÁÖÅ ÎÁ ÆÁÊÌÁÈ ÍÁËÓÉÍÁÌØÎÏÇÏ ÒÁÚÍÅÒÁ ÂÏÌØÛÁÑ
+ÞÁÓÔØ ÏÐÅÒÁÃÉÊ ÂÕÄÅÔ ×ÙÐÏÌÎÑÔØÓÑ Ó ÔÁËÏÊ ÓËÏÒÏÓÔØÀ, ÞÔÏ ÚÁ
+0.1\% ×ÒÅÍÅÎÉ ÒÁÂÏÔÙ ÐÏÌØÚÏ×ÁÔÅÌØ ÎÅ ÕÓÐÅÅÔ ÒÅÛÉÔØ, ÞÔÏ ÐÒÏÇÒÁÍÍÁ ÚÁ×ÉÓÌÁ.
+
+
+ëÒÏÍÅ ÔÏÇÏ, ÓÕÝÅÓÔ×ÕÅÔ ÆÕÎËÃÉÑ
+\function{int check\_int(int rowno,int seqno,int nrows);}
+\index{check_int}%
+ËÏÔÏÒÁÑ ÎÉÞÅÇÏ ÎÅ ×Ù×ÏÄÉÔ, Á ÔÏÌØËÏ ÐÒÏ×ÅÒÑÅÔ ÓÉÇÎÁÌ.
+òÅËÏÍÅÎÄÕÅÔÓÑ ×ÓÅÇÄÁ ÉÍÅÔØ ×ÏÚÍÏÖÎÏÓÔØ ÉÓÐÏÌØÚÏ×ÁÔØ ÅÅ × ËÁÞÅÓÔ×Å
+ÁÌØÔÅÒÎÁÔÉ×Ù {\tt show\_percent}, ÎÁÐÒÉÍÅÒ ÄÌÑ ÆÏÎÏ×ÏÇÏ ×ÙÐÏÌÎÅÎÉÑ.
+
+õÓÔÁÎÁ×ÌÉ×ÁÅÔÓÑ ÏÄÎÁ ÉÚ ÜÔÉÈ ÆÕÎËÃÉÊ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ
+
+\function{void install\_progress\_indicator(int (*func)(int,int,int));}%
+\index{install_progress_indicator}
+
+æÕÎËÃÉÑ 
+
+\function{int clear\_progress(int result);}\index{clear_progress}
+óÔÉÒÁÅÔ ÓÏÏÂÝÅÎÉÅ, ÓÄÅÌÁÎÎÏÅ ÆÕÎËÃÉÅÊ~--- ÐÒÏÇÒÅÓÓ-ÉÎÄÉËÁÔÏÒÏÍ É ×Ù×ÏÄÉÔ
+ÓÏÏÂÝÅÎÉÅ {\tt Done}, ÅÓÌÉ {\tt result = 0} ÉÌÉ {\tt Aborted}.
+
+÷ÏÚ×ÒÁÝÁÅÔ {\tt result}, ÐÏÜÔÏÍÕ ÌÏÇÉÞÎÙÊ ÓÐÏÓÏ ÅÅ ÐÒÉÍÅÎÅÎÉÑ
+ÔÁËÏÊ:
+
+\begin{verbatim}
+install_progress_indicator(show_percent);
+if ((res=clear_progress(for_each_cell 
+                          (infile,my_iterator_func))))
+  unlink(out_file_name);
+close_epp(infile);
+close_epp(outfile);
+return res;
+\end{verbatim}
+
+\chapter{÷ÎÕÔÒÅÎÎÅÅ ÕÓÔÒÏÊÓÔ×Ï ÂÉÂÌÉÏÔÅËÉ}
+\section{õÓÔÒÏÊÓÔ×Ï ÒÁÓÔÒÏ×ÏÇÏ ÆÁÊÌÁ EPPL7}
+\section{òÁÂÏÔÁ ÏÂßÅËÔÁ EPP}
+\label{EPP-internals}
+\section{÷ÅËÔÏÒÎÙÅ ÏÂßÅËÔÙ}
+\section{÷ÅËÔÏÒÎÙÅ ÆÁÊÌÙ × ÐÁÍÑÔÉ}
+\catcode`\_=11
+\input lib_doc.ind
+\end{document}
+
+
diff --git a/doc/lib_doc.toc b/doc/lib_doc.toc
new file mode 100644 (file)
index 0000000..c966faa
--- /dev/null
@@ -0,0 +1,33 @@
+\select@language {russian}
+\contentsline {chapter}{\IeC {\CYRV }\IeC {\cyrv }\IeC {\cyre }\IeC {\cyrd }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyre }}{3}
+\contentsline {chapter}{\numberline {1}\IeC {\CYRL }\IeC {\cyro }\IeC {\cyrg }\IeC {\cyri }\IeC {\cyrch }\IeC {\cyre }\IeC {\cyrs }\IeC {\cyrk }\IeC {\cyra }\IeC {\cyrya } \IeC {\cyrm }\IeC {\cyro }\IeC {\cyrd }\IeC {\cyre }\IeC {\cyrl }\IeC {\cyrsftsn } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyro }\IeC {\cyrv } \IeC {\cyrd }\IeC {\cyra }\IeC {\cyrn }\IeC {\cyrn }\IeC {\cyrery }\IeC {\cyrh }}{4}
+\contentsline {section}{\numberline {1.1}\IeC {\CYRR }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }}{4}
+\contentsline {section}{\numberline {1.2}\IeC {\CYRV }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }}{5}
+\contentsline {chapter}{\numberline {2}\IeC {\CYRF }\IeC {\cyru }\IeC {\cyrn }\IeC {\cyrk }\IeC {\cyrc }\IeC {\cyri }\IeC {\cyri } \IeC {\cyrd }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyru }\IeC {\cyrp }\IeC {\cyra } \IeC {\cyrk } epp \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrm }}{7}
+\contentsline {section}{\numberline {2.1}\IeC {\CYRP }\IeC {\cyro }\IeC {\cyrl }\IeC {\cyrya } \IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyru }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyru }\IeC {\cyrr }\IeC {\cyrery } EPP}{7}
+\contentsline {section}{\numberline {2.2}\IeC {\CYRO }\IeC {\cyrt }\IeC {\cyrk }\IeC {\cyrr }\IeC {\cyrery }\IeC {\cyrt }\IeC {\cyri }\IeC {\cyre } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra } \IeC {\cyri } \IeC {\cyrr }\IeC {\cyre }\IeC {\cyrzh }\IeC {\cyri }\IeC {\cyrm }\IeC {\cyrery } \IeC {\cyrd }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyru }\IeC {\cyrp }\IeC {\cyra }}{8}
+\contentsline {section}{\numberline {2.3}\IeC {\CYRI }\IeC {\cyrz }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyre } \IeC {\cyrr }\IeC {\cyre }\IeC {\cyrzh }\IeC {\cyri }\IeC {\cyrm }\IeC {\cyro }\IeC {\cyrv } \IeC {\cyrd }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyru }\IeC {\cyrp }\IeC {\cyra }}{8}
+\contentsline {section}{\numberline {2.4}\IeC {\CYRD }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyru }\IeC {\cyrp } \IeC {\cyrk } \IeC {\cyrya }\IeC {\cyrch }\IeC {\cyre }\IeC {\cyrishrt }\IeC {\cyrk }\IeC {\cyra }\IeC {\cyrm } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra }}{9}
+\contentsline {section}{\numberline {2.5}\IeC {\CYRI }\IeC {\cyrt }\IeC {\cyre }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrery }}{10}
+\contentsline {section}{\numberline {2.6}\IeC {\CYRR }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyra } \IeC {\cyrs } \IeC {\cyrz }\IeC {\cyra }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrl }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrk }\IeC {\cyro }\IeC {\cyrm } epp-\IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra }}{11}
+\contentsline {section}{\numberline {2.7}\IeC {\CYRP }\IeC {\cyre }\IeC {\cyrr }\IeC {\cyre }\IeC {\cyrs }\IeC {\cyrch }\IeC {\cyre }\IeC {\cyrt } \IeC {\cyrk }\IeC {\cyro }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrd }\IeC {\cyri }\IeC {\cyrn }\IeC {\cyra }\IeC {\cyrt }}{13}
+\contentsline {section}{\numberline {2.8}\IeC {\CYRN }\IeC {\cyra }\IeC {\cyrl }\IeC {\cyro }\IeC {\cyrzh }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyre } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyro }\IeC {\cyrv }}{13}
+\contentsline {section}{\numberline {2.9}\IeC {\CYRP }\IeC {\cyrr }\IeC {\cyro }\IeC {\cyrch }\IeC {\cyre }\IeC {\cyre }}{14}
+\contentsline {section}{\numberline {2.10}\IeC {\CYRO }\IeC {\cyrb }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyrk }\IeC {\cyra } \IeC {\cyro }\IeC {\cyrsh }\IeC {\cyri }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrk }}{14}
+\contentsline {chapter}{\numberline {3}\IeC {\CYRF }\IeC {\cyru }\IeC {\cyrn }\IeC {\cyrk }\IeC {\cyrc }\IeC {\cyri }\IeC {\cyri } \IeC {\cyrd }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyru }\IeC {\cyrp }\IeC {\cyra } \IeC {\cyrk } \IeC {\cyrv }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrn }\IeC {\cyrery }\IeC {\cyrm } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrm }}{16}
+\contentsline {section}{\numberline {3.1}T\IeC {\cyri }\IeC {\cyrp }\IeC {\cyrery } \IeC {\cyrd }\IeC {\cyra }\IeC {\cyrn }\IeC {\cyrn }\IeC {\cyrery }\IeC {\cyrh }}{16}
+\contentsline {section}{\numberline {3.2}\IeC {\CYRO }\IeC {\cyrt }\IeC {\cyrk }\IeC {\cyrr }\IeC {\cyrery }\IeC {\cyrt }\IeC {\cyri }\IeC {\cyre } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra }}{17}
+\contentsline {section}{\numberline {3.3}\IeC {\CYRS }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyra } \IeC {\cyrr }\IeC {\cyre }\IeC {\cyrzh }\IeC {\cyri }\IeC {\cyrm }\IeC {\cyra } \IeC {\cyri } \IeC {\cyrz }\IeC {\cyra }\IeC {\cyrk }\IeC {\cyrr }\IeC {\cyrery }\IeC {\cyrt }\IeC {\cyri }\IeC {\cyre } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra }}{17}
+\contentsline {section}{\numberline {3.4}\IeC {\CYRCH }\IeC {\cyrt }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyre } \IeC {\cyri } \IeC {\cyrz }\IeC {\cyra }\IeC {\cyrp }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyrsftsn } \IeC {\cyro }\IeC {\cyrb }\IeC {\cyrhrdsn }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrv }}{18}
+\contentsline {section}{\numberline {3.5}\IeC {\CYRI }\IeC {\cyrt }\IeC {\cyre }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrery }}{18}
+\contentsline {section}{\numberline {3.6}\IeC {\CYRR }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyra } \IeC {\cyrs } \IeC {\cyrt }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyru }\IeC {\cyrshch }\IeC {\cyri }\IeC {\cyrm } \IeC {\cyro }\IeC {\cyrb }\IeC {\cyrhrdsn }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrm }}{19}
+\contentsline {section}{\numberline {3.7}DGT-\IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyrery } \IeC {\cyrv } \IeC {\cyrp }\IeC {\cyra }\IeC {\cyrm }\IeC {\cyrya }\IeC {\cyrt }\IeC {\cyri }}{21}
+\contentsline {section}{\numberline {3.8}\IeC {\CYRR }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyra } \IeC {\cyrs } \IeC {\cyrk }\IeC {\cyro }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrd }\IeC {\cyri }\IeC {\cyrn }\IeC {\cyra }\IeC {\cyrt }\IeC {\cyra }\IeC {\cyrm }\IeC {\cyri }}{21}
+\contentsline {chapter}{\numberline {4}\IeC {\CYRF }\IeC {\cyru }\IeC {\cyrn }\IeC {\cyrk }\IeC {\cyrc }\IeC {\cyri }\IeC {\cyri }-\IeC {\cyru }\IeC {\cyrt }\IeC {\cyri }\IeC {\cyrl }\IeC {\cyri }\IeC {\cyrt }\IeC {\cyrery }}{23}
+\contentsline {section}{\numberline {4.1}\IeC {\CYRO }\IeC {\cyrb }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyrk }\IeC {\cyra } \IeC {\cyri }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrn } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyro }\IeC {\cyrv }}{23}
+\contentsline {section}{\numberline {4.2}\IeC {\CYRP }\IeC {\cyrr }\IeC {\cyro }\IeC {\cyrg }\IeC {\cyrr }\IeC {\cyre }\IeC {\cyrs }\IeC {\cyrs }-\IeC {\cyri }\IeC {\cyrn }\IeC {\cyrd }\IeC {\cyri }\IeC {\cyrk }\IeC {\cyra }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }}{24}
+\contentsline {chapter}{\numberline {5}\IeC {\CYRV }\IeC {\cyrn }\IeC {\cyru }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyrn }\IeC {\cyre }\IeC {\cyre } \IeC {\cyru }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyro }\IeC {\cyrishrt }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrv }\IeC {\cyro } \IeC {\cyrb }\IeC {\cyri }\IeC {\cyrb }\IeC {\cyrl }\IeC {\cyri }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyri }}{25}
+\contentsline {section}{\numberline {5.1}\IeC {\CYRU }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyro }\IeC {\cyrishrt }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrv }\IeC {\cyro } \IeC {\cyrr }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyro }\IeC {\cyrg }\IeC {\cyro } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyra } EPPL7}{25}
+\contentsline {section}{\numberline {5.2}\IeC {\CYRR }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyra } \IeC {\cyro }\IeC {\cyrb }\IeC {\cyrhrdsn }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyra } EPP}{25}
+\contentsline {section}{\numberline {5.3}\IeC {\CYRV }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrn }\IeC {\cyrery }\IeC {\cyre } \IeC {\cyro }\IeC {\cyrb }\IeC {\cyrhrdsn }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyrery }}{25}
+\contentsline {section}{\numberline {5.4}\IeC {\CYRV }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrn }\IeC {\cyrery }\IeC {\cyre } \IeC {\cyrf }\IeC {\cyra }\IeC {\cyrishrt }\IeC {\cyrl }\IeC {\cyrery } \IeC {\cyrv } \IeC {\cyrp }\IeC {\cyra }\IeC {\cyrm }\IeC {\cyrya }\IeC {\cyrt }\IeC {\cyri }}{25}
diff --git a/doc/object_concept b/doc/object_concept
new file mode 100644 (file)
index 0000000..f7c444d
--- /dev/null
@@ -0,0 +1,218 @@
+îÅËÏÔÏÒÙÅ ÉÄÅÉ
+
+1. îÕÖÅΠÌÉ ÎÁÍ ÇÌÏÂÁÌØÎÙÊ ÍÁÓÓÉ× map_items? Y
+îÅ ÐÒÏÝÅ ÌÉ ÄÌÑ ËÁÖÄÏÇÏ mapcanvas ÓÏÚÄÁ×ÁÔØ Ó×ÏÊ ÍÁÓÓÉ×?
+
+ôÏÇÄÁ ×ÚÁÉÍÏÄÅÊÓÔ×ÉÅ ÓÌÏÑ Ó canvas ÄÏÌÖÎÏ ÂÙÔØ Ä×ÕÈÓÔÏÒÏÎÎÉÍ.
+canvas ÄÏÌÖÅΠÚÎÁÔØ ×ÓÅ Ó×ÏÉ ÓÌÏÉ, Á ÓÌÏÊ - ×ÓÅ canvas, × ËÏÔÏÒÙÈ ÏΠ×ÉÄÅÎ
+(ÎÅ ÏÂÑÚÁÔÅÌØÎÏ ÔÅ, × ËÏÔÏÒÙÈ ÏΠlookable - ÄÌÑ ÜÔÏÇÏ ÄÏÓÔÁÔÏÞÎÏ ÚÎÁÔØ
+ËÏÏÒÄÉÎÁÔÙ)
+
+äÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÐÅÒÅÒÉÓÏ×ÁÔØ ÓÌÏÊ (image) ÍÙ ÄÏÌÖÎÙ ÚÎÁÔØ
+1. raster 
+2. palette/symbols
+3. border mode
+(ÜÔÏ ÚÎÁÅÔ ÓÌÏÊ)
+
+4. Item ID (ÎÁÈÏÄÉÔÓÑ ÐÏ tag)
+
+éÔÁË: ÄÌÑ ËÁÖÄÏÇÏ ÓÌÏÑ ÓÕÝÅÓÔ×ÕÅÔ ÐÒÏÃÅÄÕÒÁ redraw_${layer}_${mode}
+Ó ÐÁÒÁÍÅÔÒÏÍ canvas 
+ËÏÔÏÒÁÑ ÐÅÒÅÒÉÓÏ×Ù×ÁÅÔ ÓÌÏÊ
+
+ÄÌÑ ÒÁÓÔÒÁ ÏÎÁ ÄÏÌÖÎÁ ×ÙÇÌÑÄÅÔØ ËÁË
+layer_title $canvas self
+raster image $self(raster) $canvas [force_image $canvas self] -palette $self(palette) ?-border ?base??
+
+ðÒÉ ÒÅËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉ ÂÏÒÄÅÒÁ ÏÎÁ ÐÅÒÅÓÏÚÄÁÅÔÓÑ. åÓÌÉ ÖÅ ÓÄÅÌÁÔØ 
+ÏÐÃÉÀ border ×ÏÓÐÒÉÎÉÍÁÀÝÕ ÔÒÉ ÆÌÁÇÁ (yes, no, base) ÔÏ ÐÒÏÃÅÄÕÒÕ
+ÐÅÒÅÓÏÚÄÁ×ÁÔØ ÎÅ ÎÁÄÏ.
+
+ÏÎÁ ÂÕÄÅÔ ×ÙÇÌÑÄÅÔØ ËÁË
+
+proc __raster_redraw_base {layer canvas} {
+upvar #0 $layer self
+if [set t [get_title $canvas $layer] {
+ $canvas itemconf $t -text $self(title)
+} else { $canvas create text [expr [winfo width $canvas]/2] 0 -anchor n -text 
+  $self(title)
+  }
+raster image $self(raster) $canvas [force_image $canvas $layer] -palette $self(palette) -border $self(border) -mapmode $self(mapmode)
+}
+
+ôÉÐÙ ÓÌÏÅ×
+
+I ÒÁÓÔÒÏ×ÙÅ
+  ËÌÁÓÓÉÆÉËÁÃÉÑ (ÌÅÇÅÎÄÁ ÐÒÉÍÅÎÑÅÔÓÑ Ë ÔÏÍÕ ÖÅ ÒÅËÌÁÓÓÕ, ÞÔÏ É ÐÁÌÉÔÒÁ.
+                 ÌÅÇÅÎÄÁ ÐÒÅÄÓÔÁ×ÌÑÅÔ ÓÏÂÏÊ ÎÁÂÏÒ ÓÔÒÏË (ÏÂßÅËÔ ÌÅÇÅÎÄÙ ÉÌÉ
+                 ËÏÍÁÎÄÕ))
+  ËÁÒÔÏÇÒÁÍÍÁ (ÌÅÇÅÎÄÁ ÐÒÉÍÅÎÑÅÔÓÑ Ë ÂÁÚÏ×ÏÍÕ ÓÌÏÀ ÉÌÉ ÏÄÎÏÍÕ ÒÅËÌÁÓÓÕ,
+               Á ÐÁÌÉÔÒÁ Ë ÄÒÕÇÏÍÕ ÒÅËÌÁÓÓÕ, ÐÒÉÞÅÍ ÐÏÓÌÅÄÎÉÊ£
+               ÍÅÎÑÅÔÓÑ ÄÉÎÁÍÉÞÅÓËÉ × ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ ÚÁÄÁÎÎÙÈ ÉÎÔÅÒ×ÁÌÏ×
+               ÌÅÇÅÎÄÁ ÐÒÅÄÓÔ×ÁÌÑÅÔ ÓÏÂÏÊ ×ÙÒÁÖÅÎÉÅ (Tcl cËÒÉÐÔ)
+  çÏÌÙÊ ÒÁÓÔÒ - ÐÁÌÉÔÒÁ default, ÌÅÇÅÎÄÙ ÎÅÔ. ÞÔÏÂÙ ÓÄÅÌÁÔØ ÉÚ ÜÔÏÇÏ ÏÓÍÙÓÌÅÎÎÙÊ  ÓÌÏÊ, ×ÏÓÐÏÌØÚÕÊÔÅÓÔØ ËÏÍÁÎÄÏÊ new
+II ôÜÇÉ
+  1. ïÂÙÞÎÙÊ ÔÜÇ - ÎÁÂÏÒ ÓÔÒÏË  
+    ÷ÏÚÍÏÖÎÏÓÔØ ÚÁÄÁÔØ ËÏÍÁÎÄÕ, ×ÏÚ×ÒÁÝÁÀÝÕÀ ÔÉРÍÁÒËÅÒÁ É ÛÒÉÆÔ ÐÏ
+    ÓÔÒÏËÅ
+  2. äÉÁÇÒÁÍÍÁ - ÎÁÂÏÒ ÓÐÉÓËÏ× ÞÉÓÅÌ + ËÏÍÁÎÄÁ ÄÌÑ ÏÔÒÉÓÏ×ËÉ
+III ÷ÅËÔÏÒÎÙÅ ÓÌÏÉ 
+  ??
+
+CÕÂËÏÍÁÎÄÙ ÄÌÑ ÒÁÓÔÒÏ×ÏÇÏ ÓÌÏÑ
+
+1. source - ×ÏÚ×ÒÁÝÁÅÔ ÉÍÑ ÆÁÊÌÁ (×ÏÚÍÏÖÎÏ ÞÅÒÅÚ C-ÛÎÙÊ ËÏÄ)
+2. show canvas ?mode? - ÄÅÌÁÅÔ ÓÌÏÊ ×ÉÄÉÍÙÍ × ÕËÁÚÁÎÎÏÍ canvas. mode ÐÏ
+         ÕÍÏÌÞÁÎÉÀ base
+3. look canvas {add|remove}
+4. configure
+5. cget
+6. value x y - ×ÏÚ×ÒÁÝÁÅÔ ÚÎÁÞÅÎÉÅ ÐÏ ËÏÏÒÄÉÎÁÔÁÍ
+7. classvalue class - ×ÏÚ×ÒÁÝÁÅÔ ÚÎÁÞÅÎÉÅ ÐÏ ËÌÁÓÓÕ (ÄÌÑ ÒÅÁÌÉÚÁÃÉÉ count -
+             ÐÏÄÏÂÎÙÈ ÏÐÅÒÁÃÉÊ
+8. legtext index - ×ÏÚ×ÒÁÝÁÅÔ ÔÅËÓÔ ÌÅÇÅÎÄÙ ÐÏ ÉÎÄÅËÓÕ × ÐÁÌÉÔÒÅ
+9. leglist - ×ÏÚ×ÒÁÝÁÅÔ ÓÐÉÓÏË ÐÏÚÉÃÉÊ ÌÅÇÅÎÄÙ
+11. color index - ÄÅÌÁÅÔ palette get
+13. pattern index - ×ÏÚ×ÒÁÝÁÅÔ ÛÔÒÉÈÏ×ËÕ (ÎÅ ÚÎÁÀ ËÁË)
+14. drawopaque canvas - ÐÅÒÅÒÉÓÏ×Ù×ÁÅÔ Ã×ÅÔÏÍ
+15. drawtransparent canvas - ÐÅÒÅÒÉÓÏ×Ù×ÁÅÔ ÛÔÒÉÈÏ×ËÏÊ
+16. info legend - ×ÏÚ×ÒÁÝÁÅÔ true, ÅÓÌÉ ÅÓÔØ ÞÅÇÏ ÒÉÓÏ×ÁÔØ × legbox
+    info lookable - ×ÏÚ×ÒÁÝÁÅÔ true, ÅÓÌÉ ÅÓÔØ ÞÅÇÏ ×Ù×ÏÄÉÔØ × ÔÏÞËÅ (Ô.Å ×ÓÅÇÄÁ)
+    info opaque - ×ÏÚ×ÒÁÝÁÅÔ true, ÅÓÌÉ ÒÁÓÔÒ ÍÏÖÅÔ ÂÙÔØ ×Ù×ÅÄÅΠËÁË ÂÁÚÏ×ÙÊ
+          ÓÌÏÊ, Ô.Å. ×ÓÅÇÄÁ
+17 hide canvas - ÕÄÁÌÑÅÔ ÓÌÏÊ ÉÚ canvas
+ïÐÃÉÉ configure
+-reclass, -table - ÍÏÄÉÆÉÃÉÒÕÀÔ ÂÁÚÏ×ÙÊ reclass.
+-legend - ÚÁÄÁÀÔ ÏÂßÅËÔ ÌÅÇÅÎÄÙ ËÏÎÆÌÉËÔÕÅÔ Ó values É intervals.
+         -legfile - ×ÅÒÓÉÑ ÜÔÏÊ ÏÐÃÉÉ, ËÏÔÏÒÁÑ ÐÏÌÕÞÁÅÔ ÉÍÑ ÆÁÊÌÁ ×ÍÅÓÔÏ
+         ÇÏÔÏ×ÏÇÏ ÏÂßÅËÔÁ õËÁÚÁÎÉÅ ÜÔÏÊ ÏÐÃÉÉ ÒÁ×ÎÏÚÎÁÞÎÏ ÐÒÉÚÎÁÎÉÀ ËÁÒÔÙ
+         ÓÌÏÅÍ ËÌÁÓÓÉÆÉËÁÃÉÉ 
+         
+-palette - ÚÁÄÁÅÔ ÏÂßÅËÔ ÐÁÌÉÔÒÙ
+-palfile - ÇÒÕÚÉÔ ÆÁÊÌ
+
+-values - ÚÁÄÁÅÔ ÓËÒÉÐÔ ÄÌÑ ÐÅÒÅÓÞÅÔÁ ËÌÁÓÓÁ × ÚÎÁÞÅÎÉÅ. õËÁÚÁÎÉÅ ÜÔÏÊ
+          ÏÐÃÉÉ ÒÁ×ÎÏÓÉÌØÎÏ ÐÒÉÚÎÁÎÉÀ ÓÌÏÑ ËÁÒÔÏÇÒÁÍÍÏÊ
+          ÐÏ ÕÍÏÌÞÁÎÉÀ ÒÁ×ÎÏ set
+-legendheader ÚÁÄÁÅÔ ÔÏ, ÞÔÏ ÂÕÄÅÔ ×ÏÚ×ÒÁÝÅÎÏ legend title É legend subtitle
+-intervals - ÚÁÄÁÅÔ ÓÐÉÓÏË ×ÅÝÅÓÔ×ÅÎÎÙÈ ÞÉÓÅÌ ÏÇÒÁÎÉÞÉ×ÁÀÝÉÊ ×ÉÄÉÍÙÅ ÄÉÁÐÁÚÏÎÙ
+          ÚÎÁÞÅÎÉÊ. ðÒÉÍÅÎÑÅÔÓÑ Ë ÔÅËÕÝÅÍÕ values
+-border {none yes base} - ËÁË ÒÉÓÏ×ÁÔØ ÇÒÁÎÉÃÙ
+-bordercolor color
+      ðÏËÁ undefined
+-ovrborder
+-ovrcolor
+-patterns
+-symbols
+
+ëÏÍÁÎÄÙ ÄÌÑ ÓÌÏÑ tag
+title
+legend title
+legend subtitle
+1. source - ×ÏÚ×ÒÁÝÁÅÔ ÉÍÑ ÆÁÊÌÁ ?
+2. show canvas ?mode? - ÄÅÌÁÅÔ ÓÌÏÊ ×ÉÄÉÍÙÍ × ÕËÁÚÁÎÎÏÍ canvas. 
+              mode ÍÏÖÅÔ ÂÙÔØ ÔÏÌØËÏ overlay
+3. look canvas {add|remove} 
+4. configure
+5. cget
+6. value x y - ×ÏÚ×ÒÁÝÁÅÔ ÚÎÁÞÅÎÉÅ ÐÏ ËÏÏÒÄÉÎÁÔÁÍ. ÍÏÖÅÔ É ÎÅ ×ÅÒÎÕÔØ
+7. classvalue class - ÎÅ ÏÐÒÅÄÅÌÅÎÁ 
+8. legtext index - ÎÅ ÏÐÒÅÄÅÌÅÎÁ??
+9. leglist - ×ÏÚ×ÒÁÝÁÅÔ ÓÐÉÓÏË ÐÏÚÉÃÉÊ ÌÅÇÅÎÄÙ (ÓÐÉÓÏË ÍÁÒËÅÒÏ×?)
+11. color index - ÎÅ ÏÐÒÅÄÅÌÅÎÁ 
+13. pattern index - ÎÅ ÏÐÒÅÄÅÌÅÎÁ 
+14. drawopaque canvas - ÎÅ ÏÐÒÅÄÅÌÅÎÁ 
+15. drawtransparent canvas - ÐÅÒÅÒÉÓÏ×Ù×ÁÅÔ
+16. info legend - ×ÏÚ×ÒÁÝÁÅÔ true, ÅÓÌÉ ÅÓÔØ ÞÅÇÏ ÒÉÓÏ×ÁÔØ × legbox
+    info lookable - ×ÏÚ×ÒÁÝÁÅÔ true, ÅÓÌÉ ÅÓÔØ ÞÅÇÏ ×Ù×ÏÄÉÔØ × ÔÏÞËÅ 
+    info opaque - ×ÏÚ×ÒÁÝÁÅÔ true, ÅÓÌÉ ÒÁÓÔÒ ÍÏÖÅÔ ÂÙÔØ ×Ù×ÅÄÅΠËÁË ÂÁÚÏ×ÙÊ
+          ÓÌÏÊ, Ô.Å. ÎÉËÏÇÄÁ
+17 marker ÓÔÒÏËÁ - ×ÏÚ×ÒÁÝÁÅÔ ÉÍÑ ÍÁÒËÅÒÁ ÄÌÑ ÓÔÒÏËÉ
+18 font ÓÔÒÏËÁ - ×ÏÚ×ÒÁÝÁÅÔ ÉÍÑ ÓÌÏÑ ÄÌÑ ÓÔÒÏËÉ
+
+ÍÁÒËÅÒ ÒÉÓÕÅÔÓÑ ËÏÍÍÁÎÄÏÊ
+set offset [eval $marker $canvas $x $y]
+offset - ÐÒÉÎÉÍÁÅÔ ÚÎÁÞÅÎÉÅ ÄÉÓÔÁÎÃÉÉ × ÐÉËÓÅÌÁÈ, ÎÁ ËÏÔÏÒÕÀ ÎÁÄÏ ÓÍÅÓÔÉÔØ
+      ÎÁÞÁÌØÎÕÀ ÔÏÞËÕ ÔÅËÓÔÁ.
+
+ planchet widget
+
+îÁ ÓÁÍÏÍ ÄÅÌÅ ÜÔÏ canvas ÓÏ ×ÓÅÍÉ Ó×ÏÉÍÉ ËÁÎ×ÁÓÎÙÍÉ Ó×ÏÊÓÔ×ÁÍÉ.
+îÏ Ó ÎÉÍ ÁÓÓÏÃÉÉÒÏ×ÁΠÍÁÓÓÉ× (ÓÏ×ÐÁÄÁÀÝÉÊ ÐÏ ÉÍÅÎÉ)
+× ËÏÔÏÒÏÍ ÈÒÁÎÉÔÓÑ ÄÏÐÏÌÎÉÔÅÌØÎÁÑ ÉÎÆÏÒÍÁÃÉÑ
+1. limits - ÔÅËÕÝÉÅ ÐÒÅÄÅÌÙ ËÏÏÒÄÉÎÁÔ. åÖÅÌÉ ÏÔÓÕÔÓÔ×ÕÅÔ, ÔÏ ÍÎÏÇÉÅ
+ËÏÍÁÎÄÙ ÂÕÄÕÔ ×ÏÚ×ÒÁÝÁÔØ ÏÛÉÂËÕ.
+2. zoom - ÔÅËÕÝÉÊ ÓÔÅË Õ×ÅÌÉÞÅÎÉÊ
+÷ÓÐÏÍÏÇÁÔÅÌØÎÙÅ ×ÉÄÇÅÔÙ
+3. bzoom - ËÎÏÐËÁ Õ×ÅÌÉÞÅÎÉÑ
+   bunzoom - ÓÐÉÓÏË ËÎÏÐÏË ÕÍÅÎØÛÅÎÉÑ
+   shifts - ÓÐÉÓÏË ËÎÏÐÏË ÓÄ×ÉÇÁ left down up right
+   scalelabel - ÍÅÓÔÏ ÇÄÅ ÏÔÏÂÒÁÖÁÅÔÓÑ ÍÁÓÛÔÁÂ
+óÌÏÉ base
+     overlays - ÓÐÉÓÏË
+     looks - ÓÐÉÓÏË
+
+îÏ×ÙÅ ÏÐÃÉÉ × widget command
+$w limits ?ÞÅÔÙÒÅ ËÏÏÒÄÉÎÁÔÙ? - ÕÓÔÁÎÁ×ÌÉ×ÁÅÔ ÎÏ×ÙÅ ÐÒÅÄÅÌÙ. åÓÌÉ
+ ËÏÏÒÄÉÎÁÔÙ ÂÙÌÉ ÎÅ ÏÐÒÅÄÅÌÅÎÙ, ÔÏ ÐÏÒÑÄÏË ÓÞÉÔÁÅÔÓÑ
+  ÌÅ×Ï ÎÉÚ ÐÒÁ×Ï ×ÅÒÈ, ÉÎÁÞÅ ÎÁÐÒÁ×ÌÅÎÉÅ ÏÓÅÊ ÓÏÈÒÁÎÑÅÔÓÑ.
+limits ÂÅÚ ÁÒÇÕÍÅÎÔÏ× ×ÏÚ×ÒÁÝÁÅÔ ÔÅËÕÝÉÅ ÁÒÇÕÍÅÎÔÙ
+$w clear - ÏÞÉÝÁÅÔ ×ÓÅ (ÄÌÑ ÓÍÅÎÙ ÒÅÇÉÏÎÁ)
+$w zoom - ÐÏÞÔÉ ÔÏ ÖÅ ÓÁÍÏÅ, ÞÔÏ É limits, ÎÏ ÐÏÌÕÞÁÅÔ ËÏÏÒÄÉÎÁÔÙ
+  × ÅÄÉÎÉÃÁÈ canvas, Á ÎÅ × ÁÌØÔÅÒÎÁÎÉ×ÎÙÈ ÅÄÉÎÉÃÁÈ. óÍ. ÔÁËÖÅ
+  ÐÒÏÃÅÄÕÒÕ zoom
+$w unzoom ?-all?  - ÏÔÍÅÎÑÅÔ ÐÏÓÌÅÄÎÅÅ ÉÌÉ ×ÓÅ Õ×ÅÌÉÞÅÎÉÑ
+$w shift ÎÁÐÒÁ×ÌÅÎÉÅ - ÓÄ×ÉÇÁÅÔ ÔÅËÕÝÅÅ ÐÏÌÅ ÚÒÅÎÉÑ × ÕËÁÚÁÎÎÏÍ ÎÁÐÒÁ×ÌÅÎÉÉ
+
+$w layers - ×ÏÚ×ÒÁÝÁÅÔ ÓÐÉÓÏË ×ÓÅÈ ÓÌÏÅ×, ×ËÌÀÞÁÑ ÂÁÚÏ×ÙÊ
+$w lookable - ×ÏÚ×ÒÁÝÁÅÔ ÓÐÉÓÏË ×ÓÅ lookable ÓÌÏÅ×.
+÷ÎÉÍÁÎÉÅ - ÐÏËÁÚÙ×ÁÀÔÓÑ É ÓËÒÙ×ÁÀÔÓÑ ÓÌÏÉ ËÏÍÁÎÄÁÍÉ ÓÌÏÑ Á ÎÅ ÐÌÁÎÛÅÔÁ
+$w scale ?denominator? - ×ÏÚ×ÒÁÝÁÅÔ ÔÅËÕÝÉÊ ÚÎÁÍÅÎÁÔÅÌØ ÍÁÓÛÔÁÂÁ ÉÌÉ
+                  ÕÓÔÁÎÁ×ÌÉ×ÁÅÔ ÍÁÓÛÔÁÂ. ãÅÎÔÒÁÌØÎÁÑ ÔÏÞËÁ ÐÒÉ ÜÔÏÍ 
+                 ÏÓÔÁÅÔÓÑ ÎÅÉÚÍÅÎÎÏÊ,
+$w ruler {on|off} - ×ËÌÀÞÁÅÔ/×ÙËÌÀÞÁÅÔ ÍÁÓÛÔÁÂÎÕÀ ÌÉÎÅÊËÕ   
+
+$W MApx x
+$w mapy y
+$w scrx x  
+$w scry y
+$w look x y - ×ÏÚ×ÒÁÝÁÅÔ ÓÐÉÓÏË ÓÌÏÅ× É ÉÈ ÚÎÁÞÅÎÉÊ × ÔÅËÕÝÅÊ ÔÏÞËÅ
+$w statustext ÔÅËÓÔ - ×Ù×ÏÄÉÔ ÔÅËÓÔ × ÏËÏÛËÅ ÓÔÁÔÕÓÁ
+$w projection type ?options? 
+- ÚÁÄÁÅÔ ÐÒÏÅËÃÉÀ
+$w longitide x y
+$w latitide x y
+$w fit x y 
+1, ÅÓÌÉ ÔÏÞËÁ ÐÏÐÁÄÁÅÔ × canvas É 0 ÅÓÌÉ ÎÅÔ
+îÏ×ÙÅ ÏÐÃÉÉ configure/cget
+1. -legbox
+2. -zoombutton
+3. -unzoombuttons
+4. -shiftbuttons
+5. -statusline
+6. -rulerpos - ÐÏÚÉÃÉÑ ÎÁÞÁÌÁ ÍÁÓÛÔÁÂÎÏÊ ÌÉÎÅÊËÉ
+
+îÅÄÏÓÔÕÐÎÙÅ ÏÐÃÉÉ canvas
+-borderwidth -bd -highlightthickness -relief
+
+BINDINGS
+<Configure> - ÐÅÒÅÈ×ÁÔ resize É ÓÏÏÔ×ÅÔÓ×ÔÕÀÝÅÅ ÉÚÍÅÎÅÎÉÅ ÐÒÅÄÅÌÏ× ËÏÏÒÄÉÎÁÔ
+<Destroy> - ÔÝÁÔÅÌØÎÏ ÚÁÍÅÔÁÅÔ ×ÓÅ ÓÌÅÄÙ ÔÏÇÏ, ÞÔÏ ÜÔÏ ÎÅ ÎÁÓÔÏÑÝÉÊ
+            widget, Õ×ÅÄÏÍÌÑÅÔ ×ÓÅ ÓÌÏÉ Ï ÔÏÍ, ÞÔÏ × ÜÔÏÍ ÐÌÁÎÛÅÔÅ ÏÎÉ ÂÏÌØÛÅ
+            ÎÅ ×ÉÄÎÙ.
+<Button-3> - ÌÕËÏÛËÏ Ó ÏËÏÍ (ÏËÏÛËÏ Ó ÌÕËÏÍ)
+<Double-1> zoom %W %x %y
+(Á binding ÚÁÐÏÍÉÎÁÅÔÓÑ × ÐÒÉ×ÁÔÎÙÈ ÄÁÎÎÙÈ ÐÌÁÎÛÅÔÁ)
+<Any-Motion> - ÅÓÌÉ ÏÐÒÅÄÅÌÅΠÓÔÁÔÕÓ, ÏÔÏÂÒÁÖÁÅÔ ËÏÏÒÄÉÎÁÔÙ
+
+ðÒÏÞÉÅ ÏÂßÅËÔÙ 
+ðÒÏÅËÃÉÑ - ÜÔÏ ÔÏÖÅ ÏÂßÅËÔ. ðÒÉÞÅÍ ÎÁÐÉÓÁÎÎÙÊ ÞÅÓÔÎÏ ÎÁ C.
+
+ðÒÏÞÉÅ ËÏÍÁÎÄÙ
+
+zoom  - ÂÙ×ÛÉÊ mapzoom
+print - ÂÙ×ÛÉÊ mapprint
+
+÷ÓÅ ËÏÍÁÎÄÙ, ËÏÔÏÒÙÅ ÒÁÂÏÔÁÀÔ Ó ËÏÏÒÄÉÎÁÔÁÍÉ, ÐÅÒÅÉÍÅÎÏ×Ù×ÁÀÔÓÑ
+× __planchet_mapx
+  __planchet_mapy É Ô.Ä.
diff --git a/doc/region.concept b/doc/region.concept
new file mode 100644 (file)
index 0000000..ce411c6
--- /dev/null
@@ -0,0 +1,31 @@
+ ëÏÎÃÅÐÃÉÑ ÒÅÇÉÏÎÁ.
+
+÷ ÏÂÌÁÓÔÉ çéó-ÏÂÒÁÂÏÔËÉ ÐÒÁËÔÉÞÅÓËÉ ÎÉËÏÇÄÁ ÎÅÌØÚÑ ÏÇÒÁÎÉÞÉÔØÓÑ
+ÒÁÓÓÍÏÔÒÅÎÉÅÍ ÏÄÎÏÊ ËÁÒÔÙ ÎÁ ÏÐÒÅÄÅÌÅÎÎÕÀ ÔÅÒÒÉÔÏÒÉÀ, ÏÓÏÂÅÎÎÏ
+ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ËÏÎÃÅÐÃÉÉ ÆÕÎËÃÉÏÎÁÌØÎÙÈ ËÁÒÔ.
+
+ëÒÏÍÅ ÔÏÇÏ, ÄÏÓÔÁÔÏÞÎÏ ÞÁÓÔÏ ×ÏÚÎÉËÁÅÔ ÚÁÄÁÞÁ ÒÁÂÏÔÙ Ó ÎÅÓËÏÌØËÉÍÉ
+ÒÁÚÎÏÍÁÓÛÔÁÂÎÙÍÉ ÕÞÁÓÔËÁÍÉ ÔÅÒÒÉÔÏÒÉÉ.
+
+ðÏÜÔÏÍÕ × fGIS ××ÅÄÅÎÁ ËÏÎÃÅÐÃÉÑ ÒÅÇÉÏÎÁ. òÅÇÉÏΠÜÔÏ ÇÒÕÐÐÁ ËÁÒÔ,
+ÏÐÉÓÙ×ÁÀÝÉÈ ÏÄÎÕ É ÔÕ ÖÅ ÔÅÒÒÉÔÏÒÉÀ. ÷ÓÅ ËÁÒÔÙ ÒÅÇÉÏÎÁ ÄÏÌÖÎÙ
+ÉÍÅÔØ ÏÄÉÎÁËÏ×ÕÀ ËÏÏÒÄÉÎÁÔÎÕÀ ÓÉÓÔÅÍÕ (ÐÒÏÅËÃÉÀ), ÈÏÔÑ ÎÉËÔÏ ÎÅ 
+ÍÅÛÁÅÔ ÓÏÚÄÁÔØ ÎÅÓËÏÌØËÏ ÒÅÇÉÏÎÏ× fGIS, ÉÍÅÀÝÉÈ ÒÁÚÎÕÀ ÐÒÏÅËÃÉÀ,
+ÄÌÑ ÏÄÎÏÊ É ÔÏÊ ÖÅ ÔÅÒÒÉÔÏÒÉÉ. 
+
+ëÏÐÉÒÏ×ÁÎÉÅ ËÁÒÔÙ ÉÚ ÏÄÎÏÇÏ ÒÅÇÉÏÎÁ × ÄÒÕÇÏÊ (ÅÓÔÅÓÔ×ÅÎÎÏ, ÓÒÅÄÓÔ×ÁÍÉ
+fGIS, Á ÎÅ ÓÒÅÄÓÔ×ÁÍÉ ÏÐÅÒÁÃÉÏÎÎÏÊ ÓÉÓÔÅÍÙ) ÐÒÉ×ÏÄÉÔ Ë Á×ÔÏÍÁÔÉÞÅÓËÏÍÕ
+ÉÚÍÅÎÅÎÉÀ ÐÒÏÅËÃÉÉ.
+
+òÅÇÉÏÎÙ ÍÏÇÕÔ ÂÙÔØ ÉÅÒÁÒÈÉÞÅÓËÉ ×ÌÏÖÅÎÙ ÄÒÕÇ × ÄÒÕÇÁ. ðÏÜÔÏÍÕ ÅÝÅ ÏÄÎÉÍ
+Ó×ÏÊÓÔ×ÏÍ ÒÅÇÉÏÎÁ Ñ×ÌÑÅÔÓÑ ËÁÒÔÁ ÅÇÏ ÒÁÚÂÉÅÎÉÑ ÎÁ ÓÕÂÒÅÇÉÏÎÙ.
+ó ÅÅ ÐÏÍÏÝØÀ ÍÏÖÎÏ ÐÅÒÅÊÔÉ × ÒÅÇÉÏÎ, ÄÁÀÝÉÊ ÂÏÌÅÅ ÄÅÔÁÌØÎÕÀ ÈÁÒÁËÔÅÒÉÓÔÉËÕ
+ÐÒÏÓÔÏ ÐÕÔÅÍ ×ÙÂÏÒÁ ÔÏÞËÉ ÎÁ ËÁÒÔÅ.
+
+÷ÎÕÔÒÉ ÒÅÇÉÏÎÁ ËÁÒÔÙ ÍÏÇÕÔ ÂÙÔØ ÏÂßÅÄÉÎÅÎÙ × ÔÅÍÁÔÉÞÅÓËÉÅ ÇÒÕÐÐÙ,
+ÞÔÏ ÏÂÌÅÇÞÁÅÔ ÎÁ×ÉÇÁÃÉÀ ÐÏ ÎÉÍ. 
+
+òÅÇÉÏÎÕ ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ËÁÔÁÌÏÇ ÆÁÊÌÏ×ÏÊ ÓÉÓÔÅÍÙ OS, Á ÓÕÂÒÅÇÉÏÎÁÍ -
+ÐÏÄËÁÔÁÌÏÇÉ ÄÁÎÎÏÇÏ ËÁÔÁÌÏÇÁ. ðÏÜÔÏÍÕ ÐÅÒÅÈÏÄ × ×ÙÛÅÌÅÖÁÝÉÊ ÒÅÇÉÏÎ
+×ÓÅÇÄÁ ÏÐÒÅÄÅÌÅΠÏÄÎÏÚÎÁÞÎÏ.
+
diff --git a/doc/visualisagion.concept b/doc/visualisagion.concept
new file mode 100644 (file)
index 0000000..0bcea71
--- /dev/null
@@ -0,0 +1,18 @@
+ðÒÉÎÃÉÐÙ ×ÉÚÕÁÌÉÚÁÃÉÉ fGIS
+
+ïÄÎÉÍ ÉÚ ÏÓÎÏ×ÎÙÈ ÎÅÄÏÓÔÁÔËÏ× ÔÒÁÄÉÃÉÏÎÎÙÈ GIS (ARC/Info, Idrisi, EPPL7)
+Ñ×ÌÑÅÔÓÑ ÒÁÚÄÅÌÅÎÉÅ ÓÏÂÓÔ×ÅÎÎÏ ÜÌÅËÔÒÏÎÎÙÈ ËÁÒÔ (ÐÏËÒÙÔÉÊ) É ËÁÒÔÏÇÒÁÆÉÞÅÓËÉÈ
+ËÏÍÐÏÚÉÃÉÊ, ÐÒÅÄÎÁÚÎÁÞÅÎÎÙÈ ÄÌÑ ÐÒÏÓÍÏÔÒÁ É ÐÅÞÁÔÉ.
+
+÷ ÜÔÏÍ ÐÏÄÈÏÄÅ ÅÓÔØ Ó×ÏÉ ÐÒÅÉÍÕÝÅÓÔ×Á --- ÐÅÒÅÈÏÄ ÏÔ ËÏÒÒÅËÔÎÏ ÐÏÓÔÒÏÅÎÎÏÊ
+ÍÏÄÅÌÉ ÍÅÓÔÎÏÓÔÉ, ËÁËÏ×ÏÊ Ñ×ÌÑÅÔÓÑ ÐÏËÒÙÔÉÅ, Ë ÐÒÏÉÚ×ÅÄÅÎÉÀ ÐÏÌÉÇÒÁÆÉÞÅÓËÏÇÏ
+ÉÓËÕÓÓÔ×Á, ËÁËÏ×ÙÍ Ñ×ÌÑÅÔÓÑ ÂÕÍÁÖÎÁÑ ËÁÒÔÁ, ÚÁÄÁÞÁ ÎÅÐÒÏÓÔÁÑ É, ÎÅÓÏÍÎÅÎÎÏ,
+ÔÒÅÂÕÀÝÁÑ ÕÞÁÓÔÉÑ ÞÅÌÏ×ÅËÁ. ôÅÍ ÎÅ ÍÅÎÅÅ ÄÌÑ ÂÏÌØÛÉÎÓÔ×Á ÐÏÌØÚÏ×ÁÔÅÌÅÊ
+çéó, Ñ×ÌÑÀÝÉÍÉÈÓÑ ÓÐÅÃÉÁÌÉÓÔÁÍÉ × ÐÒÅÄÍÅÔÎÏÊ ÏÂÌÁÓÔÉ, Á ÎÅ ÐÒÏÆÅÓÓÉÏÎÁÌØÎÙÍÉ
+ËÁÒÔÏÇÒÁÆÁÍÉ, ÎÅ×ÏÚÍÏÖÎÏÓÔØ ÍÇÎÏ×ÅÎÎÏ Õ×ÉÄÅÔØ ÒÅÚÕÌØÔÁÔ ÐÒÉÍÅÎÅÎÉÑ ÔÏÊ ÉÌÉ
+ÉÎÏÊ ÏÐÅÒÁÃÉÉ, Ñ×ÌÑÅÔÓÑ ÓÕÝÅÓÔ×ÅÎÎÏÊ ÐÏÍÅÈÏÊ ÐÒÉ ÐÏÓÔÒÏÅÎÉÉ çéó ÍÏÄÅÌÅÊ.
+
+ðÏÜÔÏÍÕ × fGIS ÐÁÒÁÍÅÔÒÙ ×ÉÚÕÁÌÉÚÁÃÉÉ, ÔÁËÉÅ ËÁË ÐÁÌÉÔÒÁ, ÛÔÒÉÈÏ×ËÉ ÉÌÉ
+ÎÁÂÏÒ ÓÌÏÅ×-ÏÒÉÅÎÔÉÒÏ×, ÏÂÌÅÇÞÁÀÝÉÈ ÞÔÅÎÉÅ ÏÓÎÏ×ÎÏÊ ÔÅÍÁÔÉÞÅÓËÏÊ ÉÎÆÏÒÍÁÃÉÉ,
+Ñ×ÌÑÅÔÓÑ ÁÔÒÉÂÕÔÁÍÉ ËÁÒÔÙ É ËÁÖÄÁÑ ËÁÒÔÁ ÍÏÖÅÔ ÂÙÔØ ×ÉÚÕÁÌÉÚÉÒÏ×ÁÎÁ ÉÌÉ
+ÎÁÐÅÞÁÔÁÎÁ ÐÒÏÓÔÏ ÐÕÔÅÍ ÕËÁÚÁÎÉÑ ÅÅ ÉÍÅÎÉ.
diff --git a/epu/Makefile b/epu/Makefile
new file mode 100644 (file)
index 0000000..d33ab0e
--- /dev/null
@@ -0,0 +1,42 @@
+CC=gcc
+CFLAGS=-g -Wall -pedantic -O2 -I../lib/gnu_lib -I../include
+LDFLAGS=-L../lib
+LOADLIBES=-lm -lepp
+SRC=\
+RCS/border.c,v\
+RCS/cluster.c,v\
+RCS/dgt2gen.c,v\
+RCS/eheader.c,v\
+RCS/extents.c,v\
+RCS/fill.c,v\
+RCS/intable.c,v\
+RCS/mosaic.c,v\
+RCS/neighbours.c,v\
+RCS/outtab.c,v\
+RCS/reclass1.c,v\
+RCS/window.c,v
+ALL=\
+border\
+cluster\
+dgt2gen\
+eheader\
+extents\
+fill\
+intable\
+mosaic\
+neighbours\
+outtable\
+reclass1\
+centers\
+project\
+window
+RCS/%,v : %
+       ci $<
+% : %.o
+       ${CC} $< -o $@ ${LDFLAGS} ${LOADLIBES}
+all: ${ALL}
+rcs: ${SRC}
+project: project.o
+       ${CC} $< -o $@ ${CFLAGS} ${LDFLAGS} -lproj ${LOADLIBES}
+outtable: outtable.o outtable_func.o
+       gcc outtable.o outtable_func.o ${LDFLAGS} ${LOADLIBES} -o outtable
diff --git a/epu/bil2epp b/epu/bil2epp
new file mode 100755 (executable)
index 0000000..3e00b13
Binary files /dev/null and b/epu/bil2epp differ
diff --git a/epu/bil2epp.c b/epu/bil2epp.c
new file mode 100644 (file)
index 0000000..7e38cde
--- /dev/null
@@ -0,0 +1,137 @@
+#define __USE_GNU 
+#define __USE_XOPEN
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <epp.h>
+#include <ctype.h>
+#include <eppl_ut.h>
+void error(const char * message)
+{
+  fprintf(stderr,"%s\n",message);
+  exit(1);
+}
+void swab(const void *from,void *to,size_t size);
+void dcopy(const void *from,void *to,size_t size)
+{
+  memcpy(to,from,size);
+}
+
+int convert(EPP *epp,FILE *in,void (*copyrow)(const void *,void*,size_t),
+          int shift)
+{
+  int bytes=(epp->lc-epp->fc)*2,row,col,i,rows=epp->lr-epp->fr;
+  short int *buf,*buf2,*p;
+  buf=malloc(bytes);
+  buf2=malloc(bytes);
+  for (row=epp->fr,i=1;row<epp->lr;row++,i++) {
+    fread(buf,bytes,1,in);
+    copyrow(buf,buf2,bytes);
+    for (col=epp->fc,p=buf2;col<epp->lc;col++,p++) {
+        epp_put(epp,col,row,(unsigned short)(*p+shift));
+        if (EndLineProc) 
+           if (EndLineProc(row,i,rows)) return -1;
+    }
+  }
+  return 0;
+}
+
+EPP *read_header(char *filename,int *swapbytes,int shift)
+{ char buf[1024],*p;
+  int rows=0,cols=0,nodata=32768;
+  FILE *f=fopen(filename,"r");
+  double X1=0,Y1=0,X2=0,Y2=0,DX=0,DY=0;
+  while (!feof(f)) {
+     fgets(buf,1024,f);
+     p=strchr(buf,'\n');
+     if (p) *p=0;
+     p=buf;
+     while(isalpha(*p)) p++;
+     *p=0;p++;
+     if (!strcmp(buf,"BYTEORDER")) {
+        while(isspace(*p)) p++;
+        *swapbytes=toupper(*p)=='M';
+     } else if (!strcmp(buf,"NROWS")) {
+        rows=atol(p);
+     } else if (!strcmp(buf,"NCOLS")) {
+        cols=atol(p);
+     } else if (!strcmp(buf,"NBITS")) {
+        if (atol(p)!=16) {
+          fprintf(stderr,"Data size in %s is not 16 bit\n",filename);
+          return NULL;
+        }
+     } else if (!strcmp(buf,"NODATA")) {
+        nodata=atol(p)+shift;
+        if (nodata<0) nodata+=65536;
+     } else if (!strcmp(buf,"ULXMAP")) {
+        X1=strtod(p,NULL);
+     } else if (!strcmp(buf,"ULYMAP")) {
+        Y1=strtod(p,NULL);
+     } else if (!strcmp(buf,"XDIM")) {
+        DX=strtod(p,NULL);
+     } else if (!strcmp(buf,"YDIM")) {
+        DY=strtod(p,NULL);
+     } 
+  }
+  fclose(f);
+  X1-=DX/2;
+  Y1-=DY/2;
+  X2=X1+DX*cols;
+  Y2=Y1+DY*rows;
+  Create16bit=1;
+  return creat_epp(force_ext(filename,".epp"),1,1,cols,
+     rows,X1,Y1,X2,Y2,100,0,nodata);
+}
+int main(int argc, char **argv)
+{ int shift=0;
+  char headersuffix[100]=".hdr",headername[1024];
+  int i,c,verbose=0; 
+  while ((c=getopt(argc,argv,"s:h:%"))!=EOF) {
+   switch (c) {
+    case 's': {char *erptr;       
+               shift = strtol(optarg,&erptr,0);
+               if (!*erptr) {
+                  error("Invalid shift value");
+               }
+               break;
+              }
+    case 'h': strcpy(headersuffix, optarg);
+              break;
+    case '%': verbose=1;
+              break;
+    default: error("Invalid option.\n Usage bil2epp [-h header_suffix]"
+               " [-s shift_value] [-%] files\n");   
+   }
+  }
+   
+  install_progress_indicator(verbose?show_percent:check_int);
+  if (optind==argc) error("No files specified");
+
+  for (i=optind;i<argc;i++) {
+    EPP *epp;
+    FILE *f=fopen(argv[i],"r");
+    int swapbytes;
+   
+    if (!f) {
+        fprintf(stderr,"Cannot open %s, skipping\n",argv[i]);
+        continue;
+    }
+    strcpy(headername,force_ext(argv[i],headersuffix));
+    if (!(epp=read_header(headername,&swapbytes,shift))) {
+      fprintf(stderr,"Cannot open %s, skipping %s\n",headername,argv[i]);
+      continue;
+    }        
+    if (verbose) {
+      fprintf(stderr,"\r%s\n",argv[i]);
+    }
+    if (convert (epp,f,swapbytes?swab:dcopy,shift)) {
+       clear_progress(1);
+       exit(1);
+    }
+    close_epp(epp);
+    fclose(f);
+  }
+  clear_progress(0);
+  exit(0);
+} 
diff --git a/epu/border.c b/epu/border.c
new file mode 100644 (file)
index 0000000..910f080
--- /dev/null
@@ -0,0 +1,526 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "eppl_ut.h"
+#include "epp.h"
+#include "dgt.h"
+#include <getopt.h>
+#ifndef __LINUX__
+#include <errno.h>
+#endif
+#define TRUE 1
+#define FALSE 0
+#define SEG_LEFT 1
+#define SEG_VERT 2
+#define SEG_RIGHT 4
+#define SEG_UP 8
+#define DELTA 16
+typedef struct U_POINT {
+        unsigned short x,y;} U_POINT;
+typedef U_POINT *LINEBUF;
+typedef struct INODE {
+                            unsigned short int count;
+                            short int both_ends;
+                            unsigned short int limit;
+                            int x_tail,x_head;
+                            LINEBUF points;
+                          } *LINE_INODE;
+typedef struct LINE_END { LINE_INODE buf;
+                          int tail;
+                         } LINE_END;
+/* ðÁÒÁÍÅÔÒÙ ËÏÎÆÉÇÕÒÁÃÉÉ */
+int offsite_option=1;
+int tolerance=3;
+/* ïÓÎÏ×ÎÙÅ ÒÁÂÏÞÉÅ ÓÔÒÕËÔÕÒÙ ÄÁÎÎÙÈ */
+LINE_END *lines;
+unsigned short *rp1,*rp2;
+EPP* source;
+DGT* dest;
+/* ïÓÎÏ×ÎÙÅ ÐÒÏÃÅÄÕÒÙ */
+int epp2dgtX(int col);
+int epp2dgtY(int row);
+void getrow(int row);
+void add_segment(LINE_END line,int col,int row);
+/* ÄÏÂÁ×ÌÑÅÔ ÓÅÇÍÅÎÔ × ÎÁÞÁÌÏ ÉÌÉ × ËÏÎÅÃ, × ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ 
+  ÐÏÌÑ line->tail, ËÏÎÞÁÀÝÉÊÓÑ × ÔÏÞËÅ col,row */ 
+void put_line(LINE_INODE buf);
+/* çÅÎÅÒÁÌÉÚÕÅÔ ÌÉÎÉÀ É ÚÁÐÉÓÙ×ÁÅÔ ÅÅ. ðÒÉ ÎÅÏÂÈÏÄÉÍÏÓÔÉ ÒÅÖÅÔ
+   ðÏ ÚÁ×ÅÒÛÅÎÉÉ ÏÐÅÒÁÃÉÉ ÏÓ×ÏÂÏÖÄÁÅÔ ×ÓÀ ÐÁÍÑÔØ, ÚÁÎÑÔÕÀ ÌÉÎÉÅÊ
+*/
+int create_header(EPP *epp,char *dgtname);
+/* óÏÚÄÁÅÔ ×ÙÈÏÄÎÏÊ ÆÁÊÌ */
+void write_labels(EPP *epp,DGT *dgt);
+/* óÏÚÄÁÅÔ ÔÏÞËÉ */
+void end_line(LINE_END line);
+/* úÁ×ÅÒÛÁÅÔ ÐÏÐÏÌÎÅÎÉÅ ÌÉÎÉÉ Ó ÕËÁÚÁÎÎÏÇÏ ËÏÎÃÁ. åÓÌÉ Ó ÄÒÕÇÏÇÏ ËÏÎÃÁ
+  ÏÎÁ ÕÖÅ ÎÅ ÍÏÖÅÔ ÐÏÐÏÌÎÑÔØÓÑ, ÄÅÌÁÅÔ ÅÊ put_line */  
+LINEBUF enlarge(LINE_INODE buf);
+/* õ×ÅÌÉÞÉ×ÁÅÔ ÄÌÉÎÕ ÌÉÎÉÉ ÎÁ 1. ðÒÉ ÎÅÏÂÈÏÄÉÍÏÓÔÉ ÄÏ×ÙÄÅÌÑÅÔ ÐÁÍÑÔØ */
+int smooth(LINE_INODE line,LINEBUF *buf);
+/*óÇÌÁÖÉ×ÁÅÔ ÌÉÎÉÀ 
+  ×ÏÚ×ÒÁÝÁÅÔ ËÏÌÉÞÅÓÔ×Ï ÕÚÌÏ×, ÏÓÔÁ×ÛÉÈÓÑ ÐÏÓÌÅ ÇÅÎÅÒÁÌÉÚÁÃÉÉ*/
+LINE_INODE new_line(int both,int col1,int row1,int col2,int row2);
+/* óÏÚÄÁÅÔ ÎÏ×ÕÀ ÌÉÎÉÀ, ÐÏÍÅÝÁÑ × ÎÅÅ ÅÄÉÎÓÔ×ÅÎÎÙÊ ÓÅÇÍÅÎÔ Ó ÚÁÄÁÎÎÙÍÉ
+ËÏÏÒÄÉÎÁÔÁÍÉ.*/
+void join_lines(LINE_END line1,LINE_END  line2); 
+/* ïÂßÅÄÉÎÑÅÔ Ä×Å ÌÉÎÉÉ × ÏÄÎÕ. */
+int border_dgt(EPP *epp,char *dgtname,int offs_opt,int tol,int do_labels)
+{int nrows=epp->lr-epp->fr+1;
+ int ncols=epp->lc-epp->fc+2;
+ unsigned short *left,*right,*up;
+ int this_node,next_node;
+ LINE_END hor_line,*vert_line;
+ int i,j;
+ offsite_option=offs_opt;
+ tolerance=tol;
+ if ((i=create_header(epp,dgtname))) return i;
+ rp1=calloc(ncols,sizeof(short int));
+ rp2=calloc(ncols,sizeof(short int));
+ lines=calloc(ncols,sizeof(struct LINE_END));
+ for(i=0;i<nrows;i++)
+ { getrow(i);
+   
+   if (EndLineProc) if ((*EndLineProc)(i,i,nrows)) return 1;
+   left=rp1;
+   right=rp1+1;
+   up=rp2+1;
+   vert_line=lines;
+   this_node=0;
+   hor_line.buf=NULL;
+   for(j=0;j<ncols-1;j++,left++,right++,up++,vert_line++)
+   { /* çÏÒÉÚÏÎÔÁÌØÎÙÊ ÓÅÇÍÅÎÔ*/
+     if (*up!=*right)
+       {next_node=SEG_LEFT;
+        this_node|=SEG_RIGHT;
+       } else next_node=0;
+     if (*left!=*right)
+       this_node|=SEG_VERT;
+     if (vert_line->buf)  
+       this_node|=SEG_UP;
+#ifdef DEBUG
+  if ((this_node&SEG_LEFT)&&(!hor_line.buf))
+   fprintf(stderr,"Hor_line exists, where shouldn't x=%d y=%d\n",j,i);
+  if (!(this_node&SEG_LEFT)&&(hor_line.buf))
+   fprintf(stderr,"Hor_line doesn't exist x=%d y=%d\n",j,i);
+  if (this_node&SEG_UP)
+  if ((vert_line->tail?vert_line->buf->x_tail:vert_line->buf->x_head)!=j)
+   fprintf(stderr,"Invalid vertical segment at x=%d y=%d\n",j,i);
+#endif      
+   switch(this_node)
+   {/* ìÉÎÉÉ ÐÒÏÄÏÌÖÁÀÔÓÑ ÐÒÑÍÏ*/ 
+     case 0:/* äÅÌÁÔØ ÚÄÅÓØ ÎÅÞÅÇÏ */ break;
+     case SEG_UP|SEG_VERT:add_segment(*vert_line,j,i+1);
+                          break;
+     case SEG_LEFT|SEG_RIGHT:add_segment(hor_line,j+1,i);
+                          break;
+    /* ìÉÎÉÉ ÐÒÏÄÏÌÖÁÀÔÓÑ Ó ÉÚÇÉÂÏÍ */
+     case SEG_LEFT|SEG_VERT:*vert_line=hor_line;hor_line.buf=NULL;
+                             add_segment(*vert_line,j,i+1);
+                            break;
+     case SEG_UP|SEG_RIGHT:hor_line=*vert_line;vert_line->buf=NULL;
+                             add_segment(hor_line,j+1,i);
+                             break;
+     /* ìÉÎÉÉ ÓÌÉ×ÁÀÔÓÑ */
+     case SEG_UP|SEG_LEFT:join_lines(hor_line,*vert_line);
+                          vert_line->buf=NULL;
+                          hor_line.buf=NULL;
+                          break;
+     /* ìÉÎÉÑ ÓÁÍÏÚÁÒÏÖÄÁÅÔÓÑ ÎÁ ÐÕÓÔÏÍ ÍÅÓÔÅ */
+     case SEG_VERT|SEG_RIGHT:hor_line.buf=new_line(TRUE,j,i,j+1,i);
+                             hor_line.tail=TRUE;
+                             vert_line->buf=hor_line.buf;
+                             vert_line->tail=FALSE;
+                             add_segment(*vert_line,j,i+1);
+                          /* ÓÏÚÄÁÔØ ÔÏÞËÕ */
+                             break;
+     /* ìÉÎÉÉ ÒÁÓÓÅËÁÀÔÓÑ - 5 ÓÌÕÞÁÅ× ËÏÇÄÁ × ÔÏÞËÅ 3 É ÂÏÌÅÅ ÌÉÎÉÊ */
+     case SEG_VERT|SEG_LEFT|SEG_RIGHT:
+       /* T ×ÎÉÚ */
+       end_line(hor_line);
+       hor_line.buf=new_line(FALSE,j,i,j+1,i);
+       hor_line.tail=TRUE;
+       vert_line->buf=new_line(FALSE,j,i,j,i+1);
+       vert_line->tail=TRUE;
+       /* cÏÚÄÁÔØ ÔÏÞËÕ */
+       break;
+     case SEG_UP|SEG_LEFT|SEG_RIGHT:
+       /* ô ××ÅÒÈ ÎÏÇÁÍÉ */
+       /*×ÙÂÒÏÓÉÔØ ÔÏÞËÕ*/
+       end_line(hor_line);
+       end_line(*vert_line);
+       hor_line.buf=new_line(FALSE,j,i,j+1,i);
+       hor_line.tail=TRUE;
+       vert_line->buf=NULL;
+       break;                   
+     case SEG_UP|SEG_LEFT|SEG_VERT:
+       /* ô È×ÏÓÔÏÍ ×ÌÅ×Ï */
+       /* ×ÙÂÒÏÓÉÔØ ÔÏÞËÕ */
+       end_line(hor_line);
+       end_line(*vert_line);
+       vert_line->buf=new_line(FALSE,j,i,j,i+1);
+       vert_line->tail=TRUE;
+       hor_line.buf=NULL;
+       break;   
+      case SEG_UP|SEG_RIGHT|SEG_VERT:                
+       /* ô È×ÏÓÔÏÍ ×ÐÒÁ×Ï */
+       /* ×ÙÂÒÏÓÉÔØ ÔÏÞËÕ */
+       end_line(*vert_line);
+       hor_line.buf=new_line(FALSE,j,i,j+1,i);
+       hor_line.tail=TRUE;
+       vert_line->buf=new_line(FALSE,j,i,j,i+1);
+       vert_line->tail=TRUE;
+       /* ÓÏÚÄÁÔØ ÔÏÞËÕ */
+       break;
+      case SEG_UP|SEG_RIGHT|SEG_LEFT|SEG_VERT:
+       /* ËÒÅÓÔ */ 
+       end_line(*vert_line);
+       end_line(hor_line);
+       hor_line.buf=new_line(FALSE,j,i,j+1,i);
+       hor_line.tail=TRUE;
+       vert_line->buf=new_line(FALSE,j,i,j,i+1);
+       vert_line->tail=TRUE;
+       /* ÓÏÚÄÁÔØ ÔÏÞËÕ */
+       break;
+      default:
+        /* ÷ÉÓÑÞÉÅ ÕÚÌÙ, ËÏÔÏÒÙÈ îå âù÷áåô */
+       fprintf(stderr,"Dangling node at x=%d,y=%d\n",j,i);
+      }
+      this_node=next_node; 
+    }
+  }  
+if (do_labels) write_labels(source,dest); 
+close_dgt(dest);
+
+return 0;
+}
+
+void add_segment(LINE_END line,int col,int row)
+{
+ LINE_INODE l=line.buf;
+
+ LINEBUF points;
+ if (line.tail)
+ {points=l->points+l->count-2;
+  if (points->x==col&&points[1].x==col) {points[1].y=row;return;}
+  if (points->y==row&&points[1].y==row) {points[1].x=col;l->x_tail=col;return;}
+  points=enlarge(l);
+  points+=l->count-1;
+  points->x=col;
+  points->y=row;
+  l->x_tail=col;
+ }
+ else
+ {LINEBUF tmp;int i=l->count; 
+  points=l->points;
+  if (points->x==col&&points[1].x==col) {points->y=row;return;}
+  if (points->y==row&&points[1].y==row) {points->x=col;l->x_head=col;return;}
+  points=enlarge(l);
+  points+=l->count-1;
+  tmp=points-1;
+  for(;i>0;i--,*(points--)=*(tmp--));
+  points->x=col;
+  points->y=row;
+  l->x_head=col; 
+ } 
+} 
+
+LINEBUF enlarge(LINE_INODE buf)
+{ if (buf->count++==buf->limit)
+    buf->points=realloc(buf->points,(buf->limit+=DELTA)*sizeof(U_POINT));
+   return buf->points; 
+} 
+void end_line(LINE_END line)
+{ if (line.buf->both_ends)
+     line.buf->both_ends=FALSE;
+  else
+    put_line(line.buf);
+}
+#ifdef DEBUG
+#define DEBUG_CHECK(x1,x2) if (line1.buf->x1!=line2.buf->x2) fprintf(stderr,"Joining lines with separate ends %d %d\n",line1.buf->x1,line2.buf->x2)
+#else
+#define DEBUG_CHECK(x1,x2)
+#endif
+#define COPY_DIRECT(l) for(i=l.buf->count,source=l.buf->points;i>0;i--,*(dest++)=*(source++))
+#define COPY_REVERSE(l) for(i=l.buf->count,source=l.buf->points+l.buf->count-1;i>0; i--,*(dest++)=*(source--)) 
+void join_lines(LINE_END line1,LINE_END line2)
+{int i;
+ LINEBUF source,dest;
+ LINE_INODE new;
+ if (line1.buf==line2.buf)
+  { put_line(line1.buf);
+    return;
+  } 
+ new=malloc(sizeof(struct INODE)); 
+ new->count=line1.buf->count+line2.buf->count-1;
+ new->limit=(new->count+DELTA-1)/DELTA*DELTA;
+ new->points=malloc(new->limit*sizeof(U_POINT));
+ dest=new->points;
+
+ if (line1.tail)
+ {
+    new->x_head=line1.buf->x_head;
+    COPY_DIRECT(line1);
+    dest--;
+
+ if (line2.tail)
+  { 
+    DEBUG_CHECK(x_tail,x_tail);
+    new->x_tail=line2.buf->x_head;
+    COPY_REVERSE(line2);    
+  }
+ else
+  { DEBUG_CHECK(x_tail,x_head);
+    new->x_tail=line2.buf->x_tail;
+    COPY_DIRECT(line2);
+  }
+ }
+ else
+ { 
+   new->x_head=line1.buf->x_tail;
+   COPY_REVERSE(line1);
+   dest--;
+   if (line2.tail)
+   { DEBUG_CHECK(x_head,x_tail);
+     new->x_tail=line2.buf->x_head;
+     COPY_REVERSE(line2);
+   }
+   else
+   { DEBUG_CHECK(x_head,x_head);
+     new->x_tail=line2.buf->x_tail;
+     COPY_DIRECT(line2);
+   }
+ }
+ new->both_ends=-1;
+ if (line1.buf->both_ends)
+  { new->both_ends++;
+    lines[new->x_head].buf=new;
+    lines[new->x_head].tail=FALSE;
+  }
+ if (line2.buf->both_ends)
+  { new->both_ends++;
+    lines[new->x_tail].buf=new;
+    lines[new->x_tail].tail=TRUE;
+  }
+ if (new->both_ends<0) 
+     put_line(new);
+ free(line1.buf->points);
+ free(line2.buf->points);
+ free(line1.buf);
+ free(line2.buf);
+}
+LINE_INODE new_line(int both,int col1,int row1,int col2,int row2)
+{LINE_INODE tmp=malloc(sizeof(struct INODE));
+ tmp->both_ends=both;
+ tmp->count=2;
+ tmp->limit=DELTA;
+ tmp->points=malloc(DELTA*sizeof(U_POINT));
+ tmp->points[0].x=col1;
+ tmp->points[0].y=row1;
+ tmp->points[1].x=col2;
+ tmp->points[1].y=row2;
+ tmp->x_head=col1;
+ tmp->x_tail=col2;
+ return tmp;
+}
+void getrow(int row)
+{ unsigned short int *tmp,*tmp2;
+  int i;
+  tmp=rp2;
+  rp2=rp1;
+  rp1=tmp;
+  if(row+source->fr<source->lr) 
+   {
+    epp_get(source,source->fc,source->fr+row);
+    memcpy(rp1+1,source->row,(source->lc-source->fc)*sizeof(short));
+    if (offsite_option) 
+    { rp1[0]=source->offsite;
+      rp1[source->lc-source->fc+1]=source->offsite;
+    }
+    else
+    { rp1[0]=rp1[1];
+      tmp=rp1+source->lc-source->fc;
+      *(tmp+1)=*tmp;
+    }
+   }
+  else
+   if (offsite_option)
+     for(i=source->lc-source->fc,tmp=rp1;i>=0;*(tmp++)=source->offsite,i--);
+   else
+     for(i=source->lc-source->fc,tmp=rp1,tmp2=rp2;i>=0;*(tmp++)=*(tmp2++),i--);
+  if (!row) 
+   if (offsite_option)
+     for(i=source->lc-source->fc+1,tmp=rp2;i>=0;*(tmp++)=source->offsite,i--);
+   else
+     for(i=source->lc-source->fc,tmp=rp2,tmp2=rp1;i>=0;*(tmp++)=*(tmp2++),i--);
+}
+void put_line(LINE_INODE line)
+{static int lineno=1;
+ int c,n;LINEBUF p;LINEBUF buf;POINT *s;
+ if (tolerance) c=smooth(line,&buf);
+  else {c=line->count;buf=line->points;}
+ p=line->points;
+ while (c>0)
+ { if (c>500) {n=500;c-=499;} else {n=c;c=0;} 
+   s=dest->buffer->s;
+   dest->buffer->npoints=n;
+   dest->buffer->ID=1;
+   for(;n>0;p++,n--,s++)
+    {s->x=epp2dgtX(p->x);
+     s->y=epp2dgtY(p->y);
+    }
+   dgt_touch(dest);
+   dgt_next(dest); 
+   p--;
+  }
+ lineno++;
+ free(buf);
+ free(line);
+}
+int rowfact,colfact;
+int create_header(EPP *epp,char *dgtname)
+{EPPHEADER h;
+ get_epp_header(epp,&h);
+ dest=creat_dgt(dgtname,epp->XLeft,epp->YBottom,epp->XRight,epp->YTop,h.coord_sys);
+if (dest==NULL) return errno;
+source=epp;
+rowfact=epp->lr-epp->fr;
+colfact=epp->lc-epp->fc;
+if (tolerance) {rowfact*=2;colfact*=2;}
+return 0;
+}
+int epp2dgtX(int col)
+{ return (col*(unsigned long)65535/colfact-32768);
+}
+int epp2dgtY(int row)
+{ return (32767-row*(unsigned long)65535/rowfact);
+
+}
+#ifdef __GNUC__
+#define seg_len(a) abs(a->x-a[1].x?:a->y-a[1].y)
+#else
+#define seg_len(a) abs(a->x-a[1].x?a->x-a[1].x:a->y-a[1].y)
+#endif
+U_POINT make_middle_point(LINEBUF src1,LINEBUF src2)
+{U_POINT tmp;
+ tmp.x=src1->x+src2->x;
+ tmp.y=src1->y+src2->y;
+ return tmp;
+}
+int smooth(LINE_INODE line,LINEBUF *buf)
+{LINEBUF tmp; 
+ LINEBUF dest,src1,src2;
+ int i,prev_kept=TRUE;
+ if (line->count==2)
+ { *buf=line->points;
+   line->points->x=2*line->points->x;
+   line->points->y=2*line->points->y;
+   line->points[1].x=2*line->points[1].x;
+   line->points[1].y=2*line->points[1].y;
+   return 2;
+ } 
+ src1=line->points;
+ tmp=malloc(((4*line->count)/3+1)*sizeof(U_POINT));
+ tmp->x=src1->x*2;
+ tmp->y=src1->y*2;
+ dest=tmp+1;
+ *buf=tmp;
+ for(i=line->count-2,src2=src1+1;i>=0;i--,src1++,src2++)
+ { 
+   if (prev_kept)
+   { if (seg_len(src1)<tolerance)
+       {*(dest++)=make_middle_point(src1,src2);prev_kept=FALSE;}
+     else
+     {
+      if (i&&seg_len(src2)<tolerance)
+        {*(dest++)= make_middle_point(src1,src2);prev_kept=FALSE;}
+      else
+        {dest->x=src2->x*2;
+         dest->y=src2->y*2;dest++;
+        }
+      }
+    }
+    else
+    { U_POINT tmp=make_middle_point(src1,src2);
+      dest--;
+      if (((dest-1)->x-dest->x)*(dest->y-tmp.y)==
+         ((dest-1)->y-dest->y)*(dest->x-tmp.x)) *dest=tmp; else *(++dest)=tmp;
+      dest++;
+      if(seg_len(src1)>tolerance)
+       { 
+         if(i&&seg_len(src2)>tolerance)
+          { dest->x=src2->x*2;
+            dest->y=src2->y*2;
+            dest++;
+            prev_kept=TRUE; }  
+       }
+    }
+  }
+ dest->x=src1->x*2;
+ dest->y=src1->y*2; 
+ dest--;
+ if(line->count>4)
+ {
+ if(seg_len(dest)<tolerance) *dest=dest[1]; else dest++;
+ if(seg_len(tmp)<tolerance) *(++tmp)=**buf;
+ } else dest++;
+ free(line->points);
+ line->count=dest-tmp+1;
+ line->points=tmp;
+ return line->count;
+}
+void write_labels(EPP *epp,DGT *dgt)
+{
+}
+
+int main(int argc,char **argv)
+{ struct option longoptions[]={
+  {"tolerance",1,0,'t'},
+  {"margin",0,0,'m'},
+  {"output-file",1,0,'o'},
+  {"labels",0,0,'l'},
+  {"verbose",0,0,'%'},
+  {"margins",0,0,'m'},
+  {"help",0,0,1},
+  {"version",0,0,2},
+  {NULL,0,0,0}};
+  int c,index;
+  int verbose=0;
+  int tolerance=0,draw_frame=1,do_labels=0;
+  char *endptr,outname[1024]="";
+  EPP *epp;
+  while ((c=getopt_long(argc,argv,"t:mo:l%",longoptions,&index))!=-1)
+   switch(c)
+   {
+    case 't':tolerance=strtol(optarg,&endptr,0);
+             if (*endptr||tolerance<0||tolerance>100) 
+               { fprintf(stderr,"Invalalid tolerance value %s\n",optarg);
+                 exit(1);
+               }
+             break;
+    case 'f':draw_frame=0;break;
+    case 'l':do_labels=1;break;
+    case 'm':draw_frame=0;break;
+
+    case '%':verbose=1;break;
+    case 'o':strcpy(outname,default_ext(optarg,".dgt"));
+             break; 
+    case 2:show_version("border","$Revision: 1.1 $");  
+    case 1:
+    default:
+            printf ("Usage:border [-%%][-f][-l][-t value][-o file] file.epp\n");
+            return (c!=1); 
+    }
+   if (optind==argc) { fprintf(stderr,"No input file given\n"); 
+                       exit(1);
+                     }
+   if (!*outname) strcpy(outname,force_ext(argv[optind],".dgt"));
+   epp=open_epp(default_ext(argv[optind],".epp"));
+   if (!epp) {fprintf(stderr,"Cannot open input file %s\n",argv[optind]);
+              exit(1);
+             }
+   install_progress_indicator(verbose?show_percent:check_int);
+   if ((c=clear_progress(
+        border_dgt(epp,outname,draw_frame,tolerance,do_labels))))
+   unlink(outname);
+   return c;
+}
diff --git a/epu/centers.c b/epu/centers.c
new file mode 100644 (file)
index 0000000..3cbd386
--- /dev/null
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "epp.h"
+#include "eppl_ut.h"
+#include <getopt.h>
+void help(int exitcode) {
+   printf("Usage centers [-%%] cluster_file radius_file\n");
+   printf("Table of coordinates and cluster values is written to stdout\n");
+   exit (exitcode);
+}   
+struct center {
+         int row,col;
+         int radius;
+       };
+struct center *table;
+   EPP *cluster_file,*radius_file;
+int check_max_r (int col,int row, int value) {
+  int r=epp_get(radius_file,col,row);
+  struct center *rec = table+value;
+  if (rec->radius<r) {
+    rec->radius=r;
+    rec->row=row;
+    rec->col=col;
+  }  
+  return 0;
+}
+int main(int argc,char **argv) {
+    struct option long_options[]={
+    {"help",0,0,1},
+    {"version",0,0,2},
+    {"verbose",0,0,'%'},
+   }; 
+   int c,index,result,i;
+   int verbose=0;
+   while ((c=getopt_long(argc,argv,"%",long_options,&index))!=-1) {
+      switch(c) {
+         case 2:show_version("centers","$Revision: 1.1 $");
+        case '%':verbose=1;break;
+        case 1:
+        default: help(c==1?0:1);
+      }
+   }   
+   cluster_file = open_epp(default_ext(argv[optind],".epp"));
+   if (!cluster_file) {
+      fprintf(stderr,"Cannot open file %s\n",
+       default_ext(argv[optind],".epp"));
+      exit (2);
+    }
+    optind++;
+    radius_file = open_epp(default_ext(argv[optind],".epp"));
+    if (!radius_file) {
+      fprintf(stderr,"Cannot open file %s\n",
+       default_ext(argv[optind],".epp"));
+      exit (2);
+    }
+    if (!is_aligned(cluster_file,radius_file)) {
+       fprintf(stderr,"Files don't have same coordinate system and cell size\n");
+       exit(2);
+    }   
+    table=calloc((cluster_file->max+1),sizeof(struct center));
+    if (!table) {
+      perror("allocating table");
+      exit(2);
+    }
+    install_progress_indicator(verbose?show_percent:check_int);
+    result=clear_progress(for_each_cell(cluster_file,check_max_r));
+   if (result) {
+      return abs(result);
+   }   
+   for (i=0;i<=cluster_file->max;i++) {
+     if (table[i].radius) {
+       printf ("%5d,%12g,%12g\n",i,alt_x(cluster_file,table[i].col),
+         alt_yc(cluster_file,table[i].row));
+     }
+   }
+   return 0;
+}   
diff --git a/epu/clip.c b/epu/clip.c
new file mode 100644 (file)
index 0000000..807b883
--- /dev/null
@@ -0,0 +1,154 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "epp.h"
+#include "eppl_ut.h"
+#include <getopt.h>
+#include <unistd.h>
+EPP *src,*dest,*mask;
+EPP_LINK lnk;
+ int mask_value=-1;
+ int row1=32767, row2=-32768, col1=32767, col2=-32768;
+void help(int exitcode)
+{
+ printf("Usage: clip [-%%] [-m number] [-o filename] [--help][--version] file mask_file\n"
+"\t--help - displays this message\n"
+"\t--version - shows version number\n"
+"\t-%% --verbose - shows progress indicator\n"
+"\t-m --mask-value - class in mask file, which denotes area to copy.\n"
+"\t\t (default - all onsite classes)\n"
+"\t-o name --output-file=name - sets name of output file\n");
+exit (exitcode);
+}
+int mask_offsite(int class) {
+    return class!=mask->offsite;
+}
+
+int (*mask_func)(int)=mask_offsite;
+int mask_class(int class) {
+    return class==mask_value;
+}
+int fill_cell(int col, int row, int value)
+{
+  if (mask_func(epp_get(mask,col,row))) 
+     return epp_get(src,col,row);
+  else 
+     return value;
+}
+
+int fill_cell_transform(int col, int row, int value)
+{  
+  if (mask_func(epp_get(mask,col,row))) 
+     return epp_get(src,linked_col(lnk,col),linked_row(lnk,row));
+  else 
+     return value;
+}
+
+int find_extent(int col, int row, int value) 
+{  
+  if (mask_func(value)) {
+    if (col<col1) col1=col;
+    if (col>col2) col2=col;
+    if (row<row1) row1=row;
+    if (row>row2) row2=row;
+  }
+  return 0;
+}
+int main(int argc,char **argv)
+{char output_file[1024]="clip.out.epp";
+ struct option long_options[]=
+{ 
+ {"help",0,0,1},
+ {"version",0,0,2},
+ {"mask-value",1,0,'m'},
+ {"verbose",0,0,'%'},
+ {"output-file",1,0,'o'},
+ {NULL,0,0,0}};
+ int index,c;char *endptr;
+ int  x1=32767,y1=32767,x2=-32767,y2=-32767,
+     result,verbose=0;
+ while ((c=getopt_long(argc,argv,"m:%o:",long_options,&index))!=-1)
+ { switch (c)
+   { case 2:show_version("mosaic","$Revision: 1.1 $");
+     case '%':verbose=1;break;
+     case 'm':mask_value=strtol(optarg,&endptr,0);
+         if(*endptr)
+         { fprintf(stderr,"Invalid mask value %s\n",optarg); return 2;
+         } 
+         mask_func=mask_class;
+         break;
+     case 'o':strcpy(output_file,default_ext(optarg,".epp"));break;
+     case  1:
+     case '?':
+     default:
+       help(c!=1);
+   }
+ } 
+  if (argc-optind!=2) { help(1);}
+  src=open_epp(argv[optind]);
+  if (!src) src=open_epp(default_ext(argv[optind],".epp"));
+  if (!src) {
+       fprintf(stderr,"Cannot open file %s\n",argv[optind]);
+       exit(1);
+  }
+  mask=open_epp(argv[optind+1]);
+  if (!mask) mask=open_epp(default_ext(argv[optind+1],".epp"));
+  if (!mask) {
+      fprintf(stderr,"Cannot open file %s\n",argv[optind+1]);
+      exit(1);
+  }
+  if (mask_value>0&&(mask_value<mask->min||mask_value>mask->max)&&
+      mask_value!=mask->offsite) {
+      fprintf(stderr,"No cells with value %d in file %s\n",mask_value,
+          argv[optind+1]);
+      exit(1);
+   }
+  /* determine limits of new file */
+  if (verbose) fprintf(stderr,"Determining output extent\n");
+  install_progress_indicator(verbose?show_percent:check_int);
+  if (for_each_cell(mask,find_extent)!=0) exit(1);
+  fputc('\r',stderr);
+  x1=epp_col(mask,src->XLeft);
+  x2=epp_col(mask,src->XRight)+1;
+  y1=epp_row(mask,src->YTop);
+  y2=epp_row(mask,src->YBottom)+1;
+  if (y1>y2) {
+     int tmp=y1;
+     y1=y2;
+     y2=tmp;
+  }
+  if (x1>x2) { 
+    int tmp=x1;
+    x1=x2;
+    x2=tmp;
+  }
+  row1=y1<row1?row1:y1;
+  row2=y2>row2?row2:y2;
+  col1=x1<col1?col1:x1;
+  col2=x2>col2?col2:x2;
+  if (row1>=row2||col1>=col2) {
+     fprintf(stderr,"No applicable cells found\n");
+     exit(1);
+  }
+  dest=creat_epp(output_file,col1,row1,col2,row2,
+        alt_x(mask,col1),alt_y(mask,row1), alt_x(mask,col2+1),
+        alt_y(mask,row2+1), 100,0, src->offsite);
+   
+   
+  if (!dest) {fprintf(stderr,"Cannot create output file %s\n",output_file);
+              return 2;
+             }
+  if (verbose) fprintf(stderr,"Writing file\n");
+  if (is_aligned(mask,src))
+     result=clear_progress(for_each_cell(dest,fill_cell));
+  else {
+    lnk=link_epp(mask,src);
+    result=clear_progress(for_each_cell(dest,fill_cell_transform));
+    free(lnk);
+  }
+  close_epp(dest);
+  close_epp(src);
+  close_epp(mask);
+  if (result) unlink(output_file);
+  return result;
+}
diff --git a/epu/cluster b/epu/cluster
new file mode 100755 (executable)
index 0000000..29577e3
Binary files /dev/null and b/epu/cluster differ
diff --git a/epu/cluster.c b/epu/cluster.c
new file mode 100644 (file)
index 0000000..5d11e28
--- /dev/null
@@ -0,0 +1,841 @@
+#include <stdio.h>
+#include <string.h>
+#include "epp.h"
+#include "dgt.h"
+#include <math.h>
+#include <unistd.h>
+#include "eppl_ut.h"
+#include <getopt.h>
+#include <stdlib.h>
+
+
+# ifdef __unix 
+#   define EARLY_UNLINK 1
+# endif
+
+#define LABEL_DELTA 16384
+/* step to increase size of labels array */
+#define LABEL_INIT_SIZE 65536
+/* initial size of label array */
+int *labels, last, limit;
+int megabytes=4;
+int line_color=0;
+EPP *epp;/*global pointer to input file for coordinate info access*/
+int new_label()
+{ int tmp;
+  tmp=last;
+  labels[last]=0;
+  if (++last>=limit)
+   { labels=realloc(labels,(limit+=LABEL_DELTA)*sizeof(int));
+     if (!labels)
+     { fprintf(stderr,"Cannot perform realloc()\n");
+      exit(1); 
+     }
+   }
+ return tmp;
+}
+void *check_alloc(size_t size)
+{void *tmp;
+ if (!(tmp=malloc(size)))
+ { fprintf(stderr,"Cannot perform malloc()\n");
+   exit(1);
+ }
+ return tmp;
+}
+unsigned short *alloc_buffer(int width,int *height)
+{int i=0,l=0,h=megabytes*524288/width;
+ unsigned short *buffer;
+ buffer=malloc(h*width*sizeof(short));
+ if (!buffer)
+ { while (l<h)
+   { i=(l+h)>>1;
+     buffer=malloc(i*width*sizeof(short));
+     if (buffer)
+     { free(buffer);
+       l=i+1;
+     }
+    else
+     { h=i-1; }
+   }
+   i--;
+   i=i*3/4;
+   buffer=malloc(i*width*sizeof(short));
+   *height=i;
+ }
+ else
+  *height=h;
+ return buffer;
+}
+void alloc_labels()
+{ labels=check_alloc(LABEL_INIT_SIZE*sizeof(int));
+  limit=LABEL_INIT_SIZE;
+  labels[0]=1;
+  last=1;
+} 
+int check_line(int this,int other)
+{ 
+  return other==line_color;
+}
+int check_border(int this,int other)
+{ 
+  return other!=this;
+}
+
+int base_color(int color)
+{ while (labels[color]<0) color=-labels[color];
+  return color;
+}
+void report_dup(int row,int col,int class1,int class2)
+{ static int dup_count=0;
+  fprintf(stderr,"\r Duplicate label %d:",++dup_count);
+  fflush(stderr);
+  printf("%10g %10g %6d %6d\n",
+  alt_xc(epp,col),alt_yc(epp,row),class1,class2); 
+
+}
+int merge_colors(int color1,int color2,int row,int col)
+{ color1=base_color(color1);
+  color2=base_color(color2);
+  if (labels[color1]&&labels[color2]&&labels[color1]!=labels[color2])
+     report_dup(row,col,labels[color1],labels[color2]);
+  if (color1==color2) 
+    return color1;
+  if (color1<color2) 
+     {labels[color2]=-color1;return color1;}
+  else 
+     {labels[color1]=-color2;return color2;}
+}
+
+int (*is_border)(int this,int other)=check_line;
+
+int first_pass(EPP *fin,EPP *temp1,EPP *temp2, int eight_way,int do_labels)
+{ int nrows,ncol,seqrow,row,col;
+  unsigned short int *in_rp1,*in_rp2;
+  long int *out_rp1,*out_rp2;
+  int i,j,color;
+  unsigned short int *inp1,*inp2;
+  long int *cc; 
+  alloc_labels();
+ /* set up global pointer */
+  epp=fin;
+/* calculate file sizes */
+  ncol=fin->lc-fin->fc;
+  nrows=fin->lr-fin->fr;
+/* Allocating row buffers */
+  in_rp1=check_alloc((ncol+2)*sizeof(short int));
+  in_rp2=check_alloc((ncol+2)*sizeof(short int));
+  out_rp1=check_alloc((ncol+2)*sizeof(long int));
+  out_rp2=check_alloc((ncol+2)*sizeof(long int));
+/* initiliazing row buffers */
+  for(i=0,cc=out_rp2,inp2=in_rp2;i<ncol+2;*(cc++)=0,*(inp2++)=line_color,i++); 
+  out_rp1[0]=0;out_rp1[ncol+1]=0;
+  *in_rp1=in_rp1[ncol+1]=line_color; 
+/* row loop */
+  for (seqrow=1,row=fin->fr;row<fin->lr;seqrow++,row++)
+  {  /*swap output row buffers*/
+    cc=out_rp1;out_rp1=out_rp2;out_rp2=cc;    
+     /* swap input row buffers*/
+    inp1=in_rp1; in_rp1=in_rp2; in_rp2=inp1;
+     /*get input file row */
+    memcpy(in_rp2+1,epp_getline(fin,fin->fc,row),ncol*sizeof(short int));
+    /* position output files */
+    epp_put(temp1,fin->fc,row,1);
+    epp_put(temp2,fin->fc,row,1);
+    /* handle progress indicator */
+    if (*EndLineProc)
+    {int exitcode;
+     if ((exitcode=EndLineProc(row,seqrow,nrows)))
+      { return exitcode; }
+    }
+    /*scan row */
+    for(j=epp->fc,col=1,inp1=in_rp1+1,inp2=in_rp2+1,cc=out_rp2+1;
+         col<=ncol;col++,inp1++,inp2++,cc++,j++)
+     { if (*inp2==line_color) *cc=0;
+       else 
+        /*check for labels with id!=0&&id!=line_color */
+        { if (do_labels&&*inp2) 
+           { int* lptr=labels+base_color(*inp2);
+                if (*lptr) report_dup(row,col,*inp2,*lptr);
+                   else *lptr=*inp2;
+           } 
+          if (is_border(*inp2,*inp1)) color=0; else color= out_rp1[col];  
+          if (!is_border(*inp2,*(inp2-1))) 
+            if (color) 
+              {if(*(cc-1))  
+               color=merge_colors(*(cc-1),color,row,j);
+              }
+           else color=*(cc-1);
+          if (eight_way)
+          { if (!is_border(*inp2,*(inp1-1)))
+             if (color) color=merge_colors(out_rp1[col-1],color,row,j);
+               else color=out_rp1[col-1];
+            if (!is_border(*inp2,*(inp1+1)))
+             if (color) color=merge_colors(out_rp1[col+1],color,row,j);
+              else color=out_rp1[col+1]; 
+          }
+          if (!color)
+          { int j;
+            unsigned short int *this,*next; 
+            /* no color found. Trying to get it from some right cell*/
+            for (this=inp2,next=this+1,j=col;j<=ncol&&
+                   is_border(*this,in_rp1[j]) 
+                 &&!is_border(*this,*next);this++,next++,j++);
+            if (j<=ncol&&!is_border(*this,in_rp1[j])) color=out_rp1[j];
+              else
+              { color=new_label();}
+           } else color=base_color(color);
+         *cc=color;
+        }
+    } /* end of inner loop */
+  /* save out_rp2 */
+  for (i=0,inp1=temp1->row,inp2=temp2->row,cc=out_rp2+1;
+       i<ncol;i++,cc++,inp1++,inp2++)
+  { *inp1=*cc & 0xFFFF;
+    *inp2=*cc >> 16;
+  }     
+ }
+ reset_epp(temp1);
+ reset_epp(temp2);
+ close_epp(fin);
+ free(in_rp1);
+ free(in_rp2);
+ free(out_rp1);
+ free(out_rp2);
+ last--;
+ labels[0]=0;
+ return 0;
+}    
+int remap_labels()
+/* search array of labels to actual numer of clusters */
+/* case where there are no label points */
+{ long int i,j,c=1;
+  for (i=1;i<=last;i++)
+  { j=base_color(i);
+    if (!labels[j])
+     labels[i]=labels[j]=c++;
+    else
+     labels[i]=labels[j];   
+  }   
+  c--;
+  if (c>65535)
+  { fprintf(stderr,"Count of contours exceedes EPPL limit of 65535\n");
+    exit(2);
+  }
+  Create16bit=c>255;
+  printf("Temporary numbers used %d\nContours found %ld\n Output file will be %d-bit\n",
+          last,
+          c,
+          c>255?16:8);
+  return c;        
+}
+int remap_hard_labels()
+/* link temporary numbers with actual labels .
+   mark each temporary contour with no labels by unique number greater than
+   65535 
+   returns count of classes in resulting file.
+   Side effects: label[i] contain value to fill temporary contour i;
+   Create16bit is set appropriate.
+*/
+{ long int i,j,c=65536,unlabelled=0,max=0;
+  for (i=1;i<last;i++)
+  { j=base_color(i);
+    if (!labels[j])
+     { labels[j]=labels[i]=c++;unlabelled++;
+     }
+    else 
+   {
+    labels[i]=labels[j];
+    if (labels[j]>max) max=labels[j];
+   } 
+  }
+  Create16bit=max>255;
+  printf("Temporary numbers used %d\nMaximal class is %ld\nUnlabelled polygons found %ld\n",
+        last,max,unlabelled);
+  return max;    
+}
+int second_pass(EPP *temp1,EPP *temp2,EPP *fout)
+/* creates final clusterized file in case, if no fill rules given
+   file is not from rasterize */
+{int i,row,col,nrows,fc,secondc,exitcode;
+ unsigned short *src1,*src2,*dest;
+ nrows=fout->lr-fout->fr;
+ secondc=(fc=fout->fc)+1;
+ for (i=1,row=fout->fr;row<fout->lr;i++,row++)
+ { if (EndLineProc)
+    if ((exitcode=EndLineProc(row,i,nrows))) return exitcode;
+   epp_put(fout,fc,row,
+      labels[epp_get(temp1,fc,row)|(epp_get(temp2,fc,row)<<16)]);
+   for (col=secondc,src1=epp_getline(temp1,secondc,row),
+                    src2=epp_getline(temp2,secondc,row),
+                    dest=fout->row+1;
+        col<fout->lc;
+        *(dest++)=labels[*(src1++)|(*(src2++)<<16)],col++);   
+ }      
+ close_epp(temp1);
+ close_epp(temp2);
+ return 0;
+}
+void report_unlabelled(int row,int col,int class,int offsite)
+{ int i,*lbl;
+  printf("%g %g unlabelled\n",alt_xc(epp,col),alt_yc(epp,row));
+  for (i=1,lbl=labels+1;i<=last;i++,lbl++)
+   if (*lbl==class) *lbl=offsite;
+}
+void fill_and_save(EPP *fout,EPP *fill, unsigned short *rp1,
+        unsigned short *rp2, unsigned short *rp3, int row)
+{int col=fout->fc,value;
+ for (rp1++,rp2++,rp3++;col<fout->lc;rp1++,rp2++,rp3++,col++)
+  { value=*rp2; 
+    if (!value)
+    switch (epp_get(fill,row,col))
+    { case 1:value=*rp1;break;
+      case 2:value=*(rp2+1);break;
+      case 3:value=*(rp1+1);break;
+      case 4:value=*(rp3);break;
+      case 6:value=*(rp3+1);break;
+      case 8:value=*(rp2-1);break;
+      case 9:value=*(rp1-1);break;
+      case 12: value=*(rp3-1);break;
+     }
+    epp_put(fout,col,row,value?value:fout->offsite);
+  }  
+}
+int second_pass_fill(EPP *temp1,EPP *temp2,EPP *fill,EPP *fout)
+{unsigned short *rp1,*rp2,*rp3,*rtmp;
+ int i,row,col,ncols,nrows,fc,secondc,exitcode,value;
+ unsigned short *src1,*src2,*dest;
+ nrows=fout->lr-fout->fr;
+ secondc=(fc=fout->fc)+1;
+ ncols=fout->lc-fout->fc+2;
+ /*set global pointer */
+ epp=fout;
+ /* allocate buffers */
+ rp1=check_alloc(ncols*sizeof(short int));
+ rp2=check_alloc(ncols*sizeof(short int));
+ rp3=check_alloc(ncols*sizeof(short int));
+ for(i=0,rtmp=rp2;i<ncols;i++,*(rp1++)=fout->offsite);
+ *rp1=rp1[ncols-1]=*rp3=rp3[ncols-1]=fout->offsite;
+ for (row=fout->fr,i=1;row<fout->lr;i++,row++)
+ {  if (EndLineProc)
+    if ((exitcode=EndLineProc(row,i,nrows))) return exitcode;
+    for (col=fout->fc,
+           dest=rp3+1,
+           src1=epp_getline(temp1,fc,row),
+           src2=epp_getline(temp2,fc,row);
+         col<fout->lc;
+         dest++,src1++,src2++,col++)
+      {value=labels[*src1|(*src2<<16)];
+       if (value>65535)
+         report_unlabelled(row,col,value,*dest=fout->offsite);
+        else *dest=value==65534?0:value;
+      }
+     if (row>fout->fr) fill_and_save(fout,fill,rp1,rp2,rp3,row-1);
+    rtmp=rp1;
+    rp1=rp2; rp2=rp3; rp3=rtmp;
+   }
+  fill_and_save(fout,fill,rp1,rp2,rp3,fout->lc-1);   
+  close_epp(temp1);
+  close_epp(temp2);
+  close_epp(fill);
+  return 0;
+}
+/* rasterize should fill this variables near its beginning */
+int right_border, bottom_border, nrow, ncol,half_vert,half_horiz;
+int dgt2col(int x)
+{ return (((unsigned long)(x+32767))*ncol)/right_border;
+}
+int dgt2absrow(int y)
+{
+ return (((unsigned long)(32767-y))*nrow)/bottom_border+1;
+}
+int absrow2dgt(int row)
+{
+  return 32767-((long)((unsigned long)(row-1)*bottom_border/nrow));
+}
+#define CELL(buf,row,col) *(buf+row*width+col)
+#define row2dgt(row) (absrow2dgt(row+firstrow))
+#define dgt2row(y) (dgt2absrow(y)-firstrow)
+
+int save_buffer(EPP *epp,unsigned short *buf,int firstrow,int lastrow,int width)
+{unsigned short *b; int row;
+ for (row=firstrow,b=buf;row<lastrow;row++,b+=width)
+ { 
+   epp_put(epp,1,row,epp->offsite);
+   memcpy(epp->row,b,width*sizeof(short));
+   if (EndLineProc)    
+      {
+       if  ((*EndLineProc)(row,row,nrow)) return -1;
+      }
+
+ }
+ return 0;
+}
+
+
+
+int rasterize(DGT *dgt,EPP *fout,EPP *fill,int modulo,int divisor)
+{unsigned short *buf,*fillbuf=NULL;
+ int width,height,firstrow,lastrow,fry,lry;
+ width=fout->lc-fout->fc;
+ ncol=width;
+ nrow=fout->lr-fout->fr;
+ right_border=(fout->XRight-fout->XLeft)/(dgt->XRight-dgt->XLeft)*65535;
+ bottom_border=(fout->YBottom-fout->YTop)/(dgt->YBottom-dgt->YTop)*65535;
+ half_horiz=right_border>>1;
+ half_vert=bottom_border>>1;
+ buf=alloc_buffer(width,&height);
+ if (fill) 
+   { 
+     height>>=1; 
+     fillbuf=buf+height*width;
+   }
+ firstrow=fout->fr;
+ lastrow=fout->fr+height;
+ do {
+ if (lastrow>fout->lc) lastrow=fout->lc;
+ memset(buf,0,width*height*sizeof(short));
+ if (fill) memset(fillbuf,0,width*height*sizeof(short));
+ reset_dgt(dgt);
+ fry=absrow2dgt(firstrow);
+ lry=absrow2dgt(lastrow);
+ while (!dgt_eof(dgt))
+   { if (dgt_is_point(dgt))
+     { int y,id,row,col;
+        if ((y=dgt_pointy(dgt))<lry&&(y>=fry))
+         { if (divisor) id=(dgt_id(dgt)%modulo)/divisor;
+                else  id=dgt_id(dgt);
+           if (id>65533) 
+             { fprintf(stderr,"Label ID too large. Use -d or -x options\n");
+               return 1;
+             }  
+           if (!id) id=65534;
+           row=dgt2row(dgt_pointx(dgt));
+           col=dgt2col(y);
+           if (CELL(buf,row,col)) 
+            { printf("%g %g more than one object in same cell\n",alt_xc(fout,col),alt_yc(fout,row));
+            }
+           CELL(buf,row,col)=id;
+         }
+     }
+     else
+     { if (dgt_yt(dgt)>lry&&dgt_yb(dgt)<fry)
+        { int i,id,x,y;
+           POINT *start,*end,p1,p2;
+          if (fill) id=line_color;
+           else 
+          {    if (divisor) id=(dgt_id(dgt)%modulo)/divisor;
+                else  id=dgt_id(dgt);
+              if (id>65533) 
+              { fprintf(stderr,"Line ID too large. Use -d or -x options\n");
+                 return 1;
+              }
+              if (!id) id=65534;
+           }
+          /* Now we can begin an actual drawing */
+          for (i=1,start=dgt->buffer->s,end=dgt->buffer->s+1;
+            i<dgt_line_len(dgt);i++,start++,end++)
+            if((start->y>lry&&end->y<fry)||(start->y<fry&&end->y>lry))
+             { POINT rc1,rc2;
+                if (start->y>end->y) {p1=*end;p2=*start;}
+                  else 
+                 {p1=*start;p2=*end;}
+                if (p1.y<lry) 
+                 {int xx=(lry-p1.y)*((int)p2.x-p1.x)/((int)p2.y-p1.y)+p1.x;
+                  p1.x=xx;
+                  p1.y=lry;
+                 }
+                if (p2.y>fry) 
+                {int xx=(fry-p1.y)*((int)p2.x-p1.x)/((int)p2.y-p1.y)+p1.x;
+                 p2.x=xx;
+                 p2.y=fry;
+                }
+                rc2.x=dgt2col(p1.x);
+                rc2.y=dgt2row(p1.y);
+                rc1.x=dgt2col(p2.x);
+                rc1.y=dgt2row(p2.y);
+                if(rc2.x==rc1.x&&rc2.y==rc1.y)
+                { CELL(buf,rc1.y,rc1.x)=id;
+                  if (fill) CELL(buf,rc1.y,rc1.x)|=2;
+                }
+                else  
+                 if ((unsigned long)abs((int)p1.x-p2.x)*bottom_border>(unsigned long)abs((int)p1.y-p2.y)*right_border)
+                    { /* ïÔÒÅÚÏË ÛÉÒÅ ÞÅÍ ÄÌÉÎÎÅÅ */
+                      int xn,ndx,dy;
+                      if (rc1.x>rc2.x) 
+                       { POINT tmp=rc1;
+                         rc1=rc2;
+                         rc2=tmp;
+                         tmp=p1;
+                         p1=p2;
+                         p2=tmp;
+                       }
+                      xn=((int)p1.x+32767)*ncol-half_horiz;
+                      ndx=((int)p2.x-p1.x)*ncol;
+                      dy=(int)p2.y-p1.y;
+                      for (x=rc1.x;x<=rc2.x;x++)
+                      { unsigned long ybig=(32767UL-((right_border*x-xn)*dy/ndx+p1.y))*nrow;
+                        y=ybig/bottom_border+1-firstrow;
+                        CELL(buf,y,x)=id;
+                        if (fill)
+                         {
+                           CELL(fillbuf,y,x)|=ybig%bottom_border>half_vert?4:1;
+                         } 
+                      }
+                    }
+                   else
+                  {int yn,ndy,dx;
+                   yn=(32767-(int)p1.y)*nrow-half_vert;
+                   ndy=((int)p2.y-p1.y)*nrow; 
+                   dx=(int)p2.x-p1.x;
+                   for (y=rc1.y;y<=rc2.y;y++)
+                    { unsigned long xbig=(32767UL+((yn-bottom_border*
+                      (y-1+firstrow))*dx /ndy+p1.x))*ncol;
+                     x=xbig/right_border;
+                     CELL(buf,y,x)=id;
+                     if (fill) {
+                      CELL(fillbuf,y,x)|=xbig%right_border>half_horiz?8:2;
+                      }
+                    }
+                  }
+                 }
+               
+              
+        }
+     }
+     dgt_next(dgt); 
+   }
+ if (save_buffer(fout,buf,firstrow,lastrow,width)) {free(buf);return 1;};
+ if (fill)
+   if (save_buffer(fill,fillbuf,firstrow,lastrow,width)) {free(buf);return 1;};
+ firstrow+=height;
+ lastrow+=height;
+ } while(firstrow<fout->lc); 
+ free(buf);
+ return 0;
+}
+void extract_digits(int base,char *s,int *divisor,int *modulo)
+{char *c;
+ *divisor=0;
+ *modulo=0;
+ for (c=s;*c;c++)
+  switch(*c)
+  {case '_':if (*modulo&&!*divisor)*divisor=base; 
+        else
+               *divisor*=base; 
+      *modulo*=base;
+      break;
+  case 'x':if(!*modulo) *modulo=base; 
+            else *modulo*=base;
+      if (*divisor) {fprintf(stderr,"Digits in -d or -x option must form continous range\n");
+      exit(1);
+      }
+      break;
+  default: fprintf(stderr,"Parameter of -d or -x option must consist of ``x''-es\n"
+"for each digit to use and ``_'' for each digit to ignore\n");
+  exit(1);
+  }
+ if (*divisor==0) *divisor=1;
+ if (*modulo/ *divisor>0x10000)
+ { fprintf(stderr,"EPP file classes cannot contain more than four digits\n");
+   exit(1);
+ } 
+}   
+
+# ifndef EARLY_UNLINK
+
+char __tempnames[4][80];
+char *tempnames[]={__tempnames[0],__tempnames[1],__tempnames[2],__tempnames[3]};
+char **tempptr=tempnames;
+void store_temp_name(char *name)
+{strcpy(*(tempptr++),name);
+}
+void remove_temp_files()
+{while(--tempptr>=tempnames)
+  { unlink(*tempptr);
+  }
+}
+
+# endif
+char cluster_help[]=
+"Usage: cluster [--help] [-version] [-%%8lu] [-o file] [-c color] file\n";
+char rasterize_help[]=
+"Usage: rasterize [--help] [-version] [-o file] [-c color] [-s size]\n"
+"\t[-x string] [-d string] [-m megabytes] [-%%pu] file\n";
+
+int main(int argc,char **argv)
+{struct option cluster_options[]={
+ {"help",0,0,1},
+ {"version",0,0,2},
+ {"verbose",0,0,'%'},
+ {"output-file",1,0,'o'},
+ {"line-color",1,0,'c'},
+ {"8-way",0,0,'8'},
+ {"rasterize",0,0,'R'},
+ {"labels",0,0,'l'},
+ {"unuque",0,0,'u'},
+ {NULL,0,0,0}},
+ rasterize_options[]={
+ {"help",0,0,1},
+ {"version",0,0,2},
+ {"verbose",0,0,'%'},
+ {"output-file",1,0,'o'},
+ {"cell-size",1,0,'s'},
+ {"line-color",1,0,'c'},
+ {"line-point",0,0,'p'},
+ {"digits",1,0,'d'},
+ {"hex-digits",1,0,'x'},
+ {"unique",0,0,'u'},
+ {"memory",1,0,'m'}, 
+ {NULL,0,0,0}},
+ *options=cluster_options;
+ int c,index,expect_vector=0;
+ char c_opt[]="%o:c:8Rlu",
+      r_opt[]="%o:c:s:pudxm:",
+    *optstring=c_opt;
+ char    *basename;
+ char tempname[1024],outname[1024]="";
+ int verbose=0,eight_way=0,do_labels=0,result,maxclass;
+ EPP *fin,*ffill=NULL,*ftmp1,*ftmp2,*fout;
+ int modulo=0,divisor=0; 
+ int (*remap)(void)=remap_labels;
+ double cell_size=0.0;
+ if ((basename=strrchr(argv[0],'/')))
+  basename++; else basename=argv[0];
+ if (!strcmp(basename,"rasterize"))
+  { optstring=r_opt; options=rasterize_options;
+    expect_vector=1;
+    remap=remap_hard_labels;
+    do_labels=1;
+  }
+ while ((c=getopt_long(argc,argv,optstring,options,&index))!=-1)
+   switch (c)
+   {
+    case '%' :verbose=1;break;
+    case 2  : show_version("cluster","$Revision: 1.1 $");
+    case 'o':strcpy(outname,default_ext(optarg,".epp"));break;
+    case 'R':optstring=r_opt;options=rasterize_options;
+             remap=remap_hard_labels;
+             do_labels=1;
+              expect_vector=1;break;
+    case 'c':{char *endptr;
+              line_color=strtol(optarg,&endptr,0);
+              if (*endptr||line_color<=0||line_color>65535) 
+               { fprintf(stderr,"Invalid line color %s\n",optarg);
+                 exit(1);
+               }
+              break;
+              } 
+    case 'u':if (!expect_vector) is_border=check_border;
+             else {remap=remap_labels;do_labels=0;}
+             break;
+    case '8':if (expect_vector)
+             {fprintf(stderr,"option -8 is valid only in cluster mode\n");
+              exit(1);
+             }
+             eight_way=1;
+             break;
+    case  'l':if (expect_vector)
+             {fprintf(stderr,"option -l is valid only in cluster mode\n");
+              exit(1);
+             }
+             remap=remap_labels;do_labels=1;
+             break;
+    case 's':if (!expect_vector)
+             {fprintf(stderr,"option -%c is valid only in rasterize mode\n",c);
+              exit(1);
+             }else
+             {char *endptr;
+               cell_size=strtod(optarg,&endptr);
+               if (*endptr)
+                { fprintf(stderr,"Invalid cell size value %s\n",optarg);
+                  exit(1);
+                }
+              }
+              break; 
+    case 'p': if (!expect_vector)
+             {fprintf(stderr,"option -%c is valid only in rasterize mode\n",c);
+              exit(1);
+             }
+             expect_vector=2;
+             break;    
+    case 'd':if (!expect_vector)
+             {fprintf(stderr,"option -%c is valid only in rasterize mode\n",c);
+              exit(1);
+             }
+             extract_digits(10,optarg,&divisor,&modulo);
+             break;
+    case 'x':if (!expect_vector)
+             {fprintf(stderr,"option -%c is valid only in rasterize mode\n",c);
+              exit(1);
+             }
+             extract_digits(16,optarg,&divisor,&modulo);
+             break; 
+    case 'm':if (!expect_vector)
+             {fprintf(stderr,"option -%c is valid only in rasterize mode\n",c);
+              exit(1);
+             }else
+             {char *endptr;
+              megabytes=strtol(optarg,&endptr,0);
+              if (*endptr)
+              { fprintf(stderr,"Invalid integer value %s\n",optarg);
+              
+              exit(1);
+              }
+              }
+             break;   
+    case 1:
+    case '?':
+    default: printf(expect_vector?rasterize_help:cluster_help);
+             exit(c!=1);
+   }
+ /***********************************************************/
+ if (argc==optind)
+ {fprintf(stderr,"No input file name given\n");
+  exit(1);
+ }
+ strcpy(tempname,default_ext(argv[optind],expect_vector?".dgt":".epp"));
+ if (!*outname)
+  if (expect_vector) strcpy(outname,force_ext(tempname,".epp"));
+   else  
+# ifdef __unix
+    strcpy(outname,"cluster.out.epp");
+# else
+    strcpy(outname,"cluster.epp");
+# endif          
+  install_progress_indicator(verbose?show_percent:check_int);
+ /*** Zero pass,rasterizing **********************************/
+ if (expect_vector)
+ {DGT *dgt=open_dgt(tempname);
+  int rows,cols;
+  double XR,YB;
+  if (!dgt) { fprintf(stderr,"Cannot open file %s\n",tempname);
+              exit(1);
+            }
+  /*calculating file dimensions*/
+  if (cell_size==0.0)
+  { /*no cell size given, defaulting to 1024 cells/line*/
+    cell_size=fabs(dgt->XRight-dgt->XLeft)/1024.0;
+  } 
+  cols=ceil(fabs(dgt->XRight-dgt->XLeft)/cell_size);
+  rows=ceil(fabs(dgt->YTop-dgt->YBottom)/cell_size);
+  XR=cols*cell_size;
+  if (dgt->XRight<dgt->XLeft) XR=dgt->XLeft-XR;
+   else XR+=dgt->XLeft;
+  YB=rows*cell_size;
+  if (dgt->YTop>dgt->YBottom) YB=dgt->YTop-YB;
+   else YB+=dgt->YTop;
+  fprintf(stderr,"EPP file would be %d rows by %d columns\n",rows,cols);
+  /*creating outputfile*/
+  Create16bit=1;
+  if(expect_vector==1)
+  { /*rasterized file would be temporary */
+    line_color=65535;
+    strcpy(tempname,force_ext(tmpnam(NULL),".epp"));  
+  } else
+   strcpy(tempname,outname);    
+  fin=creat_epp(tempname,1,1,cols,rows,dgt->XLeft,dgt->YTop,XR,YB,
+            100,0,0);
+
+  if (!fin) {fprintf(stderr,"Cannot create file %s\n",tempname);
+               exit(1);
+            }
+  if (expect_vector==1)
+   { Create16bit=0;
+#ifdef EARLY_UNLINK
+     unlink(tempname);
+#else
+     store_temp_name(tempname);
+#endif     
+     strcpy(tempname,force_ext(tmpnam(NULL),".epp"));
+     ffill=creat_epp(tempname,1,1,cols,rows,dgt->XLeft,dgt->YTop,XR,YB,
+         100,0,0);
+     if (!ffill) {fprintf(stderr,"Cannot create file %s\n",tempname);
+          exit(1);
+                 }
+#ifdef EARLY_UNLINK
+     unlink(tempname); 
+#else
+     store_temp_name(tempname);
+#endif
+   }  
+  if (verbose) fprintf(stderr,"Rasterizing...\n");
+  if ((result=rasterize(dgt,fin,ffill,modulo,divisor))) 
+        exit(clear_progress(result));
+  close_dgt(dgt);
+  if (expect_vector==2)
+    { /* nothing more to do - close and exit */
+     if (fin->max<=255)
+      {
+        if (verbose) fprintf(stderr,"\rConverting to 8 bit\n");
+#ifdef EARLY_UNLINK
+        unlink(outname);
+        fast_convert_to_8bit(fin,outname);
+#else
+        strcpy(tempname,force_ext(outname,".8bi"));
+        fast_convert_to_8bit(fin,tempname);
+        unlink(outname);
+        rename(tempname,outname);
+#endif 
+       } else close_epp(fin);
+      exit(clear_progress(result));
+    }
+  else
+   { reset_epp(fin);
+     reset_epp(ffill);
+   } 
+ } else
+  if (!(fin=open_epp(tempname)))
+  { fprintf(stderr,"Cannot open file %s",tempname);
+    exit(1);
+  }
+/*************** First pass -- counting unique contours ***************/
+if (verbose) fprintf(stderr,"\rAssembling polygons...\n");
+  Create16bit=1;
+      strcpy(tempname,force_ext(tmpnam(NULL),".epp"));
+  if(!(ftmp1=creat_epp_as(tempname,fin)))
+  { fprintf(stderr,"Cannot create file %s\n",tempname);
+    exit(1);
+  }  
+#ifdef EARLY_UNLINK
+  unlink(tempname);
+#else
+  store_temp_name(tempname);
+#endif
+      strcpy(tempname,default_ext(tmpnam(NULL),".epp"));
+  if(!(ftmp2=creat_epp_as(tempname,fin)))
+  { fprintf(stderr,"Cannot create file %s\n",tempname);
+    exit(1);
+  }  
+#ifdef EARLY_UNLINK
+ unlink(tempname);
+#else
+  store_temp_name(tempname);
+#endif
+ if (!expect_vector&&(is_border==check_border))line_color=fin->offsite;
+ if((result=first_pass(fin,ftmp1,ftmp2,eight_way,do_labels)))
+  exit(clear_progress(result));
+/**** creating correspondence table *************/
+ if (verbose) {fputc('\r',stderr);fflush(stderr);}
+ maxclass=remap();
+/************* Second pass -- creating final file *****************/
+fout=creat_epp_as(outname,ftmp1);
+if (do_labels) fout->offsite=Create16bit?65535:255;
+if (verbose) fprintf(stderr,"\rWriting final file...\n");
+if (ffill)
+ result=second_pass_fill(ftmp1,ftmp2,ffill,fout);
+else
+ result=second_pass(ftmp1,ftmp2,fout);
+ fout->max=maxclass;
+close_epp(fout);
+#ifndef EARLY_UNLINK
+ remove_temp_files();
+#endif
+return(clear_progress(result));
+} 
diff --git a/epu/dgt2gen b/epu/dgt2gen
new file mode 100755 (executable)
index 0000000..699239d
Binary files /dev/null and b/epu/dgt2gen differ
diff --git a/epu/dgt2gen.c b/epu/dgt2gen.c
new file mode 100644 (file)
index 0000000..9329ea5
--- /dev/null
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <unistd.h>
+#include "dgt.h"
+#include "math.h"
+#include "eppl_ut.h"
+#include <getopt.h>
+FILE *lines,*points;
+long int linecount=0,pointcount=0;
+char line_feed[3]="\n";
+void putreal(FILE *f,double x)
+{ 
+  if (fabs(x)>1000000000.0||fabs(x)<0.01)
+   fprintf(f,"%13E",x);
+  else
+  if (fabs(x)<10.0)
+   fprintf(f,"%13.10f",x);
+  else
+  if (fabs(x)<1000.0)
+   fprintf(f,"%13.8f",x);
+  else if(fabs(x)<1000000.0)
+   fprintf(f,"%13.5f",x);
+  else
+   fprintf(f,"%13.2f",x);
+}
+void putpoint(FILE *f,DGT *dgt,POINT p)
+{ putreal(f,real_x(dgt,p.x));
+  fputc(' ',f);
+  putreal(f,real_y(dgt,p.y));
+  fputs(line_feed,f);
+}
+
+void putline(DGT* dgt)
+{int i;
+ fprintf(lines,"%ld%s",dgt_id(dgt),line_feed);
+ for(i=0;i<dgt_line_len(dgt);i++)
+  putpoint(lines,dgt,dgt_node(dgt,i));
+ fprintf(lines,"END%s",line_feed);
+ linecount++;
+}
+
+void putlabel(DGT *dgt)
+{ fprintf(points,"%ld ",dgt_id(dgt));
+  putpoint(points,dgt,dgt_point(dgt));
+  pointcount++;
+}
+void close_gen(const char *name,FILE *f,int count)
+{if (count)
+ {fprintf(f,"END%s",line_feed);
+  fclose(f);
+ } else { fclose(f); unlink(name);}
+}
+void do_nothing(char c)
+{
+}
+void print_count(char c)
+{ fprintf(stderr,"Exported %ld lines,%ld labels%c",linecount,pointcount,c);
+  fflush(stderr);
+}
+void (*show_done)(char c)=do_nothing;
+void help(void)
+{printf("Usage:\n\t dgt2gen [-o filename] [-r] [-v] file\n"
+        "\t -o filename gives template for output file names (suffixess\n\t\tgen and gpn would be appended"
+        "\t -r forces MS-DOS like linefeeds (\\r\\n instead of just \\n\n"
+        "\t -v reports progress after each item converted\n");
+} 
+
+void write_item(DGT *dgt)
+{ if (dgt_is_line(dgt)) putline(dgt); else putlabel(dgt);
+  show_done('\r');
+}
+int main (int argc,char **argv)
+{ char pointname[1024]="",linename[1024]="";
+  struct option longopt[]={
+                    {"output-file",1,0,'o'},
+                    {"help",0,0,1},
+                    {"version",0,0,2},
+                    {"dos-linefeeds",0,0,'r'},
+                    {"verbose",0,0,'v'},
+                    {NULL,0,0,0},
+                  };
+  int c,index;
+  DGT *d;
+  while((c=getopt_long(argc,argv,"o:rv",longopt,&index))!=-1)
+   switch(c)
+   { case 2: show_version("dgt2gen","$Revision: 1.1 $");
+     case 'r': strcpy(line_feed,"\r\n");break;
+     case 'v': show_done=print_count;break;
+     case 'o': strcpy(pointname,force_ext(optarg,".gpn"));
+               strcpy(linename,force_ext(optarg,".gen"));
+               break;
+     case '1':
+     case '?':
+     default: if (c!=1) fprintf(stderr,"Invalid options\n");
+              help();
+              exit(c!=1);
+   }
+   if (argc==optind) {fprintf(stderr,"No file name supplied\n");
+                      help();
+                      exit(1);
+                     }
+   if (!(d=open_dgt(default_ext(argv[optind],".dgt"))))
+   {fprintf(stderr,"Cannot open file:%s\n",default_ext(argv[optind],".dgt"));
+    exit(1);
+   }
+  if (!*linename)
+  { strcpy(linename,force_ext(argv[optind],".gen"));  
+    strcpy(pointname,force_ext(argv[optind],".gpn"));
+  }
+  if(!(lines=fopen(linename,"wb")))
+  {fprintf(stderr,"Cannot create file:%s\n",linename);
+   exit(1);
+  }
+  if(!(points=fopen(pointname,"wb")))
+  { fprintf(stderr,"Cannot create file:%s\n",pointname);
+    fclose(lines);
+    unlink(linename);
+  }
+  for_each_item(d,write_item);
+  close_dgt(d);
+  close_gen(linename,lines,linecount);
+  close_gen(pointname,points,pointcount);
+  print_count('\n');
+  return (0);
+}   
+                     
+             
+
diff --git a/epu/eheader.c b/epu/eheader.c
new file mode 100644 (file)
index 0000000..6aa0fad
--- /dev/null
@@ -0,0 +1,564 @@
+
+/* This program edits header of EPP file */
+#include <eppl.h>
+/*#define LSB_FIRST 1*/
+#ifdef LSB_FIRST
+/* portability issues when reading binary files */
+/* define LSB_FIRST, when your processor uses Intel byte order */
+# define COPY_DOUBLE(x) x
+# define COPY_LONG(x) x
+# define COPY_SHORT(x) x
+#else
+# define COPY_DOUBLE(x) swapdouble(x)
+# define COPY_LONG(x)  swaplong(x)
+# define COPY_SHORT(x) swapshort(x)
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define DO_XSHIFT 1
+#define DO_YSHIFT 2
+#define DO_SCALE 4
+#define RESCALING 7
+#define SET_X_LEFT 0x10
+#define SET_X_RIGHT 0x20
+#define SET_Y_BOTTOM 0x40
+#define SET_Y_TOP 0x80
+#define SET_PRJ 8
+#define DGT_OPS 0xFF
+#define EXPLICIT_COORDS 0xF0
+#define SET_FR 0x100
+#define SET_FC 0x200
+#define EXPLICIT_ROW_COL 0x300
+#define DO_ALIGN 0x400
+#define SET_AREA 0x800
+#define SET_COMMENT 0x1000
+#define SET_UNIT 0x2000
+#define SET_OFFSITE 0x4000
+#define VERBOSE_MODE 0x8000
+#define MAX_PROJECTION 3
+#define MAX_UNIT 5
+
+long operations=0;/* Bit mask of operations to apply */
+void usage(int return_code)
+{ printf(
+"Usage eheader options files\n\
+where options may be:\n\
+These are applicable to both EPP and DGT files:\n\
+-x n  - shifts alternative x by n\n\
+-y n  - same with alternative y\n\
+-s factor - multiplies all coordinates by factor\n\
+-Xl n - sets alternative x of left border to specified value\n\
+-Xr n - same with right border\n\
+-Yb n, Yt - same with bottom and top y\n\
+-p xxx - set projection type, where projection can be:\n\
+\tnone - cause EPPL ver 3 to say \"No alternate coordinates\"\n\
+\tutm - UTM projection\n\
+\tstplate - state plane\n\
+\tll - geographic coordinates\n\
+Following is applicable to EPP files only:\n\
+-o n - set offsite value\n\
+-fr n - set first row to n\n\
+-fc n - set first column to n\n\
+-A filename - align to specified file\n\
+-a n - set cell area\n\
+-c \"string\" - set description\n\
+-u xxx - set area unit type, where unit type may be:\n\
+\tnone - cause EPPL ver 3 to say \"No alternate coordinates\"\n\
+\tft  - square feet\n\
+\tm - square meters\n\
+\tkm - square kilometers\n\
+\tmile - square miles\n\
+\tha - hectares\n\
+\tacre - acres\n");
+   exit(return_code);
+}
+
+int get_epp_header(FILE *f,EPPHEADER *hdr);
+int put_epp_header(FILE *f,EPPHEADER *hdr);
+int get_dgt_header(FILE *f,EPPHEADER *hdr,long *maxline,long *maxpt);
+int put_dgt_header(FILE *f,EPPHEADER *hdr);
+void main(int argc,char **argv)
+{ int i=1;
+  char *progname;
+        int option(int *num,char **argv);
+       void process_file(const char *filename);
+        void read_align_values(const char *filename);
+       if (argc==1) usage(0);
+progname=strrchr(argv[0],'/');
+if (progname==NULL) progname=argv[0];
+else progname++;
+  if (!strcmp(progname,"maplist"))
+    operations|=VERBOSE_MODE;
+  else
+  if (!strcmp(progname,"mapalign"))
+  { operations|=DO_ALIGN;
+    if (!strcmp(argv[1],"-v")) {operations|=VERBOSE_MODE;i++;}
+    read_align_values(argv[i++]); 
+    if (!strcmp(argv[i],"-v")) {operations|=VERBOSE_MODE;i++;}
+  }
+ else
+     while (argv[i]&&(argv[i][0]=='-'))
+        { if (!option(&i,argv))
+               { fprintf(stderr,"Unknown option :%s\n",argv[i]);
+                        exit(1);
+                }
+        }
+        for(;i<argc;i++)
+        { process_file(argv[i]);
+        }
+}
+/* global variables - parameters of transformation */
+char header[33];
+double x_shift,y_shift,scale_fact,area_val,XLeft,XRight,YTop,YBottom;
+long fr,fc,proj,unit,offsite;
+struct ALIGN_VALUES
+   { double XLeft,YBottom,XRight,YTop;
+     int fr,fc,lr,lc;
+   } align_val;
+double double_value(const char *s)
+
+{ char *errcheck=NULL;
+  double tmp;
+  tmp=strtod(s,&errcheck);
+  if (errcheck&& *errcheck )
+  { fprintf(stderr,"Invalid number : %s\n",s);
+    exit(1);
+  }
+  return tmp;
+}
+void check_key(char *keytext,int this_key,int incompatible_keys)
+{ if (operations & incompatible_keys)
+  { fprintf(stderr,"Option %s is incompatible with prevoius\n",keytext);
+   exit(1);
+  }
+  operations|=this_key;
+}
+long int_value(const char *s)
+{ long tmp;
+  if (!sscanf(s,"%ld",&tmp))
+   { fprintf(stderr,"Invalid integer %s\n",s);
+      exit(1);
+    }
+ return tmp;
+}
+void read_align_values(const char *filename)
+{ FILE *f;EPPHEADER hdr;
+  f=fopen(filename,"rb");
+  if (NULL==f)
+  { fprintf(stderr,"Error open file %s\n",filename);
+    exit(1);
+  }
+ if (!get_epp_header(f,&hdr))
+ { fprintf(stderr,"%s is invalid EPP file\n",filename);
+   fclose(f);
+   exit(1);
+ }
+ fclose(f);
+ align_val.XLeft=hdr.fcx;
+ align_val.XRight=hdr.lcx;
+ align_val.YTop=hdr.fry;
+ align_val.YBottom=hdr.lry;
+ align_val.fc=hdr.fc;
+ align_val.fr=hdr.fr;
+ align_val.lc=hdr.lc;
+ align_val.lr=hdr.lr;
+}
+int option(int *num,char **argv)
+{ if (argv[*num][0]!='-') return 0;
+  switch (argv[*num][1])
+        { case 'x': { check_key(argv[*num],DO_XSHIFT,EXPLICIT_COORDS);
+                      x_shift=double_value(argv[++(*num)]);
+                      break;
+                   }
+         case 'y':  {
+                     check_key(argv[(*num)],DO_YSHIFT,EXPLICIT_COORDS);
+                      y_shift=double_value(argv[++(*num)]);
+                      break;
+                    }
+        case 'X': { switch ((argv[(*num)])[2])
+                    { case 'l':
+                      case 'L': { check_key(argv[(*num)],SET_X_LEFT,RESCALING);
+                                  XLeft=double_value(argv[++(*num)]);
+                                  break;
+                                }
+                      case 'r':
+                      case 'R': { check_key(argv[(*num)],SET_X_RIGHT,RESCALING);
+                                  XRight=double_value(argv[++(*num)]);
+                                  break;
+                                }
+                      default:
+                         { fprintf(stderr,"Invalid option %s\n",argv[(*num)]);
+                            exit(1);
+                          }
+                    }
+                    break;
+                  }
+        case 'Y': { switch ((argv[(*num)])[2])
+                    { case 'b':
+                      case 'B': { check_key(argv[(*num)],SET_Y_BOTTOM,RESCALING);
+                                  YBottom=double_value(argv[++(*num)]);
+                                  break;
+                                }
+                      case 't':
+                      case 'T': { check_key(argv[(*num)],SET_Y_TOP,RESCALING);
+                                  YTop=double_value(argv[++(*num)]);
+                                  break;
+                                }
+                      default:
+                         { return 0;
+                          }
+                    }
+                    break;
+                  }
+
+        case 'p': { check_key(argv[(*num)],SET_PRJ,0);
+                    (*num)++;
+                    if (!strcmp(argv[(*num)],"none"))
+                     { proj=0; }
+                    else
+                    if (!strcmp(argv[(*num)],"utm"))
+                     { proj=1; }
+                   else
+                   if (!strcmp(argv[(*num)],"UTM"))
+                    { proj=1; }
+                   else
+                    if (!strcmp(argv[(*num)],"stplane"))
+                     { proj=2; }
+                    else
+                    if (!strcmp(argv[(*num)],"ll"))
+                     { proj=3; }
+                    else
+                    { fprintf(stderr,"Invalid projection name %s\n",argv[(*num)]);
+                      exit(1);
+                   }
+                   break;
+                  }
+        case 'o': { check_key(argv[(*num)],SET_OFFSITE,0);
+                   offsite=int_value(argv[++(*num)]);
+                   if (offsite>32767) offsite=65536-offsite;
+                   if (offsite<-32768)
+                   { fprintf(stderr,"Invalid offsite value %s\n",argv[*num]);
+                     exit(1);
+                   }
+                    break;
+                 }
+  case 's' : { check_key(argv[(*num)],DO_SCALE,EXPLICIT_COORDS);
+              scale_fact=double_value(argv[++(*num)]);
+              break;
+            }
+  case 'f': {  switch((argv[(*num)])[2])
+                    { case 'r':{ check_key(argv[(*num)],SET_FR,DO_ALIGN);
+                                 fr=int_value(argv[++(*num)]);
+                                 break;
+                               }
+                      case 'c':{ check_key(argv[(*num)],SET_FC,DO_ALIGN);
+                                 fc=int_value(argv[++(*num)]);
+                                 break;
+                               }
+                     default: { fprintf(stderr,"Invalid option %s\n",argv[(*num)]);
+                            exit(1);
+                              }
+                     break;
+                  }
+                  break;
+                }
+   case 'a':{ check_key(argv[(*num)],SET_AREA,RESCALING|EXPLICIT_COORDS);
+              area_val=double_value(argv[++(*num)]);
+              break;
+            }
+       case 'A':{ check_key(argv[(*num)],DO_ALIGN,EXPLICIT_ROW_COL);
+                                                 read_align_values(argv[++(*num)]);
+                                                 break;
+                  }
+        case 'c':{check_key(argv[(*num)],SET_COMMENT,0);
+                                                strncpy(header,argv[++(*num)],32);
+                                                break;
+                 }
+        case 'u':{check_key(argv[(*num)],SET_UNIT,0);
+                                                (*num)++;
+                    if (!strcmp(argv[(*num)],"none"))
+                     { unit=0; }
+                    else
+                    if (!strcmp(argv[(*num)],"ft"))
+                    { unit=1; }
+                    else
+                    if (!strcmp(argv[(*num)],"m"))
+                    { unit=2; }
+                    else
+                    if (!strcmp(argv[(*num)],"km"))
+                    { unit=3; }
+                                else
+                    if (!strcmp(argv[(*num)],"mile"))
+                    { unit=4; }
+                    else
+                    if (!strcmp(argv[(*num)],"ha"))
+                    { unit=5; }
+                    else
+                    if (!strcmp(argv[(*num)],"acre"))
+                    { unit=6; }
+                    else
+                    { fprintf(stderr,"Invalid area unit %s\n",argv[(*num)]);
+                      exit(1);
+                    }
+                                break;
+        }
+case 'v': { operations|=VERBOSE_MODE;
+           break;
+          }
+default: { return 0;
+          }
+}
+
+(*num)++;
+return 1;
+}
+
+int get_epp_header(FILE *f,EPPHEADER *hdr)
+{ EPPHEADER buf;
+  if (fseek(f,0,SEEK_SET)) return 0;
+  if (!fread(&buf,sizeof(buf),1,f)) return 0;
+  hdr->kind=COPY_SHORT(buf.kind);
+  if ((hdr->kind!=8)&&(hdr->kind!=16)) return 0;
+hdr->fr = COPY_SHORT(buf.fr);
+hdr->lr = COPY_SHORT(buf.lr);
+hdr->fc = COPY_SHORT(buf.fc);
+hdr->lc = COPY_SHORT(buf.lc);
+hdr->fry = COPY_DOUBLE(buf.fry);
+hdr->lry = COPY_DOUBLE(buf.lry);
+hdr->fcx = COPY_DOUBLE(buf.fcx);
+hdr->lcx = COPY_DOUBLE(buf.lcx);
+hdr->kind = COPY_SHORT(buf.kind);
+hdr->base = COPY_SHORT(buf.base);
+hdr->scale = COPY_SHORT(buf.scale);
+hdr->offsite = COPY_SHORT(buf.offsite);
+hdr->sfact = COPY_DOUBLE(buf.sfact);
+hdr->access_ptr = COPY_LONG(buf.access_ptr);
+hdr->minclass = COPY_SHORT(buf.minclass);
+hdr->maxclass = COPY_SHORT(buf.maxclass);
+hdr->area_unit =(buf.area_unit);
+hdr->coord_sys =(buf.coord_sys);
+memcpy(&(hdr->date),&(buf.date),16+8+32);
+return 1;
+}
+int put_epp_header(FILE *f,EPPHEADER *hdr)
+{ EPPHEADER buf;
+  if (fseek(f,0,SEEK_SET)) return 0;
+memset(&buf,0x20,128);
+buf.kind=COPY_SHORT(hdr->kind);
+buf.fr = COPY_SHORT(hdr->fr);
+buf.lr = COPY_SHORT(hdr->lr);
+buf.fc = COPY_SHORT(hdr->fc);
+buf.lc = COPY_SHORT(hdr->lc);
+buf.fry = COPY_DOUBLE(hdr->fry);
+buf.lry = COPY_DOUBLE(hdr->lry);
+buf.fcx = COPY_DOUBLE(hdr->fcx);
+buf.lcx = COPY_DOUBLE(hdr->lcx);
+buf.kind = COPY_SHORT(hdr->kind);
+buf.base = COPY_SHORT(hdr->base);
+buf.scale = COPY_SHORT(hdr->scale);
+buf.offsite = COPY_SHORT(hdr->offsite);
+buf.sfact = COPY_DOUBLE(hdr->sfact);
+buf.access_ptr = COPY_LONG(hdr->access_ptr);
+buf.minclass = COPY_SHORT(hdr->minclass);
+buf.maxclass = COPY_SHORT(hdr->maxclass);
+buf.area_unit =(hdr->area_unit);
+buf.coord_sys =(hdr->coord_sys);
+memcpy(&(buf.date),&(hdr->date),16+8+32);
+{int i;
+ for(i=strlen(buf.date);i<16;buf.date[i++]=' ');
+ for(i=strlen(buf.time);i<8;buf.time[i++]=' ');
+ for(i=strlen(buf.comment);i<32;buf.comment[i++]=' ');
+}
+return  fwrite(&buf,sizeof(buf),1,f);
+}
+int get_dgt_header(FILE *f,EPPHEADER *hdr,long *maxline,long *maxpt)
+{ DGTHEADER buf;
+  if (fseek(f,0,SEEK_SET)) return 0;
+  if (!fread(&buf,sizeof(buf),1,f)) return 0;
+  hdr->fry = COPY_DOUBLE(buf.ytop);
+  hdr->lry = COPY_DOUBLE(buf.ybottom);
+  hdr->fcx = COPY_DOUBLE(buf.xleft);
+  hdr->lcx = COPY_DOUBLE(buf.xright);
+  hdr->coord_sys =(buf.coord_sys);
+  *maxline=COPY_LONG(buf.maxline);
+  *maxpt=COPY_LONG(buf.maxpt);
+  return 1;
+}
+int put_dgt_header(FILE *f,EPPHEADER *hdr)
+{ DGTHEADER buf;
+  if (fseek(f,0,SEEK_SET)) return 0;
+  fread(&buf,sizeof(buf),1,f);
+       if (fseek(f,0,SEEK_SET)) return 0;
+  buf.ytop = COPY_DOUBLE(hdr->fry);
+  buf.ybottom = COPY_DOUBLE(hdr->lry);
+  buf.xleft = COPY_DOUBLE(hdr->fcx);
+  buf.xright = COPY_DOUBLE(hdr->lcx);
+  buf.coord_sys =(hdr->coord_sys);
+  return   fwrite(&buf,sizeof(buf),1,f);
+}
+char *coord_name[]={"Alternative","UTM","State plane","Geographic"};
+char *unit_name[]={"unknown units","sq.feet","sq.m","sq.km","sq.miles","ha","acres"};
+void print_epp_header(const char *filename,EPPHEADER hdr)
+{ char commentstr[33],datestr[17],timestr[9];
+       commentstr[32]=datestr[16]=timestr[8]='\0';
+       strncpy(datestr,hdr.date,16);
+       strncpy(timestr,hdr.time,8);
+       if ((unsigned char)hdr.area_unit>6) hdr.area_unit=0;
+       if ((unsigned char)hdr.coord_sys>3) hdr.coord_sys=0;
+       printf("File:%s\n\
+Description:%s\n\
+First row    = %6d   Last row    = %6d\n\
+First column = %6d   Last column = %6d\n\
+%s coordinates:\nFirst row    = %12g   Last row    = %12g\n\
+First column = %12g   Last column = %12g\n\
+Cell area: %12g %s\n\
+Created: %s %s\n\
+Data size = %d\n\
+Minimum class = %d, Maximum class = %d, Offsite class = %d\n",
+filename,strncpy(commentstr,hdr.comment,32),
+hdr.fr,hdr.lr,hdr.fc,hdr.lc,coord_name[(int)hdr.coord_sys],
+hdr.fry,hdr.lry,hdr.fcx,hdr.lcx,hdr.sfact,unit_name[(int)hdr.area_unit],
+datestr,timestr,hdr.kind,
+hdr.minclass,hdr.maxclass,hdr.offsite);
+}
+void print_dgt_header(const char*filename,EPPHEADER hdr,long maxline,long maxpt)
+{ printf("File: %s\n\
+%s coordinates:\n\
+Xleft = %12g, XRight  = %12g\n\
+Ytop  = %12g, YBottom = %12g\n\
+Maximum point id = %ld, Maximum line id = %ld\n",
+filename,coord_name[(int)hdr.coord_sys],hdr.fcx,hdr.lcx,hdr.fry,hdr.lry,
+maxline,maxpt);
+}
+void set_row( EPPHEADER *hdr,int row)
+{
+  hdr->lr=hdr->lr-hdr->fr+row;
+  hdr->fr=row;
+}
+void set_column( EPPHEADER *hdr,int column)
+{ 
+  hdr->lc=hdr->lc-hdr->fc+column;
+  hdr->fc=column;
+}
+int align(EPPHEADER *hdr,const char *name)
+{ double cw,sfx,sfy;
+  int new_row,new_col;
+ cw=(align_val.XRight-align_val.XLeft)/(align_val.lc-align_val.fc+1);
+ sfx=cw/((hdr->lcx-hdr->fcx)/(hdr->lc-hdr->fc+1));
+ cw=(align_val.YBottom-align_val.YTop)/(align_val.lr-align_val.fr+1);
+ sfy=cw/((hdr->lry-hdr->fry)/(hdr->lr-hdr->fr+1));
+ if (fabs(sfx-1)>(1.0/(hdr->lc-hdr->fc+1))||fabs(sfy-1)>(1.0/(hdr->lr-hdr->fr+1)))
+  {  fprintf(stderr,"Unable to align file %s.\nRescale it with X factor %7.4f and Y factor %7.4f\n",
+     name,sfx,sfy);
+     return 0;}
+
+ new_col=(hdr->fcx-align_val.XLeft)/(align_val.XRight-align_val.XLeft)*
+        (align_val.lc-align_val.fc+1);
+ new_col+=align_val.fc;
+ new_row=(hdr->fry-align_val.YTop)/(align_val.YBottom-align_val.YTop)*
+        (align_val.lr-align_val.fr+1);
+ new_row+=align_val.fr;
+ set_row(hdr,new_row);
+ set_column(hdr,new_col);
+ return 1;
+}
+void process_file(const char *filename)
+{ FILE *f;
+  EPPHEADER hdr;
+  long maxline,maxpt;
+  int isdgt;
+  char ext[8];
+  int readonly=0;
+  strncpy(ext,filename+(strlen(filename)-3),4);
+  #ifdef __MSDOS__
+   strlwr(ext);/* dos filenames are not case-sensitive */
+  #endif
+  isdgt=0;
+  if (!strcmp(ext,"dgt")||!strcmp(ext,"DGT"))
+   { if (!(operations&(DGT_OPS|VERBOSE_MODE)))
+     { fprintf(stderr,"No operations to apply to %s\n",filename);
+       return;
+      }
+     isdgt=1;
+   }
+  else
+   if (strcmp(ext,"epp")&&strcmp(ext,"EPP"))
+   { fprintf(stderr,"File %s has unknown extension\n",filename);
+     return;
+   }
+  f=fopen(filename,"r+b");
+  if (NULL==f) 
+  if (NULL==(f=fopen(filename,"rb")))
+  { 
+    fprintf(stderr,"Cannot open file %s\n",filename);
+    return;
+  } else readonly=1;
+ if (!(isdgt?get_dgt_header(f,&hdr,&maxline,&maxpt):get_epp_header(f,&hdr)))
+ { fprintf(stderr,"invalid %s file %s\n",ext,filename);
+   return;
+ }
+ if (hdr.coord_sys>MAX_PROJECTION)
+   hdr.coord_sys=0;
+ if (!isdgt)
+ { if  (hdr.area_unit>MAX_UNIT)
+    hdr.area_unit=0;
+   if (hdr.kind==8)
+   { if (hdr.maxclass>255) hdr.maxclass=255;
+     if (hdr.minclass>hdr.maxclass) hdr.minclass=0;
+   }
+ }
+ /****************** Applying requested operations *****************/
+  if (operations & DO_XSHIFT)
+   { hdr.fcx+=x_shift;
+     hdr.lcx+=x_shift;
+   }
+  if (operations & DO_YSHIFT)
+  { hdr.fry+=y_shift;
+    hdr.lry+=y_shift;
+  }
+  if (operations & DO_SCALE)
+  { hdr.fcx*=scale_fact;
+    hdr.fry*=scale_fact;
+    hdr.lcx*=scale_fact;
+    hdr.lry*=scale_fact;
+   }
+  if (operations & SET_X_LEFT) hdr.fcx=XLeft;
+  if (operations & SET_X_RIGHT) hdr.lcx=XRight;
+  if (operations & SET_Y_BOTTOM) hdr.lry=YBottom;
+  if (operations & SET_Y_TOP) hdr.fry=YTop;
+  if (operations & SET_PRJ) hdr.coord_sys=proj;
+  if (!isdgt &&(operations & SET_FR)) set_row(&hdr,fr);
+  if (!isdgt &&(operations & SET_FC)) set_column(&hdr,fc);
+  if (!isdgt &&(operations & DO_ALIGN)) align(&hdr,filename);
+  if (!isdgt &&(operations &  SET_AREA)) hdr.sfact=area_val;
+  if (!isdgt &&(operations & SET_COMMENT))
+  { char *src=header;
+    char *dest=hdr.comment;
+    int count=0;
+    memset(&(hdr.comment),' ',32);
+    while (*src!='\0'&&count++<32) *(dest++)=*(src++);
+  }
+  if (!isdgt &&(operations & SET_UNIT )) hdr.area_unit=unit;
+  if (!isdgt &&(operations & SET_OFFSITE )) 
+   
+if (hdr.kind==16||(offsite<=255&&offsite>=-1))hdr.offsite=offsite;
+ else
+  hdr.offsite=-1;
+ /******************** End of operations ***************************/
+ if (operations & VERBOSE_MODE )
+ { if (readonly) printf("Read-only ");
+   if (isdgt)
+    print_dgt_header(filename,hdr,maxline,maxpt);
+  else
+   print_epp_header(filename,hdr);
+ }
+if ((operations& ~VERBOSE_MODE)&& !readonly)
+ if (!(isdgt?put_dgt_header(f,&hdr):put_epp_header(f,&hdr)))
+ { fprintf(stderr,"Cannot modify file %s\n",filename);
+   clearerr(f);
+ }
+ fclose(f);
+}
diff --git a/epu/extents.c b/epu/extents.c
new file mode 100644 (file)
index 0000000..d23f28f
--- /dev/null
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "epp.h"
+#include "eppl_ut.h"
+typedef struct Contour {int Class,XMin,YMin,XMax,YMax,Count;} CONTOUR;
+/* ÏÐÉÓÁÎÉÅ ÏÄÎÏÇÏ ËÏÎÔÕÒÁ */
+CONTOUR *a; 
+EPP *epp;
+EPPHEADER *h;
+int first_class; /* ÄÌÑ ÐÅÒÅÓÞÅÔÁ */
+
+int sort_area(const void *p1, const void *p2)
+/* óÒÁ×ÎÅÎÉÅ ÐÏ ÐÌÏÝÁÄÉ */
+{
+int t1,t2;
+t1=(((CONTOUR *)p1))->Count;
+t2=(((CONTOUR *)p2))->Count;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+
+int sort_y_top(const void *p1, const void *p2)
+/* óÒÁ×ÎÅÎÉÅ ÐÏ ×ÅÒÈÎÅÊ ÇÒÁÎÉÃÅ */
+{
+int t1, t2;
+t1=((CONTOUR *)p1)->YMin;
+t2=((CONTOUR *)p2)->YMin;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+
+int sort_y_bottom(const void *p1, const void *p2)
+{
+int t1, t2;
+t1=((CONTOUR *)p1)->YMax;
+t2=((CONTOUR *)p2)->YMax;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+int sort_x_right(const void *p1, const void *p2)
+{
+int t1, t2;
+t1=((CONTOUR *)p1)->XMax;
+t2=((CONTOUR *)p2)->XMax;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+int sort_x_left(const void *p1, const void *p2)
+{
+int t1, t2;
+t1=((CONTOUR *)p1)->XMin;
+t2=((CONTOUR *)p2)->XMin;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+
+int sort_x(const void *p1, const void *p2)
+/* óÒÁ×ÎÅÎÉÅ ÐÏ ÓÒÅÄÎÅÍÕ X */
+{
+int t1, t2;
+t1=((CONTOUR *)p1)->XMin+((CONTOUR *)p1)->XMax;
+t2=((CONTOUR *)p2)->XMin+((CONTOUR *)p2)->XMax;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+
+int sort_y(const void *p1, const void *p2)
+/* óÒÁ×ÎÅÎÉÅ ÐÏ ÓÒÅÄÎÅÍÕ Y */
+{
+int t1, t2;
+t1=((CONTOUR *)p1)->YMin+((CONTOUR *)p1)->YMax;
+t2=((CONTOUR *)p2)->YMin+((CONTOUR *)p2)->YMax;
+if (t1>t2) return 1;
+if (t1==t2) return 0;
+return -1;
+}
+
+/*int sort_s(const void *p1, const void *p2)*/
+/* óÒÁ×ÎÅÎÉÅ ÐÏ ÏÔÎÏÛÅÎÉÀ count/(W*H) */
+/*{
+}*/
+
+
+
+int process_cell(int col,int row, int value)
+{
+CONTOUR *b=a+value;  
+if (b->XMin>col) b->XMin=col;
+if (b->XMax<col) b->XMax=col;
+if (b->YMin>row) b->YMin=row;
+if (b->YMax<row) b->YMax=row;
+b->Count++;
+return 0;
+}
+
+int main(int argc,char **argv)
+{
+int (*sort_function)(const void *,const void *)=NULL;
+/*òÁÚÂÏÒ ÐÁÒÁÍÅÔÒÏ× ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÉ*/
+struct option longoptions[]={
+{"help",0,0,1},
+{"version",0,0,2},
+{"verbose",0,0,'%'},
+{"alt-coords",0,0,'a'},
+{"sort-left",0,0,'l'},
+{"sort-right",0,0,'r'},
+{"sort-top",0,0,'t'},
+{"sort-bottom",0,0,'b'},
+{"sort-area",0,0,'A'},
+{"sort-x-center",0,0,'x'},
+{"sort-y-center",0,0,'y'},
+{"output-file",1,0,'o'},
+{"header",0,0,'h'},
+{NULL,0,0,0}
+};
+int c,index,i;
+int verbose=0;
+int use_alt=0;
+int print_header=0;
+CONTOUR *b;
+FILE *f=stdout;
+while((c=getopt_long(argc,argv,"alrtbxyA%ho:",longoptions,&index))!=-1)
+ switch(c)
+  { case 2:show_version("extents","$Revision: 1.1 $");
+    case '%': verbose=1; break; 
+    case 'a': use_alt=1;break;
+    case 'o': if (!(f=fopen(optarg,"w"))) 
+                 {fprintf(stderr,"Cannot open file %s\n",optarg); return 2;}
+              break;
+    case 'l':sort_function=sort_x_left; break;
+    case 'r':sort_function=sort_x_right; break;
+    case 't':sort_function=sort_y_top; break;
+    case 'b':sort_function=sort_y_bottom; break;
+    case 'x':sort_function=sort_x; break;
+    case 'y':sort_function=sort_y; break;
+    case 'A':sort_function=sort_area; break;
+    case 'h':print_header=1;break;
+    case 1:
+    case '?':
+    default: printf("Usage: extents [-%%alrtbxtA] [-o file] file.epp\n");
+             return c!=1;
+   }
+            
+  
+/*ïÔËÒÙÔØ epp-ÛÎÉË, ÐÒÏÞÉÔÁÔØ ÚÁÇÏÌÏ×ÏË, ÓÏÚÄÁÔØ ÍÁÓÓÉ× CONTOUR ÄÌÉÎÙ 
+*/
+epp=open_epp(default_ext(argv[optind],".epp"));
+if(epp==NULL) {fprintf(stderr,"Can not open file %s\n",
+           default_ext(argv[optind],".epp"));
+               return 2;} 
+a=calloc(sizeof(CONTOUR),epp->max+1);
+for(i=0,b=a;i<=epp->max;i++,b++)
+{ b->XMin=epp->lc;
+  b->XMax=epp->fc;
+  b->YMin=epp->lr;
+  b->YMax=epp->fr;
+  b->Class=i;
+}
+install_progress_indicator(verbose?show_percent:check_int);
+if (clear_progress(for_each_cell(epp,process_cell))) return 3;
+if (sort_function) qsort(a,epp->max+1,sizeof(CONTOUR),sort_function);
+if (print_header) 
+    fprintf(f,use_alt?
+" Class        X Left       X Right         Y Top      Y Bottom           Area\n":
+" Class Min Col Max Col Min Row Max Row     Count\n");
+for(i=0;i<=epp->max;i++)
+  if (a[i].Count) 
+    { if (use_alt) 
+        fprintf(f,"%6d %13g %13g %13g %13g %14g\n",
+                a[i].Class,alt_x(epp,a[i].XMin),alt_x(epp,a[i].XMax+1),
+                alt_y(epp,a[i].YMin),alt_y(epp,a[i].YMax+1),
+                a[i].Count*epp->cell_area);
+      else
+        fprintf(f,"%6d %7d %7d %7d %7d %9d\n",  
+                 a[i].Class,a[i].XMin,a[i].XMax,a[i].YMin,a[i].YMax,a[i].Count);
+     }
+         
+close_epp(epp);
+if (f!=stdout) fclose(f);
+return 0;
+}
diff --git a/epu/fill.c b/epu/fill.c
new file mode 100644 (file)
index 0000000..afa35e0
--- /dev/null
@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "epp.h"
+#include "eppl_ut.h"
+int color_to_fill=0;
+int color_to_not_expand=-1;/* 1 in eppl */
+int cells_filled,cells_remain;
+int verbose=0;
+int gap_size=0;
+void add_color(int color,int *col_list,int *col_count,int *list_len)
+{ int i;
+  if(color==color_to_fill||color==color_to_not_expand) return;
+  for (i=0;i<*list_len;i++,col_list++,col_count++)
+   if (color==col_list[i]) {col_count[i]++;return;}
+ *col_list=color;*col_count=1;(*list_len)++;
+}
+#define addcolor(i) add_color(i,color,count,&cc);
+void fillrow(unsigned short *out_row,unsigned short *prev_row, 
+             unsigned short *cur_row,unsigned short *next_row, 
+             int ncols)
+{ int i; 
+  for (i=1;i<=ncols;i++)
+   if (cur_row[i]!=color_to_fill) *(out_row++)=cur_row[i];
+    else
+    { int color[8],count[8],ii,jj,cc=0,cnt=0;
+      unsigned short *clr_ptr=prev_row+i-1;   
+      addcolor(*(clr_ptr++));
+      addcolor(*(clr_ptr++));
+      addcolor(*(clr_ptr++));
+      addcolor(cur_row[i-1]);
+      addcolor(cur_row[i+1]);
+      addcolor(*(clr_ptr=next_row+i-1));
+      addcolor(*(++clr_ptr));
+      addcolor(*(++clr_ptr));
+      for(ii=0,jj=color_to_fill;ii<cc;ii++)
+      if(count[ii]>cnt) {cnt=count[ii];jj=color[ii];}
+       if (jj==color_to_fill) 
+           {cells_remain++;*(out_row++)=color_to_fill;}
+           else 
+           {cells_filled++;*(out_row++)=jj;};
+    }
+} 
+int fill(char *in_file_name,char *out_file_name)
+{ unsigned short int *prev_row,*cur_row,*next_row,*rptr,*dest;
+  int i,j,nrows,seqrow,ncols;
+  EPP *in_file;
+  EPP *out_file;
+  
+  cells_filled=0;
+  cells_remain=0;
+  
+  in_file=open_epp(in_file_name);
+  if (NULL==in_file)
+  { fprintf(stderr,"Cannot open file %s\n",in_file_name);
+    exit(2);
+  }
+  Create16bit=in_file->kind==16;
+  out_file=creat_epp_as(out_file_name,in_file);
+  if (NULL==out_file)
+  { fprintf(stderr,"Cannt create file %s\n",out_file_name);
+    exit(2);
+  }
+  ncols=in_file->lc-in_file->fc;
+  prev_row=malloc(sizeof(short)*(ncols+2));
+  cur_row=malloc(sizeof(short)*(ncols+2));
+  next_row=malloc(sizeof(short)*(ncols+2));
+  for(i=0;i<=ncols+1;prev_row[i++]=color_to_fill);
+  cur_row[0]=cur_row[ncols+1]=next_row[0]=next_row[ncols+1]=color_to_fill;
+  rptr=epp_getline(in_file,in_file->fc,in_file->fr); 
+  for(i=1,dest=cur_row+1;i<=ncols;*(dest++)=*(rptr++),i++);
+  rptr=epp_getline(in_file,in_file->fc,in_file->fr+1);
+  for(i=1,dest=next_row+1;i<=ncols;*(dest++)=*(rptr++),i++);
+  nrows=in_file->lr-in_file->fr;
+  for(seqrow=1,i=in_file->fr+2;seqrow<=nrows;i++,seqrow++)
+  { 
+   if (EndLineProc)
+    if ((*EndLineProc)(i,seqrow,nrows)) return 1;
+   epp_put(out_file,out_file->fc,i-2,out_file->offsite); 
+   fillrow(out_file->row,prev_row,cur_row,next_row,ncols);
+   {unsigned short int *tmp;
+    tmp=prev_row;
+    prev_row=cur_row;
+    cur_row=next_row;
+    next_row=tmp;
+   }
+   if (i<in_file->lr) 
+   { rptr=epp_getline(in_file,in_file->fc,i);
+     for(j=1,dest=next_row+1;j<=ncols;*(dest++)=*(rptr++),j++);
+   }
+  else
+  for(j=1,dest=next_row+1;j<=ncols;*(dest++)=color_to_fill,j++);
+}  
+out_file->max=in_file->max;
+out_file->min=in_file->min; 
+close_epp(out_file);
+close_epp(in_file);
+return 0;
+}
+int main(int argc,char **argv)
+{ 
+#ifdef unix
+  char out_name[256]="fill.out.epp";
+#else
+  char out_name[256]="fill.epp";
+#endif
+  struct option long_options[]={
+  {"help",0,0,1},
+  {"version",0,0,2},
+  {"verbose",0,0,'%'}, 
+  {"gap-size",required_argument,0,'g'},
+  {"color-to-fill",required_argument,0,'f'},
+  {"exclude-color",required_argument,0,'x'},
+  {"output-file",required_argument,0,'o'}, 
+  {NULL,0,0,0} };
+  int c;     
+  int index;
+  while ((c=getopt_long(argc,argv,"%g:c:f:x:o:",long_options,&index))!=-1)
+  { switch(c)
+    { 
+      case 2:/*version*/
+             show_version("fill","$Revision: 1.1 $");
+
+      case '%':verbose=1;break;
+      case 'g':/*gap size is unused now*/
+               gap_size=atoi(optarg);break;
+      case 'c':/*color to fill*/
+               color_to_fill=atoi(optarg);break;
+      case 'x':color_to_not_expand=atoi(optarg);break;
+      case 'o':strcpy(out_name,optarg);break;
+      case 1:
+      case '?':
+      default:
+      /*help*/
+             printf("Usage %s [--help] [--version] [-v] [-g gap size]\n"
+             "\t[-c color to fill] [-x color to exclude] [-o output file]\n"
+             "\tepp file\n",argv[0]);
+             return c==1?0:2;
+     }
+   }
+   if (argc==optind) 
+    {fprintf(stderr,"No input files specified\n");
+     return 2;
+    }
+   if (argc>optind+1)
+    { fprintf(stderr,"Too many input files\n");
+      return 2;
+    }
+   install_progress_indicator(verbose?show_percent:check_int);
+   if((c=clear_progress(fill(argv[optind],out_name))))
+    {unlink(out_name);
+     return 2;
+    }
+   printf("Cells filled %d\nCells of class %d remain:%d\n",
+          cells_filled,color_to_fill,cells_remain);
+   return cells_remain?1:0;
+}
diff --git a/epu/intable b/epu/intable
new file mode 100755 (executable)
index 0000000..99482a1
Binary files /dev/null and b/epu/intable differ
diff --git a/epu/intable.c b/epu/intable.c
new file mode 100644 (file)
index 0000000..25c1251
--- /dev/null
@@ -0,0 +1,252 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <getopt.h>
+#include "epp.h"
+#include "eppl_ut.h"
+struct record {
+               unsigned short int outclass;
+               unsigned short int classes[32];
+              };
+typedef struct record *rec;
+
+void help(int exitcode)
+{ printf("Usage: intable [-%%] [-i] [-o file] [-f file] [-O value] [-u value] files\n");
+  exit(exitcode);
+}
+
+short int* table;
+
+EPP *files[32];
+char skip[32]={0,0,0,0,0,0,0,0,
+               0,0,0,0,0,0,0,0,
+               0,0,0,0,0,0,0,0,
+               0,0,0,0,0,0,0,0,};
+int files_count,count,limit,delta;
+int skip_count=0;   
+char delimiter=',';
+
+int offsite=-1;
+int unmatched=-1;
+
+int compare(struct record *r1, struct record *r2)
+{int i; 
+ for (i=0;i<files_count;i++)
+ { if (r1->classes[i]>r2->classes[i]) return 1;
+   else
+   if (r1->classes[i]<r2->classes[i]) return -1;
+ }
+ return 0;
+
+}
+int search(struct record *key,int *index)
+{int l=0,h=count-1,i,c;
+ while(l<=h)
+ { i=(l+h)>>1;
+   c=compare((struct record *)(table+(1+files_count)*i),key);
+   if (c<0) l=i+1;
+   else
+   { h=i-1;
+     if (!c) { *index=i;return 1;}
+   }
+  } 
+ *index=l;
+ return 0;
+}
+void insert(struct record *key,int index)
+{ int i;unsigned short int *l;
+  if (count==limit)
+  {  
+     table=realloc(table,(limit+=delta)*(1+files_count)*sizeof(short int));
+     if (!table)
+     { fprintf(stderr,"Couldn't realloc table. Table limit is %d\n",limit);
+       exit(1);
+     }
+   }
+
+ for(i=count;i>index;i--)
+  memcpy(table+(i)*(1+files_count),table+(i-1)*(1+files_count),
+  (1+files_count)*sizeof(short int)); 
+ l=(unsigned short int *)(table+index*(1+files_count));
+ memcpy(l,key,(files_count+1)*sizeof(short int));
+ count++;
+} 
+void setvalue(int index,int value)
+{
+ unsigned short int *l=(unsigned short int *)(table+index*(1+files_count));
+ *l=value;
+}
+int lineno=0;
+int add_record(FILE *f)
+{ /* ÷ÏÚ×ÒÁÝÁÅÔ 0, ÅÓÌÉ ÔÁËÁÑ ËÏÍÂÉÎÁÃÉÑ ÕÖÅ ÅÓÔØ*/
+  struct record tmp;
+  char *endptr;
+  char line[256];
+  int i,v,j;
+  endptr=fgets(line,256,f);
+  if (!endptr) return 1;
+  lineno++;
+  for(i=0,j=0;i<files_count+skip_count;i++)
+  { v=strtol(endptr,&endptr,0);
+    while(*endptr==' '||*endptr=='\t') endptr++;
+    if (*endptr!=delimiter&&!(isdigit(*endptr)&&delimiter==' '))
+    { fprintf(stderr,"Invalid line %d in table. Error at char %d\n",
+      lineno,endptr-line);
+      exit(2);
+    }
+    if (*endptr==delimiter) 
+      endptr++; 
+    if (*endptr=='\n') 
+     { fprintf(stderr,"Not enough values in line %d:%d instead of%d\n",
+         lineno,i+1,files_count+1);
+       exit(2);
+     }
+    /* if ((v<files[i]->min||v>files[i]->max)&&v!=files[i]->offsite) */
+    if (v<0||v>65535) 
+     { fprintf(stderr,"Illegal value %d in column %d of line %d\n",
+        v,i+1,lineno);
+       exit(2);
+     } 
+    if (!skip[i])  
+    tmp.classes[j++]=v;
+  }
+  v=strtol(endptr,&endptr,0);
+  while (*endptr==' '||*endptr=='\t')endptr++;
+  if(*endptr!='\n')
+  { fprintf(stderr,"Extra data in line %d\n",lineno);
+    exit(2);
+  }
+    if (v<0||v>65535) 
+     { fprintf(stderr,"Illegal value %d in column %d of line %d\n",
+        v,files_count+1,lineno);
+       exit(2);
+     }   
+  tmp.outclass=v;
+  if (v>255) Create16bit=1;
+  if (search(&tmp,&i))
+  { setvalue(i,v); return 0;}
+  else
+  { insert(&tmp,i); return 1;}
+}
+
+int make_cell(int x,int y,int value)
+{ struct record tmp;
+  int i;EPP **epp;
+  for(i=0,epp=files;i<files_count;tmp.classes[i++]=epp_get(*(epp++),x,y));
+  if (search(&tmp,&i))
+   return *((unsigned short int *)(table+i*(1+files_count)));
+  else
+   return unmatched;
+}
+
+int getclass(const char *s)
+
+{char *endptr;
+ int tmp=strtol(s,&endptr,0);
+ if (*endptr||tmp<0||tmp>65535) 
+  { fprintf(stderr,"Invalid class value %s\n",s);
+    exit(2);
+  }
+ return tmp;
+}
+   
+int main(int argc,char **argv)
+{ struct option long_options[]={
+{"help",0,0,1},
+{"version",0,0,2},
+{"verbose",0,0,'%'},
+{"delimiter",1,0,'d'},
+{"input-file",1,0,'f'},
+{"output-file",1,0,'o'},
+{"offsite",1,0,'O'},
+{"unmatched",1,0,'u'},
+{"skip",1,0,3},
+{"ignore-dupes",0,0,'i'},
+{NULL,0,0,0}
+};
+char outname[1024]="intable.out.epp";
+int index,c,i;
+int ignore_dupes=0,verbose=0;
+FILE *f=stdin;
+EPP *new_file,**epp;
+while ((c=getopt_long(argc,argv,"%iu:d:f:o:O:129456789",
+         long_options,&index))!=-1)
+switch(c)
+{case 2:show_version("intable","$Revision: 1.1 $");
+ case '%':verbose=1;break;
+ case 'd':delimiter=optarg[0];break;
+ case 'f':if (!(f=fopen(optarg,"r")))
+     { fprintf(stderr,"Cannot open file %s\n",optarg);
+       exit(2);
+     } break;
+  case 'o':strcpy(outname,default_ext(optarg,".epp"));break;
+  case 'O':offsite=getclass(optarg);
+      break;
+  case 'u':unmatched=getclass(optarg);break;
+  case 'i':ignore_dupes=1;break;
+  case '?':
+  case '1': case '2': case '3': case '4': case '5': case '6': case '7':
+  case '8': case '9':
+          skip_count++;
+          skip[c-'1']=1;
+          break;
+  case 3:{char *endptr;
+         i=strtol(optarg,&endptr,0);
+         if (*endptr||i<1||i>32) 
+         { fprintf(stderr,"Invalid column number %s\n",optarg); 
+           exit(2);
+         }
+         skip_count++;
+         skip[i]=1;
+         break;
+        }
+  case 1:
+  default:
+      help(c==1);
+
+  }
+ files_count=argc-optind;
+ table=malloc(65536*sizeof(short)*(files_count+1));
+ limit=65536;
+ delta=1024;
+ count=0;
+ epp=files;
+ for(i=0,index=optind;i<files_count;i++,index++,epp++)
+ {if (!(*epp=open_epp(default_ext(argv[index],".epp"))))
+  { fprintf(stderr,"Cannot open file %s\n",default_ext(argv[index],".epp"));
+    exit(2);
+  }
+  if(i&&!is_aligned(*files,*epp))
+  { fprintf(stderr,"File %s is incompatible with %s\n",
+     argv[optind],argv[index]);
+     exit(2);
+  }
+ }
+ while (!feof(f))
+ { if(!ignore_dupes && !add_record(f))
+   {fprintf(stderr,"Duplicated lines in table\n");
+     exit(2);
+   }
+ }
+ printf("%d lines read. %d values used\n",lineno,count);
+ if (offsite==-1) offsite=Create16bit?65535:255;
+ if (unmatched==-1) unmatched=offsite;
+ if (!(new_file=creat_epp_as(outname,*files)))
+ { fprintf(stderr,"Cannot create file %s\n",outname);
+   exit(2);
+ }
+ new_file->offsite=offsite;
+ install_progress_indicator(verbose?show_percent:check_int);
+ if ((i=clear_progress(for_each_cell(new_file,make_cell))))
+  unlink(outname);
+ if (!Create16bit||new_file->max>255)
+   close_epp(new_file);
+ else
+  {unlink(outname);
+   fast_convert_to_8bit(new_file,outname); 
+  }
+return abs(i);
+}
diff --git a/epu/mosaic.c b/epu/mosaic.c
new file mode 100644 (file)
index 0000000..beebeaa
--- /dev/null
@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "epp.h"
+#include "eppl_ut.h"
+#include <getopt.h>
+#include <unistd.h>
+EPP **files;
+int count;
+
+int fill_cell(int col,int row,int value)
+{ int i,c;
+  EPP **epp;
+  for (i=count,epp=files+count-1;i>0;i--,epp--)
+    if ((c=epp_get(*epp,col,row))!=(*epp)->offsite) return c;
+  return value;
+}
+
+void help(int exitcode)
+{
+ printf("Usage: mosaic [-%%RA] [-O number] [-o filename] [--help][--version]files\n"
+"\t--help - displays this message\n"
+"\t--version - shows version number\n"
+"\t-%% --verbose - shows progress indicator\n"
+"\t-R --force-row - process misaligned files using row/col coords\n"
+"\t-A --force-alt - process misaligned files using alternative coords\n"
+"\t-O number --offsite=number - set offsite value of output file\n"
+"\t-o name --output-file=name - sets name of output file\n");
+exit (exitcode);
+}
+
+int main(int argc,char **argv)
+{char output_file[1024]="mosaic.out.epp";
+ struct option long_options[]=
+{ 
+ {"help",0,0,1},
+ {"version",0,0,2},
+ {"offsite",1,0,'O'},
+ {"verbose",0,0,'%'},
+ {"force-row",0,0,'R'},
+ {"force-alt",0,0,'A'},
+ {"output-file",1,0,'o'},
+ {NULL,0,0,0}};
+ int index,i,c;char *endptr;
+ int offsite=-1, x1=32767,y1=32767,x2=-32767,y2=-32767,
+     max=0,min=65535,force=0,use_alt=1,result,verbose=0;
+ double X1,Y1,X2,Y2;
+ EPP *out_f;
+ while ((c=getopt_long(argc,argv,"O:%RAo:",long_options,&index))!=-1)
+ { switch (c)
+   { case 2:show_version("mosaic","$Revision: 1.1 $");
+     case '%':verbose=1;break;
+     case 'O':offsite=strtol(optarg,&endptr,0);
+         if(*endptr||offsite<0||offsite>65535)
+         { fprintf(stderr,"Invalid offsite value %s\n",optarg); return 2;
+         } 
+         break;
+     case 'A':force=1;use_alt=1;break;
+     case 'R':force=1;use_alt=0;break;
+     case 'o':strcpy(output_file,default_ext(optarg,".epp"));break;
+     case  1:
+     case '?':
+     default:
+       help(c!=1);
+   }
+ } 
+  count=argc - optind;
+  if (!count) { fprintf(stderr,"No input files specified\n");return 2;}
+  files=malloc(count*sizeof(EPP *));
+  for (i=optind,index=0;i<argc;i++,index++)
+  { files[index]=open_epp(default_ext(argv[i],".epp"));
+    if (!files[index]) 
+    {fprintf(stderr,"Cannot open file %s\n",argv[i]); 
+     return 2;
+    } 
+    if (index>0&&!compare_cell_size(files[0],files[index]))
+     { fprintf(stderr,"File %s is incompatible with %s\n",argv[i],argv[optind]);
+      return 2;
+     }
+    if (index>0&&!is_aligned(files[0],files[index]))
+    { fprintf(stderr,"File %s is misaligned with %s\n",argv[i],argv[optind]);
+      if (!force) return 2;
+      if (use_alt)
+      {if (!shift_epp(files[index],epp_row(files[0],files[index]->YTop),
+                             epp_col(files[0],files[index]->XLeft)))
+       {fprintf(stderr,"Cannot align file %s\n",argv[i]) ;
+       return 2;
+       }
+      }
+      else
+      { files[index]->XLeft=alt_x(files[0],files[index]->fc);
+        files[index]->XRight=alt_x(files[0],files[index]->lc);
+        files[index]->YTop=alt_y(files[0],files[index]->fr);
+        files[index]->YBottom=alt_y(files[0],files[index]->lr);
+      }
+     }
+     if (!index||x1>files[index]->fc){ x1=files[index]->fc;X1=files[index]->XLeft;}
+     if (!index||x2<files[index]->lc){ x2=files[index]->lc;X2=files[index]->XRight;}
+     if (!index||y1>files[index]->fr){ y1=files[index]->fr;Y1=files[index]->YTop;}
+     if (!index||y2<files[index]->lr){ y2=files[index]->lr;Y2=files[index]->YBottom;}
+     if (max<files[index]->max) max=files[index]->max;
+     if (min>files[index]->min) min=files[index]->min;
+     if (files[index]->kind==16) Create16bit=1;
+
+  }
+  x2--;
+  y2--;
+  if (offsite<0)
+  { if (files[0]->offsite<min||files[0]->offsite>max)
+     offsite=files[0]->offsite;
+     else 
+     offsite=Create16bit?65535:255;
+  }
+  install_progress_indicator(verbose?show_percent:check_int);
+  out_f=creat_epp(output_file,x1,y1,x2,y2,X1,Y1,X2,Y2,
+                  100,0,offsite);
+  if (!out_f) {fprintf(stderr,"Cannot create output file %s\n",output_file);
+              return 2;
+             }
+  result=clear_progress(for_each_cell(out_f,fill_cell));
+  close_epp(out_f);
+  if (result) unlink(output_file);
+  for (i=0;i<count;i++) close_epp(files[i]);
+  return result;
+}
diff --git a/epu/neighbours.c b/epu/neighbours.c
new file mode 100644 (file)
index 0000000..73df8a2
--- /dev/null
@@ -0,0 +1,147 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "epp.h"
+#include "eppl_ut.h" 
+void help()
+{ printf("Usage: neighbours [-%%][-d] file\n");
+  exit(0);
+}
+
+short int* table;
+
+EPP *file;
+
+int count,limit,delta;
+int duplicates=0;   
+
+int compare(unsigned short int *r1, unsigned short int *r2)
+{int i; 
+ for (i=0;i<2;i++,r1++,r2++)
+ { if (*r1>*r2) return 1;
+   else
+   if (*r1<*r2) return -1;
+ }
+ return 0;
+
+}
+int search(unsigned short *key,int *index)
+{int l=0,h=count-1,i,c;
+ while(l<=h)
+ { i=(l+h)>>1;
+   c=compare(table+2*i,key);
+   if (c<0) l=i+1;
+   else
+   { h=i-1;
+     if (!c) { *index=i;return 1;}
+   }
+  } 
+ *index=l;
+ return 0;
+}
+void insert(unsigned short *key,int index)
+{ int i;
+  if (count==limit)
+  {  
+     table=realloc(table,(limit+=delta)*2*sizeof(short int));
+     if (!table)
+     { fprintf(stderr,"Couldn't realloc table. Table limit is %d\n",limit);
+       exit(1);
+     }
+   }
+
+ for(i=count;i>index;i--)
+  {table[2*i]=table[2*(i-1)];
+  table[2*i+1]=table[2*i-1];}
+  table[2*index]=key[0];
+  table[2*index+1]=key[1];
+  count++;
+} 
+void delete(int index)
+{ int i;
+  for(i=index+1;i<count;i++)
+  { table[2*(i-1)]=table[2*i];
+    table[2*i-1]=table[2*i+1];
+  }
+  count--;  
+}
+
+void add_pair(int v1,int v2)
+{int index;unsigned short int key[2]; 
+ if (v1==v2||v1==file->offsite||v2==file->offsite) return;
+ if (v1>v2) {key[0]=v2;key[1]=v1;}
+      else  {key[0]=v1;key[1]=v2;}
+ if (!search(key,&index))
+  insert(key,index);
+}
+
+void print_table()
+{int i,j;unsigned short int pair[2];
+ unsigned short *t=table;
+ i=0; 
+ while (i<count)
+  { printf("%d\t%d\n",*t,*(t+1));
+    if (duplicates&&*t<*(t+1))
+     { pair[1]=*t;
+       pair[0]=*(t+1);
+       delete(i);
+       search(pair,&j);
+       insert(pair,j);
+     }
+    else
+     { i++;t+=2;}
+  }
+}
+int main(int argc,char **argv)
+{int i=1,j,k,rows,c,verbose=0;
+ struct option long_options[]={
+ {"help",0,0,1},
+ {"verbose",0,0,'%'},
+ {"double",0,0,'d'},
+ {NULL,0,0,0}}; 
+ while ((c=getopt_long(argc,argv,"%d",long_options,&j))!=-1)
+ { switch(c)
+   {  case '%':verbose=1;break;
+     case 'd':duplicates=1;break;   
+     case 1:
+     case '?':
+     default: help();
+   } 
+  }
+ if (argc==optind)
+  { fprintf(stderr,"No input file\n");
+    return 2;
+  }
+ file=open_epp(argv[optind]);
+ if (!file) file=open_epp(default_ext(argv[optind],".epp"));
+ if (!file) {fprintf(stderr,"Cannot open file %s\n",argv[optind]);
+             return 2;
+            }
+ set_epp_cache(file,2); 
+table=malloc(65536*2*sizeof(short int));
+ if (!table) { fprintf(stderr,"Not enough memory to allocate %d records\n",65536);
+ exit(1);
+ }
+ limit=65536;
+ delta=1024;
+ count=0;
+ rows=file->lr-file->fr;
+ install_progress_indicator(verbose?show_percent:check_int);
+ for(i=file->fr,k=1;i<file->lr;i++,k++)
+  { if (EndLineProc)
+     if ((c=(*EndLineProc)(i,k,rows)))
+      {break;} 
+  for(j=file->fc;j<file->lc;j++)
+    { add_pair((c=epp_get(file,j,i)),epp_get(file,j+1,i));
+      add_pair(c,epp_get(file,j,i+1));
+      add_pair(c,epp_get(file,j+1,i+1));
+    } 
+ }
+ if(clear_progress(c)) exit(abs(c)); 
+ print_table();
+ free(table);
+ close_epp(file);
+ return 0;
+} 
diff --git a/epu/outtab.c b/epu/outtab.c
new file mode 100644 (file)
index 0000000..4aeb629
--- /dev/null
@@ -0,0 +1,180 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "eppl_ut.h"
+#include "epp.h"
+
+/* This structure is used to keep information about 
+   combination of classes. count is count of cells already found,
+   classes are classes. Really each of these structures occupies
+   less then sizeof(struct record) bytes, becouse count of files is
+   usially less than 32 */ 
+struct record {
+               long int count;
+               unsigned short int classes[32];
+              };
+
+  
+
+
+unsigned short int* table;
+typedef struct record *rec;
+
+EPP *files[32]; /* array of pointers to files
+
+int tuple_size, /* bytes in tuple != files_count*sizeof(short)+sizeof(int)
+                   due to 4-byte alignment of
+    files_count, /* Count of files */
+    count,       /* current size of table */
+    limit,       /* number of records, currently allocated */
+    delta;       /* Increment of record number to reallocate when reserves
+                    exhausted */
+   
+/* comparation function. Sorts two records according to classes
+   of files in order 
+   returns -1 if *r1 <*r2 ,0 if *r1=*r2 1 if *r1>*r2
+*/
+int compare(struct record *r1, struct record *r2)
+{int i; 
+ for (i=0;i<files_count;i++)
+ { if (r1->classes[i]>r2->classes[i]) return 1;
+   else
+   if (r1->classes[i]<r2->classes[i]) return -1;
+ }
+ return 0;
+
+}
+
+/* Searches table for record which contains classes, specified
+   in record key. if found, returns non-zero and places index of it
+   into index. If not, returns zero and places index, where to insert
+   record into index */ 
+int search(struct record *key,int *index)
+{int l=0,h=count-1,i,c;
+ while(l<=h)
+ { i=(l+h)>>1;
+   c=compare((struct record *)(table+(tuple_size)*i),key);
+   if (c<0) l=i+1;
+   else
+   { h=i-1;
+     if (!c) { *index=i;return 1;}
+   }
+  } 
+ *index=l;
+ return 0;
+}
+/* Inserts given record into table at position index.
+   Fills count field of inserted record by 1
+ */
+void insert(struct record *key,int index)
+{ int i;long int *l;
+  if (count==limit)
+  {  
+     table=realloc(table,(limit+=delta)*(tuple_size)*sizeof(short int));
+     if (!table)
+     { fprintf(stderr,"Couldn't realloc table. Table limit is %d\n",limit);
+       exit(1);
+     }
+   }
+
+ for(i=count;i>index;i--)
+  memcpy(table+(i)*(tuple_size),table+(i-1)*(tuple_size),
+  (tuple_size)*sizeof(short int)); 
+ l=(long int *)(table+index*(tuple_size));
+ *l=1L;
+ memcpy(table+index*tuple_size+2,key->classes,files_count*sizeof(short int));
+ count++;
+} 
+/*
+   adds pixel into table, i.e. if record with such combination of classes
+   already exists, increments its count. Otherwise inserts new record.
+ */
+void add_pixel(struct record *key)
+{int index;long int *l; 
+ if (search(key,&index))
+  {
+   l=((long int *)(table+index*(tuple_size)));
+   (*l)++;
+  }
+ else insert(key,index);
+}
+
+void help()
+{ printf("Usage: outtab [-%%] files\n");
+  exit(0);
+}
+
+/*
+   Processes cell - forms record and adds it to table
+ */
+void do_cell(int x,int y)
+   { int k;
+     struct record r;
+     unsigned short int *c=r.classes;  
+     for(k=0;k<files_count;k++,c++)
+       if((*c=epp_get(files[k],x,y))==files[k]->offsite) return;
+     add_pixel(&r);
+   } 
+
+/*
+   Prints table.
+ */
+void print_table()
+{int i,j;
+ unsigned short *t;
+for(i=0,t=table;i<count;i++,t+=tuple_size)
+{ for(j=0;j<files_count;j++)
+   printf("%d,",((struct record *)t)->classes[j]);
+  printf("%ld\n",((struct record *)t)->count);
+}
+}
+/******************** main ***********************************/
+int main(int argc,char **argv)
+{int i=1,j,k,rows;
+ int verbose=0;
+ if (!strcmp(argv[1],"-%")) {verbose=1;i++;}
+ for(j=0;i<argc;i++,j++)
+ { if (j>=32) 
+   { fprintf(stderr,"To many files in command line, 32 max\n");
+     exit(1);
+   }
+   files[j]=open_epp(argv[i]);
+   if (!files[j]) files[j]=open_epp(default_ext(argv[i],".epp"));
+   if (!files[j]) { fprintf(stderr,"Cannot open file %s\n",argv[i]);
+                    exit(1);
+                  }
+   if(j){ if(files[j]->fr!=files[0]->fr||files[j]->fc!=files[0]->fc||
+             files[j]->lr!=files[0]->lr||files[j]->lc!=files[0]->lc)
+           {fprintf(stderr,"Size of file %s doesn't match.\n",argv[i]);
+            exit(1);
+           }
+         }  
+ }
+ files_count=j;
+ if (files_count%2) {
+    tuple_size=(3+files_count);
+ } else {
+    tuple_size=(2+files_count);
+ }
+ table=malloc(65536*tuple_size*sizeof(short int));
+ if (!table) { fprintf(stderr,"Not enough memory to allocate %d records\n",65536);
+ exit(1);
+ }
+ limit=65536;
+ delta=1024;
+ count=0;
+ rows=files[0]->lr-files[0]->fr;
+ install_progress_indicator(verbose?show_percent:check_int);
+ for(i=files[0]->fr,k=1;i<files[0]->lr;i++,k++)
+ { for(j=files[0]->fc;j<files[0]->lc;j++)
+    do_cell(j,i);
+    if (EndLineProc) if ((*EndLineProc)(j,k,rows)) break;
+ }
+ if (verbose) {fprintf(stderr,"\r                                        \rdone\n");}
+  print_table();
+ free(table);
+
+ for(i=0;i<files_count;close_epp(files[i++]));
+ return 0;
+} 
diff --git a/epu/outtable.c b/epu/outtable.c
new file mode 100644 (file)
index 0000000..2f1044a
--- /dev/null
@@ -0,0 +1,386 @@
+# include <stdio.h>
+# define __USE_BSD
+# include <string.h>
+# include <stdlib.h>
+# include <epp.h>
+# include <eppl_ut.h>
+# include <stdarg.h>
+# include "outtable.h"
+int
+      useOffsite=0,
+      areaInCells=0,  
+      verbose=0;
+      int fileCount=0,/* total number of files in record*/
+          funcCount=0,/* Number of functions to use */
+          openCount=0,/* Number of distinct open files */
+          baseFiles=-1;/* number of files which used to find combinations*/
+double zUnit=1.0,
+       zOffset=0.0,
+       cellArea=0.0;
+char *baseFile=NULL,
+     delimiter=',';
+EPP* fileinfo[MAX_OUTTABLE_FILES];
+EPP_LINK links[MAX_OUTTABLE_FILES];
+unsigned short int *table;
+typedef struct record *rec;
+int tuple_size, limit, delta, count;
+struct FuncItem funcList[MAX_OUTTABLE_FILES];
+struct FileInfo openFiles[MAX_OUTTABLE_FILES];
+
+void error(const char *format,...)
+{ va_list ap;
+  va_start(ap,format);
+  vfprintf(stderr,format,ap);
+  va_end(format);
+  exit(1);
+}
+void help(void)
+{ struct FuncInfo *f;
+  char sep=' '; 
+ printf("Usage: outtable [-%%][-u][-c][-d char][-b file][-z value][-Z value] files.."
+  "-function file(s)...\n");
+  printf("Where function are:\n");
+  for(f=funcTable;f->func;f++){
+   printf("%c-%s %s",sep,f->name,f->nargs==1?"file":"file file");
+   sep=',';
+  }
+  printf("\n");
+}
+void scanOpt(int *i,int argc, char **argv)
+{ 
+  /* parsing options */
+  for (*i=1;*i<argc;(*i)++) {
+    if (argv[*i][0]=='-') {
+       if (strlen(argv[*i])==2) {
+           /* short options */ 
+          switch(argv[*i][1]) {
+             case 'u' : 
+                useOffsite=0;
+                break;
+             case 'c' :
+                 areaInCells=1;
+                 break;
+             case 'b' : 
+                 baseFile=argv[++*i];
+                 break;
+             case 'd':
+                 delimiter=argv[++*i][0];
+                 break;
+              case 'z': {char *errptr;
+                  zUnit=strtod(argv[++(*i)],&errptr);
+                  if (*errptr) 
+                     error("Invalid Z unit %s\n",argv[*i]);
+               }
+              case 'Z': { char *errptr;
+                          zOffset=strtod(argv[++(*i)],&errptr);
+                          if (*errptr)
+                            error("invalid Z offset %s\n",argv[*i]);
+              }
+             case '%':
+                 verbose=1;
+                 break;
+             default: help();
+                      exit (argv[*i][1]=='h');
+          }
+      } else if (strlen(argv[*i])==3&&argv[*i][1]=='d') {
+              delimiter=argv[*i][2];
+      } else if (argv[*i][1]=='-') {
+           /* long options */
+           if (!strcmp(argv[*i],"--help")) {
+              help(); exit(0);
+           } else if (!strcmp(argv[*i],"--version")) {
+              show_version("outtable","$Revision: 1.1 $");
+              
+           } else if (!strcmp(argv[*i],"--cells")) {
+              areaInCells=1;
+           } else if (!strcmp(argv[*i],"--union")) {
+              useOffsite=1;
+           } else if (!strcmp(argv[*i],"--base")) {
+              baseFile=argv[++*i];
+           } else if (!strcmp(argv[*i],"--delimiter")) {
+              delimiter=argv[++*i][0];
+           } else {
+              help();
+              exit(1);
+           }
+        } else {
+          /* Starts with - but not recognized as option - 
+           should be function */
+           return;
+        }
+     } else {
+        /* Doesn't start with - should be filename */ 
+        return;              
+     }
+   }
+}
+
+
+
+struct FuncInfo * findFunction(char *name)
+{struct FuncInfo* f;
+ for(f=funcTable;strcmp(name,f->name)&&f->func;f++);
+ if (f->func) return f;
+    else return NULL;
+}
+void openFile(char *name) {
+int i;
+struct FileInfo *f;
+char Name[1024];
+strcpy(Name,default_ext(name,".epp"));
+for (i=0,f=openFiles;i<openCount&&strcmp(Name,f->name);i++,f++);
+  if (i<=openCount) {
+    fileinfo[fileCount++]=f->epp;
+  } else {
+
+    f->epp=open_epp(Name);
+    f->name=strdup(Name);
+    openCount++;
+    if (!f->epp) {
+       error("Couldn't open file %s\n",name);
+    }
+  }
+} 
+    
+
+void parseArgs(int i, int argc, char **argv) {
+  struct FuncInfo *func;
+  int j;
+  while (i<argc) {
+     if (argv[i][0]=='-') {
+        if (!(func=findFunction(argv[i]+1))) {
+          error("Undefined function %s\n",argv[i]);
+        }
+        /* Make function list entry */
+        funcList[funcCount].func=func->func;
+        funcList[funcCount].index=fileCount;
+        funcList[funcCount].data=malloc(func->datasize);
+        /* Note, that definition of combinations finished */ 
+        if (baseFiles<0) baseFiles=fileCount;
+        for (j=0;j<func->nargs;j++) {
+          if (i==argc) error("Not enough args for function -%s\n",func->name); 
+          openFile(argv[i++]);
+        }
+     } else {
+       if (baseFiles>=0) 
+          error("Files to define combinations should precede functions\n");
+       openFile(argv[i++]);
+     }
+   }
+}   
+
+int compare(struct record *r1, struct record *r2)
+{int i; 
+ for (i=0;i<fileCount;i++)
+ { if (r1->classes[i]>r2->classes[i]) return 1;
+   else
+   if (r1->classes[i]<r2->classes[i]) return -1;
+ }
+ return 0;
+
+}
+/* Searches table for record which contains classes, specified
+   in record key. if found, returns non-zero and places index of it
+   into index. If not, returns zero and places index, where to insert
+   record into index */ 
+int search(struct record *key,int *index)
+{int l=0,h=count-1,i,c;
+ while(l<=h)
+ { i=(l+h)>>1;
+   c=compare((struct record *)(table+(tuple_size)*i),key);
+   if (c<0) l=i+1;
+   else
+   { h=i-1;
+     if (!c) { *index=i;return 1;}
+   }
+  } 
+ *index=l;
+ return 0;
+}
+/* Inserts given record into table at position index.
+   Fills count field of inserted record by 1
+ */
+void insert(struct record *key,int index)
+{ int i;long int *l;
+  if (count==limit)
+  {  
+     table=realloc(table,(limit+=delta)*(tuple_size)*sizeof(short int));
+     if (!table)
+      error("Couldn't realloc table. Table limit is %d\n",limit);
+     
+   }
+
+ for(i=count;i>index;i--)
+  memcpy(table+(i)*(tuple_size),table+(i-1)*(tuple_size),
+  (tuple_size)*sizeof(short int)); 
+ l=(long int *)(table+index*(tuple_size));
+ *l=1L;
+ memcpy(table+index*tuple_size+2,key->classes,fileCount*sizeof(short int));
+ count++;
+} 
+/*
+   adds pixel into table, i.e. if record with such combination of classes
+   already exists, increments its count. Otherwise inserts new record.
+ */
+void add_pixel(struct record *key)
+{int index;long int *l; 
+ if (search(key,&index))
+  {
+   l=((long int *)(table+index*(tuple_size)));
+   (*l)++;
+  }
+ else insert(key,index);
+}
+
+/*
+   Processes cell - forms record and adds it to table
+ */
+void do_cell(int x,int y)
+{    int k;
+     struct record r;
+     unsigned short int *c=r.classes;  
+     for(k=0;k<fileCount;k++,c++) {
+       if (links[k]) 
+         *c=epp_get(fileinfo[k],linked_col(links[k],x),linked_row(links[k],y));
+       else
+         *c=epp_get(fileinfo[k],x,y);
+       if(*c==fileinfo[k]->offsite&&!useOffsite) return;
+     }
+     add_pixel(&r);
+} 
+/*
+ * Print combinations along with cell areas
+ *
+ */
+ void print_table(void)
+{
+ int i,j;
+ unsigned short *t;
+ for(i=0,t=table;i<count;i++,t+=tuple_size) { 
+     for(j=0;j<fileCount;j++)
+         printf("%d%c",((struct record *)t)->classes[j],delimiter);
+     if (areaInCells) 
+         printf("%ld\n",((struct record *)t)->count);
+     else 
+         printf("%0.8g\n",((struct record *)t)->count*cellArea);
+ }   
+}
+/*
+ *  Compute functions and print results
+ *
+ *
+ */
+void init_functions(void)
+{ int i;
+  struct FuncItem *f;
+  for(i=0,f=funcList;i<funcCount;i++,f++) {
+     f->func(FuncInit,f->data,NULL,f->index);
+  }
+}
+void print_row(struct record *row)
+{  int j;
+   struct FuncItem *f;
+  /* first, print away all things defining a combination */
+     for(j=0;j<fileCount;j++)
+         printf("%d%c",row->classes[j],delimiter);
+  /* second, compute all functions and print away results */    
+     for(j=0,f=funcList;j<funcCount;j++,f++)
+         printf("%g%c",f->func(FuncResult,f->data,row,f->index),
+             j==funcCount-1?'\n':delimiter);
+}
+
+void process_table(void)
+{ int i,j;
+  unsigned short *t;
+  struct record *prev=NULL;
+  struct FuncItem *f;
+  /* reset all functions persistend data */
+  init_functions();
+  fileCount=baseFiles;/* for compare to compare only files,
+                         defining combinations*/
+  for(i=0,t=table;i<count;i++,t+=tuple_size) {
+    if (prev&&compare(prev,(struct record *)t)) {
+      /* combination changed, print a row */ 
+      print_row(prev);
+      init_functions();  
+    }
+    for (j=0,f=funcList;j<funcCount;j++,f++) {
+      f->func(FuncIterate,f->data,(struct record *)t,f->index);
+    }
+    prev=(struct record *)t;
+  }
+  print_row(prev);       
+}     
+/*
+ * main program
+ */
+int main(int argc, char **argv) 
+{int i,j,k,rows;
+ EPP *base;
+ scanOpt(&i, argc, argv);
+ parseArgs(i, argc, argv);
+ if (!openCount) {
+    error("No files specified\n");
+ }
+ /* Find out base file */
+ if (!baseFile) {
+   base=fileinfo[0];
+ } else {
+   int saveCount=fileCount;
+   openFile(baseFile);
+   base=fileinfo[saveCount];
+   fileCount=saveCount;
+ }
+
+ /* Determine cell area */
+ if (areaInCells) {
+    cellArea=1.0;
+  } else {
+    cellArea=base->cell_area;
+  }
+  /* establish coordinate links */
+  for (i=0;i<fileCount;i++) {
+    if (is_aligned(base,fileinfo[i])) {
+      links[i]=NULL;
+    } else {
+      links[i]=link_epp(base,fileinfo[i]);   
+    }
+  }
+  /* create table of combinations */ 
+  if (fileCount%2) {
+    tuple_size=2+fileCount;
+  } else {
+    tuple_size=3+fileCount;
+  }
+  limit=65536;
+  delta=1024;
+  table=malloc(limit*tuple_size*sizeof(short int));
+  if (!table) 
+    error("Cannot allocate %d records\n",limit);
+  count=0;
+  /* iterate through base file */
+ rows=base->lr-base->fr;
+ install_progress_indicator(verbose?show_percent:check_int);
+ for(i=base->fr,k=1;base->lr;i++,k++)
+ { for(j=base->fc;j<base->lc;j++)
+    do_cell(j,i);
+    if (EndLineProc) if ((*EndLineProc)(j,k,rows)) {
+      clear_progress(1);  
+      exit(1);
+    }
+ }
+ clear_progress(0);
+ if (funcCount) {
+    /* there are some functions. Process them */
+    process_table();
+ } else {
+    print_table();
+ }
+ free(table);
+ for(i=0;i<openCount;i++) {
+   close_epp(openFiles[i].epp);
+ }    
+ return 0;
+}
diff --git a/epu/outtable.h b/epu/outtable.h
new file mode 100644 (file)
index 0000000..b34902e
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef OUTTABLE_H
+#define OUTTABLE_H
+#include <epp.h>
+
+#define MAX_OUTTABLE_FILES 32
+/* This structure is used to keep information about 
+   combination of classes. count is count of cells already found,
+   classes are classes. Really each of these structures occupies
+   less then sizeof(struct record) bytes, becouse count of files is
+   usially less than 32 */ 
+struct record {
+               long int count;
+               unsigned short int classes[MAX_OUTTABLE_FILES];
+              };
+/* data which outtable functions need to keep between calls */
+typedef void* FuncData;
+
+/* Action which function should take */
+typedef enum {
+    FuncInit, /* Initialize FuncData */
+    FuncIterate,/* Collect data from given record, return non-zero on failure */
+    FuncResult /* Return computed value */
+} FuncAction;
+
+/* Type for all data processing functions */
+typedef double (*OuttableFunc)(FuncAction action,/* what to do */
+          FuncData data, /* pointer to persistent data */
+         struct record *record, /*record to process */
+         int index); /* number of file in record to cope with */
+
+/* Type for record in functuon-table */
+
+struct FuncInfo {
+      char name[16]; /* how function is named in command-line */
+      OuttableFunc func; /* actual function to perform operation */
+      int nargs; /* number of file arguments */
+      int datasize; /* How many bytes to allocate for FuncData */
+};
+
+struct FuncItem {
+       OuttableFunc func;
+       FuncData data;
+       int index;
+      };
+
+struct FileInfo {
+       char *name;
+       EPP *epp;
+     };
+
+extern struct FileInfo openFiles[MAX_OUTTABLE_FILES];
+extern struct FuncInfo funcTable[];
+extern EPP* fileinfo[MAX_OUTTABLE_FILES];
+extern struct FuncItem funcList[MAX_OUTTABLE_FILES];
+extern double cellArea, zUnit, zOffset;
+#endif
diff --git a/epu/outtable_func.c b/epu/outtable_func.c
new file mode 100644 (file)
index 0000000..f92872e
--- /dev/null
@@ -0,0 +1,467 @@
+#include "outtable.h"
+#include <limits.h>
+#include <math.h>
+/* Data structures for functions */
+typedef struct n_info {
+       int count;
+       int value;
+      } n_info;
+/* Sum of the all cells in combination */
+double OuttableSum(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct n_info *info=(struct n_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->value=0;
+         info->count=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite) {
+             info->value+=record->classes[index]*record->count;
+             info->count+=record->count;
+         }
+         return 0;
+     case FuncResult:
+         return zUnit*info->value+zOffset*info->count;
+  
+  }
+  return 0;
+}
+   
+/* Count of the non-offsite cells for given file in combination */
+double OuttableCount(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *sum=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *sum=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite)
+             *sum+=record->count;
+         return 0;
+     case FuncResult:
+         return *sum*cellArea;
+  
+  }
+  return 0;
+}
+/* Average of the all cells in combination */
+struct avg_info {
+      long sum;
+      int count;
+      };
+double OuttableAvg(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct avg_info *info=(struct avg_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->sum=0;
+         info->count=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite) {
+             info->sum+=record->classes[index]*record->count;
+             info->count+=record->count;
+         }
+         return 0;
+     case FuncResult:
+         if (info->count)
+            return (zUnit*info->sum/info->count)+zOffset;
+         else return 0;
+  
+  }
+  return 0;
+}
+/* Minimal cell value  in combination */
+double OuttableMin(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *min=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *min=65536;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->classes[index]<*min)
+             *min=record->classes[index];
+         return 0;
+     case FuncResult:
+         return *min*zUnit+zOffset;
+  
+  }
+  return 0;
+}
+
+/* Count of cell with minimal  value  in combination */
+double OuttableNMin(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct n_info *info=(n_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->value=65536;
+         info->count=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->classes[index]<info->value) {
+               info->value=record->classes[index];
+               info->count=record->count;
+             }
+         return 0;
+     case FuncResult:
+         return info->count*cellArea;
+  
+  }
+  return 0;
+}
+
+/* Maximal cell value  in combination */
+double OuttableMax(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *max=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *max=-1;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->classes[index]>*max)
+             *max=record->classes[index];
+         return 0;
+     case FuncResult:
+         return *max*zUnit+zOffset;
+  
+  }
+  return 0;
+}
+
+/* Count of cell with maximal  value  in combination */
+double OuttableNMax(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct n_info *info=(n_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->value=-1;
+         info->count=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->classes[index]>info->value) {
+               info->value=record->classes[index];
+               info->count=record->count;
+             }
+         return 0;
+     case FuncResult:
+         return info->count*cellArea;
+  
+  }
+  return 0;
+}
+/* Count of cells with most frequent value  in combination */
+double OuttableNMode(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *max=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *max=-1;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->count>*max)
+             *max=record->count;
+         return 0;
+     case FuncResult:
+         return *max*cellArea;
+  
+  }
+  return 0;
+}
+
+/* Most frequent cell value  in combination */
+double OuttableMode(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct n_info *info=(n_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->value=-1;
+         info->count=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->count>info->count) {
+               info->value=record->classes[index];
+               info->count=record->count;
+             }
+         return 0;
+     case FuncResult:
+         return info->value*zUnit+zOffset;
+  
+  }
+  return 0;
+}
+/* Count of cells with rarest value in combination */
+double OuttableNFewest(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *min=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *min=INT_MAX;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->count<*min)
+             *min=record->count;
+         return 0;
+     case FuncResult:
+         return *min*cellArea;
+  
+  }
+  return 0;
+}
+
+/* Rarest cell value in combination  */
+double OuttableFewest(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct n_info *info=(n_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->value=0;
+         info->count=INT_MAX;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite &&
+             record->count<info->count) {
+               info->value=record->classes[index];
+               info->count=record->count;
+             }
+         return 0;
+     case FuncResult:
+         return info->value*zUnit+zOffset;
+  
+  }
+  return 0;
+}
+/* Range of classes in cell */
+typedef struct r_info {
+       int max,min;
+    } r_info;
+double OuttableRange(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct r_info *info=(r_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->max=0;
+         info->min=INT_MAX;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite) {
+            if (record->classes[index]<info->min) 
+               info->min=record->classes[index];
+            if (record->classes[index]>info->max)
+               info->max=record->classes[index];
+         }
+         return 0;
+     case FuncResult:
+         return (info->max-info->min)*zUnit;
+  
+  }
+  return 0;
+}
+
+/* count of distinct classes. Note that function can be called more than once
+   for each distinct class (if there are more functions), so we need to 
+   keep track on found classes in bit table */
+#define BIT_TABLE_LENGTH (8192/sizeof(int))
+struct c_info {
+        int found; 
+        int bittable[BIT_TABLE_LENGTH];
+       }; 
+double OuttableClasses(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ struct c_info *info=(struct c_info*) data;
+  int i,mask;
+  switch (action) {
+     case FuncInit:
+         info->found=0;
+         for (i=0;i<BIT_TABLE_LENGTH;i++) info->bittable[i]=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite) {
+           i=record->classes[index]/(sizeof(int)*8);
+           mask=1<<record->classes[index]%(sizeof(int)*8);
+           if (!(info->bittable[i]&mask)) {
+              info->found++;
+              info->bittable[i]|=mask;
+           }  
+         }
+         return 0;
+     case FuncResult:
+         return info->found;
+  
+  }
+  return 0;
+}
+/* Bitwise OR of all values. Why Pete Olson was so proud of this
+   function adding it in EPPL ver 2.1? */
+double OuttableOr(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *res=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *res=0;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite)
+             *res|=record->classes[index];
+         return 0;
+     case FuncResult:
+         return *res;
+  
+  }
+  return 0;
+}
+
+/* Bitwise And of all values in combination  */
+double OuttableAnd(FuncAction action, FuncData data, struct record *record,
+                int index)
+{ int *res=(int *)data;
+  switch (action) {
+     case FuncInit:
+         *res=65535;
+         return 0;
+     case FuncIterate:
+         if (record->classes[index]!=fileinfo[index]->offsite)
+             *res&=record->classes[index];
+         return 0;
+     case FuncResult:
+         return *res;
+  
+  }
+  return 0;
+}
+
+/* Standard deviation of all values in combination, biased */
+struct var_info {
+         double sum;
+         double sumsq;
+         int count;
+       };
+double OuttableStd(FuncAction action, FuncData data, struct record *record,
+               int index)
+{ struct var_info *info=(struct var_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->count=0;
+         info->sum=0;
+         info->sumsq=0;
+        return 0;
+     case FuncIterate:
+        if (record->classes[index]!=fileinfo[index]->offsite) { 
+              info->count +=record->count;
+              info->sum   +=record->count*record->classes[index];
+              info->sumsq +=record->count*record->classes[index]*record->
+                             classes[index];
+         }
+        return 0;
+     case FuncResult:
+         if (info->count<2) return 0;
+         return sqrt((info->sumsq-(info->sum*info->sum/info->count))/
+                       (info->count))*zUnit;
+          
+  }
+  return 0;
+}
+/*Variance of cell values, biased*/
+double OuttableVar(FuncAction action, FuncData data, struct record *record,
+               int index)
+{ struct var_info *info=(struct var_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->count=0;
+         info->sum=0;
+         info->sumsq=0;
+        return 0;
+     case FuncIterate:
+        if (record->classes[index]!=fileinfo[index]->offsite) { 
+              info->count +=record->count;
+              info->sum   +=record->count*record->classes[index];
+              info->sumsq +=record->count*record->classes[index]*record->
+                             classes[index];
+         }
+        return 0;
+     case FuncResult:
+         if (info->count<2) return 0;
+         return ((info->sumsq-(info->sum*info->sum/info->count))/
+                       (info->count-1))*zUnit*zUnit;
+          
+  }
+  return 0;
+}
+
+/* correlation of cell values in files index and index+1, multiplied by 100 */
+typedef struct cov_info {
+         double sumx;
+         double sumy;
+         double sumxy;
+         double sumxsq;
+         double sumysq;
+         int count;
+       } cov_info; 
+double OuttableCorr(FuncAction action, FuncData data, struct record *record,
+               int index)
+{ struct cov_info *info=(struct cov_info *)data;
+  switch (action) {
+     case FuncInit:
+         info->count=0;
+         info->sumx=0;
+         info->sumxsq=0;
+         info->sumy=0;
+         info->sumysq=0;
+         info->sumxy=0;
+        return 0;
+     case FuncIterate:
+        if (record->classes[index]!=fileinfo[index]->offsite&&
+             record->classes[index+1]!=fileinfo[index+1]->offsite) { 
+              info->count +=record->count;
+              info->sumx   +=record->count*record->classes[index];
+              info->sumxsq +=record->count*record->classes[index]*record->
+                             classes[index];
+              info->sumy   +=record->count*record->classes[index+1];
+              info->sumysq +=record->count*record->classes[index+1]*record->
+                             classes[index+1];
+              info->sumxy  +=record->count*record->classes[index]*
+                                           record->classes[index+1];
+         }
+        return 0;
+     case FuncResult:
+         if (info->count<2) return 0;
+         return (info->sumxy-(info->sumx*info->sumy/info->count))/
+               sqrt((info->sumxsq-(info->sumx*info->sumx/info->count))*
+                    (info->sumysq-(info->sumy*info->sumy/info->count)));
+          
+  }
+  return 0;
+}
+
+struct FuncInfo funcTable[]={
+{"sum",OuttableSum,1,sizeof(int)},
+{"cnt",OuttableCount,1,sizeof(int)},
+{"avg",OuttableAvg,1,sizeof(struct avg_info)},
+{"min",OuttableMin,1,sizeof(int)},
+{"nmin",OuttableNMin,1,sizeof(struct n_info)},
+{"max",OuttableMax,1,sizeof(int)},
+{"nmax",OuttableNMax,1,sizeof(struct n_info)},
+{"mode",OuttableMode,1,sizeof(struct n_info)},
+{"nmode",OuttableNMode,1,sizeof(int)},
+{"fewest",OuttableFewest,1,sizeof(struct n_info)},
+{"nfewest",OuttableNFewest,1,sizeof(int)},
+{"range",OuttableRange,1,sizeof(struct r_info)},
+{"classes",OuttableClasses,1,sizeof(struct c_info)},
+{"or",OuttableOr,1,sizeof(int)},
+{"and",OuttableAnd,1,sizeof(int)},
+{"std",OuttableStd,1,sizeof(struct var_info)},
+{"var",OuttableVar,1,sizeof(struct var_info)},
+{"corr",OuttableCorr,2,sizeof(struct cov_info)},
+{"",NULL,0,0},
+};
diff --git a/epu/points.tab b/epu/points.tab
new file mode 100644 (file)
index 0000000..9b5fe55
--- /dev/null
@@ -0,0 +1,262 @@
+    1,       456.8,         0.2
+    2,      1865.6,      1127.4
+    3,      1951.6,      1298.6
+    4,        1784,      1268.6
+    5,      1928.4,      1276.2
+    6,      1892.8,      1268.2
+    7,        1980,      1268.2
+    8,      1980.8,      1267.8
+    9,      1887.2,      1264.2
+   10,      1983.6,      1266.6
+   11,       961.2,      1242.6
+   12,         976,        1229
+   13,       980.8,      1236.2
+   14,        1028,      1228.2
+   15,      1015.2,      1221.4
+   16,      1020.4,      1223.8
+   17,        1006,      1212.6
+   18,       966.8,      1220.2
+   19,       998.4,      1217.8
+   20,      1008.8,      1218.6
+   21,      1023.6,      1217.4
+   22,      1015.6,        1217
+   23,      1044.8,      1213.4
+   24,       990.4,      1213.8
+   25,       967.2,      1213.4
+   26,       982.4,      1211.4
+   27,      1002.4,      1210.2
+   28,        1016,      1212.2
+   29,      1016.8,      1210.6
+   30,      1025.6,      1204.2
+   31,       990.8,        1205
+   32,      1003.2,      1198.2
+   33,       995.2,      1198.6
+   34,      1018.8,      1195.8
+   35,      1040.4,      1191.8
+   36,         998,      1197.4
+   37,      1792.4,      1187.4
+   38,      1004.8,      1185.4
+   39,      1978.4,      1167.8
+   40,      1990.4,      1167.4
+   41,        1990,        1167
+   42,        1928,        1165
+   43,      1111.2,      1160.2
+   44,      1926.4,      1159.8
+   45,       632.8,      1087.4
+   46,      1168.8,      1153.8
+   47,      1188.8,      1135.8
+   48,        1772,        1149
+   49,      1987.6,        1145
+   50,        1988,      1143.8
+   51,      1983.6,      1141.4
+   52,         656,      1138.6
+   53,        1172,      1132.2
+   54,      1179.2,      1129.4
+   55,      1174.4,      1119.4
+   56,      1197.2,        1103
+   57,        1178,        1123
+   58,      1554.8,      1112.2
+   59,       501.6,        1013
+   60,      1203.6,      1117.4
+   61,      1202.4,        1115
+   62,      1200.8,        1113
+   63,      1176.8,        1111
+   64,      1176.8,      1107.8
+   65,      1233.2,      1080.6
+   66,      1486.8,      1074.6
+   67,        1952,        1023
+   68,        1210,      1100.2
+   69,      1519.6,       755.8
+   70,         228,      1064.2
+   71,         840,      1032.2
+   72,      1230.4,      1090.6
+   73,        1230,      1089.8
+   74,       219.2,      1083.8
+   75,         232,      1082.6
+   76,      1739.6,      1078.6
+   77,         590,        1077
+   78,      1995.6,      1075.8
+   79,      1254.8,      1074.2
+   80,       887.2,      1073.4
+   81,        1260,        1071
+   82,       891.6,      1071.8
+   83,      1465.2,      1064.2
+   84,      1180.8,       913.8
+   85,       870.4,        1057
+   86,       891.2,      1057.4
+   87,       891.6,        1057
+   88,      1516.4,        1051
+   89,         582,      1054.2
+   90,         444,         977
+   91,      1531.6,      1044.6
+   92,       668.8,      1051.8
+   93,       667.6,      1050.6
+   94,      1145.6,      1049.8
+   95,         878,      1047.8
+   96,      1140.4,      1045.8
+   97,       416.8,      1045.4
+   98,       416.4,        1045
+   99,         874,      1042.6
+  100,       869.2,      1041.4
+  101,      1189.6,      1039.4
+  102,      1252.8,      1041.4
+  103,         870,        1041
+  104,      1575.6,      1032.6
+  105,      1588.8,      1025.8
+  106,       445.2,      1014.2
+  107,       337.6,       989.4
+  108,        1524,      1032.2
+  109,      1485.2,      1029.8
+  110,       788.8,       921.8
+  111,       573.2,       936.6
+  112,      2006.4,      1025.4
+  113,        1818,         861
+  114,       828.8,      1020.2
+  115,      1082.8,        1011
+  116,      1305.2,      1011.8
+  117,        1172,      1009.4
+  118,       753.2,       999.4
+  119,      1184.8,      1008.2
+  120,      1921.2,      1007.8
+  121,         582,      1006.6
+  122,      1183.6,      1006.6
+  123,       579.2,      1005.4
+  124,       386.4,       971.8
+  125,       978.4,       985.4
+  126,       832.8,       986.6
+  127,      1110.4,       983.4
+  128,       647.2,       982.2
+  129,         966,       749.4
+  130,      1430.4,         981
+  131,       363.2,       979.8
+  132,      1019.6,         975
+  133,      1312.4,       971.4
+  134,       470.4,       930.2
+  135,      1542.8,       969.4
+  136,       846.4,       961.4
+  137,      1005.6,       966.2
+  138,       400.4,       911.4
+  139,        1022,       964.6
+  140,         782,       964.2
+  141,       783.6,       963.8
+  142,      1115.6,       963.8
+  143,        1454,       963.8
+  144,      1365.2,       960.6
+  145,      1515.2,       960.2
+  146,      1516.8,       958.6
+  147,      1041.6,         949
+  148,       313.2,       915.8
+  149,      1026.4,       942.2
+  150,        1992,         941
+  151,       696.8,         841
+  152,      1488.8,       933.4
+  153,      2123.2,       919.4
+  154,        2116,       915.8
+  155,       442.4,       882.6
+  156,      2092.4,       903.4
+  157,         282,       870.6
+  158,       379.6,       868.6
+  159,        2032,       786.6
+  160,       319.6,       869.4
+  161,       492.4,       841.8
+  162,       415.6,         823
+  163,       447.6,       833.4
+  164,       339.6,       831.4
+  165,         302,       835.4
+  166,       550.4,       777.4
+  167,       271.2,         821
+  168,       804.4,       717.4
+  169,      1196.8,       724.2
+  170,       888.8,       822.6
+  171,       379.2,       801.8
+  172,       358.8,       824.2
+  173,         446,       782.2
+  174,      1112.8,       478.2
+  175,      1832.4,       475.4
+  176,       325.2,       791.8
+  177,         272,       780.6
+  178,       992.4,       807.8
+  179,       626.8,       756.2
+  180,       304.8,       750.6
+  181,       353.2,         755
+  182,       408.4,         769
+  183,       503.2,       756.6
+  184,       615.6,       704.2
+  185,      1838.4,       783.8
+  186,         406,       720.2
+  187,       697.2,         663
+  188,       474.8,       751.4
+  189,       569.2,       722.2
+  190,       505.6,         717
+  191,       444.4,       712.6
+  192,         402,       661.4
+  193,      2057.2,         733
+  194,         320,         671
+  195,         236,       669.8
+  196,       183.2,       669.4
+  197,       204.4,       703.8
+  198,      2094.4,       682.2
+  199,       141.6,       698.6
+  200,         142,       698.2
+  201,      2091.6,       695.8
+  202,       462.4,       662.2
+  203,        1284,         463
+  204,       550.4,       635.4
+  205,       436.8,       685.4
+  206,       437.6,       685.4
+  207,       170.8,       639.4
+  208,         492,       614.2
+  209,        2100,       654.2
+  210,         758,       597.8
+  211,       212.8,       604.2
+  212,       638.4,       610.6
+  213,       266.8,         591
+  214,       958.4,       557.4
+  215,       302.4,       558.6
+  216,       151.2,       635.4
+  217,      2105.2,       633.4
+  218,      2106.4,         631
+  219,       683.2,       580.2
+  220,      1936.4,       521.8
+  221,       165.6,       595.4
+  222,       804.8,       520.6
+  223,      1867.6,       606.2
+  224,      1879.6,       599.8
+  225,      1880.8,       598.6
+  226,        1882,       598.6
+  227,      2111.6,       598.2
+  228,      2112.8,         597
+  229,       181.6,       568.6
+  230,      2113.2,       575.4
+  231,      1850.8,       572.6
+  232,      1689.2,       458.6
+  233,        1910,         565
+  234,       213.6,         491
+  235,      1708.8,       559.8
+  236,       188.8,       542.6
+  237,      1501.6,       401.8
+  238,       212.4,       530.2
+  239,       889.6,       483.4
+  240,       281.6,       543.8
+  241,      2104.8,         519
+  242,      1412.4,         445
+  243,       244.4,       509.4
+  244,      2090.4,       478.6
+  245,        1010,       455.8
+  246,       783.2,       483.4
+  247,      1340.4,       377.8
+  248,      1056.8,         391
+  249,       947.6,         387
+  250,        2076,       438.6
+  251,      2003.6,         441
+  252,      1877.2,         347
+  253,      2095.6,       434.6
+  254,      1785.2,       381.8
+  255,      1278.8,         381
+  256,      1143.6,       336.6
+  257,         986,         333
+  258,        1018,       362.2
+  259,      1468.4,         339
+  260,      1288.8,         349
+  261,      1290.8,       346.2
+  262,        1024,       344.6
diff --git a/epu/project b/epu/project
new file mode 100755 (executable)
index 0000000..efd5d60
Binary files /dev/null and b/epu/project differ
diff --git a/epu/project.c b/epu/project.c
new file mode 100644 (file)
index 0000000..d7b662f
--- /dev/null
@@ -0,0 +1,373 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <epp.h>
+#include <eppl_ut.h>
+#include <projects.h>
+#include <getopt.h>
+#include <sys/mman.h>
+PJ *in_proj=NULL,*out_proj=NULL;
+int positive_west=0;/* Whether to adjust west hemisphere coords to range 
+                      180-360 from range -180-0 */
+EPP *infile,*outfile;
+/* This function does perform actual projection conversion
+   It computes long/lat data from current cell and then computes
+   cell on input map to get value from */
+int project_cell(int col, int row, int value) {
+   UV out,ll,in;
+   int in_row,in_col;
+   out.u=alt_xc(outfile,col);
+   out.v=alt_yc(outfile,row);
+   if (out_proj) {
+     ll=pj_inv(out,out_proj);
+   } else {
+       if (positive_west&&out.u>180) {
+          out.u-=360.0;
+       }              
+       ll.u=out.u*DEG_TO_RAD;
+       ll.v=out.v*DEG_TO_RAD;
+          
+   }    
+   if (ll.u == HUGE_VAL || ll.v == HUGE_VAL) {
+     return value;
+   } 
+   if (in_proj) {
+   in=pj_fwd(ll,in_proj);
+   } else {
+       in.u=ll.u*RAD_TO_DEG;
+       if (positive_west && in.u<0) {
+          in.u+=360.0;
+       }          
+       in.v=ll.v*RAD_TO_DEG;
+   }    
+   in_row=epp_row(infile,in.v);
+   in_col=epp_col(infile,in.u);
+   return epp_get(infile,in_col,in_row);
+}
+
+void help(exitcode) {
+   printf("Usage: project [-%%] {-b basefile|-c cellsize -l xl,yb,xr,yt} [-i source_proj]\n\t"
+   "[-p target_proj] -o outfile -O offsite {-r rows_to_cache|-x [tmpdir]} file\n"
+  "Projection definition can be either file name or list of comma separated\n"
+  "name=value pairs. If either input or output projection omitted, it is assumed\n"
+  "to be geographic coords\n");
+  exit(exitcode);
+} 
+PJ* get_projection(const char *source);
+void expand_epp(EPP *epp,const char *tempdir,int verbose);
+void check_hemisphere(EPP *epp);
+int main(int argc,char **argv) {
+struct option long_options[]={
+  {"help",0,0,1},
+  {"version",0,0,2},
+  {"verbose",0,0,'%'},
+  {"base-file",1,0,'b'},
+  {"cell-size",1,0,'c'},
+  {"source-projection",1,0,'i'},
+  {"output-file",1,0,'o'},
+  {"target-projection",1,0,'p'},
+  {"offsite",1,0,'O'},
+  {"cache-rows",1,0,'r'},
+  {"expand",2,0,'x'},
+  {"limits",1,0,'l'}
+  };
+char outname[1024]="project.out.epp";
+char tmpdir[1024]="/tmp";
+char *basefilename=NULL,*errptr;
+int limits_flag=0,result,offsite_flag=0,offsite=0,cache_size=0,expand_flag=0;
+double xright=0,xleft=0,ybottom=0,ytop=0,cellsize = 0;
+int c,index,verbose=0;
+  while ((c=getopt_long(argc,argv,"c:i:o:p:O:r:x::l:b:%",long_options,&index))
+            !=-1) {
+      switch (c) {
+         case 2: show_version("project","$Revision: 1.1 $");
+          case '%': verbose = 1; break;
+          case 'b' : if (cellsize !=0 || limits_flag) {
+                        fprintf(stderr,"basefile cannot be combined with" 
+                                "explicit coordinate parameters\n");
+                        exit(1);
+                     }
+                    if (basefilename) {
+                        fprintf(stderr,"Duplicate basefile specification\n");
+                        exit(1);
+                    }           
+                    basefilename=strdup(default_ext(optarg,".epp"));
+                    break;
+         case 'c' : if (basefilename) {
+                      fprintf(stderr,"cannot use cell size and"
+                                     "basefile at the same time\n");
+                      exit(1);
+                    }
+                    cellsize=strtod(optarg,&errptr);
+                    if (*errptr || cellsize<=0) {
+                        fprintf(stderr,"invalid cellsize %s\n",optarg);
+                        exit(1);
+                    }
+                    break;
+         case  'i' : in_proj=get_projection(optarg);
+                     if (!in_proj) exit(1);
+                     break;
+         case 'l' :  if (basefilename) {
+                        fprintf(stderr,"Cannot use both basefile" 
+                                "and limits\n");
+                        exit(1);
+                     }
+                     if (limits_flag) {
+                         fprintf(stderr,"Duplicate limit specification\n");
+                         exit(1);
+                     }   
+                     xleft = strtod(optarg,&errptr);
+                     while (strchr(",;\n \t",*errptr)) errptr++;
+                     if (!*errptr) {
+                          fprintf(stderr,"Invalid limits");
+                          exit(1);
+                     }            
+                     ybottom = strtod(errptr,&errptr);
+                     while (strchr(",;\n \t",*errptr)) errptr++;
+                     if (!*errptr) {
+                          fprintf(stderr,"Invalid limits");
+                          exit(1);
+                     }            
+                     xright = strtod(errptr,&errptr);
+                     while (strchr(",;\n \t",*errptr)) errptr++;
+                     if (!*errptr) {
+                          fprintf(stderr,"Invalid limits");
+                          exit(1);
+                     }            
+                     ytop = strtod(errptr,&errptr);
+                     if (*errptr) {
+                          fprintf(stderr,"Invalid limits");
+                          exit(1);
+                     }
+                     limits_flag=1;
+                     break;
+          case 'p'  : out_proj=get_projection(optarg);
+                     if (!out_proj) exit(1);
+                     if (!out_proj->inv) {
+                         fprintf (stderr,"Cannot project - inverse "
+                                 "transformation for output projection"
+                                 "unavailable\n");
+                         exit(1);
+                     }
+                     break;
+         case 'o'  : strncpy(outname,default_ext(optarg,".epp"),1023);
+                    outname[1023]=0;
+                     break;
+         case 'O' : offsite = strtol(optarg,&errptr,0);
+                   if (*errptr || offsite<0 || offsite>65535) {
+                        fprintf(stderr,"Invalid offsite value %s\n",optarg);
+                        exit(1);
+                   }
+                    offsite_flag=1;
+                   break;
+        case 'r' : cache_size = strtol(optarg,&errptr,0);
+                   if (*errptr || cache_size<0 || cache_size>30000) {
+                       fprintf(stderr,"Invalid cache size:%s\n",optarg);
+                       exit(1);
+                   }   
+                   break;
+        case 'x' : expand_flag=1;
+                   if (optarg) {
+                      strncpy(tmpdir,optarg,1023);
+                      tmpdir[1023]=0;
+                   }   
+                   break;
+        default: {
+                  help(c==1?0:1);
+        }
+      }                        
+   }    
+   if (cache_size && expand_flag) {
+      fprintf(stderr,"cannot use cache and expanding to temp dir"
+             "simulateously\n");
+      exit(1);
+   }    
+   if (!in_proj) {
+       if (!out_proj) {
+          fprintf(stderr,"Neither input nor output projection specified\n");
+          exit(1);
+       } else {
+        fprintf(stderr,"input projection is not specified, assuming latlong\n");
+       }
+   } else if (!out_proj) {
+       fprintf(stderr,"Output projection is not specified, assuming latlong\n");
+   }
+   if (optind>=argc) {
+       fprintf(stderr,"No input file specified\n");
+       exit(1);
+   }
+   
+   infile=open_epp(default_ext(argv[optind],".epp"));
+   if (!infile) {
+        perror("open input file");
+       exit(2);
+   }
+   if (!in_proj) {
+       check_hemisphere(infile);
+   }   
+   if (cache_size) {
+       set_epp_cache(infile,cache_size);
+   }   
+   if (!offsite_flag) {
+     offsite = infile->offsite;
+   }
+   Create16bit=infile->kind==16;
+   if (basefilename) {
+       EPP *basefile;
+       basefile=open_epp(basefilename);
+       if (!basefile) {
+          perror("open base file");
+          exit(2);
+       }
+       outfile=creat_epp_as(outname,basefile); 
+       if (!outfile) {
+          perror("opening output file\n");
+          exit(1);
+       }   
+          outfile->offsite=offsite;
+       close_epp(basefile);       
+   } else {
+      int rows;int cols;
+      if (!limits_flag || cellsize==0) {
+         fprintf(stderr,"output file geometry is not specified\n");
+         exit(2);
+      }          
+      rows=ceil(fabs(ytop-ybottom)/cellsize);
+      cols=ceil(fabs(xright-xleft)/cellsize);
+      if (ybottom<ytop) {
+         ytop=ybottom+rows*cellsize;
+      } else {
+         ytop=ybottom-rows*cellsize;
+      }
+      if (xleft<xright) {
+         xright=xleft+cols*cellsize;
+      } else {
+         xright=xleft-cols*cellsize;
+      }
+      outfile=creat_epp(outname,1,1,cols,rows,xleft,ytop,xright,ybottom,
+             0,0,offsite);
+      if (!outfile) {
+         perror("opening output file");
+      }          
+   }  
+   if (!out_proj) {
+       check_hemisphere(outfile);
+   }    
+   if (expand_flag) {
+       expand_epp(infile,tmpdir,verbose);
+   }
+   install_progress_indicator(verbose?show_percent:check_int);
+   result=clear_progress(for_each_cell(outfile,project_cell));
+   if (result) {
+       return abs(result);
+   }
+   close_epp(outfile);
+   if (expand_flag) {
+       infile->row=malloc(1);
+       munmap(infile->cache,infile->width*(infile->lr-infile->fr)*
+              sizeof(unsigned short));
+       close(infile->cache_size);             
+   }    
+   close_epp(infile);
+   return(0);
+}  
+
+PJ* get_projection(const char *source) {
+    char *work_area,*token,**args;
+    int argc,limit=16;
+    PJ *pj;
+    if (!strchr(source,'=')) {
+       FILE *f=fopen(default_ext(source,".prj"),"r");
+       int size;
+       if (!f) {
+         perror(default_ext(source,".prj"));
+         exit(2);
+       }
+       fseek(f,0,SEEK_END);
+       size = ftell(f);
+       fseek(f,0,SEEK_SET);
+       work_area=malloc(size+1);
+       if(fread(work_area,1,size,f)!=size) {
+          perror(default_ext(source,"prj"));
+          exit(2);
+       }
+       work_area[size]=0;
+       fclose(f);
+    } else {
+       work_area = strdup(source);
+    }
+    args=calloc(limit,sizeof(char *));
+    argc=0;
+    token=strtok(work_area,",;\n \r\t");
+    do {
+     args[argc++]=token;
+     if (argc>=limit) {
+       args=realloc(args,(limit+=16)*(sizeof(char *)));
+     }
+    } while ((token = strtok(NULL,",;\n \r\t")));
+    pj = pj_init(argc,args);
+    free(work_area);
+    free(args);
+    if (!pj) { fprintf(stderr,"Invalid projection definition: %s\n",
+           source);
+          exit(2);
+    }
+    return pj;
+ }    
+ void position_mmap(EPP *epp,int row) {
+     epp->row=((unsigned short*) epp->cache)+(epp->width)*(row-epp->fr);
+     epp->currentline=row;
+}     
+void expand_epp(EPP *epp,const char* tmpdir, int verbose) {
+   int fd,i,k,n,row_size;
+   char tempname[1048]="/tmp";
+   if (tmpdir && *tmpdir) {
+      strcpy(tempname,tmpdir);
+   }
+   strcat(tempname,"/eppXXXXXX");
+   /* We use mkstemp rather than POSIX tmpfile here, becouse we need
+    * to have control over place where file is created. I don't expect
+    * that everybody have few gigabytes free in /tmp for unpacking large
+    * map
+    */
+   fd=mkstemp(tempname);
+   unlink(tempname); 
+   /*file has mode 0666, so it is better to not show it to anyone*/
+   if (verbose) {
+     fprintf(stderr,"unpacking...\n");
+     install_progress_indicator(show_percent);
+   } else {
+     install_progress_indicator(check_int);
+   }   
+   n=epp->lr - epp->fr;
+   row_size=epp->width*sizeof(unsigned short);
+   for (i=epp->fr,k=1;i<epp->lr;i++,k++) {
+       epp_get(epp,epp->fc,i);
+       if (write(fd,epp->row,row_size)!=row_size) {
+          fprintf(stderr,"Not enough space for temporary file\n");
+          exit(2);
+       }   
+       if(EndLineProc(i,k,n)) {
+          clear_progress(1);
+          exit(2);
+       } 
+   }   
+   clear_progress(0);
+   free(epp->row);
+   lseek(fd,0,SEEK_SET);
+   epp->cache=mmap(NULL,row_size*n,PROT_READ,MAP_SHARED,fd,0);
+   if (epp->cache==MAP_FAILED) {
+       perror("mmap");
+       exit(2);
+   }   
+   epp->position=position_mmap;
+   infile->cache_size=fd;
+}
+
+void check_hemisphere(EPP *epp) {
+    if (epp->XLeft>=0 && epp->XRight>=180) {
+       fprintf(stderr,"Western hemisphere coords would be adjusted\n");
+        positive_west=1;
+    }
+}    
diff --git a/epu/reclass1.c b/epu/reclass1.c
new file mode 100644 (file)
index 0000000..d344e7d
--- /dev/null
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "epp.h"
+#include "eppl_ut.h"
+#include "reclass.h"
+#define required_argument 1
+  FILE *input_stream;
+  short int *table;
+  EPP *infile;
+int reclass_getc()
+{ return fgetc(input_stream);
+}
+int get_cell(int col,int row,int value)
+{ return table[epp_get(infile,col,row)];
+}
+int main(int argc,char **argv)
+{ char outname[256]="reclass.out.epp"; 
+  char filename[256];      
+  struct option long_options[]={
+  {"help",0,0,1},
+  {"version",0,0,2},
+  {"verbose",0,0,'%'},
+  {"file",required_argument,0,'f'},
+  {"output-file",required_argument,0,'o'},
+  {NULL,0,0,0} };
+  int c;
+  int index,verbose=0;
+  EPP *outfile;  
+  input_stream=stdin;
+   
+  while ((c=getopt_long(argc,argv,"%f:o:",long_options,&index))!=-1)
+  { switch(c)
+    { case 2:/* version */show_version("reclass","$Revision: 1.1 $");
+      case '%':verbose=1;break;
+      case 'o':strcpy(outname,default_ext(optarg,".epp"));
+      case 'f':if((input_stream=fopen(optarg,"r"))==NULL) 
+               {fprintf(stderr,"Cannot open reclass file %s\n",optarg);
+                return 1;
+               } else break;
+      case 1:/*help*/
+      case '?':
+      default:
+             printf("Usage %s [--help] [--version] [-v] [-f reclass_file]\n"
+                    "[-o output_file] file_to_reclass\n",argv[0]);
+             return c==1?0:2; 
+    }
+  }
+  if (argc==optind)
+    { fprintf(stderr,"No input files specified\n");
+      return 2; 
+    }
+  if (argc>=optind+2)
+    { fprintf(stderr,"Too many input files\n");
+      return 2;
+    }
+      
+  infile=open_epp(default_ext(argv[optind],".epp"));    
+  if (!infile) { fprintf(stderr,"Cannot open input file\n");
+              return 1;
+            }
+  Create16bit=1; 
+  outfile=creat_epp_as(outname,infile);
+  if (!outfile){ fprintf(stderr,"Cannot create output file\n");
+                 return 1;
+               }
+  if (input_stream==stdin&&isatty(0))
+  {
+   printf("Enter reclass statements. Press ^D to end.\n");
+   interactive_parser=1;
+  }
+  /* init reclass table */
+  if (!(table=make_reclass_table(infile,reclass_getc)))
+      { unlink(outname);return 1;}
+  if (table[infile->offsite]!=infile->offsite)
+   outfile->offsite=table[infile->offsite];
+   install_progress_indicator(verbose?show_percent:check_int);
+  for_each_cell(outfile,get_cell);
+  close_epp(infile);
+  if (outfile->max<255){
+    fast_convert_to_8bit(outfile,strcat(strcpy(filename,outname),".8bit"));
+    unlink(outname);
+    rename(filename,outname);
+  }
+  else
+  close_epp(outfile);
+  clear_progress(0);  
+ return 0;
+}
diff --git a/epu/tag2epp.c b/epu/tag2epp.c
new file mode 100644 (file)
index 0000000..ee7caf9
--- /dev/null
@@ -0,0 +1,32 @@
+/* 
+ * converts tag file to epp file
+ */
+
+
+
+
+
+int main(int argc,char **argv)
+{char output_file[1024]="clip.out.epp";
+ struct option long_options[]=
+{ 
+ {"help",0,0,1},
+ {"version",0,0,2},
+ {"linear",0,0,'l'}, /* óÞÉÔÁÔØ, ÞÔÏ ÔÜÇ ÓÕÔØ ×ÅÝÅÓÔ×ÅÎÎÏÅ ÞÉÓÌÏ É ÉÓÐÏÌØÚÏ×ÁÔØ
+                        ÌÉÎÅÊÎÕÀ ÆÕÎËÃÉÀ ÄÌÑ ÐÒÅÏÂÒÁÚÏ×ÁÎÉÑ ÅÇÏ × ËÌÁÓÓ */
+ {"max",1,0,'x'}, /* ÚÁÄÁÔØ ÍÁËÓÉÍÁÌØÎÏÅ ÚÎÁÞÅÎÉÅ ÔÅËÓÔÁ ÔÜÇÁ Ñ×ÎÏ*/
+ {"min",1,0,'m'}, /* ÚÁÄÁÔØ ÍÉÎÉÍÁÌØÎÏÅ ÚÎÁÞÅÎÉÅ ÔÅËÓÔÁ ÔÜÇÁ Ñ×ÎÏ*/
+ {"range",1,0,'r'}, /* õËÁÚÁÔØ ËÏÌÉÞÅÓÔ×Ï ËÌÁÓÓÏ×, ËÏÔÏÒÏÅ ÚÁÄÅÊÓÔ×Ï×ÁÔØ*/
+ {"8-but",0,0,'8'}, /* ÜË×É×ÁÌÅÎÔ --range=255 */
+ {"offsite",1,0,'O'}. /* ÚÁÄÁÔØ offsite. ðÏ ÕÍÏÌÞÁÎÉÀ 0 */
+ {"base",1,0,'b'}, /*æÁÊÌ, ÏÔËÕÄÁ ÓÌÉÚÁÔØ ËÏÏÒÄÉÎÁÔÎÕÀ ÓÉÓÔÅÍÕ É ÒÁÚÍÅÒ ÑÞÅÊËÉ*/
+ {"direct",0,0,'D'}, /*óÞÉÔÁÔØ ÞÔÏ ÔÅËÓÔ ÔÜÇÁ ÃÅÌÏÅ ÞÉÓÌÏ É ÐÉÓÁÔØ ÅÇÏ × ÆÁÊÌ*/
+ {"delimiter",1,0,d}, /* òÁÚÄÅÌÉÔÅÌØ ÐÏÌÅÊ ×Ï ×ÈÏÄÎÏÍ ÆÁÊÌÅ*/
+ {"verbose",0,0,'%'},
+ {"cell-size",1,0,'c'} /* òÁÚÍÅÒ ÑÞÅÊËÉ. ïÞÅÎØ ÐÏÌÅÚÅÎ, ÅÓÌÉ -b ÎÅ ÚÁÄÁΠ*/
+ {"output-file",1,0,'o'},
+ {NULL,0,0,0}};
+ int index,c;char *endptr;
+ int  x1=32767,y1=32767,x2=-32767,y2=-32767,
+     result,verbose=0;
+ while ((c=getopt_long(argc,argv,"m:%o:",long_options,&index))!=-1)
diff --git a/epu/window.c b/epu/window.c
new file mode 100644 (file)
index 0000000..e544139
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "epp.h"
+#include "eppl_ut.h"
+EPP *old,*new;
+int recalc=0;
+int copy_cell(int col,int row,int value)
+{ return epp_get(old,col,row);
+}
+void help(int exitcode)
+{ printf("Usage window [-a%%] input_file fr lr fc lc [output_file]\n"
+         "coordinates are given in rows/cols unless -a option specified\n");
+ exit(exitcode);
+}
+void error(char *msg)
+{ fprintf(stderr,"%s\n",msg);
+  exit(1);
+}
+int get_coord_alt(char *param,int (*convert)(EPP *,double))
+{ double tmp;
+  char *endptr;
+  tmp=strtod(param,&endptr);
+  if (*endptr) error("Invalid coordinate");
+  return convert(old,tmp);
+}
+int get_coord_int(char *param,int (*convert)(EPP *,double))
+{ int tmp;
+  char *endptr;
+  tmp=strtol(param,&endptr,0);
+  if (*endptr) error("Invalid coordinate");
+  return tmp;
+}
+
+int main(int argc,char **argv)
+{char outname[1024]="window.out.epp";
+ int (*get_coord)(char *,int (*)(EPP *,double))=get_coord_int;
+ int x1,y1,x2,y2;
+ int c,index,nonopt=1,verbose=0,result;
+  for(index=1;index<argc;index++)
+  if (argv[index][0]=='-'&&!(isdigit(c=argv[index][1])))
+  switch(c)
+  {case 'a':recalc=1;get_coord=get_coord_alt;break;
+   case '%':verbose=1;break;
+   case 'o':strcpy(outname,default_ext(argv[++index],".epp"));break;
+   case '-':if (!strcmp(argv[index],"--version")) 
+             show_version("window","$Revision: 1.1 $");
+            else if (!strcmp(argv[index],"--help")) help(0);
+   case 'h':
+   default: help(c!='h');
+  } 
+ else
+ switch (nonopt++)
+ {case 1:
+ if (!(old=open_epp(argv[index]))) error("Cannot open input file");
+ break;
+ case 2: 
+y1=get_coord(argv[index],epp_row);break;
+ case 3:
+ y2=get_coord(argv[index],epp_row);break;
+ case 4:
+ x1=get_coord(argv[index],epp_col);break;
+ case 5:
+ x2=get_coord(argv[index],epp_col);break;
+ default:error("Extra parameters in command line");
+ }
+ if (nonopt!=6) help(1);
+ if (!recalc) y2++;
+ if (y1>=y2) error("Negative number of rows"); 
+ if (!recalc) x2++;
+ if (x1>=x2) error("Negative number of columns");
+ Create16bit=old->kind==16;
+ if(!(new=creat_epp(outname,x1,y1,x2-1,y2-1,
+               alt_x(old,x1),alt_y(old,y1),alt_x(old,x2),alt_y(old,y2),
+               100,0,old->offsite))) error("Cannot create output file");
+ install_progress_indicator(verbose?show_percent:check_int); 
+ result=clear_progress(for_each_cell(new,copy_cell));
+ close_epp(old);
+
+ close_epp(new);
+ if (result) unlink(outname);
+ return -result;
+}
diff --git a/fgis.rc b/fgis.rc
new file mode 100644 (file)
index 0000000..d432c19
--- /dev/null
+++ b/fgis.rc
@@ -0,0 +1,30 @@
+lappend auto_path $fGIS_HOME/tcl
+array set fgis_font {
+1 -cronyx-times-medium-r-normal--10-100-75-75-p-54-koi8-r
+1b -cronyx-times-bold-r-normal--10-100-75-75-p-54-koi8-r
+2 -cronyx-times-medium-r-normal--12-120-75-75-p-64-koi8-r
+2b -cronyx-times-bold-r-normal--12-120-75-75-p-64-koi8-r
+3 -cronyx-times-medium-r-normal--14-100-100-100-p-54-koi8-r
+3b -cronyx-times-bold-r-normal--14-100-100-100-p-54-koi8-r
+4 -cronyx-times-medium-r-normal--18-180-75-75-p-94-koi8-r
+4b -cronyx-times-bold-r-normal--18-180-75-75-p-94-koi8-r
+}
+array set fgis_fontmap [list \
+$fgis_font(1) {Times-Roman 10}\
+$fgis_font(2) {Times-Roman 12}\
+$fgis_font(3) {Times-Roman 14}\
+$fgis_font(4) {Times-Roman 18}\
+$fgis_font(1b) {Times-Bold 10}\
+$fgis_font(2b) {Times-Bold 12}\
+$fgis_font(3b) {Times-Bold 14}\
+$fgis_font(4b) {Times-Bold 18}]
+array set fgis {
+printer lp 
+printcmd /usr/bin/lpr
+orient n
+print_colormode color
+shift_factor 0.75
+undefined_legend "Not defined"
+coordformat "X=%0.8g Y=%0.8g"
+}
+if [file exists ~/.fgisrc] {source ~/.fgisrc}
diff --git a/include/Makefile b/include/Makefile
new file mode 100644 (file)
index 0000000..2539d3c
--- /dev/null
@@ -0,0 +1,14 @@
+RCS/%,v : %
+       ci -u $<
+SRC=\
+RCS/clr.h,v\
+RCS/defpal.h,v\
+RCS/dgt.h,v\
+RCS/epp.h,v\
+RCS/epp_err.h,v\
+RCS/eppl.h,v\
+RCS/eppl_ut.h,v\
+RCS/reclass.h,v
+
+rcs: ${SRC}
+
diff --git a/include/clr.h b/include/clr.h
new file mode 100644 (file)
index 0000000..a0ee660
--- /dev/null
@@ -0,0 +1,6 @@
+
+typedef int *PALETTE; 
+PALETTE default_palette;
+PALETTE read_palette(FILE *f);
+char *ppm_pixel(PALETTE palette,int index);
+
diff --git a/include/defpal.h b/include/defpal.h
new file mode 100644 (file)
index 0000000..c677e75
--- /dev/null
@@ -0,0 +1,256 @@
+0x000000,
+0xff0000,
+0x00ff00,
+0xa5a5ff,
+0xffff00,
+0xff00ff,
+0x00ffff,
+0xa5a5a5,
+0xffa500,
+0xa55000,
+0x00a500,
+0x0000ff,
+0xa5a500,
+0xa500a5,
+0x00a5a5,
+0xdadada,
+0x959595,
+0x006060,
+0x008989,
+0x00adad,
+0x00d6d6,
+0x00ffff,
+0x18cefa,
+0x30a9fa,
+0x4891fa,
+0x6081fa,
+0x7d7dff,
+0x5d005d,
+0x850085,
+0xad00ad,
+0xd600d6,
+0xff00ff,
+0xfa18e6,
+0xfa30d2,
+0xfa48c6,
+0xfa60be,
+0xff7dbe,
+0x000030,
+0x000060,
+0x000095,
+0x0000ca,
+0x0000ff,
+0x2410ea,
+0x4420da,
+0x5d34c6,
+0x7144b6,
+0x5454a1,
+0x303000,
+0x606000,
+0x959500,
+0xcaca00,
+0xffff00,
+0xeaea10,
+0xdada20,
+0xc6c634,
+0xb6b644,
+0xa1a154,
+0x003000,
+0x006000,
+0x009500,
+0x00ca00,
+0x00ff00,
+0x10e610,
+0x24d224,
+0x3cbe3c,
+0x4ca94c,
+0x649564,
+0x300000,
+0x600000,
+0x950000,
+0xca0000,
+0xff0000,
+0xe61010,
+0xd22424,
+0xbe3c3c,
+0xa94c4c,
+0x956464,
+0x3cbebe,
+0x3ca1be,
+0x3c85be,
+0x3c69be,
+0x3c48be,
+0x483cbe,
+0x693cbe,
+0x853cbe,
+0xa13cbe,
+0xbe3cbe,
+0xbe3ca1,
+0xbe3c89,
+0xbe3c71,
+0xbe3c58,
+0xbe3c40,
+0xbe543c,
+0xbe713c,
+0xbe893c,
+0xbea13c,
+0xbebe3c,
+0xa1be3c,
+0x69be3c,
+0x3cbe48,
+0x3cbe81,
+0x3cbebe,
+0x602800,
+0x953c00,
+0xca5000,
+0xff6900,
+0xff8530,
+0x141414,
+0x303030,
+0x484848,
+0x646464,
+0x7d7d7d,
+0x959595,
+0xadadad,
+0xc6c6c6,
+0xe2e2e2,
+0xfafafa,
+0x007dff,
+0x00ffff,
+0xbe7d00,
+0x00d603,
+0xa500a5,
+0xb16400,
+0xd69548,
+0xffa5a5,
+0xffca95,
+0x00caff,
+0x00ffca,
+0x606060,
+0xff3c3c,
+0xffa550,
+0x5050ff,
+0x0050ff,
+0xff5000,
+0xbe3c00,
+0xbe1414,
+0x000000,
+0xdaffda,
+0xffff00,
+0xff00ff,
+0xa5a5a5,
+0xff7d00,
+0xff0000,
+0x7dff00,
+0x007d00,
+0x50b100,
+0x0000ff,
+0x007dff,
+0x00ffff,
+0xbe7d00,
+0x00d600,
+0xa500a5,
+0xb16400,
+0xd69548,
+0xffa5a5,
+0xffca95,
+0x00caff,
+0x00ffca,
+0x606060,
+0xff3c3c,
+0xffa550,
+0x5050ff,
+0x0050ff,
+0xff5000,
+0xbe3c03,
+0xbe1414,
+0x000003,
+0xdaeaff,
+0xffff00,
+0xff00ff,
+0xa5a5a5,
+0xff7d00,
+0xff0000,
+0x7dff00,
+0x007d00,
+0x50b100,
+0x0000ff,
+0x007dff,
+0x00ffff,
+0xbe7d00,
+0x00d600,
+0xa500a5,
+0xb16400,
+0xd69548,
+0xffa5a5,
+0xffca95,
+0x00caff,
+0x00ffca,
+0x606060,
+0xff3c3c,
+0xffa550,
+0x5050ff,
+0x0050ff,
+0xff5000,
+0xbe3c03,
+0xbe1414,
+0x000000,
+0xffdada,
+0xffff00,
+0xff00ff,
+0xa5a5a5,
+0xff7d00,
+0xff0000,
+0x7dff00,
+0x007d00,
+0x50b100,
+0x0000ff,
+0x007dff,
+0x00ffff,
+0xbe7d00,
+0x00d603,
+0xa500a5,
+0xb16400,
+0xd69548,
+0xffa5a5,
+0xffca95,
+0x00caff,
+0x00ffca,
+0x606060,
+0xff3c3c,
+0xffa550,
+0x5050ff,
+0xbe3c00,
+0xbe1414,
+0x000000,
+0xffdaff,
+0xffff00,
+0xff00ff,
+0xa5a5a5,
+0xff7d00,
+0xff0000,
+0x7dff00,
+0x007d00,
+0x50b100,
+0x0000ff,
+0x007dff,
+0x00ffff,
+0xbe7d00,
+0x00d600,
+0xa500a5,
+0xb16400,
+0xd69548,
+0xffa5a5,
+0xffca95,
+0x00caff,
+0x00ffca,
+0x606060,
+0xff3c3c,
+0xffa550,
+0x5050ff,
+0x0050ff,
+0xff5000,
+0xbe3c00,
+0xbe1414,
+0x000000,
+0xffffff,
diff --git a/include/dgt.h b/include/dgt.h
new file mode 100644 (file)
index 0000000..c7d454a
--- /dev/null
@@ -0,0 +1,164 @@
+#ifndef DGT_H
+#define DGT_H
+# include <stdio.h>
+#ifndef EPPL_H
+# include "eppl.h"
+#endif
+#ifndef EPP_ERR_H
+# include "epp_err.h"
+#endif
+#define MAX_LINE_LEN 500
+typedef struct POINT { short int x,y; } POINT;
+typedef struct DGT_ITEM { long int ID;
+                          short int x1,y1,x2,y2;
+                          short int npoints;
+                          POINT s[MAX_LINE_LEN];
+                        } DGT_ITEM;    
+struct ITEM_AS_POINT {long int ID;
+                      POINT p;
+                     };
+typedef struct DGT { double XLeft,YBottom,XRight,YTop;
+                     int mode;
+                     int item_no;  
+                     unsigned char projection;
+                     DGT_ITEM* buffer;
+                     int limit; 
+                     void* F;
+                     int eof;
+                     int modified;
+                     int (*next_item)(struct DGT* buffer); 
+                     void (*rewind) (struct DGT *d); 
+                     void (*dispose) (void *f);  
+                     int (*cmp_item)(DGT_ITEM* i1,DGT_ITEM* i2);  
+                    } DGT;
+#define KEEP_OLD_VALUE -32768
+                      
+DGT* open_dgt(char *filename);
+/*opens existing file, given by name*/
+DGT* fopen_dgt(FILE *f);
+/* open existing file given by file variable */
+DGT* creat_dgt(char *filename,double x_left,double y_bottom,
+               double x_right,double y_top, unsigned char proj);
+/* creates file with given limits with given name */               
+DGT* fcreat_dgt(FILE *f ,double x_left,double y_bottom,
+               double x_right,double y_top,unsigned char proj);
+/* creates dgt file with given limits in given stream */
+DGT* mcreat_dgt(double x_left,double y_bottom,
+               double x_right,double y_top, unsigned char proj);
+/* creates empty dgt in memory with given limits*/               
+DGT* creat_dgt_as(char *filename,DGT* pattern);
+DGT* fcreat_dgt_as(FILE *f,DGT *pattern);
+DGT* mcreat_dgt_as(DGT *pattern);
+/* creates file, with limits as in given file */
+
+int load_dgt(DGT* dgt);
+/* loads file opened for reading into memory */
+void save_dgt(DGT* dgt,FILE *f);
+/* saves loaded file*/
+void close_dgt(DGT* dgt);
+/* Destroys DGT object */
+void reset_dgt(DGT* dgt);
+/* rewinds dgt file for first item, reopens for reading,if nessecary */
+DGT_ITEM* dgt_get(DGT* dgt);
+/* allocates current item in memory and returns pointer to it*/
+void dgt_put(DGT *dgt, DGT_ITEM* item);
+/* inserts item in writable file*/
+void dgt_replace(DGT *dgt, int index, DGT_ITEM *item);
+/* replaces item number index with given item (memory files only*/
+DGT_ITEM* dgt_item_ptr(DGT *dgt, int index);
+/* returns pointer to specified item without copiing it*/
+#define dgt_next(dgt) ((dgt)->next_item(dgt))
+/* flushes current item buffer */
+void dgt_seek(DGT *dgt,int index);
+/* makes item with given number current (for memory files only)*/
+void chk_mask(DGT_ITEM* item);
+/*set correct values of bounding rectangle*/
+void dgt_sort(DGT *dgt,int (*compare_func)(DGT_ITEM *i1,DGT_ITEM *i2));
+
+void for_each_line(DGT *dgt,void (*item_proc)(DGT *dgt),DGT *outstream);
+void for_each_point(DGT *dgt,void (*item_proc)(DGT *dgt),DGT *outstream);
+/* Applies given item_proc to each item of given type in file. If outstream 
+   not NULL,
+   copies all items (inclding those, which are not a subject of item_proc
+   to outstream */
+void for_each_item(DGT *dgt,void (*item_proc)(DGT *dgt));
+/* Applies given item_proc to each item in file. If items to be copied
+   to other stream, item_proc has to do it itself */
+/* coordinate recalculation */
+
+
+int dgt_x(DGT* dgt,double x);
+int dgt_y(DGT* dgt,double y);
+
+double real_x(DGT* dgt,int x);
+double real_y(DGT* dgt,int y);
+double real_dx(DGT* dgt,int dx);
+double real_dy(DGT* dgt,int dy);
+double dgt_dist(DGT* dgt,int x1,int y1,int x2,int y2);
+double dgt_pdist(DGT* dgt,POINT p1,POINT p2);
+long int sq_dist(DGT* dgt,int x1,int y1,int x2,int y2);
+long int sq_pdist(DGT* dgt,POINT p1,POINT p2);
+long int sq_const(DGT* dgt,double dist);
+/* item modification */
+#define dgt_touch(x) ((x)->modified=1);
+void item_set_id(DGT_ITEM *item,long int newID);
+#define dgt_set_id(x,ID) ((x)->modified=1,item_set_id((x)->buffer,ID))
+void dgt_set_point(DGT *dgt,int x,int y);
+int dgt_add_node(DGT *dgt,int x,int y);
+int dgt_ins_node(DGT *dgt,int index,int x,int y);
+int item_mv_node(DGT_ITEM *item,int index,int x,int y);
+#define dgt_mv_node(d,index,x,y) ((d)->modified=1,item_mv_node((d)->buffer,index,x,y))
+int dgt_rm_node(DGT *dgt,int index);
+int dgt_split(DGT *dgt,int index);
+int dgt_cut_segment(DGT *dgt,int index);
+/* item utilities */
+DGT_ITEM* alloc_item(DGT_ITEM* item);
+/* allocates new copy of item */
+/* Macros for access current item */
+#define dgt_item(x) (((DGT *)(x))->buffer)
+/* returns pointer to current item */
+#define dgt_line_len(x)  (((DGT *)(x))->buffer->npoints)
+/* returns lile length (number of points) in current item*/
+
+/* following macros provide a read/write access to current item */
+#define dgt_id(x) (((DGT *)(x))->buffer->ID)
+/*  ID of current item */
+#define dgt_node(x,i) (((DGT *)(x))->buffer->s[i])
+
+/* node #i (0 - (line_len-1)) */
+#define dgt_nx(d,i) (((DGT *)(d))->buffer->s[i].x)
+#define dgt_ny(d,i) (((DGT *)(d))->buffer->s[i].y)
+#define dgt_xl(x) (((DGT *)(x))->buffer->x1)                             
+/* left limit of bounding rectangle */
+#define dgt_xr(x) (((DGT *)(x))->buffer->x2)   
+/* right limit of bounding rectangle */
+#define dgt_yb(x) (((DGT *)(x))->buffer->y1)
+/* bottom limit of bounding rectangle */   
+#define dgt_yt(x) (((DGT *)(x))->buffer->y1)   
+/* top limit of bounding rectangle */
+#define dgt_pointx(x) (((DGT *)(x))->buffer->x1)   
+/* X of label point (if current object is label point)*/
+#define dgt_pointy(x) (((DGT *)(x))->buffer->y1)                     
+/* Y of label point (if current object is label point)*/
+#define dgt_is_line(x)  (((DGT *)(x))->buffer->npoints)
+/* non-zero if current item is line */
+#define dgt_is_point(x)  (!(((DGT *)(x))->buffer->npoints))
+/* non-zero if current item is point */
+#define dgt_point(x) (((((struct ITEM_AS_POINT *)(((DGT *)(x))->buffer)))->p))
+#define dgt_eof(x) (((DGT *)(x))->eof)
+/*macros for access item, given by pointer*/
+#define item_id(x) ((x)->ID)
+#define item_node(x,i) ((x)->s[i])
+#define item_xn(d,i) ((d)->s[i].x)
+#define item_yn(d,i) ((d)->s[i].y)
+#define item_xl(x) ((x)->x1)
+#define item_xr(x) ((x)->x2)
+#define item_yb(x) ((x)->y1)
+#define item_yt(x) ((x)->y2)
+#define point_x(x) ((x)->x1)
+#define point_y(x) ((x)->y1)
+#define item_len(x) ((x)->npoints)
+#define item_point(x) (((struct ITEM_AS_POINT *)(x))->p)
+
+#endif
diff --git a/include/epp.h b/include/epp.h
new file mode 100644 (file)
index 0000000..0479d6d
--- /dev/null
@@ -0,0 +1,148 @@
+/* Epp file access definition */
+# ifndef EPP_H
+# define EPP_H
+# include <stdio.h>
+#ifndef EPPL_H
+# include "eppl.h"
+#endif
+#ifndef EPP_ERR_H
+# include "epp_err.h"
+#endif
+/* this structure defines internal representation of open EPP file */
+typedef struct EPP { int fr,lr,fc,lc;
+                     double XLeft,YBottom,XRight,YTop;
+                     double cell_area;
+                     int offsite;
+                     int mode;
+                     unsigned short *widthtable, *row;
+                     int kind;
+                     FILE *F;
+                     int min,max;
+                     int width;
+                     int currentline;
+                     long filepos; 
+                     int cache_size;
+                     void *cache;
+                     int *counttable;
+                     unsigned char *packed_buffer;
+                     void (*position)(struct EPP* epp,int row);
+                     int modified;
+                    } EPP;
+/*this structure used for simulatenouis operations on files with
+  different cell size*/
+typedef struct { int ax,bx,cx,
+                     ay,by,cy;
+               } LINK_BUFFER,*EPP_LINK;
+
+EPP *open_epp(char *pathname);
+EPP *fopen_epp(FILE *f);
+/* opens existing EPP file */
+EPP *creat_epp(char *pathname,int first_col,int first_row,int last_col,
+               int last_row, double AXLeft,double AYTop, double AXRight, 
+               double AYBottom, int scale, int base, int offsite);
+EPP *fcreat_epp(FILE *f,int first_col,int first_row,int last_col,
+               int last_row, double AXLeft,double AYTop, double AXRight, 
+               double AYBottom, int scale, int base, int offsite);
+               
+/* creating epp file from scratch. All fields which are not defined as
+ parameters, are filled by default values. Kind depends of global variable
+ Create16bit */
+extern int Create16bit; /* if non-zero, all created EPP files would be 16 bit*/
+int set_epp_cache(EPP* epp,int lines);
+/* set cache to lines lines. to keep accessed lines in memory.
+   affects only MAP_INPUT files*/
+EPP* load_epp(char *filename);
+/* loads EPP file given by name into memory. Keeps open file for saving*/
+EPP* fload_epp(FILE *f);
+/* loads EPP from given file. */
+int load_new_epp(EPP *f);
+/* fills write-only file with offsite and reopens it for read-write */
+int save_epp(EPP* epp);
+/* flushes file, loaded into memory
+   If file isn't modified, does nothing.
+ */
+
+#define touch_epp(epp) ((epp)->mode|=MAP_MODIFIED)
+/* marks file as modified to ensure that it would be actually written
+   by save_epp */
+
+int save_epp_as(EPP* epp,char *newname);
+/* saves loaded epp under new filename, making new stream default for this epp*/
+int fsave_epp_as(EPP* epp,FILE *f);
+/* saves loaded epp into new stream, making it default */
+int epp_expand(EPP *epp);
+/* converts loaded epp into file with greater depth */
+EPP *creat_epp_as(char *pathname,EPP *pattern);
+EPP *fcreat_epp_as(FILE *f,EPP *pattern);
+/* creates new epp file, copiing a most header fields from given file */
+void fast_convert_to_8bit(EPP *source,char *filename);
+/* given a 16-bit epp file open for writing, writes a 8-bit epp file
+   containing low bytes from all pixels of source files. Closes both files
+   after that */
+void get_epp_header(EPP* epp, EPPHEADER *h);
+/* reads header of EPP file */
+void change_epp_header(EPP* epp,EPPHEADER h);
+/* changes several fields of EPP file */
+void setcomment(EPP *epp,char *comment);
+/* change comment of epp file, which was open by creat_epp or creat_epp_as */
+
+char *getcomment(EPP *epp);
+/* returns comment of EPP file (address of static buffer,which would be
+   overriden by next call */
+int shift_epp(EPP *epp,int new_fr,int new_fc);
+/* shifts row and col numbers to make fr and fc equial to fr and fc.
+   returns non-zero on success, zero, if some of boundaries hit signed short
+   limits */
+       
+typedef int (*EPP_ITER_PROC)(int col,int row,int value);
+
+int for_each_cell(EPP *epp, EPP_ITER_PROC action);
+/* performs given operation for each non-offsite cell of existing EPP file
+   (terminated if action returns non-zero,
+   or performs operation for each cell of created EPP file, filling cell
+   by value, returned by action. value parameter in this case always containt
+   offsite of epp */
+long count_cells(EPP *epp, EPP_ITER_PROC condition);
+/* calls condition for each non-offsite cell in existing epp file, returns
+   count of cells, for which condition was non-zero */
+extern int (*EndLineProc)(int row,int seqno,int total);
+/* if not NULL, this function called from for_each_cell and count_cells
+   after processing of each line. If it returns non-zero, processing 
+   terminated */
+
+void reset_epp(EPP *epp);
+/* reopens epp file for reading. if file was in create mode, fills all non-filled
+lines by offsite */
+
+unsigned short int *epp_getline(EPP *epp,int x,int y);
+/* returns pointer to array of integer, which represents line y of raster,
+   starting from col x. NULL if x<fr */
+int  epp_get(EPP *epp,int x,int y);
+/* returns value of given cell, offsite if cell is outside file boundaries */
+void epp_put(EPP *epp,int x,int y,int value);
+/* fills given cell by value. File must be in create mode. if line is not
+ current, does nothing if line above current or fills all lines between current
+ and specified by offsite */
+void epp_putline(EPP *epp,int x1,int x2,int y,int value);
+/* fills range of cells in same row by value. Shortcut for multiple epp_put */
+/* fills given cell by value. File must be in create mode. if line is not */
+int epp_contains(EPP *epp,int x,int y);
+/* returns non-zero if <x,y> is within boundares of epp */
+void close_epp(EPP *epp);
+/*********** coordinate recalculation **********/
+int epp_row(EPP *epp,double y);/* returns row by given alternate y */
+int epp_col(EPP *epp,double x);/* returns col for given alternate x */
+double alt_x(EPP *epp,int col);/* returns alternate x for given col */
+double alt_y(EPP *epp,int row);/* returns alternate y for given row */
+double alt_xc(EPP *epp,int col);/* returns alternate x for given col */
+double alt_yc(EPP *epp,int row);/* returns alternate y for given row */
+/**** this was private in pascal version ********/
+void get_row(EPP *epp);/* reads and unpacks row of epp file */
+void put_row(EPP *epp);/* packs and writes row */
+/********* compatibility of files *************/
+int compare_cell_size(EPP *f1,EPP *f2);
+int is_aligned(EPP *f1,EPP *f2);
+EPP_LINK link_epp(EPP *base,EPP *overlay);
+int linked_row(EPP_LINK link,int row);
+int linked_col(EPP_LINK link,int col);
+# endif
diff --git a/include/epp_err.h b/include/epp_err.h
new file mode 100644 (file)
index 0000000..d53537a
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef EPP_ERR_H
+#define EPP_ERR_H
+extern int map_error; /* after each operation contains error code */
+# define ME_POINT_OUTSIDE 1 
+/* given coorndates are outside given epp file */
+# define ME_INVALID_MODE 2
+/* operation is non allowed for this mode */
+# define ME_READ_ERROR 3
+/* something wrong with reading file */
+# define ME_WRITE_ERROR 4
+/* disk full or something wrong writing file */
+# define ME_INVALID_PUT 5
+/* epp_put above current line */
+# define ME_OUT_OF_MEMORY 6
+# define ME_ACCESS_DENIED 7
+# define ME_NO_FILE 8
+# define ME_INVALID_FILE 9
+# define ME_CREATE_ERROR 10           
+/* Return values for dgt item modification function */
+# define DGT_SUCCESS 0
+# define DGT_LINE_TOO_LONG 1
+# define DGT_ZERO_SEGMENT 2
+# define DGT_INVALID_NODE 3
+# define DGT_LINE_TOO_SHORT 4
+# define DGT_BAD_SPLIT_POINT 5
+#endif
diff --git a/include/eppl.h b/include/eppl.h
new file mode 100644 (file)
index 0000000..cd9fbb9
--- /dev/null
@@ -0,0 +1,74 @@
+/**********************************************************************/
+/*           Common include file for epp and dgt file access          */
+/**********************************************************************/
+#ifndef EPPL_H
+# define EPPL_H
+
+/* attempt to make epp.c portable to machines with non-intel CPU */
+# define LSB_FIRST 
+/* if defined, get_row and put_row thinks, that least significant byte
+   is first in int variable */ 
+
+/* Area unit definition */
+# define AREA_NO_UNIT 0
+# define AREA_SQ_FOOT 1
+# define AREA_SQ_METER 2
+# define AREA_SQ_KM 3
+# define AREA_SQ_MILE 4
+# define AREA_HECTARE 5
+# define AREA_ACRE 6
+
+/* Coordinate system definition */
+# define COORD_NONE 0
+# define COORD_UTM 1
+# define COORD_STPLANE 2
+# define COORD_LL 3                        
+
+/* values for mode field of EPP */
+# define MAP_INPUT 1
+# define MAP_OUTPUT 2
+# define MAP_LOADED 4 
+# define MAP_CACHED 8
+# define MAP_MODIFIED 128
+/* this structure defines 128-byte header of EPP file. 
+   it assumes that all numeric types are in Intel format
+   short  - 16-bit, lsb first,
+   long  32-bit, lsb first
+   double - 64-bit IEEE conforming */
+typedef struct EPPHEADER { short int fr,lr,fc,lc;/* last and first row/column */
+                           double fry,lry,fcx,lcx;/*corresponding alternative 
+                                                    coordinates*/
+                           short int kind;/* 8 or 16 bit file */
+                           short int base,scale;
+                           unsigned short int offsite; /* blank class */
+                           double sfact; /* cell area */
+                           long access_ptr; /* file offset of width table */
+                           unsigned short  minclass, maxclass; /* class limits. unused in
+                                                              8-bit files */
+                           char area_unit;
+                           char coord_sys;                                   
+                           char Reserved[6];
+                           char date[16], time[8];/* ASCII date and time */
+                           char comment[32]; } EPPHEADER;
+typedef struct DGTHEADER {double  xleft,ybottom,xright,ytop;
+                          long    maxpt,maxline;
+                          short   kind;
+                          char    coord_sys;
+                          char reserved[85];
+                          } DGTHEADER;
+                          
+#ifndef LSB_FIRST
+                          
+ short swapshort(short x);
+ long  swaplong(long x);
+ double swapdouble(double x);
+#else
+# define swapshort(x) (x)
+# define swaplong(x) (x)
+# define swapdouble(x) (x)   
+#endif
+#endif
+/* Here is the end of this file */   
+
diff --git a/include/eppl_ut.h b/include/eppl_ut.h
new file mode 100644 (file)
index 0000000..f5db53e
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef EPPL_UT_H
+#define EPPL_UT_H
+#include <stdio.h>
+#include <getopt.h>
+#include <unistd.h>
+#define LIBDIR "/usr/local/lib/fgis/"
+FILE *lookup_file(const char *name,const char *suffix,const char *dir);
+/* éÝÅÔ ÆÁÊÌ ÓÎÁÞÁÌÁ × ÔÅËÕÝÅÊ ÄÉÒÅËÔÏÒÉÉ, ÐÏÔÏÍ × ÄÉÒÅËÔÏÒÉÉ
+   dir × ÔÅËÕÝÅÊ ÄÉÒÅËÔÏÒÉÉ, ÐÏÔÏÍ × /usr/local/lib/fgis/$dir */
+char *default_ext(const char *filename,const char *ext);
+char *force_ext(const char *filename,const char *ext);
+char *last_ext(const char *name);
+int show_progress(int row,int seqno,int total);
+int check_int(int row,int seqno, int total);
+int show_percent(int row,int seqno,int total);
+void install_progress_indicator(int (*)(int,int,int));
+int clear_progress(int success);
+void show_version(char *name,char *RCS_ID);
+#endif
diff --git a/include/getopt.h b/include/getopt.h
new file mode 100644 (file)
index 0000000..d751c6b
--- /dev/null
@@ -0,0 +1,132 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if    __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument             0
+#define required_argument      1
+#define optional_argument      2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/include/reclass.h b/include/reclass.h
new file mode 100644 (file)
index 0000000..4043c87
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef RECLASS_H
+#define RECLASS_H
+
+#include <epp.h>
+
+typedef unsigned short int * RECLASS;
+/*  */
+extern int interactive_parser;
+RECLASS create_reclass_table(int size);
+RECLASS parse_statements(int size,RECLASS src,int (*recl_getc)());
+RECLASS make_reclass_table(EPP *infile,int (*recl_getc)());
+/* óÏÚÄÁÅÔ ÇÌÏÂÁÌØÎÕÀ ÔÁÂÌÉÃÕ ÒÅËÌÁÓÓÁ ÄÌÑ ÆÁÊÌÁ infile.
+ ïÐÅÒÁÔÏÒÙ ÒÅËÌÁÓÓÁ ÞÉÔÁÀÔÓÑ Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ recl_getc, ËÏÔÏÒÁÑ
+ ÚÁ ÏÄÉΠÒÁÚ ×ÏÚ×ÒÁÝÁÅÔ ÏÄÉΠÓÉÍ×ÏÌ.
+*/
+RECLASS wrapped_reclass(EPP *infile,int white);
+
+
+
+/* óÏÚÄÁÅÔ ÒÅËÌÁÓÓ ÐÏ ÕÍÏÌÞÁÎÉÀ (offsite=white,0=0, ÏÓÔÁÌØÎÙÅ (c-1)%(white-1)+1;*/
+#define epp_table_size(epp) ((epp)->max>(epp)->offsite?(epp)->max:(epp)->offsite)
+
+#define default_reclass(epp) create_reclass_table(epp_table_size(epp))
+
+
+/* ÐÒÉÓ×ÏÊÔÅ ÜÔÏÊ ÐÅÒÅÍÅÎÎÏÊ ÎÅÎÕÌÅ×ÏÅ ÚÎÁÞÅÎÉÅ, ÅÓÌÉ ××ÏÄ
+ ÏÐÅÒÁÔÏÒÏ× reclass ÐÒÏÉÓÈÏÄÉÔ Ó ËÌÁ×ÉÁÔÕÒÙ É ÐÏÌØÚÏ×ÁÔÅÌØ ÍÏÖÅÔ,
+ ÐÏÌÕÞÉ× ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ ÐÅÒÅ××ÅÓÔÉ ÓÔÒÏËÕ ÚÁÎÏ×Ï*/
+
+#endif
diff --git a/include/regex.h b/include/regex.h
new file mode 100644 (file)
index 0000000..a495005
--- /dev/null
@@ -0,0 +1,490 @@
+/* Definitions for data structures and routines for the regular
+   expression library, version 0.12.
+
+   Copyright (C) 1985, 89, 90, 91, 92, 1993 Free Software Foundation, Inc.
+
+   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 2, 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef __REGEXP_LIBRARY_H__
+#define __REGEXP_LIBRARY_H__
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+   <regex.h>.  */
+
+#ifdef VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+   should be there.  */
+#include <stddef.h>
+#endif
+
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+   If set, then such a \ quotes the following character.  */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+     literals. 
+   If set, then \+ and \? are operators and + and ? are literals.  */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported.  They are:
+     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
+     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+   If not set, then character classes are not supported.  */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+     expressions, of course).
+   If this bit is not set, then it depends:
+        ^  is an anchor if it is at the beginning of a regular
+           expression or after an open-group or an alternation operator;
+        $  is an anchor if it is at the end of a regular expression, or
+           before a close-group or an alternation operator.  
+
+   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+   POSIX draft 11.2 says that * etc. in leading positions is undefined.
+   We already implemented a previous draft which made those constructs
+   invalid, though, so we haven't changed the code back.  */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+     regardless of where they are in the pattern.
+   If this bit is not set, then special characters are special only in
+     some contexts; otherwise they are ordinary.  Specifically, 
+     * + ? and intervals are only special when not after the beginning,
+     open-group, or alternation operator.  */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+     immediately after an alternation or begin-group operator.  */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+   If not set, then it doesn't.  */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+   If not set, then it does.  */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+   If not set, they do.  */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+     interval, depending on RE_NO_BK_BRACES. 
+   If not set, \{, \}, {, and } are literals.  */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+   If not set, they are.  */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+   If not set, newline is literal.  */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+     are literals.
+  If not set, then `\{...\}' defines an interval.  */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+   If not set, \(...\) defines a group, and ( and ) are literals.  */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+   If not set, then \<digit> is a back-reference.  */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal. 
+   If not set, then \| is an alternation operator, and | is literal.  */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+     than the starting range point, as in [z-a], is invalid.
+   If not set, then when ending range point collates higher than the
+     starting range point, the range is ignored.  */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+   If not set, then an unmatched ) is invalid.  */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+   some interfaces).  When a regexp is compiled, the syntax used is
+   stored in the pattern buffer, so changing this does not affect
+   already-compiled regexps.  */
+extern reg_syntax_t re_syntax_options;
+\f
+/* Define combinations of the above bits for the standard possibilities.
+   (The [[[ comments delimit what gets put into the Texinfo file, so
+   don't delete them!)  */ 
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK                                                  \
+  (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL                      \
+   | RE_NO_BK_PARENS            | RE_NO_BK_REFS                                \
+   | RE_NO_BK_VBAR               | RE_NO_EMPTY_RANGES                  \
+   | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK                                            \
+  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP                                                 \
+  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES                                \
+   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS                           \
+   | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP                                                        \
+  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS                   \
+   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE                   \
+   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS                            \
+   | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP                                          \
+  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax.  */
+#define _RE_SYNTAX_POSIX_COMMON                                                \
+  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL             \
+   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC                                          \
+  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+   isn't minimal, since other operators, such as \`, aren't disabled.  */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC                                  \
+  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED                                       \
+  (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS                  \
+   | RE_CONTEXT_INDEP_OPS  | RE_NO_BK_BRACES                           \
+   | RE_NO_BK_PARENS       | RE_NO_BK_VBAR                             \
+   | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+   replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added.  */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED                               \
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
+   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES                          \
+   | RE_NO_BK_PARENS        | RE_NO_BK_REFS                            \
+   | RE_NO_BK_VBAR         | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+\f
+/* Maximum number of duplicates an interval can allow.  Some systems
+   (erroneously) define this in other header files, but we want our
+   value, so remove any previous define.  */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1) 
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp').  */
+
+/* If this bit is set, then use extended regular expression syntax.
+   If not set, then use basic regular expression syntax.  */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+#define REG_ICASE (REG_EXTENDED << 1)
+/* If this bit is set, then anchors do not match at newline
+     characters in the string.
+   If not set, then anchors do match at newlines.  */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+   If not set, then returns differ between not matching and errors.  */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec).  */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+     the beginning of the string (presumably because it's not the
+     beginning of a line).
+   If not set, then the beginning-of-line operator does match the
+     beginning of the string.  */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line.  */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+   `re_error_msg' table in regex.c.  */
+typedef enum
+{
+  REG_NOERROR = 0,     /* Success.  */
+  REG_NOMATCH,         /* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+  REG_BADPAT,          /* Invalid pattern.  */
+  REG_ECOLLATE,                /* Not implemented.  */
+  REG_ECTYPE,          /* Invalid character class name.  */
+  REG_EESCAPE,         /* Trailing backslash.  */
+  REG_ESUBREG,         /* Invalid back reference.  */
+  REG_EBRACK,          /* Unmatched left bracket.  */
+  REG_EPAREN,          /* Parenthesis imbalance.  */ 
+  REG_EBRACE,          /* Unmatched \{.  */
+  REG_BADBR,           /* Invalid contents of \{\}.  */
+  REG_ERANGE,          /* Invalid range end.  */
+  REG_ESPACE,          /* Ran out of memory.  */
+  REG_BADRPT,          /* No preceding re for repetition op.  */
+
+  /* Error codes we've added.  */
+  REG_EEND,            /* Premature end.  */
+  REG_ESIZE,           /* Compiled pattern bigger than 2^16 bytes.  */
+  REG_ERPAREN          /* Unmatched ) or \); not returned from regcomp.  */
+} reg_errcode_t;
+\f
+/* This data structure represents a compiled pattern.  Before calling
+   the pattern compiler, the fields `buffer', `allocated', `fastmap',
+   `translate', and `no_sub' can be set.  After the pattern has been
+   compiled, the `re_nsub' field is available.  All other fields are
+   private to the regex routines.  */
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+       /* Space that holds the compiled pattern.  It is declared as
+          `unsigned char *' because its elements are
+           sometimes used as array indexes.  */
+  unsigned char *buffer;
+
+       /* Number of bytes to which `buffer' points.  */
+  unsigned long allocated;
+
+       /* Number of bytes actually used in `buffer'.  */
+  unsigned long used;  
+
+        /* Syntax setting with which the pattern was compiled.  */
+  reg_syntax_t syntax;
+
+        /* Pointer to a fastmap, if any, otherwise zero.  re_search uses
+           the fastmap, if there is one, to skip over impossible
+           starting points for matches.  */
+  char *fastmap;
+
+        /* Either a translate table to apply to all characters before
+           comparing them, or zero for no translation.  The translation
+           is applied to a pattern when it is compiled and to a string
+           when it is matched.  */
+  char *translate;
+
+       /* Number of subexpressions found by the compiler.  */
+  size_t re_nsub;
+
+        /* Zero if this pattern cannot match the empty string, one else.
+           Well, in truth it's used only in `re_search_2', to see
+           whether or not we should use the fastmap, so we don't set
+           this absolutely perfectly; see `re_compile_fastmap' (the
+           `duplicate' case).  */
+  unsigned can_be_null : 1;
+
+        /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+             for `max (RE_NREGS, re_nsub + 1)' groups.
+           If REGS_REALLOCATE, reallocate space if necessary.
+           If REGS_FIXED, use what's there.  */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+  unsigned regs_allocated : 2;
+
+        /* Set to zero when `regex_compile' compiles a pattern; set to one
+           by `re_compile_fastmap' if it updates the fastmap.  */
+  unsigned fastmap_accurate : 1;
+
+        /* If set, `re_match_2' does not return information about
+           subexpressions.  */
+  unsigned no_sub : 1;
+
+        /* If set, a beginning-of-line anchor doesn't match at the
+           beginning of the string.  */ 
+  unsigned not_bol : 1;
+
+        /* Similarly for an end-of-line anchor.  */
+  unsigned not_eol : 1;
+
+        /* If true, an anchor at a newline matches.  */
+  unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+
+/* search.c (search_buffer) in Emacs needs this one opcode value.  It is
+   defined both in `regex.c' and here.  */
+#define RE_EXACTN_VALUE 1
+\f
+/* Type for byte offsets within the string.  POSIX mandates this.  */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in.  See
+   regex.texinfo for a full description of what registers match.  */
+struct re_registers
+{
+  unsigned num_regs;
+  regoff_t *start;
+  regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+   `re_match_2' returns information about at least this many registers
+   the first time a `regs' structure is passed.  */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers.  Aside from the different names than
+   `re_registers', POSIX uses an array of structures, instead of a
+   structure of arrays.  */
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+\f
+/* Declarations for routines.  */
+
+/* To avoid duplicating every routine declaration -- once with a
+   prototype (if we are ANSI), and once without (if we aren't) -- we
+   use the following macro to declare argument types.  This
+   unfortunately clutters up the declarations a bit, but I think it's
+   worth it.  */
+
+#if __STDC__
+
+#define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+#define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+   You can also simply assign to the `re_syntax_options' variable.  */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+   and syntax given by the global `re_syntax_options', into the buffer
+   BUFFER.  Return NULL if successful, and an error string if not.  */
+extern const char *re_compile_pattern
+  _RE_ARGS ((const char *pattern, int length,
+             struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+   accelerate searches.  Return 0 if successful and -2 if was an
+   internal error.  */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+   compiled into BUFFER.  Start searching at position START, for RANGE
+   characters.  Return the starting position of the match, -1 for no
+   match, or -2 for an internal error.  Also return register
+   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
+extern int re_search
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+            int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+   STRING2.  Also, stop searching at index START + STOP.  */
+extern int re_search_2
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+             int length1, const char *string2, int length2,
+             int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+   in BUFFER matched, starting at position START.  */
+extern int re_match
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+             int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
+extern int re_match_2 
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+             int length1, const char *string2, int length2,
+             int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
+   for recording register information.  STARTS and ENDS must be
+   allocated with malloc, and must each be at least `NUM_REGS * sizeof
+   (regoff_t)' bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+extern void re_set_registers
+  _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+             unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+/* 4.2 bsd compatibility.  */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+
+/* POSIX compatibility.  */
+extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
+extern int regexec
+  _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
+             regmatch_t pmatch[], int eflags));
+extern size_t regerror
+  _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
+             size_t errbuf_size));
+extern void regfree _RE_ARGS ((regex_t *preg));
+
+#endif /* not __REGEXP_LIBRARY_H__ */
+\f
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..c4d0739
--- /dev/null
@@ -0,0 +1,64 @@
+CC=gcc
+CFLAGS=-g -fPIC -O2 -Wall -ansi -pedantic -I ../include 
+LIB_OBJS=\
+byteorder.o\
+dgt_dist.o\
+dgt_input.o\
+dgt_iter.o\
+dgt_output.o\
+epp_cache.o\
+epp_input.o\
+epp_iter.o\
+epp_loaded.o\
+epp_output.o\
+file_utils.o\
+lookup.o\
+overlay.o\
+reclass.tab.o
+RCS=\
+RCS/byteorder.c,v\
+RCS/clr.c,v\
+RCS/dgt_dist.c,v\
+RCS/dgt_input.c,v\
+RCS/dgt_iter.c,v\
+RCS/dgt_output.c,v\
+RCS/epp_cache.c,v\
+RCS/epp_input.c,v\
+RCS/epp_iter.c,v\
+RCS/epp_loaded.c,v\
+RCS/epp_output.c,v\
+RCS/file_utils.c,v\
+RCS/lookup.c,v\
+RCS/overlay.c,v\
+RCS/reclass.y,v
+SRC=\
+byteorder.c\
+clr.c\
+dgt_dist.c\
+dgt_input.c\
+dgt_iter.c\
+dgt_output.c\
+epp_cache.c\
+epp_input.c\
+epp_iter.c\
+epp_loaded.c\
+epp_output.c\
+file_utils.c\
+lookup.c\
+overlay.c\
+reclass.y
+RCS/%,v : %
+       ci $<
+libepp.a:${LIB_OBJS} 
+       ar r libepp.a ${LIB_OBJS} 
+libepp.so:${LIB_OBJS}
+       gcc -shared ${LIB_OBJS} -o libepp.so -lm
+reclass.tab.c:reclass.y
+       bison reclass.y
+clean:
+       rm *.o
+       rm reclass.tab.c
+distclean: clean
+       rm libepp.a
+rcs: ${RCS}
+
diff --git a/lib/TODO.lib b/lib/TODO.lib
new file mode 100644 (file)
index 0000000..8650f71
--- /dev/null
@@ -0,0 +1,16 @@
+æÕÎËÃÉÑ epp_expand(epp) - ÐÒÅ×ÒÁÝÁÅÔ ÚÁÇÒÕÖÅÎÎÙÊ × ÐÁÍÑÔØ 8-ÂÉÔÎÙÊ
+     ÒÁÓÔÒ × 16-ÂÉÔÎÙÊ.
+    (á ÍÏÖÅÔ ÂÙÔØ ÓÔÏÉÔ ×ÓÅÇÄÁ ËÏÎ×ÅÒÔÉÒÏ×ÁÔØ ÒÁÓÔÒ ÐÒÉ ÚÁÇÒÕÚËÅ
+    É ×ÏÚÍÏÖÎÏ ÐÒÉ ÓÏÈÒÁÎÅÎÉÉ ËÏÎ×ÅÒÔÉÒÏ×ÁÔØ ÏÂÒÁÔÎÏ)
+
+   õÓÌÏ×ÉÑ ËÏÎ×ÅÒÔÉÒÏ×ÁÎÉÑ
+   if ((max<=255&&offsite<=255)||(max<255&&offsite==65535)||
+        (max<=255&&offsite==65535&&counttable(255)==0))
+
+ïÂÒÁÂÁÔÙ×ÁÔØ ÏÛÉÂËÕ, ÅÓÌÉ ÄÌÉÎÁ ÕÐÁËÏ×ÁÎÎÏÊ ÓÔÒÏËÉ >65535 ÂÁÊÔ
+
+æÕÎËÃÉÑ epp_putline(EPP *epp,int x1,int x2,int y,int value)
+
+÷×ÅÓÔÉ ÇÌÏÂÁÌØÎÙÊ ÆÌÁÇ ÉÚÍÅÎÅÎÉÑ ÆÁÊÌÁ 
+
+ðÅÒÅÉÍÅÎÏ×ÁÔØ ÐÏÌÅ modified × row_modified ÄÌÑ ÑÓÎÏÓÔÉ.
diff --git a/lib/byteorder.c b/lib/byteorder.c
new file mode 100644 (file)
index 0000000..5e78fc4
--- /dev/null
@@ -0,0 +1,18 @@
+short swapshort(short x)
+{ return (signed short) (((unsigned short) x)>>8)|(((unsigned short) x)<<8);
+}
+long swaplong(long x)
+{ 
+#define ulx ((unsigned long) x)
+return (signed long) (((ulx & 0xFF000000)>>24)|((ulx &0xFF0000)>>8)|((ulx & 0xFF00)<<8)|((ulx & 0xFF)<<24));
+}
+union doubleconv {double d;
+                  unsigned char b[8];
+                  };
+double swapdouble(double x)
+{ union doubleconv tmp1,tmp2;
+  int i,j;
+  tmp1.d=x;
+   for (i=0,j=7;i<8;tmp2.b[j--]=tmp1.b[i++]);
+   return tmp2.d;
+ }
diff --git a/lib/clr.c b/lib/clr.c
new file mode 100644 (file)
index 0000000..ac92d49
--- /dev/null
+++ b/lib/clr.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "eppl_ut.h"
+#include <clr.h>
+#include <X11/Xlib.h>
+int defarray[]={
+#include "defpal.h"
+};
+PALETTE default_palette=defarray;
+PALETTE read_palette(FILE *f)
+/* þÉÔÁÅÔ ÐÁÌÉÔÒÕ ÉÚ ÆÁÊÌÁ × ÆÏÒÍÁÔÅ EPPL7 */
+{ PALETTE pal;
+  int index,r,g,b;
+  pal=memcpy(malloc(256*sizeof(long int)),default_palette,256*sizeof(long int));
+  do {
+    if (fscanf(f,"%d %d %d %d\n",&index,&r,&g,&b)!=4) break;
+    if (index>255) continue;
+    pal[index]=(r*255/1000)<<16|(g*255/1000)<<8|(b*255/1000);
+  } while (!feof(f));
+  return pal;
+}
+
+char *ppm_pixel(PALETTE palette,int index)
+{ int value;
+  static char buffer[24];
+  if(index>=0&&index<255)
+  value=palette[index];
+  else value=palette[255];
+  sprintf(buffer,"%d %d %d ",value>>16,(value>>8)&0xFF,value & 0xFF);
+  return buffer;
+}
+
+char *Xcolor_string(PALETTE palette,int index)
+{ int value;
+  static char buffer[24];
+  if(index>=0&&index<255)
+  value=palette[index]; else value=palette[255];
+  sprintf(buffer,"#%06x",value);
+  return buffer;
+}
+XColor Xcolor_struct(PALETTE palette,int index)
+{ int value;
+  XColor buffer;
+  if (index>=0&&index<255)
+   value=palette[index]; else value=palette[255];
+  buffer.red=value>>16;
+  buffer.green=(value>>8)&0xFF;
+  buffer.blue=value&0xFF;
+  buffer.flags=DoRed|DoGreen|DoBlue;
+  return buffer;
+}
+
diff --git a/lib/dgt_dist.c b/lib/dgt_dist.c
new file mode 100644 (file)
index 0000000..5b955f8
--- /dev/null
@@ -0,0 +1,21 @@
+#include <math.h>
+#include "dgt.h"
+
+double real_dx(DGT *dgt,int dx)
+{ return (dgt->XRight-dgt->XLeft)*dx/65535;
+}
+
+double real_dy(DGT *dgt,int dy)
+{ return (dgt->YTop-dgt->YBottom)*dy/65535;
+}
+double dgt_dist(DGT *dgt,int x1,int y1,int x2,int y2)
+{ 
+  return hypot(real_dx(dgt,x1-x2),real_dy(dgt,y1-y2));
+}
+double dgt_pdist(DGT *dgt,POINT p1,POINT p2)
+{
+  return hypot(real_dx(dgt,p1.x-p2.x),real_dy(dgt,p1.y-p2.y)); 
+}
+double dgt_atan2(DGT *dgt,int dx,int dy)
+{ return atan2(dy/(dgt->XRight-dgt->XLeft),dx/(dgt->YTop-dgt->YBottom));
+}
diff --git a/lib/dgt_input.c b/lib/dgt_input.c
new file mode 100644 (file)
index 0000000..9528623
--- /dev/null
@@ -0,0 +1,112 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "dgt.h"
+int read_item(DGT* dgt)
+/* read next item of dgt file opened for reading */
+{ int to_skip=0;
+#ifndef LSB_FIRST
+  DGT_ITEM tmp;
+#endif   
+#ifdef LSB_FIRST 
+  if(fread(dgt->buffer,1,14,(FILE *)dgt->F)!=14) return 1;
+#else
+  if(fread(&tmp,1,14,(FILE *)(dgt->F))!=14) return 1;
+  dgt->buffer->ID=swaplong(tmp.ID);
+  swab(&(tmp.x1),&(dgt->buffer->x1),10);
+#endif
+  if (dgt->buffer->npoints)
+  { if(dgt->buffer->npoints>MAX_LINE_LEN) {to_skip=(dgt->buffer->npoints-MAX_LINE_LEN)*4;
+                                  dgt->buffer->npoints=MAX_LINE_LEN;}
+#ifdef LSB_FIRST
+   if (fread(&(dgt->buffer->s),4,dgt->buffer->npoints,
+                   (FILE *)dgt->F)!=dgt->buffer->npoints) 
+   { map_error = ME_READ_ERROR; return 1;}
+#else       
+   if(fread(&(tmp.s),4,dgt->buffer->npoints,
+    (FILE *)dgt->F)!=dgt->buffer->npoints)
+     {map_error=ME_READ_ERROR;return 1;}
+   swab(&(tmp.s),&(dgt->buffer->s),dgt->buffer->npoints*4);
+#endif
+   if (to_skip) fseek((FILE*)dgt->F,to_skip,SEEK_CUR);
+  }
+   dgt->item_no++;
+   return dgt->eof=(dgt->buffer->ID==0&&dgt->buffer->npoints==0);
+    
+}
+void go_first(DGT *dgt)
+{
+ fseek((FILE *)dgt->F,128L,SEEK_SET);
+ dgt->item_no=0;
+ dgt->eof=dgt->next_item(dgt);
+}
+
+DGT* open_dgt(char *filename)
+/*opens existing file, given by name*/
+{FILE *f;
+ if (!(f=fopen(filename,"r")))
+  return NULL;
+ return fopen_dgt(f); 
+}
+typedef void (*close_func)(void *f); 
+DGT* fopen_dgt(FILE *f)
+/* open existing file given by file variable */
+{ DGT* tmp;
+  DGTHEADER h;
+  if(!(tmp=malloc(sizeof(DGT)))) {map_error=ME_OUT_OF_MEMORY;return NULL;}
+  if(fread(&h,1,sizeof(h),f)!=sizeof(h)) {map_error=ME_READ_ERROR;free(tmp);return NULL;}
+  if(!(tmp->buffer=malloc(sizeof(DGT_ITEM)))) {map_error=ME_OUT_OF_MEMORY;free(tmp);return NULL;}
+  tmp->XLeft=swapdouble(h.xleft);
+  tmp->XRight=swapdouble(h.xright);
+  tmp->YTop=swapdouble(h.ytop);
+  tmp->YBottom=swapdouble(h.ybottom);
+  tmp->projection=h.coord_sys;
+  tmp->mode=MAP_INPUT;
+  tmp->item_no=0;
+  tmp->next_item=read_item;
+  tmp->rewind=go_first;
+  tmp->F=f;
+  tmp->dispose=(close_func)fclose;
+  tmp->cmp_item=NULL; 
+  tmp->next_item(tmp);
+  return tmp;
+}
+void close_dgt(DGT* dgt)
+/* Destroys DGT object */
+{ dgt->rewind(dgt);
+  dgt->dispose(dgt->F);
+  free(dgt->buffer);
+  free(dgt);
+}
+DGT_ITEM* dgt_get(DGT* dgt)
+/* allocates current item in memory and returns pointer to it*/
+{ DGT_ITEM* item;
+  if (!(dgt->mode&MAP_INPUT)) {map_error=ME_INVALID_MODE;return NULL;}
+  if (!dgt->eof) {item= alloc_item(dgt->buffer);dgt->next_item(dgt);return item;}
+  else return NULL;
+}
+int dgt_x(DGT* dgt,double x)
+{
+return ((x-dgt->XLeft)/(dgt->XRight-dgt->XLeft)*65535)-32767;
+}
+int dgt_y(DGT* dgt,double y)
+{
+return ((y-dgt->YBottom)/(dgt->YTop-dgt->YBottom)*65535)-32767;
+}
+double real_x(DGT* dgt,int x)
+{ return (x+32767)/65535.0*(dgt->XRight-dgt->XLeft)+dgt->XLeft;
+}
+double real_y(DGT* dgt,int y)
+{
+return (y+32767)/65535.0*(dgt->YTop-dgt->YBottom)+dgt->YBottom;
+}
+
+DGT_ITEM* alloc_item(DGT_ITEM *item)
+{DGT_ITEM* new_item;
+ new_item=malloc(14+item->npoints*4);
+ return memcpy(new_item,item,14+item->npoints*4);
+}
+void reset_dgt(DGT* dgt)
+/* rewinds dgt file for first item, reopens for reading,if nessecary */
+{ dgt->rewind(dgt);
+  dgt->eof=dgt->next_item(dgt);
+}  
diff --git a/lib/dgt_iter.c b/lib/dgt_iter.c
new file mode 100644 (file)
index 0000000..997e002
--- /dev/null
@@ -0,0 +1,27 @@
+#include "dgt.h"
+void for_each_line(DGT *dgt,void (*item_proc)(DGT *dgt),DGT *outstream)
+{ reset_dgt(dgt);
+  while(!dgt_eof(dgt))
+  { if (dgt_is_line(dgt))
+     item_proc(dgt);
+    if (outstream) dgt_put(outstream,dgt->buffer);
+    dgt_next(dgt);
+  }
+}
+void for_each_point(DGT *dgt,void (*item_proc)(DGT *dgt),DGT *outstream)
+{ reset_dgt(dgt);
+  while(!dgt_eof(dgt))
+  { if (dgt_is_point(dgt))
+     item_proc(dgt);
+    if (outstream) dgt_put(outstream,dgt->buffer);
+    dgt_next(dgt);
+  }
+}
+void for_each_item(DGT *dgt,void (*item_proc)(DGT *dgt))
+{ reset_dgt(dgt);
+  while(!dgt_eof(dgt))
+  { 
+     item_proc(dgt);
+    dgt_next(dgt);
+  }
+}
diff --git a/lib/dgt_output.c b/lib/dgt_output.c
new file mode 100644 (file)
index 0000000..ffc426f
--- /dev/null
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "dgt.h"
+typedef void (*close_func)(void *f); 
+
+
+DGT* creat_dgt(char *filename,double x_left,double y_bottom,
+               double x_right,double y_top, unsigned char proj)
+/* creates file with given limits with given name */           
+{FILE *f;
+ f=fopen(filename,"w+");
+ if (!f) return NULL;
+ return fcreat_dgt(f,x_left,y_bottom,x_right,y_top,proj);
+}    
+int write_header(FILE *f ,double x_left,double y_bottom,
+               double x_right,double y_top,unsigned char proj)
+{ DGTHEADER h;
+  memset(&h,0,sizeof(h));
+  h.xleft=swapdouble(x_left);
+  h.ybottom=swapdouble(y_bottom);
+  h.xright=swapdouble(x_right);
+  h.ytop=swapdouble(y_top);
+  h.coord_sys=proj;
+  return ( fwrite(&h,1,128,f)==128); 
+}               
+int write_buf(DGT *dgt)
+{
+#ifdef LSB_FIRST
+chk_mask(dgt->buffer);
+dgt->modified=0;dgt->item_no++;
+return fwrite(dgt->buffer,1,14+4*dgt->buffer->npoints,(FILE *)dgt->F)==
+  14+4*dgt->buffer->npoints;
+#else
+DGT_ITEM tmp;
+chk_mask(dgt->buffer);
+tmp.ID=swaplong(dgt->buffer->ID);
+swab(&(dgt->buffer->x1),&(tmp.x1),10+4*dgt->buffer->npoints);
+dgt->modified=0;dgt->item_no++;
+return fwrite(&tmp,14+4*dgt->buffer->npoints,1,(FILE *)dgt->F)==
+  14+4*dgt->buffer->npoints;
+#endif
+}
+void write_eof(DGT* dgt)
+{short int eof_marker[7]={0,0,0,0,0,0,0};
+ if (dgt->modified) write_buf(dgt);
+ fwrite(&eof_marker,14,1,(FILE *)dgt->F);
+}
+DGT* fcreat_dgt(FILE *f ,double x_left,double y_bottom,
+               double x_right,double y_top,unsigned char proj)
+/* creates dgt file with given limits in given stream */
+{ DGT* tmp;
+  if (!write_header(f,x_left,y_bottom,x_right,y_top,proj)) { map_error=ME_WRITE_ERROR; return NULL;}
+  if (!(tmp=malloc(sizeof(DGT)))) {map_error=ME_OUT_OF_MEMORY;return NULL;}
+  tmp->XLeft=x_left;
+  tmp->YBottom=y_bottom;
+  tmp->XRight=x_right;
+  tmp->YTop=y_top;
+  tmp->mode=MAP_OUTPUT;
+  tmp->item_no=0;
+  tmp->projection=proj;
+  tmp->F=f;
+  tmp->eof=1;
+  tmp->modified=0;
+  tmp->next_item=write_buf;
+  tmp->rewind=write_eof;
+  tmp->dispose=(close_func) fclose;
+  tmp->buffer=malloc(sizeof(DGT_ITEM));
+  return tmp;
+}
+DGT* creat_dgt_as(char *filename,DGT* pattern)
+{return creat_dgt(filename,pattern->XLeft,pattern->YBottom,pattern->XRight,
+   pattern->YTop,pattern->projection);
+}
+DGT* fcreat_dgt_as(FILE *f,DGT *pattern)
+{return fcreat_dgt(f,pattern->XLeft,pattern->YBottom,pattern->XRight,
+   pattern->YTop,pattern->projection);
+}
+void chk_mask(DGT_ITEM* item)
+/*set correct values of bounding rectangle*/
+{int i,x1,y1,x2,y2;
+ POINT* p;
+ if (!item->npoints) return;
+ x1=32767;
+ y1=32767;
+ x2=-32767;
+ y2=-32767;
+ for(i=0,p=item->s;i<item->npoints;i++,p++)
+ { if(p->x<x1) x1=p->x;
+   if(p->x>x2) x2=p->x;
+   if(p->y<y1) y1=p->y;
+   if(p->y>y2) y2=p->y;
+ }
+ item->x1=x1;
+ item->y1=y1;
+ item->x2=x2;
+ item->y2=y2;  
+}
+void dgt_put(DGT *dgt, DGT_ITEM* item)
+/* inserts item in writable file*/
+{ if (!dgt->mode&MAP_OUTPUT) {map_error=ME_INVALID_MODE;}
+  if (dgt->modified) dgt->next_item(dgt);
+  memcpy(dgt->buffer,item,14+4*item->npoints);
+  dgt->modified=1;
+  dgt->next_item(dgt);
+}
+void item_set_id(DGT_ITEM *item,long int newID)
+{item->ID=newID?newID:1;
+}
+void dgt_set_point(DGT *dgt,int x,int y)
+{ dgt->modified=1;
+  dgt->buffer->npoints=0;
+  if (x!=KEEP_OLD_VALUE) dgt->buffer->x1=x;
+  if (y!=KEEP_OLD_VALUE) dgt->buffer->y1=y;
+}
+int dgt_add_node(DGT* dgt,int x,int y)
+{ DGT_ITEM *buf=dgt->buffer;
+  POINT *p=dgt->buffer->s+dgt->buffer->npoints-1;
+  
+  if (buf->npoints==MAX_LINE_LEN) return DGT_LINE_TOO_LONG;
+  if (buf->npoints==0||p->x!=x||p->y!=y)
+  { p++;
+    p->x=x;p->y=y;
+    buf->npoints++;
+    dgt->modified=1;
+    return 0;
+  } else return DGT_ZERO_SEGMENT;
+}
+int dgt_ins_node(DGT *dgt,int index,int x,int y)
+{ DGT_ITEM *buf=dgt->buffer;
+  if (index<0) return 3;
+  if (buf->npoints==MAX_LINE_LEN) return DGT_LINE_TOO_LONG;
+  if (index>=buf->npoints)
+   if (index==buf->npoints) return dgt_add_node(dgt,x,y);
+    else return DGT_INVALID_NODE;
+  if ((index==0||buf->s[index-1].x!=x||buf->s[index-1].y!=y)
+      &&(buf->s[index].x!=x||buf->s[index].y!=y))
+   {int i; POINT *s,*s1;
+    s=buf->s+buf->npoints;
+    s1=s-1;
+    for(i=buf->npoints;i>index;i--,*(s--)=*(s1--));
+    s->x=x;
+    s->y=y;
+    buf->npoints++;
+    dgt->modified=1;
+    return 0;
+   }
+  else
+   return DGT_ZERO_SEGMENT;
+
+}  
+
+int item_mv_node(DGT_ITEM *item,int index,int x,int y)
+{ POINT *s=item->s+index,*s1;
+  if (index>=item->npoints||index<0) return DGT_INVALID_NODE;
+  
+  if (x==KEEP_OLD_VALUE) x=s->x;
+  if (y==KEEP_OLD_VALUE) y=s->y;
+  if (index>0) {s1=s-1;if (s1->x==x&&s1->y==y) return DGT_ZERO_SEGMENT;}
+  if (index<item->npoints-1)
+   { s1=s+1;if (s1->x==x&&s1->y==y) return DGT_ZERO_SEGMENT;}
+  s->x=x;
+  s->y=y;
+  return 0;
+}
+int dgt_rm_node(DGT *dgt,int index)
+{ DGT_ITEM *buf=dgt->buffer;int i;POINT *s,*s1,*s2;
+  if (buf->npoints==2) return DGT_LINE_TOO_SHORT;
+  if (index<0||index>=buf->npoints) return DGT_INVALID_NODE;
+  s=buf->s+index;
+  s1=s+1;s2=s-1;
+  if(!index&&index<buf->npoints-1&&s1->x==s2->x&&s1->y==s2->y) 
+   return DGT_ZERO_SEGMENT;
+  for(i=index+1;i<buf->npoints;i++,*(s++)=*(s1++));
+  dgt->modified=1;
+  return 0;
+}
+int dgt_split(DGT *dgt,int index)
+{DGT_ITEM new_line,*buf=dgt->buffer;
+ POINT *s,*s1;
+ int i;
+ if (index<=0||index>=buf->npoints-1) return DGT_BAD_SPLIT_POINT;
+ s=buf->s+index;
+ s1=new_line.s;
+ for(i=index;i<buf->npoints;i++,*(s1++)=*(s++));
+ new_line.npoints=buf->npoints-index;
+ buf->npoints=index+1;
+ dgt_next(dgt);
+ memcpy(buf,&new_line,14+4*new_line.npoints);
+ dgt->modified=1;
+ return 0;
+}
+
+int dgt_cut_segment(DGT *dgt,int index)
+{ POINT *s,*s1;
+  DGT_ITEM new_line,*buf=dgt->buffer;
+  int i;
+ if (index<=1||index>=buf->npoints-1) return DGT_BAD_SPLIT_POINT;
+ s=buf->s+index;
+ s1=new_line.s;
+ for(i=index;i<buf->npoints;i++,*(s1++)=*(s++));
+ new_line.npoints=buf->npoints-index;
+ buf->npoints=index;
+ dgt_next(dgt);
+ memcpy(buf,&new_line,14+4*new_line.npoints);
+ dgt->modified=1;
+ return 0;
+}
+
+
diff --git a/lib/epp_cache.c b/lib/epp_cache.c
new file mode 100644 (file)
index 0000000..fb2c7f6
--- /dev/null
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "epp.h"
+#define BAD_ROW -32769
+int search_cache(EPP *epp,int row);
+void position_input(EPP *epp,int row);
+void position_cached(EPP *epp, int row)/* makes given line current */
+{ 
+  if (row==epp->currentline) return;
+  if (!search_cache(epp,row))
+     { position_input(epp,row);
+    }        
+}
+typedef struct CACHE_REC { int row_no;
+                           unsigned short *row_ptr;} cache_rec;
+int search_cache(EPP *epp,int row)
+{ cache_rec* c;unsigned short int *rp; 
+  int i;
+  for(c=epp->cache,i=0;i<epp->cache_size && c->row_no!=BAD_ROW&&c->row_no!=row;
+          i++) c++;
+  if (i==epp->cache_size) {
+   /* Cache is full and row not found. Discard last row */
+   c--;
+  }
+  rp=c->row_ptr;
+  i=epp->currentline;
+  epp->currentline=c->row_no;
+  /* move all rows one forward */
+  for(;c!=epp->cache;c--) *c=*(c-1);
+  c=epp->cache;/* may be this is not nessecary*/
+  c->row_no=i;
+  c->row_ptr=epp->row;
+  epp->row=rp;
+  return epp->currentline==row;
+}
+void free_cache(EPP *epp)
+{ int i;cache_rec *c;
+  for (i=0,c=epp->cache;i<epp->cache_size;i++,c++)
+   free(c->row_ptr);
+  if (epp->cache) free(epp->cache);
+  epp->cache=NULL;
+  epp->cache_size=0;
+}     
+int set_epp_cache(EPP *epp,int lines)
+{ int i; cache_rec* c;
+  if (!(epp->mode&MAP_INPUT)||(epp->mode&MAP_LOADED))
+  { map_error = ME_INVALID_MODE;
+    return 0;
+  }
+ free_cache(epp);
+  /* this is really assignment inside condition*/
+ if (lines)  
+ {if (!(epp->cache=calloc(lines, sizeof(cache_rec))))
+   { return 0; }
+  for (i=0,c=epp->cache;i<lines;i++,c++)
+    {  c->row_ptr=calloc(epp->width+1,sizeof(short));
+       c->row_no=-32768;
+    }
+  epp->cache_size=lines;
+  epp->position=position_cached;
+  }
+  else epp->position=position_input;
+ return 1;
+} 
+
diff --git a/lib/epp_input.c b/lib/epp_input.c
new file mode 100644 (file)
index 0000000..4dee819
--- /dev/null
@@ -0,0 +1,274 @@
+# include "epp.h"
+# include <string.h>
+# include <stdlib.h>
+# include <math.h>
+# include <time.h>
+# include "epp_private.h"
+int map_error=0; /* after each operation contains error code */
+EPP *open_epp(char *pathname)
+/* opens existing EPP file */
+{
+  FILE *f;
+  f=fopen(pathname,"rb");
+  if (f==NULL) {map_error=ME_NO_FILE;return NULL;}
+  return fopen_epp(f);
+}  
+
+
+
+EPP *fopen_epp(FILE* f)
+{
+  EPPHEADER h;
+  EPP *epp;
+#ifndef LSB_FIRST 
+  short *file_width_table;
+#endif
+  fseek(f,0,SEEK_SET);
+  if (fread(&h,1,128,f)<128) {fclose(f);map_error=ME_INVALID_FILE;return NULL;};
+  
+  if ((swapshort(h.kind)!=8)&&(swapshort(h.kind)!=16)) {fclose(f);map_error=ME_INVALID_FILE;return NULL;}
+  epp=malloc(sizeof(EPP));
+  if (NULL==epp) { fclose(f);map_error=ME_OUT_OF_MEMORY;return NULL;}
+  epp->XLeft=swapdouble(h.fcx);
+  epp->XRight=swapdouble(h.lcx);
+  epp->YTop=swapdouble(h.fry);
+  epp->YBottom=swapdouble(h.lry);
+  epp->fr=swapshort(h.fr);
+  epp->fc=swapshort(h.fc);
+  epp->lc=swapshort(h.lc)+1;
+  epp->lr=swapshort(h.lr)+1;
+  epp->min=swapshort(h.minclass);
+  epp->max=swapshort(h.maxclass);
+  epp->offsite=swapshort(h.offsite);
+  epp->kind=swapshort(h.kind);
+  if (epp->kind==8&&(epp->min>255||epp->max>255||epp->min>epp->max))
+   {epp->min=0;epp->max=255;}
+  epp->mode=MAP_INPUT;
+  epp->position=position_input;
+  epp->cell_area=swapdouble(h.sfact);
+  epp->width=(epp->lc-epp->fc+1);
+  if ((epp->row=calloc(epp->width+1,sizeof(short)))==NULL)
+    {fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
+  if(( h.access_ptr!=0)&&(h.access_ptr!=0x20202020))
+#ifdef LSB_FIRST
+  { if((epp->widthtable = calloc(epp->lr-epp->fr,sizeof(short)))==NULL)
+     {fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
+     fseek(f,128*h.access_ptr,SEEK_SET);
+     fread(epp->widthtable,epp->lr-epp->fr,sizeof(short),f);
+  } 
+#else  
+  { if((epp->widthtable = calloc(epp->lr-epp->fr,sizeof(short)))==NULL ||
+    ( file_width_table = calloc(epp->lr-epp->fr,sizeof(short)))==NULL )
+     {fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
+     fseek(f,128*swaplong(h.access_ptr),SEEK_SET);
+     fread(file_width_table,epp->lr-epp->fr,sizeof(short),f);
+     swab(file_width_table,epp->widthtable,(epp->lr-epp->fr)*sizeof(short));
+     free(file_width_table);
+  } 
+#endif  
+  else epp->widthtable=NULL; 
+  if ((epp->packed_buffer=malloc(epp->width*4/3))==NULL)
+  { free(epp->row);if (epp->widthtable!=NULL) free(epp->widthtable);
+    fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
+ epp->F=f;
+ epp->filepos=128;
+ fseek(f,128,SEEK_SET);
+ epp->currentline=epp->fr-1; 
+ epp->cache_size=0;
+ epp->cache=NULL;
+ return epp;
+}
+void get_epp_header(EPP* epp, EPPHEADER *h)
+/* reads header of EPP file */
+{
+#ifndef LSB_FIRST
+ EPPHEADER file_header;
+#endif 
+ fseek(epp->F,0L,SEEK_SET);
+#ifdef LSB_FIRST
+ fread(h,1,128,epp->F);
+#else
+ fread(&file_header,1,128,epp->F);
+ swab(&file_header,h,64);
+ memcpy(&(h->area_unit),&(file_header.area_unit),64);
+ h->fry=swapdouble(file_header.fry); 
+ h->lry=swapdouble(file_header.lry); 
+ h->fcx=swapdouble(file_header.fcx); 
+ h->lcx=swapdouble(file_header.lcx); 
+ h->sfact=swapdouble(file_header.sfact);
+ h->access_ptr=swaplong(file_header.access_ptr);  
+#endif  
+ fseek(epp->F,epp->filepos,SEEK_SET);
+}
+
+char *getcomment(EPP *epp)
+/* returns comment of EPP file (address of static buffer,which would be
+   overriden by next call */
+{static char cmt[33];
+ char *endptr;
+ EPPHEADER h;
+ get_epp_header(epp,&h);
+ strncpy(cmt,h.comment,32);
+ cmt[32]='\0';
+ for(endptr=cmt+31;endptr>=cmt&&*endptr==' ';endptr--);
+ *(++endptr)='\0';
+ return cmt;
+}
+
+unsigned short int *epp_getline(EPP *epp,int x,int y)
+/* returns pointer to array of integer, which represents line y of raster,
+   starting from col x. NULL if x<fr */
+{ 
+  map_error=0;
+  if (!epp_contains(epp,x,y)) {map_error=ME_POINT_OUTSIDE; return NULL;}
+  if (!(epp->mode&MAP_INPUT)){map_error=ME_INVALID_MODE; return NULL;}
+  if (epp->currentline!=y)
+   { epp->position(epp,y);
+     if (map_error) return NULL;
+   }
+  return epp->row+(x-epp->fc);
+}
+
+int  epp_get(EPP *epp,int x,int y)
+/* returns value of given cell, offsite if cell is outside file boundaries */
+{ map_error=0;
+  if (!(epp->mode&MAP_INPUT)){map_error=ME_INVALID_MODE; return epp->offsite;}
+  if (!epp_contains(epp,x,y)) {map_error=ME_POINT_OUTSIDE; return epp->offsite;}
+  if (epp->currentline!=y) 
+    { 
+      epp->position(epp,y);
+      if (map_error) return epp->offsite;
+    }
+  return epp->row[x-epp->fc];
+}
+int epp_contains(EPP *epp,int x,int y)
+/* returns non-zero if <x,y> is within boundares of epp */
+{
+ return (x<epp->lc)&&(x>=epp->fc)&&(y<epp->lr)&&(y>=epp->fr);
+}
+void close_epp(EPP *epp)
+{ 
+  if (epp->mode==MAP_OUTPUT) update_header(epp);
+  if (epp->mode&MAP_CACHED)  free_cache(epp);
+  if (epp->mode&MAP_LOADED)
+  { char **row=epp->cache;
+    int i;
+    for(i=epp->fr;i<epp->lr;i++,row++) free(*row);
+    free(epp->cache); 
+  }
+  free(epp->packed_buffer);
+  fclose(epp->F);
+  free(epp->row);
+  if (epp->widthtable!=NULL) free (epp->widthtable);
+  free(epp);
+}
+/*********** coordinate recalculation **********/
+int epp_row(EPP *epp,double y)/* returns row by given alternate y */
+{
+ return floor((y-epp->YTop)/(epp->YBottom-epp->YTop)*(epp->lr-epp->fr))+epp->fr;
+
+}
+int epp_col(EPP *epp,double x)/* returns col for given alternate x */
+{
+return floor((x-epp->XLeft)/(epp->XRight-epp->XLeft)*(epp->lc-epp->fc))+epp->fc;
+}
+double alt_x(EPP *epp,int col)/* returns alternate x for given col */
+{
+return (epp->XRight-epp->XLeft)*(col-epp->fc)/(epp->lc-epp->fc)+epp->XLeft;
+}
+double alt_y(EPP *epp,int row)/* returns alternate y for given row */
+{
+return (epp->YBottom-epp->YTop)*(row-epp->fr)/(epp->lr-epp->fr)+epp->YTop;
+}
+double alt_xc(EPP *epp,int col)/* returns alternate x for given col */
+{
+return (epp->XRight-epp->XLeft)*(col-epp->fc+0.5)/(epp->lc-epp->fc)+epp->XLeft;
+}
+double alt_yc(EPP *epp,int row)/* returns alternate y for given row */
+{
+return (epp->YBottom-epp->YTop)*(row-epp->fr+0.5)/(epp->lr-epp->fr)+epp->YTop;
+}
+/**** this was private in pascal version ********/
+void position_input(EPP *epp,int row)
+{  int i,offset;
+   if (epp->currentline==row) return;
+   if (epp->currentline+1!=row)
+   {
+      if (epp->widthtable==NULL)
+      {
+        if (row>epp->currentline)
+           for(i=epp->currentline+1;i<=row;i++) get_row(epp);
+        else
+        {  fseek(epp->F,128L,SEEK_SET);
+           epp->filepos=128;
+            epp->currentline=epp->fr-1;
+           for(i=epp->fr;i<row;i++) get_row(epp);
+        }
+      }
+      else
+      {  offset=128L;
+        for (i=0;i<row-epp->fr;offset+=epp->widthtable[i++]);
+        fseek(epp->F,offset,SEEK_SET);
+        epp->filepos=offset;
+        epp->currentline=--row;
+      }
+   }
+   get_row(epp);
+
+   }
+               
+void unpack_row(unsigned char *row,int *bufpos,EPP *epp)
+{register unsigned char a,c,*r,*src;
+ int i,k;  
+ i=0;
+ r=row;
+ src=epp->packed_buffer+(*bufpos);
+ do {
+      c=*(src++);
+ if (c)
+  {
+    a=*(src++);
+    if (c+i>epp->width) c=epp->width-i+1;
+    for(k=0;k<c;k++,r+=2,i++)
+     *r=a;
+  }
+ else
+  {
+    c=*(src++);
+    if (c+i>epp->width) c=epp->width-i+1;
+    for(k=0;k<c;k++,r+=2,i++)
+      { *r=*(src++); }
+  }
+ } while (i<(epp->width-1));
+ *bufpos=src-(epp->packed_buffer);
+}
+int unpack_buffer(EPP *epp)
+{ unsigned short *r;
+  int i;
+  int bufpos=0;
+  if (epp->kind==8)
+        for(i=0,r=epp->row;i<epp->width;*(r++)=0,i++);
+#ifdef LSB_FIRST
+ unpack_row((unsigned char *)epp->row,&bufpos,epp);
+ if (epp->kind==16)
+    unpack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
+#else
+ unpack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
+ if (epp->kind==16)
+   unpack_row((unsigned char *)epp->row,&bufpos,epp);
+#endif
+  return bufpos; 
+}  
+void get_row(EPP *epp)/* reads and unpacks row of epp file */
+{
+ if  (!(epp->mode & MAP_INPUT)) {map_error=ME_INVALID_MODE;return; }
+ epp->currentline++;
+ fread(epp->packed_buffer,epp->widthtable?
+         epp->widthtable[epp->currentline-epp->fr]:epp->width*4/3,1,epp->F);
+ epp->filepos+=unpack_buffer(epp);        
+ if (!epp->widthtable)
+ { 
+   fseek(epp->F,epp->filepos,SEEK_SET);
+ }
+}
diff --git a/lib/epp_iter.c b/lib/epp_iter.c
new file mode 100644 (file)
index 0000000..5cc769f
--- /dev/null
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <string.h>
+#include <epp.h>
+#include "epp_private.h"
+int (*EndLineProc)(int row,int seqno,int total);
+int for_each_cell(EPP *epp, EPP_ITER_PROC action)
+/* performs given operation for each non-offsite cell of existing EPP file
+   (terminated if action returns non-zero,
+   or performs operation for each cell of created EPP file, filling cell
+   by value, returned by action. value parameter in this case always containt
+   offsite of epp */
+{ int i,j,k,l,rowcount,offsite;
+  rowcount=epp->lr-epp->fr;
+  offsite=epp->offsite;
+  if (epp->mode&MAP_INPUT)
+  { reset_epp(epp);
+   for(i=epp->fr,l=1;i<epp->lr;i++,l++)
+   { epp->position(epp,i);
+     for(k=0,j=epp->fc;j<epp->lc;k++,j++)
+       if (epp->row[k]!=epp->offsite) if ((*action)(j,i,epp->row[k])) return -2;
+     if (EndLineProc!=NULL) 
+      {
+       if  ((*EndLineProc)(i,l,rowcount)) return -1;
+      }
+    }
+  }
+ else
+ {
+  if (epp->currentline>epp->fr) {map_error=ME_INVALID_PUT;}
+  for (i=epp->fr,l=1;i<epp->lr;i++,l++)
+  { for(k=0,j=epp->fc;j<epp->lc;k++,j++)
+      epp_put(epp,j,i,(*action)(j,i,offsite));
+     if (EndLineProc!=NULL) 
+      {
+       if  ((*EndLineProc)(i,l,rowcount)) return -1;
+      }
+  }
+ }   
+ return 0; 
+}
+long count_cells(EPP *epp, EPP_ITER_PROC condition)
+/* calls condition for each non-offsite cell in existing epp file, returns
+   count of cells, for which condition was non-zero */
+{ int i,j,k,l,rowcount;
+  long count=0;
+  rowcount=epp->lr-epp->fr;
+  if (epp->mode&MAP_OUTPUT)
+    {map_error=ME_INVALID_MODE; return 0L;}
+   reset_epp(epp);
+   for(i=epp->fr,l=1;i<epp->lr;i++,l++)
+   { get_row(epp);
+     for(k=0,j=epp->fc;j<epp->lc;k++,j++)
+       if (epp->row[k]!=epp->offsite)
+        {
+         if ((*condition)(j,i,epp->row[k])) count++;
+        }
+     if (EndLineProc!=NULL) 
+      {
+       if  ((*EndLineProc)(i,l,rowcount)) return -1;
+      }
+    }
+  return count;
+}
+
diff --git a/lib/epp_loaded.c b/lib/epp_loaded.c
new file mode 100644 (file)
index 0000000..48f3747
--- /dev/null
@@ -0,0 +1,327 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <epp.h>
+#include "epp_private.h"
+#define row_buffer ((unsigned char **)epp->cache)
+
+
+
+/*
+ * Opens file in read-write mode and loads raster into memory 
+ * Returns pointer to newly created structure or NULL on error
+ */
+
+EPP *load_epp(char *filename)
+{
+  FILE *f;
+  f=fopen(filename,"rb+");
+  if (!f) {
+    map_error=ME_NO_FILE;
+    return NULL;
+  }
+  return fload_epp(f);
+}
+
+/*
+ * Reads file from given stream into memory. Returns 0 if Ok, -1 if
+ * something wrong
+ */
+
+int do_load_epp(EPP *epp)
+{ char **row,**rr;
+  int i,j,k,nrows;
+  unsigned short *width;
+  unsigned short *new_widthtable=NULL; /* if we have to create widthtable 
+                                  on the fly, we would keep it here */
+  int *counttab;
+  unsigned short int *pixel;
+  int oldpos;
+
+  if(!epp->widthtable) { 
+     new_widthtable=calloc(epp->lr-epp->fr,sizeof(short int));
+     
+  }
+  /* 
+    If we want to have read-write access, we should have read access
+     first. Switching from write-only to read-write access requires
+     reset_epp
+   */
+  if(!(epp->mode&MAP_INPUT)) {
+        map_error=ME_INVALID_MODE;
+        return -1;
+  }
+  /*
+    We use pointer where cache is otherwise kept
+   */
+  if (epp->mode&MAP_CACHED) { 
+     free_cache(epp);
+  }
+  /*
+     Create array of pointers to file rows
+   */
+  if ((epp->cache=calloc(epp->lr-epp->fr,sizeof(char *)))==NULL) {
+       map_error=ME_OUT_OF_MEMORY;return -1;
+  }
+  /*
+      Allocate table of frequencies.
+   */
+   /* Note, count of pixels with value==offsite not stored here! */
+   epp->counttable=calloc(1<<epp->kind,sizeof(int));
+   counttab=epp->counttable;
+   if (epp->counttable==NULL) {
+      map_error=ME_OUT_OF_MEMORY;
+      return -1;
+   }
+  /*
+     Allocate and read
+   */
+  /* We are assuming that file is fresh from fopen_epp or reset_epp */
+  nrows=epp->lr-epp->fr;
+  if (epp->widthtable) {
+     width=epp->widthtable;
+  } else {
+     width=new_widthtable;
+  }
+  for(row=epp->cache,i=epp->fr,k=1;i<epp->lr;width++,i++,row++,k++)
+   { if((*row=malloc(*width))==NULL)
+     { for(rr=epp->cache;rr<row;rr++) free(*rr);
+       free(epp->cache);
+       free(epp->counttable);
+       map_error=ME_OUT_OF_MEMORY;
+       return 0;
+     }
+     if (EndLineProc) (*EndLineProc)(i,k,nrows);
+     oldpos=epp->filepos;
+     get_row(epp); 
+     if (new_widthtable) {
+       *width=epp->filepos-oldpos;
+     }
+     memcpy(*row,epp->packed_buffer,*width);
+     for (j=epp->fc,pixel=epp->row;j<epp->lc;j++,pixel++) {
+       counttab[*pixel]++;
+     }  
+   }
+  /* find out what is actual maximum minimum of file */
+  for (i=(1<<epp->kind)-1;i>0&&(counttab[i]==0||i==epp->offsite);i--);
+  epp->max=i;
+  for (i=0;i<epp->max&&(counttab[i]==0||i==epp->offsite);i++);
+  epp->min=i; 
+  fseek(epp->F,128L,SEEK_SET);
+  epp->filepos=128;
+  epp->currentline=epp->fr-1;
+  epp->modified=0;
+  epp->mode=MAP_INPUT|MAP_OUTPUT|MAP_LOADED;
+  epp->position=position_loaded;
+  return 0;
+}
+/*
+ * Recieves stream and loads epp-file from it
+ *
+ */
+EPP *fload_epp(FILE *f) 
+{ EPP *epp;
+  epp=fopen_epp(f);
+  if (!epp) {
+    fclose(f);
+    return NULL;
+  }
+  /* do_load return non-zero on error */
+  if (do_load_epp(epp)) {
+     close_epp(epp);
+     return NULL;
+  }
+  return epp;
+}
+
+int load_new_epp(EPP *epp) 
+{
+  if (epp->mode!=MAP_OUTPUT) {
+     map_error=ME_INVALID_MODE;
+     return -1;
+  }
+  reset_epp(epp);
+  if (do_load_epp(epp)) {
+    close_epp(epp);
+    return -1;
+  }
+  return 0;
+}
+void save_row(EPP *epp)
+{  int oldsize,newsize,l=epp->currentline-epp->fr;
+   
+   if (!epp->modified) return;
+    
+   epp->mode|=MAP_MODIFIED;
+   oldsize=epp->widthtable[l];
+   newsize=pack_buffer(epp);
+   if (oldsize != newsize) { 
+      free(row_buffer[l]);
+      row_buffer[l]=malloc(newsize);
+      epp->widthtable[l]=newsize;
+   }  
+   memcpy(row_buffer[l],epp->packed_buffer,newsize);
+   epp->modified=0;
+}   
+/*
+ * Writes loaded file back. Uses stream stored in F field.
+ * Returns 0 on success, -1 on failure 
+ * Calls EndLineProc after saving each row.
+ */
+
+int save_epp(EPP *epp)
+{ 
+    char **row;
+    unsigned short *width;
+    int i,k,nrows;
+    if (!(epp->mode&MAP_LOADED)) {
+       map_error=ME_INVALID_MODE;
+       return -1;
+    }
+    save_row(epp);
+    /* If file wasn't modified, don't save. See touch_epp macro in epp.h */
+    if (!(epp->mode&MAP_MODIFIED)) {
+       map_error=0;
+       return 0;
+    }
+    fseek(epp->F,128L,SEEK_SET);
+    epp->filepos=128;
+    nrows=epp->lr-epp->fr;
+    map_error=ME_WRITE_ERROR;
+    for(i=epp->fr,row=epp->cache,width=epp->widthtable,k=1;
+           i<epp->lr; row++,width++,i++,k++) { 
+       if (EndLineProc) (*EndLineProc)(i,k,nrows);
+       if (fwrite(*row,1,*width,epp->F)!=*width) 
+           return -1; 
+       epp->filepos+=*width;
+    }
+    epp->currentline=epp->lr;
+    update_header(epp);
+    epp->position(epp,epp->fr);
+    map_error=0;     
+    return 0;
+}
+/*
+ * Writes epp file to given stream and makes this stream default
+ * Copies header by hand and then calls save_epp
+ *
+ */
+int fsave_epp_as(EPP *epp,FILE *f)
+{ EPPHEADER h;
+  
+  fread(&h,128,1,epp->F);
+  fclose(epp->F);
+  epp->F=f;
+  fseek(f,0L,SEEK_SET);
+  if (fwrite(&h,128,1,f)!=128) return 1;
+  touch_epp(epp);
+  return save_epp(epp);
+}
+/*
+ * Wrapper around fsave_epp_as, which opens stream to pass there
+ *
+ */
+
+int save_epp_as(EPP *epp,char *newname)
+{FILE *f;
+ f=fopen(newname,"w+");
+ if (!f) return 1;
+ return fsave_epp_as(epp,f);
+}
+/*
+ * position_loaded - sets current line of epp to given row. 
+ * To be stored in position field of EPP structure.
+ * Takes care of saving row, if modified and unpacks neccesary row 
+ * temporary substituting pointer to it into packed_buffer field.
+ */
+void position_loaded(EPP *epp,int row)
+{ 
+  unsigned char *tmp; /* to keep packed buffer */
+
+  if (row==epp->currentline) return;
+  save_row(epp); /* save row does nothing if row isn't modified */
+  tmp=epp->packed_buffer;
+  epp->packed_buffer=row_buffer[row-epp->fr];
+  unpack_buffer(epp);
+  epp->modified=0;
+  epp->packed_buffer=tmp;
+  epp->currentline=row;
+  map_error=0;
+} 
+/*
+ * epp_expand - converts loaded 8-bit file into 16-bit one
+ * by appending packed string of zeros to each row
+ * return 0 on succes -1 of failure.
+ * errors:
+ *    ME_INVALID_MODE - file is not loaded
+ *    ME_INVALID_FILE - file already have maximum depth
+ *    ME_OUT_OF_MEMORY - no comments
+ */ 
+int epp_expand (EPP *epp) 
+{ unsigned char *tail; /* here prepaired packed tail is kept*/
+                       /* ATTENCTION, packtail is VERY poisoneuos fish*/
+  int tail_length;
+  unsigned char *byteptr, 
+      **row;/* pointer to pointer to current packed row */
+  int i;
+  unsigned short *width; /* pointer to current element of widthtable */
+  EPPHEADER h;
+  /* check if passed file is suitable for expanding */
+  if (!(epp->mode&MAP_LOADED)) {
+     map_error=ME_INVALID_MODE;
+     return -1;
+  }
+  if (epp->kind==16) {
+     /* nowhere to expand */
+     map_error=ME_INVALID_FILE;
+     return -1;
+  }    
+  
+  /* any error, which occurs further, should be ME_OUT_OF_MEMORY*/
+  map_error=ME_OUT_OF_MEMORY;
+  
+  /* prepare packed tail */
+  tail_length=((epp->lc-epp->fc+254)/255)*2;
+  tail=malloc(tail_length);
+  if (!tail) return -1;
+  for (i=epp->lc-epp->fc,byteptr=tail;i>0;i-=255) {
+    int count=i>255?255:i;
+    *(byteptr++)=count;
+    *(byteptr++)=0;
+  }
+  /* reallocate rows */
+  
+  for (i=epp->fc,width=epp->widthtable,row=row_buffer;
+           i<epp->lc;i++,row++,width++) {
+     unsigned char *tmp=realloc(*row,*width+tail_length);
+     if (!tmp) {
+        /* realloc fails, trying to restore status quo */
+        for (i--,width--;i>=epp->fc;i--,width--)
+            *width-=tail_length;
+        return -1;
+     }
+     /* fill newly allocated memory */
+     memcpy(tmp+*width,tail,tail_length);
+     /* store new row ptr and new width */
+     *row=tmp;
+     *width+=tail_length;
+     /* Width overflow is not checked, becouse packed string of zeros
+       couldn't overflow even most lengthly 8-bit row */
+  }
+  /* fix epp->kind value */
+  epp->kind+=8;
+  /* and write it to disk immediately, becouse no one cares about
+     updating this field in header, but this function */
+  fseek(epp->F,0,SEEK_SET);
+  fread(&h,128,1,epp->F);
+  /* read errors are not checked, becouse thay are quite improbable */
+  h.kind=swapshort(epp->kind);
+  fseek(epp->F,0,SEEK_SET);
+  fwrite(&h,128,1,epp->F);
+  /* Now we are ready to exit successifully */
+  map_error=0;
+  return 0;
+}  
+  
diff --git a/lib/epp_output.c b/lib/epp_output.c
new file mode 100644 (file)
index 0000000..f99156a
--- /dev/null
@@ -0,0 +1,525 @@
+# define _POSIX_SOURCE
+/* I don't know what it means, but otherwise fileno function is not declared
+   in stdio.h
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+# define __USE_MISC
+/* Even more strange define. It is neccesary to access ftruncate function */
+#include <unistd.h>
+# undef __USE_MISC
+#include <epp.h>
+# include <math.h>
+# include <time.h>
+# include "epp_private.h"
+int Create16bit=0; /* if non-zero, all created EPP files would be 16 bit*/
+
+EPP *creat_epp(char *pathname,int first_col,int first_row,int last_col,
+               int last_row, double AXLeft,double AYTop, double AXRight,
+               double AYBottom, int scale, int base, int offsite)
+/* creating epp file from scratch. All fields which are not defined as
+ parameters, are filled by default values. Kind depends of global variable
+ Create16bit */
+{ FILE *f;
+  f=fopen(pathname,"wb+");
+  if (f==NULL) {map_error=ME_CREATE_ERROR;return NULL;}
+  return fcreat_epp(f,first_col,first_row,last_col,last_row,AXLeft,AYTop,
+  AXRight,AYBottom,scale,base,offsite);
+}  
+
+
+EPP *fcreat_epp(FILE* f,int first_col,int first_row,int last_col,
+               int last_row, double AXLeft,double AYTop, double AXRight,
+               double AYBottom, int scale, int base, int offsite)
+
+{ EPPHEADER h;
+  EPP *epp;
+  int i;
+  unsigned short int *r;
+  memset(&h,128,0);
+  if ((epp=malloc(sizeof(EPP)))==NULL) {fclose(f);map_error=ME_OUT_OF_MEMORY;
+                                           return NULL;}
+  h.fcx=swapdouble(epp->XLeft=AXLeft);
+  h.lcx=swapdouble(epp->XRight=AXRight);
+  h.lry=swapdouble(epp->YBottom=AYBottom);
+  h.fry=swapdouble(epp->YTop=AYTop);
+  h.fc=swapshort(epp->fc=first_col);
+  h.fr=swapshort(epp->fr=first_row);
+  h.lc=swapshort(epp->lc=last_col);epp->lc++;
+  h.lr=swapshort(epp->lr=last_row);epp->lr++;
+  h.scale=swapshort(scale==0?100:scale);
+  h.base=swapshort(base);
+  h.offsite=swapshort(epp->offsite=offsite);
+  epp->width=last_col-first_col+2;
+  if ((epp->row=calloc(epp->width+1,sizeof(short)))==NULL)
+   {free(epp);fclose(f);map_error=ME_OUT_OF_MEMORY;return NULL;}
+  epp->min=65535;
+  epp->max=0;
+  for(r=epp->row,i=0;i<=epp->width;*(r++)=offsite,i++);
+  if((epp->widthtable=calloc(epp->lr-epp->fr,sizeof(short)))==NULL)
+   {free(epp->row);free(epp);fclose(f);map_error=ME_OUT_OF_MEMORY;return NULL;}
+  if ((epp->packed_buffer=malloc(epp->width*4/3))==NULL)
+  { free(epp->row);if (epp->widthtable!=NULL) free(epp->widthtable);
+    fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
+  epp->F=f;
+  epp->mode=MAP_OUTPUT;
+  epp->position=position_output;
+  h.kind=swapshort(epp->kind=Create16bit?16:8);
+  h.access_ptr=0;
+  h.sfact=swapdouble(epp->cell_area=fabs(AXRight-AXLeft)/(last_col-first_col+1)*
+    fabs(AYBottom-AYTop)/(last_row-first_row+1));
+  memset(h.comment,32,' ');
+  fwrite(&h,128,1,f);
+  epp->filepos=128;
+  epp->currentline=epp->fr;
+  epp->cache_size=0;
+  epp->cache=NULL;
+  return epp;
+}
+EPP *creat_epp_as(char *pathname,EPP *pattern)
+{ FILE *f;
+  f=fopen(pathname,"wb+");
+  if (f==NULL) {map_error=ME_CREATE_ERROR;return NULL;}
+  return fcreat_epp_as(f,pattern);
+}  
+EPP *fcreat_epp_as(FILE *f,EPP *pattern)
+/* creates new epp file, copiing a most header fields from given file */
+{ EPPHEADER h;
+  EPP *epp;
+  get_epp_header(pattern,&h);
+  epp=fcreat_epp(f,h.fc,h.fr,h.lc,h.lr,
+               pattern->XLeft,pattern->YTop,pattern->XRight,
+                pattern->YBottom,h.scale,h.base,h.offsite);
+  if (epp!=NULL)
+   { char cmt[33];
+     setcomment(epp,strncpy(cmt,h.comment,32));
+   }
+  return epp;
+}
+void setcomment(EPP *epp,char *comment)
+/* change comment of epp file, which was open by creat_epp or creat_epp_as */
+{ EPPHEADER h;
+  int i;
+ if((epp->mode & MAP_OUTPUT) == 0)
+  { map_error=ME_INVALID_MODE; return; }
+ fseek(epp->F,0L,SEEK_SET);
+ fread(&h,128,1,epp->F);
+ strncpy(h.comment,comment,32); 
+ for(i=strlen(comment);i<32;i++) h.comment[i]=' ';
+ fseek(epp->F,0L,SEEK_SET);
+ fwrite(&h,128,1,epp->F);
+ fseek(epp->F,epp->filepos,SEEK_SET);
+}
+void change_epp_header(EPP *epp,EPPHEADER h)
+{ 
+  EPPHEADER fh;
+  fseek(epp->F,0L,SEEK_SET);
+  fread(&fh,128,1,epp->F);
+  fh.fcx=swapdouble(h.fcx);
+  fh.lcx=swapdouble(h.lcx);
+  fh.fry=swapdouble(h.fry);
+  fh.lry=swapdouble(h.lry);
+  fh.base=swapshort(h.base);
+  fh.scale=swapshort(h.scale);
+  fh.offsite=swapshort(epp->offsite=h.offsite);
+  fh.sfact=swapdouble(h.sfact);
+  fh.coord_sys=h.coord_sys;
+  fh.area_unit=h.area_unit;
+  memcpy(h.comment,fh.comment,32);
+  fseek(epp->F,0L,SEEK_SET);
+  fwrite(&fh,128,1,epp->F);
+  fseek(epp->F,epp->filepos,SEEK_SET);
+}
+
+int shift_epp(EPP *epp,int new_fr,int new_fc)
+{int new_lr,new_lc,result;
+ EPPHEADER h;
+ new_lr=epp->lr-epp->fr+new_fr;
+ new_lc=epp->lc-epp->fc+new_fc;
+ if ((new_fr<-32767)||(new_fc<-32767)||(new_lc>32768)||(new_lc>32768))
+  return 0;
+ if (epp->mode & MAP_OUTPUT)
+ { 
+ fseek(epp->F,0,SEEK_SET);
+ fread(&h,128,1,epp->F);
+ h.fc=swapshort(epp->fc=new_fc);
+ h.fr=swapshort(epp->fr=new_fr);
+ h.lr=swapshort((epp->lr=new_lr)-1);
+ h.lc=swapshort((epp->lc=new_lc)-1);
+ fseek(epp->F,0,SEEK_SET);
+ result=(fwrite(&h,128,1,epp->F)==128);
+ fseek(epp->F,epp->filepos,SEEK_SET);
+ }
+ else  result=1;
+ if (result)
+ { epp->fr=new_fr;
+   epp->lr=new_lr;
+   epp->fc=new_fc;
+   epp->lc=new_lc;
+ }
+ return result; 
+}
+    
+
+void reset_epp(EPP *epp)
+/* reopens epp file for reading. if file was in create mode, fills all non-filled
+lines by offsite */
+{ if (epp->mode==MAP_OUTPUT)
+  { update_header(epp); 
+    epp->mode=MAP_INPUT;
+    fseek(epp->F,128L,SEEK_SET);
+    epp->filepos=128L;
+    epp->currentline=epp->fr-1;
+    epp->position=position_input;
+   }
+   else (*epp->position)(epp,epp->fr);   
+}
+/*
+ * update_header - writes changes into header and writes width table.
+ * for write-only files also fills all unfilled rows by offsite.
+ * Modifies following field in file header:
+ * 1. access_ptr (to point to newly written width table)
+ * 2. maxclass
+ * 3. minclass
+ * 4. offsite (so we can play with its value)
+ * 5. date and time stamp
+ */
+void update_header(EPP *epp)/* writes changes into header */
+{ 
+  int i;
+  unsigned short int *r;
+  struct tm *t;
+  int table_offset;
+#ifndef LSB_FIRST
+  short *fwt;
+#endif
+  time_t timesec;
+  EPPHEADER h;
+  /* For write-only file fill rest of it by offsite */
+  if(epp->mode==MAP_OUTPUT) { 
+    put_row(epp);
+    for (r=epp->row,i=0;i<epp->width;*(r++)=epp->offsite,i++);
+    for (i=epp->currentline;i<epp->lr;i++){put_row(epp);}
+  }  
+  memset(&h,128,0);
+  /* width table should be aligned to 128 byte boundary */
+  if((i=(epp->filepos % 128))) fwrite(&h,128-i,1,epp->F);
+  table_offset=ftell(epp->F);
+#ifdef LSB_FIRST
+  fwrite(epp->widthtable,epp->lr-epp->fr,sizeof(short),epp->F);
+#else
+  fwt=calloc(epp->lr-epp->fr,sizeof(short));
+  swab(epp->widthtable,fwt,epp->lr-epp->fr);
+  fwrite(fwt,epp->lr-epp->fr,sizeof(short),epp->F);
+  free(fwt);
+#endif   
+  if ((i=(ftell(epp->F)%128))) fwrite(&h,128-i,1,epp->F);
+  /* I don't know how old software would behave if file size is
+     not multiplication of 128, so write few bytes of junk */
+  if ((i=(ftell(epp->F)%128))) fwrite(&h,128-i,1,epp->F);
+  /* Truncate file here.*/
+  ftruncate(fileno(epp->F),ftell(epp->F));
+  /* Now we are ready to write header. */
+  fseek(epp->F,0,SEEK_SET);
+  fread(&h,128,1,epp->F);
+  h.access_ptr=swaplong(table_offset / 128);
+  h.offsite=swapshort(epp->offsite);
+  h.maxclass=swapshort(epp->max);
+  h.minclass=swapshort(epp->min);
+  /* correct date/time values */
+  time(&timesec);
+  t=localtime(&timesec);
+  sprintf(h.date,"%02d/%02d/%02d",t->tm_mon+1,t->tm_mday,t->tm_year);
+  for(i=strlen(h.date);i<16;h.date[i++]=' ');
+  sprintf(h.time,"%02d:%02d:%02d",t->tm_hour,t->tm_min,t->tm_sec);
+  for(i=strlen(h.time);i<8;h.time[i++]=' ');
+  fseek(epp->F,0L,SEEK_SET);
+  fwrite(&h,128,1,epp->F);
+  epp->filepos=128;
+  epp->currentline=epp->fr-1;
+}
+/*
+ * Perform actual eppl packing algoritm. Fetch each second byte from
+ * source row, so pack_buffer can call it twice for 16-bit files
+ * row is row buffer to pack (may be pointer to second byte of actual
+ * row buffer) bufpos - stores offset in epp->packed_buffer, where to
+ * start packing. On exit it contains offset of next byte after last packed
+ */
+
+void pack_row(unsigned char *row,int *bufpos,EPP *epp)
+{
+  register unsigned char c, *dest, *i;
+  register unsigned char *stop;
+  register unsigned char *j, *k;
+  stop=row+((epp->width-1)<<1);
+  dest=epp->packed_buffer+(*bufpos);
+  for(i=row;i<stop;)
+   { j=i+2;
+     c=1;
+     while((j<stop)&&(c<255)&&(*i==*j))
+      { j+=2;c++;}
+     if (c>1)
+      { *(dest++)=c;*(dest++)=*i;
+        i=j;
+      }
+     else
+      { for(j=i+2;(j<stop-2)&&(c<255)&&(*j!=*(j+2));
+            j+=2,c++);
+       if ((j==stop-2)&&(c<255)) {j+=2;c++;}
+        if (c>1)
+          { *(dest++)=0;}
+        *(dest++)=c;
+       for (k=i;k<j;k+=2) *(dest++)=*k;
+       i=j;
+      }
+  }
+  *bufpos=(int)dest-(int)(epp->packed_buffer);
+}
+/*
+ * Stores content of epp->row into epp->packed_buffer by calling
+ * pack_row epp->kind/8 times.
+ * Updates width table.
+ */
+int pack_buffer(EPP *epp)
+{int bufpos=0;
+ if (!(epp->mode & MAP_OUTPUT)) {map_error=ME_INVALID_MODE; return 0;}
+#ifdef LSB_FIRST
+  /* Intel architecture - first byte of short is LSB. store it first */
+  pack_row((unsigned char *)epp->row,&bufpos,epp);
+  if (epp->kind==16)
+      pack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
+#else
+  /* Sparc architecture - store second byte of short first, first byte last*/
+  pack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
+  if (epp->kind==16)
+      pack_row(((unsigned char *)epp->row),&bufpos,epp);
+#endif
+  /* update width table */
+  epp->widthtable[epp->currentline-epp->fr]=bufpos;
+  return bufpos;
+} 
+/*
+ * Packs and writes row
+ *
+ */
+void put_row(EPP *epp)
+{   int l;
+    if (!(epp->mode & MAP_OUTPUT)) {
+       map_error=ME_INVALID_MODE; 
+       return;
+    }
+    l=pack_buffer(epp);
+    if (fwrite(epp->packed_buffer,1,l,epp->F)!=l) {
+       map_error=ME_WRITE_ERROR;
+       return;
+    }
+    epp->filepos+=l;
+    epp->currentline++; 
+}
+/*
+ * Positions write-only file. To be stored in position field of EPP structure.
+ * If row > current fills all rows between current and given by offsite.
+ */ 
+void position_output(EPP *epp,int row)
+{ 
+  unsigned short *r;
+  int i;
+  
+  if (row==epp->currentline) 
+     return;
+  if (!epp_contains(epp,epp->fc,row)) {
+      map_error=ME_POINT_OUTSIDE; return;
+  }
+  if (row<epp->currentline) { 
+     map_error=ME_INVALID_PUT; 
+     return;
+  }
+  /* store current row */
+  map_error=0;
+  put_row(epp);
+  if (map_error) return;
+  /* fill row buffer with offsite */
+  for (r=epp->row,i=epp->fc;i<epp->lc;i++,r++)*r=epp->offsite;
+  while (epp->currentline<row) {
+     put_row(epp); 
+     if (map_error) return;
+  }
+  /* Here we are - buffer filled with offsite and prevouis rows are written */
+}
+/*
+ * Recieves write-only file, writing to which is just finished,
+ *  and writes it into filename as
+ * 8-bit file.
+ * Doesn't even try to unpack high byte
+ */
+void fast_convert_to_8bit(EPP *source,char *filename)
+{
+   int bufpos;
+   FILE *dest;
+#ifndef LSB_FIRST
+   short *swapped_bytes;
+#endif
+   EPPHEADER h;
+   int i,j,nrows,access_ptr;
+   if (source->mode!=MAP_OUTPUT) {
+      map_error=ME_INVALID_MODE; 
+      return;
+   }
+ reset_epp(source);
+ fseek(source->F,0L,SEEK_SET);
+ fread(&h,128,1,source->F);
+ h.kind=swapshort(8);
+ if (source->offsite>255&&source->offsite!=65535) {
+     h.offsite=swapshort(source->offsite & 0xff);
+ }
+ dest=fopen(filename,"w+");
+ if (!dest) {
+     map_error=ME_WRITE_ERROR;
+     return;
+ }
+ fwrite(&h,128,1,dest);
+ nrows=source->lr-source->fr;
+ for(i=source->fr,j=0;i<source->lr;i++,j++) { 
+   if (EndLineProc) 
+      (*EndLineProc)(i,j+1,nrows);
+   fread(source->packed_buffer,source->widthtable[j],1,source->F);
+   bufpos=0;
+   unpack_row((unsigned char *)source->row,&bufpos,source);
+   source->widthtable[j]=bufpos;
+   fwrite(source->packed_buffer,bufpos,1,dest); 
+  }
+  memset(&h,128,0);
+  /* This is assignment, not condition */
+  if((i=ftell(dest) % 128)) fwrite(&h,128-i,1,dest);
+  access_ptr=ftell(dest)/128;
+#ifdef LSB_FIRST
+  fwrite(source->widthtable,nrows,2,dest);
+#else
+  swapped_bytes=malloc(nrows*2);
+  swab(source->widthtable,swapped_bytes,nrows*2);
+  fwrite(swapped_bytes,nrows,2,dest);
+#endif
+  fseek(dest,0L,SEEK_SET);
+  fread(&h,128,1,dest);
+  h.access_ptr=swaplong(access_ptr);
+  fseek(dest,0L,SEEK_SET);
+  fwrite(&h,128,1,dest);
+  fclose(dest);
+  close_epp(source);
+}
+
+/* fills given cell by value. File must be in create mode. if line is not
+ current, does nothing if line above current or fills all lines between current
+ and specified by offsite 
+*/
+void epp_put(EPP *epp,int x,int y,int value)
+{  
+    unsigned short *pixel;
+
+    if (!(epp->mode&MAP_OUTPUT)){
+       map_error=ME_INVALID_MODE; return ;
+    }
+
+    if (!epp_contains(epp,x,y)) {
+       map_error=ME_POINT_OUTSIDE; return;
+    }
+
+    if (epp->currentline!=y) { 
+    (*epp->position)(epp,y);
+    }
+    if (epp->counttable) {
+    /* if we are supporting counting of cell values*/
+        pixel=epp->row+(x-epp->fc);
+        /* # maintain table */
+       epp->counttable[*pixel]--;
+       epp->counttable[value]++;
+        *pixel=value;
+       /* # check if maximum or minimum changed   */
+        if (value>epp->max&&value!=epp->offsite) {
+           epp->max=value;
+        } else {
+           while ((epp->max==epp->offsite||!epp->counttable[epp->max])&&
+                    epp->max) 
+              epp->max--;
+        }  
+        if (value<epp->min&&value!=epp->offsite) {
+           epp->min=value;
+        } else {
+           while ((epp->min==epp->offsite||!epp->counttable[epp->min])&&
+                  epp->min<epp->max)
+              epp->min++;
+        }
+    } else {
+     /* we can only change max/min if value is outside them */
+       epp->row[x-epp->fc]=value;
+       if (value!=epp->offsite) {
+           if ((unsigned)value>epp->max) epp->max=value;
+           if ((unsigned)value<epp->min) epp->min=value;
+        }
+    }
+    epp->modified=1;
+}
+/* fills range of adjanced cells in same row with same value 
+   In create mode complains, if row is above current.
+   If any point of specified range is outside physical file limits,
+   complains and does nothing.
+*/
+void epp_putline(EPP *epp,int x1,int x2,int y,int value)
+{  
+    unsigned short *pixel;
+    int i;
+    if (!(epp->mode&MAP_OUTPUT)){
+       map_error=ME_INVALID_MODE; return ;
+    }
+
+    map_error=0;
+    /* Positioning to desired row */
+    if (epp->currentline!=y) { 
+    (*epp->position)(epp,y);
+    }
+    /* return if row is invalid */
+    if (map_error) return;
+    /* if line exceeds file limits, truncate it */
+    if (x1<epp->fc) x1=epp->fc;
+    if (x2>=epp->lc) x2=epp->lc-1;
+    /* if nothing left, return error */
+    if (x1>x2) {
+       map_error=ME_POINT_OUTSIDE;
+       return;
+    }
+    if (epp->counttable) {
+    /* if we are supporting counting of cell values*/
+        for (pixel=epp->row+(x1-epp->fc),i=x1;i<=x2;i++,pixel++) {
+           /* # maintain table */
+          epp->counttable[*pixel]--;
+           *pixel=value;
+        }
+        epp->counttable[value]+=x2-x1+1;
+       /* # check if maximum or minimum changed   */
+        if (value>epp->max&&value!=epp->offsite) {
+           epp->max=value;
+        } else {
+           while ((epp->max==epp->offsite||!epp->counttable[epp->max])&&
+                    epp->max) 
+              epp->max--;
+        }  
+        if (value<epp->min&&value!=epp->offsite) {
+           epp->min=value;
+        } else {
+           while ((epp->min==epp->offsite||!epp->counttable[epp->min])&&
+                  epp->min<epp->max)
+              epp->min++;
+        }
+    } else {
+     /* we can only change max/min if value is outside them */
+        for (pixel=epp->row+(x1-epp->fc),i=x1;i<=x2;i++,pixel++) {  
+          *pixel=value;
+        }
+        if (value!=epp->offsite) {
+           if ((unsigned)value>epp->max) epp->max=value;
+           if ((unsigned)value<epp->min) epp->min=value;
+        }
+    }
+    epp->modified=1;
+}
diff --git a/lib/epp_private.h b/lib/epp_private.h
new file mode 100644 (file)
index 0000000..b21248b
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef EPP_PRIVATE_H
+#define EPP_PRIVATE_H
+/* decladed in epp_input.c */
+void position_input(EPP* epp,int row);
+void unpack_row(unsigned char *row,int *bufpos,EPP *epp);
+int unpack_buffer(EPP *epp);
+
+/* declared in epp_output.c */
+void position_output(EPP* epp,int row);
+void update_header(EPP *epp);/* writes changes into header */
+int pack_buffer(EPP *epp);
+
+/* declared in epp_cached.c */
+extern void free_cache(EPP *epp);
+int search_cache(EPP *epp,int row);
+void position_cached(EPP* epp,int row);
+
+/* declared in epp_loaded.c */
+void position_loaded(EPP *epp,int row);
+#endif
diff --git a/lib/file_utils.c b/lib/file_utils.c
new file mode 100644 (file)
index 0000000..0312dac
--- /dev/null
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include "epp.h"
+char* default_ext(const char *name,const char *ext)
+{static char buf [1024];
+ strcpy(buf,name);
+ if (strcmp(buf+strlen(buf)-strlen(ext),ext)) {
+     struct stat statbuf;
+     strcat(buf,ext);
+     if (stat(buf,&statbuf)&&!stat(name,&statbuf)) {
+       strcpy(buf,name);
+     }
+ }
+ return buf;
+}
+
+char *force_ext(const char *name,const char *ext)
+{static char buf [1024];
+ char *last_ext;
+ strcpy(buf,name);
+ if ((last_ext=strrchr(buf,'.'))&&last_ext>strrchr(buf,'/')) *last_ext='\0';
+ return strcat(buf,ext);
+}
+char *last_ext(const char *name)
+{static char buf[128];
+ char *extptr;
+ extptr=strrchr(name,'.');
+ if(!extptr) return NULL;
+ if (strchr(extptr,'/')) return NULL;
+ return strcpy(buf,extptr);
+}
+
+int signal_recieved;
+int show_progress(int row,int seqno,int total)
+{ fprintf(stderr,"\rProcessing row %d of %d",seqno,total);
+  fflush(stderr);
+  return (signal_recieved);
+}
+int show_percent(int row,int seqno,int total)
+{ static int already_done;
+  int percent=seqno*1000/total;
+  if (percent!=already_done)
+  {  fprintf(stderr,"\r%3d.%1d%% complete",percent/10,percent%10);
+     fflush(stderr);
+     already_done=percent;
+  }
+  return signal_recieved;
+}
+
+int check_int(int row,int seqno,int total)
+{ 
+  return (signal_recieved);
+}
+
+void int_handler(int sig_no)
+{ signal_recieved=sig_no;
+  signal(sig_no,int_handler);
+}
+
+void install_progress_indicator(int (*show_progress)(int,int,int))
+{ signal_recieved=0;
+  signal(SIGINT,int_handler);
+  EndLineProc=show_progress;
+}
+
+int clear_progress(int success)
+{ if (EndLineProc)
+  { fprintf(stderr,"\r%s                           \n",success?"Aborted":"Done");
+  signal(SIGINT,SIG_DFL);
+  }
+  return success;
+}
+void show_version(char *name,char *RCS_ID)
+{ char ver[25],*version=RCS_ID+1;
+     for(;*version!='$' && *version!=':';version++);
+     strcpy(ver,version);
+     version=strrchr(ver,'$');
+     if (version) *version=0;
+     printf("SoftWeyr %c%s. Version %s\n",toupper(name[0]),name+1,ver);
+     exit(0);
+                          
+}
diff --git a/lib/gnu_lib/getopt.c b/lib/gnu_lib/getopt.c
new file mode 100644 (file)
index 0000000..7a4673b
--- /dev/null
@@ -0,0 +1,757 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+       Free Software Foundation, Inc.
+
+   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 2, 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, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+#ifdef HAVE_CONFIG_H
+#if defined (emacs) || defined (CONFIG_BROKETS)
+/* We use <config.h> instead of "config.h" so that a compilation
+   using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+   (which it would do because it found this file in $srcdir).  */
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+#ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#endif /* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define        my_index        strchr
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.
+   (Supposedly there are some machines where it might get a warning,
+   but changing this conditional to __STDC__ is too risky.)  */
+#ifdef __GNUC__
+#ifdef IN_GCC
+#include "gstddef.h"
+#else
+#include <stddef.h>
+#endif
+extern size_t strlen (const char *);
+#endif
+
+#endif                         /* GNU C library.  */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         register int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+       {
+         ordering = RETURN_IN_ORDER;
+         ++optstring;
+       }
+      else if (optstring[0] == '+')
+       {
+         ordering = REQUIRE_ORDER;
+         ++optstring;
+       }
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+       ordering = REQUIRE_ORDER;
+      else
+       ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Now skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc
+                && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+                && (longopts == NULL
+                    || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+                )
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* Special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return EOF;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+         && (longopts == NULL
+             || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+         )
+       {
+         if (ordering == REQUIRE_ORDER)
+           return EOF;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+          && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound;
+
+      while (*s && *s != '=')
+       s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+          p++, option_index++)
+       if (!strncmp (p->name, nextchar, s - nextchar))
+         {
+           if (s - nextchar == strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else
+             /* Second nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (opterr)
+           fprintf (stderr, "%s: option `%s' is ambiguous\n",
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*s)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = s + 1;
+             else
+               {
+                 if (opterr)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                "%s: option `--%s' doesn't allow an argument\n",
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                            "%s: option `%c%s' doesn't allow an argument\n",
+                            argv[0], argv[optind - 1][0], pfound->name);
+                   }
+                 nextchar += strlen (nextchar);
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (opterr)
+                   fprintf (stderr, "%s: option `%s' requires an argument\n",
+                            argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (opterr)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, "%s: unrecognized option `--%s'\n",
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (opterr)
+         {
+#if 0
+           if (c < 040 || c >= 0177)
+             fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                      argv[0], c);
+           else
+             fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+           /* 1003.2 specifies the format of this message.  */
+           fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+         }
+       optopt = c;
+       return '?';
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = 0;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (opterr)
+                 {
+#if 0
+                   fprintf (stderr, "%s: option `-%c' requires an argument\n",
+                            argv[0], c);
+#else
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr, "%s: option requires an argument -- %c\n",
+                            argv[0], c);
+#endif
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/gnu_lib/getopt.h b/lib/gnu_lib/getopt.h
new file mode 100644 (file)
index 0000000..d751c6b
--- /dev/null
@@ -0,0 +1,132 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if    __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument             0
+#define required_argument      1
+#define optional_argument      2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/lib/gnu_lib/getopt1.c b/lib/gnu_lib/getopt1.c
new file mode 100644 (file)
index 0000000..f784b57
--- /dev/null
@@ -0,0 +1,187 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+       Free Software Foundation, Inc.
+
+   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 2, 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, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+#ifdef HAVE_CONFIG_H
+#if defined (emacs) || defined (CONFIG_BROKETS)
+/* We use <config.h> instead of "config.h" so that a compilation
+   using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+   (which it would do because it found this file in $srcdir).  */
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+#include "getopt.h"
+
+#ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#else
+char *getenv ();
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == EOF)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/gnu_lib/regex.c b/lib/gnu_lib/regex.c
new file mode 100644 (file)
index 0000000..81b06ff
--- /dev/null
@@ -0,0 +1,5171 @@
+/* Extended regular expression matching and search library,
+   version 0.12.
+   (Implements POSIX draft P10003.2/D11.2, except for
+   internationalization features.)
+
+   Copyright (C) 1993 Free Software Foundation, Inc.
+
+   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 2, 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (REGEX_MALLOC)
+  #pragma alloca
+#endif
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#if defined (CONFIG_BROKETS)
+/* We use <config.h> instead of "config.h" so that a compilation
+   using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+   (which it would do because it found this file in $srcdir).  */
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+/* We need this for `regex.h', and perhaps for the Emacs include files.  */
+#include <sys/types.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* The `emacs' switch turns on certain matching commands
+   that make sense only in Emacs. */
+#ifdef emacs
+
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+/* Emacs uses `NULL' as a predicate.  */
+#undef NULL
+
+#else  /* not emacs */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+   `BSTRING', as far as I know, and neither of them use this code.  */
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+#ifndef bcmp
+#define bcmp(s1, s2, n)        memcmp ((s1), (s2), (n))
+#endif
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+#ifndef bzero
+#define bzero(s, n)    memset ((s), 0, (n))
+#endif
+#else
+#include <strings.h>
+#endif
+
+/* Define the syntax stuff for \<, \>, etc.  */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+   commands in re_match_2.  */
+#ifndef Sword 
+#define Sword 1
+#endif
+
+#ifdef SYNTAX_TABLE
+
+extern char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+/* How many characters in the character set.  */
+#define CHAR_SET_SIZE 256
+
+static char re_syntax_table[CHAR_SET_SIZE];
+
+static void
+init_syntax_once ()
+{
+   register int c;
+   static int done = 0;
+
+   if (done)
+     return;
+
+   bzero (re_syntax_table, sizeof re_syntax_table);
+
+   for (c = 'a'; c <= 'z'; c++)
+     re_syntax_table[c] = Sword;
+
+   for (c = 'A'; c <= 'Z'; c++)
+     re_syntax_table[c] = Sword;
+
+   for (c = '0'; c <= '9'; c++)
+     re_syntax_table[c] = Sword;
+
+   re_syntax_table['_'] = Sword;
+
+   done = 1;
+}
+
+#endif /* not SYNTAX_TABLE */
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+\f
+/* Get the interface, including the syntax bits.  */
+#include "regex.h"
+
+/* isalpha etc. are used for the character classes.  */
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+   "... Some ctype macros are valid only for character codes that
+   isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+   using /bin/cc or gcc but without giving an ansi option).  So, all
+   ctype uses should be through macros like ISPRINT...  If
+   STDC_HEADERS is defined, then autoconf has verified that the ctype
+   macros don't need to be guarded with references to isascii. ...
+   Defining isascii to 1 should let any compiler worth its salt
+   eliminate the && through constant folding."  */
+#if ! defined (isascii) || defined (STDC_HEADERS)
+#undef isascii
+#define isascii(c) 1
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (isascii (c) && isblank (c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (isascii (c) && isgraph (c))
+#else
+#define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c))
+#endif
+
+#define ISPRINT(c) (isascii (c) && isprint (c))
+#define ISDIGIT(c) (isascii (c) && isdigit (c))
+#define ISALNUM(c) (isascii (c) && isalnum (c))
+#define ISALPHA(c) (isascii (c) && isalpha (c))
+#define ISCNTRL(c) (isascii (c) && iscntrl (c))
+#define ISLOWER(c) (isascii (c) && islower (c))
+#define ISPUNCT(c) (isascii (c) && ispunct (c))
+#define ISSPACE(c) (isascii (c) && isspace (c))
+#define ISUPPER(c) (isascii (c) && isupper (c))
+#define ISXDIGIT(c) (isascii (c) && isxdigit (c))
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+   since ours (we hope) works properly with all combinations of
+   machines, compilers, `char' and `unsigned char' argument types.
+   (Per Bothner suggested the basic approach.)  */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else  /* not __STDC__ */
+/* As in Harbison and Steele.  */
+#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
+\f
+/* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
+   use `alloca' instead of `malloc'.  This is because using malloc in
+   re_search* or re_match* could cause memory leaks when C-g is used in
+   Emacs; also, malloc is slower and causes storage fragmentation.  On
+   the other hand, malloc is more portable, and easier to debug.  
+   
+   Because we sometimes use alloca, some routines have to be macros,
+   not functions -- `alloca'-allocated space disappears at the end of the
+   function it is called in.  */
+
+#ifdef REGEX_MALLOC
+
+#define REGEX_ALLOCATE malloc
+#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+
+#else /* not REGEX_MALLOC  */
+
+/* Emacs already defines alloca, sometimes.  */
+#ifndef alloca
+
+/* Make alloca work the best possible way.  */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not __GNUC__ or HAVE_ALLOCA_H */
+#ifndef _AIX /* Already did AIX, up at the top.  */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */ 
+#endif /* not __GNUC__ */
+
+#endif /* not alloca */
+
+#define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable.  */
+#define REGEX_REALLOCATE(source, osize, nsize)                         \
+  (destination = (char *) alloca (nsize),                              \
+   bcopy (source, destination, osize),                                 \
+   destination)
+
+#endif /* not REGEX_MALLOC */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+   `string1' or just past its end.  This works if PTR is NULL, which is
+   a good thing.  */
+#define FIRST_STRING_P(ptr)                                    \
+  (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail.  */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define RETALLOC_IF(addr, n, t) \
+  if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits.  */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+\f
+/* These are the command codes that appear in compiled regular
+   expressions.  Some opcodes are followed by argument bytes.  A
+   command code can specify any interpretation whatsoever for its
+   arguments.  Zero bytes may appear in the compiled regular expression.
+
+   The value of `exactn' is needed in search.c (search_buffer) in Emacs.
+   So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
+   `exactn' we use here must also be 1.  */
+
+typedef enum
+{
+  no_op = 0,
+
+        /* Followed by one byte giving n, then by n literal bytes.  */
+  exactn = 1,
+
+        /* Matches any (more or less) character.  */
+  anychar,
+
+        /* Matches any one char belonging to specified set.  First
+           following byte is number of bitmap bytes.  Then come bytes
+           for a bitmap saying which chars are in.  Bits in each byte
+           are ordered low-bit-first.  A character is in the set if its
+           bit is 1.  A character too large to have a bit in the map is
+           automatically not in the set.  */
+  charset,
+
+        /* Same parameters as charset, but match any character that is
+           not one of those specified.  */
+  charset_not,
+
+        /* Start remembering the text that is matched, for storing in a
+           register.  Followed by one byte with the register number, in
+           the range 0 to one less than the pattern buffer's re_nsub
+           field.  Then followed by one byte with the number of groups
+           inner to this one.  (This last has to be part of the
+           start_memory only because we need it in the on_failure_jump
+           of re_match_2.)  */
+  start_memory,
+
+        /* Stop remembering the text that is matched and store it in a
+           memory register.  Followed by one byte with the register
+           number, in the range 0 to one less than `re_nsub' in the
+           pattern buffer, and one byte with the number of inner groups,
+           just like `start_memory'.  (We need the number of inner
+           groups here because we don't have any easy way of finding the
+           corresponding start_memory when we're at a stop_memory.)  */
+  stop_memory,
+
+        /* Match a duplicate of something remembered. Followed by one
+           byte containing the register number.  */
+  duplicate,
+
+        /* Fail unless at beginning of line.  */
+  begline,
+
+        /* Fail unless at end of line.  */
+  endline,
+
+        /* Succeeds if at beginning of buffer (if emacs) or at beginning
+           of string to be matched (if not).  */
+  begbuf,
+
+        /* Analogously, for end of buffer/string.  */
+  endbuf,
+        /* Followed by two byte relative address to which to jump.  */
+  jump, 
+
+       /* Same as jump, but marks the end of an alternative.  */
+  jump_past_alt,
+
+        /* Followed by two-byte relative address of place to resume at
+           in case of failure.  */
+  on_failure_jump,
+       
+        /* Like on_failure_jump, but pushes a placeholder instead of the
+           current string position when executed.  */
+  on_failure_keep_string_jump,
+  
+        /* Throw away latest failure point and then jump to following
+           two-byte relative address.  */
+  pop_failure_jump,
+
+        /* Change to pop_failure_jump if know won't have to backtrack to
+           match; otherwise change to jump.  This is used to jump
+           back to the beginning of a repeat.  If what follows this jump
+           clearly won't match what the repeat does, such that we can be
+           sure that there is no use backtracking out of repetitions
+           already matched, then we change it to a pop_failure_jump.
+           Followed by two-byte address.  */
+  maybe_pop_jump,
+
+        /* Jump to following two-byte address, and push a dummy failure
+           point. This failure point will be thrown away if an attempt
+           is made to use it for a failure.  A `+' construct makes this
+           before the first repeat.  Also used as an intermediary kind
+           of jump when compiling an alternative.  */
+  dummy_failure_jump,
+
+       /* Push a dummy failure point and continue.  Used at the end of
+          alternatives.  */
+  push_dummy_failure,
+
+        /* Followed by two-byte relative address and two-byte number n.
+           After matching N times, jump to the address upon failure.  */
+  succeed_n,
+
+        /* Followed by two-byte relative address, and two-byte number n.
+           Jump to the address N times, then fail.  */
+  jump_n,
+
+        /* Set the following two-byte relative address to the
+           subsequent two-byte number.  The address *includes* the two
+           bytes of number.  */
+  set_number_at,
+
+  wordchar,    /* Matches any word-constituent character.  */
+  notwordchar, /* Matches any char that is not a word-constituent.  */
+
+  wordbeg,     /* Succeeds if at word beginning.  */
+  wordend,     /* Succeeds if at word end.  */
+
+  wordbound,   /* Succeeds if at a word boundary.  */
+  notwordbound /* Succeeds if not at a word boundary.  */
+
+#ifdef emacs
+  ,before_dot, /* Succeeds if before point.  */
+  at_dot,      /* Succeeds if at point.  */
+  after_dot,   /* Succeeds if after point.  */
+
+       /* Matches any character whose syntax is specified.  Followed by
+           a byte which contains a syntax code, e.g., Sword.  */
+  syntaxspec,
+
+       /* Matches any character whose syntax is not that specified.  */
+  notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+\f
+/* Common operations on the compiled pattern.  */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION.  */
+
+#define STORE_NUMBER(destination, number)                              \
+  do {                                                                 \
+    (destination)[0] = (number) & 0377;                                        \
+    (destination)[1] = (number) >> 8;                                  \
+  } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+   the byte after where the number is stored.  Therefore, DESTINATION
+   must be an lvalue.  */
+
+#define STORE_NUMBER_AND_INCR(destination, number)                     \
+  do {                                                                 \
+    STORE_NUMBER (destination, number);                                        \
+    (destination) += 2;                                                        \
+  } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+   at SOURCE.  */
+
+#define EXTRACT_NUMBER(destination, source)                            \
+  do {                                                                 \
+    (destination) = *(source) & 0377;                                  \
+    (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8;          \
+  } while (0)
+
+#ifdef DEBUG
+static void
+extract_number (dest, source)
+    int *dest;
+    unsigned char *source;
+{
+  int temp = SIGN_EXTEND_CHAR (*(source + 1)); 
+  *dest = *source & 0377;
+  *dest += temp << 8;
+}
+
+#ifndef EXTRACT_MACROS /* To debug the macros.  */
+#undef EXTRACT_NUMBER
+#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+   SOURCE must be an lvalue.  */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source)                   \
+  do {                                                                 \
+    EXTRACT_NUMBER (destination, source);                              \
+    (source) += 2;                                                     \
+  } while (0)
+
+#ifdef DEBUG
+static void
+extract_number_and_incr (destination, source)
+    int *destination;
+    unsigned char **source;
+{ 
+  extract_number (destination, *source);
+  *source += 2;
+}
+
+#ifndef EXTRACT_MACROS
+#undef EXTRACT_NUMBER_AND_INCR
+#define EXTRACT_NUMBER_AND_INCR(dest, src) \
+  extract_number_and_incr (&dest, &src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+\f
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+   it is doing (if the variable `debug' is nonzero).  If linked with the
+   main program in `iregex.c', you can enter patterns and strings
+   interactively.  And if linked with the main program in `main.c' and
+   the other test files, you can run the already-written tests.  */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging.  */
+#include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging.  */
+#include <assert.h>
+
+static int debug = 0;
+
+#define DEBUG_STATEMENT(e) e
+#define DEBUG_PRINT1(x) if (debug) printf (x)
+#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)                          \
+  if (debug) print_partial_compiled_pattern (s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)                 \
+  if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+extern void printchar ();
+
+/* Print the fastmap in human-readable form.  */
+
+void
+print_fastmap (fastmap)
+    char *fastmap;
+{
+  unsigned was_a_range = 0;
+  unsigned i = 0;  
+  
+  while (i < (1 << BYTEWIDTH))
+    {
+      if (fastmap[i++])
+       {
+         was_a_range = 0;
+          printchar (i - 1);
+          while (i < (1 << BYTEWIDTH)  &&  fastmap[i])
+            {
+              was_a_range = 1;
+              i++;
+            }
+         if (was_a_range)
+            {
+              printf ("-");
+              printchar (i - 1);
+            }
+        }
+    }
+  putchar ('\n'); 
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+   the START pointer into it and ending just before the pointer END.  */
+
+void
+print_partial_compiled_pattern (start, end)
+    unsigned char *start;
+    unsigned char *end;
+{
+  int mcnt, mcnt2;
+  unsigned char *p = start;
+  unsigned char *pend = end;
+
+  if (start == NULL)
+    {
+      printf ("(null)\n");
+      return;
+    }
+    
+  /* Loop over pattern commands.  */
+  while (p < pend)
+    {
+      printf ("%d:\t", p - start);
+
+      switch ((re_opcode_t) *p++)
+       {
+        case no_op:
+          printf ("/no_op");
+          break;
+
+       case exactn:
+         mcnt = *p++;
+          printf ("/exactn/%d", mcnt);
+          do
+           {
+              putchar ('/');
+             printchar (*p++);
+            }
+          while (--mcnt);
+          break;
+
+       case start_memory:
+          mcnt = *p++;
+          printf ("/start_memory/%d/%d", mcnt, *p++);
+          break;
+
+       case stop_memory:
+          mcnt = *p++;
+         printf ("/stop_memory/%d/%d", mcnt, *p++);
+          break;
+
+       case duplicate:
+         printf ("/duplicate/%d", *p++);
+         break;
+
+       case anychar:
+         printf ("/anychar");
+         break;
+
+       case charset:
+        case charset_not:
+          {
+            register int c, last = -100;
+           register int in_range = 0;
+
+           printf ("/charset [%s",
+                   (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+            
+            assert (p + *p < pend);
+
+            for (c = 0; c < 256; c++)
+             if (c / 8 < *p
+                 && (p[1 + (c/8)] & (1 << (c % 8))))
+               {
+                 /* Are we starting a range?  */
+                 if (last + 1 == c && ! in_range)
+                   {
+                     putchar ('-');
+                     in_range = 1;
+                   }
+                 /* Have we broken a range?  */
+                 else if (last + 1 != c && in_range)
+              {
+                     printchar (last);
+                     in_range = 0;
+                   }
+                
+                 if (! in_range)
+                   printchar (c);
+
+                 last = c;
+              }
+
+           if (in_range)
+             printchar (last);
+
+           putchar (']');
+
+           p += 1 + *p;
+         }
+         break;
+
+       case begline:
+         printf ("/begline");
+          break;
+
+       case endline:
+          printf ("/endline");
+          break;
+
+       case on_failure_jump:
+          extract_number_and_incr (&mcnt, &p);
+         printf ("/on_failure_jump to %d", p + mcnt - start);
+          break;
+
+       case on_failure_keep_string_jump:
+          extract_number_and_incr (&mcnt, &p);
+         printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+          break;
+
+       case dummy_failure_jump:
+          extract_number_and_incr (&mcnt, &p);
+         printf ("/dummy_failure_jump to %d", p + mcnt - start);
+          break;
+
+       case push_dummy_failure:
+          printf ("/push_dummy_failure");
+          break;
+          
+        case maybe_pop_jump:
+          extract_number_and_incr (&mcnt, &p);
+         printf ("/maybe_pop_jump to %d", p + mcnt - start);
+         break;
+
+        case pop_failure_jump:
+         extract_number_and_incr (&mcnt, &p);
+         printf ("/pop_failure_jump to %d", p + mcnt - start);
+         break;          
+          
+        case jump_past_alt:
+         extract_number_and_incr (&mcnt, &p);
+         printf ("/jump_past_alt to %d", p + mcnt - start);
+         break;          
+          
+        case jump:
+         extract_number_and_incr (&mcnt, &p);
+         printf ("/jump to %d", p + mcnt - start);
+         break;
+
+        case succeed_n: 
+          extract_number_and_incr (&mcnt, &p);
+          extract_number_and_incr (&mcnt2, &p);
+         printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);
+          break;
+        
+        case jump_n: 
+          extract_number_and_incr (&mcnt, &p);
+          extract_number_and_incr (&mcnt2, &p);
+         printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);
+          break;
+        
+        case set_number_at: 
+          extract_number_and_incr (&mcnt, &p);
+          extract_number_and_incr (&mcnt2, &p);
+         printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);
+          break;
+        
+        case wordbound:
+         printf ("/wordbound");
+         break;
+
+       case notwordbound:
+         printf ("/notwordbound");
+          break;
+
+       case wordbeg:
+         printf ("/wordbeg");
+         break;
+          
+       case wordend:
+         printf ("/wordend");
+          
+#ifdef emacs
+       case before_dot:
+         printf ("/before_dot");
+          break;
+
+       case at_dot:
+         printf ("/at_dot");
+          break;
+
+       case after_dot:
+         printf ("/after_dot");
+          break;
+
+       case syntaxspec:
+          printf ("/syntaxspec");
+         mcnt = *p++;
+         printf ("/%d", mcnt);
+          break;
+         
+       case notsyntaxspec:
+          printf ("/notsyntaxspec");
+         mcnt = *p++;
+         printf ("/%d", mcnt);
+         break;
+#endif /* emacs */
+
+       case wordchar:
+         printf ("/wordchar");
+          break;
+         
+       case notwordchar:
+         printf ("/notwordchar");
+          break;
+
+       case begbuf:
+         printf ("/begbuf");
+          break;
+
+       case endbuf:
+         printf ("/endbuf");
+          break;
+
+        default:
+          printf ("?%d", *(p-1));
+       }
+
+      putchar ('\n');
+    }
+
+  printf ("%d:\tend of pattern.\n", p - start);
+}
+
+
+void
+print_compiled_pattern (bufp)
+    struct re_pattern_buffer *bufp;
+{
+  unsigned char *buffer = bufp->buffer;
+
+  print_partial_compiled_pattern (buffer, buffer + bufp->used);
+  printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
+
+  if (bufp->fastmap_accurate && bufp->fastmap)
+    {
+      printf ("fastmap: ");
+      print_fastmap (bufp->fastmap);
+    }
+
+  printf ("re_nsub: %d\t", bufp->re_nsub);
+  printf ("regs_alloc: %d\t", bufp->regs_allocated);
+  printf ("can_be_null: %d\t", bufp->can_be_null);
+  printf ("newline_anchor: %d\n", bufp->newline_anchor);
+  printf ("no_sub: %d\t", bufp->no_sub);
+  printf ("not_bol: %d\t", bufp->not_bol);
+  printf ("not_eol: %d\t", bufp->not_eol);
+  printf ("syntax: %d\n", bufp->syntax);
+  /* Perhaps we should print the translate table?  */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+    const char *where;
+    const char *string1;
+    const char *string2;
+    int size1;
+    int size2;
+{
+  unsigned this_char;
+  
+  if (where == NULL)
+    printf ("(null)");
+  else
+    {
+      if (FIRST_STRING_P (where))
+        {
+          for (this_char = where - string1; this_char < size1; this_char++)
+            printchar (string1[this_char]);
+
+          where = string2;    
+        }
+
+      for (this_char = where - string2; this_char < size2; this_char++)
+        printchar (string2[this_char]);
+    }
+}
+
+#else /* not DEBUG */
+
+#undef assert
+#define assert(e)
+
+#define DEBUG_STATEMENT(e)
+#define DEBUG_PRINT1(x)
+#define DEBUG_PRINT2(x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+\f
+/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
+   also be assigned to arbitrarily: each pattern buffer stores its own
+   syntax, so it can be changed between regex compilations.  */
+reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
+
+
+/* Specify the precise syntax of regexps for compilation.  This provides
+   for compatibility for various utilities which historically have
+   different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit mask comprised of the various bits
+   defined in regex.h.  We return the old syntax.  */
+
+reg_syntax_t
+re_set_syntax (syntax)
+    reg_syntax_t syntax;
+{
+  reg_syntax_t ret = re_syntax_options;
+  
+  re_syntax_options = syntax;
+  return ret;
+}
+\f
+/* This table gives an error message for each of the error codes listed
+   in regex.h.  Obviously the order here has to be same as there.  */
+
+static const char *re_error_msg[] =
+  { NULL,                                      /* REG_NOERROR */
+    "No match",                                        /* REG_NOMATCH */
+    "Invalid regular expression",              /* REG_BADPAT */
+    "Invalid collation character",             /* REG_ECOLLATE */
+    "Invalid character class name",            /* REG_ECTYPE */
+    "Trailing backslash",                      /* REG_EESCAPE */
+    "Invalid back reference",                  /* REG_ESUBREG */
+    "Unmatched [ or [^",                       /* REG_EBRACK */
+    "Unmatched ( or \\(",                      /* REG_EPAREN */
+    "Unmatched \\{",                           /* REG_EBRACE */
+    "Invalid content of \\{\\}",               /* REG_BADBR */
+    "Invalid range end",                       /* REG_ERANGE */
+    "Memory exhausted",                                /* REG_ESPACE */
+    "Invalid preceding regular expression",    /* REG_BADRPT */
+    "Premature end of regular expression",     /* REG_EEND */
+    "Regular expression too big",              /* REG_ESIZE */
+    "Unmatched ) or \\)",                      /* REG_ERPAREN */
+  };
+\f
+/* Avoiding alloca during matching, to placate r_alloc.  */
+
+/* Define MATCH_MAY_ALLOCATE if we need to make sure that the
+   searching and matching functions should not call alloca.  On some
+   systems, alloca is implemented in terms of malloc, and if we're
+   using the relocating allocator routines, then malloc could cause a
+   relocation, which might (if the strings being searched are in the
+   ralloc heap) shift the data out from underneath the regexp
+   routines.
+
+   Here's another reason to avoid allocation: Emacs insists on
+   processing input from X in a signal handler; processing X input may
+   call malloc; if input arrives while a matching routine is calling
+   malloc, then we're scrod.  But Emacs can't just block input while
+   calling matching routines; then we don't notice interrupts when
+   they come in.  So, Emacs blocks input around all regexp calls
+   except the matching calls, which it leaves unprotected, in the
+   faith that they will not malloc.  */
+
+/* Normally, this is fine.  */
+#define MATCH_MAY_ALLOCATE
+
+/* But under some circumstances, it's not.  */
+#if defined (emacs) || (defined (REL_ALLOC) && defined (C_ALLOCA))
+#undef MATCH_MAY_ALLOCATE
+#endif
+
+\f
+/* Failure stack declarations and macros; both re_compile_fastmap and
+   re_match_2 use a failure stack.  These have to be macros because of
+   REGEX_ALLOCATE.  */
+   
+
+/* Number of failure points for which to initially allocate space
+   when matching.  If this number is exceeded, we allocate more
+   space, so it is not a hard limit.  */
+#ifndef INIT_FAILURE_ALLOC
+#define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack.  Would be
+   exactly that if always used MAX_FAILURE_SPACE each time we failed.
+   This is a variable only so users of regex can assign to it; we never
+   change it ourselves.  */
+int re_max_failures = 2000;
+
+typedef unsigned char *fail_stack_elt_t;
+
+typedef struct
+{
+  fail_stack_elt_t *stack;
+  unsigned size;
+  unsigned avail;                      /* Offset of next open position.  */
+} fail_stack_type;
+
+#define FAIL_STACK_EMPTY()     (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL()      (fail_stack.avail == fail_stack.size)
+#define FAIL_STACK_TOP()       (fail_stack.stack[fail_stack.avail])
+
+
+/* Initialize `fail_stack'.  Do `return -2' if the alloc fails.  */
+
+#ifdef MATCH_MAY_ALLOCATE
+#define INIT_FAIL_STACK()                                              \
+  do {                                                                 \
+    fail_stack.stack = (fail_stack_elt_t *)                            \
+      REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+                                                                       \
+    if (fail_stack.stack == NULL)                                      \
+      return -2;                                                       \
+                                                                       \
+    fail_stack.size = INIT_FAILURE_ALLOC;                              \
+    fail_stack.avail = 0;                                              \
+  } while (0)
+#else
+#define INIT_FAIL_STACK()                                              \
+  do {                                                                 \
+    fail_stack.avail = 0;                                              \
+  } while (0)
+#endif
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+   Return 1 if succeeds, and 0 if either ran out of memory
+   allocating space for it or it was already too large.  
+   
+   REGEX_REALLOCATE requires `destination' be declared.   */
+
+#define DOUBLE_FAIL_STACK(fail_stack)                                  \
+  ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS             \
+   ? 0                                                                 \
+   : ((fail_stack).stack = (fail_stack_elt_t *)                                \
+        REGEX_REALLOCATE ((fail_stack).stack,                          \
+          (fail_stack).size * sizeof (fail_stack_elt_t),               \
+          ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)),       \
+                                                                       \
+      (fail_stack).stack == NULL                                       \
+      ? 0                                                              \
+      : ((fail_stack).size <<= 1,                                      \
+         1)))
+
+
+/* Push PATTERN_OP on FAIL_STACK. 
+
+   Return 1 if was able to do so and 0 if ran out of memory allocating
+   space to do so.  */
+#define PUSH_PATTERN_OP(pattern_op, fail_stack)                                \
+  ((FAIL_STACK_FULL ()                                                 \
+    && !DOUBLE_FAIL_STACK (fail_stack))                                        \
+    ? 0                                                                        \
+    : ((fail_stack).stack[(fail_stack).avail++] = pattern_op,          \
+       1))
+
+/* This pushes an item onto the failure stack.  Must be a four-byte
+   value.  Assumes the variable `fail_stack'.  Probably should only
+   be called from within `PUSH_FAILURE_POINT'.  */
+#define PUSH_FAILURE_ITEM(item)                                                \
+  fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
+
+/* The complement operation.  Assumes `fail_stack' is nonempty.  */
+#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging.  */
+#ifdef DEBUG
+#define DEBUG_PUSH PUSH_FAILURE_ITEM
+#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM ()
+#else
+#define DEBUG_PUSH(item)
+#define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+   if we ever fail back to it.  
+   
+   Requires variables fail_stack, regstart, regend, reg_info, and
+   num_regs be declared.  DOUBLE_FAIL_STACK requires `destination' be
+   declared.
+   
+   Does `return FAILURE_CODE' if runs out of memory.  */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code)  \
+  do {                                                                 \
+    char *destination;                                                 \
+    /* Must be int, so when we don't save any registers, the arithmetic        \
+       of 0 + -1 isn't done as unsigned.  */                           \
+    int this_reg;                                                      \
+                                                                       \
+    DEBUG_STATEMENT (failure_id++);                                    \
+    DEBUG_STATEMENT (nfailure_points_pushed++);                                \
+    DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id);          \
+    DEBUG_PRINT2 ("  Before push, next avail: %d\n", (fail_stack).avail);\
+    DEBUG_PRINT2 ("                     size: %d\n", (fail_stack).size);\
+                                                                       \
+    DEBUG_PRINT2 ("  slots needed: %d\n", NUM_FAILURE_ITEMS);          \
+    DEBUG_PRINT2 ("     available: %d\n", REMAINING_AVAIL_SLOTS);      \
+                                                                       \
+    /* Ensure we have enough space allocated for what we will push.  */        \
+    while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS)                  \
+      {                                                                        \
+        if (!DOUBLE_FAIL_STACK (fail_stack))                   \
+          return failure_code;                                         \
+                                                                       \
+        DEBUG_PRINT2 ("\n  Doubled stack; size now: %d\n",             \
+                      (fail_stack).size);                              \
+        DEBUG_PRINT2 ("  slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+      }                                                                        \
+                                                                       \
+    /* Push the info, starting with the registers.  */                 \
+    DEBUG_PRINT1 ("\n");                                               \
+                                                                       \
+    for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+         this_reg++)                                                   \
+      {                                                                        \
+       DEBUG_PRINT2 ("  Pushing reg: %d\n", this_reg);                 \
+        DEBUG_STATEMENT (num_regs_pushed++);                           \
+                                                                       \
+       DEBUG_PRINT2 ("    start: 0x%x\n", regstart[this_reg]);         \
+        PUSH_FAILURE_ITEM (regstart[this_reg]);                                \
+                                                                        \
+       DEBUG_PRINT2 ("    end: 0x%x\n", regend[this_reg]);             \
+        PUSH_FAILURE_ITEM (regend[this_reg]);                          \
+                                                                       \
+       DEBUG_PRINT2 ("    info: 0x%x\n      ", reg_info[this_reg]);    \
+        DEBUG_PRINT2 (" match_null=%d",                                        \
+                      REG_MATCH_NULL_STRING_P (reg_info[this_reg]));   \
+        DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg]));   \
+        DEBUG_PRINT2 (" matched_something=%d",                         \
+                      MATCHED_SOMETHING (reg_info[this_reg]));         \
+        DEBUG_PRINT2 (" ever_matched=%d",                              \
+                      EVER_MATCHED_SOMETHING (reg_info[this_reg]));    \
+       DEBUG_PRINT1 ("\n");                                            \
+        PUSH_FAILURE_ITEM (reg_info[this_reg].word);                   \
+      }                                                                        \
+                                                                       \
+    DEBUG_PRINT2 ("  Pushing  low active reg: %d\n", lowest_active_reg);\
+    PUSH_FAILURE_ITEM (lowest_active_reg);                             \
+                                                                       \
+    DEBUG_PRINT2 ("  Pushing high active reg: %d\n", highest_active_reg);\
+    PUSH_FAILURE_ITEM (highest_active_reg);                            \
+                                                                       \
+    DEBUG_PRINT2 ("  Pushing pattern 0x%x: ", pattern_place);          \
+    DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend);          \
+    PUSH_FAILURE_ITEM (pattern_place);                                 \
+                                                                       \
+    DEBUG_PRINT2 ("  Pushing string 0x%x: `", string_place);           \
+    DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2,   \
+                                size2);                                \
+    DEBUG_PRINT1 ("'\n");                                              \
+    PUSH_FAILURE_ITEM (string_place);                                  \
+                                                                       \
+    DEBUG_PRINT2 ("  Pushing failure id: %u\n", failure_id);           \
+    DEBUG_PUSH (failure_id);                                           \
+  } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+   for each register.  */
+#define NUM_REG_ITEMS  3
+
+/* Individual items aside from the registers.  */
+#ifdef DEBUG
+#define NUM_NONREG_ITEMS 5 /* Includes failure point id.  */
+#else
+#define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack.  */
+#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items.  */
+#define NUM_FAILURE_ITEMS                                              \
+  ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS        \
+    + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it.  */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+   We restore into the parameters, all of which should be lvalues:
+     STR -- the saved data position.
+     PAT -- the saved pattern position.
+     LOW_REG, HIGH_REG -- the highest and lowest active registers.
+     REGSTART, REGEND -- arrays of string positions.
+     REG_INFO -- array of information about each subexpression.
+   
+   Also assumes the variables `fail_stack' and (if debugging), `bufp',
+   `pend', `string1', `size1', `string2', and `size2'.  */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{                                                                      \
+  DEBUG_STATEMENT (fail_stack_elt_t failure_id;)                       \
+  int this_reg;                                                                \
+  const unsigned char *string_temp;                                    \
+                                                                       \
+  assert (!FAIL_STACK_EMPTY ());                                       \
+                                                                       \
+  /* Remove failure points and point to how many regs pushed.  */      \
+  DEBUG_PRINT1 ("POP_FAILURE_POINT:\n");                               \
+  DEBUG_PRINT2 ("  Before pop, next avail: %d\n", fail_stack.avail);   \
+  DEBUG_PRINT2 ("                    size: %d\n", fail_stack.size);    \
+                                                                       \
+  assert (fail_stack.avail >= NUM_NONREG_ITEMS);                       \
+                                                                       \
+  DEBUG_POP (&failure_id);                                             \
+  DEBUG_PRINT2 ("  Popping failure id: %u\n", failure_id);             \
+                                                                       \
+  /* If the saved string location is NULL, it came from an             \
+     on_failure_keep_string_jump opcode, and we want to throw away the \
+     saved NULL, thus retaining our current position in the string.  */        \
+  string_temp = POP_FAILURE_ITEM ();                                   \
+  if (string_temp != NULL)                                             \
+    str = (const char *) string_temp;                                  \
+                                                                       \
+  DEBUG_PRINT2 ("  Popping string 0x%x: `", str);                      \
+  DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2);     \
+  DEBUG_PRINT1 ("'\n");                                                        \
+                                                                       \
+  pat = (unsigned char *) POP_FAILURE_ITEM ();                         \
+  DEBUG_PRINT2 ("  Popping pattern 0x%x: ", pat);                      \
+  DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend);                      \
+                                                                       \
+  /* Restore register info.  */                                                \
+  high_reg = (unsigned) POP_FAILURE_ITEM ();                           \
+  DEBUG_PRINT2 ("  Popping high active reg: %d\n", high_reg);          \
+                                                                       \
+  low_reg = (unsigned) POP_FAILURE_ITEM ();                            \
+  DEBUG_PRINT2 ("  Popping  low active reg: %d\n", low_reg);           \
+                                                                       \
+  for (this_reg = high_reg; this_reg >= low_reg; this_reg--)           \
+    {                                                                  \
+      DEBUG_PRINT2 ("    Popping reg: %d\n", this_reg);                        \
+                                                                       \
+      reg_info[this_reg].word = POP_FAILURE_ITEM ();                   \
+      DEBUG_PRINT2 ("      info: 0x%x\n", reg_info[this_reg]);         \
+                                                                       \
+      regend[this_reg] = (const char *) POP_FAILURE_ITEM ();           \
+      DEBUG_PRINT2 ("      end: 0x%x\n", regend[this_reg]);            \
+                                                                       \
+      regstart[this_reg] = (const char *) POP_FAILURE_ITEM ();         \
+      DEBUG_PRINT2 ("      start: 0x%x\n", regstart[this_reg]);                \
+    }                                                                  \
+                                                                       \
+  DEBUG_STATEMENT (nfailure_points_popped++);                          \
+} /* POP_FAILURE_POINT */
+
+
+\f
+/* Structure for per-register (a.k.a. per-group) information.
+   This must not be longer than one word, because we push this value
+   onto the failure stack.  Other register information, such as the
+   starting and ending positions (which are addresses), and the list of
+   inner groups (which is a bits list) are maintained in separate
+   variables.  
+   
+   We are making a (strictly speaking) nonportable assumption here: that
+   the compiler will pack our bit fields into something that fits into
+   the type of `word', i.e., is something that fits into one item on the
+   failure stack.  */
+typedef union
+{
+  fail_stack_elt_t word;
+  struct
+  {
+      /* This field is one if this group can match the empty string,
+         zero if not.  If not yet determined,  `MATCH_NULL_UNSET_VALUE'.  */
+#define MATCH_NULL_UNSET_VALUE 3
+    unsigned match_null_string_p : 2;
+    unsigned is_active : 1;
+    unsigned matched_something : 1;
+    unsigned ever_matched_something : 1;
+  } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R)  ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R)  ((R).bits.is_active)
+#define MATCHED_SOMETHING(R)  ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R)  ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+   for the subexpressions which we are currently inside.  Also records
+   that those subexprs have matched.  */
+#define SET_REGS_MATCHED()                                             \
+  do                                                                   \
+    {                                                                  \
+      unsigned r;                                                      \
+      for (r = lowest_active_reg; r <= highest_active_reg; r++)                \
+        {                                                              \
+          MATCHED_SOMETHING (reg_info[r])                              \
+            = EVER_MATCHED_SOMETHING (reg_info[r])                     \
+            = 1;                                                       \
+        }                                                              \
+    }                                                                  \
+  while (0)
+
+
+/* Registers are set to a sentinel when they haven't yet matched.  */
+#define REG_UNSET_VALUE ((char *) -1)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+
+\f
+/* How do we implement a missing MATCH_MAY_ALLOCATE?
+   We make the fail stack a global thing, and then grow it to
+   re_max_failures when we compile.  */
+#ifndef MATCH_MAY_ALLOCATE
+static fail_stack_type fail_stack;
+
+static const char **     regstart, **     regend;
+static const char ** old_regstart, ** old_regend;
+static const char **best_regstart, **best_regend;
+static register_info_type *reg_info; 
+static const char **reg_dummy;
+static register_info_type *reg_info_dummy;
+#endif
+
+\f
+/* Subroutine declarations and macros for regex_compile.  */
+
+static void store_op1 (), store_op2 ();
+static void insert_op1 (), insert_op2 ();
+static boolean at_begline_loc_p (), at_endline_loc_p ();
+static boolean group_in_compile_stack ();
+static reg_errcode_t compile_range ();
+
+/* Fetch the next character in the uncompiled pattern---translating it 
+   if necessary.  Also cast from a signed character in the constant
+   string passed to us by the user to an unsigned char that we can use
+   as an array index (in, e.g., `translate').  */
+#define PATFETCH(c)                                                    \
+  do {if (p == pend) return REG_EEND;                                  \
+    c = (unsigned char) *p++;                                          \
+    if (translate) c = translate[c];                                   \
+  } while (0)
+
+/* Fetch the next character in the uncompiled pattern, with no
+   translation.  */
+#define PATFETCH_RAW(c)                                                        \
+  do {if (p == pend) return REG_EEND;                                  \
+    c = (unsigned char) *p++;                                          \
+  } while (0)
+
+/* Go backwards one character in the pattern.  */
+#define PATUNFETCH p--
+
+
+/* If `translate' is non-null, return translate[D], else just D.  We
+   cast the subscript to translate because some data is declared as
+   `char *', to avoid warnings when a string constant is passed.  But
+   when we use a character as a subscript we must make it unsigned.  */
+#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
+
+
+/* Macros for outputting the compiled pattern into `buffer'.  */
+
+/* If the buffer isn't allocated when it comes in, use this.  */
+#define INIT_BUF_SIZE  32
+
+/* Make sure we have at least N more bytes of space in buffer.  */
+#define GET_BUFFER_SPACE(n)                                            \
+    while (b - bufp->buffer + (n) > bufp->allocated)                   \
+      EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it.  */
+#define BUF_PUSH(c)                                                    \
+  do {                                                                 \
+    GET_BUFFER_SPACE (1);                                              \
+    *b++ = (unsigned char) (c);                                                \
+  } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2.  */
+#define BUF_PUSH_2(c1, c2)                                             \
+  do {                                                                 \
+    GET_BUFFER_SPACE (2);                                              \
+    *b++ = (unsigned char) (c1);                                       \
+    *b++ = (unsigned char) (c2);                                       \
+  } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes.  */
+#define BUF_PUSH_3(c1, c2, c3)                                         \
+  do {                                                                 \
+    GET_BUFFER_SPACE (3);                                              \
+    *b++ = (unsigned char) (c1);                                       \
+    *b++ = (unsigned char) (c2);                                       \
+    *b++ = (unsigned char) (c3);                                       \
+  } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO.  We store a
+   relative address offset by the three bytes the jump itself occupies.  */
+#define STORE_JUMP(op, loc, to) \
+  store_op1 (op, loc, (to) - (loc) - 3)
+
+/* Likewise, for a two-argument jump.  */
+#define STORE_JUMP2(op, loc, to, arg) \
+  store_op2 (op, loc, (to) - (loc) - 3, arg)
+
+/* Like `STORE_JUMP', but for inserting.  Assume `b' is the buffer end.  */
+#define INSERT_JUMP(op, loc, to) \
+  insert_op1 (op, loc, (to) - (loc) - 3, b)
+
+/* Like `STORE_JUMP2', but for inserting.  Assume `b' is the buffer end.  */
+#define INSERT_JUMP2(op, loc, to, arg) \
+  insert_op2 (op, loc, (to) - (loc) - 3, arg, b)
+
+
+/* This is not an arbitrary limit: the arguments which represent offsets
+   into the pattern are two bytes long.  So if 2^16 bytes turns out to
+   be too small, many things would have to change.  */
+#define MAX_BUF_SIZE (1L << 16)
+
+
+/* Extend the buffer by twice its current size via realloc and
+   reset the pointers that pointed into the old block to point to the
+   correct places in the new one.  If extending the buffer results in it
+   being larger than MAX_BUF_SIZE, then flag memory exhausted.  */
+#define EXTEND_BUFFER()                                                        \
+  do {                                                                         \
+    unsigned char *old_buffer = bufp->buffer;                          \
+    if (bufp->allocated == MAX_BUF_SIZE)                               \
+      return REG_ESIZE;                                                        \
+    bufp->allocated <<= 1;                                             \
+    if (bufp->allocated > MAX_BUF_SIZE)                                        \
+      bufp->allocated = MAX_BUF_SIZE;                                  \
+    bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\
+    if (bufp->buffer == NULL)                                          \
+      return REG_ESPACE;                                               \
+    /* If the buffer moved, move all the pointers into it.  */         \
+    if (old_buffer != bufp->buffer)                                    \
+      {                                                                        \
+        b = (b - old_buffer) + bufp->buffer;                           \
+        begalt = (begalt - old_buffer) + bufp->buffer;                 \
+        if (fixup_alt_jump)                                            \
+          fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+        if (laststart)                                                 \
+          laststart = (laststart - old_buffer) + bufp->buffer;         \
+        if (pending_exact)                                             \
+          pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+      }                                                                        \
+  } while (0)
+
+
+/* Since we have one byte reserved for the register number argument to
+   {start,stop}_memory, the maximum number of groups we can report
+   things about is what fits in that byte.  */
+#define MAX_REGNUM 255
+
+/* But patterns can have more than `MAX_REGNUM' registers.  We just
+   ignore the excess.  */
+typedef unsigned regnum_t;
+
+
+/* Macros for the compile stack.  */
+
+/* Since offsets can go either forwards or backwards, this type needs to
+   be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1.  */
+typedef int pattern_offset_t;
+
+typedef struct
+{
+  pattern_offset_t begalt_offset;
+  pattern_offset_t fixup_alt_jump;
+  pattern_offset_t inner_group_offset;
+  pattern_offset_t laststart_offset;  
+  regnum_t regnum;
+} compile_stack_elt_t;
+
+
+typedef struct
+{
+  compile_stack_elt_t *stack;
+  unsigned size;
+  unsigned avail;                      /* Offset of next open position.  */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY  (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL  (compile_stack.avail == compile_stack.size)
+
+/* The next available element.  */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list.  */
+#define SET_LIST_BIT(c)                               \
+  (b[((unsigned char) (c)) / BYTEWIDTH]               \
+   |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern.  */
+#define GET_UNSIGNED_NUMBER(num)                                       \
+  { if (p != pend)                                                     \
+     {                                                                 \
+       PATFETCH (c);                                                   \
+       while (ISDIGIT (c))                                             \
+         {                                                             \
+           if (num < 0)                                                        \
+              num = 0;                                                 \
+           num = num * 10 + c - '0';                                   \
+           if (p == pend)                                              \
+              break;                                                   \
+           PATFETCH (c);                                               \
+         }                                                             \
+       }                                                               \
+    }          
+
+#define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
+
+#define IS_CHAR_CLASS(string)                                          \
+   (STREQ (string, "alpha") || STREQ (string, "upper")                 \
+    || STREQ (string, "lower") || STREQ (string, "digit")              \
+    || STREQ (string, "alnum") || STREQ (string, "xdigit")             \
+    || STREQ (string, "space") || STREQ (string, "print")              \
+    || STREQ (string, "punct") || STREQ (string, "graph")              \
+    || STREQ (string, "cntrl") || STREQ (string, "blank"))
+\f
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+   Returns one of error codes defined in `regex.h', or zero for success.
+
+   Assumes the `allocated' (and perhaps `buffer') and `translate'
+   fields are set in BUFP on entry.
+
+   If it succeeds, results are put in BUFP (if it returns an error, the
+   contents of BUFP are undefined):
+     `buffer' is the compiled pattern;
+     `syntax' is set to SYNTAX;
+     `used' is set to the length of the compiled pattern;
+     `fastmap_accurate' is zero;
+     `re_nsub' is the number of subexpressions in PATTERN;
+     `not_bol' and `not_eol' are zero;
+   
+   The `fastmap' and `newline_anchor' fields are neither
+   examined nor set.  */
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+     const char *pattern;
+     int size;
+     reg_syntax_t syntax;
+     struct re_pattern_buffer *bufp;
+{
+  /* We fetch characters from PATTERN here.  Even though PATTERN is
+     `char *' (i.e., signed), we declare these variables as unsigned, so
+     they can be reliably used as array indices.  */
+  register unsigned char c, c1;
+  
+  /* A random tempory spot in PATTERN.  */
+  const char *p1;
+
+  /* Points to the end of the buffer, where we should append.  */
+  register unsigned char *b;
+  
+  /* Keeps track of unclosed groups.  */
+  compile_stack_type compile_stack;
+
+  /* Points to the current (ending) position in the pattern.  */
+  const char *p = pattern;
+  const char *pend = pattern + size;
+  
+  /* How to translate the characters in the pattern.  */
+  char *translate = bufp->translate;
+
+  /* Address of the count-byte of the most recently inserted `exactn'
+     command.  This makes it possible to tell if a new exact-match
+     character can be added to that command or if the character requires
+     a new `exactn' command.  */
+  unsigned char *pending_exact = 0;
+
+  /* Address of start of the most recently finished expression.
+     This tells, e.g., postfix * where to find the start of its
+     operand.  Reset at the beginning of groups and alternatives.  */
+  unsigned char *laststart = 0;
+
+  /* Address of beginning of regexp, or inside of last group.  */
+  unsigned char *begalt;
+
+  /* Place in the uncompiled pattern (i.e., the {) to
+     which to go back if the interval is invalid.  */
+  const char *beg_interval;
+                
+  /* Address of the place where a forward jump should go to the end of
+     the containing expression.  Each alternative of an `or' -- except the
+     last -- ends with a forward jump of this sort.  */
+  unsigned char *fixup_alt_jump = 0;
+
+  /* Counts open-groups as they are encountered.  Remembered for the
+     matching close-group on the compile stack, so the same register
+     number is put in the stop_memory as the start_memory.  */
+  regnum_t regnum = 0;
+
+#ifdef DEBUG
+  DEBUG_PRINT1 ("\nCompiling pattern: ");
+  if (debug)
+    {
+      unsigned debug_count;
+      
+      for (debug_count = 0; debug_count < size; debug_count++)
+        printchar (pattern[debug_count]);
+      putchar ('\n');
+    }
+#endif /* DEBUG */
+
+  /* Initialize the compile stack.  */
+  compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+  if (compile_stack.stack == NULL)
+    return REG_ESPACE;
+
+  compile_stack.size = INIT_COMPILE_STACK_SIZE;
+  compile_stack.avail = 0;
+
+  /* Initialize the pattern buffer.  */
+  bufp->syntax = syntax;
+  bufp->fastmap_accurate = 0;
+  bufp->not_bol = bufp->not_eol = 0;
+
+  /* Set `used' to zero, so that if we return an error, the pattern
+     printer (for debugging) will think there's no pattern.  We reset it
+     at the end.  */
+  bufp->used = 0;
+  
+  /* Always count groups, whether or not bufp->no_sub is set.  */
+  bufp->re_nsub = 0;                           
+
+#if !defined (emacs) && !defined (SYNTAX_TABLE)
+  /* Initialize the syntax table.  */
+   init_syntax_once ();
+#endif
+
+  if (bufp->allocated == 0)
+    {
+      if (bufp->buffer)
+       { /* If zero allocated, but buffer is non-null, try to realloc
+             enough space.  This loses if buffer's address is bogus, but
+             that is the user's responsibility.  */
+          RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+        }
+      else
+        { /* Caller did not allocate a buffer.  Do it for them.  */
+          bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+        }
+      if (!bufp->buffer) return REG_ESPACE;
+
+      bufp->allocated = INIT_BUF_SIZE;
+    }
+
+  begalt = b = bufp->buffer;
+
+  /* Loop through the uncompiled pattern until we're at the end.  */
+  while (p != pend)
+    {
+      PATFETCH (c);
+
+      switch (c)
+        {
+        case '^':
+          {
+            if (   /* If at start of pattern, it's an operator.  */
+                   p == pattern + 1
+                   /* If context independent, it's an operator.  */
+                || syntax & RE_CONTEXT_INDEP_ANCHORS
+                   /* Otherwise, depends on what's come before.  */
+                || at_begline_loc_p (pattern, p, syntax))
+              BUF_PUSH (begline);
+            else
+              goto normal_char;
+          }
+          break;
+
+
+        case '$':
+          {
+            if (   /* If at end of pattern, it's an operator.  */
+                   p == pend 
+                   /* If context independent, it's an operator.  */
+                || syntax & RE_CONTEXT_INDEP_ANCHORS
+                   /* Otherwise, depends on what's next.  */
+                || at_endline_loc_p (p, pend, syntax))
+               BUF_PUSH (endline);
+             else
+               goto normal_char;
+           }
+           break;
+
+
+       case '+':
+        case '?':
+          if ((syntax & RE_BK_PLUS_QM)
+              || (syntax & RE_LIMITED_OPS))
+            goto normal_char;
+        handle_plus:
+        case '*':
+          /* If there is no previous pattern... */
+          if (!laststart)
+            {
+              if (syntax & RE_CONTEXT_INVALID_OPS)
+                return REG_BADRPT;
+              else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+                goto normal_char;
+            }
+
+          {
+            /* Are we optimizing this jump?  */
+            boolean keep_string_p = false;
+            
+            /* 1 means zero (many) matches is allowed.  */
+            char zero_times_ok = 0, many_times_ok = 0;
+
+            /* If there is a sequence of repetition chars, collapse it
+               down to just one (the right one).  We can't combine
+               interval operators with these because of, e.g., `a{2}*',
+               which should only match an even number of `a's.  */
+
+            for (;;)
+              {
+                zero_times_ok |= c != '+';
+                many_times_ok |= c != '?';
+
+                if (p == pend)
+                  break;
+
+                PATFETCH (c);
+
+                if (c == '*'
+                    || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+                  ;
+
+                else if (syntax & RE_BK_PLUS_QM  &&  c == '\\')
+                  {
+                    if (p == pend) return REG_EESCAPE;
+
+                    PATFETCH (c1);
+                    if (!(c1 == '+' || c1 == '?'))
+                      {
+                        PATUNFETCH;
+                        PATUNFETCH;
+                        break;
+                      }
+
+                    c = c1;
+                  }
+                else
+                  {
+                    PATUNFETCH;
+                    break;
+                  }
+
+                /* If we get here, we found another repeat character.  */
+               }
+
+            /* Star, etc. applied to an empty pattern is equivalent
+               to an empty pattern.  */
+            if (!laststart)  
+              break;
+
+            /* Now we know whether or not zero matches is allowed
+               and also whether or not two or more matches is allowed.  */
+            if (many_times_ok)
+              { /* More than one repetition is allowed, so put in at the
+                   end a backward relative jump from `b' to before the next
+                   jump we're going to put in below (which jumps from
+                   laststart to after this jump).  
+
+                   But if we are at the `*' in the exact sequence `.*\n',
+                   insert an unconditional jump backwards to the .,
+                   instead of the beginning of the loop.  This way we only
+                   push a failure point once, instead of every time
+                   through the loop.  */
+                assert (p - 1 > pattern);
+
+                /* Allocate the space for the jump.  */
+                GET_BUFFER_SPACE (3);
+
+                /* We know we are not at the first character of the pattern,
+                   because laststart was nonzero.  And we've already
+                   incremented `p', by the way, to be the character after
+                   the `*'.  Do we have to do something analogous here
+                   for null bytes, because of RE_DOT_NOT_NULL?  */
+                if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+                   && zero_times_ok
+                    && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+                    && !(syntax & RE_DOT_NEWLINE))
+                  { /* We have .*\n.  */
+                    STORE_JUMP (jump, b, laststart);
+                    keep_string_p = true;
+                  }
+                else
+                  /* Anything else.  */
+                  STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+                /* We've added more stuff to the buffer.  */
+                b += 3;
+              }
+
+            /* On failure, jump from laststart to b + 3, which will be the
+               end of the buffer after this jump is inserted.  */
+            GET_BUFFER_SPACE (3);
+            INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+                                       : on_failure_jump,
+                         laststart, b + 3);
+            pending_exact = 0;
+            b += 3;
+
+            if (!zero_times_ok)
+              {
+                /* At least one repetition is required, so insert a
+                   `dummy_failure_jump' before the initial
+                   `on_failure_jump' instruction of the loop. This
+                   effects a skip over that instruction the first time
+                   we hit that loop.  */
+                GET_BUFFER_SPACE (3);
+                INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+                b += 3;
+              }
+            }
+         break;
+
+
+       case '.':
+          laststart = b;
+          BUF_PUSH (anychar);
+          break;
+
+
+        case '[':
+          {
+            boolean had_char_class = false;
+
+            if (p == pend) return REG_EBRACK;
+
+            /* Ensure that we have enough space to push a charset: the
+               opcode, the length count, and the bitset; 34 bytes in all.  */
+           GET_BUFFER_SPACE (34);
+
+            laststart = b;
+
+            /* We test `*p == '^' twice, instead of using an if
+               statement, so we only need one BUF_PUSH.  */
+            BUF_PUSH (*p == '^' ? charset_not : charset); 
+            if (*p == '^')
+              p++;
+
+            /* Remember the first position in the bracket expression.  */
+            p1 = p;
+
+            /* Push the number of bytes in the bitmap.  */
+            BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+            /* Clear the whole map.  */
+            bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+            /* charset_not matches newline according to a syntax bit.  */
+            if ((re_opcode_t) b[-2] == charset_not
+                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+              SET_LIST_BIT ('\n');
+
+            /* Read in characters and ranges, setting map bits.  */
+            for (;;)
+              {
+                if (p == pend) return REG_EBRACK;
+
+                PATFETCH (c);
+
+                /* \ might escape characters inside [...] and [^...].  */
+                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+                  {
+                    if (p == pend) return REG_EESCAPE;
+
+                    PATFETCH (c1);
+                    SET_LIST_BIT (c1);
+                    continue;
+                  }
+
+                /* Could be the end of the bracket expression.  If it's
+                   not (i.e., when the bracket expression is `[]' so
+                   far), the ']' character bit gets set way below.  */
+                if (c == ']' && p != p1 + 1)
+                  break;
+
+                /* Look ahead to see if it's a range when the last thing
+                   was a character class.  */
+                if (had_char_class && c == '-' && *p != ']')
+                  return REG_ERANGE;
+
+                /* Look ahead to see if it's a range when the last thing
+                   was a character: if this is a hyphen not at the
+                   beginning or the end of a list, then it's the range
+                   operator.  */
+                if (c == '-' 
+                    && !(p - 2 >= pattern && p[-2] == '[') 
+                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+                    && *p != ']')
+                  {
+                    reg_errcode_t ret
+                      = compile_range (&p, pend, translate, syntax, b);
+                    if (ret != REG_NOERROR) return ret;
+                  }
+
+                else if (p[0] == '-' && p[1] != ']')
+                  { /* This handles ranges made up of characters only.  */
+                    reg_errcode_t ret;
+
+                   /* Move past the `-'.  */
+                    PATFETCH (c1);
+                    
+                    ret = compile_range (&p, pend, translate, syntax, b);
+                    if (ret != REG_NOERROR) return ret;
+                  }
+
+                /* See if we're at the beginning of a possible character
+                   class.  */
+
+                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+                  { /* Leave room for the null.  */
+                    char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+                    PATFETCH (c);
+                    c1 = 0;
+
+                    /* If pattern is `[[:'.  */
+                    if (p == pend) return REG_EBRACK;
+
+                    for (;;)
+                      {
+                        PATFETCH (c);
+                        if (c == ':' || c == ']' || p == pend
+                            || c1 == CHAR_CLASS_MAX_LENGTH)
+                          break;
+                        str[c1++] = c;
+                      }
+                    str[c1] = '\0';
+
+                    /* If isn't a word bracketed by `[:' and:`]':
+                       undo the ending character, the letters, and leave 
+                       the leading `:' and `[' (but set bits for them).  */
+                    if (c == ':' && *p == ']')
+                      {
+                        int ch;
+                        boolean is_alnum = STREQ (str, "alnum");
+                        boolean is_alpha = STREQ (str, "alpha");
+                        boolean is_blank = STREQ (str, "blank");
+                        boolean is_cntrl = STREQ (str, "cntrl");
+                        boolean is_digit = STREQ (str, "digit");
+                        boolean is_graph = STREQ (str, "graph");
+                        boolean is_lower = STREQ (str, "lower");
+                        boolean is_print = STREQ (str, "print");
+                        boolean is_punct = STREQ (str, "punct");
+                        boolean is_space = STREQ (str, "space");
+                        boolean is_upper = STREQ (str, "upper");
+                        boolean is_xdigit = STREQ (str, "xdigit");
+                        
+                        if (!IS_CHAR_CLASS (str)) return REG_ECTYPE;
+
+                        /* Throw away the ] at the end of the character
+                           class.  */
+                        PATFETCH (c);                                  
+
+                        if (p == pend) return REG_EBRACK;
+
+                        for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+                          {
+                            if (   (is_alnum  && ISALNUM (ch))
+                                || (is_alpha  && ISALPHA (ch))
+                                || (is_blank  && ISBLANK (ch))
+                                || (is_cntrl  && ISCNTRL (ch))
+                                || (is_digit  && ISDIGIT (ch))
+                                || (is_graph  && ISGRAPH (ch))
+                                || (is_lower  && ISLOWER (ch))
+                                || (is_print  && ISPRINT (ch))
+                                || (is_punct  && ISPUNCT (ch))
+                                || (is_space  && ISSPACE (ch))
+                                || (is_upper  && ISUPPER (ch))
+                                || (is_xdigit && ISXDIGIT (ch)))
+                            SET_LIST_BIT (ch);
+                          }
+                        had_char_class = true;
+                      }
+                    else
+                      {
+                        c1++;
+                        while (c1--)    
+                          PATUNFETCH;
+                        SET_LIST_BIT ('[');
+                        SET_LIST_BIT (':');
+                        had_char_class = false;
+                      }
+                  }
+                else
+                  {
+                    had_char_class = false;
+                    SET_LIST_BIT (c);
+                  }
+              }
+
+            /* Discard any (non)matching list bytes that are all 0 at the
+               end of the map.  Decrease the map-length byte too.  */
+            while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) 
+              b[-1]--; 
+            b += b[-1];
+          }
+          break;
+
+
+       case '(':
+          if (syntax & RE_NO_BK_PARENS)
+            goto handle_open;
+          else
+            goto normal_char;
+
+
+        case ')':
+          if (syntax & RE_NO_BK_PARENS)
+            goto handle_close;
+          else
+            goto normal_char;
+
+
+        case '\n':
+          if (syntax & RE_NEWLINE_ALT)
+            goto handle_alt;
+          else
+            goto normal_char;
+
+
+       case '|':
+          if (syntax & RE_NO_BK_VBAR)
+            goto handle_alt;
+          else
+            goto normal_char;
+
+
+        case '{':
+           if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+             goto handle_interval;
+           else
+             goto normal_char;
+
+
+        case '\\':
+          if (p == pend) return REG_EESCAPE;
+
+          /* Do not translate the character after the \, so that we can
+             distinguish, e.g., \B from \b, even if we normally would
+             translate, e.g., B to b.  */
+          PATFETCH_RAW (c);
+
+          switch (c)
+            {
+            case '(':
+              if (syntax & RE_NO_BK_PARENS)
+                goto normal_backslash;
+
+            handle_open:
+              bufp->re_nsub++;
+              regnum++;
+
+              if (COMPILE_STACK_FULL)
+                { 
+                  RETALLOC (compile_stack.stack, compile_stack.size << 1,
+                            compile_stack_elt_t);
+                  if (compile_stack.stack == NULL) return REG_ESPACE;
+
+                  compile_stack.size <<= 1;
+                }
+
+              /* These are the values to restore when we hit end of this
+                 group.  They are all relative offsets, so that if the
+                 whole pattern moves because of realloc, they will still
+                 be valid.  */
+              COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+              COMPILE_STACK_TOP.fixup_alt_jump 
+                = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+              COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+              COMPILE_STACK_TOP.regnum = regnum;
+
+              /* We will eventually replace the 0 with the number of
+                 groups inner to this one.  But do not push a
+                 start_memory for groups beyond the last one we can
+                 represent in the compiled pattern.  */
+              if (regnum <= MAX_REGNUM)
+                {
+                  COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+                  BUF_PUSH_3 (start_memory, regnum, 0);
+                }
+                
+              compile_stack.avail++;
+
+              fixup_alt_jump = 0;
+              laststart = 0;
+              begalt = b;
+             /* If we've reached MAX_REGNUM groups, then this open
+                won't actually generate any code, so we'll have to
+                clear pending_exact explicitly.  */
+             pending_exact = 0;
+              break;
+
+
+            case ')':
+              if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+              if (COMPILE_STACK_EMPTY)
+                if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+                  goto normal_backslash;
+                else
+                  return REG_ERPAREN;
+
+            handle_close:
+              if (fixup_alt_jump)
+                { /* Push a dummy failure point at the end of the
+                     alternative for a possible future
+                     `pop_failure_jump' to pop.  See comments at
+                     `push_dummy_failure' in `re_match_2'.  */
+                  BUF_PUSH (push_dummy_failure);
+                  
+                  /* We allocated space for this jump when we assigned
+                     to `fixup_alt_jump', in the `handle_alt' case below.  */
+                  STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+                }
+
+              /* See similar code for backslashed left paren above.  */
+              if (COMPILE_STACK_EMPTY)
+                if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+                  goto normal_char;
+                else
+                  return REG_ERPAREN;
+
+              /* Since we just checked for an empty stack above, this
+                 ``can't happen''.  */
+              assert (compile_stack.avail != 0);
+              {
+                /* We don't just want to restore into `regnum', because
+                   later groups should continue to be numbered higher,
+                   as in `(ab)c(de)' -- the second group is #2.  */
+                regnum_t this_group_regnum;
+
+                compile_stack.avail--;         
+                begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+                fixup_alt_jump
+                  = COMPILE_STACK_TOP.fixup_alt_jump
+                    ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 
+                    : 0;
+                laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+                this_group_regnum = COMPILE_STACK_TOP.regnum;
+               /* If we've reached MAX_REGNUM groups, then this open
+                  won't actually generate any code, so we'll have to
+                  clear pending_exact explicitly.  */
+               pending_exact = 0;
+
+                /* We're at the end of the group, so now we know how many
+                   groups were inside this one.  */
+                if (this_group_regnum <= MAX_REGNUM)
+                  {
+                    unsigned char *inner_group_loc
+                      = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+                    
+                    *inner_group_loc = regnum - this_group_regnum;
+                    BUF_PUSH_3 (stop_memory, this_group_regnum,
+                                regnum - this_group_regnum);
+                  }
+              }
+              break;
+
+
+            case '|':                                  /* `\|'.  */
+              if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+                goto normal_backslash;
+            handle_alt:
+              if (syntax & RE_LIMITED_OPS)
+                goto normal_char;
+
+              /* Insert before the previous alternative a jump which
+                 jumps to this alternative if the former fails.  */
+              GET_BUFFER_SPACE (3);
+              INSERT_JUMP (on_failure_jump, begalt, b + 6);
+              pending_exact = 0;
+              b += 3;
+
+              /* The alternative before this one has a jump after it
+                 which gets executed if it gets matched.  Adjust that
+                 jump so it will jump to this alternative's analogous
+                 jump (put in below, which in turn will jump to the next
+                 (if any) alternative's such jump, etc.).  The last such
+                 jump jumps to the correct final destination.  A picture:
+                          _____ _____ 
+                          |   | |   |   
+                          |   v |   v 
+                         a | b   | c   
+
+                 If we are at `b', then fixup_alt_jump right now points to a
+                 three-byte space after `a'.  We'll put in the jump, set
+                 fixup_alt_jump to right after `b', and leave behind three
+                 bytes which we'll fill in when we get to after `c'.  */
+
+              if (fixup_alt_jump)
+                STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+              /* Mark and leave space for a jump after this alternative,
+                 to be filled in later either by next alternative or
+                 when know we're at the end of a series of alternatives.  */
+              fixup_alt_jump = b;
+              GET_BUFFER_SPACE (3);
+              b += 3;
+
+              laststart = 0;
+              begalt = b;
+              break;
+
+
+            case '{': 
+              /* If \{ is a literal.  */
+              if (!(syntax & RE_INTERVALS)
+                     /* If we're at `\{' and it's not the open-interval 
+                        operator.  */
+                  || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+                  || (p - 2 == pattern  &&  p == pend))
+                goto normal_backslash;
+
+            handle_interval:
+              {
+                /* If got here, then the syntax allows intervals.  */
+
+                /* At least (most) this many matches must be made.  */
+                int lower_bound = -1, upper_bound = -1;
+
+                beg_interval = p - 1;
+
+                if (p == pend)
+                  {
+                    if (syntax & RE_NO_BK_BRACES)
+                      goto unfetch_interval;
+                    else
+                      return REG_EBRACE;
+                  }
+
+                GET_UNSIGNED_NUMBER (lower_bound);
+
+                if (c == ',')
+                  {
+                    GET_UNSIGNED_NUMBER (upper_bound);
+                    if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+                  }
+                else
+                  /* Interval such as `{1}' => match exactly once. */
+                  upper_bound = lower_bound;
+
+                if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+                    || lower_bound > upper_bound)
+                  {
+                    if (syntax & RE_NO_BK_BRACES)
+                      goto unfetch_interval;
+                    else 
+                      return REG_BADBR;
+                  }
+
+                if (!(syntax & RE_NO_BK_BRACES)) 
+                  {
+                    if (c != '\\') return REG_EBRACE;
+
+                    PATFETCH (c);
+                  }
+
+                if (c != '}')
+                  {
+                    if (syntax & RE_NO_BK_BRACES)
+                      goto unfetch_interval;
+                    else 
+                      return REG_BADBR;
+                  }
+
+                /* We just parsed a valid interval.  */
+
+                /* If it's invalid to have no preceding re.  */
+                if (!laststart)
+                  {
+                    if (syntax & RE_CONTEXT_INVALID_OPS)
+                      return REG_BADRPT;
+                    else if (syntax & RE_CONTEXT_INDEP_OPS)
+                      laststart = b;
+                    else
+                      goto unfetch_interval;
+                  }
+
+                /* If the upper bound is zero, don't want to succeed at
+                   all; jump from `laststart' to `b + 3', which will be
+                   the end of the buffer after we insert the jump.  */
+                 if (upper_bound == 0)
+                   {
+                     GET_BUFFER_SPACE (3);
+                     INSERT_JUMP (jump, laststart, b + 3);
+                     b += 3;
+                   }
+
+                 /* Otherwise, we have a nontrivial interval.  When
+                    we're all done, the pattern will look like:
+                      set_number_at <jump count> <upper bound>
+                      set_number_at <succeed_n count> <lower bound>
+                      succeed_n <after jump addr> <succed_n count>
+                      <body of loop>
+                      jump_n <succeed_n addr> <jump count>
+                    (The upper bound and `jump_n' are omitted if
+                    `upper_bound' is 1, though.)  */
+                 else 
+                   { /* If the upper bound is > 1, we need to insert
+                        more at the end of the loop.  */
+                     unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+                     GET_BUFFER_SPACE (nbytes);
+
+                     /* Initialize lower bound of the `succeed_n', even
+                        though it will be set during matching by its
+                        attendant `set_number_at' (inserted next),
+                        because `re_compile_fastmap' needs to know.
+                        Jump to the `jump_n' we might insert below.  */
+                     INSERT_JUMP2 (succeed_n, laststart,
+                                   b + 5 + (upper_bound > 1) * 5,
+                                   lower_bound);
+                     b += 5;
+
+                     /* Code to initialize the lower bound.  Insert 
+                        before the `succeed_n'.  The `5' is the last two
+                        bytes of this `set_number_at', plus 3 bytes of
+                        the following `succeed_n'.  */
+                     insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+                     b += 5;
+
+                     if (upper_bound > 1)
+                       { /* More than one repetition is allowed, so
+                            append a backward jump to the `succeed_n'
+                            that starts this interval.
+                            
+                            When we've reached this during matching,
+                            we'll have matched the interval once, so
+                            jump back only `upper_bound - 1' times.  */
+                         STORE_JUMP2 (jump_n, b, laststart + 5,
+                                      upper_bound - 1);
+                         b += 5;
+
+                         /* The location we want to set is the second
+                            parameter of the `jump_n'; that is `b-2' as
+                            an absolute address.  `laststart' will be
+                            the `set_number_at' we're about to insert;
+                            `laststart+3' the number to set, the source
+                            for the relative address.  But we are
+                            inserting into the middle of the pattern --
+                            so everything is getting moved up by 5.
+                            Conclusion: (b - 2) - (laststart + 3) + 5,
+                            i.e., b - laststart.
+                            
+                            We insert this at the beginning of the loop
+                            so that if we fail during matching, we'll
+                            reinitialize the bounds.  */
+                         insert_op2 (set_number_at, laststart, b - laststart,
+                                     upper_bound - 1, b);
+                         b += 5;
+                       }
+                   }
+                pending_exact = 0;
+                beg_interval = NULL;
+              }
+              break;
+
+            unfetch_interval:
+              /* If an invalid interval, match the characters as literals.  */
+               assert (beg_interval);
+               p = beg_interval;
+               beg_interval = NULL;
+
+               /* normal_char and normal_backslash need `c'.  */
+               PATFETCH (c);   
+
+               if (!(syntax & RE_NO_BK_BRACES))
+                 {
+                   if (p > pattern  &&  p[-1] == '\\')
+                     goto normal_backslash;
+                 }
+               goto normal_char;
+
+#ifdef emacs
+            /* There is no way to specify the before_dot and after_dot
+               operators.  rms says this is ok.  --karl  */
+            case '=':
+              BUF_PUSH (at_dot);
+              break;
+
+            case 's':  
+              laststart = b;
+              PATFETCH (c);
+              BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+              break;
+
+            case 'S':
+              laststart = b;
+              PATFETCH (c);
+              BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+              break;
+#endif /* emacs */
+
+
+            case 'w':
+              laststart = b;
+              BUF_PUSH (wordchar);
+              break;
+
+
+            case 'W':
+              laststart = b;
+              BUF_PUSH (notwordchar);
+              break;
+
+
+            case '<':
+              BUF_PUSH (wordbeg);
+              break;
+
+            case '>':
+              BUF_PUSH (wordend);
+              break;
+
+            case 'b':
+              BUF_PUSH (wordbound);
+              break;
+
+            case 'B':
+              BUF_PUSH (notwordbound);
+              break;
+
+            case '`':
+              BUF_PUSH (begbuf);
+              break;
+
+            case '\'':
+              BUF_PUSH (endbuf);
+              break;
+
+            case '1': case '2': case '3': case '4': case '5':
+            case '6': case '7': case '8': case '9':
+              if (syntax & RE_NO_BK_REFS)
+                goto normal_char;
+
+              c1 = c - '0';
+
+              if (c1 > regnum)
+                return REG_ESUBREG;
+
+              /* Can't back reference to a subexpression if inside of it.  */
+              if (group_in_compile_stack (compile_stack, c1))
+                goto normal_char;
+
+              laststart = b;
+              BUF_PUSH_2 (duplicate, c1);
+              break;
+
+
+            case '+':
+            case '?':
+              if (syntax & RE_BK_PLUS_QM)
+                goto handle_plus;
+              else
+                goto normal_backslash;
+
+            default:
+            normal_backslash:
+              /* You might think it would be useful for \ to mean
+                 not to translate; but if we don't translate it
+                 it will never match anything.  */
+              c = TRANSLATE (c);
+              goto normal_char;
+            }
+          break;
+
+
+       default:
+        /* Expects the character in `c'.  */
+       normal_char:
+             /* If no exactn currently being built.  */
+          if (!pending_exact 
+
+              /* If last exactn not at current position.  */
+              || pending_exact + *pending_exact + 1 != b
+              
+              /* We have only one byte following the exactn for the count.  */
+             || *pending_exact == (1 << BYTEWIDTH) - 1
+
+              /* If followed by a repetition operator.  */
+              || *p == '*' || *p == '^'
+             || ((syntax & RE_BK_PLUS_QM)
+                 ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+                 : (*p == '+' || *p == '?'))
+             || ((syntax & RE_INTERVALS)
+                  && ((syntax & RE_NO_BK_BRACES)
+                     ? *p == '{'
+                      : (p[0] == '\\' && p[1] == '{'))))
+           {
+             /* Start building a new exactn.  */
+              
+              laststart = b;
+
+             BUF_PUSH_2 (exactn, 0);
+             pending_exact = b - 1;
+            }
+            
+         BUF_PUSH (c);
+          (*pending_exact)++;
+         break;
+        } /* switch (c) */
+    } /* while p != pend */
+
+  
+  /* Through the pattern now.  */
+  
+  if (fixup_alt_jump)
+    STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+  if (!COMPILE_STACK_EMPTY) 
+    return REG_EPAREN;
+
+  free (compile_stack.stack);
+
+  /* We have succeeded; set the length of the buffer.  */
+  bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+  if (debug)
+    {
+      DEBUG_PRINT1 ("\nCompiled pattern: \n");
+      print_compiled_pattern (bufp);
+    }
+#endif /* DEBUG */
+
+#ifndef MATCH_MAY_ALLOCATE
+  /* Initialize the failure stack to the largest possible stack.  This
+     isn't necessary unless we're trying to avoid calling alloca in
+     the search and match routines.  */
+  {
+    int num_regs = bufp->re_nsub + 1;
+
+    /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
+       is strictly greater than re_max_failures, the largest possible stack
+       is 2 * re_max_failures failure points.  */
+    fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
+    if (fail_stack.stack)
+      fail_stack.stack =
+       (fail_stack_elt_t *) realloc (fail_stack.stack,
+                                     (fail_stack.size
+                                      * sizeof (fail_stack_elt_t)));
+    else
+      fail_stack.stack =
+       (fail_stack_elt_t *) malloc (fail_stack.size 
+                                    * sizeof (fail_stack_elt_t));
+
+    /* Initialize some other variables the matcher uses.  */
+    RETALLOC_IF (regstart,      num_regs, const char *);
+    RETALLOC_IF (regend,        num_regs, const char *);
+    RETALLOC_IF (old_regstart,  num_regs, const char *);
+    RETALLOC_IF (old_regend,    num_regs, const char *);
+    RETALLOC_IF (best_regstart,  num_regs, const char *);
+    RETALLOC_IF (best_regend,   num_regs, const char *);
+    RETALLOC_IF (reg_info,      num_regs, register_info_type);
+    RETALLOC_IF (reg_dummy,     num_regs, const char *);
+    RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
+  }
+#endif
+
+  return REG_NOERROR;
+} /* regex_compile */
+\f
+/* Subroutines for `regex_compile'.  */
+
+/* Store OP at LOC followed by two-byte integer parameter ARG.  */
+
+static void
+store_op1 (op, loc, arg)
+    re_opcode_t op;
+    unsigned char *loc;
+    int arg;
+{
+  *loc = (unsigned char) op;
+  STORE_NUMBER (loc + 1, arg);
+}
+
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2.  */
+
+static void
+store_op2 (op, loc, arg1, arg2)
+    re_opcode_t op;
+    unsigned char *loc;
+    int arg1, arg2;
+{
+  *loc = (unsigned char) op;
+  STORE_NUMBER (loc + 1, arg1);
+  STORE_NUMBER (loc + 3, arg2);
+}
+
+
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+   for OP followed by two-byte integer parameter ARG.  */
+
+static void
+insert_op1 (op, loc, arg, end)
+    re_opcode_t op;
+    unsigned char *loc;
+    int arg;
+    unsigned char *end;    
+{
+  register unsigned char *pfrom = end;
+  register unsigned char *pto = end + 3;
+
+  while (pfrom != loc)
+    *--pto = *--pfrom;
+    
+  store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2.  */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+    re_opcode_t op;
+    unsigned char *loc;
+    int arg1, arg2;
+    unsigned char *end;    
+{
+  register unsigned char *pfrom = end;
+  register unsigned char *pto = end + 5;
+
+  while (pfrom != loc)
+    *--pto = *--pfrom;
+    
+  store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN.  Return true if that ^ comes
+   after an alternative or a begin-subexpression.  We assume there is at
+   least one character before the ^.  */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+    const char *pattern, *p;
+    reg_syntax_t syntax;
+{
+  const char *prev = p - 2;
+  boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+  
+  return
+       /* After a subexpression?  */
+       (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+       /* After an alternative?  */
+    || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p.  This one is for $.  We assume there is
+   at least one character after the $, i.e., `P < PEND'.  */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+    const char *p, *pend;
+    int syntax;
+{
+  const char *next = p;
+  boolean next_backslash = *next == '\\';
+  const char *next_next = p + 1 < pend ? p + 1 : NULL;
+  
+  return
+       /* Before a subexpression?  */
+       (syntax & RE_NO_BK_PARENS ? *next == ')'
+        : next_backslash && next_next && *next_next == ')')
+       /* Before an alternative?  */
+    || (syntax & RE_NO_BK_VBAR ? *next == '|'
+        : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and 
+   false if it's not.  */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+    compile_stack_type compile_stack;
+    regnum_t regnum;
+{
+  int this_element;
+
+  for (this_element = compile_stack.avail - 1;  
+       this_element >= 0; 
+       this_element--)
+    if (compile_stack.stack[this_element].regnum == regnum)
+      return true;
+
+  return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+   uncompiled pattern *P_PTR (which ends at PEND).  We assume the
+   starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)
+   Then we set the translation of all bits between the starting and
+   ending characters (inclusive) in the compiled pattern B.
+   
+   Return an error code.
+   
+   We use these short variable names so we can use the same macros as
+   `regex_compile' itself.  */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+    const char **p_ptr, *pend;
+    char *translate;
+    reg_syntax_t syntax;
+    unsigned char *b;
+{
+  unsigned this_char;
+
+  const char *p = *p_ptr;
+  int range_start, range_end;
+  
+  if (p == pend)
+    return REG_ERANGE;
+
+  /* Even though the pattern is a signed `char *', we need to fetch
+     with unsigned char *'s; if the high bit of the pattern character
+     is set, the range endpoints will be negative if we fetch using a
+     signed char *.
+
+     We also want to fetch the endpoints without translating them; the 
+     appropriate translation is done in the bit-setting loop below.  */
+  range_start = ((unsigned char *) p)[-2];
+  range_end   = ((unsigned char *) p)[0];
+
+  /* Have to increment the pointer into the pattern string, so the
+     caller isn't still at the ending character.  */
+  (*p_ptr)++;
+
+  /* If the start is after the end, the range is empty.  */
+  if (range_start > range_end)
+    return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+  /* Here we see why `this_char' has to be larger than an `unsigned
+     char' -- the range is inclusive, so if `range_end' == 0xff
+     (assuming 8-bit characters), we would otherwise go into an infinite
+     loop, since all characters <= 0xff.  */
+  for (this_char = range_start; this_char <= range_end; this_char++)
+    {
+      SET_LIST_BIT (TRANSLATE (this_char));
+    }
+  
+  return REG_NOERROR;
+}
+\f
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+   BUFP.  A fastmap records which of the (1 << BYTEWIDTH) possible
+   characters can start a string that matches the pattern.  This fastmap
+   is used by re_search to skip quickly over impossible starting points.
+
+   The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+   area as BUFP->fastmap.
+   
+   We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+   the pattern buffer.
+
+   Returns 0 if we succeed, -2 if an internal error.   */
+
+int
+re_compile_fastmap (bufp)
+     struct re_pattern_buffer *bufp;
+{
+  int j, k;
+#ifdef MATCH_MAY_ALLOCATE
+  fail_stack_type fail_stack;
+#endif
+#ifndef REGEX_MALLOC
+  char *destination;
+#endif
+  /* We don't push any register information onto the failure stack.  */
+  unsigned num_regs = 0;
+  
+  register char *fastmap = bufp->fastmap;
+  unsigned char *pattern = bufp->buffer;
+  unsigned long size = bufp->used;
+  unsigned char *p = pattern;
+  register unsigned char *pend = pattern + size;
+
+  /* Assume that each path through the pattern can be null until
+     proven otherwise.  We set this false at the bottom of switch
+     statement, to which we get only if a particular path doesn't
+     match the empty string.  */
+  boolean path_can_be_null = true;
+
+  /* We aren't doing a `succeed_n' to begin with.  */
+  boolean succeed_n_p = false;
+
+  assert (fastmap != NULL && p != NULL);
+  
+  INIT_FAIL_STACK ();
+  bzero (fastmap, 1 << BYTEWIDTH);  /* Assume nothing's valid.  */
+  bufp->fastmap_accurate = 1;      /* It will be when we're done.  */
+  bufp->can_be_null = 0;
+      
+  while (p != pend || !FAIL_STACK_EMPTY ())
+    {
+      if (p == pend)
+        {
+          bufp->can_be_null |= path_can_be_null;
+          
+          /* Reset for next path.  */
+          path_can_be_null = true;
+          
+          p = fail_stack.stack[--fail_stack.avail];
+       }
+
+      /* We should never be about to go beyond the end of the pattern.  */
+      assert (p < pend);
+      
+#ifdef SWITCH_ENUM_BUG
+      switch ((int) ((re_opcode_t) *p++))
+#else
+      switch ((re_opcode_t) *p++)
+#endif
+       {
+
+        /* I guess the idea here is to simply not bother with a fastmap
+           if a backreference is used, since it's too hard to figure out
+           the fastmap for the corresponding group.  Setting
+           `can_be_null' stops `re_search_2' from using the fastmap, so
+           that is all we do.  */
+       case duplicate:
+         bufp->can_be_null = 1;
+          return 0;
+
+
+      /* Following are the cases which match a character.  These end
+         with `break'.  */
+
+       case exactn:
+          fastmap[p[1]] = 1;
+         break;
+
+
+        case charset:
+          for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+           if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+              fastmap[j] = 1;
+         break;
+
+
+       case charset_not:
+         /* Chars beyond end of map must be allowed.  */
+         for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+            fastmap[j] = 1;
+
+         for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+           if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+              fastmap[j] = 1;
+          break;
+
+
+       case wordchar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) == Sword)
+             fastmap[j] = 1;
+         break;
+
+
+       case notwordchar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) != Sword)
+             fastmap[j] = 1;
+         break;
+
+
+        case anychar:
+          /* `.' matches anything ...  */
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+            fastmap[j] = 1;
+
+          /* ... except perhaps newline.  */
+          if (!(bufp->syntax & RE_DOT_NEWLINE))
+            fastmap['\n'] = 0;
+
+          /* Return if we have already set `can_be_null'; if we have,
+             then the fastmap is irrelevant.  Something's wrong here.  */
+         else if (bufp->can_be_null)
+           return 0;
+
+          /* Otherwise, have to check alternative paths.  */
+         break;
+
+
+#ifdef emacs
+        case syntaxspec:
+         k = *p++;
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) == (enum syntaxcode) k)
+             fastmap[j] = 1;
+         break;
+
+
+       case notsyntaxspec:
+         k = *p++;
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) != (enum syntaxcode) k)
+             fastmap[j] = 1;
+         break;
+
+
+      /* All cases after this match the empty string.  These end with
+         `continue'.  */
+
+
+       case before_dot:
+       case at_dot:
+       case after_dot:
+          continue;
+#endif /* not emacs */
+
+
+        case no_op:
+        case begline:
+        case endline:
+       case begbuf:
+       case endbuf:
+       case wordbound:
+       case notwordbound:
+       case wordbeg:
+       case wordend:
+        case push_dummy_failure:
+          continue;
+
+
+       case jump_n:
+        case pop_failure_jump:
+       case maybe_pop_jump:
+       case jump:
+        case jump_past_alt:
+       case dummy_failure_jump:
+          EXTRACT_NUMBER_AND_INCR (j, p);
+         p += j;       
+         if (j > 0)
+           continue;
+            
+          /* Jump backward implies we just went through the body of a
+             loop and matched nothing.  Opcode jumped to should be
+             `on_failure_jump' or `succeed_n'.  Just treat it like an
+             ordinary jump.  For a * loop, it has pushed its failure
+             point already; if so, discard that as redundant.  */
+          if ((re_opcode_t) *p != on_failure_jump
+             && (re_opcode_t) *p != succeed_n)
+           continue;
+
+          p++;
+          EXTRACT_NUMBER_AND_INCR (j, p);
+          p += j;              
+         
+          /* If what's on the stack is where we are now, pop it.  */
+          if (!FAIL_STACK_EMPTY () 
+             && fail_stack.stack[fail_stack.avail - 1] == p)
+            fail_stack.avail--;
+
+          continue;
+
+
+        case on_failure_jump:
+        case on_failure_keep_string_jump:
+       handle_on_failure_jump:
+          EXTRACT_NUMBER_AND_INCR (j, p);
+
+          /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+             end of the pattern.  We don't want to push such a point,
+             since when we restore it above, entering the switch will
+             increment `p' past the end of the pattern.  We don't need
+             to push such a point since we obviously won't find any more
+             fastmap entries beyond `pend'.  Such a pattern can match
+             the null string, though.  */
+          if (p + j < pend)
+            {
+              if (!PUSH_PATTERN_OP (p + j, fail_stack))
+                return -2;
+            }
+          else
+            bufp->can_be_null = 1;
+
+          if (succeed_n_p)
+            {
+              EXTRACT_NUMBER_AND_INCR (k, p);  /* Skip the n.  */
+              succeed_n_p = false;
+           }
+
+          continue;
+
+
+       case succeed_n:
+          /* Get to the number of times to succeed.  */
+          p += 2;              
+
+          /* Increment p past the n for when k != 0.  */
+          EXTRACT_NUMBER_AND_INCR (k, p);
+          if (k == 0)
+           {
+              p -= 4;
+             succeed_n_p = true;  /* Spaghetti code alert.  */
+              goto handle_on_failure_jump;
+            }
+          continue;
+
+
+       case set_number_at:
+          p += 4;
+          continue;
+
+
+       case start_memory:
+        case stop_memory:
+         p += 2;
+         continue;
+
+
+       default:
+          abort (); /* We have listed all the cases.  */
+        } /* switch *p++ */
+
+      /* Getting here means we have found the possible starting
+         characters for one path of the pattern -- and that the empty
+         string does not match.  We need not follow this path further.
+         Instead, look at the next alternative (remembered on the
+         stack), or quit if no more.  The test at the top of the loop
+         does these things.  */
+      path_can_be_null = false;
+      p = pend;
+    } /* while p */
+
+  /* Set `can_be_null' for the last path (also the first path, if the
+     pattern is empty).  */
+  bufp->can_be_null |= path_can_be_null;
+  return 0;
+} /* re_compile_fastmap */
+\f
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
+   this memory for recording register information.  STARTS and ENDS
+   must be allocated using the malloc library routine, and must each
+   be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+    struct re_pattern_buffer *bufp;
+    struct re_registers *regs;
+    unsigned num_regs;
+    regoff_t *starts, *ends;
+{
+  if (num_regs)
+    {
+      bufp->regs_allocated = REGS_REALLOCATE;
+      regs->num_regs = num_regs;
+      regs->start = starts;
+      regs->end = ends;
+    }
+  else
+    {
+      bufp->regs_allocated = REGS_UNALLOCATED;
+      regs->num_regs = 0;
+      regs->start = regs->end = (regoff_t) 0;
+    }
+}
+\f
+/* Searching routines.  */
+
+/* Like re_search_2, below, but only one string is specified, and
+   doesn't let you say where to stop matching. */
+
+int
+re_search (bufp, string, size, startpos, range, regs)
+     struct re_pattern_buffer *bufp;
+     const char *string;
+     int size, startpos, range;
+     struct re_registers *regs;
+{
+  return re_search_2 (bufp, NULL, 0, string, size, startpos, range, 
+                     regs, size);
+}
+
+
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+   virtual concatenation of STRING1 and STRING2, starting first at index
+   STARTPOS, then at STARTPOS + 1, and so on.
+   
+   STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+   
+   RANGE is how far to scan while trying to match.  RANGE = 0 means try
+   only at STARTPOS; in general, the last start tried is STARTPOS +
+   RANGE.
+   
+   In REGS, return the indices of the virtual concatenation of STRING1
+   and STRING2 that matched the entire BUFP->buffer and its contained
+   subexpressions.
+   
+   Do not consider matching one past the index STOP in the virtual
+   concatenation of STRING1 and STRING2.
+
+   We return either the position in the strings at which the match was
+   found, -1 if no match, or -2 if error (such as failure
+   stack overflow).  */
+
+int
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+     struct re_pattern_buffer *bufp;
+     const char *string1, *string2;
+     int size1, size2;
+     int startpos;
+     int range;
+     struct re_registers *regs;
+     int stop;
+{
+  int val;
+  register char *fastmap = bufp->fastmap;
+  register char *translate = bufp->translate;
+  int total_size = size1 + size2;
+  int endpos = startpos + range;
+
+  /* Check for out-of-range STARTPOS.  */
+  if (startpos < 0 || startpos > total_size)
+    return -1;
+    
+  /* Fix up RANGE if it might eventually take us outside
+     the virtual concatenation of STRING1 and STRING2.  */
+  if (endpos < -1)
+    range = -1 - startpos;
+  else if (endpos > total_size)
+    range = total_size - startpos;
+
+  /* If the search isn't to be a backwards one, don't waste time in a
+     search for a pattern that must be anchored.  */
+  if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
+    {
+      if (startpos > 0)
+       return -1;
+      else
+       range = 1;
+    }
+
+  /* Update the fastmap now if not correct already.  */
+  if (fastmap && !bufp->fastmap_accurate)
+    if (re_compile_fastmap (bufp) == -2)
+      return -2;
+  
+  /* Loop through the string, looking for a place to start matching.  */
+  for (;;)
+    { 
+      /* If a fastmap is supplied, skip quickly over characters that
+         cannot be the start of a match.  If the pattern can match the
+         null string, however, we don't need to skip characters; we want
+         the first null string.  */
+      if (fastmap && startpos < total_size && !bufp->can_be_null)
+       {
+         if (range > 0)        /* Searching forwards.  */
+           {
+             register const char *d;
+             register int lim = 0;
+             int irange = range;
+
+              if (startpos < size1 && startpos + range >= size1)
+                lim = range - (size1 - startpos);
+
+             d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+   
+              /* Written out as an if-else to avoid testing `translate'
+                 inside the loop.  */
+             if (translate)
+                while (range > lim
+                       && !fastmap[(unsigned char)
+                                  translate[(unsigned char) *d++]])
+                  range--;
+             else
+                while (range > lim && !fastmap[(unsigned char) *d++])
+                  range--;
+
+             startpos += irange - range;
+           }
+         else                          /* Searching backwards.  */
+           {
+             register char c = (size1 == 0 || startpos >= size1
+                                 ? string2[startpos - size1] 
+                                 : string1[startpos]);
+
+             if (!fastmap[(unsigned char) TRANSLATE (c)])
+               goto advance;
+           }
+       }
+
+      /* If can't match the null string, and that's all we have left, fail.  */
+      if (range >= 0 && startpos == total_size && fastmap
+          && !bufp->can_be_null)
+       return -1;
+
+      val = re_match_2 (bufp, string1, size1, string2, size2,
+                       startpos, regs, stop);
+      if (val >= 0)
+       return startpos;
+        
+      if (val == -2)
+       return -2;
+
+    advance:
+      if (!range) 
+        break;
+      else if (range > 0) 
+        {
+          range--; 
+          startpos++;
+        }
+      else
+        {
+          range++; 
+          startpos--;
+        }
+    }
+  return -1;
+} /* re_search_2 */
+\f
+/* Declarations and macros for re_match_2.  */
+
+static int bcmp_translate ();
+static boolean alt_match_null_string_p (),
+               common_op_match_null_string_p (),
+               group_match_null_string_p ();
+
+/* This converts PTR, a pointer into one of the search strings `string1'
+   and `string2' into an offset from the beginning of that string.  */
+#define POINTER_TO_OFFSET(ptr)                 \
+  (FIRST_STRING_P (ptr)                                \
+   ? ((regoff_t) ((ptr) - string1))            \
+   : ((regoff_t) ((ptr) - string2 + size1)))
+
+/* Macros for dealing with the split strings in re_match_2.  */
+
+#define MATCHING_IN_FIRST_STRING  (dend == end_match_1)
+
+/* Call before fetching a character with *d.  This switches over to
+   string2 if necessary.  */
+#define PREFETCH()                                                     \
+  while (d == dend)                                                    \
+    {                                                                  \
+      /* End of string2 => fail.  */                                   \
+      if (dend == end_match_2)                                                 \
+        goto fail;                                                     \
+      /* End of string1 => advance to string2.  */                     \
+      d = string2;                                                     \
+      dend = end_match_2;                                              \
+    }
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+   of `string1' and `string2'.  If only one string, it's `string2'.  */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)        
+
+
+/* Test if D points to a character which is word-constituent.  We have
+   two special cases to check for: if past the end of string1, look at
+   the first character in string2; and if before the beginning of
+   string2, look at the last character in string1.  */
+#define WORDCHAR_P(d)                                                  \
+  (SYNTAX ((d) == end1 ? *string2                                      \
+           : (d) == string2 - 1 ? *(end1 - 1) : *(d))                  \
+   == Sword)
+
+/* Test if the character before D and the one at D differ with respect
+   to being word-constituent.  */
+#define AT_WORD_BOUNDARY(d)                                            \
+  (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)                            \
+   || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+
+
+/* Free everything we malloc.  */
+#ifdef MATCH_MAY_ALLOCATE
+#ifdef REGEX_MALLOC
+#define FREE_VAR(var) if (var) free (var); var = NULL
+#define FREE_VARIABLES()                                               \
+  do {                                                                 \
+    FREE_VAR (fail_stack.stack);                                       \
+    FREE_VAR (regstart);                                               \
+    FREE_VAR (regend);                                                 \
+    FREE_VAR (old_regstart);                                           \
+    FREE_VAR (old_regend);                                             \
+    FREE_VAR (best_regstart);                                          \
+    FREE_VAR (best_regend);                                            \
+    FREE_VAR (reg_info);                                               \
+    FREE_VAR (reg_dummy);                                              \
+    FREE_VAR (reg_info_dummy);                                         \
+  } while (0)
+#else /* not REGEX_MALLOC */
+/* Some MIPS systems (at least) want this to free alloca'd storage.  */
+#define FREE_VARIABLES() alloca (0)
+#endif /* not REGEX_MALLOC */
+#else
+#define FREE_VARIABLES() /* Do nothing!  */
+#endif /* not MATCH_MAY_ALLOCATE */
+
+/* These values must meet several constraints.  They must not be valid
+   register values; since we have a limit of 255 registers (because
+   we use only one byte in the pattern for the register number), we can
+   use numbers larger than 255.  They must differ by 1, because of
+   NUM_FAILURE_ITEMS above.  And the value for the lowest register must
+   be larger than the value for the highest register, so we do not try
+   to actually save any registers when none are active.  */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+\f
+/* Matching routines.  */
+
+#ifndef emacs   /* Emacs never uses this.  */
+/* re_match is like re_match_2 except it takes only a single string.  */
+
+int
+re_match (bufp, string, size, pos, regs)
+     struct re_pattern_buffer *bufp;
+     const char *string;
+     int size, pos;
+     struct re_registers *regs;
+ {
+  return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size); 
+}
+#endif /* not emacs */
+
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+   the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+   and SIZE2, respectively).  We start matching at POS, and stop
+   matching at STOP.
+   
+   If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+   store offsets for the substring each group matched in REGS.  See the
+   documentation for exactly how many groups we fill.
+
+   We return -1 if no match, -2 if an internal error (such as the
+   failure stack overflowing).  Otherwise, we return the length of the
+   matched substring.  */
+
+int
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+     struct re_pattern_buffer *bufp;
+     const char *string1, *string2;
+     int size1, size2;
+     int pos;
+     struct re_registers *regs;
+     int stop;
+{
+  /* General temporaries.  */
+  int mcnt;
+  unsigned char *p1;
+
+  /* Just past the end of the corresponding string.  */
+  const char *end1, *end2;
+
+  /* Pointers into string1 and string2, just past the last characters in
+     each to consider matching.  */
+  const char *end_match_1, *end_match_2;
+
+  /* Where we are in the data, and the end of the current string.  */
+  const char *d, *dend;
+  
+  /* Where we are in the pattern, and the end of the pattern.  */
+  unsigned char *p = bufp->buffer;
+  register unsigned char *pend = p + bufp->used;
+
+  /* We use this to map every character in the string.  */
+  char *translate = bufp->translate;
+
+  /* Failure point stack.  Each place that can handle a failure further
+     down the line pushes a failure point on this stack.  It consists of
+     restart, regend, and reg_info for all registers corresponding to
+     the subexpressions we're currently inside, plus the number of such
+     registers, and, finally, two char *'s.  The first char * is where
+     to resume scanning the pattern; the second one is where to resume
+     scanning the strings.  If the latter is zero, the failure point is
+     a ``dummy''; if a failure happens and the failure point is a dummy,
+     it gets discarded and the next next one is tried.  */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
+  fail_stack_type fail_stack;
+#endif
+#ifdef DEBUG
+  static unsigned failure_id = 0;
+  unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+  /* We fill all the registers internally, independent of what we
+     return, for use in backreferences.  The number here includes
+     an element for register zero.  */
+  unsigned num_regs = bufp->re_nsub + 1;
+  
+  /* The currently active registers.  */
+  unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+  unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+  /* Information on the contents of registers. These are pointers into
+     the input strings; they record just what was matched (on this
+     attempt) by a subexpression part of the pattern, that is, the
+     regnum-th regstart pointer points to where in the pattern we began
+     matching and the regnum-th regend points to right after where we
+     stopped matching the regnum-th subexpression.  (The zeroth register
+     keeps track of what the whole pattern matches.)  */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
+  const char **regstart, **regend;
+#endif
+
+  /* If a group that's operated upon by a repetition operator fails to
+     match anything, then the register for its start will need to be
+     restored because it will have been set to wherever in the string we
+     are when we last see its open-group operator.  Similarly for a
+     register's end.  */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
+  const char **old_regstart, **old_regend;
+#endif
+
+  /* The is_active field of reg_info helps us keep track of which (possibly
+     nested) subexpressions we are currently in. The matched_something
+     field of reg_info[reg_num] helps us tell whether or not we have
+     matched any of the pattern so far this time through the reg_num-th
+     subexpression.  These two fields get reset each time through any
+     loop their register is in.  */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
+  register_info_type *reg_info; 
+#endif
+
+  /* The following record the register info as found in the above
+     variables when we find a match better than any we've seen before. 
+     This happens as we backtrack through the failure points, which in
+     turn happens only if we have not yet matched the entire string. */
+  unsigned best_regs_set = false;
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
+  const char **best_regstart, **best_regend;
+#endif
+  
+  /* Logically, this is `best_regend[0]'.  But we don't want to have to
+     allocate space for that if we're not allocating space for anything
+     else (see below).  Also, we never need info about register 0 for
+     any of the other register vectors, and it seems rather a kludge to
+     treat `best_regend' differently than the rest.  So we keep track of
+     the end of the best match so far in a separate variable.  We
+     initialize this to NULL so that when we backtrack the first time
+     and need to test it, it's not garbage.  */
+  const char *match_end = NULL;
+
+  /* Used when we pop values we don't care about.  */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
+  const char **reg_dummy;
+  register_info_type *reg_info_dummy;
+#endif
+
+#ifdef DEBUG
+  /* Counts the total number of registers pushed.  */
+  unsigned num_regs_pushed = 0;        
+#endif
+
+  DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+  
+  INIT_FAIL_STACK ();
+  
+#ifdef MATCH_MAY_ALLOCATE
+  /* Do not bother to initialize all the register variables if there are
+     no groups in the pattern, as it takes a fair amount of time.  If
+     there are groups, we include space for register 0 (the whole
+     pattern), even though we never use it, since it simplifies the
+     array indexing.  We should fix this.  */
+  if (bufp->re_nsub)
+    {
+      regstart = REGEX_TALLOC (num_regs, const char *);
+      regend = REGEX_TALLOC (num_regs, const char *);
+      old_regstart = REGEX_TALLOC (num_regs, const char *);
+      old_regend = REGEX_TALLOC (num_regs, const char *);
+      best_regstart = REGEX_TALLOC (num_regs, const char *);
+      best_regend = REGEX_TALLOC (num_regs, const char *);
+      reg_info = REGEX_TALLOC (num_regs, register_info_type);
+      reg_dummy = REGEX_TALLOC (num_regs, const char *);
+      reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+      if (!(regstart && regend && old_regstart && old_regend && reg_info 
+            && best_regstart && best_regend && reg_dummy && reg_info_dummy)) 
+        {
+          FREE_VARIABLES ();
+          return -2;
+        }
+    }
+#if defined (REGEX_MALLOC)
+  else
+    {
+      /* We must initialize all our variables to NULL, so that
+         `FREE_VARIABLES' doesn't try to free them.  */
+      regstart = regend = old_regstart = old_regend = best_regstart
+        = best_regend = reg_dummy = NULL;
+      reg_info = reg_info_dummy = (register_info_type *) NULL;
+    }
+#endif /* REGEX_MALLOC */
+#endif /* MATCH_MAY_ALLOCATE */
+
+  /* The starting position is bogus.  */
+  if (pos < 0 || pos > size1 + size2)
+    {
+      FREE_VARIABLES ();
+      return -1;
+    }
+    
+  /* Initialize subexpression text positions to -1 to mark ones that no
+     start_memory/stop_memory has been seen for. Also initialize the
+     register information struct.  */
+  for (mcnt = 1; mcnt < num_regs; mcnt++)
+    {
+      regstart[mcnt] = regend[mcnt] 
+        = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+        
+      REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+      IS_ACTIVE (reg_info[mcnt]) = 0;
+      MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+      EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+    }
+  
+  /* We move `string1' into `string2' if the latter's empty -- but not if
+     `string1' is null.  */
+  if (size2 == 0 && string1 != NULL)
+    {
+      string2 = string1;
+      size2 = size1;
+      string1 = 0;
+      size1 = 0;
+    }
+  end1 = string1 + size1;
+  end2 = string2 + size2;
+
+  /* Compute where to stop matching, within the two strings.  */
+  if (stop <= size1)
+    {
+      end_match_1 = string1 + stop;
+      end_match_2 = string2;
+    }
+  else
+    {
+      end_match_1 = end1;
+      end_match_2 = string2 + stop - size1;
+    }
+
+  /* `p' scans through the pattern as `d' scans through the data. 
+     `dend' is the end of the input string that `d' points within.  `d'
+     is advanced into the following input string whenever necessary, but
+     this happens before fetching; therefore, at the beginning of the
+     loop, `d' can be pointing at the end of a string, but it cannot
+     equal `string2'.  */
+  if (size1 > 0 && pos <= size1)
+    {
+      d = string1 + pos;
+      dend = end_match_1;
+    }
+  else
+    {
+      d = string2 + pos - size1;
+      dend = end_match_2;
+    }
+
+  DEBUG_PRINT1 ("The compiled pattern is: ");
+  DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+  DEBUG_PRINT1 ("The string to match is: `");
+  DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+  DEBUG_PRINT1 ("'\n");
+  
+  /* This loops over pattern commands.  It exits by returning from the
+     function if the match is complete, or it drops through if the match
+     fails at this starting point in the input data.  */
+  for (;;)
+    {
+      DEBUG_PRINT2 ("\n0x%x: ", p);
+
+      if (p == pend)
+       { /* End of pattern means we might have succeeded.  */
+          DEBUG_PRINT1 ("end of pattern ... ");
+          
+         /* If we haven't matched the entire string, and we want the
+             longest match, try backtracking.  */
+          if (d != end_match_2)
+           {
+              DEBUG_PRINT1 ("backtracking.\n");
+              
+              if (!FAIL_STACK_EMPTY ())
+                { /* More failure points to try.  */
+                  boolean same_str_p = (FIRST_STRING_P (match_end) 
+                                       == MATCHING_IN_FIRST_STRING);
+
+                  /* If exceeds best match so far, save it.  */
+                  if (!best_regs_set
+                      || (same_str_p && d > match_end)
+                      || (!same_str_p && !MATCHING_IN_FIRST_STRING))
+                    {
+                      best_regs_set = true;
+                      match_end = d;
+                      
+                      DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+                      
+                      for (mcnt = 1; mcnt < num_regs; mcnt++)
+                        {
+                          best_regstart[mcnt] = regstart[mcnt];
+                          best_regend[mcnt] = regend[mcnt];
+                        }
+                    }
+                  goto fail;          
+                }
+
+              /* If no failure points, don't restore garbage.  */
+              else if (best_regs_set)   
+                {
+               restore_best_regs:
+                  /* Restore best match.  It may happen that `dend ==
+                     end_match_1' while the restored d is in string2.
+                     For example, the pattern `x.*y.*z' against the
+                     strings `x-' and `y-z-', if the two strings are
+                     not consecutive in memory.  */
+                  DEBUG_PRINT1 ("Restoring best registers.\n");
+                  
+                  d = match_end;
+                  dend = ((d >= string1 && d <= end1)
+                          ? end_match_1 : end_match_2);
+
+                 for (mcnt = 1; mcnt < num_regs; mcnt++)
+                   {
+                     regstart[mcnt] = best_regstart[mcnt];
+                     regend[mcnt] = best_regend[mcnt];
+                   }
+                }
+            } /* d != end_match_2 */
+
+          DEBUG_PRINT1 ("Accepting match.\n");
+
+          /* If caller wants register contents data back, do it.  */
+          if (regs && !bufp->no_sub)
+           {
+              /* Have the register data arrays been allocated?  */
+              if (bufp->regs_allocated == REGS_UNALLOCATED)
+                { /* No.  So allocate them with malloc.  We need one
+                     extra element beyond `num_regs' for the `-1' marker
+                     GNU code uses.  */
+                  regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+                  regs->start = TALLOC (regs->num_regs, regoff_t);
+                  regs->end = TALLOC (regs->num_regs, regoff_t);
+                  if (regs->start == NULL || regs->end == NULL)
+                    return -2;
+                  bufp->regs_allocated = REGS_REALLOCATE;
+                }
+              else if (bufp->regs_allocated == REGS_REALLOCATE)
+                { /* Yes.  If we need more elements than were already
+                     allocated, reallocate them.  If we need fewer, just
+                     leave it alone.  */
+                  if (regs->num_regs < num_regs + 1)
+                    {
+                      regs->num_regs = num_regs + 1;
+                      RETALLOC (regs->start, regs->num_regs, regoff_t);
+                      RETALLOC (regs->end, regs->num_regs, regoff_t);
+                      if (regs->start == NULL || regs->end == NULL)
+                        return -2;
+                    }
+                }
+              else
+               {
+                 /* These braces fend off a "empty body in an else-statement"
+                    warning under GCC when assert expands to nothing.  */
+                 assert (bufp->regs_allocated == REGS_FIXED);
+               }
+
+              /* Convert the pointer data in `regstart' and `regend' to
+                 indices.  Register zero has to be set differently,
+                 since we haven't kept track of any info for it.  */
+              if (regs->num_regs > 0)
+                {
+                  regs->start[0] = pos;
+                  regs->end[0] = (MATCHING_IN_FIRST_STRING
+                                 ? ((regoff_t) (d - string1))
+                                 : ((regoff_t) (d - string2 + size1)));
+                }
+              
+              /* Go through the first `min (num_regs, regs->num_regs)'
+                 registers, since that is all we initialized.  */
+             for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
+               {
+                  if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+                    regs->start[mcnt] = regs->end[mcnt] = -1;
+                  else
+                    {
+                     regs->start[mcnt]
+                       = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
+                      regs->end[mcnt]
+                       = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
+                    }
+               }
+              
+              /* If the regs structure we return has more elements than
+                 were in the pattern, set the extra elements to -1.  If
+                 we (re)allocated the registers, this is the case,
+                 because we always allocate enough to have at least one
+                 -1 at the end.  */
+              for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
+                regs->start[mcnt] = regs->end[mcnt] = -1;
+           } /* regs && !bufp->no_sub */
+
+          FREE_VARIABLES ();
+          DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+                        nfailure_points_pushed, nfailure_points_popped,
+                        nfailure_points_pushed - nfailure_points_popped);
+          DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+          mcnt = d - pos - (MATCHING_IN_FIRST_STRING 
+                           ? string1 
+                           : string2 - size1);
+
+          DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+          return mcnt;
+        }
+
+      /* Otherwise match next pattern command.  */
+#ifdef SWITCH_ENUM_BUG
+      switch ((int) ((re_opcode_t) *p++))
+#else
+      switch ((re_opcode_t) *p++)
+#endif
+       {
+        /* Ignore these.  Used to ignore the n of succeed_n's which
+           currently have n == 0.  */
+        case no_op:
+          DEBUG_PRINT1 ("EXECUTING no_op.\n");
+          break;
+
+
+        /* Match the next n pattern characters exactly.  The following
+           byte in the pattern defines n, and the n bytes after that
+           are the characters to match.  */
+       case exactn:
+         mcnt = *p++;
+          DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+          /* This is written out as an if-else so we don't waste time
+             testing `translate' inside the loop.  */
+          if (translate)
+           {
+             do
+               {
+                 PREFETCH ();
+                 if (translate[(unsigned char) *d++] != (char) *p++)
+                    goto fail;
+               }
+             while (--mcnt);
+           }
+         else
+           {
+             do
+               {
+                 PREFETCH ();
+                 if (*d++ != (char) *p++) goto fail;
+               }
+             while (--mcnt);
+           }
+         SET_REGS_MATCHED ();
+          break;
+
+
+        /* Match any character except possibly a newline or a null.  */
+       case anychar:
+          DEBUG_PRINT1 ("EXECUTING anychar.\n");
+
+          PREFETCH ();
+
+          if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+              || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+           goto fail;
+
+          SET_REGS_MATCHED ();
+          DEBUG_PRINT2 ("  Matched `%d'.\n", *d);
+          d++;
+         break;
+
+
+       case charset:
+       case charset_not:
+         {
+           register unsigned char c;
+           boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+            DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+           PREFETCH ();
+           c = TRANSLATE (*d); /* The character to match.  */
+
+            /* Cast to `unsigned' instead of `unsigned char' in case the
+               bit list is a full 32 bytes long.  */
+           if (c < (unsigned) (*p * BYTEWIDTH)
+               && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+             not = !not;
+
+           p += 1 + *p;
+
+           if (!not) goto fail;
+            
+           SET_REGS_MATCHED ();
+            d++;
+           break;
+         }
+
+
+        /* The beginning of a group is represented by start_memory.
+           The arguments are the register number in the next byte, and the
+           number of groups inner to this one in the next.  The text
+           matched within the group is recorded (in the internal
+           registers data structure) under the register number.  */
+        case start_memory:
+         DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+          /* Find out if this group can match the empty string.  */
+         p1 = p;               /* To send to group_match_null_string_p.  */
+          
+          if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+            REG_MATCH_NULL_STRING_P (reg_info[*p]) 
+              = group_match_null_string_p (&p1, pend, reg_info);
+
+          /* Save the position in the string where we were the last time
+             we were at this open-group operator in case the group is
+             operated upon by a repetition operator, e.g., with `(a*)*b'
+             against `ab'; then we want to ignore where we are now in
+             the string in case this attempt to match fails.  */
+          old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+                             ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+                             : regstart[*p];
+         DEBUG_PRINT2 ("  old_regstart: %d\n", 
+                        POINTER_TO_OFFSET (old_regstart[*p]));
+
+          regstart[*p] = d;
+         DEBUG_PRINT2 ("  regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+          IS_ACTIVE (reg_info[*p]) = 1;
+          MATCHED_SOMETHING (reg_info[*p]) = 0;
+          
+          /* This is the new highest active register.  */
+          highest_active_reg = *p;
+          
+          /* If nothing was active before, this is the new lowest active
+             register.  */
+          if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+            lowest_active_reg = *p;
+
+          /* Move past the register number and inner group count.  */
+          p += 2;
+          break;
+
+
+        /* The stop_memory opcode represents the end of a group.  Its
+           arguments are the same as start_memory's: the register
+           number, and the number of inner groups.  */
+       case stop_memory:
+         DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+             
+          /* We need to save the string position the last time we were at
+             this close-group operator in case the group is operated
+             upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+             against `aba'; then we want to ignore where we are now in
+             the string in case this attempt to match fails.  */
+          old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+                           ? REG_UNSET (regend[*p]) ? d : regend[*p]
+                          : regend[*p];
+         DEBUG_PRINT2 ("      old_regend: %d\n", 
+                        POINTER_TO_OFFSET (old_regend[*p]));
+
+          regend[*p] = d;
+         DEBUG_PRINT2 ("      regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+          /* This register isn't active anymore.  */
+          IS_ACTIVE (reg_info[*p]) = 0;
+          
+          /* If this was the only register active, nothing is active
+             anymore.  */
+          if (lowest_active_reg == highest_active_reg)
+            {
+              lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+              highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+            }
+          else
+            { /* We must scan for the new highest active register, since
+                 it isn't necessarily one less than now: consider
+                 (a(b)c(d(e)f)g).  When group 3 ends, after the f), the
+                 new highest active register is 1.  */
+              unsigned char r = *p - 1;
+              while (r > 0 && !IS_ACTIVE (reg_info[r]))
+                r--;
+              
+              /* If we end up at register zero, that means that we saved
+                 the registers as the result of an `on_failure_jump', not
+                 a `start_memory', and we jumped to past the innermost
+                 `stop_memory'.  For example, in ((.)*) we save
+                 registers 1 and 2 as a result of the *, but when we pop
+                 back to the second ), we are at the stop_memory 1.
+                 Thus, nothing is active.  */
+             if (r == 0)
+                {
+                  lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+                  highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+                }
+              else
+                highest_active_reg = r;
+            }
+          
+          /* If just failed to match something this time around with a
+             group that's operated on by a repetition operator, try to
+             force exit from the ``loop'', and restore the register
+             information for this group that we had before trying this
+             last match.  */
+          if ((!MATCHED_SOMETHING (reg_info[*p])
+               || (re_opcode_t) p[-3] == start_memory)
+             && (p + 2) < pend)              
+            {
+              boolean is_a_jump_n = false;
+              
+              p1 = p + 2;
+              mcnt = 0;
+              switch ((re_opcode_t) *p1++)
+                {
+                  case jump_n:
+                   is_a_jump_n = true;
+                  case pop_failure_jump:
+                 case maybe_pop_jump:
+                 case jump:
+                 case dummy_failure_jump:
+                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+                   if (is_a_jump_n)
+                     p1 += 2;
+                    break;
+                  
+                  default:
+                    /* do nothing */ ;
+                }
+             p1 += mcnt;
+        
+              /* If the next operation is a jump backwards in the pattern
+                to an on_failure_jump right before the start_memory
+                 corresponding to this stop_memory, exit from the loop
+                 by forcing a failure after pushing on the stack the
+                 on_failure_jump's jump in the pattern, and d.  */
+              if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+                  && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+               {
+                  /* If this group ever matched anything, then restore
+                     what its registers were before trying this last
+                     failed match, e.g., with `(a*)*b' against `ab' for
+                     regstart[1], and, e.g., with `((a*)*(b*)*)*'
+                     against `aba' for regend[3].
+                     
+                     Also restore the registers for inner groups for,
+                     e.g., `((a*)(b*))*' against `aba' (register 3 would
+                     otherwise get trashed).  */
+                     
+                  if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+                   {
+                     unsigned r; 
+        
+                      EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+                      
+                     /* Restore this and inner groups' (if any) registers.  */
+                      for (r = *p; r < *p + *(p + 1); r++)
+                        {
+                          regstart[r] = old_regstart[r];
+
+                          /* xx why this test?  */
+                          if ((int) old_regend[r] >= (int) regstart[r])
+                            regend[r] = old_regend[r];
+                        }     
+                    }
+                 p1++;
+                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+                  PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+
+                  goto fail;
+                }
+            }
+          
+          /* Move past the register number and the inner group count.  */
+          p += 2;
+          break;
+
+
+       /* \<digit> has been turned into a `duplicate' command which is
+           followed by the numeric value of <digit> as the register number.  */
+        case duplicate:
+         {
+           register const char *d2, *dend2;
+           int regno = *p++;   /* Get which register to match against.  */
+           DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+
+           /* Can't back reference a group which we've never matched.  */
+            if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+              goto fail;
+              
+            /* Where in input to try to start matching.  */
+            d2 = regstart[regno];
+            
+            /* Where to stop matching; if both the place to start and
+               the place to stop matching are in the same string, then
+               set to the place to stop, otherwise, for now have to use
+               the end of the first string.  */
+
+            dend2 = ((FIRST_STRING_P (regstart[regno]) 
+                     == FIRST_STRING_P (regend[regno]))
+                    ? regend[regno] : end_match_1);
+           for (;;)
+             {
+               /* If necessary, advance to next segment in register
+                   contents.  */
+               while (d2 == dend2)
+                 {
+                   if (dend2 == end_match_2) break;
+                   if (dend2 == regend[regno]) break;
+
+                    /* End of string1 => advance to string2. */
+                    d2 = string2;
+                    dend2 = regend[regno];
+                 }
+               /* At end of register contents => success */
+               if (d2 == dend2) break;
+
+               /* If necessary, advance to next segment in data.  */
+               PREFETCH ();
+
+               /* How many characters left in this segment to match.  */
+               mcnt = dend - d;
+                
+               /* Want how many consecutive characters we can match in
+                   one shot, so, if necessary, adjust the count.  */
+                if (mcnt > dend2 - d2)
+                 mcnt = dend2 - d2;
+                  
+               /* Compare that many; failure if mismatch, else move
+                   past them.  */
+               if (translate 
+                    ? bcmp_translate (d, d2, mcnt, translate) 
+                    : bcmp (d, d2, mcnt))
+                 goto fail;
+               d += mcnt, d2 += mcnt;
+             }
+         }
+         break;
+
+
+        /* begline matches the empty string at the beginning of the string
+           (unless `not_bol' is set in `bufp'), and, if
+           `newline_anchor' is set, after newlines.  */
+       case begline:
+          DEBUG_PRINT1 ("EXECUTING begline.\n");
+          
+          if (AT_STRINGS_BEG (d))
+            {
+              if (!bufp->not_bol) break;
+            }
+          else if (d[-1] == '\n' && bufp->newline_anchor)
+            {
+              break;
+            }
+          /* In all other cases, we fail.  */
+          goto fail;
+
+
+        /* endline is the dual of begline.  */
+       case endline:
+          DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+          if (AT_STRINGS_END (d))
+            {
+              if (!bufp->not_eol) break;
+            }
+          
+          /* We have to ``prefetch'' the next character.  */
+          else if ((d == end1 ? *string2 : *d) == '\n'
+                   && bufp->newline_anchor)
+            {
+              break;
+            }
+          goto fail;
+
+
+       /* Match at the very beginning of the data.  */
+        case begbuf:
+          DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+          if (AT_STRINGS_BEG (d))
+            break;
+          goto fail;
+
+
+       /* Match at the very end of the data.  */
+        case endbuf:
+          DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+         if (AT_STRINGS_END (d))
+           break;
+          goto fail;
+
+
+        /* on_failure_keep_string_jump is used to optimize `.*\n'.  It
+           pushes NULL as the value for the string on the stack.  Then
+           `pop_failure_point' will keep the current value for the
+           string, instead of restoring it.  To see why, consider
+           matching `foo\nbar' against `.*\n'.  The .* matches the foo;
+           then the . fails against the \n.  But the next thing we want
+           to do is match the \n against the \n; if we restored the
+           string value, we would be back at the foo.
+           
+           Because this is used only in specific cases, we don't need to
+           check all the things that `on_failure_jump' does, to make
+           sure the right things get saved on the stack.  Hence we don't
+           share its code.  The only reason to push anything on the
+           stack at all is that otherwise we would have to change
+           `anychar's code to do something besides goto fail in this
+           case; that seems worse than this.  */
+        case on_failure_keep_string_jump:
+          DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+          
+          EXTRACT_NUMBER_AND_INCR (mcnt, p);
+          DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+
+          PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+          break;
+
+
+       /* Uses of on_failure_jump:
+        
+           Each alternative starts with an on_failure_jump that points
+           to the beginning of the next alternative.  Each alternative
+           except the last ends with a jump that in effect jumps past
+           the rest of the alternatives.  (They really jump to the
+           ending jump of the following alternative, because tensioning
+           these jumps is a hassle.)
+
+           Repeats start with an on_failure_jump that points past both
+           the repetition text and either the following jump or
+           pop_failure_jump back to this on_failure_jump.  */
+       case on_failure_jump:
+        on_failure:
+          DEBUG_PRINT1 ("EXECUTING on_failure_jump");
+
+          EXTRACT_NUMBER_AND_INCR (mcnt, p);
+          DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+
+          /* If this on_failure_jump comes right before a group (i.e.,
+             the original * applied to a group), save the information
+             for that group and all inner ones, so that if we fail back
+             to this point, the group's information will be correct.
+             For example, in \(a*\)*\1, we need the preceding group,
+             and in \(\(a*\)b*\)\2, we need the inner group.  */
+
+          /* We can't use `p' to check ahead because we push
+             a failure point to `p + mcnt' after we do this.  */
+          p1 = p;
+
+          /* We need to skip no_op's before we look for the
+             start_memory in case this on_failure_jump is happening as
+             the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+             against aba.  */
+          while (p1 < pend && (re_opcode_t) *p1 == no_op)
+            p1++;
+
+          if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+            {
+              /* We have a new highest active register now.  This will
+                 get reset at the start_memory we are about to get to,
+                 but we will have saved all the registers relevant to
+                 this repetition op, as described above.  */
+              highest_active_reg = *(p1 + 1) + *(p1 + 2);
+              if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+                lowest_active_reg = *(p1 + 1);
+            }
+
+          DEBUG_PRINT1 (":\n");
+          PUSH_FAILURE_POINT (p + mcnt, d, -2);
+          break;
+
+
+        /* A smart repeat ends with `maybe_pop_jump'.
+          We change it to either `pop_failure_jump' or `jump'.  */
+        case maybe_pop_jump:
+          EXTRACT_NUMBER_AND_INCR (mcnt, p);
+          DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+          {
+           register unsigned char *p2 = p;
+
+            /* Compare the beginning of the repeat with what in the
+               pattern follows its end. If we can establish that there
+               is nothing that they would both match, i.e., that we
+               would have to backtrack because of (as in, e.g., `a*a')
+               then we can change to pop_failure_jump, because we'll
+               never have to backtrack.
+               
+               This is not true in the case of alternatives: in
+               `(a|ab)*' we do need to backtrack to the `ab' alternative
+               (e.g., if the string was `ab').  But instead of trying to
+               detect that here, the alternative has put on a dummy
+               failure point which is what we will end up popping.  */
+
+           /* Skip over open/close-group commands.
+              If what follows this loop is a ...+ construct,
+              look at what begins its body, since we will have to
+              match at least one of that.  */
+           while (1)
+             {
+               if (p2 + 2 < pend
+                   && ((re_opcode_t) *p2 == stop_memory
+                       || (re_opcode_t) *p2 == start_memory))
+                 p2 += 3;
+               else if (p2 + 6 < pend
+                        && (re_opcode_t) *p2 == dummy_failure_jump)
+                 p2 += 6;
+               else
+                 break;
+             }
+
+           p1 = p + mcnt;
+           /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+              to the `maybe_finalize_jump' of this case.  Examine what 
+              follows.  */
+
+            /* If we're at the end of the pattern, we can change.  */
+            if (p2 == pend)
+             {
+               /* Consider what happens when matching ":\(.*\)"
+                  against ":/".  I don't really understand this code
+                  yet.  */
+               p[-3] = (unsigned char) pop_failure_jump;
+                DEBUG_PRINT1
+                  ("  End of pattern: change to `pop_failure_jump'.\n");
+              }
+
+            else if ((re_opcode_t) *p2 == exactn
+                    || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+             {
+               register unsigned char c
+                  = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+                if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+                  {
+                   p[-3] = (unsigned char) pop_failure_jump;
+                    DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
+                                  c, p1[5]);
+                  }
+                  
+               else if ((re_opcode_t) p1[3] == charset
+                        || (re_opcode_t) p1[3] == charset_not)
+                 {
+                   int not = (re_opcode_t) p1[3] == charset_not;
+                    
+                   if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+                       && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+                     not = !not;
+
+                    /* `not' is equal to 1 if c would match, which means
+                        that we can't change to pop_failure_jump.  */
+                   if (!not)
+                      {
+                       p[-3] = (unsigned char) pop_failure_jump;
+                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
+                      }
+                 }
+             }
+            else if ((re_opcode_t) *p2 == charset)
+             {
+               register unsigned char c
+                  = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+                if ((re_opcode_t) p1[3] == exactn
+                   && ! (p2[1] * BYTEWIDTH > p1[4]
+                         && (p2[1 + p1[4] / BYTEWIDTH]
+                             & (1 << (p1[4] % BYTEWIDTH)))))
+                  {
+                   p[-3] = (unsigned char) pop_failure_jump;
+                    DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
+                                  c, p1[5]);
+                  }
+                  
+               else if ((re_opcode_t) p1[3] == charset_not)
+                 {
+                   int idx;
+                   /* We win if the charset_not inside the loop
+                      lists every character listed in the charset after.  */
+                   for (idx = 0; idx < p2[1]; idx++)
+                     if (! (p2[2 + idx] == 0
+                            || (idx < p1[4]
+                                && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
+                       break;
+
+                   if (idx == p2[1])
+                      {
+                       p[-3] = (unsigned char) pop_failure_jump;
+                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
+                      }
+                 }
+               else if ((re_opcode_t) p1[3] == charset)
+                 {
+                   int idx;
+                   /* We win if the charset inside the loop
+                      has no overlap with the one after the loop.  */
+                   for (idx = 0; idx < p2[1] && idx < p1[4]; idx++)
+                     if ((p2[2 + idx] & p1[5 + idx]) != 0)
+                       break;
+
+                   if (idx == p2[1] || idx == p1[4])
+                      {
+                       p[-3] = (unsigned char) pop_failure_jump;
+                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
+                      }
+                 }
+             }
+         }
+         p -= 2;               /* Point at relative address again.  */
+         if ((re_opcode_t) p[-1] != pop_failure_jump)
+           {
+             p[-1] = (unsigned char) jump;
+              DEBUG_PRINT1 ("  Match => jump.\n");
+             goto unconditional_jump;
+           }
+        /* Note fall through.  */
+
+
+       /* The end of a simple repeat has a pop_failure_jump back to
+           its matching on_failure_jump, where the latter will push a
+           failure point.  The pop_failure_jump takes off failure
+           points put on by this pop_failure_jump's matching
+           on_failure_jump; we got through the pattern to here from the
+           matching on_failure_jump, so didn't fail.  */
+        case pop_failure_jump:
+          {
+            /* We need to pass separate storage for the lowest and
+               highest registers, even though we don't care about the
+               actual values.  Otherwise, we will restore only one
+               register from the stack, since lowest will == highest in
+               `pop_failure_point'.  */
+            unsigned dummy_low_reg, dummy_high_reg;
+            unsigned char *pdummy;
+            const char *sdummy;
+
+            DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+            POP_FAILURE_POINT (sdummy, pdummy,
+                               dummy_low_reg, dummy_high_reg,
+                               reg_dummy, reg_dummy, reg_info_dummy);
+          }
+          /* Note fall through.  */
+
+          
+        /* Unconditionally jump (without popping any failure points).  */
+        case jump:
+       unconditional_jump:
+         EXTRACT_NUMBER_AND_INCR (mcnt, p);    /* Get the amount to jump.  */
+          DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+         p += mcnt;                            /* Do the jump.  */
+          DEBUG_PRINT2 ("(to 0x%x).\n", p);
+         break;
+
+       
+        /* We need this opcode so we can detect where alternatives end
+           in `group_match_null_string_p' et al.  */
+        case jump_past_alt:
+          DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+          goto unconditional_jump;
+
+
+        /* Normally, the on_failure_jump pushes a failure point, which
+           then gets popped at pop_failure_jump.  We will end up at
+           pop_failure_jump, also, and with a pattern of, say, `a+', we
+           are skipping over the on_failure_jump, so we have to push
+           something meaningless for pop_failure_jump to pop.  */
+        case dummy_failure_jump:
+          DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+          /* It doesn't matter what we push for the string here.  What
+             the code at `fail' tests is the value for the pattern.  */
+          PUSH_FAILURE_POINT (0, 0, -2);
+          goto unconditional_jump;
+
+
+        /* At the end of an alternative, we need to push a dummy failure
+           point in case we are followed by a `pop_failure_jump', because
+           we don't want the failure point for the alternative to be
+           popped.  For example, matching `(a|ab)*' against `aab'
+           requires that we match the `ab' alternative.  */
+        case push_dummy_failure:
+          DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+          /* See comments just above at `dummy_failure_jump' about the
+             two zeroes.  */
+          PUSH_FAILURE_POINT (0, 0, -2);
+          break;
+
+        /* Have to succeed matching what follows at least n times.
+           After that, handle like `on_failure_jump'.  */
+        case succeed_n: 
+          EXTRACT_NUMBER (mcnt, p + 2);
+          DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+          assert (mcnt >= 0);
+          /* Originally, this is how many times we HAVE to succeed.  */
+          if (mcnt > 0)
+            {
+               mcnt--;
+              p += 2;
+               STORE_NUMBER_AND_INCR (p, mcnt);
+               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p, mcnt);
+            }
+         else if (mcnt == 0)
+            {
+              DEBUG_PRINT2 ("  Setting two bytes from 0x%x to no_op.\n", p+2);
+             p[2] = (unsigned char) no_op;
+              p[3] = (unsigned char) no_op;
+              goto on_failure;
+            }
+          break;
+        
+        case jump_n: 
+          EXTRACT_NUMBER (mcnt, p + 2);
+          DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+          /* Originally, this is how many times we CAN jump.  */
+          if (mcnt)
+            {
+               mcnt--;
+               STORE_NUMBER (p + 2, mcnt);
+              goto unconditional_jump;      
+            }
+          /* If don't have to jump any more, skip over the rest of command.  */
+         else      
+           p += 4;                  
+          break;
+        
+       case set_number_at:
+         {
+            DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+
+            EXTRACT_NUMBER_AND_INCR (mcnt, p);
+            p1 = p + mcnt;
+            EXTRACT_NUMBER_AND_INCR (mcnt, p);
+            DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p1, mcnt);
+           STORE_NUMBER (p1, mcnt);
+            break;
+          }
+
+        case wordbound:
+          DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+          if (AT_WORD_BOUNDARY (d))
+           break;
+          goto fail;
+
+       case notwordbound:
+          DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+         if (AT_WORD_BOUNDARY (d))
+           goto fail;
+          break;
+
+       case wordbeg:
+          DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+         if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+           break;
+          goto fail;
+
+       case wordend:
+          DEBUG_PRINT1 ("EXECUTING wordend.\n");
+         if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+              && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+           break;
+          goto fail;
+
+#ifdef emacs
+#ifdef emacs19
+       case before_dot:
+          DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+         if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+           goto fail;
+         break;
+  
+       case at_dot:
+          DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+         if (PTR_CHAR_POS ((unsigned char *) d) != point)
+           goto fail;
+         break;
+  
+       case after_dot:
+          DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+          if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+           goto fail;
+         break;
+#else /* not emacs19 */
+       case at_dot:
+          DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+         if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
+           goto fail;
+         break;
+#endif /* not emacs19 */
+
+       case syntaxspec:
+          DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+         mcnt = *p++;
+         goto matchsyntax;
+
+        case wordchar:
+          DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+         mcnt = (int) Sword;
+        matchsyntax:
+         PREFETCH ();
+         if (SYNTAX (*d++) != (enum syntaxcode) mcnt)
+            goto fail;
+          SET_REGS_MATCHED ();
+         break;
+
+       case notsyntaxspec:
+          DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+         mcnt = *p++;
+         goto matchnotsyntax;
+
+        case notwordchar:
+          DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+         mcnt = (int) Sword;
+        matchnotsyntax:
+         PREFETCH ();
+         if (SYNTAX (*d++) == (enum syntaxcode) mcnt)
+            goto fail;
+         SET_REGS_MATCHED ();
+          break;
+
+#else /* not emacs */
+       case wordchar:
+          DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+         PREFETCH ();
+          if (!WORDCHAR_P (d))
+            goto fail;
+         SET_REGS_MATCHED ();
+          d++;
+         break;
+         
+       case notwordchar:
+          DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+         PREFETCH ();
+         if (WORDCHAR_P (d))
+            goto fail;
+          SET_REGS_MATCHED ();
+          d++;
+         break;
+#endif /* not emacs */
+          
+        default:
+          abort ();
+       }
+      continue;  /* Successfully executed one pattern command; keep going.  */
+
+
+    /* We goto here if a matching operation fails. */
+    fail:
+      if (!FAIL_STACK_EMPTY ())
+       { /* A restart point is known.  Restore to that state.  */
+          DEBUG_PRINT1 ("\nFAIL:\n");
+          POP_FAILURE_POINT (d, p,
+                             lowest_active_reg, highest_active_reg,
+                             regstart, regend, reg_info);
+
+          /* If this failure point is a dummy, try the next one.  */
+          if (!p)
+           goto fail;
+
+          /* If we failed to the end of the pattern, don't examine *p.  */
+         assert (p <= pend);
+          if (p < pend)
+            {
+              boolean is_a_jump_n = false;
+              
+              /* If failed to a backwards jump that's part of a repetition
+                 loop, need to pop this failure point and use the next one.  */
+              switch ((re_opcode_t) *p)
+                {
+                case jump_n:
+                  is_a_jump_n = true;
+                case maybe_pop_jump:
+                case pop_failure_jump:
+                case jump:
+                  p1 = p + 1;
+                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+                  p1 += mcnt;  
+
+                  if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+                      || (!is_a_jump_n
+                          && (re_opcode_t) *p1 == on_failure_jump))
+                    goto fail;
+                  break;
+                default:
+                  /* do nothing */ ;
+                }
+            }
+
+          if (d >= string1 && d <= end1)
+           dend = end_match_1;
+        }
+      else
+        break;   /* Matching at this starting point really fails.  */
+    } /* for (;;) */
+
+  if (best_regs_set)
+    goto restore_best_regs;
+
+  FREE_VARIABLES ();
+
+  return -1;                           /* Failure to match.  */
+} /* re_match_2 */
+\f
+/* Subroutine definitions for re_match_2.  */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+   
+   Return true if the pattern up to the corresponding stop_memory can
+   match the empty string, and false otherwise.
+   
+   If we find the matching stop_memory, sets P to point to one past its number.
+   Otherwise, sets P to an undefined byte less than or equal to END.
+
+   We don't handle duplicates properly (yet).  */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+    unsigned char **p, *end;
+    register_info_type *reg_info;
+{
+  int mcnt;
+  /* Point to after the args to the start_memory.  */
+  unsigned char *p1 = *p + 2;
+  
+  while (p1 < end)
+    {
+      /* Skip over opcodes that can match nothing, and return true or
+        false, as appropriate, when we get to one that can't, or to the
+         matching stop_memory.  */
+      
+      switch ((re_opcode_t) *p1)
+        {
+        /* Could be either a loop or a series of alternatives.  */
+        case on_failure_jump:
+          p1++;
+          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+          
+          /* If the next operation is not a jump backwards in the
+            pattern.  */
+
+         if (mcnt >= 0)
+           {
+              /* Go through the on_failure_jumps of the alternatives,
+                 seeing if any of the alternatives cannot match nothing.
+                 The last alternative starts with only a jump,
+                 whereas the rest start with on_failure_jump and end
+                 with a jump, e.g., here is the pattern for `a|b|c':
+
+                 /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+                 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+                 /exactn/1/c                                           
+
+                 So, we have to first go through the first (n-1)
+                 alternatives and then deal with the last one separately.  */
+
+
+              /* Deal with the first (n-1) alternatives, which start
+                 with an on_failure_jump (see above) that jumps to right
+                 past a jump_past_alt.  */
+
+              while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+                {
+                  /* `mcnt' holds how many bytes long the alternative
+                     is, including the ending `jump_past_alt' and
+                     its number.  */
+
+                  if (!alt_match_null_string_p (p1, p1 + mcnt - 3, 
+                                                     reg_info))
+                    return false;
+
+                  /* Move to right after this alternative, including the
+                    jump_past_alt.  */
+                  p1 += mcnt;  
+
+                  /* Break if it's the beginning of an n-th alternative
+                     that doesn't begin with an on_failure_jump.  */
+                  if ((re_opcode_t) *p1 != on_failure_jump)
+                    break;
+               
+                 /* Still have to check that it's not an n-th
+                    alternative that starts with an on_failure_jump.  */
+                 p1++;
+                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+                  if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+                    {
+                     /* Get to the beginning of the n-th alternative.  */
+                      p1 -= 3;
+                      break;
+                    }
+                }
+
+              /* Deal with the last alternative: go back and get number
+                 of the `jump_past_alt' just before it.  `mcnt' contains
+                 the length of the alternative.  */
+              EXTRACT_NUMBER (mcnt, p1 - 2);
+
+              if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+                return false;
+
+              p1 += mcnt;      /* Get past the n-th alternative.  */
+            } /* if mcnt > 0 */
+          break;
+
+          
+        case stop_memory:
+         assert (p1[1] == **p);
+          *p = p1 + 2;
+          return true;
+
+        
+        default: 
+          if (!common_op_match_null_string_p (&p1, end, reg_info))
+            return false;
+        }
+    } /* while p1 < end */
+
+  return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+   It expects P to be the first byte of a single alternative and END one
+   byte past the last. The alternative can contain groups.  */
+   
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+    unsigned char *p, *end;
+    register_info_type *reg_info;
+{
+  int mcnt;
+  unsigned char *p1 = p;
+  
+  while (p1 < end)
+    {
+      /* Skip over opcodes that can match nothing, and break when we get 
+         to one that can't.  */
+      
+      switch ((re_opcode_t) *p1)
+        {
+       /* It's a loop.  */
+        case on_failure_jump:
+          p1++;
+          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+          p1 += mcnt;
+          break;
+          
+       default: 
+          if (!common_op_match_null_string_p (&p1, end, reg_info))
+            return false;
+        }
+    }  /* while p1 < end */
+
+  return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+   alt_match_null_string_p.  
+   
+   Sets P to one after the op and its arguments, if any.  */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+    unsigned char **p, *end;
+    register_info_type *reg_info;
+{
+  int mcnt;
+  boolean ret;
+  int reg_no;
+  unsigned char *p1 = *p;
+
+  switch ((re_opcode_t) *p1++)
+    {
+    case no_op:
+    case begline:
+    case endline:
+    case begbuf:
+    case endbuf:
+    case wordbeg:
+    case wordend:
+    case wordbound:
+    case notwordbound:
+#ifdef emacs
+    case before_dot:
+    case at_dot:
+    case after_dot:
+#endif
+      break;
+
+    case start_memory:
+      reg_no = *p1;
+      assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+      ret = group_match_null_string_p (&p1, end, reg_info);
+      
+      /* Have to set this here in case we're checking a group which
+         contains a group and a back reference to it.  */
+
+      if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+        REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+      if (!ret)
+        return false;
+      break;
+          
+    /* If this is an optimized succeed_n for zero times, make the jump.  */
+    case jump:
+      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+      if (mcnt >= 0)
+        p1 += mcnt;
+      else
+        return false;
+      break;
+
+    case succeed_n:
+      /* Get to the number of times to succeed.  */
+      p1 += 2;         
+      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+      if (mcnt == 0)
+        {
+          p1 -= 4;
+          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+          p1 += mcnt;
+        }
+      else
+        return false;
+      break;
+
+    case duplicate: 
+      if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+        return false;
+      break;
+
+    case set_number_at:
+      p1 += 4;
+
+    default:
+      /* All other opcodes mean we cannot match the empty string.  */
+      return false;
+  }
+
+  *p = p1;
+  return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+   bytes; nonzero otherwise.  */
+   
+static int
+bcmp_translate (s1, s2, len, translate)
+     unsigned char *s1, *s2;
+     register int len;
+     char *translate;
+{
+  register unsigned char *p1 = s1, *p2 = s2;
+  while (len)
+    {
+      if (translate[*p1++] != translate[*p2++]) return 1;
+      len--;
+    }
+  return 0;
+}
+\f
+/* Entry points for GNU code.  */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+   compiles PATTERN (of length SIZE) and puts the result in BUFP.
+   Returns 0 if the pattern was valid, otherwise an error string.
+   
+   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+   are set in BUFP on entry.
+   
+   We call regex_compile to do the actual compilation.  */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+     const char *pattern;
+     int length;
+     struct re_pattern_buffer *bufp;
+{
+  reg_errcode_t ret;
+  
+  /* GNU code is written to assume at least RE_NREGS registers will be set
+     (and at least one extra will be -1).  */
+  bufp->regs_allocated = REGS_UNALLOCATED;
+  
+  /* And GNU code determines whether or not to get register information
+     by passing null for the REGS argument to re_match, etc., not by
+     setting no_sub.  */
+  bufp->no_sub = 0;
+  
+  /* Match anchors at newline.  */
+  bufp->newline_anchor = 1;
+  
+  ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+  return re_error_msg[(int) ret];
+}     
+\f
+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them if this is an Emacs or POSIX compilation.  */
+
+#if !defined (emacs) && !defined (_POSIX_SOURCE)
+
+/* BSD has one and only one pattern buffer.  */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+    const char *s;
+{
+  reg_errcode_t ret;
+  
+  if (!s)
+    {
+      if (!re_comp_buf.buffer)
+       return "No previous regular expression";
+      return 0;
+    }
+
+  if (!re_comp_buf.buffer)
+    {
+      re_comp_buf.buffer = (unsigned char *) malloc (200);
+      if (re_comp_buf.buffer == NULL)
+        return "Memory exhausted";
+      re_comp_buf.allocated = 200;
+
+      re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+      if (re_comp_buf.fastmap == NULL)
+       return "Memory exhausted";
+    }
+
+  /* Since `re_exec' always passes NULL for the `regs' argument, we
+     don't need to initialize the pattern buffer fields which affect it.  */
+
+  /* Match anchors at newlines.  */
+  re_comp_buf.newline_anchor = 1;
+
+  ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+  
+  /* Yes, we're discarding `const' here.  */
+  return (char *) re_error_msg[(int) ret];
+}
+
+
+int
+re_exec (s)
+    const char *s;
+{
+  const int len = strlen (s);
+  return
+    0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+}
+#endif /* not emacs and not _POSIX_SOURCE */
+\f
+/* POSIX.2 functions.  Don't define these for Emacs.  */
+
+#ifndef emacs
+
+/* regcomp takes a regular expression as a string and compiles it.
+
+   PREG is a regex_t *.  We do not expect any fields to be initialized,
+   since POSIX says we shouldn't.  Thus, we set
+
+     `buffer' to the compiled pattern;
+     `used' to the length of the compiled pattern;
+     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+       REG_EXTENDED bit in CFLAGS is set; otherwise, to
+       RE_SYNTAX_POSIX_BASIC;
+     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+     `fastmap' and `fastmap_accurate' to zero;
+     `re_nsub' to the number of subexpressions in PATTERN.
+
+   PATTERN is the address of the pattern string.
+
+   CFLAGS is a series of bits which affect compilation.
+
+     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+     use POSIX basic syntax.
+
+     If REG_NEWLINE is set, then . and [^...] don't match newline.
+     Also, regexec will try a match beginning after every newline.
+
+     If REG_ICASE is set, then we considers upper- and lowercase
+     versions of letters to be equivalent when matching.
+
+     If REG_NOSUB is set, then when PREG is passed to regexec, that
+     routine will report only success or failure, and nothing about the
+     registers.
+
+   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
+   the return codes and their meanings.)  */
+
+int
+regcomp (preg, pattern, cflags)
+    regex_t *preg;
+    const char *pattern; 
+    int cflags;
+{
+  reg_errcode_t ret;
+  unsigned syntax
+    = (cflags & REG_EXTENDED) ?
+      RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+  /* regex_compile will allocate the space for the compiled pattern.  */
+  preg->buffer = 0;
+  preg->allocated = 0;
+  preg->used = 0;
+  
+  /* Don't bother to use a fastmap when searching.  This simplifies the
+     REG_NEWLINE case: if we used a fastmap, we'd have to put all the
+     characters after newlines into the fastmap.  This way, we just try
+     every character.  */
+  preg->fastmap = 0;
+  
+  if (cflags & REG_ICASE)
+    {
+      unsigned i;
+      
+      preg->translate = (char *) malloc (CHAR_SET_SIZE);
+      if (preg->translate == NULL)
+        return (int) REG_ESPACE;
+
+      /* Map uppercase characters to corresponding lowercase ones.  */
+      for (i = 0; i < CHAR_SET_SIZE; i++)
+        preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
+    }
+  else
+    preg->translate = NULL;
+
+  /* If REG_NEWLINE is set, newlines are treated differently.  */
+  if (cflags & REG_NEWLINE)
+    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
+      syntax &= ~RE_DOT_NEWLINE;
+      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+      /* It also changes the matching behavior.  */
+      preg->newline_anchor = 1;
+    }
+  else
+    preg->newline_anchor = 0;
+
+  preg->no_sub = !!(cflags & REG_NOSUB);
+
+  /* POSIX says a null character in the pattern terminates it, so we 
+     can use strlen here in compiling the pattern.  */
+  ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+  
+  /* POSIX doesn't distinguish between an unmatched open-group and an
+     unmatched close-group: both are REG_EPAREN.  */
+  if (ret == REG_ERPAREN) ret = REG_EPAREN;
+  
+  return (int) ret;
+}
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+   string STRING.
+   
+   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
+   least NMATCH elements, and we set them to the offsets of the
+   corresponding matched substrings.
+   
+   EFLAGS specifies `execution flags' which affect matching: if
+   REG_NOTBOL is set, then ^ does not match at the beginning of the
+   string; if REG_NOTEOL is set, then $ does not match at the end.
+   
+   We return 0 if we find a match and REG_NOMATCH if not.  */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+    const regex_t *preg;
+    const char *string; 
+    size_t nmatch; 
+    regmatch_t pmatch[]; 
+    int eflags;
+{
+  int ret;
+  struct re_registers regs;
+  regex_t private_preg;
+  int len = strlen (string);
+  boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+  private_preg = *preg;
+  
+  private_preg.not_bol = !!(eflags & REG_NOTBOL);
+  private_preg.not_eol = !!(eflags & REG_NOTEOL);
+  
+  /* The user has told us exactly how many registers to return
+     information about, via `nmatch'.  We have to pass that on to the
+     matching routines.  */
+  private_preg.regs_allocated = REGS_FIXED;
+  
+  if (want_reg_info)
+    {
+      regs.num_regs = nmatch;
+      regs.start = TALLOC (nmatch, regoff_t);
+      regs.end = TALLOC (nmatch, regoff_t);
+      if (regs.start == NULL || regs.end == NULL)
+        return (int) REG_NOMATCH;
+    }
+
+  /* Perform the searching operation.  */
+  ret = re_search (&private_preg, string, len,
+                   /* start: */ 0, /* range: */ len,
+                   want_reg_info ? &regs : (struct re_registers *) 0);
+  
+  /* Copy the register information to the POSIX structure.  */
+  if (want_reg_info)
+    {
+      if (ret >= 0)
+        {
+          unsigned r;
+
+          for (r = 0; r < nmatch; r++)
+            {
+              pmatch[r].rm_so = regs.start[r];
+              pmatch[r].rm_eo = regs.end[r];
+            }
+        }
+
+      /* If we needed the temporary register info, free the space now.  */
+      free (regs.start);
+      free (regs.end);
+    }
+
+  /* We want zero return to mean success, unlike `re_search'.  */
+  return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
+}
+
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+   from either regcomp or regexec.   We don't use PREG here.  */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+    int errcode;
+    const regex_t *preg;
+    char *errbuf;
+    size_t errbuf_size;
+{
+  const char *msg;
+  size_t msg_size;
+
+  if (errcode < 0
+      || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
+    /* Only error codes returned by the rest of the code should be passed 
+       to this routine.  If we are given anything else, or if other regex
+       code generates an invalid error code, then the program has a bug.
+       Dump core so we can fix it.  */
+    abort ();
+
+  msg = re_error_msg[errcode];
+
+  /* POSIX doesn't require that we do anything in this case, but why
+     not be nice.  */
+  if (! msg)
+    msg = "Success";
+
+  msg_size = strlen (msg) + 1; /* Includes the null.  */
+  
+  if (errbuf_size != 0)
+    {
+      if (msg_size > errbuf_size)
+        {
+          strncpy (errbuf, msg, errbuf_size - 1);
+          errbuf[errbuf_size - 1] = 0;
+        }
+      else
+        strcpy (errbuf, msg);
+    }
+
+  return msg_size;
+}
+
+
+/* Free dynamically allocated space used by PREG.  */
+
+void
+regfree (preg)
+    regex_t *preg;
+{
+  if (preg->buffer != NULL)
+    free (preg->buffer);
+  preg->buffer = NULL;
+  
+  preg->allocated = 0;
+  preg->used = 0;
+
+  if (preg->fastmap != NULL)
+    free (preg->fastmap);
+  preg->fastmap = NULL;
+  preg->fastmap_accurate = 0;
+
+  if (preg->translate != NULL)
+    free (preg->translate);
+  preg->translate = NULL;
+}
+
+#endif /* not emacs  */
+\f
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/lib/gnu_lib/regex.h b/lib/gnu_lib/regex.h
new file mode 100644 (file)
index 0000000..a495005
--- /dev/null
@@ -0,0 +1,490 @@
+/* Definitions for data structures and routines for the regular
+   expression library, version 0.12.
+
+   Copyright (C) 1985, 89, 90, 91, 92, 1993 Free Software Foundation, Inc.
+
+   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 2, 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef __REGEXP_LIBRARY_H__
+#define __REGEXP_LIBRARY_H__
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+   <regex.h>.  */
+
+#ifdef VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+   should be there.  */
+#include <stddef.h>
+#endif
+
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+   If set, then such a \ quotes the following character.  */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+     literals. 
+   If set, then \+ and \? are operators and + and ? are literals.  */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported.  They are:
+     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
+     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+   If not set, then character classes are not supported.  */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+     expressions, of course).
+   If this bit is not set, then it depends:
+        ^  is an anchor if it is at the beginning of a regular
+           expression or after an open-group or an alternation operator;
+        $  is an anchor if it is at the end of a regular expression, or
+           before a close-group or an alternation operator.  
+
+   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+   POSIX draft 11.2 says that * etc. in leading positions is undefined.
+   We already implemented a previous draft which made those constructs
+   invalid, though, so we haven't changed the code back.  */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+     regardless of where they are in the pattern.
+   If this bit is not set, then special characters are special only in
+     some contexts; otherwise they are ordinary.  Specifically, 
+     * + ? and intervals are only special when not after the beginning,
+     open-group, or alternation operator.  */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+     immediately after an alternation or begin-group operator.  */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+   If not set, then it doesn't.  */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+   If not set, then it does.  */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+   If not set, they do.  */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+     interval, depending on RE_NO_BK_BRACES. 
+   If not set, \{, \}, {, and } are literals.  */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+   If not set, they are.  */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+   If not set, newline is literal.  */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+     are literals.
+  If not set, then `\{...\}' defines an interval.  */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+   If not set, \(...\) defines a group, and ( and ) are literals.  */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+   If not set, then \<digit> is a back-reference.  */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal. 
+   If not set, then \| is an alternation operator, and | is literal.  */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+     than the starting range point, as in [z-a], is invalid.
+   If not set, then when ending range point collates higher than the
+     starting range point, the range is ignored.  */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+   If not set, then an unmatched ) is invalid.  */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+   some interfaces).  When a regexp is compiled, the syntax used is
+   stored in the pattern buffer, so changing this does not affect
+   already-compiled regexps.  */
+extern reg_syntax_t re_syntax_options;
+\f
+/* Define combinations of the above bits for the standard possibilities.
+   (The [[[ comments delimit what gets put into the Texinfo file, so
+   don't delete them!)  */ 
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK                                                  \
+  (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL                      \
+   | RE_NO_BK_PARENS            | RE_NO_BK_REFS                                \
+   | RE_NO_BK_VBAR               | RE_NO_EMPTY_RANGES                  \
+   | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK                                            \
+  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP                                                 \
+  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES                                \
+   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS                           \
+   | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP                                                        \
+  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS                   \
+   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE                   \
+   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS                            \
+   | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP                                          \
+  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax.  */
+#define _RE_SYNTAX_POSIX_COMMON                                                \
+  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL             \
+   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC                                          \
+  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+   isn't minimal, since other operators, such as \`, aren't disabled.  */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC                                  \
+  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED                                       \
+  (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS                  \
+   | RE_CONTEXT_INDEP_OPS  | RE_NO_BK_BRACES                           \
+   | RE_NO_BK_PARENS       | RE_NO_BK_VBAR                             \
+   | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+   replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added.  */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED                               \
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
+   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES                          \
+   | RE_NO_BK_PARENS        | RE_NO_BK_REFS                            \
+   | RE_NO_BK_VBAR         | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+\f
+/* Maximum number of duplicates an interval can allow.  Some systems
+   (erroneously) define this in other header files, but we want our
+   value, so remove any previous define.  */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1) 
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp').  */
+
+/* If this bit is set, then use extended regular expression syntax.
+   If not set, then use basic regular expression syntax.  */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+#define REG_ICASE (REG_EXTENDED << 1)
+/* If this bit is set, then anchors do not match at newline
+     characters in the string.
+   If not set, then anchors do match at newlines.  */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+   If not set, then returns differ between not matching and errors.  */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec).  */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+     the beginning of the string (presumably because it's not the
+     beginning of a line).
+   If not set, then the beginning-of-line operator does match the
+     beginning of the string.  */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line.  */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+   `re_error_msg' table in regex.c.  */
+typedef enum
+{
+  REG_NOERROR = 0,     /* Success.  */
+  REG_NOMATCH,         /* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+  REG_BADPAT,          /* Invalid pattern.  */
+  REG_ECOLLATE,                /* Not implemented.  */
+  REG_ECTYPE,          /* Invalid character class name.  */
+  REG_EESCAPE,         /* Trailing backslash.  */
+  REG_ESUBREG,         /* Invalid back reference.  */
+  REG_EBRACK,          /* Unmatched left bracket.  */
+  REG_EPAREN,          /* Parenthesis imbalance.  */ 
+  REG_EBRACE,          /* Unmatched \{.  */
+  REG_BADBR,           /* Invalid contents of \{\}.  */
+  REG_ERANGE,          /* Invalid range end.  */
+  REG_ESPACE,          /* Ran out of memory.  */
+  REG_BADRPT,          /* No preceding re for repetition op.  */
+
+  /* Error codes we've added.  */
+  REG_EEND,            /* Premature end.  */
+  REG_ESIZE,           /* Compiled pattern bigger than 2^16 bytes.  */
+  REG_ERPAREN          /* Unmatched ) or \); not returned from regcomp.  */
+} reg_errcode_t;
+\f
+/* This data structure represents a compiled pattern.  Before calling
+   the pattern compiler, the fields `buffer', `allocated', `fastmap',
+   `translate', and `no_sub' can be set.  After the pattern has been
+   compiled, the `re_nsub' field is available.  All other fields are
+   private to the regex routines.  */
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+       /* Space that holds the compiled pattern.  It is declared as
+          `unsigned char *' because its elements are
+           sometimes used as array indexes.  */
+  unsigned char *buffer;
+
+       /* Number of bytes to which `buffer' points.  */
+  unsigned long allocated;
+
+       /* Number of bytes actually used in `buffer'.  */
+  unsigned long used;  
+
+        /* Syntax setting with which the pattern was compiled.  */
+  reg_syntax_t syntax;
+
+        /* Pointer to a fastmap, if any, otherwise zero.  re_search uses
+           the fastmap, if there is one, to skip over impossible
+           starting points for matches.  */
+  char *fastmap;
+
+        /* Either a translate table to apply to all characters before
+           comparing them, or zero for no translation.  The translation
+           is applied to a pattern when it is compiled and to a string
+           when it is matched.  */
+  char *translate;
+
+       /* Number of subexpressions found by the compiler.  */
+  size_t re_nsub;
+
+        /* Zero if this pattern cannot match the empty string, one else.
+           Well, in truth it's used only in `re_search_2', to see
+           whether or not we should use the fastmap, so we don't set
+           this absolutely perfectly; see `re_compile_fastmap' (the
+           `duplicate' case).  */
+  unsigned can_be_null : 1;
+
+        /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+             for `max (RE_NREGS, re_nsub + 1)' groups.
+           If REGS_REALLOCATE, reallocate space if necessary.
+           If REGS_FIXED, use what's there.  */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+  unsigned regs_allocated : 2;
+
+        /* Set to zero when `regex_compile' compiles a pattern; set to one
+           by `re_compile_fastmap' if it updates the fastmap.  */
+  unsigned fastmap_accurate : 1;
+
+        /* If set, `re_match_2' does not return information about
+           subexpressions.  */
+  unsigned no_sub : 1;
+
+        /* If set, a beginning-of-line anchor doesn't match at the
+           beginning of the string.  */ 
+  unsigned not_bol : 1;
+
+        /* Similarly for an end-of-line anchor.  */
+  unsigned not_eol : 1;
+
+        /* If true, an anchor at a newline matches.  */
+  unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+
+/* search.c (search_buffer) in Emacs needs this one opcode value.  It is
+   defined both in `regex.c' and here.  */
+#define RE_EXACTN_VALUE 1
+\f
+/* Type for byte offsets within the string.  POSIX mandates this.  */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in.  See
+   regex.texinfo for a full description of what registers match.  */
+struct re_registers
+{
+  unsigned num_regs;
+  regoff_t *start;
+  regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+   `re_match_2' returns information about at least this many registers
+   the first time a `regs' structure is passed.  */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers.  Aside from the different names than
+   `re_registers', POSIX uses an array of structures, instead of a
+   structure of arrays.  */
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+\f
+/* Declarations for routines.  */
+
+/* To avoid duplicating every routine declaration -- once with a
+   prototype (if we are ANSI), and once without (if we aren't) -- we
+   use the following macro to declare argument types.  This
+   unfortunately clutters up the declarations a bit, but I think it's
+   worth it.  */
+
+#if __STDC__
+
+#define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+#define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+   You can also simply assign to the `re_syntax_options' variable.  */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+   and syntax given by the global `re_syntax_options', into the buffer
+   BUFFER.  Return NULL if successful, and an error string if not.  */
+extern const char *re_compile_pattern
+  _RE_ARGS ((const char *pattern, int length,
+             struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+   accelerate searches.  Return 0 if successful and -2 if was an
+   internal error.  */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+   compiled into BUFFER.  Start searching at position START, for RANGE
+   characters.  Return the starting position of the match, -1 for no
+   match, or -2 for an internal error.  Also return register
+   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
+extern int re_search
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+            int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+   STRING2.  Also, stop searching at index START + STOP.  */
+extern int re_search_2
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+             int length1, const char *string2, int length2,
+             int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+   in BUFFER matched, starting at position START.  */
+extern int re_match
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+             int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
+extern int re_match_2 
+  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+             int length1, const char *string2, int length2,
+             int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
+   for recording register information.  STARTS and ENDS must be
+   allocated with malloc, and must each be at least `NUM_REGS * sizeof
+   (regoff_t)' bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+extern void re_set_registers
+  _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+             unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+/* 4.2 bsd compatibility.  */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+
+/* POSIX compatibility.  */
+extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
+extern int regexec
+  _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
+             regmatch_t pmatch[], int eflags));
+extern size_t regerror
+  _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
+             size_t errbuf_size));
+extern void regfree _RE_ARGS ((regex_t *preg));
+
+#endif /* not __REGEXP_LIBRARY_H__ */
+\f
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/lib/lookup.c b/lib/lookup.c
new file mode 100644 (file)
index 0000000..e2f00dc
--- /dev/null
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include "eppl_ut.h"
+FILE *lookup_file(const char *name,const char *suffix,const char *dir)
+/* éÝÅÔ ÆÁÊÌ ÓÎÁÞÁÌÁ × ÔÅËÕÝÅÊ ÄÉÒÅËÔÏÒÉÉ, ÐÏÔÏÍ × ÄÉÒÅËÔÏÒÉÉ
+   dir × ÔÅËÕÝÅÊ ÄÉÒÅËÔÏÒÉÉ, ÐÏÔÏÍ × /usr/local/lib/fgis/$dir */
+{ char namebuf[1024],pathbuf[1024];
+  
+  struct stat buf;
+  strcpy(namebuf,name);
+  if (strlen(name)<strlen(suffix)||
+      strcmp(name+strlen(name)-strlen(suffix),suffix)) 
+        strcat(namebuf,suffix); 
+  if (!stat(namebuf,&buf)) return fopen(namebuf,"r");
+
+  if (dir)
+    {strcpy(pathbuf,dir);
+     if (pathbuf[strlen(dir)-1]!='/'){ pathbuf[strlen(dir)]='/';
+                                      pathbuf[strlen(dir)+1]=0;
+                                     }
+     strcat(pathbuf,namebuf);
+     strcpy(namebuf,pathbuf);
+     if (!stat(namebuf,&buf)) return fopen(namebuf,"r");
+    }
+  strcat(strcpy(pathbuf,LIBDIR),namebuf);
+  if (!stat(pathbuf,&buf)) return fopen(pathbuf,"r");
+    return NULL;
+}
diff --git a/lib/overlay.c b/lib/overlay.c
new file mode 100644 (file)
index 0000000..9a91196
--- /dev/null
@@ -0,0 +1,53 @@
+#include <math.h>
+#include <stdlib.h>
+#include "epp.h"
+int compare_cell_size(EPP *f1,EPP *f2)
+{ double xsize1=fabs(f1->XRight-f1->XLeft)/(f1->lc-f1->fc);
+  double xsize2=fabs(f2->XRight-f2->XLeft)/(f2->lc-f2->fc);
+  double ysize1=fabs(f1->YTop-f1->YBottom)/(f1->lr-f1->fr); 
+  double ysize2=fabs(f2->YTop-f2->YBottom)/(f2->lr-f2->fr); 
+/*  fprintf(stderr,"Xsize ratio %g X tolerance %g\nYsize ratio %g Y tolerance %g\n",
+   xsize1/xsize2,1.0/(f1->lc-f1->fc),ysize1/ysize2,1.0/(f1->lr-f1->fr));
+*/  return (fabs(xsize1/xsize2-1.0)<1.0/(f1->lc-f1->fc)&&
+     fabs(ysize1/ysize2-1.0)<1.0/(f1->lr-f1->fr));
+}
+int is_aligned(EPP *f1,EPP *f2)
+{ if (!compare_cell_size(f1,f2)) return 0;
+   return (epp_row(f1,alt_yc(f2,f2->fr))==f2->fr&&
+       epp_col(f1,alt_xc(f2,f2->fc))==f2->fc); 
+}
+EPP_LINK link_epp(EPP *base,EPP *overlay)
+{double x1,y1,x2,y2;
+ EPP_LINK tmp=malloc(sizeof(LINK_BUFFER));
+ if (base->XLeft<base->XRight)
+  {x1=base->XLeft<overlay->XLeft?base->XLeft:overlay->XLeft;
+   x2=base->XRight>overlay->XRight?base->XRight:overlay->XRight;
+  }
+  else
+  {x1=base->XLeft>overlay->XLeft?base->XLeft:overlay->XLeft;
+   x2=base->XRight<overlay->XRight?base->XRight:overlay->XRight;
+  }
+ if (base->YBottom<base->YTop)
+  {y1=base->YBottom<overlay->YBottom?base->YBottom:overlay->YBottom;
+   y2=base->YTop>overlay->YTop?base->YTop:overlay->YTop;
+  }
+  else
+  {y1=base->YBottom>overlay->YBottom?base->YBottom:overlay->YBottom;
+   y2=base->YTop<overlay->YTop?base->YTop:overlay->YTop;
+  }
+ tmp->ax=epp_col(overlay,x2)-epp_col(overlay,x1);
+ tmp->cx=epp_col(base,x2)-epp_col(base,x1);
+ tmp->bx=epp_col(overlay,x1)*tmp->cx-epp_col(base,x1)*tmp->ax;
+ tmp->ay=epp_row(overlay,y2)-epp_row(overlay,y1);
+ tmp->cy=epp_row(base,y2)-epp_row(base,y1);
+ tmp->by=epp_row(overlay,y1)*tmp->cy-epp_row(base,y1)*tmp->ay;
+ return tmp;
+}
+int linked_row(EPP_LINK link,int row)
+{ return (link->ay*row+link->by)/link->cy;
+}
+int linked_col(EPP_LINK link,int col)
+{ return (link->ax*col+link->bx)/link->cx;
+}
+
+
diff --git a/lib/reclass.tab.c b/lib/reclass.tab.c
new file mode 100644 (file)
index 0000000..13c731f
--- /dev/null
@@ -0,0 +1,967 @@
+
+/*  A Bison parser, made from reclass.y
+ by  GNU Bison version 1.25
+  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define        NUMBER  258
+
+#line 1 "reclass.y"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "reclass.h"
+#include "epp.h"
+#define YYSTYPE int
+int yylex();
+int yyerror();
+ RECLASS table;
+ int curval,startval,endval,loop_var;
+ int maxclass;
+ int interactive_parser=0;
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define        YYFINAL         33
+#define        YYFLAG          -32768
+#define        YYNTBASE        10
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 258 ? yytranslate[x] : 18)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     8,
+     2,     2,     9,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     5,
+     7,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     6,     2,     2,
+     4,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     2,     3
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     2,     6,     7,    10,    12,    14,    17,    24,    26,
+    29,    31,    34,    36,    40,    42
+};
+
+static const short yyrhs[] = {    11,
+     0,    10,    13,    11,     0,     0,    12,    14,     0,    17,
+     0,     1,     0,    16,     4,     0,     5,    16,     6,    16,
+     7,     4,     0,     8,     0,     9,     8,     0,    15,     0,
+    14,    15,     0,    16,     0,    16,     6,    16,     0,     3,
+     0,    16,     6,    16,     4,    16,     6,    16,     0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+    17,    19,    22,    23,    24,    25,    31,    32,    34,    35,
+    36,    37,    38,    46,    54,    59
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = {   "$","error","$undefined.","NUMBER",
+"'='","'('","':'","')'","'\\n'","'\\r'","list","statement","dest","eol","range",
+"subrange","value","map_statement", NULL
+};
+#endif
+
+static const short yyr1[] = {     0,
+    10,    10,    11,    11,    11,    11,    12,    12,    13,    13,
+    14,    14,    15,    15,    16,    17
+};
+
+static const short yyr2[] = {     0,
+     1,     3,     0,     2,     1,     1,     2,     6,     1,     2,
+     1,     2,     1,     3,     1,     7
+};
+
+static const short yydefact[] = {     0,
+     6,    15,     0,     0,     1,     0,     0,     5,     0,     9,
+     0,     0,     4,    11,    13,     7,     0,     0,    10,     2,
+    12,     0,     0,     0,    14,     0,     0,     0,     8,     0,
+    16,     0,     0
+};
+
+static const short yydefgoto[] = {     4,
+     5,     6,    12,    13,    14,     7,     8
+};
+
+static const short yypact[] = {     4,
+-32768,-32768,    -2,     8,-32768,    -2,    14,-32768,    -4,-32768,
+     3,     4,    -2,-32768,     0,-32768,    -2,    -2,-32768,-32768,
+-32768,    -2,    17,    15,-32768,    -2,    20,    19,-32768,    -2,
+-32768,    26,-32768
+};
+
+static const short yypgoto[] = {-32768,
+    16,-32768,-32768,-32768,    18,    -3,-32768
+};
+
+
+#define        YYLAST          31
+
+
+static const short yytable[] = {     9,
+     2,    18,    15,    -3,     1,    22,     2,    32,     3,    15,
+    19,    -3,    -3,    23,    24,    10,    11,    16,    25,    17,
+    26,    27,    28,    29,    30,    33,    31,    20,     0,     0,
+    21
+};
+
+static const short yycheck[] = {     3,
+     3,     6,     6,     0,     1,     6,     3,     0,     5,    13,
+     8,     8,     9,    17,    18,     8,     9,     4,    22,     6,
+     4,     7,    26,     4,     6,     0,    30,    12,    -1,    -1,
+    13
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/lib/bison.simple"
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+   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 2, 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc.  */
+#endif /* not GNU C.  */
+#endif /* alloca not defined.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                -2
+#define YYEOF          0
+#define YYACCEPT       return(0)
+#define YYABORT        return(1)
+#define YYERROR                goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL         goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    { yychar = (token), yylval = (value);                      \
+      yychar1 = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK;                                              \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    { yyerror ("syntax error: cannot back up"); YYERROR; }     \
+while (0)
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+#ifndef YYPURE
+#define YYLEX          yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX          yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX          yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX          yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX          yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int    yychar;                 /*  the lookahead symbol                */
+YYSTYPE        yylval;                 /*  the semantic value of the           */
+                               /*  lookahead symbol                    */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;                        /*  location data for the lookahead     */
+                               /*  symbol                              */
+#endif
+
+int yynerrs;                   /*  number of parse errors so far       */
+#endif  /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug;                   /*  nonzero means print parse trace     */
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYINITDEPTH indicates the initial size of the parser's stacks      */
+
+#ifndef        YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+\f
+#if __GNUC__ > 1               /* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)     __builtin_memcpy(TO,FROM,COUNT)
+#else                          /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     int count;
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (char *to, char *from, int count)
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#endif
+#endif
+\f
+#line 196 "/usr/lib/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  int yyerrstatus;     /*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;             /*  lookahead token as an internal (translated) token number */
+
+  short        yyssa[YYINITDEPTH];     /*  the state stack                     */
+  YYSTYPE yyvsa[YYINITDEPTH];  /*  the semantic value stack            */
+
+  short *yyss = yyssa;         /*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;       /*  to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];  /*  the location stack                  */
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
+
+  YYSTYPE yyval;               /*  the variable used to return         */
+                               /*  semantic values from the action     */
+                               /*  routines                            */
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+        the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+        but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+                &yyss1, size * sizeof (*yyssp),
+                &yyvs1, size * sizeof (*yyvsp),
+                &yyls1, size * sizeof (*yylsp),
+                &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+                &yyss1, size * sizeof (*yyssp),
+                &yyvs1, size * sizeof (*yyvsp),
+                &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+       {
+         yyerror("parser stack overflow");
+         return 2;
+       }
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+       yystacksize = YYMAXDEPTH;
+      yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
+      yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+      if (yyssp >= yyss + yystacksize - 1)
+       YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+  goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)             /* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;          /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+       {
+         fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+         /* Give the individual parser a way to print the precise meaning
+            of a token, for further debugging info.  */
+#ifdef YYPRINT
+         YYPRINT (stderr, yychar, yylval);
+#endif
+         fprintf (stderr, ")\n");
+       }
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      int i;
+
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+              yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+       fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 6:
+#line 25 "reclass.y"
+{ if (interactive_parser) 
+                     yyerrok;
+                   else
+                     YYABORT;
+                  ;
+    break;}
+case 7:
+#line 31 "reclass.y"
+{ curval=yyvsp[-1]; ;
+    break;}
+case 8:
+#line 32 "reclass.y"
+{ curval=-1; startval=yyvsp[-4] ; endval = yyvsp[-2]; 
+                               loop_var=startval;;
+    break;}
+case 13:
+#line 38 "reclass.y"
+{ 
+                 if (curval>=0) table[yyvsp[0]]=curval;
+                    else {table[yyvsp[0]]=loop_var++;
+                          if (loop_var>endval) 
+                            loop_var=startval;
+                         }
+                 ;
+    break;}
+case 14:
+#line 46 "reclass.y"
+{ int i; for(i=yyvsp[-2];i<=yyvsp[0];i++) 
+                         if (curval>=0) table[i]=curval;
+                         else {table[i]=loop_var++;
+                               if (loop_var>endval) 
+                                loop_var=startval;
+                              }
+                        ;
+    break;}
+case 15:
+#line 54 "reclass.y"
+{if (yyvsp[0]>65535) 
+                   { yyerror("Class value out of range\n");
+                     return 1;YYERROR;
+                   }
+ ;
+    break;}
+case 16:
+#line 59 "reclass.y"
+{
+               int i,start,stop,startv,stopv;
+               if (yyvsp[-2]>yyvsp[0]) {start=yyvsp[0];startv=yyvsp[-4];stop=yyvsp[-2];stopv=yyvsp[-6];}
+                   else   {start=yyvsp[-2];startv=yyvsp[-6];stop=yyvsp[0];stopv=yyvsp[-4];}
+               for (i=start;i<=stop;i++)
+                table[i]=(i-start)*(stopv-startv)/(start-stop)+startv;
+               ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 498 "/usr/lib/bison.simple"
+\f
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+       fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+       {
+         int size = 0;
+         char *msg;
+         int x, count;
+
+         count = 0;
+         /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+         for (x = (yyn < 0 ? -yyn : 0);
+              x < (sizeof(yytname) / sizeof(char *)); x++)
+           if (yycheck[x + yyn] == x)
+             size += strlen(yytname[x]) + 15, count++;
+         msg = (char *) malloc(size + 15);
+         if (msg != 0)
+           {
+             strcpy(msg, "parse error");
+
+             if (count < 5)
+               {
+                 count = 0;
+                 for (x = (yyn < 0 ? -yyn : 0);
+                      x < (sizeof(yytname) / sizeof(char *)); x++)
+                   if (yycheck[x + yyn] == x)
+                     {
+                       strcat(msg, count == 0 ? ", expecting `" : " or `");
+                       strcat(msg, yytname[x]);
+                       strcat(msg, "'");
+                       count++;
+                     }
+               }
+             yyerror(msg);
+             free(msg);
+           }
+         else
+           yyerror ("parse error; also virtual memory exceeded");
+       }
+      else
+#endif /* YYERROR_VERBOSE */
+       yyerror("parse error");
+    }
+
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+       YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;             /* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+       fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+}
+#line 68 "reclass.y"
+
+int (*my_getc)();
+int yylex()
+{ int c,numb=0,isnumb=0; 
+  static char unget_buf=0;
+ while ((c=unget_buf?unget_buf:(*my_getc)())!=EOF)
+ { unget_buf=0;
+   switch (c)
+   {
+    case '0':
+    case '1':
+    case '2': 
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9': {isnumb=1; numb=numb*10+c-'0'; break;}
+    case ' ':
+    case '\t': {if (isnumb) { yylval=numb; return NUMBER; } break;}
+    default: if (isnumb) { yylval=numb; unget_buf=c; return NUMBER;}
+             else return c;
+ }
+ }
+ return 0;
+}
+
+int yyerror(char *s)
+{ fprintf(stderr,"%s\n",s);
+ return 0;
+}
+RECLASS make_reclass_table(EPP *infile,int (*recl_getc)())
+{ int size=epp_table_size(infile); 
+  
+  return parse_statements(size,create_reclass_table(size),recl_getc);
+}
+RECLASS parse_statements(int size,RECLASS src,int (*recl_getc)())
+{ my_getc=recl_getc;
+  table=src;
+  if (size>65535)size=65535;
+  maxclass=size;
+  if (yyparse()) { free(table);return NULL;}
+    else return table;
+}
+RECLASS create_reclass_table(size)
+{ RECLASS table;
+  int i;
+  if (size<=0) return NULL;
+  else if (size>65535) size=65535;
+  table=malloc((size+1)*sizeof(short int));
+  for(i=0;i<=size;i++) table[i]=i;
+  return table;
+}
+RECLASS wrapped_reclass(EPP *infile,int white)
+{ int i,maxclass;
+  RECLASS table;
+  maxclass=epp_table_size(infile);
+  table=malloc(maxclass*sizeof(short int));
+  table[0]=0;
+  for(i=1;i<=maxclass;i++) table[i]=(i-1)%(white-1)+1;
+  table[infile->offsite]=white;
+  return table;  
+}
diff --git a/lib/reclass.y b/lib/reclass.y
new file mode 100644 (file)
index 0000000..8bf9b94
--- /dev/null
@@ -0,0 +1,131 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include "reclass.h"
+#include "epp.h"
+#define YYSTYPE int
+int yylex();
+int yyerror();
+ RECLASS table;
+ int curval,startval,endval,loop_var;
+ int maxclass;
+ int interactive_parser=0;
+%}
+%expect 2
+%token NUMBER
+%%
+list: 
+     statement 
+    | list eol statement 
+    ;
+
+statement: /* empty */
+         | dest range 
+         | map_statement 
+         | error { if (interactive_parser) 
+                     yyerrok;
+                   else
+                     YYABORT;
+                  }
+
+dest: value '=' { curval=$1; }
+     | '(' value ':' value ')' '=' { curval=-1; startval=$2 ; endval = $4; 
+                               loop_var=startval;}
+eol: '\n' 
+   | '\r' '\n'
+range:subrange
+     |range subrange
+subrange:value { 
+                 if (curval>=0) table[$1]=curval;
+                    else {table[$1]=loop_var++;
+                          if (loop_var>endval) 
+                            loop_var=startval;
+                         }
+                 }
+     
+     | value ':' value { int i; for(i=$1;i<=$3;i++) 
+                         if (curval>=0) table[i]=curval;
+                         else {table[i]=loop_var++;
+                               if (loop_var>endval) 
+                                loop_var=startval;
+                              }
+                        }     
+     ;
+value: NUMBER {if ($1>65535) 
+                   { yyerror("Class value out of range\n");
+                     return 1;YYERROR;
+                   }
+ }
+map_statement: value ':' value '=' value ':' value {
+               int i,start,stop,startv,stopv;
+               if ($5>$7) {start=$7;startv=$3;stop=$5;stopv=$1;}
+                   else   {start=$5;startv=$1;stop=$7;stopv=$3;}
+               for (i=start;i<=stop;i++)
+                table[i]=(i-start)*(stopv-startv)/(start-stop)+startv;
+               }
+;
+
+%%
+int (*my_getc)();
+int yylex()
+{ int c,numb=0,isnumb=0; 
+  static char unget_buf=0;
+ while ((c=unget_buf?unget_buf:(*my_getc)())!=EOF)
+ { unget_buf=0;
+   switch (c)
+   {
+    case '0':
+    case '1':
+    case '2': 
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9': {isnumb=1; numb=numb*10+c-'0'; break;}
+    case ' ':
+    case '\t': {if (isnumb) { yylval=numb; return NUMBER; } break;}
+    default: if (isnumb) { yylval=numb; unget_buf=c; return NUMBER;}
+             else return c;
+ }
+ }
+ return 0;
+}
+
+int yyerror(char *s)
+{ fprintf(stderr,"%s\n",s);
+ return 0;
+}
+RECLASS make_reclass_table(EPP *infile,int (*recl_getc)())
+{ int size=epp_table_size(infile); 
+  
+  return parse_statements(size,create_reclass_table(size),recl_getc);
+}
+RECLASS parse_statements(int size,RECLASS src,int (*recl_getc)())
+{ my_getc=recl_getc;
+  table=src;
+  if (size>65535)size=65535;
+  maxclass=size;
+  if (yyparse()) { free(table);return NULL;}
+    else return table;
+}
+RECLASS create_reclass_table(size)
+{ RECLASS table;
+  int i;
+  if (size<=0) return NULL;
+  else if (size>65535) size=65535;
+  table=malloc((size+1)*sizeof(short int));
+  for(i=0;i<=size;i++) table[i]=i;
+  return table;
+}
+RECLASS wrapped_reclass(EPP *infile,int white)
+{ int i,maxclass;
+  RECLASS table;
+  maxclass=epp_table_size(infile);
+  table=malloc(maxclass*sizeof(short int));
+  table[0]=0;
+  for(i=1;i<=maxclass;i++) table[i]=(i-1)%(white-1)+1;
+  table[infile->offsite]=white;
+  return table;  
+}
diff --git a/lib/test/Makefile b/lib/test/Makefile
new file mode 100644 (file)
index 0000000..ba6b6e6
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Makefile for test directory 
+# compilies test programs and performs tests on major functions
+# of libepp
+# 
+
+#
+# which library to link to extended mallock debugging
+#
+MEM_DEBUG=-lefence
+# 
+# define MEM_DEBUG_LOCATION if your memory debugging library 
+# lives somewhere in non-standard place
+#MEM_DEBUG_LOCATION=/usr/local/lib
+#
+# We use real compilier flags 
+#
+CFLAGS=-g -O2 -I ../../include
+LDFLAGS=-static -L.. ${MEM_DEBUG_LOCATION}
+LOADLIBES=-lepp -lm ${MEM_DEBUG}
+
+test: test_epplib testdata.dat test256.epp run_test.sh
+       run_test.sh
+test_epplib: test_epplib.o ../libepp.a
+
+test_epplib.o: test_epplib.c
diff --git a/lib/test/recltest.c b/lib/test/recltest.c
new file mode 100644 (file)
index 0000000..5484eae
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <reclass.h>
+int mygetc()
+{
+  return getc(stdin);
+}
+int main(int argc,char **argv)
+{ RECLASS src,dest;
+  int i;
+  src=create_reclass_table(65536);
+  dest=parse_statements(65536,src,mygetc);
+  if (dest)
+  for (i=0;i<65536;i++)
+   if (dest[i]!=i) printf("%d reclassed to %d\n",i,dest[i]);
+}
+
diff --git a/lib/test/test8.epp b/lib/test/test8.epp
new file mode 100644 (file)
index 0000000..fe8f37d
Binary files /dev/null and b/lib/test/test8.epp differ
diff --git a/lib/test/test_epplib.c b/lib/test/test_epplib.c
new file mode 100644 (file)
index 0000000..92e33db
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Test program for epp library. It reads file, given as argument
+ * (while not stdin? to simplify running under debugger)
+ * and performs specified operations
+ * After each operation some fields of epp structure are printed
+ * Availiable operations
+ * read file - open epp file for reading
+ * create file width height offsite bits - create file (write-only mode)
+ * load file - opens file for random read-write access
+ * save - saves loaded file
+ * reset - resets write-only file to read-only mode 
+ * get col row - return value
+ * put col row value - change value of pixel
+ * line col1 col2 row value - change value of several adjanced pixels
+ * # text    - comment
+ * NOTE: space after hash mark is mandantory
+ */
+#include <epp.h>
+#include <string.h>
+#include <stdlib.h>
+char filename[1024]; /* name of currently used epp-file */
+FILE *f; /*file with test command. */
+char *error_code[]={"OK","ME_POINT_OUTSIDE","ME_INVALID_MODE",
+  "ME_READ_ERROR","ME_WRITE_ERROR","ME_INVALID_PUT","ME_OUT_OF_MEMORY",
+  "ME_ACCESS_DENIED","ME_NO_FILE","ME_INVALID_FILE","ME_CREATE_ERROR",NULL};
+/* prints value of global map_error varable. If it is 
+   related with file-system error, also
+   prints system error description */
+void print_result()
+{
+  if (map_error>ME_OUT_OF_MEMORY) {
+     perror(error_code[map_error]);
+  } else {
+     printf("%s\n",error_code[map_error]);
+  }
+    map_error=0;
+}
+/*
+ * Prints verbosely mode field of EPP structure.
+ * Note: if it prints something hexadecimal, it should be considered
+ * error in library!
+ */
+char *epp_flags[]={"MAP_INPUT","MAP_OUTPUT","MAP_LOADED","MAP_CACHED",
+   NULL,NULL,NULL,"MAP_MODIFIED",
+   NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+   NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+   NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+};
+/*
+ * Prints verbosely mode field of EPP structure.
+ * Note: if it prints something hexadecimal, it should be considered
+ * error in library!
+ */
+void print_flags(EPP *epp)
+{  int i, mask;
+   char separator=':';
+   printf("EPP mode");
+   for(i=0,mask=1;i<32;i++,mask<<=1) {
+       if (epp->mode&mask) { 
+          if (!epp_flags[i]) {
+             printf("%c 0x%X",separator,mask);
+          } else {
+             printf("%c %s",separator,epp_flags[i]);
+          }
+          separator=',';
+       }
+   }
+   printf("\n");
+}  
+/*************************************************************************/
+/* individual test procedures begin here                                 */
+/************************************************************************/
+
+/*
+ * testing epp_put 
+ */
+void test_put(EPP *epp) 
+{   int row,col,value;
+    if (!epp) {
+       fprintf(stderr,"Invalid test case - put before open");
+       exit(2);
+    }
+    if (fscanf(f,"%d %d %d",&col,&row,&value)!=3) {
+       fprintf(stderr,"Invalid line in input file\n");
+       exit(2);
+    }
+    printf("epp_put(%d,%d,%d):",col,row,value);
+    epp_put(epp, col, row, value);
+    printf("max=%d,min=%d ",epp->max, epp->min);
+}
+/* 
+ * testing epp_putline
+ */
+void test_putline(EPP *epp)
+{  int row,col,col2,value;
+   if (!epp) {
+       fprintf(stderr,"Invalid test case - putline before open");
+       exit(2);
+   }
+    if (fscanf(f,"%d %d %d %d",&col,&col2,&row,&value)!=4) {
+       fprintf(stderr,"Invalid line in input file\n"); 
+       exit(2);
+    }
+    printf("epp_putline(%d,%d,%d,%d):",col,col2,row,value); 
+     epp_putline(epp,col,col2,row,value); 
+    printf("max=%d,min=%d ",epp->max, epp->min);
+}
+/*
+ * testing epp_get
+ */
+void test_get(EPP *epp)
+{  int row,col;
+   if (!epp) {
+       fprintf(stderr,"Invalid test case - get before open");
+       exit(2);
+   }
+   if (fscanf(f,"%d %d",&row,&col)!=2) {
+       fprintf(stderr,"Invalid line in input file\n"); 
+       exit(2);
+   }
+   printf("epp_get(%d,%d)=%d ",col,row,epp_get(epp,col,row)); 
+}
+/*
+ * Testing save_epp
+ *
+ */
+void test_save(EPP* epp) 
+{
+   if (!epp) {
+       fprintf(stderr,"Invalid test case - save before load");
+       exit(2);
+   }
+  printf("Saving %s...",filename);
+  save_epp(epp);
+  print_result();
+  print_flags(epp);
+}
+/*
+ * testing open_epp
+ *
+ */
+
+EPP *test_read(EPP *epp)
+{
+  if (epp) close_epp(epp);
+  if (fscanf(f,"%s",filename)!=1) {
+    fprintf(stderr,"Missing filename for read command\n");
+    exit(2);
+  }
+  printf("Opening %s in read-only mode..",filename);
+  epp=open_epp(filename);
+  print_result();
+  if (!epp) {
+    printf("File wasn't opened.\n");
+    return NULL;
+  }
+  printf("%s header information:\n  bits per cell:%d\n  size:%dx%d\n  "
+     "offsite %d\n  values from: %d to %d\n  ",filename,epp->kind,
+   epp->lc-epp->fc,epp->lr-epp->fr,epp->offsite,epp->min,epp->max);
+  print_flags(epp);
+  return epp;
+}
+/*
+ *
+ * testing load_epp
+ *
+ */
+EPP *test_load(EPP *epp)
+{
+  if (epp) close_epp(epp);
+  if (fscanf(f,"%s",filename)!=1) {
+    fprintf(stderr,"Missing filename for load command\n");
+    exit(2);
+  }
+  printf("Loading %s...",filename);
+  epp=load_epp(filename);
+  print_result();
+  if (!epp) {
+    printf("File wasn't loaded.\n");
+    return NULL;
+  }
+  printf("%s header information:\n  bits per cell:%d\n  size:%dx%d\n  "
+     "offsite %d\n  values from: %d to %d\n  ",filename,epp->kind,
+   epp->lc-epp->fc,epp->lr-epp->fr,epp->offsite,epp->min,epp->max);
+  print_flags(epp);
+  return epp;
+}
+/*
+ *
+ * Test reset. Performs reset operation
+ *
+ */
+void test_reset(EPP *epp)
+{
+   if (!epp) {
+       fprintf(stderr,"Invalid test case - reset before read");
+       exit(2);
+   }
+  printf("Resetting file.\n Current line was %d\n Flags was:",
+       epp->currentline);
+  print_flags(epp);
+  
+  reset_epp(epp);
+  print_result();
+  printf("Current line now is:%d\n",epp->currentline);
+  printf("%s header information:\n  bits per cell:%d\n  size:%dx%d\n  "
+     "offsite %d\n  values from: %d to %d\n  ",filename,epp->kind,
+   epp->lc-epp->fc,epp->lr-epp->fr,epp->offsite,epp->min,epp->max);
+  print_flags(epp);
+}
+/*
+ * testing creat_epp;
+ *
+ */
+EPP *test_create(EPP *epp)
+{ int width,height,bits,offsite;
+  if (epp) close_epp(epp);
+  if (fscanf(f,"%s %d %d %d %d",filename,&width,&height,&offsite,&bits)!=5) {
+    fprintf(stderr,"Wrong arguments for create command\n");
+    exit(2);
+  }
+  Create16bit= (bits!=8);
+  printf("Creating %d-bit file %s...",Create16bit?16:8,filename); 
+  epp=creat_epp(filename,1,1,width,height,0.5,0.5,width+0.5,height+0.5,
+       100,0,offsite);
+  print_result();
+  if (!epp) {
+    fprintf(stderr,"File is not created\n");
+    return NULL;
+  }
+  printf("%s header information:\n  bits per cell:%d\n  size:%dx%d\n  "
+     "offsite %d\n  values from: %d to %d\n  ",filename,epp->kind,
+   epp->lc-epp->fc,epp->lr-epp->fr,epp->offsite,epp->min,epp->max);
+  print_flags(epp);
+  return epp;
+}
+int main (int argc, char *argv[])
+{ EPP *epp=NULL;
+  char command[256];
+  if (argc!=2) {
+    fprintf(stderr,"Usage: test_load test-file");
+    exit(2);
+  }
+  f=fopen(argv[1],"r");
+  if (!f) {
+     perror(argv[0]);
+     exit(2);
+  }
+  while (!feof(f)) {
+    /* skip empty lines */
+    if (fscanf(f,"%s",command)!=1) { 
+       continue;
+    }
+    if (!strcmp(command,"put")) {
+        test_put(epp); 
+    } else if (!strcmp(command,"get")) {
+        test_get(epp);
+    } else if (!strcmp(command,"reset")) {
+        test_reset(epp);
+    } else if (!strcmp(command,"save")) {
+        test_save(epp);
+    } else if (!strcmp(command,"load"))  {
+        epp=test_load(epp);
+    } else if (!strcmp(command,"read")) {
+        epp=test_read(epp);
+    } else if (!strcmp(command,"create")) {
+        epp=test_create(epp);
+    } else if (!strcmp(command,"line")) {
+        test_putline(epp);  
+    } else if (!strcmp(command,"#")) {
+       char *newline;
+       fgets(command,255,f);
+       newline=strchr(command,'\n');
+       if (newline) *newline=0; 
+       printf("*** %s ***\n",command);
+       continue;
+     } else { 
+       fprintf(stderr,"Unknown command:%s",command);
+       continue;
+     }
+    print_result();
+  }
+  fclose(f);
+  if (epp) close_epp(epp);
+  return 0;
+}
diff --git a/lib/test/testdata.dat b/lib/test/testdata.dat
new file mode 100644 (file)
index 0000000..205ff89
--- /dev/null
@@ -0,0 +1,57 @@
+# create test file 
+create test8.epp 100 100 255 8
+put 1 1 20
+put 100 1 29
+# get shouldn't work here
+get 1 10
+put 1 40 20
+# testing if we are allowed to change values above current line
+put 10 10 20
+line 10 90 80 30
+# This line should produce error
+line 10 90 70 22
+# this too
+line 10 90 120 22
+# this line should be drawn partially
+line 90 120 85 22
+# this line too
+line -20 20 86 23
+# and this wouldn't be drawn at all
+line 120 180 87 23
+put 1 100 30
+put 100 100 25
+# resetting file in read mode 
+reset
+put 1 1 10
+get 1 1
+get 100 1
+get 1 100
+get 100 100
+get 1 40
+get 1 30
+load test8.epp
+# testing if file is loaded correc
+# testing decrease of max when value filled with offsite
+put 20 20 40 
+get 5 10
+put 20 20 255
+line 10 90 80 255
+# testing if we are allowed to change values above current line
+put 10 10 20
+# testing minimum support
+put 40 40 1
+put 40 40 20
+put 50 50 3
+put 50 50 255
+# testing decrease of max when value filled with another value
+put 10 20 50 
+put 10 20 20 
+# testing what happens if we are trying to work with point outside file
+put 101 8 8
+get 101 8
+# do something else
+put 8 8 5
+get 1 1
+get 1 100
+get 100 1
+get 100 100
diff --git a/maketar b/maketar
new file mode 100755 (executable)
index 0000000..2fe5885
--- /dev/null
+++ b/maketar
@@ -0,0 +1,16 @@
+#!/bin/sh
+# @(#) maketar - packs all files, neccessary to bring source distribution
+# @(#) of fGIS to another machine
+# This stuff should go to toplevel Makefile eventually, when I create one
+
+
+# year omitted, becouse file name should fit in msdos file system
+tarname=`date +fgis%m%d.tgz`
+
+# search directories, where something like core files or object files could
+# occur
+files=`find lib include dll man -type f \! -name core \! -name '*.o' \! -perm +0111  \! -name '*,v' \! -name '*.a'`
+tclfiles=`find tcl -type f \! -name core \! -path "*/RCS/*"`
+docfiles=`find doc -type f \! -name "*.bak" \! -path "*/RCS/*" \! -name "*.bak"\
+ \! -name "*.dvi" \! -name "*.aux" \! -name "*.i??" \! -name "*.log"`
+tar czvf $tarname $files fgis.rc $tclfiles $docfiles colors symbols testdata pkgIndex.tcl maketar TODO Makefile
diff --git a/man/border.1 b/man/border.1
new file mode 100644 (file)
index 0000000..cea9478
--- /dev/null
@@ -0,0 +1,60 @@
+.TH BORDER 1 "Version 1.0" "EPU" "EPU user manual"
+.SH NAME
+border \- plots contour boundaries of raster file into vector file
+.SH SYNOPSIS
+.B border
+[-v] [-m] [-l] [-t
+.I value
+] [-o
+.I output_file
+]
+.SH DESCRIPTION
+Creates a 
+.B dgt
+file with lines which delimit different classes in input
+.B epp file.
+If 
+.B -l
+option given, puts a label point into each closed polygon. 
+.PP
+Default output filename is constructed from name of input file, by
+replacing suffix 
+.I .epp
+by
+.I .dgt
+\.
+.PP
+Lines can be created "staircase"-like or smooth. Smoothing is controlled
+by 
+.B tolerance 
+factor, which defines maximum size of line segment, which can be changed.
+
+.SH OPTIONS
+.TP 8
+.B --help
+Display brief usage information and exit successifully.
+.TP 8
+.B --version
+Display version number and exit successifully.
+.TP 8
+.B -%, --verbose
+Display progress indication. Useful on large files, but significantly
+decreases performans on small ones.
+.TP 8
+.B -m, --margins
+Controls behavouir on file edges. By default 
+.B border
+treats all areas outside file as 
+.I offsite,
+but when this option given, it assumes that all classes at the file edge
+are continued outside it.
+.TP 8
+.B -t --tolerance
+Defines tolerance value. Default is zero -- no smoothing.
+.TP 8
+.B -o --output-file
+Allows to specify output file name explicitly.
+
+.SH BUGS
+Label creation is unwritten yet
+
diff --git a/man/clip.1 b/man/clip.1
new file mode 100644 (file)
index 0000000..5b9890d
--- /dev/null
@@ -0,0 +1,43 @@
+.TH CLIP 1 "Version 1.0" "EPU" "EPU user manual"
+.SH NAME
+clip \- clips a region from old file using mask file 
+.SH SYNOPSIS
+.B clip 
+[-%] [-m number] [-o filename] [--help][--version] file mask
+.SH DESCRIPTION
+Clip creates new file, containing part of old file, which corresponds
+to given onsite area or specified class of mask file. 
+.PP
+Cell size of new file would be equial to cell size of mask file.
+If cell sizes don't match, ``nearest neighbour'' algorithm would be used
+for rescaling.
+
+.SH OPTIONS
+.TP 8
+.B --help
+displays brief usage information.
+.TP 8
+.B --version
+displays version number
+.TP 8
+.B -%
+Displays percentage of processed lines in file.
+.TP 8
+.BI -o " file " --output-file= file
+gives the name for output file. Defaults to
+.I mosaic.out.epp
+.TP 8
+.BI -m " number" --mask-value= number
+Clip region which has class
+.I number
+in the mask file. Otherwise all onsite area of mask file would be clipped.
+.SH SEE ALSO
+.BR window(1), mosaic(1), eheader (1)
+
+.SH AUTHOR
+
+Victor B. Wagner <vitus@agropc.msk.su>
+
+.SH BUGS
+
+Should deal with different cell sizes.
diff --git a/man/cluster.1 b/man/cluster.1
new file mode 100644 (file)
index 0000000..aed3b48
--- /dev/null
@@ -0,0 +1,71 @@
+.TH CLUSTER 1 "Version 1.0" "Lessa GIS" "Lessa user manual"
+.SH NAME
+cluster \- fills each contour on raster map with its own color
+.SH SYNOPSIS
+.B cluster 
+[-v] [-f] 
+.I input_file 
+[-o 
+.I output_file
+] [-c 
+.I line_color
+] [-T 
+.I temp_dir]
+.SH DESCRIPTION
+Paints each area in 
+.B epp
+file, surrounded by color
+.I line_color
+by unique color from 1 to maximal contour number. Can handle up to 65535 contours in file.
+.PP
+Requires at least three time more space in temporary directore then input file occupies.
+.PP 
+By default assumes that line color is 0 and output file name
+.I cluster.out.epp
+.PP
+Performs two passes on input file and between them prints to stdout information about
+number of contours in output file and temporary numbers assigned when calculating 
+contours. So, redirect standard output, if start cluster in background mode.
+.SH OPTIONS
+.TP 8
+.B \-v
+Verbose mode. Information about current line in processing is printed to stderr.
+.TP 8
+.BI \-c " line_color"
+\- Set contour separation color to
+.I " line_color".
+.TP 8
+.BI \-o " output_file"
+\- overrides default name of output file.
+.TP 8
+.BI \-f " input_file"
+\- Equivalent of simple command-line parameter without option prefix.
+.TP 8
+.I "-?" " -h"
+\- Print brief help message and exit successifully.
+.TP 8
+.BI \-T " directory" 
+\- Uses
+.I directory 
+instead of 
+.I /tmp 
+for storing temporary files
+
+.SH "SEE ALSO"
+.BR lessa (1),
+.BR mappaint (1),
+.BR mapcopy (1),
+.BR eheader (1),
+.BR epp (5),
+.BR dgt (5)
+
+.SH BUGS
+For some unknown reason reports very strange errors (usially page faults) or
+produces very strange results, when compilied under DOS. So use unix versions.
+.PP
+It seems obvouis, that same program must perform 
+.B rasterize
+operation, but this still not implemented.
+.SH AUTHOR
+Vitus Wagner,
+.B SoftWeyr.
diff --git a/man/eheader.1 b/man/eheader.1
new file mode 100644 (file)
index 0000000..60c05ee
--- /dev/null
@@ -0,0 +1,209 @@
+.TH EHEADER 1 "Version 1.0" "Environmental planning utilities" "EPU user manual"
+.SH NAME
+eheader \- display and modify headers of EPPL7 data files
+.SH SYNOPSIS
+.B eheader 
+options files
+.PP
+.B maplist
+files
+.PP
+.B mapalign
+base_file 
+.B [-v]
+files
+.SH DESCRIPTION
+Applies given editing commands to list of
+.B epp
+or
+.B dgt
+ files.
+.PP
+Several commands are applicable to both file types and several
+to 
+.B epp
+(raster) files only.
+No warning is issued when 
+.B dgt
+file is processed during section when epp\-specific commands used,
+becouse several epp\-files can be processed at same time.
+.PP
+No warning is issued also when no editing commands given, therefore 
+this utility can be used just for viewing header information.
+.PP
+When invoked as
+.B maplist,
+simply dumps headers of given files. 
+.PP
+when invoked as
+.B mapalign
+performs same operations as with
+.B \-A 
+key, but only other option accepted is 
+.B -v.
+This option may be given as before, as after base file.
+
+
+.SH UNIVERSAL OPTIONS
+This commands can be applied to both 
+.B dgt 
+(vector)
+and
+.B epp
+(raster)
+files.
+.TP 8
+.B \-v
+\- dumps file header information
+.B after
+applying any edit options to
+.I stdout.
+
+.TP 8
+.B \-x increment
+  \- shifts alternative x by 
+.B increment.
+Increment can be any real number, both positive and negative.
+.TP 8
+.B \-y increment
+  \- same with alternative y
+.TP 8
+.B \-s factor 
+\- multiplies all coordinates by factor
+.PP
+This commands cannot be used together with explicit settings of some
+alternative coordinate limit.
+.TP 8
+.BR "\-Xl value" " or  " "\-XL value"
+\- sets alternative x of left border to specified value
+.TP 8
+.BR "\-Xr value" " or " "\-XR value"
+\- same with right border
+.TP 8
+.BR "\-Yb value" " or " "\-YB value" , "\-Yt value" " or " "\-YT" 
+\- same with bottom and top y
+.TP 8 
+.B \-p name
+  \- set projection type to name. Available projection types (
+.B EPPL7 version 3.0
+) are:
+.RS
+.TP 8 
+.B none
+\- cause EPPL ver 3 to say "No alternate coordinates"
+.TP 8 
+.BR utm " or " UTM 
+\- UTM projection
+.TP 8 
+.B stplate 
+\- state plane (projection for US state maps)
+.TP 8
+.B ll 
+\- latitude and longitude (geographic coordinates)
+.RE
+.SH "EPP SPECIFIC COMMANDS"
+Following is applicable to EPP files only:
+.TP 8
+.B \-o n
+ \- set offsite value to n. Value can be in range \-32768 65535.
+Negative values are equivalent to 65536\-abs(n). Values above 255, applied
+to 
+.I 8\-bit 
+data files are silently translated into \-1 (no offsite)
+.TP 8
+.B \-fr n 
+\- set first row to n and updates last row field respectively.
+.TP 8
+.B \-fc n
+ \- set first column to n and updates last column field.
+.TP 8
+.B \-A filename 
+\- align to specified file, i.e updates row/column coordinates
+so row and column with same number have same alternative coordinates.
+.TP 8
+.B \-a  value
+\- set cell area to value.
+.TP 8
+.B \-c "string"
+ \- fills description field of the header. String must be single command line
+argument, but not nessecary need quotes.
+.TP 8
+.B \-u name 
+\- set area unit type, where unit type may be:
+.RS
+.TP 8
+.B none 
+\- cause EPPL ver 3 to say "No alternate coordinates"
+.TP 8
+.B ft
+  \- square feet
+.TP 8
+.B m 
+\- square meters
+.TP 8
+.B km
+ \- square kilometers
+.TP 8
+.B mile \- square miles
+.TP 8
+.B ha
+ \- hectares
+.TP 8
+.B acre 
+\- acres
+.PP 
+This command does not perform any recalculation, it just update 
+unit name field. Use 
+.B \-a
+command for change cell area value respectively.
+.RE
+.SH "OPTION COMPATIBILYTY"
+Some options of 
+.B eheader
+cannot coexist together in same command line.
+there are two groups of options with incompatibilities between subgroup
+of each group.
+
+First, options dealing with alternative coordinates. There are options
+.B "-Xl -Xr -Yt -Yb,"
+which set alternative coordinates explicitely, and options
+.B "-x -y -s",
+which change coordinates by arithmetic calculations.
+Explicit and arithmetic changes of coordinates are not allowed simulateneously,
+becouse it is to hard to understand, which kind user want to apply first.
+
+Second, options dealing with row/column coordinates of 
+.B epp
+files. Here there are options 
+.BR "-A" " and " "-fr -fc"
+which performs directly opposite task.
+(usially 
+.B -fr -lr
+are used to set first row and column to one, to process file cutted from
+large 
+.epp
+file separately
+and 
+.B -A
+to change it back to
+.BR mosaic (1)
+file into larger one. 
+
+.SH "SEE ALSO"
+.BR lessa (1),
+.BR mappaint (1),
+.BR mapcopy (1)
+.BR epp (5),
+.BR dgt (5)
+.SH BUGS
+No check is performed by 
+.B \-fr
+and
+.B \-lr
+command to ensure that row/column values are in valid range.
+.PP
+.B \-A
+command sometimes miscalculates one cell. (but EPPL ver 2.1 does the same).
+.SH AUTHOR
+Vitus Wagner,
+.B SoftWeyr.
diff --git a/man/extents.1 b/man/extents.1
new file mode 100644 (file)
index 0000000..583916b
--- /dev/null
@@ -0,0 +1,71 @@
+.TH EXTENTS 1 "Version 1.0" "EPU" "EPU user manual"
+.SH NAME
+extents \- displays information about class extents in given EPP file.
+.SH SYNOPSIS
+.B extents 
+[-%ahlrtbxtA] [-o file] file.epp
+.SH DESCRIPTION
+
+Extents calculates area extents of all classes in given file and
+displays it in tabular form.
+
+This information includes minimal and maximal coordinates and area of
+class.
+.PP
+By default information is printed to 
+.I stdout.
+
+It may be given in row/column and alternative coordinates.
+.SH OPTIONS
+.TP 8
+.B --help
+displays brief usage information.
+.TP 8
+.B --version
+displays version number
+.TP 8
+.B -% --verbose
+Displays percentage of processed lines in file.
+.TP 8
+.BI -o " file " --output-file= file
+gives the name for output file, to write results to, instead of standard 
+output.
+.TP 8
+.B -a --alt-coords
+display coordinates in alternative system and area in real units,
+insted of row/col and cell count.
+.TP 8
+.B -h --header
+display one-line header above table.
+.TP 8
+.B -l --sort-left
+sort classes by leftmost coordinate
+.TP 8
+.B -r --sort-right
+sort classes by rightmost coordinate
+.TP 8
+.B -t --sort-top
+same for topmost coordinate
+.TP 8
+.B -b --sort-bottom
+I'm tired with this sort orders
+.TP 8
+.B -A --sort-area
+Sort classes by count of cells.
+.TP 8
+.B -x --sort-x-center
+Sort by x-coordinate of center of rectangle, containing all cells of that class.
+.B -y --sort-y-center
+same, but by y-coordinate
+
+.SH SEE ALSO
+.BR outtable (1)
+
+.SH AUTHOR
+
+Victor B. Wagner <vitus@agropc.msk.su>
+
+.SH BUGS
+
+???
+
diff --git a/man/fgisRasterColorImage.n b/man/fgisRasterColorImage.n
new file mode 100644 (file)
index 0000000..0823c20
--- /dev/null
@@ -0,0 +1,94 @@
+.TH palette n 1.0 Fgis "developer Tcl commands"
+
+.SH NAME
+fgisRasterColorImage, fgisRasterBWImage \- render raster object into planchet item
+
+.SH SYNOPSIS
+\fBfgisRasterColorImage\fI raster planchet item\fR ?\fIoption\fR?
+
+\fBfgisRasterBWImage\fI raster planchet item\fR ?\fIoption\fR?
+
+.SH DESCRIPTION
+
+These commands perform visualisation of fGIS raster objects in fGIS planchet
+(essentially same as Tk canvas). They work on platform independent manner,
+creating visible representation of layer in Tk image object, which should
+be previously created. 
+
+User (and even application writer) seldom accesses this commands directly.
+Raser layer objects and planchet subcommands should be used to visualize
+raster layers.
+
+These commands controls all attributes of layer appearance, which have no
+semantic meaning. I.e. raster file class to palette index correspondence is
+part of raster object, becouse it also used for access legend and GIS
+operation, while palette itself appear only in call to this command, becouse
+it used only to visualisation.
+
+.SH ARGUMENTS
+
+.TP 4
+\fIraster\fR -
+name of fGIS raster object (see \fBraster\fR(n)).
+
+.TP 4
+\fIplanchet\fR -
+name of fGIS planchet widget. Planchet should be mapped and have coordinate
+system already defined.
+
+.TP 4
+\fIitem\fR -
+ID of planchet item to render raster in. It should exist, be of type image
+and contain valid image (photo for \fBfgisRasterColorImage\fR and bitmap for
+\fBfgisRasterBWImage\fR) in its -image atribute.
+
+.SH OPTIONS
+.TP 4
+\fB-border\fI option\fR -
+specifies whether borders between raster object classes or base file classes
+(polygon borders) should be drawn. \fIOption\fR can be one of \fBnone\fR,
+\fByes\fR, \fBbase\fR. Abbreviations are not allowed (bug?). \fByes\fR means
+that borders are drawn only between distinct classes of current raster object,
+\fBbase\fR means that borders should be drawn if base file classes are distinct,
+even if they are reclassed into same value. Useful for choropleth plots.
+
+For symbol plots option is ignored. Defaults to \fBnone\fR for color images
+and \fByes\fR for BW images.
+.TP 4
+\fB-color\fI color\fR 
+- specifies color to plot borders in color mode or
+for entire image in pattern or symbol mode. \fIcolor\fR can be any form
+of color specification, acceptable by Tk. Defaults to "black".
+.TP 4
+\fB-map\fI option\fR -
+specifies how to deal with map classes, which exceed palette or pattern range
+(0\-255). Option is one of \fBwrap\fR - use symbol (color) \fIclass%255\fR for
+classes which exceeds 255, \fBnone\fR - use symbol (color) 255 for all these
+clases and \fInumber\fR - map range 0-\fImax class\fR to range 0-\fInumber\fR.
+Defaults to \fBwrap\fR.
+.TP 4
+\fB-palette \fIpalettename\fR (color only) -
+specifies fGIS palette object to use for coloring of map classes. Defaults
+to \fBdefaultpalette\fR.
+.TP 4
+\fB-patterns \fIpatternname\fR (BW only) -
+sets plotting mode to pattern and specifies pattern set to plot. In pattern
+mode patterns are clipped by polygon boundaries, and thus any border modes
+are allowed. Defaults to {} (empty pattern). This mode is default for 
+\fBfgisRasterBWImage\fR
+.TP 4
+\fB-symbols \fIpatternname\fR (BW only) -
+sets plotting mode to symbol and specifies pattern set to plot. In symbol
+mode patterns can be drawn only at whole, so if central point of pattern
+belongs to certain class, pattern for this class would be drawn on entire
+rectangle. Borders are never plotted in this mode No defaults, becouse this
+mode must be turned on explicitely.
+.TP 4
+\fB-update \fI{x1 y1 x2 y2}\fR
+- Specifies, that only part of image should be replotted. Useful for
+raster editing application. Rectangle to update is given in map coordinates.
+It is clipped by image boundaries.
+
+.SH SEE ALSO
+.BR raster (n), planchet (n), palette (n), 
+.BR patterns (n)
diff --git a/man/legend.n b/man/legend.n
new file mode 100644 (file)
index 0000000..6b74d33
--- /dev/null
@@ -0,0 +1,85 @@
+.TH legend n 1.0 EPTcl "Environmental Planning Tcl extensions"
+.SH NAME
+legend \- Create and manipulate EPTcl  legends
+
+.SH SYNOPSIS
+\fBlegend read\fI filename\fR options
+
+\fBlegend parse\fI string\fR
+
+\fBlegend set\fI list\fR
+
+.SH DESCRIPTION
+
+\fBlegend\fR creates legend object, which is used to store and manipulate
+descriptive information about maps. There are three ways to create legend:
+.TP 4
+from file, which shoild be an EPPL7 legend file
+.TP 4
+from string, which should hold content of such file
+.TP 4
+from Tcl list, simular to one, used for \fBarray set\fR command
+.PP
+\fBlegend\fR command returns handle for legend which is unique identifier,
+used for subsequent references for this legend. It creates new Tcl command
+with name of this identifier, that used to manipulate legend. 
+.PP
+Actually, legend object is combination of global array and Tcl procedure,
+and legend handle is simply name of both of them.
+
+.SH OPTIONS
+.TP 4
+\fBlegend read\fI filename\fR
+Opens and reads text file in EPPL7 format. Each line of this file contain
+number and descriptive text, separated by two spaces (originally, there should
+be some information concering printing map on line printer (not graphical one)
+between this spaces, but this format is no longer used and supported.
+Numbers between 0 and 65535 are considered map classes and numbers -2 and -1
+have special meaning - they are considered legend title and subtitle respecitvely. There can be several lines with same classes in legend. They are concatenated.
+Note that EPTcl never uses this line separations as line breaks when outputting
+legend (may be this should go to BUGS section)
+.TP 4
+\fBlegend parse\fI string\fR
+Produces legend from string which should be identical to content of EPPL7
+legend file.
+.TP 4
+\fBlegend set\fI list\fR
+Produces legend from Tcl list. Such list can be obtained by \fBarray get 
+\fIlegendname\fR command. Differ from \fBarray set\fR in that finds correct
+name for legend and defines object command for it. Can be used to create
+empty legend for subsequentual filling by \fIlegendname \fBset\fR subcommand. 
+In this case empty list should be specified.
+
+.SH OBJECT COMMAND
+.TP 4
+\fIlegendName\fB classes\fR
+Return sorted list of classes defined in legend
+.TP 4
+\fIlegendName\fB delete\fR
+Destructor of object. Unsets all data and destroys object command.
+.TP 4
+\fIlegendName\fB drawable\fI ?boolean?
+if boolean specified, set legend drawmode and return nothing.
+Otherwise returns 0 or 1, depending of current settings.
+Drawmode controls if legend could be displayed in legend box.
+.TP 4
+\fIlegendName\fB get \fI class\fR 
+Returns value of given class or string "Not defined",such class is not defined.
+String could be changed by changing value of element \fBudefined_legend\fR of
+global array \fBfgis\fR
+.TP 4
+\fIlegendName\fB print\fI
+Returns content of legend in form of EPPL7 legend format as string.
+.TP 4
+\fIlegendName\fB set \fIclass value\fR
+Changes description of given class
+.TP 4
+\fIlegendName\fB subtitle\fR ?\fIstring\fR?
+If no \fIstring\fR specified, returns current legend subtitle. Otherwise
+replaces subtitle by given string
+.TP 4
+\fIlegendName\fB title\fR ?\fIstring\fR?
+If no \fIstring\fR specified, returns current legend title. Otherwise
+replaces title by given string
+.SH BUGS
+None noticed
diff --git a/man/mosaic.1 b/man/mosaic.1
new file mode 100644 (file)
index 0000000..fa626e8
--- /dev/null
@@ -0,0 +1,62 @@
+.TH MOSAIC 1 "Version 1.0" "EPU" "EPU user manual"
+.SH NAME
+mosaic \- merges several epp files together
+.SH SYNOPSIS
+.B mosaic 
+[-%RA] [-O number] [-o filename] [--help][--version]files
+.SH DESCRIPTION
+Mosaic merges several 
+.IR epp -files
+into one. If some cell has non-offsite value in several files,
+value from last files would be used.
+.PP
+Cell sizes of all old files must be equial. Usially 
+.B mosaic
+deals with properly aligned files, but it can deal with misaligned files,
+taking into account row/column or alternative coordinates regarding to
+command-line options.
+.PP
+If 
+.I offsite
+value is not explicitely given in command line, it defaults to 
+offsite of first (base) file if it is not used as data class in one
+of overlay files. In last case offsite would be set to 255 for 8-bit and
+to 65535 to 16-bit files.
+.SH OPTIONS
+
+.SH OPTIONS
+.TP 8
+.B --help
+displays brief usage information.
+.TP 8
+.B --version
+displays version number
+.TP 8
+.B -%
+Displays percentage of processed lines in file.
+.TP 8
+.BI -o " file " --output-file= file
+gives the name for output file. Defaults to
+.I mosaic.out.epp
+.TP 8
+.B -A --force-alt
+Do not complain, if files are misaligned. Use alternate coordinates to
+reference them.
+.TP 8
+.B -R --force-row
+Same, but use row/col cordinates.
+
+.TP 8
+.BI -O " value " --offsite= value
+specifies offsite value of new file.
+
+.SH SEE ALSO
+.BR eheader (1), window (1)
+
+.SH AUTHOR
+
+Victor B. Wagner <vitus@agropc.msk.su>
+
+.SH BUGS
+
+???
diff --git a/man/neighbours.1 b/man/neighbours.1
new file mode 100644 (file)
index 0000000..07165ea
--- /dev/null
@@ -0,0 +1,43 @@
+.TH NEIGHBOURS 1 "Version 1.0" "Environmental planning utilities" "EPU user manual"
+.SH NAME
+neighbours \- prints list of neighbouring clasees in epp-file
+.SH SYNOPSIS
+.B neighbours [-%][-d] file
+.SH DESCRIPTION
+This command searches 
+.IR epp -file
+for all class boundaries and print a table of class pair which
+are neighbouring at least in one place. 
+DO NOT MIX it with EPPL7 NEIGHBOUR command, which is part of
+.BR evaluate (1)
+in EPU.
+
+It prints pairs of classes to stdout, one per line separated by commas.
+
+Each pair of classes can be printed once or twice, first among neighbours
+of first class in pair, than neighbours of second.
+
+.SH OPTIONS
+.TP 8
+.B --help
+displays brief usage information.
+.TP 8
+.B --version
+displays version number
+.TP 8
+.B --verbose -%
+Displays percentage of processed lines in file.
+.TP 8
+.B -d --double
+print each pair twice. 
+
+.SH SEE ALSO
+.BR outtable (1), mapcolor (1), evaluate (1), extents (1). 
+
+.SH AUTHOR
+
+Victor B. Wagner <vitus@agropc.msk.su>
+
+.SH BUGS
+
+???
diff --git a/man/outtable.1 b/man/outtable.1
new file mode 100644 (file)
index 0000000..44fcdb1
--- /dev/null
@@ -0,0 +1,153 @@
+.TH OUTTABLE 1 "Version 1.0" "Environmental planning utilities" "EPU user manual"
+.SH NAME
+outtable \- computes table of statistics from several epp files.
+.SH SYNOPSIS
+.B outtable 
+.RI [ options ]
+.RI [ function "] file [ [" function "] file ...]"
+
+.SH DESCRIPTION
+.B outtable 
+takes several 
+.IR epp -files
+counts all possible combinations of classes in them and produces
+table of them. 
+.PP
+Some files  can be preceded by 
+.I function
+Such files wouldn't be used to define new combination. Instead, corresponding
+column of table would contain value of function, computed from this file for
+area, defined by combination of classes of all "function-less" files.
+.PP
+All files, used to define combination, should be specified before first
+file with function.
+.PP
+If no function defined, table would be appended by column, containing area
+of each combination.
+.PP
+If all files have function, table would contain only one row, containing
+values of the functions for all area.
+.PP
+If files have different cell size and limits, limits and coordinate systems
+of the first file are used, unless overriden by 
+.B
+--base
+option.
+.PP
+By default, semantic value of classes are considered equial to values of
+classes. This can be overridden by specifying parameters of linear mapping
+function using 
+
+.BR -z " and " -Z " options."
+This option can be specified only once per invocation, becouse usially
+.B outtable
+is used to calculate statistics for one file in combinations, given by
+several other files.
+.PP
+By default, all area-related values are calculated in alternative coordinate
+units. It can be overriden using 
+.B -c
+option.
+.SH OPTIONS
+.TP 8
+.B --help
+displays brief usage information.
+.TP 8
+.B --version
+displays version number
+.TP 8
+.B --verbose -%
+Displays percentage of processed lines in file.
+.TP 8
+.B -u --union 
+Take into account all cells, where at least one of output files is not offsite.
+By default, only cells where all input files are onsite are taken into account.
+.TP 8
+.B -c --cells
+Output areas in cells. By default map units as specified in file header
+are used to compute areas.
+.TP 8
+.BI -d "char " --delimiter= char 
+sets table column separator to 
+.I char. Defaults to comma.
+.TP 8
+.BI -b " file" --base " file"
+Specifies epp file, used as reference grid. Cell area and cell size of this
+file, as well as its coordinate limits would be used for processing. 
+Defaults to first file in the command line.
+.TP 8
+.BI -z " value"
+Specifies multiplier for calculating semantic value from class value.
+.TP 8
+.BI -Z " value"
+Specifies offset of semantic values, i.e. semantic value of class 0.
+.SH FUNCTIONS
+.TP 8
+.B -sum
+Sum of classes in given file for combination, multiplied by cell area.
+.TP 8
+.B -cnt
+Count of onsite cells of given file.
+.TP 8
+.B -avg
+Average cell value
+.TP 8
+.B -min
+Minimum cell value
+.TP 8
+.B -nmin
+Area of cells with minimum value
+
+.TP 8
+.B -max
+Maximum cell value
+.TP 8
+.B -nmax
+Area of cells with maximum value
+.TP 8
+.B -mode
+Modal value (value of most cells)
+.TP 8
+.B -nmode
+Area of cells with modal value
+.TP 8
+.B -fewest
+Class with fewest cells
+.TP 8
+.B -nfewest
+Area of cells in fewest class
+.TP 8
+.B -range
+Range of classes (maximum-minimum)
+.TP 8
+.B -classes
+Number of different classes
+.TP 8
+.B -or
+Bitwise or of all cells (values of 
+.BR -z " and " -Z
+options are not used)
+.TP 8
+.B -and
+Bitwise and of all cells (values of 
+.BR -z " and " -Z
+options are not used)
+.TP 8
+.B -std
+Standard deviation of classes
+.TP 8
+.B -var
+Variance of classes
+.TP 8
+.B -corr
+Correlation coefficient between two files. Requires two arguments.
+.SH SEE ALSO
+.BR intable (1), reclass (1), evaluate (1), resample (1), eheader (1)
+
+.SH AUTHOR
+
+Victor B. Wagner <vitus@agropc.msk.su>
+
+.SH BUGS
+
+???
diff --git a/man/palette.n b/man/palette.n
new file mode 100644 (file)
index 0000000..c67ae7b
--- /dev/null
@@ -0,0 +1,67 @@
+.TH palette n 1.0 Fgis "user Tcl commands"
+
+.SH NAME
+palette \- Create and manipulate color palettes 
+
+.SH SYNOPSIS
+\fB palette \fIoption\fR ?\fIarg\fR?
+
+.SH DESCRIPTION
+.PP
+This command creates palette object, which is used for map visualisation. Palette is
+array of 256 RGB color specifications, indexed by integers from 0 to 255. 
+Typically palette entry N is used for displaying map class N.
+Upon creation of object new Tcl command with same name as object is defined
+and can be used for manipulating palette. \fBpalette\fR command returns
+name of created object. One palette, named \fBdefaultpalette\fR is created
+during initialization of fGIS. In difference of user-created palettes it
+cannot be modified.
+
+.SH OPTIONS
+.TP 4
+\fBpalette read \fIfilename\fR
+- reads palette from specified file. File should confirm EPPL7 clr file
+syntax.
+.TP 4
+\fBpalette parse \fIstring\fR
+- reads palette from string. String should have same format as EPPL7 clr file.
+.TP 4
+\fBpalette set \fIlist\fR
+- creates palette from list of color specification. Each element of list
+should have format \#rrggbb. Color names are not supported by palettes.
+Color specifications are assigned to palette indices in sequentual order.
+.TP 4
+\fBpalette blank\fR
+- creates new palette with all entries set to white (#ffffff).
+
+.TP 4
+\fBpalette copy \fIpaletteName\fR
+- creates a copy of existing palette. This allows to create modifable copy
+of default palette.
+.SH OBJECT COMMAND
+Palette object names can be used as command names. They support folowing 
+options:
+.TP 4
+\fIpaletteName\fB delete\fR -
+destroys palette object. 
+.TP 4
+\fIpaletteName\fB get\fI index\fR
+- return color for given index in palette. Color is returned as \#rrggbb,
+and can be used as color specification in Tk commands.
+.TP 4
+\fIpaletteName\fB list\fR
+- return list of all colors in palette. This list always contains 256
+elements. This list can be used as argument for \fBpalette set\fR command,
+to create same palette.
+.TP 4
+\fIpaletteName\fB print\fR
+- returns string, containing content of valid EPPL7 clr file, which can
+be used to reproduce this palette.
+.TP 4
+\fIpaletteName\fB set\fI index value\fR
+- changes contents of given entry to \fIvalue\fR. Value should be in form
+\#rrggbb. Other forms of colors, supported by Tk are not supported by
+palettes.
+.SH SEE ALSO
+.BR patterns (n), fgisRasterColorImage (n).
+
diff --git a/man/planchet.n b/man/planchet.n
new file mode 100644 (file)
index 0000000..3b92b8c
--- /dev/null
@@ -0,0 +1,535 @@
+'\" Stuff below is shamelessly borrowed from canvas(n) manual page, and 
+'\" therefore shares its copyright
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ie !"\\$3"" \{\
+.ta \\n()Au \\n()Bu
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$1"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 4c 8c 12c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+.TH planchet n 1.0 Fgis "user Tcl commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+planchet \- Create and manipulate planchet widgets
+.SH SYNOPSIS
+\fBplanchet\fI \fIpathName \fR?\fIoptions\fR?
+.SO
+\-background   \-insertwidth   \-state
+\-insertbackground     \-relief        \-tile
+\-cursor       \-insertborderwidth     \-selectbackground      \-takefocus
+\-highlightbackground  \-insertofftime \-selectborderwidth     \-xscrollcommand
+\-highlightcolor       \-insertontime  \-selectforeground      \-yscrollcommand
+.SE
+.PP
+\fBNote:\fR Standard optiosn \fb\-highlightthickness\fR and \fB\-bordewidth\fR
+are ignored by planchet, and set to 0. Therefore \fB\-relief\fR options have
+no effect.
+.SH "WIDGET-SPECIFIC OPTIONS"
+.OP \-coordformat coordFormat CoordFormat
+Specifies format string to display current map coordinates, if no projection
+defined. Defaults to "X=%0.8g Y=%0.8g"
+.OP \-orient orient Orient
+Specifies printing orientation for this planchet. May be either portrait
+or landscape. Defaults to landscape
+.OP \-lookwidth lookWidth LookWidth
+Wraplength of text in popup look window. Defaults to 200.
+.OP \-shiftfactor shiftFactor ShiftFactor
+Specifies share of window size to move on \fBshift\fR widget command.
+Defaults to 0.75
+.OP \-resizable resizable Resizable
+Specifies a boolean value that indicates whether or not should planchet
+adjust its width/height ratio, when coordinate limits are first defined.
+.OP \-rulerpos rulerPos RulerPos
+Indicates position of scale ruler in planchet. (its left end). Should be
+list of two coordinates in any form, acceptable by Tk. Positive values
+are measured from top and left and negative from lower and right side 
+of planchet
+.OP \-scalevar scaleVar Variable
+Specifies the name of variable. Current scale of map would be stored in
+this variable automatically upon each change of scale in form 1:denominator.
+If variable doesn't exist in global scope, it would be created.
+.OP \-statusline statusLine none
+Specifies name of label widget which would be used for displaying status
+information of planchet (i.e. current mouse pointer coordinates).
+Widget should exist before creating planchet or before passing it to
+planchet configure command.
+.OP \-legbox legBox none
+Specifies name of canvas widget which would display scrollable legend of 
+base layer. Note, that scrollable legend is not printed automatically by
+print command. All contents of this widget would be erased each time
+base layer changed in planchet.
+.OP \-zoombutton zoomButton none
+Specifies name of button, which is used to initiate zoom operation on
+canvas. (usially via \fBzoom\fR) widget command. Planchet controls its
+state, disabling it, if coordinate system is not defined. It should
+exist before it passed to planchet.
+.OP \-unzoombuttons unzoomButtons none
+Specifies list of buttons, which are used to perform various unzoom operations
+(like \fBunzoom\fR or \fBlimits default\fR widget commands). Planchet
+controls their state, disabling them if such operations are impossible.
+.OP \-shiftbuttons shiftButtons none
+Specifies list of four buttons for perform shift operation on planchet.
+Buttons are specified in following order  left(west) down(south) up(north) and
+right(west), the same way as vi cursor movement keys are situated on keyboard.
+.OP \-zoombutton zoomButton none
+Specifies name of button, which is used to initiate zoom operation on
+canvas. (usially via \fBzoom\fR) widget command. Planchet controls its
+state, disabling it, if coordinate system is not defined. It should
+exist before it passed to planchet.
+.OP \-unzoombuttons unzoomButtons none
+Specifies list of buttons, which are used to perform various unzoom operations
+(like \fBunzoom\fR or \fBlimits default\fR widget commands). Planchet
+controls their state, disabling them if such operations are impossible.
+.OP \-shiftbuttons shiftButtons none
+Specifies list of four buttons for perform shift operation on planchet.
+Buttons are specified in following order  left(west) down(south) up(north) and
+right(west), the same way as vi cursor movement keys are situated on keyboard.
+This buttons should be either all be specified or all be empty, in which case
+list of four empty elements should be passed. Planchet not only controls
+state of buttons, but also redefines their commands.
+.OP \-projection projection none
+Specifies Fgis projection object which is used to convert chartographic 
+coordinates of planchet into geographic (latitude and longitude) and vice versa.
+
+.PP
+In addition to these all options of \fBcanvas\fR widget are supported.
+.SH INTRODUCTION
+.PP
+The \fBplanchet\fR command creates a new window (given by the \fIpathName\fR
+argument and makes it into planchet widget.
+
+Additional options, described above, can be given to control its behavoir.
+Currently they could be specified only in command line, not in option database,
+but it shoudl change in future.
+
+\fBplanchet\fR command returns its \fIpathName\fR argument. At the time this
+command is invoked, there must not exist a window, named \fIpathName\fR,
+but \fIpathName\fR's parent must exist.
+\fBplanchet\fR command also creates new Tcl command named \fIpathName\fR
+which can be used to control widget.
+
+.PP
+ Planchet widget have all behavoir
+supported by Tk \fBcanvas\fR widget, but, in addition it could have 
+chartographic coordinate system and able to visualize and manipulate maps.
+
+.SH COORDINATE SYSTEM
+
+Planchet coordinate system is real-world coordinate system. Its coordinates
+should be in meters of earth surface, not in pixels, millimeters or other
+map sheet or screen-related units. It can be defined either explicitely
+via \fBlimits\fR widget command, or implicitely, when first map is shown
+in planchet.
+
+There are special commands which allow to recalculate from map (realword)
+coordinates to screen coordinates. Screen coordinate system of planchet is
+same as of canvas. 
+.SH LAYERS
+Planchet can visualize maps, which are represented as Fgis layer objects.
+There are two ways of display layer - as base layer or as ovelay.
+.PP
+Base layers are opaque, they are typically raster layers, shown by colors.
+There can be only one base layer in plachet in given time. If \fBlegbox\fR
+helper widget is defined, and legend for base layer is drawable, it would
+be displayed in this widget.
+Several layer types couldn't be displayed as base layers.
+
+.PP
+Overlay layers are transparent, although visible. There can be several 
+overlay layers in planchet at given time. Any layer can be displayed as
+overlay.
+.PP
+When first layer is displayed in planchet, with undefined coordinate system,
+coordinate system limits for planchet are got from limits of layer. If
+layer cannot provide this information, it causes an error.
+
+.SH HELPER WIDGETS
+
+Planchet can be accompanied with several other widgets, which are used
+to interact with user. If this widgets are passed to planchet via commandline
+options (or via widget \fBconfigure\fR) command, it can control them
+automatically and disable them, if corresponding action is impossible.
+See \fBOPTIONS ABOVE\fR.
+
+.SH SCALE INDICATION 
+
+There are two traditional ways of scale indication - numerical and graphical.
+As numerical indication, \fB\-scalevar\fR option of planchet widget allows
+to specfy Tcl global variable, which would always hold current value of map
+scale.
+.PP
+As graphical representation of scale,
+planchet can display scale ruler which shows how some realword distance
+is visible in planchet.
+
+.SH LOOK FEATURE
+
+Planchet allows to collect information from several layers in given point.
+By default it pops up window with this information on right button click.
+Set of layers which included in this information is called \fBlook list\fR.
+
+.SH "WIDGET COMMAND"
+.PP
+
+The \fBplanchet\fR command creates a new Tcl command whose name is
+\fIpathName\fR. This command can be used to invoke various operaitons on
+the widget. It has following general form:
+.CS
+\fIpathName option \fR?\fIarg arg ..\fR?
+.CE
+\fIOption\fR and the \fIarg\fRs
+determine the exact behavior of the command.
+Planchet supports all  widget commands, defined for \fBcanvas\fR widget
+and following special commands, specific to planchet:
+.TP
+\fIpathName \fBclear\fR
+Removes all layers from planchet, and from look list and unsets coordinate
+system
+.TP
+\fIpathName \fBcget\fI option\fR
+Returns value of specified configuration option. In addition to standard
+options and widget specific options, supports all options of canvas widget.
+Several internal variables can also be obtained this way, but it is dirty
+and undocumented hack.
+.TP
+\fIpathName \fBconfigure\fI option arg ?option arg ...?\fR
+Allows to change value of one or more options. 
+.TP
+\fIpathName \fBfit\fI x y\fR
+Returns 1 if point, given in real world coordinates is inside current
+planchet limits, and 0 otherwise.
+.TP
+\fIpathName \fBhide\fI pattern ?pattern...?\fR
+Removes all layers which matches pattern from planchet.
+.TP
+\fIpathName \fBlayers\fR ?\fIpattern\fR?
+Return list of all visible layers, either base or overlays, which match given
+pattern. By default - all layers.
+.TP
+\fIpathName \fBlimits\fR
+Used to control limits of realword coordinate system. Can have one of
+following form
+.RS
+.TP
+\fBlimits\fR 
+Without any arguments return list of four double values, representing real
+world coordinates of window sides. They are given in folowing order:
+.CS
+\fIXLeft YBottom XRight YTop
+.CE
+.TP
+\fBlimits \fIlist\fR
+.TP
+\fBlimits \fIxleft ybottom xright ytop\fR
+Given list of four double values or four double values as separate arguments,
+sets planchet limits for this value. If \fB\-resizable\fR option is true
+and no coordinate system was defined before, adjusts width/height ratio
+of planchet to reflect this ratio of given limits. Otherwise expands
+given limits to have same width/height ratio as widget.
+
+If directions of axes of given limits doesn't match those of currently
+defined coordinate system, silently reverts them. Therefore order
+of coordinates in insignificant, once coordinate system is defined.
+
+If coordinate system was defined, assumes that zooming operation is
+performed and stores old limits in zoom stack for subsequent unzoom
+operation. If scale of given limits is smaller, then
+of some limits in zoom stack, discards all elements with scale larger
+than given for unzoom operation shouldn't increase scale. Nevertheless
+initial limits are never discarded this way.
+.TP
+\fBlimits default\fR
+Clears zoom stack and restores coordinate limits to their initial values.
+.RE
+.TP
+\fIpathName \fBlook\fR
+Controls \fBLOOK FEATURE\fR of planchet. Can have one of following forms
+.RS
+.TP
+\fBlook add \fIlayer\fR
+adds layer to look list.
+.TP
+\fBlook list \fR?\fIpattern\fR?
+Returns list of layers in look list, which match pattern. By default all layers
+.TP
+\fBlook remove \fIpattern\fR
+removes layers which match pattern from look list
+.TP
+\fBlook remove all\fR
+clears look list entirely
+.TP
+\fBlook \fIx y \fR?\fB-titled|-list|-raw\fR?
+return list of information for all layers in look list at given point.
+If \fB-titled\fR option is specified, each element in list is formatted
+string. Otherwise it is two element list which first element - layer title,
+and second - layer value. \fB-raw\fR option returns only values, without
+layer title information. 
+
+Length of this list not neccesary matches length of look list, becouse if
+some layers are undefined in given point, they do not create list element.
+.RE
+.TP
+\fIpathName \fBmapx \fIx\fR
+.TP
+\fIpathName \fBmapy\fR
+Given screen coordinate in any form, acceptable by Tk, returns realword
+coordinate.
+.TP
+\fIpathName \fBprint\fR ?option arg ...?
+Wrapper around \fBpostscript\fR command. Uses default Fgis font mapping and
+print system, also widget default orientation. By default, send output
+to default Fgis printer using command, defined in fgis configuration file.
+
+Following options are supported:
+.RS
+\fB-colormode\fI mode\fR
+Same as \fBcolormode\fR option in canvas \fBpostscript\fR command.
+.TP
+.TP
+\fB-file\fI filename\fR
+Write postscript representation of planchet into given file, instead of
+piping it to print command.
+.TP
+\fB-fontmap \fIvariable\fR
+array used to map screen fonts to postscript fonts. See canvas \fBpostscript\fR
+command for more information.
+.TP
+\fB-printer \fIprintername\fR
+Overrides default printer, specified in fgis.rc file.
+.RE
+.TP
+\fIpathName \fBruler\fI ?on|off?\fR
+Controls scale ruler.
+.TP
+\fIpathName \fBscale\fR ?\fIdenominator\fR?
+With no arguments returns current scale denominator. If \fIdenominator\fR
+is given, adjust coordinate limits so that scale would be as specified and
+center point of widget would have same realworld coordinates as before.
+
+If any other arguments are specified, behaves as \fBcanvas\fR widget \fBscale\fR
+command.
+
+.TP
+\fIpathName \fBscrx \fIx\fR
+.TP
+\fIpathName \fBscry \fIy\fR
+Given realworld coordinate, returns screen coordinate in pixels.
+.TP
+\fIpathName \fBsetstatus\fR
+Displays message if \fB\-statusline\fR helper widget, if defined, otherwise
+does nothing. Can have one of two form:
+.RS
+.TP
+\fBsetstatus\fI message\fR
+displays message as specified
+.TP
+\fBsetstatus\fI x y\fR
+Displays given coordinates. If no projection defined, they would be displayed
+using Tcl \fBformat\fR command with value of \fB\-coordformat\fR option as
+first argument. Otherwise they would be displayed using \fBformat\fR object
+command of current projection.
+.RE
+.TP
+\fIpathName \fBshift \fIdirection\fR
+Changes current coordinate limits so that current view shifts in specified
+\fIdirection\fR by share of corresponding widget size, specified by 
+\fB-shiftfactor\fR option.
+.TP
+\fIpathName \fBshow \fIlayer \fR?\fB-base\fR|\fB-overlay\fR?
+Displays specified layer. If neither \fB-base\fR nor \fB-overlay\fR is specifed,
+shows layer as base if no base layer currently present and layer can be
+displayed as base. Otherwise displays it as overlay.
+.TP
+\fIpathName \fBunzoom\fR
+Pops last coordinate limits from zoom stack
+.TP
+\fIpathName \fBzoom\fR ?\fI x y\fR? x y\fR??
+Initiates interactive zoom operation. If no coordinates are specified,
+prompts user to pick both corners of rectangle to display. If one pair
+is specified, prompts only for second pair. With two pairs just converts
+values from canvas to realworld coordinates and performs \fBlimits\fR command
+on them.
+.CS
+\fIpathName \fBzoom cancel\fR
+.CE
+can be used to abort interactive zoom operation currently in progress.
+.CS
+\fIpathName \fBzoom cancel\fR
+.CE
+can be used to abort interactive zoom operation currently in progress.
+.SH SEE ALSO
+.BR layer (n)
+.SH BUGS
+No care taken to do something useful if interactive zoom operation is
+performed on two planchets simulateously.
+
+
+
+
diff --git a/man/projection.n b/man/projection.n
new file mode 100644 (file)
index 0000000..1a3b4ba
--- /dev/null
@@ -0,0 +1,85 @@
+
+.TH projection n 1.0 Fgis "user Tcl commands"
+
+.SH NAME
+projection \- Create and manipulate projection objects 
+
+.SH SYNOPSIS
+\fB projection \fItype\fR ?\fIparameters\fR?
+.PP
+
+
+.SH DESCRIPTION
+.PP
+
+This command creates projection object, used to recalculate geographic
+coordinates (latitude and longitude) into map projection coodrinates.
+.PP
+\fBprojection\fR command takes  list of options and
+returns name of newly created projection object. 
+Name of object can be used as Tcl command which have several subcommands
+(see \fBPROJECTION SUBCOMMANDS\fR below) used for manipulation
+of projections.
+
+.SH PROJECTION TYPES 
+
+Most important property of projection is projection type. fGIS supports
+following types of projections:
+
+\" list should be here
+
+.SH PROJECTION OPTIONS
+
+\" list should be here
+
+.SH PROJECTION SUBCOMMANDS
+.TP 8
+\fIprojName \fBforward\fI long lat\fR
+recieves two arguments - geographic longitude and latitude as degrees in
+decimal format and returs list of two double values representing map
+coordinates in meters.
+
+.TP 8
+\fIprojName \fBbackward\fI X Y \fR
+performs backword transformation - given map coordinates in meters
+returns longitude and latitude in decimal degrees,
+.TP 8
+\fIprojName \fBformat\fI X Y\fR ?\fB-format\fI formatString\fR
+Returns formatted representation of latitude and longitude. String
+can contain following escapes sequences:
+.RS
+.TP
+\fB%lt\fR  
+unsigned latitude in DDMMSS format
+.TP
+\fB%lg\fR
+unsigned longitude in DDMMSS format
+.TP
+\fB%-t\fR \fB%-g\fR
+optionally signed latitude and longitude in DDMMSS format
+.TP
+\fB%+t\fR \fB%+g\fR
+explicitely signed latitude and longitude in DDMMSS format
+.TP
+\fB%lG %lT %-G %-T %+G %+T\fR
+same as above, but in decimal fractions of degree
+.TP
+\fB%dl %dg\fR
+direction indicator - letters N and S for latitude and E and W for
+longitude (or some other national language values as defined in fgis.rc
+file).
+.RE
+If \fIformatString\fR omitted, default "%lt%dt %lg%dg" is used.
+.TP 8
+\fIprojName\fB dump\fR
+returns argumets for projection command used to create this projection
+object.
+.TP 8
+\fIprojName\fB delete\fR
+destroys projection object.
+
+.SH "SEE ALSO"
+
+.BR proj "(1), " pj_init "(3), " transform (1)
+
+
diff --git a/man/raster.n b/man/raster.n
new file mode 100644 (file)
index 0000000..353ac51
--- /dev/null
@@ -0,0 +1,326 @@
+.TH raster n 1.0 Fgis "developer Tcl commands"
+
+.SH NAME
+raster \- Create and manipulate raster object 
+
+.SH SYNOPSIS
+\fB raster \fIfilename\fR ?\fIoptions\fR?
+
+.SH DESCRIPTION
+.PP
+This command allows to create raster objects. Raster objects are more low-level
+concept than fGIS \fBlayers\fR. They directly correspond to raster files
+in EPPL7 format. Their values are always unsigned short integer. 
+They even make cell size visible to user. This command returns name of
+raster object which is used for manipulating this object. By default
+it requires existing raster file without reclass table. 
+
+Raster files are objects which holds information of certain integer spatial
+variable in given rectangular area. Value is stored with certain granulariry.
+Minimal square, which can be addressed as separate unit, is named cell.
+Of course, you can specify coordinates with any precision, but while they are
+in same cell, same value would be returned. Moreover, when you edit raster,
+you can change values only on per cell basis.
+
+Raster file is always rectangular, but spatial variable can be defined on
+any arbitrary area. So, special value is reserved for "undefined" areas of
+raster. It is named \fBoffsite\fR value. Typically you can read raster it
+any coordinates, but if no information is provided for this area, offsite
+would be returned. 
+
+There are certain limitation on raster files - file cannot contain more than
+32767 cells per row or per column. Possible values of raster should be in
+range 0\-65535. Rows and columns of cells can be numbered starting from
+any integer, provided that no row or column in file has number out of range
+-32767- 32767. fGIS, however never relies on column numbers. They are supported
+only for compatibility with EPPL7. 
+
+Raster objects differs from raster files in the way that they include
+\fBreclass table\fR. This allows to store information about several
+spatial variables in one file, provided that total count of value combination
+doesn't exceed raster file limit. Reclass table defines correspondence
+between file classes (values) and values, returned by raster object.
+It can be defined by two ways - using special syntax like in EPPL7 RECLASS
+command (see RECLASS SYNTAX below) or using Tcl list, each element of which
+is pair of values, first base, then reclassed.
+
+When raster objects are accessed or created via GIS operations, user may not
+be aware about underlying raster file level. But when objects are created
+by interative editing, certain properties of raster (i.e. cell size) should
+be specified.
+
+Raster objects behave like other fGIS objects - layers, legends, palettes etc.
+Once object is created, new Tcl command with same name is created. This
+command is used to access and modify rasters.
+
+.SH OPTIONS
+.TP 4
+\fB-reclass \fIstatements\fR
+-specifies reclass table for created raster object. \fIstatements\fR is
+string, containing set of reclass statements. See \fBRECLASS SYNTAX\fR below
+for details
+.TP 4
+\fB-table \fIlist\fR 
+-specifies reclass table in form of Tcl list. Each
+element of this list should be list of two integers, first of them representing
+value in raster file, and second - representing value which would be value
+of new raster object.
+.TP 4
+\fB-new\fR 
+- specifies that new raster file should be created instead of
+opening old. This option should be specified immediately after file name
+and followed by several other options, defining properties of new raster.
+All subsequent options are applicable only if \fB-new\fR is specified.
+.TP 4
+\fB-like\fI rasterObject\fR 
+- specifies that all important properties 
+should be copied from existing raster object.
+.TP 4
+\fB-width\fI integer\fR 
+- specifies how many cells should appear in each
+row. Cannot be used together with \fB-like\fR
+.TP 4
+\fB-height\fIinteger\fR 
+- specifies how many cells should be in each column.
+.TP 4
+\fB-offsite\fIinteger\fR
+ - specifies which value would be used as "no data"
+value. Default is 65535 for 16-bit files and 255 for 8-bit. Value -1 can
+be specified for 8-bit files. It means that all classes are onsite. For
+16-bit files it is equivalent to 65535.
+.TP 4
+\fB-8bit\fR - specifies that only one byte should be used for storing
+values of raster. This limits value range to 0-255, slightly decreases file
+size (usially much less than two times) and makes file compatible with
+EPPL7 ver. 2.1.
+.TP 4
+\fB-limits\fI{x1 y1 x2 y2}\fR 
+- Allows to specify list of four double values,
+determinig map coordinates of file.
+.TP 4
+\fB-cell\fI value\fR - specifies size of cell. In conjunction with \fB-limits\fR
+it gives more convinient way to create new raster, becouse limits defines 
+area of interest and cell size - accuracy of map.
+
+.SH OBJECT COMMAND
+\fBraster\fR command creates new Tcl command with same name as raster object,
+which can be used to manipulate this object. 
+
+\fIrasterName\fB box\fIvalue x1 y1 x2 y2\fR -
+fills rectangular region with given value. Raster should be opened in
+read-write mode (either by \fB-new\fI option of object command or by
+\fBload\fR object command). Returns list of four double values, specifying
+region actually affected by command. (Can be less that specified region,
+if it exceeds raster boundary). Value is class of base raster file, not
+reclassed value.
+
+.TP 4
+\fIrasterName\fB bpp\fR - returns size of data in this raster file
+(8 for 8-bit and 16 for 16 bit rasters).
+.TP 4
+\fIrasterName\fB cache \fR?\fInew size\fR?
+- controls size of cache. If raster file is accessed from disk (default
+read only mode) setting sufficient cache can improve performance of operations,
+which require nonsequentual access, like \fBtransect\fR.
+.TP 4
+\fIrasterName \fBcell\fR ?\fB-area\fR?
+- returns parameters of cell. By default, returns cell width in map 
+coordinates, which should be meters, and with \fB-area\fI flag returns
+cell area in current units (see \fBunit\fR object command).
+.TP 4
+\fIrasterName \fBcelllimit\fR
+- returns list of four intergers, representig start and end numbers of cells
+in order \fIfirst column\fR, \fIlast row\fR, \fIlast column\fB, \fIfirst row\fR.
+(Why this order? X direction of cell numbers is same as of coordinates
+ (usially), and Y coodinates usially go from bottom to top, while cells - from
+top to bottom. So, order of values is same as order of values in \fBlimits\fI
+object command.
+.TP 4
+\fIrasterName \fBclasses \fIvalue\fR
+- returns list of base file classes which are mapped to specified value of
+this raster object.
+.TP 4
+\fIrasterName \fBcircle\fI value x y radius \fR?\fB-cells\fR?
+- fills circulare region in read-write raster with given value. If \fB-cells\fR,flag is given, radius is assumed to be in raster cells. Otherwise it is assumed
+to be in coordinate units. Returns list of coordinates, specifying actualy
+affected region.
+.TP 4
+\fIrasterName \fBcol\fI x\fR
+- returns cell number corresponding to given X coordinate. Returns error, if
+coordinate is out of file boundaries.
+.TP 4
+\fIrasterName \fBcomment\fR ?\fIstring\fR? 
+- returns (or modifies) comment, stored in file header. Comment length is
+limited by 32 symbols.
+.TP 4
+\fIrasterName \fBcount\fR ?\fBoptions\fR?
+- performs various area-calculating operation
+General formats folows:
+.TP 8 
+\fIrasterName \fBcount\fR ?\fB--\fR? \fI varname \fR?\fIregion specification\fR?
+fills dynamic array \fIvarname\fR indexed by raster classes by areas of these
+classes in given region. 
+.TP 8
+\fIrasterName \fBcount -classes \fIlist \fR?\fIregion specification\fR?
+returns area of given classes within given region.
+
+Region specification defaults to whole file. Other possible formats are:
+.TP 8
+\fB-box\fI x1 y1 x2 y2\fR 
+- within given rectangular area
+.TP 8
+\fB-polygon\fI x y x y ...\fR
+- within polygon, given by set of coordinate pairs
+.TP 8
+\fB-radius\fI distance x y ...\fR
+within given distance of any of given points.
+.TP 8
+\fB-mask\fI rasterObject list\fR
+in areas where value of another rasterObject is in given list.
+
+.TP 4
+\fIrasterName \fBdelete\fR
+- destroys raster object. If raster was in readwrite mode, all unsaved changes
+are lost.
+.TP 4
+\fIrasterName \fBextents\fI value\fR
+- returns list of four coordinates, within those all values of given class
+are contained.
+.TP 4
+\fIrasterName \fBfilename\fR
+- returns name of file, corresponding to this raster object.
+.TP 4
+\fIrasterName \fBfill\fI value x y \fR?\fB-stop\fR?\fI value\fR
+- fills area, starting with given coordinates with value. By default,
+stops on encounter of any value other than in given point. If \fB-stop\fR
+option is specified, stops only when encountering given value. Returns
+list of coordinates, specifying actually affected region.
+.TP 4
+\fIrasterName \fBframe\fI value  x1 y1 x2 y2\fR ?\fB-width\fI cells\fR?
+- a rectangle with given value, not changing inside area. By default
+this rectangle is 1 cell wide.
+.TP 4
+\fIrasterName \fBget\fI x y \fR?\fB-base\fR?
+Returns value of raster in given point. By default returns reclassed value,
+but if \fB-base\fR is specified, returns class of raster file.
+.TP 4
+\fIrasterName \fBlimits\fR
+Returns list of four doubles, specifying physical limits of raster file, in
+order \fIXLeft\fR, \fIYBottom\fR, \fIXRight\fR, \fIYTop\fR.
+.TP 4
+\fIrasterName \fBline\fI value x y x y .... \fR?\fB-width \fIcells\fR?
+draws a line with given value. By default one-cell wide. Returns boundaries
+of region affected.
+.TP 4
+\fIrasterName \fBload\fR
+Loads raster file into memory, changing it from readonly to readwrite mode,
+and enabling all editing operation. (\fB-new\fR option of \fBraster\fR command
+performs \fBload\fR implicitely). 
+.TP 4
+\fIrasterName \fBmax\fR
+-returns maximal value of raster object.
+.TP 4
+\fIrasterName \fBmin\fR
+- returns minimal value of raster object.
+.TP 4
+\fIrasterName \fBoffsite\fR ?\fIvalue\fR?
+- returns offsite value for raster object, or modifies it.
+.TP 4
+\fIrasterName \fBpolygon\fI value x y x y ...\fR
+- fills given polygon of given value. Returns boundaries of region affected.
+.TP 4
+\fIrasterName \fBput\fI value x y\fR
+Changes value of individual cell. Returns nothing.
+.TP 4
+\fIrasterName \fBreclass\fR ?\fIoption\fR? ?\fIarg\fR?
+- manipulates reclass table. Without any options, returns reclass table as
+Tcl list.
+.TP 8
+\fIrasterName \fBreclass -statements\fR
+option returns reclass table in form of reclass statements. (see \fB RECLASS SYNTAX\fR below).
+.TP 8
+\fIrasterName \fBreclass -table\fI list\fR
+modifies current reclass using given Tcl list. Values for classes given
+in this list would be changed as specified, all other remains unchanged.
+.TP 8
+\fIrasterName \fBreclass \fIstatements\fR
+modifies reclass using specified reclass statements. As \fB-table\fR options,
+applies statements to base classes and leaves all nonspecified classes as is.
+.TP 8
+\fIrasterName \fBreclass -clear\fR
+clears all changes in reclass table and makes reclassed classes equial to
+base classes.
+.TP 4
+\fIrasterName \fBrow\fI y\fR
+return cell number, correspondign to given Y coordinate. Raises error, if
+coodinnate is outside file limits.
+.TP 4
+\fIrasterName \fBsave\fR ?\fIoptions\fR?
+- saves raster file. By default, if raster is in readwrite mode, saves
+changes to current filename.
+.TP 8 
+\fIrasterName \fBsave -as\fI filename\fR
+- saves raster, open for editing into other file, and makes this file
+current file of this raster object.
+.TP 8
+\fB-backup\fR 
+option can be specified
+for both \fBsave\fR and \fBsave -as \fRcommands. It makes raster object to
+keep old version of file with suffix \fI.bak\fR appended to name.
+.TP 8
+\fIrasterName \fBsave -to\fI filename\fR ?\fB-8bit\fR?
+allows to write raster object into raster file. Reclass table is applied
+to this operation, so new file would have base classes like classes of
+raster object, rather than classes of its base file.
+
+If \fB-8bit\fR switch is specified, resulting raster will be forced to 8-bit
+by discarding high-order byte, even if max value or offsite are outside
+0-255 range. (in latter case offsite would be set to 65535).
+.TP 4
+\fIrasterName \fBshift \fI dx dy\fR
+changes origin of cell (row/column) numbers. This is required for certain
+command of DOS version of EPPL7, although fGIS always uses map (alternative)
+coordinates)
+.TP 4
+\fIrasterName \fBtransect\fR ?\fB-count\fI varname\fR? \fIx y x y ...\fR
+by default, return list consisting of pairs {value width} along the given line.
+If \fB-count\fR is specified, fills dynamic array \fIvarname\fR, indexed
+by classes, by total widthes of given value along this line.
+.TP 4
+\fIrasterName \fBunused\fR
+returns value which is never encountered in this raster.
+.TP 4
+\fIrasterName \fBunit\fR ?\fInew-unit\fR?
+- returns (or changes) area unit of this raster Unit can be one of
+following: \fBundefined\fR,\fBft\fR.\fBm\fR,\fBkm\fR,\fBmile\fR,\fBha\fR,\fBacre\fR. All subsequent count operations would return result in given units. \fBNote:\fR map coordinates are always in meters.
+.TP 4
+\fIrasterName \fBxleft\fR ?\fInew value\fR?
+- returns (or modifies) left boundary coordinate.\fBNote:\fR it simply modifies
+value, without appropriate changes in other limits or cell area value. 
+.TP 4
+\fIrasterName \fBxright\fR ?\fInew value\fR?
+- returns (or modifies) right boundary coordinate. 
+.TP 4
+\fIrasterName \fBybottom\fR ?\fInew value\fR?
+- returns (or modifies) bottom boundary coordinate. 
+.TP 4
+\fIrasterName \fBytop\fR ?\fInew value\fR?
+- returns (or modifies) left boundary coordinate. 
+.SH RECLASS SYNTAX
+
+Syntax of reclass syntax is inherited from EPPL7. General form of reclass
+statement is line, terminated by newline (\fBNote:\fR trailing newline is
+obligatory), which consist of new value and list of old (base) values. New
+value separated from list by equal sign. List of old values can contain
+individual values and ranges, which are two values, separated by colon.
+
+.TP 4
+Example
+1=1:10 20
+.PP
+means, that all values from one to ten and value 20 should be reclassed into
+1.
+
+Set of statements can contain arbitrary number of lines, same value can occur
+on left side of several lines. If some value occur on right side more than
+once, last occurence have precedence.
diff --git a/man/reclass.1 b/man/reclass.1
new file mode 100644 (file)
index 0000000..a07ac59
--- /dev/null
@@ -0,0 +1,92 @@
+.TH RECLASS 1 "Version 1.0" "Environmental planning utilities" "EPU User manual".SH NAME
+reclass1 \- Change classes of given EPPL7 data file
+.SH SYNOPSIS
+.B reclass1 [
+.I-v
+] [
+.I-f 
+reclass_file] [
+.I -o
+output_file] file
+.SH DESCRIPTION
+Applies given set of reclass statements to 
+.B epp
+file. Reclass statements have simular syntax to DOS version of EPPL7 and
+may be read from 
+.I stdin
+(both from terminal or pipe) and from file.
+.PP
+By default, creates file named
+.I reclass.out.epp
+in current directory, but this behavoir can be overriden by 
+.I -o
+option.
+.PP
+This version can perform only
+.B one-way
+reclass.
+For multy-file reclass use
+.BR intable (1)
+instead.
+.PP
+Output file is created as 16-bit and if after reclass it would contain
+only classes less than 255, it would be converted into 8-bit.
+.PP
+If offsite value of old file appears in right side of any reclass statement,
+offsite value of new file would be from left side of this statement.
+
+
+
+.SH OPTIONS
+.TP 8
+.B --help
+\- display brief usage message and exit successifully
+.TP 8
+.B --version
+\- display version information and exit successifully
+.TP 8
+.B -v
+\- verbose. Display number of rows processed during reclass.
+.TP 8
+.BR -f " reclass_file"
+\- read reclass statements from given file, instead of 
+.B stdin
+.TP 8
+.BR -o " output_file"
+\- write result into given file, instead of 
+.B reclass.out.epp.
+Suffix .epp would be substituted, if absent.
+
+.SH RECLASS STATEMENT SYNTAX
+
+Set of reclass statements consists of zero or more lines,
+each of which has following structure:
+.PP
+new_class
+.B =
+list of old classes
+.PP
+
+New class is number in range 0-65535.
+List of old classes is space separated list of classes (numbers)
+and ranges. Range is two numbers, separated by colon. First of them
+must be less then second, or this range would have no effect.
+.PP
+If one old class occurs in several statements, only last occurence
+would take effect, so it is possible to write:
+.PP
+1=1:255
+.PP
+2=2
+.PP
+3=12
+.PP
+to reclass all classes between 1 and 255, exept 2 and 12 to 1 and reclass
+12 to 3.
+
+.SH "SEE ALSO"
+.BR eheader (1), cluster (1), rescale (1), outtab (1), intable (1)
+
+.SH "AUTHOR"
+
+Victor B. Wagner, SoftWeyr.
diff --git a/man/window.1 b/man/window.1
new file mode 100644 (file)
index 0000000..2885ea5
--- /dev/null
@@ -0,0 +1,47 @@
+.TH WINDOW 1 "Version 1.0" "EPU" "EPU user manual"
+.SH NAME
+window \- cuts a portion of epp file
+.SH SYNOPSIS
+.B window 
+[-a%] [-o output_file]  input_file fr lr fc lc 
+.SH DESCRIPTION
+
+Window creates new 
+.IR epp -file
+with given limits. If new limits exceeds limits of old file, this areas
+would be filled by 
+.I offsite 
+value.
+.PP
+By default limits are given in rows/columns, but with 
+.I -a
+option you may use alternate coordinates.
+.PP 
+Output file would always be properly aligned with input.
+.SH OPTIONS
+.TP 8
+.B --help
+displays brief usage information.
+.TP 8
+.B --version
+displays version number
+.TP 8
+.B -%
+Displays percentage of processed lines in file.
+.TP 8
+.BI -o " file " 
+gives the name for output file. Defaults to
+.I window.out.epp
+.TP 8
+.B -a 
+specifies that limits are given in alternate coordinates.
+.SH SEE ALSO
+.BR mosaic (1), eheader (1)
+
+.SH AUTHOR
+
+Victor B. Wagner <vitus@agropc.msk.su>
+
+.SH BUGS
+
+???
diff --git a/pkgIndex.tcl b/pkgIndex.tcl
new file mode 100644 (file)
index 0000000..8284669
--- /dev/null
@@ -0,0 +1 @@
+package ifneeded Fgis 1.0 "package require Tk; [list load [file join $dir fgis.so] Fgis]"
diff --git a/symbols/alpha10.sym b/symbols/alpha10.sym
new file mode 100644 (file)
index 0000000..2b2cde2
--- /dev/null
@@ -0,0 +1,148 @@
+-10 -10 79/11/07.ALPHANUMERIC NOT MODIFIED WITH TONES\r
+  1 0018003C00660066007E007E006600E700000000\r
+  2 00FC007E0066007C00660066007E00FC00000000\r
+  3 003C007E0067006000600067007E003C00000000\r
+  4 00FC007E0066006600660066007E00FC00000000\r
+  5 00FE007E0062007800780062007E00FE00000000\r
+  6 00FE007E0062007800780060006000F000000000\r
+  7 003C007E00670060006F0066007E003C00000000\r
+  8 00E700660066007E007E0066006600E700000000\r
+  9 003C001800180018001800180018003C00000000\r
+ 10 000F00060006000600060066007E003C00000000\r
+ 11 00E70066006C0078007C0066006600E700000000\r
+ 12 00F000600060006000600062007E00FE00000000\r
+ 13 01C700EE00FE00BA00D600C600C601C700000000\r
+ 14 00C700660076007E007E006E006600E300000000\r
+ 15 003C007E0066006600660066007E003C00000000\r
+ 16 00FC007E00660066007E007C006000F000000000\r
+ 17 003C007E006600660066006C007E003600000000\r
+ 18 00FC007E00660066007C007E006600E700000000\r
+ 19 003C007E00620078001E0046007E003C00000000\r
+ 20 00FF00FF00990018001800180018003C00000000\r
+ 21 00E700660066006600660066007E003C00000000\r
+ 22 00E7006600660066003C003C0018001800000000\r
+ 23 01C700C600D600D600FE007C006C006C00000000\r
+ 24 00E700660024001800180024006600E700000000\r
+ 25 00E70066007E003C001800180018003C00000000\r
+ 26 00FE00FE008C00180030006200FE00FE00000000\r
+ 27 0018003C0066006600660066003C001800000000\r
+ 28 0018003800380018001800180018003C00000000\r
+ 29 003C007E00660006003C0060007E007E00000000\r
+ 30 003C007E0066000C000E0066007E003C00000000\r
+ 31 000C001C003C006400E400FC000C001E00000000\r
+ 32 007E007E0060007C00060066007E003C00000000\r
+ 33 003C007E0060007C00660066007E003C00000000\r
+ 34 007E007E0046000C000C000C000C000C00000000\r
+ 35 003C007E0066003C00660066007E003C00000000\r
+ 36 003C007E00660066003E0006007E003C00000000\r
+ 37 000000180018007E007E00180018000000000000\r
+ 38 0000000000000000007E007E0000000000000000\r
+ 39 000000920054003800EE00380054009200000000\r
+ 40 00060006000C0018001800300060006000000000\r
+ 41 000C001C0038003000300038001C000C00000000\r
+ 42 00300038001C000C000C001C0038003000000000\r
+ 43 0008001C002A0028001C000A002A001C00080000\r
+ 44 0000007E007E00000000007E007E000000000000\r
+ 46 00000000000000000000001C0014001C000C0000\r
+ 47 0000000000000000000000000018001800000000\r
+ 48 01FF01FF01FF01FF01FF01FF01FF01FF01FF0000\r
+ 49 007C007C0060006000600060007C007C00000000\r
+ 50 007C007C000C000C000C000C007C007C00000000\r
+ 51 0000001800180000000000180018000000000000\r
+ 52 0004007E007E00080010007E007E002000000000\r
+ 53 00000008000C007E006C00080000000000000000\r
+ 54 000000000000000003FF03FF0000000000000000\r
+ 55 0030003000300030003000300030003000300030\r
+ 56 0008001C003E0008000800080008000000000000\r
+ 57 0008000800080008003E001C0008000000000000\r
+ 58 00000004000C001800300018000C000400000000\r
+ 59 0000002000300018000C00180030002000000000\r
+ 60 0030003000300030003F003F0000000000000000\r
+ 61 003000300030003003F003F00000000000000000\r
+ 62 0000000000000000003F003F0030003000300030\r
+ 63 000000000000000003F003F00030003000300030\r
+ 64 0000000000200050008800440028001000000000\r
+ 65 0000000000780084010201020084007800000000\r
+ 66 0000003000480084010201020084004800300000\r
+ 67 00000030004800B4014A014A00B4004800300000\r
+ 68 0000003000FC00AC01C6018E00D400FC00300000\r
+ 69 000000FC00FC00CC01A6019600CC00FC00FC0000\r
+ 70 000000FC00FC00FC01FE01FE00FC00FC00FC0000\r
+ 71 0000000000100000008000040000002000000000\r
+ 72 0000013200000000013201320000000001320000\r
+ 73 000001FE01FE018601B601B6018601FE01FE0000\r
+ 74 0092016D016D0092016D016D0092016D016D0000\r
+ 75 01FF0000000001FF0000000001FF000000000000\r
+ 76 0000000000440000000000000044000000000000\r
+ 77 01FF01FF018301BB01AB01BB018301FF01FF0000\r
+ 78 01FF01FF0193019301FF0193019301FF01FF0000\r
+ 79 011100AA004400000000011100AA004400000000\r
+ 80 0000000C00E00000000F000000600000001C0000\r
+ 81 01C701C701C700380038003801C701C701C70000\r
+ 82 0018003C0066006600660066003C001800000000\r
+ 83 0000000000000010000000000000000000000000\r
+ 84 0000000000000030004800480030000000000000\r
+ 85 0010000000000028008200280000000000100000\r
+ 86 018300100000003800AA00380000001001830000\r
+ 87 018300100010003800EE00380010001001830000\r
+ 88 019300100000003801FF00380000001001930000\r
+ 89 019301930010003801FF00380010019301930000\r
+ 90 01FF01FF0111013901FF0139011101FF01FF0000\r
+ 91 01FF01FF019301BB01FF01BB019301FF01FF0000\r
+ 92 021F03EF03FF02FF03FE019B03FF03FF02FE01BF\r
+ 93 03FF02FD03FF03FF03EF03FF03FF03FF02FD03FF\r
+ 94 003F00110011001101FF01FF006000600060007C\r
+ 95 0048004800480FFF004800480FFF004800480048\r
+ 96 007800CC01860303023102310303018600CC0078\r
+ 97 00E700A600EC000800100037006500E700000000\r
+ 98 0000000000240000000000240000000000000000\r
+ 99 000000100010003800EE00380010001000000000\r
+100 0038004400820101010100010082004400380000\r
+101 0038004400820129010101290082004400380000\r
+102 003800540082011101AB01110082005400380000\r
+103 0038004400D601290155012900D6004400380000\r
+104 0038005400EE015501BB015500EE005400380000\r
+105 0038007C00FE01FF01FF01FF00FE007C00380000\r
+106 002C00D200A6004C00D200340030003000780000\r
+107 00B8007C00F800FC00FE007800B0003000780000\r
+108 0000000000000000003000300000000000000000\r
+109 02AA0155015502AA0155015502AA0155015502AA\r
+110 01FF000001FF000001FF000001FF000001FF0000\r
+111 011100AA004400000000011100AA004400000000\r
+112 00C1000C00600100001C00C00006017100000000\r
+113 001000A800C400EE0129012901E9010901FF0000\r
+114 0000000000440000000000000000000000000000\r
+115 0101008200440028001000AA01C701EF01C70000\r
+116 0000008200000028000000280000008200000000\r
+117 01EF0129012901EF000001EF0129012901EF0000\r
+118 000002AA00000155000002AA00000155000002AA\r
+119 0092024900920249009202490092024900920249\r
+120 015502AA015502AA015502AA015502AA015502AA\r
+121 03BB02EE03BB02FE03FB02FE03FB02FE03BB02EE\r
+122 03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF\r
+123 0000010200000000001000000000000001020000\r
+124 0000000000000020005000A80154000000000000\r
+125 010000000000000000000000000A000201000000\r
+126 000000200020002001FE00200020002000200000\r
+127 0000000000000030007800FC01FE000000000000\r
+128 0140004000410190000000270002000000400200\r
+129 00000000000000F800F800F800F800F800000000\r
+130 000000300030003001FE01FE0030003000300030\r
+131 0229004A0100000601240025001B011100080002\r
+132 02010302018600CC00780030007800CC01860303\r
+133 000001FE01FE003000300030003001FE01FE0000\r
+134 0053004C034000CB014603040223020202590090\r
+135 0201013200B4007801FE01FE007800B401320201\r
+136 00200020002000AA01FE03FE03FE01FC007C007C\r
+137 0293023A00880058037A00EE0382018A00E401A6\r
+138 01FE02CD034B0387020102010387034B02CD01FE\r
+139 000001FE01FE01FE01CE01CE01FE01FE01FE0000\r
+140 034A02EB00C103D6013B018C039701E3027A0231\r
+141 01FE00FD02790333038703CF03870333027900FC\r
+142 03FF03CF03CF03CF0201020103CF03CF03CF03CF\r
+143 01B5019302CF02BD01FC03F7001D03BE034F0361\r
+144 03FF03FF03FF0307030703070307030703FF03FF\r
+145 03FF03FF0303037B037B037B037B030303FF03FF\r
+146 03EE03DE02BF03BB017F037E021A02FF00F102FF\r
+147 03FF03DF03DF03DF020103DF03DF03DF03DF03FF\r
+148 03FF03FF03FF03DF03AF035702AB03FF03FF03FF\r
diff --git a/symbols/alpha6.sym b/symbols/alpha6.sym
new file mode 100644 (file)
index 0000000..fdb01e9
--- /dev/null
@@ -0,0 +1,81 @@
+-6 -6 79/11/07.ALPHANUMMERICS (MODIFIED) WITH TONES\r
+  1  00C 012 01E 012 012 000\r
+  2  01C 012 01C 012 01C 000\r
+  3  00E 010 010 010 00E 000\r
+  4  01C 012 012 012 01C 000\r
+  5  01E 010 01C 010 01E 000\r
+  6  01E 010 01C 010 010 000\r
+  7  00E 010 016 012 00E 000\r
+  8  012 012 01E 012 012 000\r
+  9  00E 004 004 004 00E 000\r
+ 10  00E 004 004 014 008 000\r
+ 11  012 014 018 014 012 000\r
+ 12  010 010 010 010 01E 000\r
+ 13  011 01B 015 011 011 000\r
+ 14  011 019 015 013 011 000\r
+ 15  00C 012 012 012 00C 000\r
+ 16  01C 012 01C 010 010 000\r
+ 17  00C 012 012 014 00A 000\r
+ 18  01C 012 01C 012 012 000\r
+ 19  00E 010 00C 002 01C 000\r
+ 20  01F 004 004 004 004 000\r
+ 21  012 012 012 012 00C 000\r
+ 22  011 011 011 00A 004 000\r
+ 23  011 011 015 015 00A 000\r
+ 24  011 00A 004 00A 011 000\r
+ 25  011 00A 004 004 004 000\r
+ 26  01F 002 004 008 01F 000\r
+ 27  00E 00A 00A 00A 00E 000\r
+ 28  004 00C 004 004 00E 000\r
+ 29  00C 002 00C 008 00E 000\r
+ 30  00E 002 004 002 00E 000\r
+ 31  00A 00A 00E 002 002 000\r
+ 32  00E 008 00C 002 00C 000\r
+ 33  008 008 00E 00A 00E 000\r
+ 34  00E 002 002 002 002 000\r
+ 35  00E 00A 00E 00A 00E 000\r
+ 36  00E 00A 00E 002 002 000\r
+ 37  004 004 01F 004 004 000\r
+ 38  000 000 01E 000 000 000\r
+ 39  004 00A 004 00A 004 000\r
+ 40  002 002 004 008 008 000\r
+ 41  002 004 004 004 002 000\r
+ 42  008 004 004 004 008 000\r
+ 43  00F 014 00E 005 01E 000\r
+ 44  000 01E 000 01E 000 000\r
+ 46  000 000 000 00C 00C 004\r
+ 47  000 000 000 00C 00C 000\r
+ 48  03F 03F 03F 03F 03F 03F\r
+ 49  00E 008 008 008 00E 000\r
+ 50  01C 004 004 004 01C 000\r
+ 51  00C 00C 000 00C 00C 000\r
+ 52  002 01F 004 01F 008 000\r
+ 53  007 007 007 007 007 007\r
+ 54  007 007 00F 00F 007 007\r
+ 55  000 000 004 006 007 007\r
+ 56  004 00E 015 004 004 000\r
+ 57  000 000 000 03F 03F 03F\r
+ 58  000 000 000 020 038 03E\r
+ 59  038 030 020 000 000 000\r
+ 60  03F 03F 03F 03E 03C 038\r
+ 61  03F 03C 038 030 030 030\r
+ 62  030 030 030 038 03E 03F\r
+ 63  020 030 038 03C 03E 03E\r
+ 64  00D 013 00A 014 013 000\r
+ 65  00A 00A 00A 00A 000 000\r
+ 66  000 015 00A 000 000 000\r
+ 67  000 003 000 00C 000 000\r
+ 68  011 015 01F 015 011 000\r
+ 69  01F 015 01B 015 01F 000\r
+ 70  000 00A 000 00A 000 000\r
+ 71  01F 011 015 011 01F 000\r
+ 72  01F 01F 01F 01F 01F 000\r
+ 73  000 03F 000 000 03F 000\r
+ 74  012 012 012 012 012 012\r
+ 75  008 010 020 001 002 004\r
+ 76  004 002 001 020 010 008\r
+ 77  03F 03F 03F 03F 03F 03F\r
+ 78  02A 015 02A 015 02A 015\r
+ 79  02A 000 015 000 02A 000\r
+ 97  009 002 004 009 000 000\r
+ 98  000 00A 000 00A 000 000\r
diff --git a/symbols/digit25.sym b/symbols/digit25.sym
new file mode 100644 (file)
index 0000000..78acbc6
--- /dev/null
@@ -0,0 +1,405 @@
+-25 -25 79/11/27. DOUBLE DIGIT NUMBERS IN BOXES\r
+  1 01FFFFFF010000010100000101000001010000010100000101000061010000E1\r
+  1 010001E1010001E1010000610100006101000061010000610100006101000061\r
+  1 01000061010001F1010001F10100000101000001010000010100000101000001\r
+  1 01FFFFFF\r
+  2 01FFFFFF0100000101000001010000010100000101000001010001F9010003FD\r
+  2 0100038D0100030D0100030D0100001D0100003D01000079010001E1010003C1\r
+  2 01000381010003FD010003FD0100000101000001010000010100000101000001\r
+  2 01FFFFFF\r
+  3 01FFFFFF0100000101000001010000010100000101000001010001F9010003FD\r
+  3 0100030D0100030D0100001D0100007901000071010000790100001D0100030D\r
+  3 0100030D010003FD010000F90100000101000001010000010100000101000001\r
+  3 01FFFFFF\r
+  4 01FFFFFF01000001010000010100000101000001010000010100001D0100003D\r
+  4 0100006D010000CD0100018D0100010D010003FD010003FD0100000D0100000D\r
+  4 0100000D0100000D0100000D0100000101000001010000010100000101000001\r
+  4 01FFFFFF\r
+  5 01FFFFFF0100000101000001010000010100000101000001010003FD010003FD\r
+  5 0100030D0100030101000371010003F90100030D0100000D0100000D0100030D\r
+  5 0100031D010001F9010000F10100000101000001010000010100000101000001\r
+  5 01FFFFFF\r
+  6 01FFFFFF0100000101000001010000010100000101000001010000F9010001FD\r
+  6 0100038D0100030D0100030101000371010003F90100039D0100030D0100030D\r
+  6 0100030D010003FD010001F90100000101000001010000010100000101000001\r
+  6 01FFFFFF\r
+  7 01FFFFFF0100000101000001010000010100000101000001010003FD010003FD\r
+  7 0100030D0100001901000019010000310100006101000061010000C1010000C1\r
+  7 0100018101000181010001810100000101000001010000010100000101000001\r
+  7 01FFFFFF\r
+  8 01FFFFFF0100000101000001010000010100000101000001010001F9010003FD\r
+  8 0100030D0100030D0100030D010001F9010000F1010001990100030D0100030D\r
+  8 0100030D010003FD010001F90100000101000001010000010100000101000001\r
+  8 01FFFFFF\r
+  9 01FFFFFF0100000101000001010000010100000101000001010001F9010003FD\r
+  9 0100030D0100030D0100030D0100039D010001FD010000ED0100000D0100000D\r
+  9 0100030D010003F9010001F10100000101000001010000010100000101000001\r
+  9 01FFFFFF\r
+ 10 01FFFFFF0100000101000001010000010100000101000001010300F1010701F9\r
+ 10 010F039D010F030D0103030D0103030D0103030D0103030D0103030D0103030D\r
+ 10 0103039D010F81F9010F80F10100000101000001010000010100000101000001\r
+ 10 01FFFFFF\r
+ 11 01FFFFFF010000010100000101000001010000010100000101030061010700E1\r
+ 11 010F01E1010F01E1010300610103006101030061010300610103006101030061\r
+ 11 01030061010F81F1010F81F10100000101000001010000010100000101000001\r
+ 11 01FFFFFF\r
+ 12 01FFFFFF0100000101000001010000010100000101000001010301F9010703FD\r
+ 12 010F038D010F030D0103030D0103001D0103003D01030079010301E1010303C1\r
+ 12 01030381010F83FD010F83FD0100000101000001010000010100000101000001\r
+ 12 01FFFFFF\r
+ 13 01FFFFFF0100000101000001010000010100000101000001010301F9010703FD\r
+ 13 010F030D010F030D0103001D0103007901030071010300790103001D0103030D\r
+ 13 0103030D010F83FD010F80F90100000101000001010000010100000101000001\r
+ 13 01FFFFFF\r
+ 14 01FFFFFF01000001010000010100000101000001010000010103001D0107003D\r
+ 14 010F006D010F00CD0103018D0103030D010303FD010303FD0103000D0103000D\r
+ 14 0103000D010F800D010F800D0100000101000001010000010100000101000001\r
+ 14 01FFFFFF\r
+ 15 01FFFFFF0100000101000001010000010100000101000001010303FD010703FD\r
+ 15 010F030D010F030101030371010303F90103030D0103000D0103000D0103030D\r
+ 15 0103031D010F81F9010F80F10100000101000001010000010100000101000001\r
+ 15 01FFFFFF\r
+ 16 01FFFFFF0100000101000001010000010100000101000001010300F9010701FD\r
+ 16 010F038D010F030D0103030101030371010303F90103039D0103030D0103030D\r
+ 16 0103030D010F83FD010F81F90100000101000001010000010100000101000001\r
+ 16 01FFFFFF\r
+ 17 01FFFFFF0100000101000001010000010100000101000001010303FD010703FD\r
+ 17 010F030D010F001901030019010300310103006101030061010300C1010300C1\r
+ 17 01030181010F8181010F81810100000101000001010000010100000101000001\r
+ 17 01FFFFFF\r
+ 18 01FFFFFF0100000101000001010000010100000101000001010301F9010703FD\r
+ 18 010F030D010F030D0103030D010301F9010300F1010301990103030D0103030D\r
+ 18 0103030D010F83FD010F81F90100000101000001010000010100000101000001\r
+ 18 01FFFFFF\r
+ 19 01FFFFFF0100000101000001010000010100000101000001010301F9010703FD\r
+ 19 010F030D010F030D0103030D0103039D010301FD010300ED0103000D0103000D\r
+ 19 0103030D010F83F9010F81F10100000101000001010000010100000101000001\r
+ 19 01FFFFFF\r
+ 20 01FFFFFF0100000101000001010000010100000101000001010FC0F1011FE1F9\r
+ 20 011C639D0118630D0118630D0100E30D0101E30D0103C30D010F030D011E030D\r
+ 20 011C239D011FE1F9011FE0F10100000101000001010000010100000101000001\r
+ 20 01FFFFFF\r
+ 21 01FFFFFF0100000101000001010000010100000101000001010FC061011FE0E1\r
+ 21 011C61E1011861E1011860610100E0610101E0610103C061010F0061011E0061\r
+ 21 011C2061011FE1F1011FE1F10100000101000001010000010100000101000001\r
+ 21 01FFFFFF\r
+ 22 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 22 011C638D0118630D0118630D0100E01D0101E03D0103C079010F01E1011E03C1\r
+ 22 011C2381011FE3FD011FE3FD0100000101000001010000010100000101000001\r
+ 22 01FFFFFF\r
+ 23 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 23 011C630D0118630D0118601D0100E0790101E0710103C079010F001D011E030D\r
+ 23 011C230D011FE3FD011FE0F90100000101000001010000010100000101000001\r
+ 23 01FFFFFF\r
+ 24 01FFFFFF0100000101000001010000010100000101000001010FC01D011FE03D\r
+ 24 011C606D011860CD0118618D0100E30D0101E3FD0103C3FD010F000D011E000D\r
+ 24 011C200D011FE00D011FE00D0100000101000001010000010100000101000001\r
+ 24 01FFFFFF\r
+ 25 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 25 011C630D01186301011863710100E3F90101E30D0103C00D010F000D011E030D\r
+ 25 011C231D011FE1F9011FE0F10100000101000001010000010100000101000001\r
+ 25 01FFFFFF\r
+ 26 01FFFFFF0100000101000001010000010100000101000001010FC0F9011FE1FD\r
+ 26 011C638D0118630D011863010100E3710101E3F90103C39D010F030D011E030D\r
+ 26 011C230D011FE3FD011FE1F90100000101000001010000010100000101000001\r
+ 26 01FFFFFF\r
+ 27 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 27 011C630D01186019011860190100E0310101E0610103C061010F00C1011E00C1\r
+ 27 011C2181011FE181011FE1810100000101000001010000010100000101000001\r
+ 27 01FFFFFF\r
+ 28 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 28 011C630D0118630D0118630D0100E1F90101E0F10103C199010F030D011E030D\r
+ 28 011C230D011FE3FD011FE1F90100000101000001010000010100000101000001\r
+ 28 01FFFFFF\r
+ 29 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 29 011C630D0118630D0118630D0100E39D0101E1FD0103C0ED010F000D011E000D\r
+ 29 011C230D011FE3F9011FE1F10100000101000001010000010100000101000001\r
+ 29 01FFFFFF\r
+ 30 01FFFFFF0100000101000001010000010100000101000001010FC0F1011FE1F9\r
+ 30 0118639D0118630D0100E30D0103C30D0103830D0103C30D0100E30D0118630D\r
+ 30 0118639D011FE1F90107C0F10100000101000001010000010100000101000001\r
+ 30 01FFFFFF\r
+ 31 01FFFFFF0100000101000001010000010100000101000001010FC061011FE0E1\r
+ 31 011861E1011861E10100E0610103C061010380610103C0610100E06101186061\r
+ 31 01186061011FE1F10107C1F10100000101000001010000010100000101000001\r
+ 31 01FFFFFF\r
+ 32 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 32 0118638D0118630D0100E30D0103401D0103803D0103C0790100E1E1011863C1\r
+ 32 01186381011FE3FD0107C3FD0100000101000001010000010100000101000001\r
+ 32 01FFFFFF\r
+ 33 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 33 0118630D0118630D0100E01D0103C079010380710103C0790100E01D0118630D\r
+ 33 0118630D191FE3FD0107C0F90100000101000001010000010100000101000001\r
+ 33 01FFFFFF\r
+ 34 01FFFFFF0100000101000001010000010100000101000001010FC01D011FE03D\r
+ 34 0118606D011860CD0100E18D0103C30D010383FD0103C3FD0100E00D0118600D\r
+ 34 0118600D011FE00D0107C00D0100000101000001010000010100000101000001\r
+ 34 01FFFFFF\r
+ 35 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 35 0118630D011863010100E3710103C3F90103830D0103C00D0100E00D0118630D\r
+ 35 0118631D011FE1F90107C0F10100000101000001010000010100000101000001\r
+ 35 01FFFFFF\r
+ 36 01FFFFFF0100000101000001010000010100000101000001010FC0F9011FE1FD\r
+ 36 0118638D0118630D0100E3010103C371010383F90103C39D0100E30D0118630D\r
+ 36 0118630D011FE3FD0107C1F90100000101000001010000010100000101000001\r
+ 36 01FFFFFF\r
+ 37 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 37 0118630D011860190100E0190103C031010380610103C0610100E0C1011860C1\r
+ 37 01186181011FE1810107C1810100000101000001010000010100000101000001\r
+ 37 01FFFFFF\r
+ 38 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 38 0118630D0118630D0100E30D0103C1F9010380F10103C1990100E30D0118630D\r
+ 38 0118630D011FE3FD0107C1F90100000101000001010000010100000101000001\r
+ 38 01FFFFFF\r
+ 39 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 39 0118630D0118630D0100E30D0103C39D010381FD0103C0ED0100E00D0118600D\r
+ 39 0118630D011FE3F90107C1F10100000101000001010000010100000101000001\r
+ 39 01FFFFFF\r
+ 40 01FFFFFF01000001010000010100000101000001010000010100E0F10101E1F9\r
+ 40 0103639D0106630D010C630D0118630D191FE30D011FE30D0100630D0100630D\r
+ 40 0100639D010061F9010060F10100000101000001010000010100000101000001\r
+ 40 01FFFFFF\r
+ 41 01FFFFFF01000001010000010100000101000001010000010100E0610101E0E1\r
+ 41 010361E1010661E1010C606101186061011FE061011FE0610100606101006061\r
+ 41 01006061010061F1010061F10100000101000001010000010100000101000001\r
+ 41 01FFFFFF\r
+ 42 01FFFFFF01000001010000010100000101000001010000010100E1F90101E3FD\r
+ 42 0103638D0106630D010C630D0118601D011FE03D011FE079010061E1010063C1\r
+ 42 01006381010063FD010063FD0100000101000001010000010100000101000001\r
+ 42 01FFFFFF\r
+ 43 01FFFFFF01000001010000010100000101000001010000010100E1F90101E3FD\r
+ 43 0103630D0106630D010C601D01186079011FE071011FE0790100601D0100630D\r
+ 43 0100630D010063FD010060F90100000101000001010000010100000101000001\r
+ 43 01FFFFFF\r
+ 44 01FFFFFF01000001010000010100000101000001010000010100E01D0101E03D\r
+ 44 0103606D010660CD010C618D0118630D011FE3FD011FE3FD0100600D0100600D\r
+ 44 0100600D0100600D0100600D0100000101000001010000010100000101000001\r
+ 44 01FFFFFF\r
+ 45 01FFFFFF01000001010000010100000101000001010000010100E3FD0101E1FD\r
+ 45 0103630D01066301010C6371011863F9011FE30D011FE00D0100600D0100630D\r
+ 45 0100631D010061F9010060F10100000101000001010000010100000101000001\r
+ 45 01FFFFFF\r
+ 46 01FFFFFF01000001010000010100000101000001010000010100E0F90101E1FD\r
+ 46 0103638D0106630D010C630101186371011FE3F9011FE39D0100630D0100630D\r
+ 46 0100630D010063FD010061F90100000101000001010000010100000101000001\r
+ 46 01FFFFFF\r
+ 47 01FFFFFF01000001010000010100000101000001010000010100E3FD0101E3FD\r
+ 47 0103630D01066019010C601901186031011FE061011FE061010060C1010060C1\r
+ 47 0100618101006181010061810100000101000001010000010100000101000001\r
+ 47 01FFFFFF\r
+ 48 01FFFFFF01000001010000010100000101000001010000010100E1F90101E3FD\r
+ 48 0103630D0106630D010C630D011861F9011FE0F1011FB1990100630D0100630D\r
+ 48 0100630D010063FD010061F90100000101000001010000010100000101000001\r
+ 48 01FFFFFF\r
+ 49 01FFFFFF01000001010000010100000101000001010000010100E1F90101E3FD\r
+ 49 0103630D0106630D010C630D0118639D011FE1FD011FE0ED0100600D0100600D\r
+ 49 0100630D010063F9010061F10100000101000001010000010100000101000001\r
+ 49 01FFFFFF\r
+ 50 01FFFFFF0100000101000001010000010100000101000001011FE0F1011FE1F9\r
+ 50 0118639D0118030D011B830D011FC30D0118630D0100630D0100630D0118630D\r
+ 50 0118E39D010FC1F9010780F10100000101000001010000010100000101000001\r
+ 50 01FFFFFF\r
+ 51 01FFFFFF0100000101000001010000010100000101000001011FE061011FE0E1\r
+ 51 011861E1011801E1011B8061011FC06101186061010060610100606101186061\r
+ 51 0118E061010FC1F1010781F10100000101000001010000010100000101000001\r
+ 51 01FFFFFF\r
+ 52 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 52 0118638D0118030D011B830D011FC01D0118603D01006079010061E1011863C1\r
+ 52 0118E381010FC3FD010783FD0100000101000001010000010100000101000001\r
+ 52 01FFFFFF\r
+ 53 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 53 0118630D0118030D010F801D011FC07901186071010060790100601D0118630D\r
+ 53 0118E30D010FC3FD010780F90100000101000001010000010100000101000001\r
+ 53 01FFFFFF\r
+ 54 01FFFFFF0100000101000001010000010100000101000001011FE01D011FE03D\r
+ 54 0118606D011800CD011B818D011FC30D011863FD010063FD0100600D0118600D\r
+ 54 0118E00D010FC00D0107800D0100000101000001010000010100000101000001\r
+ 54 01FFFFFF\r
+ 55 01FFFFFF0100000101000001010000010100000101000001011FE3FD011FE3FD\r
+ 55 0118630D01180301011B8371011FC3F90118630D0100600D0100600D0118E30D\r
+ 55 0118E31D010FC1F9010780F10100000101000001010000010100000101000001\r
+ 55 01FFFFFF\r
+ 56 01FFFFFF0100000101000001010000010100000101000001011FE0F9011FE1FD\r
+ 56 0118638D0118030D011B8301011FC371011863F90100639D0100630D0118630D\r
+ 56 0118E30D010FC3FD010781F90100000001000001010000010100000101000001\r
+ 56 01FFFFFF\r
+ 57 01FFFFFF0100000101000001010000010100000101000001011FE3FD011FE3FD\r
+ 57 0118630D01180019011B8019011FC0310118606101006061010060C1011860C1\r
+ 57 0118E181010FC181010781810100000101000001010000010100000101000001\r
+ 57 01FFFFFF\r
+ 58 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 58 0118630D0118030D011B830D011FC1F9011860F1010061990100630D0118630D\r
+ 58 0118E30D010FC3FD010781F90100000101000001010000010100000101000001\r
+ 58 01FFFFFF\r
+ 59 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 59 0118630D0118030D011B830D011FC39D011861FD010060ED0100600D0118600D\r
+ 59 0118E30D010FC3F9010781F10100000101000001010000010100000101000001\r
+ 59 01FFFFFF\r
+ 60 01FFFFFF01000001010000010100000101000001010000010107C0F1010FE1F9\r
+ 60 011C639D0118630D0118030D011B830D011FC30D011CE30D0118630D0118630D\r
+ 60 0118639D011FE1F9010FC0F10100000101000001010000010100000101000001\r
+ 60 01FFFFFF\r
+ 61 01FFFFFF01000001010000010100000101000001010000010107C061010FE0E1\r
+ 61 011C61E1011861E101180061011B8061011FC061011CE0610118606101186061\r
+ 61 01186061011FE1F1010FC1F10100000101000001010000010100000101000001\r
+ 61 01FFFFFF\r
+ 62 01FFFFFF01000001010000010100000101000001010000010107C1F9010FE3FD\r
+ 62 011C638D0118630D0118030D011B801D011FC03D011CE079011861E1011863C1\r
+ 62 01186381011FE3FD010FC3FD0100000101000001010000010100000101000001\r
+ 62 01FFFFFF\r
+ 63 01FFFFFF01000001010000010100000801000001010000010107C1F9010FE3FD\r
+ 63 011C630D0118630D0118001D011B8079011FC071011CE0790118601D0118630D\r
+ 63 0118630D011FE3FD010FC0F90100000101000001010000010100000101000001\r
+ 63 01FFFFFF\r
+ 64 01FFFFFF01000001010000010100000101000001010000010107C01D010FE03D\r
+ 64 011C606D011860CD0118018D010F830D011FC3FD011CE3FD0118600D0118600D\r
+ 64 0118600D011FE00D010FC00D0100000101000001010000010100000101000001\r
+ 64 01FFFFFF\r
+ 65 01FFFFFF01000001010000010100000101000001010000010107C3FD010FE3FD\r
+ 65 011C630D0118630101180371011B83F9011FC30D011CE00D0118600D0118630D\r
+ 65 0118631D011FE1F9010FC0F10100000101000001010000010100000101000001\r
+ 65 01FFFFFF\r
+ 66 01FFFFFF01000001010000010100000101000001010000010107C0F9010FE1FD\r
+ 66 011C638D0118630D01180301011B8371011FC3F9011CE39D0118630D0118630D\r
+ 66 0118630D011FE3FD010FC1F90100000101000001010000010100000101000001\r
+ 66 01FFFFFF\r
+ 67 01FFFFFF01000001010000010100000101000001010000010107C3FD010FE3FD\r
+ 67 011C630D0118601901180019011B8031011FC061011CE061011860C1011860C1\r
+ 67 01186181011FE181010FC1810100000101000001010000010100000101000001\r
+ 67 01FFFFFF\r
+ 68 01FFFFFF01000001010000010100000101000001010000010107C1F9010FE3FD\r
+ 68 011C630D0118630D0118030D011B81F9011FC0F1011CE1990118630D0118630D\r
+ 68 0118630D011FE3FD010FC1F90100000101000001010000010100000101000001\r
+ 68 01FFFFFF\r
+ 69 01FFFFFF01000001010000010100000101000001010000010107C1F9010FE3FD\r
+ 69 011C630D0118630D0118030D011B839D011FC1FD011CE0ED0118600D0118600D\r
+ 69 0118630D011FE3F9010FC1F10100000101000001010000010100000101000001\r
+ 69 01FFFFFF\r
+ 70 01FFFFFF0100000101000001010000010100000101000001011FE0F1011FE1F9\r
+ 70 0118639D0100C30D0100C30D0101830D0103030D0103030D0106030D0106030D\r
+ 70 010C039D010C01F9010C00F10100000101000001010000010100000101000001\r
+ 70 01FFFFFF\r
+ 71 01FFFFFF0100000101000001010000010100000101000001011FE061011FE0E1\r
+ 71 011861E10100C1E10100C0610101806101030061010300610106006101060061\r
+ 71 010C0061010C01F1010C01F10100000101000001010000010100000101000001\r
+ 71 01FFFFFF\r
+ 72 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 72 0118638D0100C30D0100C30D0101801D0103003D01030079010601E1010603C1\r
+ 72 010C0381010C03FD010C03FD0100000101000001010000010100000101000001\r
+ 72 01FFFFFF\r
+ 73 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 73 0118630D0100C30D0100C01D0101807901030071010300790106001D0106030D\r
+ 73 010C030D010C03FD010C00F90100000101000001010000010100000101000001\r
+ 73 01FFFFFF\r
+ 74 01FFFFFF0100000101000001010000010100000101000001011FE01D011FE03D\r
+ 74 0118606D0100C0CD0100C18D0101830D010303FD010303FD0106000D0106000D\r
+ 74 010C000D010C000D010C000D0100000101000001010000010100000101000001\r
+ 74 01FFFFFF\r
+ 75 01FFFFFF0100000101000001010000010100000101000001011FE3FD011FE3FD\r
+ 75 0118630D0100C3010100C371010183F90103030D0103000D0106000D0106030D\r
+ 75 010C031D010C01F9010C00F10100000101000001010000010100000101000001\r
+ 75 01FFFFFF\r
+ 76 01FFFFFF0100000101000001010000010100000101000001011FE0F9011FE1FD\r
+ 76 0118638D0100C30D0100C30101018371010303F90103039D0106030D0106030D\r
+ 76 010C030D010C03FD010C01F90100000101000001010000010100000101000001\r
+ 76 01FFFFFF\r
+ 77 01FFFFFF0100000101000001010000010100000101000001011FE3FD011FE3FD\r
+ 77 0118630D0100C0190100C019010180310103006101030061010600C1010600C1\r
+ 77 010C0181010C0181010C01810100000101000001010000010100000101000001\r
+ 77 01FFFFFF\r
+ 78 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 78 0118630D0100C30D0100C30D010181F9010300F1010301990106030D0106030D\r
+ 78 010C030D010C03FD010C01F90100000101000001010000010100000101000001\r
+ 78 01FFFFFF\r
+ 79 01FFFFFF0100000101000001010000010100000101000001011FE1F9011FE3FD\r
+ 79 0118630D0100C30D0100C30D0101839D010301FD010300ED0106000D0106000D\r
+ 79 010C030D010C03F9010C01F10100000101000001010000010100000101000001\r
+ 79 01FFFFFF\r
+ 80 01FFFFFF0100000101000001010000010100000101000001010FC0F1011FE1F9\r
+ 80 0118639D0118630D0118630D010FC30D0107830D010CC30D0118630D0118630D\r
+ 80 0118639D011FE1F9010FC0F10100000101000001010000010100000101000001\r
+ 80 01FFFFFF\r
+ 81 01FFFFFF0100000101000001010000010100000101000001010FC061011FE0E1\r
+ 81 011861E1011861E101186061010FC06101078061010CC0610118606101186061\r
+ 81 01186061011FE1F1010FC1F10100000101000001010000010100000101000001\r
+ 81 01FFFFFF\r
+ 82 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 82 0118638D0118630D0118630D010FC01D0107803D010CC079011861E1011863C1\r
+ 82 01186381011FE3FD010FC3FD0100000101000001010000010100000101000001\r
+ 82 01FFFFFF\r
+ 83 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 83 0118630D0118630D0118601D010FC07901078071010CC0790118601D0118630D\r
+ 83 0118630D011FE3FD010FC0F90100000101000001010000010100000101000001\r
+ 83 01FFFFFF\r
+ 84 01FFFFFF0100000101000001010000010100000101000001010FC01D011FE03D\r
+ 84 0118606D011860CD0118618D010FC30D010783FD010CC3FD0118600D0118600D\r
+ 84 0118600D011FE00D010FC00D0100000101000001010000010100000101000001\r
+ 84 01FFFFFF\r
+ 85 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 85 0118630D0118630101186371010FC3F90107830D010CC00D0118600D0118630D\r
+ 85 0118631D011FE1F9010FC0F10100000101000001010000010100000101000001\r
+ 85 01FFFFFF\r
+ 86 01FFFFFF0100000101000001010000010100000101000001010FC0F9011FE1FD\r
+ 86 0118638D0118630D01186301010FC371010783F9010CC39D0118630D0118630D\r
+ 86 0118630D011FE3FD010FC1F90100000101000001010000010100000101000001\r
+ 86 01FFFFFF\r
+ 87 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 87 0118630D0118601901186019010FC03101078061010CC061011860C1011860C1\r
+ 87 01186181011FE181010FC1810100000101000001010000010100000101000001\r
+ 87 01FFFFFF\r
+ 88 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 88 0118630D0118630D0118630D010FC1F9010780F1010CC1990118630D0118630D\r
+ 88 0118630D011FE3FD010FC1F90100000101000001010000010100000101000001\r
+ 88 01FFFFFF\r
+ 89 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 89 0118630D0118630D0118630D010FC39D010781FD010CC0ED0118600D0118600D\r
+ 89 0118630D011FE3F9010FC1F10100000101000001010000010100000101000001\r
+ 89 01FFFFFF\r
+ 90 01FFFFFF0100000101000001010000010100000101000001010FC0F1011FE1F9\r
+ 90 0118639D0118630D0118630D011CE30D010FE30D0107630D0100630D0100630D\r
+ 90 0118E39D011FC1F9010F80F10100000101000001010000010100000101000001\r
+ 90 01FFFFFF\r
+ 91 01FFFFFF0100000101000001010000010100000101000001010FC061011FE0E1\r
+ 91 011861E1011861E101186061011CE061010FE061010760610100606101006061\r
+ 91 0118E061011FC1F1010F81F10100000101000001010000010100000101000001\r
+ 91 01FFFFFF\r
+ 92 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FD3FD\r
+ 92 0118638D0118630D0118630D011CE01D010FE03D01076079010061E1010063C1\r
+ 92 0118E381011FC3FD010F83FD0100000101000001010000010100000101000001\r
+ 92 01FFFFFF\r
+ 93 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 93 0118630D0118330D0118601D011CE079010FE071010760790100601D0100630D\r
+ 93 0118E30D011FC3FD010F80F90100000101000001010000010100000101000001\r
+ 93 01FFFFFF\r
+ 94 01FFFFFF0100000101000001010000010100000101000001010FC01D011FE03D\r
+ 94 0118606D011860CD0118618D011CE30D010FE3FD010763FD0100600D0100600D\r
+ 94 0118E00D011FC00D010F800D0100000101000001010000010100000101000001\r
+ 94 01FFFFFF\r
+ 95 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 95 0118630D0118630101186371011CE3F9010FE30D0107600D0100600D0100630D\r
+ 95 0118E31D011FC1F9010F80F90100000101000001010000010100000101000001\r
+ 95 01FFFFFF\r
+ 96 01FFFFFF0100000101000001010000010100000101000001010FC0F9011FE1FD\r
+ 96 0118638D0118630D01186301011CE371010FE3F90107639D0100630D0100630D\r
+ 96 0118E30D011FC3FD010F81F90100000101000001010000010100000101000001\r
+ 96 01FFFFFF\r
+ 97 01FFFFFF0100000101000001010000010100000101000001010FC3FD011FE3FD\r
+ 97 0118630D0118601901186019011CE031010FE06101076061010060C1010060C1\r
+ 97 0118E181011FC181010F81810100000101000001010000010100000101000001\r
+ 97 01FFFFFF\r
+ 98 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FE3FD\r
+ 98 0118630D0118630D0118630D011CE1F9010FE0F1010761990100630D0100630D\r
+ 98 0118E30D011FC3FD010F81F90100000101000001010000010100000101000001\r
+ 98 01FFFFFF\r
+ 99 01FFFFFF0100000101000001010000010100000101000001010FC1F9011FC3FD\r
+ 99 0118630D0118630D0118630D011CE39D010FE1FD010760ED0100600D0100600D\r
+ 99 0118E30D011FC3F9010F81F10100000101000001010000010100000101000001\r
+ 99 01FFFFFF\r
+100 0000380000003800000038000000380000003800000038000000380000003800\r
+100 0000380000003800000038000000380000003800000038000000380000003800\r
+100 0000380000003800000038000000380000003800000038000000380000003800\r
+100 00003800\r
+101 0000000000000000000000000000000000000000000000000000000000000000\r
+101 0000000000000000000000003FFFFFFF3FFFFFFF3FFFFFFF0000000000000000\r
+101 0000000000000000000000000000000000000000000000000000000000000000\r
+101 00000000\r
diff --git a/symbols/digit6.sym b/symbols/digit6.sym
new file mode 100644 (file)
index 0000000..b8a5588
--- /dev/null
@@ -0,0 +1,22 @@
+ -6 -6 79/11/07.OPTICALLY WEIGHTED NUMBERS LIGHT TO DARK\r
+  1  004 004 004 004 004 000\r
+  2  008 004 008 008 00C 000\r
+  3  00C 004 008 004 00C 000\r
+  4  008 00A 00E 002 002 000\r
+  5  00C 008 00C 002 00E 000\r
+  6  008 008 00E 00A 00E 000\r
+  7  00E 006 00C 00C 00C 000\r
+  8  00E 00A 00E 00A 00C 000\r
+  9  00E 00A 00E 006 00E 000\r
+ 10  00E 00E 00A 00E 00E 000\r
+ 11  018 01C 01C 01C 01E 000\r
+ 12  01C 01A 01C 01C 01E 000\r
+ 13  01E 01A 01C 01A 01E 000\r
+ 14  01C 01E 01E 01E 01C 000\r
+ 15  01E 01C 01E 01E 01E 000\r
+ 16  01C 01C 01F 01D 01F 000\r
+ 17  01F 01D 01E 01E 01E 000\r
+ 18  01F 01D 01F 01D 01E 000\r
+ 19  01F 01D 01F 01B 01F 000\r
+ 20  01F 01F 01D 01F 01F 000\r
+ 21  01F 01F 01F 01F 01F 000\r
diff --git a/symbols/fort10.sym b/symbols/fort10.sym
new file mode 100644 (file)
index 0000000..454c62b
--- /dev/null
@@ -0,0 +1,12 @@
+-10 -10 79/11/16.FOREST COVER (V23)\r
+  1 001000380038007C007C00FE00FE01FF00380000\r
+  2 0010001000380054009200380054019300100000\r
+  3 002C00FE00FE007C00FE00340030003000780000\r
+  4 002C00D200A6004C00D200340030003000780000\r
+  5 007C00FE01FF01FF01FF00AA00280028007C0000\r
+  6 001000A80146010200BC00500010001000380000\r
+  7 031100AA004400000000031100AA004400000000\r
+ 77 03FF0303028502490231023102490285030303FF\r
+ 99 031100AA004400000000031100AA004400000000\r
+100 03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF\r
+\1a
\ No newline at end of file
diff --git a/symbols/gray5.sym b/symbols/gray5.sym
new file mode 100644 (file)
index 0000000..bcf1d01
--- /dev/null
@@ -0,0 +1,27 @@
+  -5 -5 79/11/07.GRAY SCALE LIGHT TO DARK\r
+  1  000 000 004 000 000\r
+  2  000 004 000 004 000\r
+  3  004 000 004 000 004\r
+  4  000 00A 000 00A 000\r
+  5  000 00A 004 00A 000\r
+  6  004 00A 000 00A 004\r
+  7  004 00A 004 00A 004\r
+  8  011 004 00A 004 011\r
+  9  004 00A 015 00A 004\r
+ 10  00A 011 00A 011 00A\r
+ 11  011 00A 015 00A 011\r
+ 12  00A 015 00A 015 00A\r
+ 13  015 00A 015 00A 015\r
+ 14  00A 015 01B 015 00A\r
+ 15  01B 00A 015 00A 01B\r
+ 16  01B 015 00A 015 01B\r
+ 17  00E 01B 015 01B 00E\r
+ 18  01B 015 01B 015 01B\r
+ 19  01B 015 01F 015 01B\r
+ 20  01F 00E 01B 00E 01F\r
+ 21  01F 015 01F 015 01F\r
+ 22  01B 01F 01B 01F 01B\r
+ 23  01F 01B 01F 01B 01F\r
+ 24  01F 01F 01B 01F 01F\r
+ 25  01F 01F 01F 01F 01F\r
+ 26  00C 012 012 012 00C\r
diff --git a/symbols/luse6.sym b/symbols/luse6.sym
new file mode 100644 (file)
index 0000000..57bcae3
--- /dev/null
@@ -0,0 +1,18 @@
+ -6 -6 79/11/07.LAND USE TONES + 7 EXTRA\r
+  1  00D 013 00A 014 013 000\r
+  2  00A 00A 00A 00A 000 000\r
+  3  000 015 00A 000 000 000\r
+  4  000 003 000 00C 000 000\r
+  5  011 015 01F 015 011 000\r
+  6  01F 015 01B 015 01F 000\r
+  7  000 00A 000 00A 000 000\r
+  8  01F 011 015 011 01F 000\r
+  9  01F 01F 01F 01F 01F 000\r
+ 10  000 000 004 000 000 000\r
+ 11  000 03F 000 000 03F 000\r
+ 12  012 012 012 012 012 012\r
+ 13  008 010 020 001 002 004\r
+ 14  004 002 001 020 010 008\r
+ 15  03F 03F 03F 03F 03F 03F\r
+ 16  02A 015 02A 015 02A 015\r
+ 17  02A 000 015 000 02A 000\r
diff --git a/symbols/misc14.sym b/symbols/misc14.sym
new file mode 100644 (file)
index 0000000..d47870d
--- /dev/null
@@ -0,0 +1,47 @@
+ -14 -14 79/11/07.DICOMED SYMBOLS (KENS)\r
+  1 00000000000000000000000000000000000000000000000000000000\r
+  2 0000000000000000000001E001E001E001E000000000000000000000\r
+  3 000000000000000000003FFF3FFF3FFF3FFF00000000000000000000\r
+  4 03F003F003F003F003F003F003F003F003F003F003F003F003F003F0\r
+  5 000000000FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC00000000\r
+  6 3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FFF\r
+  7 00C000C000C000C000C000C03FFF3FFF00C000C000C000C000C000C0\r
+  8 01E001E001E001E001E03FFF3FFF3FFF3FFF01E001E001E001E001E0\r
+  9 3FFF3FFF3FFF380738073807380738073807380738073FFF3FFF3FFF\r
+ 10 0007000F001F003E007C00F801F003E007C00F801F003E003C003800\r
+ 11 0000000000D00618040802000130006000C000C00040004000000000\r
+ 12 3FFF3FFF3FFF3FFF3FFF3E1F3E1F3E1F3E1F3FFF3FFF3FFF3FFF3FFF\r
+ 13 004000C000E001E001E003F003F007F807F80FFC0040004000400040\r
+ 14 00030007000E001C0038007000E001C0038007000E001C0038003000\r
+ 15 31E331E30E1C0E1C0E1C31E331E331E331E30E1C0E1C0E1C31E331E3\r
+ 16 3FFF3FFF300330033003300330C330C330033003300330033FFF3FFF\r
+ 17 3FFF3FFF300330033003300333F333F330033003300330033FFF3FFF\r
+ 18 300038001C000E000700038001C000E000700038001C000E00070003\r
+ 19 3F803F803F803F803F803F80007F007F007F007F007F007F007F007F\r
+ 20 3F3F3F3F333333333F3F3F3F000000003F3F3F3F333333333F3F3F3F\r
+ 21 0000003800383F003F000000003F003F00000F000F00003800380000\r
+ 22 0000000000C001E0033006180C0C0C0C0618033001E000C000000000\r
+ 23 000000C001E0033006180C0C180618060C0C0618033001E000C00000\r
+ 24 00000000000000C000C001E007F807F801E000C000C0000000000000\r
+ 25 07F00FE01FC03F803F013E033C07380F301F203F007F00FE01FC03F8\r
+ 26 0000000000C001E003F007F80FFC0FFC07F803F001E000C000000000\r
+ 27 300338071C0E0E1C073803F00120012003F007380E1C1C0E38073003\r
+ 28 000000C000C000C003F003301E1E1E1E033003F000C000C000C00000\r
+ 29 00000000000007F807F8000000000000000007F807F8000000000000\r
+ 30 000003F003F003F00FFC0FFC0FFC0FFC0FFC0FFC03F003F003F00000\r
+ 31 00000100038006C00C6018300C18060C0306018C00D8007000200000\r
+ 32 0618061806183FFF3FFF06180618061806183FFF3FFF061806180618\r
+ 33 00000000000007F807F8061806180618061807F807F8000000000000\r
+ 34 00001E1E1E1E1E1E1E1E01E001E001E001E01E1E1E1E1E1E1E1E0000\r
+ 35 0018001800380078007800F001E001E003C007800780070006000600\r
+ 36 000000000E1C0E1C0E1C00000000000000000E1C0E1C0E1C00000000\r
+ 37 000001B007200C48088C091C0330074400C800C000C001E003F00000\r
+ 38 00C000C001E003F007F80FFC1FFE00C000C000C000C000C000C00000\r
+ 39 00000000000000C001E003F007F80FFC000000000000000000000000\r
+ 40 00000000000000C000C000C003F003F000C000C000C0000000000000\r
+ 41 06180618061806180618061806180618061806180618061806180618\r
+ 42 000008C009F007E00FE00FFC07FC03F00BE40CC004C000C001E003F0\r
+ 43 00C000C000C000C000C000C000C000C000C000C000C000C000C000C0\r
+ 44 0000000000C000C000C000C000C000C000C000C000C000C000000000\r
+ 46 00000000061806180618061806180618061806180618061800000000\r
+ 47 300338071C0E0E1C073803F001E001E003F007380E1C1C0E38073003\r
diff --git a/symbols/misc16.sym b/symbols/misc16.sym
new file mode 100644 (file)
index 0000000..debd1eb
--- /dev/null
@@ -0,0 +1,236 @@
+-16 -16 16X16 FINAL\r
+  1 0000018003C007E007E00FF00FF01FF81FF83FFC3FFC7FFE7FFE03C003C00000\r
+  2 000041806186318E318C199819980DB00DB00FF07FFE7FFE000001FE01FE0000\r
+  3 0000018003C007E00FF01FF83FFC3FFC3FFC3FFC3FFC3FFC3FFC3FFC00000000\r
+  4 000001801BC01E601C3018183F0C317C314C3F4C304C304C3FFC3FFC00000000\r
+  5 00000000000000000FF00FF00FF00FF00FF00FF00FF00FF00000000000000000\r
+  6 00000000000000000000000003C003C003C003C0000000000000000000000000\r
+  7 00000000018001800180018001803FFC3FFC0180018001800180018000000000\r
+  8 000000000000C003C003F00F300C3C3C0C300FF003C003C00000000000000000\r
+  9 00000000300030003C000C000F00030003CC00CC00FC003C00FC00FC00000000\r
+ 10 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+ 11 0000666666660000000066666666000000006666666600000000666666660000\r
+ 12 00007FFE7FFE000000007FFE7FFE000000007FFE7FFE000000007FFE7FFE0000\r
+ 13 0000000000000000000000003FFC3FFC3FFC3FFC000000000000000000000000\r
+ 14 0842042182104108208410420821841042082104108208418420421021081084\r
+ 15 084314A3A3144308A49418631863A4944308A31414A3084394A46318631894A4\r
+ 16 3333333333333333333333333333333333333333333333333333333333333333\r
+ 17 3333333333333333333333333333333333333333333333333333333333333333\r
+ 18 FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333\r
+ 19 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+ 20 4208841008211042208441088210042108421084210842108420084110822104\r
+ 21 630CC6188C31186330C6618CC31886310C6318C6318C6318C6308C6118C33186\r
+ 22 738EE71CCE399C7338E771CEE39CC7398E731CE739CE739CE738CE719CE339C7\r
+ 23 000E001C0038007000E001C0038007000E001C0038007000E000C00180030007\r
+ 24 0180018001800180018001800180FFFFFFFF0180018001800180018001800180\r
+ 25 4208841000000000208441080000000008421084000000008420084100000000\r
+ 26 4208A514000000002084514A00000000084294A40000000084204A5100000000\r
+ 27 4208A514420800002084514A20840000084294A40842000084204A5184200000\r
+ 28 528AA5144208841028A5514A208441088A5214A508421084A5284A5184200841\r
+ 29 738EE71C4208841038E771CE208441088E731CE708421084E738CE7184200841\r
+ 30 FFFFE71C4208FFFFFFFF71CE2084FFFFFFFF9CE70842FFFFFFFFCE718420FFFF\r
+ 31 FFFFE71C4208E71CFFFF71CE208471CEFFFF9CE708429CE7FFFFCE718420CE71\r
+ 32 FFFFFFFF4208FFFFFFFFFFFF2084FFFFFFFFFFFF0842FFFFFFFFFFFF0421FFFF\r
+ 33 FFFFFFFF4208FFFFFFFFFFFF2084FFFFFFFFFFFF0842FFFFFFFFFFFF0421FFFF\r
+ 34 FFFF3333CCCC3333CCCC3333CCCC3333FFFF3333CCCC3333FFFF3333CCCC3333\r
+ 35 FFFF3333FFFF3333CCCC3333FFFF3333FFFF3333FFFF3333FFFF3333FFFF3333\r
+ 36 FFFF3333CCCC3333CCCC3333CCCC3333FFFF3333CCCC3333FFFF3333CCCC3333\r
+ 37 797B3232C4CC0313848423234CCC31307B793232CCC41303B7972323CC4C3031\r
+ 38 797B3232C4CC0313848423234CCC31307B793232CCC41303B7972323CC4C3031\r
+ 39 FFFF3232C4CCFFFF84842323FFFF3130FFFF3232FFFE1303FFFF2323FFFF3031\r
+ 40 ECF33232C4CCFC7F84842323FFFF3130C1E33232FFFE1302FE3F2323FFC73031\r
+ 41 ECF37672E6EEFD7F8C8C6767FFFF3131C9EB7676FFFE1313FEBF6727FFC73131\r
+ 42 ECF7767BE6FEFD7F8CDC67F7FFFF33F1CDEB7F76FFFE3F13FEBFF727FFC7F133\r
+ 43 EEF7F67BEEFFFD7FACDC67FFFFFF33F5CDEB7FF6FFFE3F53FEBFFF67FFC7F533\r
+ 44 FFFFF67BEEFFFD7FACDC67FFFFFF33F5CDEB7FF6FFFEFFFFFEBFFF67FFC7F533\r
+ 45 FFFFF67BEEFFFD7FECDC67FFFFFFFFFFCDEB7FF6FFFEFFFFFEBFFFFFFFFFF533\r
+ 46 000007C00FE01FF03FF83FF81FF00FE00380038003800380038007C000000000\r
+ 47 00000000000007801F80070001000100017801FC00F800700020002000600000\r
+ 48 00000000618073807F806D8061806180000001FC01FC0180018001FC01FC0000\r
+ 49 00000000618073807F806D8061806180000001FC018C018C01FC018C018C01FC\r
+ 50 000000003FE03FE0070007000700070007000700000000000000000000000000\r
+ 51 0000000000001F80100010001F80008000801F800000007C00400040007C0000\r
+ 52 000000003F002000200020003F000000000003F8004000400040004000400000\r
+ 53 000000003E00220022003E0028002400220001F00110011001F0014001200110\r
+ 54 000000000000FFFFFFFFFFFFFFFFCCE6FFFFFFFFFFFFFFFF0000000000000000\r
+ 55 000000000000FFFFFFFFFFFFFFFFCCE6FFFFFFFFFFFFFFFF0000000000000000\r
+ 56 0000000021020000000000002102000000000000208400000000000020840000\r
+ 57 4208000000000000208400000000000008420000000000000000000000000000\r
+ 58 C0030000000000000000000003C003C003C003C000000000000000000000C003\r
+ 59 80010000000000000000000003C003C003C003C0000000000000000000008001\r
+ 60 0000000000000FF00FF00C000C000FF00FF0003000300FF00FF0000000000000\r
+ 61 00003F8004000400058005000580000000FE0010001000100016001400160000\r
+ 62 00000E001F003F801F000E0004000438047C043804100E380000000000000000\r
+ 63 000000000400061006180618041804100510069014942C1A24100E3800000000\r
+ 64 300030002600261824D824D0649024907490059014942DDA04100E3800000000\r
+ 65 300030002600261824D824D0249064902490359024942CD824907FFC52240000\r
+ 66 0000000000000000200024D0249064902490359024942CD824907FFC52240000\r
+ 67 0000038003800380011001280148018023225555898801000100010003800000\r
+ 68 000007C001002AA81550010001000100012001500190011001001FF800000000\r
+ 69 00000000202024202420242022201240114011401150095029507FF800001FF0\r
+ 70 00000000100038007C00FE0010001020107010F8102010F87C00000000000000\r
+ 71 000000000300C103C103F38F300C3C3C0C300FF003C003C00000000000000000\r
+ 72 000001C00040C083C103F1CF300C3C3C0C300FF003C003C00000000000000000\r
+ 73 000001C00040C1C3C043F1CF300C3C3C0C300FF003C003C00000000000000000\r
+ 74 000001400140C1C3C043F04F300C3C3C0C300FF003C003C00000000000000000\r
+ 75 000001C00100C1C3C043F1CF300C3C3C0C300FF003C003C00000000000000000\r
+ 76 000001C00100C1C3C143F1CF300C3C3C0C300FF003C003C00000000000000000\r
+ 77 000001C00040C083C083F10F300C3C3C0C300FF003C003C00000000000000000\r
+ 78 000001C00140C1C3C143F1CF300C3C3C0C300FF003C003C00000000000000000\r
+ 79 000001C00140C1C3C043F1CF300C3C3C0C300FF003C003C00000000000000000\r
+ 80 0000666666660000000066666666000000006666666600000000666666660000\r
+ 81 000001801BC01E601C3018183F0C317C314C3F4C304C304C3FFC3FFC00000000\r
+ 82 FFFF2448FFFF244824482448FFFF2448FFFF24482448FFFF2448FFFF24482448\r
+ 83 FFFF2549FFFF2549FFFF2549FFFF2549FFFF25492549FFFF2549FFFF25492549\r
+ 84 00000000231013200B4007803CF807800B401320231003000000000000000000\r
+ 85 00004210222012400A8007007FF807000A801240222042100000000000000000\r
+ 86 00000000102038707CF83870102000000000102038707CF83870102000000000\r
+ 87 FFFF3333CCCC3333CCCC3333CCCC3333FFFF3333CCCC3333FFFF3333CCCC3333\r
+ 88 FFFF3333FFFF3333CCCC3333FFFF3333FFFF3333FFFF3333FFFF3333FFFF3333\r
+ 89 738EE71CCE399C7338E771CEE39CC7398E731CE739CE739CE738CE719CE339C7\r
+ 90 FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333\r
+ 91 3333333333333333333333333333333333333333333333333333333333333333\r
+ 92 0000249200002492000024920000249200002492000024920000249200002492\r
+ 93 00007FFE7FFE000000007FFE7FFE000000007FFE7FFE000000007FFE7FFE0000\r
+ 94 0000000000000000000000003FFC3FFC3FFC3FFC000000000000000000000000\r
+ 95 0000000022221414080814142222000022221414080814142222000000000000\r
+ 96 00000000300030003C000C000F00030003CC00CC00FC003C00FC00FC00000000\r
+ 97 AAAA000055550000AAAA000055550000AAAA000055550000AAAA000055550000\r
+ 98 0000000010202850448828501020000000001020285044882850102000000000\r
+ 99 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+100 B6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DB\r
+101 B6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB\r
+102 7BDF7BDF7BDF7BDF7BDF00007BDF7BDF7BDF7BDF00007BDF7BDF7BDF7BDF0000\r
+103 7BDF4A594A597BDF7BDF00007BDF4A594A597BDF00007BDF4A594A597BDF0000\r
+104 7BDF4A514A514A517BDF00007BDF4A514A517BDF00007BDF4A514A517BDF0000\r
+105 7F7F7F7F7F7F7F7F7F7F7F7F7F7F00007F7F7F7F7F7F7F7F7F7F7F7F7F7F0000\r
+106 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+107 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+108 7F7F41415D5D5D5D5D5D41417F7F00007F7F41415D5D5D5D5D5D41417F7F0000\r
+109 7F7F41415D5D55555D5D41417F7F00007F7F41415D5D55555D5D41417F7F0000\r
+110 BEBE41415D5D55555D5D4141BEBE8080BEBE41415D5D55555D5D4141BEBE8080\r
+111 A2A241411C1C14141C1C4141A2A28080A2A241411C1C14141C1C4141A2A28080\r
+112 A2A241410808141408084141A2A28080A2A241410808141408084141A2A28080\r
+113 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r
+114 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+115 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+116 FFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAA\r
+117 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+118 7577AEEEDD5DABBB7757EAEEDDD5BABB7775EEAE5DDDBBAB5777EEEAD5DDBBBA\r
+119 6167A6E6C95989B936566A6E9D949A996761E6A659C9B98956366E6A949D999A\r
+120 EEEE5555BBBB5555EEEE5555BBBB5555EEEE5555BBBB5555EEEE5555BBBB5555\r
+121 084314A3A3144308A49418631863A4944308A31414A3084394A46318631894A4\r
+122 0000000021020000000000002102000000000000208400000000000020840000\r
+123 4208841008211042208441088210042108421084210842108420084110822104\r
+124 7F7F7F7F7F7F7F7F7F7F7F7F7F7F00007F7F7F7F7F7F7F7F7F7F7F7F7F7F0000\r
+125 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+126 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+127 7F7F41415D5D5D5D5D5D41417F7F00007F7F41415D5D5D5D5D5D41417F7F0000\r
+128 7F7F41415D5D55555D5D41417F7F00007F7F41415D5D55555D5D41417F7F0000\r
+129 BEBE41415D5D55555D5D4141BEBE8080BEBE41415D5D55555D5D4141BEBE8080\r
+130 A2A241411C1C14141C1C4141A2A28080A2A241411C1C14141C1C4141A2A28080\r
+131 A2A241410808141408084141A2A28080A2A241410808141408084141A2A28080\r
+132 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r
+133 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+134 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+135 FFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAA\r
+136 0000666666660000000066666666000000006666666600000000666666660000\r
+137 000001801BC01E601C3018183F0C317C314C3F4C304C304C3FFC3FFC00000000\r
+138 FFFF2448FFFF244824482448FFFF2448FFFF24482448FFFF2448FFFF24482448\r
+139 FFFF2549FFFF2549FFFF2549FFFF2549FFFF25492549FFFF2549FFFF25492549\r
+140 00000000231013200B4007803CF807800B401320231003000000000000000000\r
+141 00004210222012400A8007007FF807000A801240222042100000000000000000\r
+142 00000000102038707CF83870102000000000102038707CF83870102000000000\r
+143 FFFF3333CCCC3333CCCC3333CCCC3333FFFF3333CCCC3333FFFF3333CCCC3333\r
+144 FFFF3333FFFF3333CCCC3333FFFF3333FFFF3333FFFF3333FFFF3333FFFF3333\r
+145 738EE71CCE399C7338E771CEE39CC7398E731CE739CE739CE738CE719CE339C7\r
+146 FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333\r
+147 3333333333333333333333333333333333333333333333333333333333333333\r
+148 0000249200002492000024920000249200002492000024920000249200002492\r
+149 00007FFE7FFE000000007FFE7FFE000000007FFE7FFE000000007FFE7FFE0000\r
+150 0000000000000000000000003FFC3FFC3FFC3FFC000000000000000000000000\r
+151 0000000022221414080814142222000022221414080814142222000000000000\r
+152 00000000300030003C000C000F00030003CC00CC00FC003C00FC00FC00000000\r
+153 AAAA000055550000AAAA000055550000AAAA000055550000AAAA000055550000\r
+154 0000000010202850448828501020000000001020285044882850102000000000\r
+155 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+156 B6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DB\r
+157 B6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB\r
+158 7BDF7BDF7BDF7BDF7BDF00007BDF7BDF7BDF7BDF00007BDF7BDF7BDF7BDF0000\r
+159 7BDF4A594A597BDF7BDF00007BDF4A594A597BDF00007BDF4A594A597BDF0000\r
+160 7BDF4A514A514A517BDF00007BDF4A514A517BDF00007BDF4A514A517BDF0000\r
+161 7F7F7F7F7F7F7F7F7F7F7F7F7F7F00007F7F7F7F7F7F7F7F7F7F7F7F7F7F0000\r
+162 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+163 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+164 7F7F41415D5D5D5D5D5D41417F7F00007F7F41415D5D5D5D5D5D41417F7F0000\r
+165 7F7F41415D5D55555D5D41417F7F00007F7F41415D5D55555D5D41417F7F0000\r
+166 BEBE41415D5D55555D5D4141BEBE8080BEBE41415D5D55555D5D4141BEBE8080\r
+167 A2A241411C1C14141C1C4141A2A28080A2A241411C1C14141C1C4141A2A28080\r
+168 A2A241410808141408084141A2A28080A2A241410808141408084141A2A28080\r
+169 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r
+170 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+171 FFFF00000000FFFF00000000FFFF00000000FFFF00000000FFFF000000000000\r
+172 8924124924924924924824914922924424894912922424494892912422484490\r
+173 A9A592496CB3ED34D24A2D95DDA2DA45A5A95B92BB6C34ED4AD2952DA2DC45DB\r
+174 FFFF0000000000000000FFFF0000000000000000FFFF00000000000000000000\r
+175 FFFF8420842084208420FFFF8420842084208420FFFF84208420842084208420\r
+176 FFFFA524A524A524A524FFFFA524A524A524A524FFFFA524A524A524A524A524\r
+177 8220411020881044082204118208410420821041882044102208110408820441\r
+178 8210042108421084210842108420084110822104420884100821104220844108\r
+179 8290446128621094290846148622094190826144622894100829144622864109\r
+180 829044612862109429084694B622094990926144622994900929144622864909\r
+181 8001400220041008081004200240018001800240042008101008200440028001\r
+182 9009481224241248899044212242118411882244442289911248242448129009\r
+183 90094992242412488990442122425184518A2244442289911248242449929009\r
+184 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+185 7577AEEEDD5DABBB7757EAEEDDD5BABB7775EEAE5DDDBBAB5777EEEAD5DDBBBA\r
+186 6167A6E6C95989B936566A6E9D949A996761E6A659C9B98956366E6A949D999A\r
+187 EEEE5555BBBB5555EEEE5555BBBB5555EEEE5555BBBB5555EEEE5555BBBB5555\r
+188 084314A3A3144308A49418631863A4944308A31414A3084394A46318631894A4\r
+189 0000000021020000000000002102000000000000208400000000000020840000\r
+190 4208841008211042208441088210042108421084210842108420084110822104\r
+191 0000018003C007E007E00FF00FF01FF81FF83FFC3FFC7FFE7FFE03C003C00000\r
+192 000041806186318E318C199819980DB00DB00FF07FFE7FFE000001FE01FE0000\r
+193 000E001C0038007000E001C0038007000E001C0038007000E000C00180030007\r
+194 0180018001800180018001800180FFFFFFFF0180018001800180018001800180\r
+195 000007C00FE01FF03FF83FF81FF00FE00380038003800380038007C000000000\r
+196 00000000202024202420242022201240114011401150095029507FF800001FF0\r
+197 00000000018001800180018001803FFC3FFC0180018001800180018000000000\r
+198 0000666666660000000066666666000000006666666600000000666666660000\r
+199 000001801BC01E601C3018183F0C317C314C3F4C304C304C3FFC3FFC00000000\r
+200 FFFF2448FFFF244824482448FFFF2448FFFF24482448FFFF2448FFFF24482448\r
+201 FFFF2549FFFF2549FFFF2549FFFF2549FFFF25492549FFFF2549FFFF25492549\r
+202 00000000231013200B4007803CF807800B401320231003000000000000000000\r
+203 00004210222012400A8007007FF807000A801240222042100000000000000000\r
+204 00000000102038707CF83870102000000000102038707CF83870102000000000\r
+205 FFFF3333CCCC3333CCCC3333CCCC3333FFFF3333CCCC3333FFFF3333CCCC3333\r
+206 FFFF3333FFFF3333CCCC3333FFFF3333FFFF3333FFFF3333FFFF3333FFFF3333\r
+207 738EE71CCE399C7338E771CEE39CC7398E731CE739CE739CE738CE719CE339C7\r
+208 FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333FFFFFFFF33333333\r
+209 3333333333333333333333333333333333333333333333333333333333333333\r
+210 0000249200002492000024920000249200002492000024920000249200002492\r
+211 00007FFE7FFE000000007FFE7FFE000000007FFE7FFE000000007FFE7FFE0000\r
+212 0000000000000000000000003FFC3FFC3FFC3FFC000000000000000000000000\r
+213 0000000022221414080814142222000022221414080814142222000000000000\r
+214 00000000300030003C000C000F00030003CC00CC00FC003C00FC00FC00000000\r
+215 AAAA000055550000AAAA000055550000AAAA000055550000AAAA000055550000\r
+216 0000000010202850448828501020000000001020285044882850102000000000\r
+217 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\r
+218 B6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DBB6DB\r
+219 B6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB0000B6DBB6DB\r
+220 7BDF7BDF7BDF7BDF7BDF00007BDF7BDF7BDF7BDF00007BDF7BDF7BDF7BDF0000\r
+221 7BDF4A594A597BDF7BDF00007BDF4A594A597BDF00007BDF4A594A597BDF0000\r
+222 7BDF4A514A514A517BDF00007BDF4A514A517BDF00007BDF4A514A517BDF0000\r
+223 7F7F7F7F7F7F7F7F7F7F7F7F7F7F00007F7F7F7F7F7F7F7F7F7F7F7F7F7F0000\r
+224 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+225 7F7F414141414141414141417F7F00007F7F414141414141414141417F7F0000\r
+226 7F7F41415D5D5D5D5D5D41417F7F00007F7F41415D5D5D5D5D5D41417F7F0000\r
+227 7F7F41415D5D55555D5D41417F7F00007F7F41415D5D55555D5D41417F7F0000\r
+228 BEBE41415D5D55555D5D4141BEBE8080BEBE41415D5D55555D5D4141BEBE8080\r
+229 A2A241411C1C14141C1C4141A2A28080A2A241411C1C14141C1C4141A2A28080\r
+230 A2A241410808141408084141A2A28080A2A241410808141408084141A2A28080\r
+231 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r
+232 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+233 FFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAAFFFFAAAAAAAAAAAA\r
+234 FFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAAFFFFAAAA\r
+\1a
\ No newline at end of file
diff --git a/symbols/misc25.sym b/symbols/misc25.sym
new file mode 100644 (file)
index 0000000..eb7c4c3
--- /dev/null
@@ -0,0 +1,661 @@
+ -25 -25 79/11/07.92 TONES ALPHANUMERICS AND PICTURES\r
+  1 00003C0000003C0000003C0000003C0000003C0000003C0000003C0000003C00\r
+  1 00003C0000003C0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00003C0000003C00\r
+  1 00003C0000003C0000003C0000003C0000003C0000003C0000003C0000003C00\r
+  1 00000000\r
+  2 00181818001818180018181800FFFFFF00FFFFFF001818180018181800181818\r
+  2 00181818001818180018181800FFFFFF00FFFFFF001818180018181800181818\r
+  2 00181818001818180018181800FFFFFF00FFFFFF001818180018181800181818\r
+  2 00000000\r
+  3 000618600006186000061860000618600006186000FFFFFF00FFFFFF00061860\r
+  3 00061860000618600006186000FFFFFF00FFFFFF000618600006186000061860\r
+  3 0006186000FFFFFF00FFFFFF0006186000061860000618600006186000061860\r
+  3 00000000\r
+  4 0007C3E00007C3E00007C3E00007C3E00007C3E000FFFFFF00FFFFFF00FFFFFF\r
+  4 00FFFFFF00FFFFFF0007C3E00007C3E00007C3E00007C3E000FFFFFF00FFFFFF\r
+  4 00FFFFFF00FFFFFF00FFFFFF0007C3E00007C3E00007C3E00007C3E00007C3E0\r
+  4 00000000\r
+  5 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+  5 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+  5 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+  5 00000000\r
+  6 0018181800181818001818180018181800181818001818180018181800181818\r
+  6 0018181800181818001818180018181800181818001818180018181800181818\r
+  6 0018181800181818001818180018181800181818001818180018181800181818\r
+  6 00000000\r
+  7 00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00000000\r
+  7 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+  7 0000000000FFFFFF00FFFFFF0000000000000000000000000000000000FFFFFF\r
+  7 00000000\r
+  8 0086186100861861008618610086186100861861008618610086186100861861\r
+  8 0086186100861861008618610086186100861861008618610086186100861861\r
+  8 0086186100861861008618610086186100861861008618610086186100861861\r
+  8 00000000\r
+  9 00E1C38700E1C38700E1C38700E1C38700E1C38700E1C38700E1C38700E1C387\r
+  9 00E1C38700E1C38700E1C38700E1C38700E1C38700E1C38700E1C38700E1C387\r
+  9 00E1C38700E1C38700E1C38700E1C38700E1C38700E1C38700E1C38700E1C387\r
+  9 00000000\r
+ 10 00FFFFFF00FFFFFF00FFFFFF0000000000000000000000000000000000FFFFFF\r
+ 10 00FFFFFF00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF\r
+ 10 00FFFFFF0000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF\r
+ 10 00000000\r
+ 11 00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D\r
+ 11 00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D\r
+ 11 00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D00B6DB6D\r
+ 11 00000000\r
+ 12 00CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF3\r
+ 12 00CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF3\r
+ 12 00CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF300CF3CF3\r
+ 12 00000000\r
+ 13 0000000000000000000000000000000000000000000000000000000000000000\r
+ 13 000000000000000000003C0000003C0000003C0000003C000000000000000000\r
+ 13 0000000000000000000000000000000000000000000000000000000000000000\r
+ 13 00000000\r
+ 14 0000000000000000000000000000000000000000000000000000000000000000\r
+ 14 0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00\r
+ 14 0000000000000000000000000000000000000000000000000000000000000000\r
+ 14 00000000\r
+ 15 00000000000000000000000000000000000FFFF0000FFFF0000FFFF0000FFFF0\r
+ 15 000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0\r
+ 15 000FFFF0000FFFF0000FFFF0000FFFF000000000000000000000000000000000\r
+ 15 00000000\r
+ 16 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 16 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 16 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 16 00000000\r
+ 17 00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF\r
+ 17 0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00\r
+ 17 00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF\r
+ 17 00000000\r
+ 18 00F07C1F00F07C1F00F07C1F00F07C1F00F07C1F000F83E0000F83E0000F83E0\r
+ 18 000F83E0000F83E000F07C1F00F07C1F00F07C1F00F07C1F00F07C1F000F83E0\r
+ 18 000F83E0000F83E0000F83E0000F83E000F07C1F00F07C1F00F07C1F00F07C1F\r
+ 18 00000000\r
+ 19 00CCCCCC00CCCCCC003333330033333300CCCCCC00CCCCCC0033333300333333\r
+ 19 00CCCCCC00CCCCCC003333330033333300CCCCCC00CCCCCC0033333300333333\r
+ 19 00CCCCCC00CCCCCC003333330033333300CCCCCC00CCCCCC0033333300333333\r
+ 19 00000000\r
+ 20 00E0000000E000000078000000780000001E0000001E00000007800000078000\r
+ 20 0001E0000001E000000078000000780000001E0000001E000000078000000780\r
+ 20 000001E0000001E000000078000000780000001E0000001E0000000700000007\r
+ 20 00000000\r
+ 21 00F0000000F0000000F0000000F0000000F00000000F8000000F8000000F8000\r
+ 21 000F8000000F800000007C0000007C0000007C0000007C0000007C00000003E0\r
+ 21 000003E0000003E0000003E0000003E00000001F0000001F0000001F0000001F\r
+ 21 00000000\r
+ 22 0080200800401004002008020010040100080200000401000002008000010040\r
+ 22 0000802000004010008020080040100400200802001004010008020000040100\r
+ 22 0002008000010040000080200000401000802008004010040020080200100401\r
+ 22 00000000\r
+ 23 00C00C0000E00E000070070000380380001C01C0000E00E00007007000038038\r
+ 23 0001C01C0000E00E000070070080380300C01C0100E00E000070070000380380\r
+ 23 001C01C0000E00E000070070000380380001C01C0000E00E0000700700003003\r
+ 23 00000000\r
+ 24 0080C06000C06030006030180030180C00180C06000C06030006030100030180\r
+ 24 000180C00000C0600080603000C030180060180C00300C0600180603000C0301\r
+ 24 00060180000300C0000180600080C03000C060180060300C0030180600180C03\r
+ 24 00000000\r
+ 25 00E00E0000E00E0000E00E00001C01C0001C01C0001C01C00003803800038038\r
+ 25 0003803800007007000070070000700700E00E0000E00E0000E00E00001C01C0\r
+ 25 001C01C0001C01C0000380380003803800038038000070070000700700007007\r
+ 25 00000000\r
+ 26 00C30C3000C30C300030C30C0030C30C000C30C3000C30C300C30C3000C30C30\r
+ 26 0030C30C0030C30C000C30C3000C30C300C30C3000C30C300030C30C0030C30C\r
+ 26 000C30C3000C30C300C30C3000C30C300030C30C0030C30C000C30C3000C30C3\r
+ 26 00000000\r
+ 27 000000000000000F000000FF00000FFF0000FFFF000FFFF000FFFF0000FFF000\r
+ 27 00FF000000F00000000000000000000000000000000000000000000F000000FF\r
+ 27 00000FFF0000FFFF000FFFF000FFFF0000FFF00000FF000000F0000000000000\r
+ 27 00000000\r
+ 28 00C0000300C000030030000C0030000C000C0030000C0030000300C0000300C0\r
+ 28 0000C3000000C30000003C0000003C0000003C0000003C000000C3000000C300\r
+ 28 000300C0000300C0000C0030000C00300030000C0030000C00C0000300C00003\r
+ 28 00000000\r
+ 29 00E0000700E0000700E00007001C0038001C0038001C0038000381C0000381C0\r
+ 29 000381C000007E0000007E0000007E0000007E0000007E0000007E00000381C0\r
+ 29 000381C0000381C0001C0038001C0038001C003800E0000700E0000700E00007\r
+ 29 00000000\r
+ 30 0080000600C0000E00E0001C00700038001C0038000E0070000700E0000381C0\r
+ 30 0001C3800000E70000007E0000003C0000003C0000007E000000E7000001C380\r
+ 30 000381C0000700E0000E0070001C00380038001C0070000E00E0000700C00003\r
+ 30 00000000\r
+ 31 00E0000700E000070078001E0078001E001E0078001E0078000781E0000781E0\r
+ 31 0001E7800001E78000007E0000007E0000007E0000007E000001E7800001E780\r
+ 31 000781E0000781E0001E0078001E00780078001E0078001E00E0000700E00007\r
+ 31 00000000\r
+ 32 00F0001F00F0001F00F0001F00F0001F00F0001F000F83E0000F83E0000F83E0\r
+ 32 000F83E0000F83E000007C0000007C0000007C0000007C0000007C00000F83E0\r
+ 32 000F83E0000F83E0000F83E0000F83E000F0001F00F0001F00F0001F00F0001F\r
+ 32 00000000\r
+ 33 00C0180300E018070070180E0038181C001C1838000E1870000718E0000399C0\r
+ 33 0001C3800000E70000007E0000FF3CFF00FF3CFF00007E000000E7000001C380\r
+ 33 000399C0000718E0000E1870001C18380038181C0070180E00E0180700C01803\r
+ 33 00000000\r
+ 34 00F0000F00F0000F0078001E0078001E003C003C003C003C001E0078001E0078\r
+ 34 000F00F0000F00F00007FFE00007FFE00007FFE00007FFE0000F00F0000F00F0\r
+ 34 001E0078001E0078003C003C003C003C0078001E0078001E00F0000F00F0000F\r
+ 34 00000000\r
+ 35 009024090060180600601806009024090008421000048120000300C0000300C0\r
+ 35 0004812000084210009024090060180600601806009024090008421000048120\r
+ 35 000300C0000300C0000481200008421000902409006018060060180600902409\r
+ 35 00000000\r
+ 36 00C03C0300C03C030030C30C0030C30C000F00F0000F00F0000F00F0000F00F0\r
+ 36 0030C30C0030C30C00C03C0300C03C0300C03C0300C03C030030C30C0030C30C\r
+ 36 000F00F0000F00F0000F00F0000F00F00030C30C0030C30C00C03C0300C03C03\r
+ 36 00000000\r
+ 37 0099CCE6003399CC0067379900CE6733009CCE6700399CCE0073399C0099CCE6\r
+ 37 00CCE67300E673390073399C00399CCE009CCE6700CE673300E6733900CCE673\r
+ 37 0099CCE6003399CC0067339900673399003399CC00673399003399CC0099CCE6\r
+ 37 00000000\r
+ 38 0018C3180031818C006318C600C63C63008C66310018C3180031818C006318C6\r
+ 38 00C63C63008C66310018C3180031818C006318C600C63C63008C66310018C318\r
+ 38 0031818C006318C600C63C63008C66310018C3180031818C006318C600C63C63\r
+ 38 00000000\r
+ 39 00C63C63006318C60031818C0018C318008C663100C63C63006318C60031818C\r
+ 39 0018C318008C663100C63C63006318C6006318C600C63C63008C66310018C318\r
+ 39 0031818C006318C600C63C63008C66310018C3180031818C006318C600C63C63\r
+ 39 00000000\r
+ 40 00003C0000003C000000C3000000C300000300C0000300C0000C0030000C0030\r
+ 40 0030000C0030000C00C0000300C0000300C0000300C000030030000C0030000C\r
+ 40 000C0030000C0030000300C0000300C00000C3000000C30000003C0000003C00\r
+ 40 00000000\r
+ 41 0000180000003C0000003C0000007E0000007E000000FF000000FF000001FF80\r
+ 41 0001FF800003FFC00003FFC00007FFE00007FFE0000FFFF0000FFFF0001FFFF8\r
+ 41 001FFFF8003FFFFC003FFFFC007FFFFE007FFFFE000FFFF0000FFFF0000FFFF0\r
+ 41 00000000\r
+ 42 00FFFFFF00FFFFFF00FFFFFF00FFBDFF00FFBDFF00FF3CFF00FF7EFF00FE7E7F\r
+ 42 00FE7E7F00FCFF3F00FCFF3F00F8FF1F00F9FF9F00F1FF8F00F1FF8F00E3FFC7\r
+ 42 00E3FFC700C3FFC300C7FFE30087FFE10087FFE100FFFFFF00FFFFFF00FFFFFF\r
+ 42 00000000\r
+ 43 01FFFFFF01000001010000010100000101000001010000010100000101000001\r
+ 43 0100000101000001010000010100000101000001010000010100000101000001\r
+ 43 0100000101000001010000010100000101000001010000010100000101000001\r
+ 43 01FFFFFF\r
+ 44 000000000060180600601806000000000000000000000000000300C0000300C0\r
+ 44 0000000000000000000000000060180600601806000000000000000000000000\r
+ 44 000300C0000300C0000000000000000000000000006018060060180600000000\r
+ 44 00000000\r
+ 45 0000000000C30C3000C30C300000000000186186001861860000000000C30C30\r
+ 45 00C30C300000000000186186001861860000000000C30C3000C30C3000000000\r
+ 45 00186186001861860000000000C30C3000C30C30000000000018618600186186\r
+ 45 00000000\r
+ 46 00CCCCCC00CCCCCC003333330033333300CCCCCC00CCCCCC0033333300333333\r
+ 46 00CCCCCC00CCCCCC003333330033333300CCCCCC00CCCCCC0033333300333333\r
+ 46 00CCCCCC00CCCCCC003333330033333300CCCCCC00CCCCCC0033333300333333\r
+ 46 00000000\r
+ 47 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 47 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 47 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 47 00000000\r
+ 48 00000000000018000000180000C018060060180C003018180018183800181870\r
+ 48 000C1870000C18E0000638E0000638E0000339C0000339C0000339C00001BB80\r
+ 48 0001BB800001BB80003FFFF8003FFFF8000000000000000000000FFE00000FFE\r
+ 48 00000000\r
+ 49 00000000000010000000380000007C000000FE000001FF000003FF800007FFC0\r
+ 49 000FFFE0001FFFF0003FFFF8007FFFFC0080000200FFFFFE00FFFFFE00FFFFFE\r
+ 49 00FFF1FE00C631C600C631C600FFF1FE00FFF1FE00FFF1FE00FFF1FE00000000\r
+ 49 00000000\r
+ 50 00000000000010000000380000007C000000FE000001FF000003FF800007FFC0\r
+ 50 000FFFE0001FFFF0003FFFF8007FFFFC00FFFFFE00FFFFFE00FFFFFE00FFFFFE\r
+ 50 00FFFFFE00FFFFFE00FFFFFE00FFFFFE00FFFFFE00FFFFFE00FFFFFE00000000\r
+ 50 00000000\r
+ 51 00EEEEEE00777777007BBBBB00EEEEEE00777777007BBBFB00EEFFBE007777F7\r
+ 51 007BBFFB00EEEFFE00777FF7007BBFFB00EEFFFE00777FF7007BBFFB00EEEFFE\r
+ 51 007777F7007BBBFB00EEEFFE007777F7007BBBFB00EEEEEE00777777007BBBBB\r
+ 51 00000000\r
+ 52 0000180000003C0000003C0000007E0000007E000000FF000000FF000001FF80\r
+ 52 0001FF800003FFC00003FFC00007FFE00007FFE0000FFFF0000FFFF0001FFFF8\r
+ 52 001FFFF8003FFFFC003FFFFC007FFFFE007FFFFE000FFFF0000FFFF0000FFFF0\r
+ 52 00000000\r
+ 53 00E0000700E000070078001E0078001E001E0078001E0078000781E0000781E0\r
+ 53 0001E7800001E78000007E0000007E0000007E0000007E000001E7800001E780\r
+ 53 000781E0000781E0001E0078001E00780078001E0078001E00E0000700E00007\r
+ 53 00000000\r
+ 54 000000000100080001801C0101C03E0300C0360300606306006063060070E38E\r
+ 54 0039C1DC003FC1FC001F80F800060020000000000100080001801C0101C03E03\r
+ 54 0080360300606306006063060070E38E0039C1DC003FC1FC001F80F800060020\r
+ 54 00000000\r
+ 55 00007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00\r
+ 55 00007E0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00007E00\r
+ 55 00007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00\r
+ 55 00000000\r
+ 56 00003C0000003C0000003C0000003C0000003C0000003C0000003C0000003C00\r
+ 56 00003C0000003C0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00003C0000003C00\r
+ 56 00003C0000003C0000003C0000003C0000003C0000003C0000003C0000003C00\r
+ 56 00000000\r
+ 57 00000000000010000000380000006C000000C6000001830000033980000644C0\r
+ 57 000C446000184430003038180070001C00FFFFFE00B0001E00307C1800304418\r
+ 57 0030441800304418003044180030441800304418003FFFF8003FFFF800000000\r
+ 57 00000000\r
+ 58 00000000000000000060000C0060000C00000000000000000000000000000000\r
+ 58 000000000000C6000000C6000000000000000000000000000000C6000000C600\r
+ 58 00000000000000000000000000000000000000000060000C0060000C00000000\r
+ 58 00000000\r
+ 59 0000000000606060006060600000000000000000000606060006060600000000\r
+ 59 0000000000606060006060600000000000000000000606060006060600000000\r
+ 59 0000000000606060006060600000000000000000000606060006060600000000\r
+ 59 00000000\r
+ 60 0088888800000000002222220000000000888888000000000022222200000000\r
+ 60 0088888800000000002222220000000000888888000000000022222200000000\r
+ 60 0088888800000000002222220000000000888888000000000022222200000000\r
+ 60 00000000\r
+ 61 0007C3E00007C3E00007C3E00007C3E00007C3E000FFFFFF00FFFFFF00FFFFFF\r
+ 61 00FFFFFF00FFFFFF0007C3E00007C3E00007C3E00007C3E000FFFFFF00FFFFFF\r
+ 61 00FFFFFF00FFFFFF00FFFFFF0007C3E00007C3E00007C3E00007C3E00007C3E0\r
+ 61 00000000\r
+ 62 00AAAAAA00000000005555550000000000AAAAAA000000000055555500000000\r
+ 62 00AAAAAA00000000005555550000000000AAAAAA000000000055555500000000\r
+ 62 00AAAAAA00000000005555550000000000AAAAAA000000000055555500000000\r
+ 62 00000000\r
+ 63 00AAAAAA0055555500AAAAAA0055555500AAAAAA0055555500AAAAAA00555555\r
+ 63 00AAAAAA0055555500AAAAAA0055555500AAAAAA0055555500AAAAAA00555555\r
+ 63 00AAAAAA0055555500AAAAAA0055555500AAAAAA0055555500AAAAAA00555555\r
+ 63 00000000\r
+ 64 01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF\r
+ 64 01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF\r
+ 64 01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF01FFFFFF\r
+ 64 01FFFFFF\r
+ 65 000000000000000000000000000000000000000000000000000600C0000600C0\r
+ 65 0000000000000000000000000000000000000000000000000000000000000000\r
+ 65 00000000000600C0000600C00000000000000000000000000000000000000000\r
+ 65 00000000\r
+ 66 0000000000000000000000000000000000000000000000000000000000000000\r
+ 66 0000000000000000003FFFF8003FFFF8003FFFF8003FFFF80000000000000000\r
+ 66 0000000000000000000000000000000000000000000000000000000000000000\r
+ 66 00000000\r
+ 67 00F0001F00F0001F00F0001F00F0001F00F0001F000F83E0000F83E0000F83E0\r
+ 67 000F83E0000F83E000007C0000007C0000007C0000007C0000007C00000F83E0\r
+ 67 000F83E0000F83E0000F83E0000F83E000F0001F00F0001F00F0001F00F0001F\r
+ 67 00000000\r
+ 68 0000000000000000000000000000000000000000000000000000000000000000\r
+ 68 000000000000000000003C0000003C0000003C0000003C000000000000000000\r
+ 68 0000000000000000000000000000000000000000000000000000000000000000\r
+ 68 00000000\r
+ 69 0000000000000000000000000000000000000000000000000000000000000000\r
+ 69 0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00\r
+ 69 0000000000000000000000000000000000000000000000000000000000000000\r
+ 69 00000000\r
+ 70 00000000000000000000000000000000000FFFF0000FFFF0000FFFF0000FFFF0\r
+ 70 000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0\r
+ 70 000FFFF0000FFFF0000FFFF0000FFFF000000000000000000000000000000000\r
+ 70 00000000\r
+ 71 00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FC003F00FC003F\r
+ 71 00FCFF3F00FCFF3F00FCFF3F00FCFF3F00FCFF3F00FCFF3F00FCFF3F00FCFF3F\r
+ 71 00FC003F00FC003F00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF\r
+ 71 00000000\r
+ 72 0000000000C0000600E0000E0070001C00380038001C0070000E00E0000701C0\r
+ 72 000383800001C7000000EE0000007C000000380000007C000010EE300039C738\r
+ 72 007F83FC00FF01FE00FF00FE00FF81FE00FFC3FE00FF81FE00FF00FE00FE007E\r
+ 72 00000000\r
+ 73 00C0180300E018070070180E0038181C001C1838000E1870000718E0000399C0\r
+ 73 0001C3800000E70000007E0000FF3CFF00FF3CFF00007E000000E7000001C380\r
+ 73 000399C0000718E0000E1870001C18380038181C0070180E00E0180700C01803\r
+ 73 00000000\r
+ 74 0000000000000000000000000000380000006C000000C6000001830000030180\r
+ 74 000600C0000C006000180030003000180060000C0030001800180030000C0060\r
+ 74 000600C000030180000183000000C60000006C00000038000000100000000000\r
+ 74 00000000\r
+ 75 00FFFFFF00FFFFFF00FFC3FF00FFC3FF00FFC3FF00FFC3FF00FFC3FF00FFC3FF\r
+ 75 00FFC3FF00FFC3FF00C0000300C0000300C0000300C0000300FFC3FF00FFC3FF\r
+ 75 00FFC3FF00FFC3FF00FFC3FF00FFC3FF00FFC3FF00FFC3FF00FFFFFF00FFFFFF\r
+ 75 00000000\r
+ 76 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+ 76 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+ 76 00000000000000000000000000FFFFFF00FFFFFF000000000000000000000000\r
+ 76 00000000\r
+ 77 00003F8000003F8000003F8000003F8000003F8000003F8000003F80001FFFFF\r
+ 77 001FFFFF001FFFFF001FFFFF001FFFFF001FFFFF001FFFFF00003F8000003F80\r
+ 77 00003F8000003F8000003F8000003F8000000000000000000000000000000000\r
+ 77 00000000\r
+ 78 000000000000000000000E0000008E200001CE700003EEF80001FFF00000FFE0\r
+ 78 00007FC00007FFFC0007FFFC0007FFFC00007FC00000FFE00001FFF00003EEF8\r
+ 78 0001CE7000008E2000000E000000000000000000000000000000000000000000\r
+ 78 00000000\r
+ 79 000007E0000007E0000007E0000007E000000FC000000FC000000FC000001F80\r
+ 79 00001F8000001F8000003F0000003F0000003F0000007E0000007E0000007E00\r
+ 79 0000FC000000FC000000FC000001F80000000000000000000000000000000000\r
+ 79 00000000\r
+ 80 0000040000007FC00000FFE00001FFF00003FFF80003F4F80003F4F80003F400\r
+ 80 0003FF800003FFE00001FFF000007FF800000FF80007E5F80007E5F80007F5F8\r
+ 80 0003FFF80003FFF00001FFE000007F8000000000000000000000000000000000\r
+ 80 00000000\r
+ 81 00000000000000000000000000000000001FFFFF001FFFFF001FFFFF001FFFFF\r
+ 81 001FFFFF000000000000000000000000001FFFFF001FFFFF001FFFFF001FFFFF\r
+ 81 001FFFFF00000000000000000000000000000000000000000000000000000000\r
+ 81 00000000\r
+ 82 0000FFC00000FFC00000FFC00000FFC00000FFC00000F8000000F8000000F800\r
+ 82 0000F8000000F8000000F8000000F8000000F8000000F8000000F8000000F800\r
+ 82 0000FFC00000FFC00000FFC00000FFC000000000000000000000000000000000\r
+ 82 00000000\r
+ 83 0000FFC00000FFC00000FFC00000FFC00000FFC0000007C0000007C0000007C0\r
+ 83 000007C0000007C0000007C0000007C0000007C0000007C0000007C0000007C0\r
+ 83 0000FFC00000FFC00000FFC00000FFC000000000000000000000000000000000\r
+ 83 00000000\r
+ 84 0000000000000000000000000000000000001F0000001F0000001F0000001F00\r
+ 84 00001F0000000000000000000000000000001F0000001F0000001F0000001F00\r
+ 84 00001F0000000000000000000000000000000000000000000000000000000000\r
+ 84 00000000\r
+ 85 0000007000000070000000E0000000E0001FFFFF001FFFFF001FFFFF001FFFFF\r
+ 85 001FFFFF0000070000000E0000000E00001FFFFF001FFFFF001FFFFF001FFFFF\r
+ 85 001FFFFF0000E0000000E0000001C00000000000000000000000000000000000\r
+ 85 00000000\r
+ 86 000000000000000000000000000000000000000000000300000003C00001FFF0\r
+ 86 0001FFF80001FFF00001C3C00001C3000001C0000001C0000001C0000001C000\r
+ 86 0000000000000000000000000000000000000000000000000000000000000000\r
+ 86 00000000\r
+ 87 0000000000000000000000000000000000000000000FC07E0007E0FC0003F1F8\r
+ 87 0001FBF00000FFE000007FC000003F8000001F0000000E000000040000000000\r
+ 87 0000000000000000000000000000000000000000000000000000000000000000\r
+ 87 00000000\r
+ 88 00000000000000000000000000000000000000000000040000000E0000001F00\r
+ 88 00003F8000007FC00000FFE00001FBF00003F1F80007E0FC000FC07E00000000\r
+ 88 0000000000000000000000000000000000000000000000000000000000000000\r
+ 88 00000000\r
+ 89 0000000000000000000000000000040000000E0000000E0000001F0000001F00\r
+ 89 00003F8000003F8000000E0000000E0000000E0000000E0000000E0000000E00\r
+ 89 00000E0000000E00000000000000000000000000000000000000000000000000\r
+ 89 00000000\r
+ 90 00000000000000000000000000000E0000000E0000000E0000000E0000000E00\r
+ 90 00000E0000000E0000000E0000003F8000003F8000001F0000001F0000000E00\r
+ 90 00000E0000000400000000000000000000000000000000000000000000000000\r
+ 90 00000000\r
+ 91 000000000000002000000060000000E0000001E0000003E0000007E000000FC0\r
+ 91 00001F8000003F0000007E0000003F0000001F8000000FC0000007E0000003E0\r
+ 91 000001E0000000E0000000600000002000000000000000000000000000000000\r
+ 91 00000000\r
+ 92 01FFFFFF01000001010000010100000101000001010000010100000101000001\r
+ 92 0100000101000001010000010100000101000001010000010100000101000001\r
+ 92 0100000101000001010000010100000101000001010000010100000101000001\r
+ 92 01FFFFFF\r
+ 93 000000000000000000040000000E000000FBE00000F1E0000000000000000000\r
+ 93 0000000000000000000001000000038000003EF800003C780000000000000000\r
+ 93 000000000000000000040000000E000000FBE00000F1E0000000000000000000\r
+ 93 00000000\r
+ 94 0147C011004000220080002401020011000D001E0191DF07002520000022A000\r
+ 94 004420000048407C00218000003E0000000000400007E1A000000220000005BC\r
+ 94 00000444000008A400F8090800000580000007C00000000200007C0D00000011\r
+ 94 01C00035\r
+ 95 0000000000000000000000000001800001E683E1001080000010800000228000\r
+ 95 002A80000044BE1F007B000000190000002A0380004C02400048022000400290\r
+ 95 004E0248002002680010014800080138000400A0003E0F94000000C000000100\r
+ 95 00000200\r
+ 96 0000000000080040007F03F80000000000000000000000000000400200307F03\r
+ 96 38000000000000000000000000100040007F03F8000000000000000000000000\r
+ 96 000040020183F81F00000000000000000000000000080040007F03F800000000\r
+ 96 00000000\r
+ 97 0080410200C840960035806C0002000000000000007C1F000000000000000000\r
+ 97 00002C0000005A00003E653E0001C100000100800000C1000001808000009500\r
+ 97 00004200001F1CF8000000000000000000080020003603EC00CC029400A2850A\r
+ 97 00804202\r
+ 98 00000000000001F0003160000015C000007880000002E00001083E0F00080000\r
+ 98 000800000000062C00000290001F0F3800000210000002E00000010000316100\r
+ 98 001481000079C1000010800000070000000800000181F0070008000000000000\r
+ 98 00000000\r
+ 99 000000000003E7C0000000000010000000240000002401800018024000100240\r
+ 99 0011F18000100100001001000010010000000100000001000000C00001F1203E\r
+ 99 000120000000C00000008000000080000000FC00003E80000000800000000000\r
+ 99 00000000\r
+100 0000000C007C03E8000000080000400000028A000001240001F12E3E0003B400\r
+100 000258000004E1000000220001C16E030003B100000268000004300000002000\r
+100 003E23E00000000000000400000000420000004401E07C290000001800000008\r
+100 0000000A\r
+101 0003E0A0000800A0001C02C0001C0580001C0080011C3E8F0028008000588080\r
+101 00094080000A0080000A7C80000A0080002C0080005800000008000000080000\r
+101 000BE09F000801C0000801C0000801C0000801C0007C025F000805C800000094\r
+101 00000080\r
+102 0000000000021F000017000000080004007000080028041000040300000E0320\r
+102 001200E00001001000008008003E07C800000010000000200000600000088000\r
+102 01C51F1800020000000180000000800000030000000400F80008000000000000\r
+102 00000000\r
+103 0000000000000000003E03E0000000000000000000888888000000000000F81E\r
+103 0000000000222051000000000000000001F0F83E000000000000000000888888\r
+103 0000000000000000001F03E00000000000000000002222110000000001F0F83E\r
+103 00000000\r
+104 00000000000F803E0000000000040000000E3E0000040000001F000000040000\r
+104 003F809F00040080007FC1C0000401C000FFE3E0000403E0000407F0000007F0\r
+104 0007CFF800000FF800001FFC0000040000000000003E03E00000000000000000\r
+104 00000000\r
+105 0000000000038000000863E0000740000030B000004BC8000029500000444800\r
+105 0012803E00010000000103700001014C007D02E800010E96000113F4000842D0\r
+105 00008888000004A00007C040000000400000004000000001003E005F00000040\r
+105 00000001\r
+106 0000000000080000009441020023A00000265000005480000023201000279000\r
+106 002D2040001AD0A00009E1500009423000090108001122590009021000090188\r
+106 00000210000002B000040530000000E000000040000000400040404200000040\r
+106 00000040\r
+107 00010060000101F00000020C000005B200204C65000000980000000000040821\r
+107 00000020000000200000002000000020004180620007C020000A7000000A7000\r
+107 0025C400001B342000600A000001000000010000000100000041100800010000\r
+107 00010000\r
+108 00000000000F810200086000000740000030B000004BC8100029600000444800\r
+108 0012820200010000000103700041010C000102E800010E96000113F400010A5A\r
+108 00201111000004A0000000400000004000000040004082440000004000000040\r
+108 00000040\r
+109 00000000000000000004CC04004D308000366B0000D8CC0000AB2300016DB8C1\r
+109 00202300005144800088884000049000000221020001C0000000800000208810\r
+109 0000800000008000000080000002810000008000000080000040A00800008000\r
+109 00000000\r
+110 0000000000000000000000000040404000000000000000000004740000019800\r
+110 0002C600000635000002A4000010CB000001B6000082A90400010D000000FA00\r
+110 0008820000001000000010000000100000001000004090080000100000000000\r
+110 00000000\r
+111 0080450200C840960035806C0010000000000000004040200000000000000000\r
+111 00002C0000045A02000065000001C100020000800000C100004180A000009500\r
+111 0000404000001C00010101020000000000080020003603EC00CD829400A2850A\r
+111 00804202\r
+112 00000000000000000020820400000080000001C000040882000002A0000001C0\r
+112 00000480000002A0004211C100070490001002A0000A81C00007008000124080\r
+112 000A80000007040800124000000A900000070000004200800002000000000000\r
+112 00004004\r
+113 0000075C004041F00000004000000F5E000003F800020040000A804000470000\r
+113 00020208001AC000000F800000020000003AE040000F800000020000007AF000\r
+113 001FC204000200000002004000000150002020E00000004000000358000201F0\r
+113 00000040\r
+114 000000000000004000080840000000E0000000E0000001F0004081F1000003F8\r
+114 000003F8000007FC000207FC01024FFE0007004000070000000F8000000F8000\r
+114 001FC204001FC000003FE000003FE000007FF020001000000000000000000000\r
+114 00101008\r
+115 0000000000040082000000800000014000000140002012200000022000000410\r
+115 00000410000088080000080800021FFC00020080004500100005000000088000\r
+115 0008820200104000001040000020200000202020007FF0000002000000000202\r
+115 00000000\r
+116 0000000000080000000840200014000000080000001C0000002A0000001C0402\r
+116 002A0000005D0000003E008000550080008A894200080080000001C0000002A0\r
+116 000001C0002042A1000005D0000003E00000055000020AA80000008000000000\r
+116 00402008\r
+117 000000000000000000FFFFF8009202480012024000020201000202000003FE00\r
+117 00040100001800800020003000401C08018066060000D2010001820000030200\r
+117 00020400000204000002080000023000001C4000000880000000900000028000\r
+117 00018000\r
+118 000000000000000000000000000000000000000000000018000FFFF800100038\r
+118 002000580040009A00FFFF390080013900800139009999390099993900999938\r
+118 0081810000000000000000000000000000000000000000000000000000000000\r
+118 00000000\r
+119 0000000000000000000000000000000000000000000000000000000000000000\r
+119 003FFFF80060000400900002010800010107FFFF010400010105EF790105EF79\r
+119 00C5EF790031EF790019EF790000000300000003000000000000000000000000\r
+119 00000000\r
+120 00000000000000000000000000000000000000000000000000000400000FFFE0\r
+120 00100050002000880040010400FFFE020080020200BE027200BEDB7200BEDA72\r
+120 00BEDA0200BE1800000000000000000000000000000000000000000000000000\r
+120 00000000\r
+121 000000000000000000000000000000000000FF800001C0E00003003000060030\r
+121 000C001800181C0C0010220C0010210C0010220C00181C0C0018000C000C000C\r
+121 00060018000300700000FFC000000E0000000000000000000000000000000000\r
+121 00000000\r
+122 0000000000000000000000000000000000000000000000000000000000000000\r
+122 000000000001FF00000701C0001800600018C630001C1838003F7D9C00000000\r
+122 0000000000000000000000000000000000000000000000000000000000000000\r
+122 00000000\r
+123 0000000000000000000000000000000000000000000000000000280000002800\r
+123 0000280000001000000028000000280000004400000044000000820000008200\r
+123 0001110000011100000238800002388000047C4000047C40000C7E4000000000\r
+123 00000000\r
+124 000000000000000000000000000000000000000000007F800000818000010380\r
+124 0003FC8000020480000204800002648000026480000204800002048000020480\r
+124 00020500000206000003FE000000020000000200000002000000020000000200\r
+124 00000200\r
+125 000400200044422200248124001500A8000A0050001F00F8000000000003E01F\r
+125 00000000000010010021111100409209008054050100280201807C0700000000\r
+125 01F00F80000400200044422200248124001500A8000A0050001F00F800000000\r
+125 00007C03\r
+126 012492490012492400924924009249240092492401B6DB6D0124924901249249\r
+126 01249249016DB6DB004924920049249200492492016DB6DB0124924901249249\r
+126 0124924901B6DB6D00924924009249240092492401B6DB6D0124924901249249\r
+126 01249249\r
+127 0000000000FFFFFE040000020080000200800002008000020083FF820083FF82\r
+127 008301820083018200830182008301820083FF820083FF820083000200830002\r
+127 0083000200830002008300020083000200830002008000020080000200FFFFFE\r
+127 00000000\r
+128 0000000000000000000000000000000000000000000000000000000000000000\r
+128 00000010000000300000005000000090000FFFF000020210000FFFF000020010\r
+128 0002001000020010000000000000000000000000000000000000000000000000\r
+128 00000000\r
+129 00000000000000000000000001FFFFFF00210422004208240084104400880044\r
+129 0111FC8800120400000404000007FCC000040D200007FE2000040E400007FC81\r
+129 00040D820007FF02000C0E0400147F8C00600080007FFF000000000000000000\r
+129 00000000\r
+130 000000000000000000000000000000000000000000000000000070000000F800\r
+130 0000F800000000000000FFFC0000FFC00001FC000001FC000001FC000003FE00\r
+130 0003FE000007FF000007FF000007FF0000000000000000000000000000000000\r
+130 00000000\r
+131 002082080071C71C00FBEFBE0071C71C0020820800041041010E38E3019F7DF7\r
+131 0171C71C000410410061861800F3CF3C00F3CF3C0061861800000000000C30C3\r
+131 0112492401924924000C30C30022222A00777B77002222220088888801DDDDDD\r
+131 00888888\r
+132 0022222201777777002222220088888801DDDDDD008888880186186002492491\r
+132 0049249101861860000000000030C30C0079E79E0079E79E0030C30C01041040\r
+132 018E38E101DF7DF3018E38E1010410400020820800F1C71C00FBEFBE0071C71C\r
+132 00208208\r
+133 0000000000000000000000000000000000000000000000000000000000000000\r
+133 0000000000000000000000000000000000000000000000000000000000000000\r
+133 00000000000000000155555500AAAAAA00AAAAAA00AAAAAA00AAAAAA00AAAAAA\r
+133 01555555\r
+134 0104000000F800000104000000F800000104000000F800000104000000F80000\r
+134 0104000000F800000104000000F800000104000000F800000104000000F80000\r
+134 0104000000F800000104000000F800000104000000F800000104000000F80000\r
+134 01040000\r
+135 015000000098000001240000004A00000193000000A480000049400000326000\r
+135 001490000009280000064C00000292000002A5000000C9800000524000002480\r
+135 0000193000000A48000004940000032600000149000000920000006400000029\r
+135 00000012\r
+136 000000140000003200000049000000A4000001930000024A0000052400000C98\r
+136 00001250000029200000648000009280000149000003260000049400000A4800\r
+136 001930000024A0000052400000C980000125000000920000004C000001280000\r
+136 00900000\r
+137 000000060000000900000015000000320000004C000000A80000019000000260\r
+137 0000054000000C800000130000002A0000006400000098000001500000032000\r
+137 0004C000000A800000190000002600000054000000C800000230000000B00000\r
+137 00400000\r
+138 0040000000A000000130000000C80000005400000026000000190000000A8000\r
+138 0004C0000003200000015000000098000000640000002A000000130000000C80\r
+138 000005400000026000000190000000A80000004C000000320000001500000009\r
+138 00000006\r
+139 0120000001E000000120000001E000000120000001E000000120000001E00000\r
+139 0120000001E000000120000001E000000120000001E000000120000001E00000\r
+139 0120000001E000000120000001E00000012000000120000001E0000001200000\r
+139 01E00000\r
+140 0000000000000000000000000000000000000000000000000000000000000000\r
+140 0000000000000000000000000000000000000000000000000000000000000000\r
+140 000000000000000000000000000000000000000001FFFFFF00AAAAAA00AAAAAA\r
+140 01FFFFFF\r
+141 0040000000200000011000000088000000400000002000000001000000008000\r
+141 0004400000022000000100000000800000000400000002000000110000000880\r
+141 0000040000000200000000100000000800000040000000220000001000000008\r
+141 00000000\r
+142 0000000000000008000000100000002200000044000000080000001000000200\r
+142 0000040000000880000011000000020000000400000080000001000000022000\r
+142 0004400000008000000100000020000000400000008000000110000000200000\r
+142 00400000\r
+143 0000000000000000000000000000000000000000000000000000000000000000\r
+143 0000000000000000000000000000000000000000000000000000000000000000\r
+143 000000000000000000000000000000000000000000F8F87C0000000000000000\r
+143 00F8F87C\r
+144 0000000000000000012000000120000001200000012000000120000000000000\r
+144 0000000000000000012000000120000001200000012000000120000000000000\r
+144 0000000000000000000000000120000001200000012000000120000001200000\r
+144 00000000\r
+145 0000000400000008000000110000002200000044000000880000011000000220\r
+145 0000044000000880000011000000220000004400000088000001100000022000\r
+145 0004400000088000001100000022000000440000008800000110000000200000\r
+145 00400000\r
+146 0040000000200000011000000088000000440000002200000011000000088000\r
+146 0004400000022000000110000000880000004400000022000000110000000880\r
+146 0000044000000220000001100000008800000044000000220000001100000008\r
+146 00000004\r
+147 0120000001200000012000000120000001200000012000000120000001200000\r
+147 0120000001200000012000000120000001200000012000000120000001200000\r
+147 0120000001200000012000000120000001200000012000000120000001200000\r
+147 01200000\r
+148 0000000000000000000000000000000000000000000000000000000000000000\r
+148 0000000000000000000000000000000000000000000000000000000000000000\r
+148 000000000000000000000000000000000000000001FFFFFF0000000000000000\r
+148 01FFFFFF\r
+149 0080000001C0000000E000000070000000380000001800000000000000000000\r
+149 000080000001C0000000E0000000700000003800000018000000000000000000\r
+149 00000080000001C0000000E00000007000000070000000180000000000000000\r
+149 00000000\r
+150 00000002000000070000000E0000001C00000038000000300000000000000000\r
+150 000002000000070000000E0000001C0000003800000030000000000000000000\r
+150 0002000000070000000E0000001C000000380000003000000000000000000000\r
+150 00000000\r
+151 0000000000000000000000000000000000000000000000000000000000000000\r
+151 0000000000000000000000000000000000000000000000000000000000000000\r
+151 00000000000000000000000000000000000000000000000001F1F9F000F8F8F8\r
+151 01F1F1F0\r
+152 0140000001C0000001C0000001C0000001C00000008000000000000000000000\r
+152 0140000001C0000001C0000001C0000001C00000008000000000000000000000\r
+152 0140000001C0000001C0000001C0000001C00000008000000000000000000000\r
+152 00000000\r
+153 010000000100000001000000010000000180000000C000000040000000400000\r
+153 00C000000080000000C0000000C00000004000000040000000C0000000C00000\r
+153 018000000180000000C0000000C0000000800000008000000180000001000000\r
+153 00000000\r
+154 0000000000000000000000000000000000000000000000000000000000000000\r
+154 0000000000000000000000000000000000000000000000000000000000000000\r
+154 000000000000000000000000000000000000000000000C0000007E000079C7CC\r
+154 01CF007F\r
+155 0000000100000003000000060000000C00000078000000C00000008000000080\r
+155 00000180000001000000070000000C00000038000000F0000000800000078000\r
+155 000C0000001800000010000000300000000000000020000000E0000001800000\r
+155 01800000\r
+156 010000000180000000C000000040000000700000001C00000004000000070000\r
+156 0001800000000000000040000000100000000400000000000000010000000180\r
+156 00000080000000E00000003800000008000000080000000C0000000400000007\r
+156 00000001\r
+157 0180000001800000018000000180000001800000018000000000000000000000\r
+157 0000000001800000018000000180000001800000018000000000000000000000\r
+157 0000000001800000018000000180000001800000018000000180000000000000\r
+157 00000000\r
+158 0000000000000000000000000000000000000000000000000000000000000000\r
+158 0000000000000000000000000000000000000000000000000007000000070000\r
+158 0007000000070000000200000002000000020000000200000002000001FAFC7C\r
+158 01FAFC7C\r
+159 00000000000000000000000C000000180000003000000060000000C000000000\r
+159 000700000007060000070C000007180000023000000260000002C00000020000\r
+159 00020000000200000002000000180000003000000060000000C0000001800000\r
+159 01000000\r
+160 0000000000000000000000000030000000180000000C00000006000000030000\r
+160 00000000000000E0000060E0000030E0000010E000000C400000064000000340\r
+160 00000040000000400000004000000040000000180000000C0000000600000003\r
+160 00000001\r
+161 0120000000940000004C00000124000000960000004D00000024800000164000\r
+161 000D200000049000000648E0000524E0000092E0000049E0000024C000001240\r
+161 00000960000004D00000024800000B20000000D2000000490000006400000052\r
+161 00000009\r
+162 00000009000000520000006400000049000000D20000016400000248000004D0\r
+162 00000960000E1240000E24C0000E4940000E9200000524000006480000049000\r
+162 000D20000016400000248000004D00000096000001240000004C000000940000\r
+162 01200000\r
+163 0000000000000000000000000000000000000000000000000000000000000000\r
+163 000000000000000000000000000000000000000000000000000E0000000E0000\r
+163 000E0000000E00000004004001FFFFFF0004004001FFFFFF0004004001FFFFFF\r
+163 00040040\r
+164 00A8000000A8000000AC000000A8000000B8000000A8000000E8000000A80000\r
+164 01A8000000A8000000A8000000A8000000A8000000A8000000A8000000A80000\r
+164 00AC000000A8000000B8000000A8000000E8000000A8000001A8000000A80000\r
+164 00A80000\r
+165 0054076C0039082400154235001382AE009110740081102400A5543501C3B82E\r
+165 008111040089110400AB554401DC3B80008811100088111000889554002AA3B8\r
+165 001DC11000088111008889550148883B0142AA1100E1DC150140889300408881\r
+165 0044AAA1\r
diff --git a/symbols/misc3.sym b/symbols/misc3.sym
new file mode 100644 (file)
index 0000000..8eafb28
--- /dev/null
@@ -0,0 +1,27 @@
+-3  -3 3x3symbol-1 dot on\r
+  1 000000020000\r
+  2 000500020005\r
+  3 000400020001\r
+  4 000100020004\r
+  5 000500000005\r
+  6 000500050005\r
+  7 000700000007\r
+  8 000600020003\r
+  9 000300020006\r
+ 10 000700020007\r
+ 11 000500050002\r
+ 12 000200050005\r
+ 13 000200050002\r
+ 14 000700050007\r
+ 15 000700070007\r
+ 16 000000000000\r
+ 17 000200020002\r
+ 18 000000070000\r
+ 19 000700060004\r
+ 20 000700010001\r
+ 21 000400040007\r
+ 22 000600060000\r
+ 23 000200070002\r
+ 24 000500070005\r
+ 25 000700010007\r
+ 26 000700050005\r
diff --git a/symbols/misc8.sym b/symbols/misc8.sym
new file mode 100644 (file)
index 0000000..b3af2d2
--- /dev/null
@@ -0,0 +1,44 @@
+ -8 -8 79/11/07.SYMBOLS AND TONES\r
+  1  081 042 024 018 018 024 042 081\r
+  2  018 018 018 0FF 0FF 018 018 018\r
+  3  055 0AA 055 0AA 055 0AA 055 0AA\r
+  4  041 082 004 008 010 020 041 082\r
+  5  082 041 020 010 008 004 082 041\r
+  6  082 043 024 05A 05A 024 0C2 041\r
+  7  000 042 03C 024 024 03C 042 000\r
+  8  081 0FF 081 091 089 081 0FF 081\r
+  9  001 00E 038 0E0 001 00E 038 0E0\r
+ 10  080 070 01C 007 080 070 01C 007\r
+ 11  018 024 042 052 04A 042 024 018\r
+ 12  000 03C 000 055 0AA 000 03C 000\r
+ 13  008 010 020 041 082 004 008 010\r
+ 14  008 014 022 041 082 044 028 010\r
+ 15  000 03E 042 042 042 042 07C 000\r
+ 16  0FF 081 0BD 0A5 0A5 0BD 081 0FF\r
+ 17  000 066 066 000 000 066 066 000\r
+ 18  000 066 066 018 018 066 066 000\r
+ 19  041 0DA 024 018 018 024 05B 082\r
+ 20  040 0C0 020 010 008 004 003 002\r
+ 21  002 003 004 008 010 020 0C0 040\r
+ 22  081 081 081 0FF 0FF 081 081 081\r
+ 23  0FF 018 018 018 018 018 018 0FF\r
+ 24  024 024 0FF 024 024 0FF 024 024\r
+ 25  000 000 000 0FF 0FF 000 000 000\r
+ 26  018 018 018 018 018 018 018 018\r
+ 27  0C3 0FF 000 0DB 0DB 000 0FF 0C3\r
+ 28  0DB 0DB 000 0DB 0DB 000 0DB 0DB\r
+ 29  000 000 000 018 018 000 000 000\r
+ 30  0FF 0FF 0FF 0FF 0FF 0FF 0FF 0FF\r
+ 31  0FF 000 000 0FF 000 000 000 0FF\r
+ 32  089 089 089 089 089 089 089 089\r
+ 33  0FF 000 0FF 000 0FF 000 000 0FF\r
+ 34  095 095 095 095 095 095 095 095\r
+ 35  081 042 024 0FF 018 024 042 081\r
+ 36  091 052 034 018 018 034 052 091\r
+ 37  078 078 000 01E 01E 000 078 078\r
+ 38  000 0AA 0AA 0FF 0FF 055 055 000\r
+ 39  000 018 018 0DB 0DB 0C3 0C3 000\r
+ 40  099 099 000 099 099 000 099 099\r
+ 41  0FF 0E7 0E7 099 099 0E7 0E7 0FF\r
+ 42  0FF 0FF 0C3 0C3 0C3 0C3 0FF 0FF\r
+ 43  000 000 000 018 000 000 000 000\r
diff --git a/symbols/tone10a.sym b/symbols/tone10a.sym
new file mode 100644 (file)
index 0000000..e3ebc64
--- /dev/null
@@ -0,0 +1,145 @@
+-10 -10 79/11/07.MLMIS S45 TONE DECK\r
+  1 0038004400820129010101290082004400380000\r
+  2 019301930010003801FF00380010019301930000\r
+  3 0000003000480084010201020084004800300000\r
+  4 000001FE01FE003000300030003001FE01FE0000\r
+  5 00C1000C00600100001C00C00006017100000000\r
+  6 0092016D016D0092016D016D0092016D016D0000\r
+  7 010000000000000000000000000A000201000000\r
+  8 01EF0129012901EF000001EF0129012901EF0000\r
+  9 019300100000003801FF00380000001001930000\r
+ 10 0000003000FC00AC01C6018E00D400FC00300000\r
+ 11 0038005400EE015501BB015500EE005400380000\r
+ 12 002C00D200A6004C00D200340030003000780000\r
+ 13 011100AA004400000000011100AA004400000000\r
+ 14 0201013200B4007801FE01FE007800B401320201\r
+ 15 003F00110011001101FF01FF006000600060007C\r
+ 16 0000010200000000001000000000000001020000\r
+ 17 0000000000200050008800440028001000000000\r
+ 18 0048004800480FFF004800480FFF004800480048\r
+ 19 007800CC01860303023102310303018600CC0078\r
+ 20 000000FC00FC00CC01A6019600CC00FC00FC0000\r
+ 21 01FE02CD034B0387020102010387034B02CD01FE\r
+ 22 0140004000410190000000270002000000400200\r
+ 23 000001FE01FE018601B601B6018601FE01FE0000\r
+ 24 018300100000003800AA00380000001001830000\r
+ 25 00E700A600EC000800100037006500E700000000\r
+ 26 0000000000000030007800FC01FE000000000000\r
+ 27 0000008200000028000000280000008200000000\r
+ 28 01FF0000000001FF0000000001FF000000000000\r
+ 29 01C701C701C700380038003801C701C701C70000\r
+ 30 01FF01FF018301BB01AB01BB018301FF01FF0000\r
+ 31 000000300030003001FE01FE0030003000300030\r
+ 32 003800540082011101AB01110082005400380000\r
+ 33 000002AA00000155000002AA00000155000002AA\r
+ 34 0229004A0100000601240025001B011100080002\r
+ 35 0000000000780084010201020084007800000000\r
+ 36 0038007C00FE01FF01FF01FF00FE007C00380000\r
+ 37 03FF03CF03CF03CF0201020103CF03CF03CF03CF\r
+ 38 02010302018600CC00780030007800CC01860303\r
+ 39 00B8007C00F800FC00FE007800B0003000780000\r
+ 40 00000030004800B4014A014A00B4004800300000\r
+ 41 018300100010003800EE00380010001001830000\r
+ 42 0092024900920249009202490092024900920249\r
+ 43 000000FC00FC00FC01FE01FE00FC00FC00FC0000\r
+ 44 0038004400D601290155012900D6004400380000\r
+ 45 0000000000000030004800480030000000000000\r
+ 46 01FF01FF0193019301FF0193019301FF01FF0000\r
+ 47 0053004C034000CB014603040223020202590090\r
+ 48 0000000000440000000000000044000000000000\r
+ 49 0000000C00E00000000F000000600000001C0000\r
+ 50 01FE00FD02790333038703CF03870333027900FC\r
+ 51 0010000000000028008200280000000000100000\r
+ 52 00000000000000F800F800F800F800F800000000\r
+ 53 000001FE01FE01FE01CE01CE01FE01FE01FE0000\r
+ 54 02AA0155015502AA0155015502AA0155015502AA\r
+ 55 0101008200440028001000AA01C701EF01C70000\r
+ 56 0000013200000000013201320000000001320000\r
+ 57 03FF03FF03FF03DF03AF035702AB03FF03FF03FF\r
+ 58 001000A800C400EE0129012901E9010901FF0000\r
+ 59 0000000000100000008000040000002000000000\r
+ 60 0293023A00880058037A00EE0382018A00E401A6\r
+ 61 03FF03FF03FF0307030703070307030703FF03FF\r
+ 62 000000100010003800EE00380010001000000000\r
+ 63 01FF01FF019301BB01FF01BB019301FF01FF0000\r
+ 64 01FF000001FF000001FF000001FF000001FF0000\r
+ 65 0008001C002A0028001C000A002A001C00080000\r
+ 66 0000000000440000000000000000000000000000\r
+ 67 000000200020002001FE00200020002000200000\r
+ 68 0030003000300030003F003F0000000000000000\r
+ 69 00200020002000AA01FE03FE03FE01FC007C007C\r
+ 70 015502AA015502AA015502AA015502AA015502AA\r
+ 71 007C007C0060006000600060007C007C00000000\r
+ 72 00000008000C007E006C00080000000000000000\r
+ 73 03FF03DF03DF03DF020103DF03DF03DF03DF03FF\r
+ 74 034A02EB00C103D6013B018C039701E3027A0231\r
+ 75 0000007E007E00000000007E007E000000000000\r
+ 76 000000000000000003FF03FF0000000000000000\r
+ 77 0008001C003E0008000800080008000000000000\r
+ 78 00000004000C001800300018000C000400000000\r
+ 79 03EE03DE02BF03BB017F037E021A02FF00F102FF\r
+ 80 0000000000000020005000A80154000000000000\r
+ 81 0000000000000000007E007E0000000000000000\r
+ 82 0030003000300030003000300030003000300030\r
+ 83 03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF\r
+ 84 000C001C0038003000300038001C000C00000000\r
+ 85 007C007C000C000C000C000C007C007C00000000\r
+ 86 03FF03FF0303037B037B037B037B030303FF03FF\r
+ 87 0004007E007E00080010007E007E002000000000\r
+ 88 00060006000C0018001800300060006000000000\r
+ 89 000000920054003800EE00380054009200000000\r
+ 90 0008000800080008003E001C0008000000000000\r
+ 91 0000000000000000003F003F0030003000300030\r
+ 92 03BB02EE03BB02FE03FB02FE03FB02FE03BB02EE\r
+ 93 0000001800180000000000180018000000000000\r
+ 94 01B5019302CF02BD01FC03F7001D03BE034F0361\r
+ 95 0000000000000000003000300000000000000000\r
+ 96 01FF01FF01FF01FF01FF01FF01FF01FF01FF0000\r
+ 97 00300038001C000C000C001C0038003000000000\r
+ 98 000000180018007E007E00180018000000000000\r
+ 99 01FF01FF0111013901FF0139011101FF01FF0000\r
+101 000000000000000003F003F00030003000300030\r
+102 021F03EF03FF02FF03FE019B03FF03FF02FE01BF\r
+103 0000002000300018000C00180030002000000000\r
+104 00000000000000000000001C0014001C000C0000\r
+105 003000300030003003F003F00000000000000000\r
+106 0000000000000010000000000000000000000000\r
+107 03FF02FD03FF03FF03EF03FF03FF03FF02FD03FF\r
+108 0038004400820101010100010082004400380000\r
+109 0000000000240000000000240000000000000000\r
+110 0018003C0066006600660066003C001800000000\r
+111 0018003800380018001800180018003C00000000\r
+112 003C007E00660006003C0060007E007E00000000\r
+113 003C007E0066000C000E0066007E003C00000000\r
+114 000C001C003C006400E400FC000C001E00000000\r
+115 007E007E0060007C00060066007E003C00000000\r
+116 003C007E0060007C00660066007E003C00000000\r
+117 007E007E0046000C000C000C000C000C00000000\r
+118 003C007E0066003C00660066007E003C00000000\r
+119 003C007E00660066003E0006007E003C00000000\r
+120 0018003C00660066007E007E006600E700000000\r
+121 00FC007E0066007C00660066007E00FC00000000\r
+122 003C007E0067006000600067007E003C00000000\r
+123 00FC007E0066006600660066007E00FC00000000\r
+124 00FE007E0062007800780062007E00FE00000000\r
+125 00FE007E0062007800780060006000F000000000\r
+126 003C007E00670060006F0066007E003C00000000\r
+127 00E700660066007E007E0066006600E700000000\r
+128 003C001800180018001800180018003C00000000\r
+129 000F00060006000600060066007E003C00000000\r
+130 00E70066006C0078007C0066006600E700000000\r
+131 00F000600060006000600062007E00FE00000000\r
+132 01C700EE00FE00BA00D600C600C601C700000000\r
+133 00C700660076007E007E006E006600E300000000\r
+134 003C007E0066006600660066007E003C00000000\r
+135 00FC007E00660066007E007C006000F000000000\r
+136 003C007E006600660066006C007E003600000000\r
+137 00FC007E00660066007C007E006600E700000000\r
+138 003C007E00620078001E0046007E003C00000000\r
+139 00FF00FF00990018001800180018003C00000000\r
+140 00E700660066006600660066007E003C00000000\r
+141 00E7006600660066003C003C0018001800000000\r
+142 01C700C600D600D600FE007C006C006C00000000\r
+143 00E700660024001800180024006600E700000000\r
+144 00E70066007E003C001800180018003C00000000\r
+145 00FE00FE008C00180030006200FE00FE00000000\r
diff --git a/symbols/tone10b.sym b/symbols/tone10b.sym
new file mode 100644 (file)
index 0000000..b3bec56
--- /dev/null
@@ -0,0 +1,19 @@
+-10 -10 79/11/07.TONES LIGHT TO DARK FOR POPULATION MAPS\r
+  1 0000000000000000000000000018001800000000\r
+  2 0000000000200050008800440028001000000000\r
+  3 000000100010003800EE00380010001000000000\r
+  4 00060006000C0018001800300060006000000000\r
+  5 000000300030003001FE01FE0030003000300030\r
+  6 02010302018600CC00780030007800CC01860303\r
+  7 0048004800480FFF004800480FFF004800480048\r
+  8 01C701C701C700380038003801C701C701C70000\r
+  9 01EF0129012901EF000001EF0129012901EF0000\r
+ 10 02AA0155015502AA0155015502AA0155015502AA\r
+ 11 01FE02CD034B0387020102010387034B02CD01FE\r
+ 12 000000FC00FC00FC01FE01FE00FC00FC00FC0000\r
+ 13 03FF03FF03FF0307030703070307030703FF03FF\r
+ 14 03FF03FF0303037B037B037B037B030303FF03FF\r
+ 15 03FF03FF03FF03DF03AF035702AB03FF03FF03FF\r
+ 16 03FF03FF03FF03FF03FF03FF03FF03FF03FF03FF\r
+ 17 0000000000000000001000000000000000000000\r
+ 18 000000000301038300C6007C0038000000000000\r
diff --git a/symbols/tone10c.sym b/symbols/tone10c.sym
new file mode 100644 (file)
index 0000000..23c2536
--- /dev/null
@@ -0,0 +1,14 @@
+ -10 -10 79/11/07.DOTS LIGHT TO DARK\r
+  1 0000000000000000003000300000000000000000\r
+  2 0000000000000030004800480030000000000000\r
+  3 0000000000200050008800440028001000000000\r
+  4 0000000000780084010201020084007800000000\r
+  5 0000003000480084010201020084004800300000\r
+  6 0038004400820129010101290082004400380000\r
+  7 00000030004800B4014A014A00B4004800300000\r
+  8 003800540082011101AB01110082005400380000\r
+  9 0038004400D601290155012900D6004400380000\r
+ 10 0038005400EE015501BB015500EE005400380000\r
+ 11 0000003000FC00AC01C6018E00D400FC00300000\r
+ 12 004000C801860303023102310303018600CC0078\r
+ 13 0038007C00FE01FF01FF01FF00FE007C00380000\r
diff --git a/symbols/tone10d.sym b/symbols/tone10d.sym
new file mode 100644 (file)
index 0000000..a063b6d
--- /dev/null
@@ -0,0 +1,48 @@
+ -10 -10 79/11/07.ASSORTED TONES, SYMBOLS AND PICTURES\r
+  1 0000000000000000007E007E0000000000000000\r
+  2 0000007E007E00000000007E007E000000000000\r
+  3 0004007E007E00080010007E007E002000000000\r
+  4 000001FE01FE003000300030003001FE01FE0000\r
+  5 01FF0000000001FF0000000001FF000000000000\r
+  6 01FF000001FF000001FF000001FF000001FF0000\r
+  7 0000000000000000003000300000000000000000\r
+  8 0000001800180000000000180018000000000000\r
+  9 000000180018007E007E00180018000000000000\r
+ 10 000000200020002001FE00200020002000200000\r
+ 11 000000100010003800EE00380010001000000000\r
+ 12 000000300030003001FE01FE0030003000300030\r
+ 13 0201013200B4007801FE01FE007800B401320201\r
+ 14 0048004800480FFF004800480FFF004800480048\r
+ 15 01FE02CD034B0387020102010387034B02CD01FE\r
+ 16 03FF03CF03CF03CF0201020103CF03CF03CF03CF\r
+ 17 03FF03DF03DF03DF020103DF03DF03DF03DF03FF\r
+ 18 0000000000000030004800480030000000000000\r
+ 19 0000003000480084010201020084004800300000\r
+ 20 007800CC01860303023102310303018600CC0078\r
+ 21 003800540082011101AB01110082005400380000\r
+ 22 0000000000000020005000A80154000000000000\r
+ 23 0000000000000030007800FC01FE000000000000\r
+ 24 00000000000000F800F800F800F800F800000000\r
+ 25 0038007C00FE01FF01FF01FF00FE007C00380000\r
+ 26 000000FC00FC00FC01FE01FE00FC00FC00FC0000\r
+ 27 000001FE01FE01FE01CE01CE01FE01FE01FE0000\r
+ 28 03FF03FF03FF0307030703070307030703FF03FF\r
+ 29 03FF03FF0303037B037B037B037B030303FF03FF\r
+ 30 01FF01FF01FF01FF01FF01FF01FF01FF01FF0000\r
+ 31 034A02EB00C103D6013B018C039701E3027A0231\r
+ 32 02AA0155015502AA0155015502AA0155015502AA\r
+ 33 0000000000000000007E007E0000000000000000\r
+ 34 0000000000000000003000300000000000000000\r
+ 35 0000003000480084010201020084004800300000\r
+ 36 0000000000200050008800440028001000000000\r
+ 37 0000000000000020005000A80154000000000000\r
+ 38 00000008000C007E006C00080000000000000000\r
+ 39 0008001C002A0028001C000A002A001C00080000\r
+ 40 0010000000000028008200280000000000100000\r
+ 41 0008001C003E0008000800080008000000000000\r
+ 42 000000100010003800EE00380010001000000000\r
+ 43 003F00110011001101FF01FF006000600060007C\r
+ 44 0101008200440028001000AA01C701EF01C70000\r
+ 45 002C00D200A6004C00D200340030003000780000\r
+ 46 001000A800C400EE0129012901E9010901FF0000\r
+ 47 011100AA004400000000011100AA004400000000\r
diff --git a/symbols/tone5.sym b/symbols/tone5.sym
new file mode 100644 (file)
index 0000000..e80e955
--- /dev/null
@@ -0,0 +1,98 @@
+-5 -5 79/11/07.MODIFIED ALPHANUMERICS  WITH TONES\r
+  1  000 006 009 00F 009\r
+  2  000 00E 00E 009 00E\r
+  3  000 007 008 008 007\r
+  4  000 00E 009 009 00E\r
+  5  000 00F 00E 008 00F\r
+  6  000 00F 008 00E 008\r
+  7  000 006 008 009 007\r
+  8  000 009 009 00F 009\r
+  9  000 007 002 002 007\r
+ 10  000 007 002 002 00C\r
+ 11  000 00A 00C 00A 009\r
+ 12  000 008 008 008 00F\r
+ 13  000 00A 015 015 015\r
+ 14  000 009 00D 00B 009\r
+ 15  000 006 009 009 006\r
+ 16  000 00E 009 00E 008\r
+ 17  000 006 009 00A 005\r
+ 18  000 00E 009 00E 009\r
+ 19  000 00E 00C 002 00E\r
+ 20  000 00F 004 004 004\r
+ 21  000 009 009 009 006\r
+ 22  000 009 009 00A 004\r
+ 23  000 015 00A 00E 00A\r
+ 24  000 009 006 006 009\r
+ 25  000 00A 00A 004 004\r
+ 26  000 00F 002 004 00F\r
+ 27  000 00E 00A 00A 00E\r
+ 28  000 004 004 004 004\r
+ 29  000 006 001 006 007\r
+ 30  000 00E 006 002 00E\r
+ 31  000 00A 00E 002 002\r
+ 32  000 00E 00C 002 00C\r
+ 33  000 008 00E 00A 00E\r
+ 34  000 00E 002 002 002\r
+ 35  000 00E 00E 00A 00E\r
+ 36  000 00E 00A 00E 002\r
+ 37  000 004 00E 004 000\r
+ 38  000 000 00E 000 000\r
+ 39  000 00F 00F 00F 00F\r
+ 40  000 001 002 004 008\r
+ 41  000 004 008 008 004\r
+ 42  000 004 002 002 004\r
+ 43  004 00E 00C 006 00E\r
+ 44  000 00E 000 00E 000\r
+ 46  000 000 000 00C 004\r
+ 47  000 000 000 000 004\r
+ 48  03F 03F 03F 03F 03F\r
+ 49  000 00C 008 008 00C\r
+ 50  000 006 002 002 006\r
+ 51  000 004 000 004 000\r
+ 52  002 00F 006 00F 004\r
+ 53  007 007 007 007 007\r
+ 54  007 007 00F 00F 007\r
+ 55  000 000 004 006 007\r
+ 56  004 00E 015 004 004\r
+ 57  000 000 000 03F 03F\r
+ 58  000 000 000 020 038\r
+ 59  038 030 020 000 000\r
+ 60  03F 03F 03F 03E 03C\r
+ 61  03F 03C 038 030 030\r
+ 62  030 030 030 038 03E\r
+ 63  020 030 038 03C 03E\r
+ 64  00D 013 00A 014 013\r
+ 65  00A 00A 00A 00A 000\r
+ 66  000 015 00A 000 000\r
+ 67  000 003 000 00C 000\r
+ 68  011 015 01F 015 011\r
+ 69  01F 015 01B 015 01F\r
+ 70  000 00A 000 00A 000\r
+ 71  01F 011 015 011 01F\r
+ 72  01F 01F 01F 01F 01F\r
+ 73  000 000 004 000 000\r
+ 74  000 03F 000 000 03F\r
+ 75  012 012 012 012 012\r
+ 76  008 010 020 001 002\r
+ 77  004 002 001 020 010\r
+ 78  03F 03F 03F 03F 03F\r
+ 79  02A 015 02A 015 02A\r
+ 80  02A 000 015 000 02A\r
+ 81  024 012 009 024 012\r
+ 82  009 012 024 009 012\r
+ 83  01C 038 031 023 007\r
+ 84  00E 007 023 031 038\r
+ 85  038 030 020 001 003\r
+ 86  007 003 001 020 030\r
+ 87  030 018 00C 006 003\r
+ 88  003 006 00C 018 030\r
+ 89  008 010 020 001 002\r
+ 90  004 002 001 020 010\r
+ 91  00C 018 030 021 003\r
+ 92  00C 006 003 021 030\r
+ 93  001 002 004 008 010\r
+ 94  020 010 008 004 002\r
+ 95  003 007 00E 01C 038\r
+ 96  030 038 01C 00E 007\r
+ 97  000 009 002 004 009\r
+ 98  000 00A 000 00A 000\r
diff --git a/symbols/tone6a.sym b/symbols/tone6a.sym
new file mode 100644 (file)
index 0000000..65aa2d5
--- /dev/null
@@ -0,0 +1,227 @@
+ -6 -6 79/11/07.ASSORTED TONES AND SYMBOLS\r
+  1  000 01F 01F 011 01F 01F\r
+  2  000 006 009 009 006 000\r
+  3  000 015 00A 00E 00E 000\r
+  4  000 010 00C 00C 002 000\r
+  5  000 01C 014 008 008 000\r
+  6  000 00E 00A 00A 00E 000\r
+  7  000 004 00E 004 000 000\r
+  8  000 000 01E 01E 000 000\r
+  9  03F 03F 03F 03F 03F 03F\r
+ 10  000 001 002 004 008 000\r
+ 11  000 006 01E 018 01E 006\r
+ 12  000 008 007 007 008 000\r
+ 13  004 00E 00C 006 00E 000\r
+ 14  000 00E 000 00E 000 000\r
+ 15  000 01B 01B 004 01B 01B\r
+ 16  000 006 00B 019 00B 006\r
+ 17  000 004 000 004 000 000\r
+ 18  000 002 00F 006 00F 004\r
+ 19  000 002 00F 00A 000 000\r
+ 20  000 000 01F 000 000 000\r
+ 21  000 017 007 012 007 017\r
+ 22  000 004 01F 015 004 004\r
+ 23  000 00A 015 015 00A 000\r
+ 24  000 002 006 008 006 002\r
+ 25  000 008 004 002 004 008\r
+ 26  000 01F 00E 00F 003 000\r
+ 27  000 003 00B 004 01A 019\r
+ 28  000 01F 015 011 015 01F\r
+ 29  000 00A 00A 00A 00A 000\r
+ 30  000 015 00A 000 000 000\r
+ 31  000 003 000 00C 000 000\r
+ 32  000 011 015 01F 015 011\r
+ 33  000 01F 015 01B 015 01F\r
+ 34  000 01F 011 015 011 01F\r
+ 35  000 000 004 000 000 000\r
+ 36  000 01F 000 000 01F 000\r
+ 37  000 012 012 012 012 012\r
+ 38  000 002 005 00A 014 008\r
+ 39  000 008 014 00A 005 002\r
+ 40  000 015 00A 015 00A 015\r
+ 41  000 00B 011 015 01B 00B\r
+ 42  000 012 009 004 012 009\r
+ 43  000 012 00C 012 00C 012\r
+ 44  000 00E 01D 01B 017 00E\r
+ 45  000 00E 017 01B 01D 00E\r
+ 46  000 01D 01D 011 017 017\r
+ 47  000 00E 015 01F 015 00E\r
+ 48  000 01A 017 015 015 01D\r
+ 49  000 003 006 00C 018 000\r
+ 50  000 018 00C 006 003 000\r
+ 51  000 00E 01B 015 01B 00E\r
+ 52  000 00A 000 00A 000 000\r
+ 53  000 004 004 004 004 004\r
+ 54  000 00E 006 00C 00C 00C\r
+ 55  000 00E 00A 01B 011 01F\r
+ 56  000 00E 01D 003 01D 00E\r
+ 57  000 00D 013 00A 014 013\r
+ 58  000 01B 01F 00E 01F 01B\r
+ 59  000 004 000 004 000 004\r
+ 60  000 004 00A 004 00A 004\r
+ 61  000 004 00A 015 00A 004\r
+ 62  000 009 002 004 009 000\r
+ 64  000 01A 016 01A 016 01A\r
+ 65  000 004 01B 015 01B 004\r
+ 66  000 012 00C 00C 012 01E\r
+ 67  000 005 00E 01F 00E 014\r
+ 68  000 01E 002 00B 002 01E\r
+ 69  000 008 014 015 014 008\r
+ 70  000 004 002 01D 002 004\r
+ 71  000 004 00E 01B 00E 004\r
+ 72  000 010 01F 013 01F 010\r
+ 73  000 01C 01F 019 01F 01C\r
+ 74  000 01F 01F 00A 00A 000\r
+ 75  000 00B 018 01E 018 00B\r
+ 76  000 00E 015 011 00A 004\r
+ 77  000 01E 017 011 01F 00F\r
+ 78  000 01E 01E 019 007 000\r
+ 79  000 01F 01B 00A 00E 004\r
+ 80  000 018 017 00B 017 018\r
+ 81  000 00E 001 009 006 00C\r
+ 82  000 00E 00E 00A 011 01F\r
+ 83  000 004 00E 01B 00E 004\r
+ 84  000 00F 018 013 01E 004\r
+ 85  000 01E 00E 00E 012 000\r
+ 86  000 01E 006 01A 03A 030\r
+ 87  000 004 00E 011 015 00A\r
+ 88  000 008 018 005 003 007\r
+ 89  000 01C 014 01C 000 000\r
+ 90  000 01F 01F 011 01F 01F\r
+ 91  000 004 01B 01B 01B 004\r
+ 92  000 00C 01E 00C 000 000\r
+ 93  000 00E 00E 011 00E 00E\r
+ 94  000 01C 016 01F 016 01C\r
+ 95  000 008 01F 009 009 00F\r
+ 96  000 00E 00A 00A 00A 01E\r
+ 97  000 01B 00B 00B 00B 00F\r
+ 98  000 01F 011 012 011 01F\r
+ 99  000 008 014 01C 008 00F\r
+100  008 014 01C 008 00F 000\r
+101  03F 021 027 02B 02F 03F\r
+102  03D 006 003 039 029 039\r
+103  03E 020 02C 024 02C 020\r
+104  03F 030 02E 02E 02E 021\r
+105  014 03E 022 03E 014 014\r
+106  03F 02E 02E 02E 02E 02E\r
+108  000 03E 03A 03E 022 03E\r
+109  020 010 008 007 03D 007\r
+110  000 00C 012 01B 003 000\r
+111  020 011 00E 00A 00E 001\r
+112  034 036 006 01C 01C 018\r
+113  004 00E 01F 004 00C 000\r
+114  020 013 00F 00F 01C 01D\r
+115  03E 014 014 014 03E 000\r
+116  03C 03C 020 038 00C 000\r
+117  000 00A 015 015 015 00A\r
+118  000 006 009 009 006 000\r
+119  000 010 00C 00C 002 000\r
+120  000 01C 014 008 008 000\r
+121  000 00E 00A 00A 00E 000\r
+122  000 004 00E 004 000 000\r
+123  000 000 01E 01E 000 000\r
+124  000 00F 00F 00F 00F 000\r
+125  000 001 002 004 008 000\r
+126  000 006 01E 018 01E 006\r
+127  000 008 007 007 008 000\r
+128  004 00E 00C 006 00E 000\r
+129  000 00E 000 00E 000 000\r
+130  020 01B 01B 004 01B 01B\r
+131  000 00E 01E 03E 01E 00E\r
+132  000 004 000 004 000 000\r
+133  002 00F 006 00F 004 000\r
+134  000 002 00F 00A 000 000\r
+135  000 000 01F 000 000 000\r
+136  017 007 012 007 017 000\r
+137  004 01F 015 004 004 000\r
+138  000 01C 02A 02A 01C 000\r
+139  002 006 008 006 002 000\r
+140  008 004 002 004 008 000\r
+141  000 03E 016 01E 006 000\r
+142  000 013 00F 03C 032 000\r
+143  020 02E 02A 02E 020 03F\r
+144  00A 00A 00A 00A 000 000\r
+145  000 015 00A 000 000 000\r
+146  000 003 000 00C 000 000\r
+147  011 015 01F 015 011 000\r
+148  01F 015 01B 015 01F 000\r
+149  01F 011 015 011 01F 000\r
+150  000 000 004 000 000 000\r
+151  000 03F 000 000 03F 000\r
+152  012 012 012 012 012 012\r
+153  008 010 020 001 002 004\r
+154  004 002 001 020 010 008\r
+155  02A 015 02A 015 02A 015\r
+156  01C 022 02A 036 01C 000\r
+157  024 012 009 024 012 009\r
+158  000 012 00C 012 00C 012\r
+159  01C 038 031 023 007 00E\r
+160  00E 007 023 031 038 01C\r
+161  038 030 020 001 003 007\r
+162  00E 015 01F 015 00E 000\r
+163  036 021 02C 00D 02D 021\r
+164  003 007 00E 01C 038 030\r
+165  030 038 01C 00E 007 003\r
+166  000 009 002 004 009 000\r
+167  000 00A 000 00A 000 000\r
+168  004 004 004 004 004 000\r
+169  00E 006 00C 00C 00C 000\r
+170  01C 014 01C 02A 022 000\r
+171  01C 01E 01E 01E 01C 000\r
+172  00D 013 00A 014 013 000\r
+173  033 03F 01E 01E 03F 033\r
+174  004 000 004 000 004 000\r
+175  004 00A 004 00A 004 000\r
+176  004 00A 015 00A 004 000\r
+177  00E 01B 015 01B 00E 000\r
+180  000 01A 016 01A 016 01A\r
+181  000 00C 033 02D 033 00C\r
+182  000 012 00C 00C 012 01E\r
+183  005 00E 01F 00E 014 000\r
+184  000 03C 004 017 004 03C\r
+185  008 008 014 015 014 008\r
+186  004 002 01D 01D 002 004\r
+187  004 00E 01B 01B 00E 004\r
+188  020 038 028 028 038 020\r
+189  038 03E 03A 03A 03E 038\r
+190  03F 03F 03F 012 012 000\r
+191  017 030 03E 030 017 010\r
+192  018 02A 022 014 008 000\r
+193  03F 038 03F 007 03F 000\r
+194  03C 03C 032 00E 000 000\r
+195  000 03F 033 012 01E 00C\r
+196  014 016 017 00F 016 010\r
+197  01C 01E 001 031 00E 00C\r
+198  01C 01C 014 022 03E 03E\r
+199  008 008 01C 037 01C 008\r
+200  000 02F 018 013 01E 004\r
+201  007 03F 007 00A 012 022\r
+202  000 01E 006 01A 03A 030\r
+203  008 03E 001 009 01D 023\r
+204  018 038 038 005 003 007\r
+205  000 01C 014 01C 000 000\r
+206  03E 03E 022 03E 03E 000\r
+207  008 008 036 036 036 008\r
+208  000 00C 01E 00C 000 000\r
+209  00C 00C 033 033 033 00C\r
+210  01C 016 01F 016 01C 000\r
+211  008 01F 009 009 00F 000\r
+212  008 03B 00A 00A 00A 00E\r
+213  01B 00B 00B 00B 00F 000\r
+214  03F 03F 021 022 021 03F\r
+215  008 014 01C 008 00F 000\r
+216  03F 021 027 02B 02F 03F\r
+217  03D 006 003 039 029 039\r
+218  03E 020 02C 024 02C 020\r
+219  03F 030 02E 02E 02E 021\r
+220  014 03E 022 03E 014 014\r
+221  03F 02E 02E 02E 02E 02E\r
+222  000 03E 03A 03E 022 03E\r
+223  020 010 008 007 03D 007\r
+224  000 00C 012 01B 003 000\r
+225  020 011 00E 00A 00E 001\r
+226  034 036 006 01C 01C 018\r
+227  004 00E 01F 004 00C 000\r
+228  020 013 00F 00F 01C 01D\r
+229  03E 014 014 014 03E 000\r
+230  03C 03C 020 038 00C 000\r
diff --git a/symbols/tone6b.sym b/symbols/tone6b.sym
new file mode 100644 (file)
index 0000000..6884934
--- /dev/null
@@ -0,0 +1,70 @@
+ -6 -6 79/11/07.ASSORTED TONES FOR PLOTTING\r
+  1  00D 013 00A 014 013 000\r
+  2  00A 00A 00A 00A 000 000\r
+  3  000 015 00A 000 000 000\r
+  4  000 003 000 00C 000 000\r
+  5  011 015 01F 015 011 000\r
+  6  01F 015 01B 015 01F 000\r
+  7  000 00A 000 00A 000 000\r
+  8  01F 011 015 011 01F 000\r
+  9  01F 01F 01F 01F 01F 000\r
+ 10  000 000 004 000 000 000\r
+ 11  000 03F 000 000 03F 000\r
+ 12  012 012 012 012 012 012\r
+ 13  008 010 020 001 002 004\r
+ 14  004 002 001 020 010 008\r
+ 15  024 012 009 024 012 009\r
+ 16  009 012 024 009 012 024\r
+ 17  01C 038 031 023 007 00E\r
+ 18  00E 007 023 031 038 01C\r
+ 19  038 030 020 001 003 007\r
+ 20  007 003 001 020 030 038\r
+ 21  021 012 00C 00C 012 021\r
+ 22  033 03F 01E 01E 03F 033\r
+ 23  004 000 004 000 004 000\r
+ 24  000 00A 004 00A 000 000\r
+ 25  004 00A 000 00A 004 000\r
+ 26  004 00A 004 00A 004 000\r
+ 27  004 00A 015 00A 004 000\r
+ 28  00E 01B 015 01B 00E 000\r
+ 29  00C 012 012 012 00C 000\r
+ 30  011 00A 015 00A 011 000\r
+ 31  03F 03F 03F 03F 03F 03F\r
+ 32  00D 01B 036 02D 01B 036\r
+ 33  02C 036 01B 02D 036 01B\r
+ 34  030 018 00C 006 003 001\r
+ 35  003 006 00C 018 030 008\r
+ 36  00C 018 030 021 003 006\r
+ 37  00C 006 003 021 030 018\r
+ 38  003 007 00E 01C 038 030\r
+ 39  030 038 01C 00E 007 003\r
+ 40  007 00F 01F 03E 03C 038\r
+ 41  038 03C 03E 01F 00F 007\r
+ 42  008 008 01C 01C 03E 008\r
+ 43  02D 012 02D 02D 012 02D\r
+ 44  015 02A 015 02A 015 02A\r
+ 45  000 000 008 01C 03E 000\r
+ 46  000 03F 000 000 03F 000\r
+ 47  000 000 000 000 03F 000\r
+ 48  03F 000 03F 03F 000 03F\r
+ 49  028 002 014 001 028 002\r
+ 50  008 008 03E 008 008 000\r
+ 51  000 002 008 000 004 000\r
+ 52  01F 03B 02F 03E 037 03D\r
+ 54  000 01C 01C 01C 000 000\r
+ 55  008 01C 03E 01C 008 000\r
+ 56  020 020 010 001 008 002\r
+ 57  003 003 00C 00C 030 030\r
+ 58  000 01E 01E 01E 01E 000\r
+ 59  03F 03F 021 021 03F 03F\r
+ 60  024 00A 011 024 012 029\r
+ 61  001 000 004 000 010 020\r
+ 62  01D 011 013 01F 007 03F\r
+ 63  03C 03C 033 033 00F 00C\r
+ 64  000 000 03F 03F 000 000\r
+ 65  03F 020 020 020 020 020\r
+ 66  020 020 010 001 008 002\r
+ 67  01D 010 010 01C 000 009\r
+ 68  03F 021 021 021 021 03F\r
+ 69  000 000 00C 00C 000 000\r
+ 70  000 03F 000 03F 000 03F\r
diff --git a/tcl/admin.layer b/tcl/admin.layer
new file mode 100644 (file)
index 0000000..056b847
--- /dev/null
@@ -0,0 +1,96 @@
+#fGIS Layer file. Layer type: raster
+# Layer:   áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ
+set _raster_ [raster ../testdata/admin.epp]
+set _legend_ [legend parse {-2    áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ
+1  \9bòÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ
+2  \9bòÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ
+3  \9bòÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ
+4  \9bëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ
+5  \9bòÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ
+6  \9bòÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ
+7  \9bòÅÓÐÕÂÌÉËÁ ëÏÍÉ
+8  \9bòÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ
+9  \9bíÏÒÄÏ×ÓËÁÑ óóò
+10  \9bóÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò
+11  \9bòÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ
+12  \9bòÅÓÐÕÂÌÉËÁ ôÕ×Á
+13  \9bõÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ
+14  \9bþÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ
+15  \9bþÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ
+16  \9bòÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)
+17  \9báÌÔÁÊÓËÉÊ ËÒÁÊ
+18  \9bòÅÓÐÕÂÌÉËÁ áÌÔÁÊ
+19  \9bëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ
+20  \9bòÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ
+21  \9bëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ
+22  \9bòÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ
+23  \9bôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ
+24  \9bü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ
+25  \9bðÒÉÍÏÒÓËÉÊ ËÒÁÊ
+26  \9bóÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ
+27  \9bëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ
+28  \9bèÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ
+29  \9bå×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ
+30  \9báÍÕÒÓËÁÑ
+31  \9báÒÈÁÎÇÅÌØÓËÁÑ
+32  \9bîÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ
+33  \9báÓÔÒÁÈÁÎÓËÁÑ
+34  \9bâÅÌÇÏÒÏÄÓËÁÑ
+35  \9bâÒÑÎÓËÁÑ
+36  \9b÷ÌÁÄÉÍÉÒÓËÁÑ
+37  \9b÷ÏÌÇÏÇÒÁÄÓËÁÑ
+38  \9b÷ÏÌÏÇÏÄÓËÁÑ
+39  \9b÷ÏÒÏÎÅÖÓËÁÑ
+40  \9bîÉÖÅÇÏÒÏÄÓËÁÑ
+41  \9bé×ÁÎÏ×ÓËÁÑ
+42  \9béÒËÕÔÓËÁÑ
+43  \9bõÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ
+44  \9bëÁÌÉÎÉÎÇÒÁÄÓËÁÑ
+45  \9bô×ÅÒÓËÁÑ
+46  \9bëÁÌÕÖÓËÁÑ
+47  \9bëÁÍÞÁÔÓËÁÑ
+48  \9bëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ
+49  \9bëÅÍÅÒÏ×ÓËÁÑ
+50  \9bëÉÒÏ×ÓËÁÑ
+51  \9bëÏÓÔÒÏÍÓËÁÑ
+52  \9bóÁÍÁÒÓËÁÑ
+53  \9bëÕÒÇÁÎÓËÁÑ
+54  \9bëÕÒÓËÁÑ
+55  \9bìÅÎÉÎÇÒÁÄÓËÁÑ
+56  \9bìÉÐÅÃËÁÑ
+57  \9bíÁÇÁÄÁÎÓËÁÑ
+58  \9bþÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ
+59  \9bíÏÓËÏ×ÓËÁÑ
+60  \9bíÕÒÍÁÎÓËÁÑ
+61  \9bîÏ×ÇÏÒÏÄÓËÁÑ
+62  \9bîÏ×ÏÓÉÂÉÒÓËÁÑ
+63  \9bïÍÓËÁÑ
+64  \9bïÒÅÎÂÕÒÇÓËÁÑ
+65  \9bïÒÌÏ×ÓËÁÑ
+66  \9bðÅÎÚÅÎÓËÁÑ
+67  \9bðÅÒÍÓËÁÑ
+68  \9bëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ
+69  \9bðÓËÏ×ÓËÁÑ
+70  \9bòÏÓÔÏ×ÓËÁÑ
+71  \9bòÑÚÁÎÓËÁÑ
+72  \9bóÁÒÁÔÏ×ÓËÁÑ
+73  \9bóÁÈÁÌÉÎÓËÁÑ
+74  \9båËÁÔÅÒÉÎÂÕÒÇÓËÁÑ
+75  \9bóÍÏÌÅÎÓËÁÑ
+76  \9bôÁÍÂÏ×ÓËÁÑ
+77  \9bôÏÍÓËÁÑ
+78  \9bôÕÌØÓËÁÑ
+79  \9bôÀÍÅÎÓËÁÑ
+80  \9bèÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ
+81  \9bñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ
+82  \9bõÌØÑÎÏ×ÓËÁÑ
+83  \9bþÅÌÑÂÉÎÓËÁÑ
+84  \9bþÉÔÉÎÓËÁÑ
+85  \9báÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ
+86  \9bñÒÏÓÌÁ×ÓËÁÑ
+}]
+layer create raster -raster $_raster_\
+    -border none -ovrborder yes -ovrcolor black\
+    -title {  áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ}\
+    -legend $_legend_
+
diff --git a/tcl/balloonhelp.tcl b/tcl/balloonhelp.tcl
new file mode 100644 (file)
index 0000000..3f0ce51
--- /dev/null
@@ -0,0 +1,225 @@
+## balloonhelp.tcl
+## Balloon Help Routines
+##
+## Jeffrey Hobbs
+## Initiated: 28 October 1996
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     balloonhelp
+##
+## DESCRIPTION
+##     Implements a balloon help system
+##
+## ARGUMENTS
+##     balloonhelp <option> ?arg?
+##
+## clear ?pattern?
+##     Stops the specified widgets (defaults to all) from showing balloon
+##     help.
+##
+## delay ?millisecs?
+##     Query or set the delay.  The delay is in milliseconds and must
+##     be at least 50.  Returns the delay.
+##
+## disable
+##     Disables all balloon help.
+##
+## enable
+##     Enables balloon help for defined widgets.
+##
+## <widget> ?-index index? ?message?
+##     If -index is specified, then <widget> is assumed to be a menu
+##     and the index represents what index into the menu (either the
+##     numerical index or the label) to associate the balloon help
+##     message with.  If message is {}, then the balloon help for that
+##     widget is removed.  The widget must exist prior to calling
+##     balloonhelp.  The current balloon help message for <widget> is
+##     returned, if any.
+##
+## RETURNS: varies (see methods above)
+##
+## NAMESPACE & STATE
+##     The global array BalloonHelp is used.  Procs begin with BalloonHelp.
+## The overrideredirected toplevel is named $BalloonHelp(TOPLEVEL).
+##
+## EXAMPLE USAGE:
+##     balloonhelp .button "A Button"
+##     balloonhelp .menu -index "Load" "Loads a file"
+##
+##------------------------------------------------------------------------
+
+## An alternative to binding to all would be to bind to BalloonHelp
+## and add that to the bindtags of each widget registered.
+
+## The extra :hide call in <Enter> is necessary to catch moving to
+## child widgets where the <Leave> event won't be generated
+bind all <Enter> {
+    #BalloonHelp:hide
+    set BalloonHelp(LAST) -1
+    if {$BalloonHelp(enabled) && [info exists BalloonHelp(%W)]} {
+       set BalloonHelp(AFTERID) [after $BalloonHelp(DELAY) \
+               [list BalloonHelp:show %W $BalloonHelp(%W)]]
+    }
+}
+bind BalloonsMenu <Any-Motion> {
+    if {$BalloonHelp(enabled)} {
+       set cur [%W index active]
+       if {$cur == $BalloonHelp(LAST)} return
+       set BalloonHelp(LAST) $cur
+       BalloonHelp:hide
+       if {[info exists BalloonHelp(%W,$cur)] || \
+               (![catch {%W entrycget $cur -label} cur] && \
+               [info exists BalloonHelp(%W,$cur)])} {
+           set BalloonHelp(AFTERID) [after $BalloonHelp(DELAY) \
+                   [list BalloonHelp:show %W $BalloonHelp(%W,$cur) $cur]]
+       }
+    }
+}
+bind all <Leave>               { BalloonHelp:hide }
+bind Balloons <Any-KeyPress>   { BalloonHelp:hide }
+bind Balloons <Any-Button>     { BalloonHelp:hide }
+array set BalloonHelp {
+    enabled    1
+    DELAY      500
+    AFTERID    {}
+    LAST       -1
+    TOPLEVEL   .__balloonhelp__
+}
+
+proc balloonhelp {w args} {
+    global BalloonHelp
+    switch -- $w {
+       clear   {
+           if {[llength $args]==0} { set args .* }
+           BalloonHelp:clear $args
+       }
+       delay   {
+           if {[llength $args]} {
+               if {![regexp {^[0-9]+$} $args] || $args<50} {
+                   return -code error "BalloonHelp delay must be an\
+                           integer greater than 50 (delay is in millisecs)"
+               }
+               return [set BalloonHelp(DELAY) $args]
+           } else {
+               return $BalloonHelp(DELAY)
+           }
+       }
+       disable {
+           set BalloonHelp(enabled) 0
+           BalloonHelp:hide
+       }
+       enable  {
+           set BalloonHelp(enabled) 1
+       }
+       default {
+           if {[llength $args]} {
+               set i [uplevel BalloonHelp:register $w $args]
+           }
+           set b $BalloonHelp(TOPLEVEL)
+           if {![winfo exists $b]} {
+               toplevel $b
+               wm overrideredirect $b 1
+               wm positionfrom $b program
+               wm withdraw $b
+               pack [label $b.l -highlightthickness 0 -relief raised -bd 1 \
+                       -background yellow]
+           }
+           if {[info exists BalloonHelp($i)]} { return $BalloonHelp($i) }
+       }
+    }
+}
+
+;proc BalloonHelp:register {w args} {
+    global BalloonHelp
+    set key [lindex $args 0]
+    while {[string match -* $key]} {
+       switch -- $key {
+           -index      {
+               if {[catch {$w entrycget 1 -label}]} {
+                   return -code error "widget \"$w\" does not seem to be a\
+                           menu, which is required for the -index switch"
+               }
+               set index [lindex $args 1]
+               set args [lreplace $args 0 1]
+           }
+           default     {
+               return -code error "unknown option \"$key\": should be -index"
+           }
+       }
+       set key [lindex $args 0]
+    }
+    if {[llength $args] != 1} {
+       return -code error "wrong \# args: should be \"balloonhelp widget\
+               ?-index index? message\""
+    }
+    if {[string match {} $key]} {
+       BalloonHelp:clear $w
+    } else {
+       if {![winfo exists $w]} {
+           return -code error "bad window path name \"$w\""
+       }
+       if {[info exists index]} {
+           set BalloonHelp($w,$index) $key
+           bindtags $w [linsert [bindtags $w] end BalloonsMenu]
+           return $w,$index
+       } else {
+           set BalloonHelp($w) $key
+           bindtags $w [linsert [bindtags $w] end Balloons]
+           return $w
+       }
+    }
+}
+
+;proc BalloonHelp:clear {{pattern .*}} {
+    global BalloonHelp
+    foreach w [array names BalloonHelp $pattern] {
+       unset BalloonHelp($w)
+       if {[winfo exists $w]} {
+           set tags [bindtags $w]
+           if {[set i [lsearch $tags Balloons]] != -1} {
+               bindtags $w [lreplace $tags $i $i]
+           }
+           ## We don't remove BalloonsMenu because there
+           ## might be other indices that use it
+       }
+    }
+}
+
+;proc BalloonHelp:show {w msg {i {}}} {
+    if {![winfo exists $w] || [string compare \
+           $w [eval winfo containing [winfo pointerxy $w]]]} return
+
+    global BalloonHelp
+    set b $BalloonHelp(TOPLEVEL)
+    $b.l configure -text $msg
+    update idletasks
+    if {[string compare {} $i]} {
+       set y [expr [winfo rooty $w]+[$w yposition $i]+25]
+       if {($y+[winfo reqheight $b])>[winfo screenheight $w]} {
+           set y [expr [winfo rooty $w]+[$w yposition $i]-\
+                   [winfo reqheight $b]-5]
+       }
+    } else {
+       set y [expr [winfo rooty $w]+[winfo height $w]+5]
+       if {($y+[winfo reqheight $b])>[winfo screenheight $w]} {
+           set y [expr [winfo rooty $w]-[winfo reqheight $b]-5]
+       }
+    }
+    set x [expr [winfo rootx $w]+([winfo width $w]-[winfo reqwidth $b])/2]
+    if {$x<0} {
+       set x 0
+    } elseif {($x+[winfo reqwidth $b])>[winfo screenwidth $w]} {
+       set x [expr [winfo screenwidth $w]-[winfo reqwidth $b]]
+    }
+    wm geometry $b +$x+$y
+    wm deiconify $b
+    raise $b
+}
+
+;proc BalloonHelp:hide {args} {
+    global BalloonHelp
+    after cancel $BalloonHelp(AFTERID)
+    catch {wm withdraw $BalloonHelp(TOPLEVEL)}
+}
diff --git a/tcl/calculator.tcl b/tcl/calculator.tcl
new file mode 100644 (file)
index 0000000..5adc3b1
--- /dev/null
@@ -0,0 +1,523 @@
+## calculator.tcl
+##
+## Jeffrey Hobbs, jeff.hobbs@acm.org
+##
+## WORK IN PROGRESS - NOT FUNCTIONAL
+##
+
+set tcl_precision 15
+
+array set Calculator {
+    type       frame
+    base       frame
+    components {
+       {frame menubar mbar {-relief raised -bd 1}}
+       {listbox data data {-height 5 -bg white \
+               -yscrollcommand [list $data(yscrollbar) set] \
+               -xscrollcommand [list $data(xscrollbar) set] \
+               -selectbackground yellow -selectborderwidth 0 \
+               -selectmode single -takefocus 1}}
+       {scrollbar yscrollbar sy {-takefocus 0 -bd 1 -orient v \
+               -command [list $data(data) yview]}}
+       {scrollbar xscrollbar sx {-takefocus 0 -bd 1 -orient h \
+               -command [list $data(data) xview]}}
+       {entry entry e {-bg white -takefocus 1}}
+       {frame modef}
+       {frame buttons}
+       {label label lbl {-fg \#0000FF -textvariable ${w}(message)}}
+    }
+
+    -base      {base           Base    DEC}
+    -degree    {degree         Degree  RAD}
+    -menubar   {menuBar        MenuBar 1}
+    -mode      {mode           Mode    Trig}
+    -status    {status         Status  0}
+    -type      {type           Type    REG}
+}
+proc Calculator args {}
+proc calculator args {}
+widget create Calculator
+
+;proc Calculator:construct w {
+    upvar \#0 $w data
+
+    array set data {
+       version         1.0
+       index           end
+       constants       {
+           pi          3.141592654
+           e           2.718281828
+       }
+       modes           {Scientific Logical Financial}
+    }
+
+    grid $data(menubar)        -       -sticky ew
+    grid $data(data)    $data(yscrollbar)      -sticky news
+    grid $data(xscrollbar)     -sticky ew
+    grid $data(entry)  -       -sticky ew
+    grid $data(modef)  -       -sticky ew
+    grid $data(buttons)        -       -sticky news
+    grid $data(label)  -       -sticky ew
+    grid columnconfig $w 0 -weight 1
+    grid rowconfigure $w 1 -weight 1
+    grid remove $data(yscrollbar) $data(xscrollbar) $data(label)
+
+    Calculator:menus $w
+
+    set b $data(buttons)
+    for {set i 0} {$i < 10} {incr i} {
+       button $b.$i -text $i -width 3 \
+               -bg \#d9d9FF -command [list ]
+    }
+    foreach i {A B C D E F} {
+       button $b.[string tolower $i] -text $i -width 3 \
+               -bg \#d9d9FF -command [list ]
+    }
+    button $b.del  -text DEL   -command [list Calculator_backspace $w]
+    button $b.clr  -text CLR   -command [list Calculator_clear $w]
+    button $b.drop -text Drop  -command [list Calculator_drop $w]
+    button $b.swap -text Swap  -command [list Calculator_swap $w]
+    button $b.sign -text +/-   -command [list Calculator_changesign $w]
+    button $b.inv  -text 1/x   -command [list Calculator_invert $w]
+    button $b.xtoy -text x^y   -command [list Calculator_func $w pow]
+    button $b.sqr  -text x^2   -command [list Calculator_sqr $w]
+    button $b.sqrt -text Sqrt  -command [list Calculator_sqrt $w]
+    button $b.perc -text %     -command [list Calculator_percent $w]
+    button $b.dot  -text .     -command [list Calculator_decimal $w]
+    button $b.add  -text + -bg yellow -command [list Calculator_binary $w +]
+    button $b.sub  -text - -bg yellow -command [list Calculator_binary $w -]
+    button $b.mul  -text * -bg yellow -command [list Calculator_binary $w *]
+    button $b.div  -text / -bg yellow -command [list Calculator_binary $w /]
+
+    grid $b.inv $b.sqr $b.sqrt $b.perc -sticky news
+    grid $b.d $b.e $b.f $b.clr -sticky nsew
+    grid $b.a $b.b $b.c $b.del -sticky nsew
+    grid $b.7 $b.8 $b.9 $b.add -sticky nsew
+    grid $b.4 $b.5 $b.6 $b.sub -sticky nsew
+    grid $b.1 $b.2 $b.3 $b.mul -sticky nsew
+    grid $b.sign $b.0 $b.dot $b.div -sticky nsew
+    grid columnconfig $b 0 -weight 1
+    grid columnconfig $b 1 -weight 1
+    grid columnconfig $b 2 -weight 1
+    grid columnconfig $b 3 -weight 1
+
+    ## Standard bindings
+    ##
+    foreach i {+ - * /} {
+       bind Calculator $i [list Calculator_binary $i]
+    }
+    bind Calculator <KP_Add>           [list Calculator_binary $w +]
+    bind Calculator <KP_Subtract>      [list Calculator_binary $w -]
+    bind Calculator <KP_Multiply>      [list Calculator_binary $w *]
+    bind Calculator <KP_Divide>                [list Calculator_binary $w /]
+    bind Calculator <Return>           [list Calculator_enter $w]
+    bind Calculator <KP_Enter>         [list Calculator_enter $w]
+    bind Calculator <KP_Decimal>       [list Calculator_decimal $w]
+    bind Calculator .                  [list Calculator_decimal $w]
+
+    bind Calculator <Shift-BackSpace>  [list Calculator_drop $w]
+    bind Calculator <BackSpace>                [list Calculator_backspace $w]
+
+    Calculator:dobind $w
+}
+
+;proc Calculator:init w {
+    upvar \#0 $w data
+}
+
+;proc Calculator:configure {w args} {
+    upvar \#0 $w data
+
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+           -base       {
+               if {![regexp -nocase {^(DEC|HEX|OCT|BIN)$} $val]} {
+                   return -code error "bad value \"$val\", must be one of:\
+                           dec, hex, oct, bin"
+               }
+               set val [string toupper $val]
+           }
+           -degree     {
+               if {![regexp -nocase {^(RAD|GRAD|DEG)$} $val]} {
+                   return -code error "bad value \"$val\",\
+                           must be one of: rad, grad, deg"
+               }
+               set val [string toupper $val]
+           }
+           -menubar    {
+               if {[set val [regexp -nocase $truth $val]]} {
+                   grid $data(menubar)
+               } else {
+                   grid remove $data(menubar)
+               }
+           }
+           -mode       {
+               if {![regexp -nocase ^([join $data(modes) |])\$ $val]} {
+                   return -code error "bad value \"$val\",\
+                           must be one of: [join $data(modes) {, }]"
+               }
+               set val [string toupper $val]
+           }
+           -status     {
+               if {[set val [regexp -nocase $truth $val]]} {
+                   grid $data(label)
+               } else {
+                   grid remove $data(label)
+               }
+           }
+           -type       {
+               if {![regexp -nocase ^([join $data(types) |])\$ $val]} {
+                   return -code error "bad value \"$val\",\
+                           must be one of: [join $data(types) {, }]"
+               }
+               set val [string toupper $val]
+           }
+       }
+       set data($key) $val
+    }
+}
+
+;proc Calculator:dobind w {
+    foreach c [winfo children $w] {
+       bindtags $c [concat [bindtags $c] Calculator]
+       Calculator:dobind $c
+    }
+}
+
+;proc Calculator:menus w {
+    upvar \#0 $w data
+
+    ## File Menu
+    ##
+    set m $data(menubar).file
+    pack [menubutton $m -text "File" -underline 0 -menu $m.m] -side left
+    set m [menu $m.m]
+    $m add command -label "Save" -underline 0
+
+    ## Math Menu
+    ##
+    set m $data(menubar).math
+    pack [menubutton $m -text "Math" -underline 0 -menu $m.m] -side left
+    set m [menu $m.m]
+    $m add cascade -label "Constants" -menu $m.const
+
+    ## Constants Menu
+    ##
+    menu $m.const -postcommand [list Calculator:winConst $w $m.const]
+
+    ## Help Menu
+    ##
+    set m $data(menubar).help
+    pack [menubutton $m -text "Help" -underline 0 -menu $m.m] -side right
+    set m [menu $m.m]
+    $m add command -label "About" -command [list Calculator_about $w]
+}
+
+;proc Calculator:error {w args} {
+    upvar \#0 $w data
+
+    if {[string compare $args {}]} {
+       tk_dialog $w.error "Calculator Error" $args error 0 Oops
+    }
+}
+
+;proc Calculator_constant {w type} {
+    upvar \#0 $w data
+
+    array set const $data(constants)
+    Calculator_push $w {}
+}
+
+;proc Calculator_convert {w from to args} {
+    upvar \#0 $w data
+
+    foreach num $args {
+    }
+}
+
+;proc Calculator_changesign w {
+    upvar \#0 $w data
+
+    set arg1 [Calculator_pop $w]
+    if {[string match {} $arg1]} { return 0 }
+    Calculator_push $w [expr 0 - $arg1]
+    Calculator_push $w {}
+}
+
+;proc Calculator_drop w {
+    upvar \#0 $w data
+
+    Calculator_pop $w
+    Calculator_push $w {}
+}
+
+;proc Calculator_backspace w {
+    upvar \#0 $w data
+
+    if {[string match {} [Calculator_peek $w]]} {
+       Calculator_pop $w
+       Calculator_push $w {}
+       return
+    }
+    set arg1 [Calculator_pop $w]
+    set arg2 [string trimright $arg1 .]
+    Calculator_push $w $arg2
+}
+
+;proc Calculator_binary {w op} { 
+    upvar \#0 $w data
+
+    set arg1 [Calculator_pop $w]
+    set arg2 [Calculator_pop $w]
+    if {[string match {} $arg2]} {
+       Calculator_push $w $arg1
+       if {[string compare $arg1 {}]} { Calculator_push $w {} }
+       return
+    }
+    Calculator_push $w [expr double($arg2) $op $arg1]
+    Calculator_push $w {}
+}
+
+;proc Calculator:commify {w ip} {
+    upvar \#0 $w data
+
+    if {[string len $ip] > 3} {
+       set fmt {([0-9])([0-9])([0-9])}
+       switch [expr [string len $ip]%3] {
+           0 { regsub -all $fmt $ip {\1\2\3,} ip }
+           1 { regsub -all $fmt $ip {\1,\2\3} ip }
+           2 { regsub -all $fmt $ip {\1\2,\3} ip }
+       }
+       set ip [string trimright $ip ,]
+    }
+    return $ip
+}
+
+;proc Calculator_decimal w {
+    upvar \#0 $w data
+
+    if [string match {} [$data(data) get $data(index)]] {
+       Calculator_push $w 0.
+    } else {
+       set arg1 [Calculator_pop $w]
+       Calculator_push $w [string trimright $arg1 .].
+    }
+}
+
+;proc Calculator_enter w { 
+    upvar \#0 $w data
+
+    set Calculator_push $w 0
+    if {[string match {} [$data(data) get $data(index)]]} {
+       set Calculator_push $w 1
+    }
+    set stk [Calculator_pop $w]
+    if {[string match {} $stk]} { return 0 }
+    Calculator_push $w $stk
+    if $push { Calculator_push $w $stk }
+    Calculator_push $w {}
+}
+
+;proc Calculator_func {w op} {
+    upvar \#0 $w data
+
+    set arg1 [Calculator_pop $w]
+    set arg2 [Calculator_pop $w]
+    if {[string match {} $arg2]} {
+       Calculator_push $w $arg1
+       if {[string compare $arg1 {}]} { Calculator_push $w {} }
+       return 0
+    }
+    Calculator_push $w [expr $op ($arg2, $arg1)]
+    Calculator_push $w {}
+}
+
+;proc Calculator_invert w {
+    upvar \#0 $w data
+
+    if {[string match {} [set arg1 [Calculator_pop $w]]} { return 0 }
+    if {$arg1 == 0} {
+       Calculator:error $w "Division by 0 error"
+       return 0
+    }
+    Calculator_push $w [expr 1.0 / $arg1]
+    Calculator_push $w {}
+}
+
+;proc Calculator_num {w val} {
+    upvar \#0 $w data
+
+    set idx $data(index)
+    if {[string match {} [$data(data) get $idx]]} {
+       $data(data) delete $idx
+       set stk {}
+    } else {
+       set stk [Calculator_pop $w $idx]
+    }
+    Calculator_push $w $stk$val $idx
+}
+
+;proc Calculator_swap w { 
+    upvar \#0 $w data
+
+    set arg1 [Calculator_pop $w]
+    set arg2 [Calculator_pop $w]
+    if {[string compare $arg2 {}]} {
+       Calculator_push $w $arg1
+       if {[string compare $arg1 {}]} { Calculator_push $w {} }
+       return 0
+    }
+    Calculator_push $w $arg1
+    Calculator_push $w $arg2
+    Calculator_push $w {}
+}
+
+;proc Calculator_unary {w op} {
+    upvar \#0 $w data
+
+    set arg1 [Calculator_pop $w]
+    if {[llength $arg1]} {
+       Calculator_push $w [expr $op ($arg1)]
+       Calculator_push $w {}
+    } else { return 0 }
+}
+
+;proc Calculator_peek {w {idx {}}} {
+    upvar \#0 $w data
+
+    if {[string match {} $idx]} { set idx [$data(data) curselection] }
+    if {[string match {} [$data(data) get $idx]]} { $data(data) delete $idx }
+    regsub -all {,} [$data(data) get $idx] {} val
+    return $val
+}
+
+;proc Calculator_pop {w {idx {}}} {
+    upvar \#0 $w data
+
+    if {[string match {} $idx]} { set idx [$data(data) curselection] }
+    if {[string match {} [$data(data) get $idx]]} { $data(data) delete $idx }
+    set val [$data(data) get $idx]
+    if {[string match {} $val]} {
+       Calculator:error $w "Not enough arguments"
+       return
+    }
+    $data(data) delete $idx
+    regsub -all {,} $val {} val
+    $data(data) selection clear 0 end
+    $data(data) selection set $idx $idx
+    $data(data) see $idx
+    if {[string compare end $data(index)]} {
+       set data(index) [expr $idx+1]
+    }
+    return $val
+}
+
+;proc Calculator_push {w val {idx {}}} {
+    upvar \#0 $w data
+
+    if {[string match {} $idx]} { set idx $data(index) }
+    if {[string match {} [$data(data) get $idx]]} { $data(data) delete $idx }
+
+    switch $data(-base) {
+       DEC {
+           regsub -all {^0+} $val {} val
+           ## break into sign, integer, fractional and exponent parts
+           if {[regexp {^([-+])?([0-9]*)(\.)?([0-9]*)?(e[-+]?[0-9]+)?$} \
+                   $val full sign ip dec fp ee]} {
+               if {[string match {} $ip]} {
+                   if {[string compare $full {}]} { set ip 0 }
+               } else { set ip [Calculator:commify $w $ip] }
+               set val $sign$ip$dec$fp$ee
+           } else {
+               #if [scan $val %d]
+           }
+       }
+       OCT {
+           if {![regsub -all {^0+} $val {0} val]} {
+               set val 0$val
+           }
+       }
+       HEX {  }
+       BIN {  }
+    }
+    $data(data) insert $idx $val
+    $data(data) selection clear 0 end
+    $data(data) selection set $idx $idx
+    $data(data) see $idx
+    #set data(index) $idx
+}
+
+# validate --
+# This procedure validates particular types of numbers/formats
+#
+# Arguments:
+# type         - The type of validation (alphabetic, alphanumeric, date,
+#              hex, integer, numeric, real).  Date is always strict.
+# val          - The value to be validated
+#
+# Returns:     0 or 1 (whether or not it resembles the type)
+#
+# Switches:
+# -strict      - enable more precise (strict) pattern matching on number
+#
+# Example use: validate real 55e-5
+#              validate -strict integer -505
+#
+
+;proc Calculator_validate {w args} {
+    set strict 0
+    if [string match "-s*" [lindex $args 0]] {
+       set strict 1
+       set args [lreplace $args 0 0]
+    }
+
+    if {[llength $args] == 2} {
+       set type [lindex $args 0]
+       set val  [lindex $args 1]
+    } else {
+       return -code error \
+               "wrong # args: should be \"$w validate ?-strict? type value\""
+    }
+
+    switch -glob -- $type {
+       alphab* {
+           #alphabetic
+           return [regexp -nocase [expr {$strict?{^[a-z]+$}:{^[a-z]*$}}] $val]
+       }
+       alphan* {
+           #alphanumeric
+           return [regexp -nocase [expr \
+                   {$strict?{^[a-z0-9]+$}:{^[a-z0-9]*$}}] $val]
+       }
+       d*      {
+           #date
+           return [expr ![catch {clock scan $val}]]
+       }
+       h*      {
+           #hexadecimal
+           return [regexp -nocase [expr \
+                   {$strict?{^(0x)?[0-9a-f]+$}:{^(0x)?[0-9a-f]*$}}] $val]
+       }
+       i*      {
+           #integer
+           return [regexp [expr \
+                   {$strict?{^[-+]?[0-9]+$}:{^[-+]?[0-9]*$}}] $val]
+       }
+       n*      {
+           #numeric
+           return [regexp [expr {$strict?{^[0-9]+$}:{^[0-9]*$}}] $val]
+       }
+       r*      {
+           #real
+           return [regexp -nocase [expr {$strict?\
+                   {^[-+]?([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e[-+]?[0-9]+)?$}:\
+                   {^[-+]?[0-9]*\.?[0-9]*([0-9]\.?e[-+]?[0-9]*)?$}}] $val]
+       }
+       default {
+           return -code error "unknown type \"$type\", must be one of: \
+                   alphabetic, alphanumeric, date, hexadecimal,\
+                   integer, numeric or real"
+       }
+    }
+}
diff --git a/tcl/combobox.tcl b/tcl/combobox.tcl
new file mode 100644 (file)
index 0000000..3e2fc92
--- /dev/null
@@ -0,0 +1,353 @@
+##
+## Copyright 1996 Jeffrey Hobbs
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     combobox
+##
+## DESCRIPTION
+##     Implements a Combobox mega-widget
+##
+## ARGUMENTS
+##     combobox <window pathname> <options>
+##
+## OPTIONS
+##     (Any entry widget option may be used in addition to these)
+##
+## -command script                     DEFAULT: {}
+##     Script to evaluate when a selection is made.
+##
+## -editable TCL_BOOLEAN               DEFAULT: 1
+##     Whether to allow the user to edit the entry widget contents
+##
+## -grab type                          DEFAULT: local
+##     Type of grab (local, none, global) to use when listbox appears.
+##
+## -labelanchor anchor                 DEFAULT: c
+##     Anchor for the label.  Reasonable values are c, w and e.
+##
+## -labeltext string                   DEFAULT: {}
+##     Text for the label
+##
+## -labelwidth #                       DEFAULT: 0 (self-sizing)
+##     Width for the label
+##
+## -list list                          DEFAULT: {}
+##     List for the listbox
+##
+## -listheight #                       DEFAULT: 5
+##     Height of the listbox.  If the number of items exceeds this
+##     height, a scrollbar will automatically be added.
+##
+## -postcommand script                 DEFAULT: {}
+##     A command which is evaluated before the listbox pops up.
+##
+## -prunelist TCL_BOOLEAN              DEFAULT: 0
+##     Whether to prevent duplicate listbox items
+##
+## -tabexpand TCL_BOOLEAN              DEFAULT: 1
+##     Whether to allow tab expansion in entry widget (uses listbox items)
+##
+## RETURNS: the window pathname
+##
+## BINDINGS (in addition to default widget bindings)
+##
+## <Double-1> or <Escape> in the entry widget, or selecting the
+## button will toggle the listbox portion.
+## 
+## <Escape> will close the listbox without a selection.
+## 
+## <Tab> in the entry widget searches the listbox for a unique match.
+## 
+## <Double-1> in the listbox selects that item.
+##
+## METHODS
+##     These are the methods that the Combobox recognizes.  Aside from
+##     those listed here, it accepts what is valid for entry widgets.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## add ?string?
+##     Adds the string to the listbox.
+##     If string is not specified, it uses what's in the entry widget.
+##
+## expand ?string?
+##     Expands the string based on the contents of the listbox.
+##     If string is not specified, it uses what's in the entry widget.
+##
+## popup
+##     Toggles whether the listbox is mapped or not.
+##
+## set string
+##     Sets the entry widget (or its textvariable, if it exists) to
+##     the value of string.
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are label, listbox, entry, toplevel, scrollbar.
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     The procedure combobox and those beginning with Combobox are
+## used.  Also, when a widget is created, commands named .$widgetname
+## and Combobox$widgetname are created.
+##
+## EXAMPLE USAGE:
+##
+## pack [combobox .combo -label "Hello: "]
+## pack [combobox .combo -width 15 -textvariable myvar]
+##
+##------------------------------------------------------------------------
+
+## FIX notes
+## add -command
+## single - not double click
+## -listheight should be *max height*, not strict height
+
+package require Widget 1.0
+package provide Combobox 1.1
+
+array set Combobox {
+    type               frame
+    base               entry
+    components         {
+       label
+       {button button button {-image Combobox:Image \
+               -command [list Combobox_popup $w]}}
+       {toplevel toplevel drop {-cursor arrow}}
+       {listbox listbox drop.lbox {-selectmode single \
+               -width 5 -height $data(-listheight) \
+               -yscrollcommand [list $data(scrollbar) set]}}
+       {scrollbar scrollbar drop.sy {-orient vertical \
+               -command [list $data(listbox) yview]}}
+    }
+
+    -bd                        -borderwidth
+    -borderwidth       {borderWidth    BorderWidth     0}
+    -bg                        -background
+    -background                {ALIAS entry -background}
+    -command           {command        Command         {}}
+    -editable          {editable       Editable        1}
+    -grab              {grab           Grab            local}
+    -labeltext         {labelText      Text            {}}
+    -labelwidth                {labelWidth     Width           0}
+    -labelanchor       {ALIAS label -anchor labelAnchor Anchor}
+    -list              {list           List            {}}
+    -listheight                {listHeight     ListHeight      5}
+    -postcommand       {postCommand    Command         {}}
+    -prunelist         {pruneList      PruneList       0}
+    -relief            {relief         Relief          flat}
+    -tabexpand         {tabExpand      TabExpand       1}
+}
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc Combobox args {}
+proc combobox args {}
+widget create Combobox
+
+;proc Combobox:construct {w args} {
+    upvar \#0 $w data
+
+    ## Removable List Box
+    wm overrideredirect $data(toplevel) 1
+    wm transient $data(toplevel) [winfo toplevel $w]
+    wm group $data(toplevel) [winfo toplevel $w]
+
+    bind $w <Unmap> { catch {grab release %W} }
+    bind $w <Destroy> { catch {grab release %W} }
+    bind $data(toplevel) <Unmap> "catch {grab release {$w}}"
+
+    grid $data(label) $data(entry) $data(button) -in $w -sticky news
+    grid config $data(button) -sticky ns
+    grid columnconfig $w 1 -weight 1
+    grid $data(listbox) $data(scrollbar) -in $data(toplevel) -sticky ns
+    grid config $data(listbox) -sticky news
+    grid remove $data(scrollbar) $data(label)
+    grid columnconfig $data(toplevel) 0 -weight 1
+    grid rowconfig $data(toplevel) 0 -weight 1
+
+    bind $data(listbox) <Escape>   [list $w popup]
+    bind $data(listbox) <Double-1> "Combobox:get [list $w] \[%W get \[%W nearest %y\]\]"
+    bind $data(listbox) <Return>   "Combobox:get [list $w] \[%W get active\]"
+}
+
+;proc Combobox:configure { w args } {
+    upvar \#0 $w data
+
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+           -borderwidth - -relief { .$w configure $key $val }
+           -background {
+               $data(basecmd) configure -bg $val
+               $data(listbox) configure -bg $val
+           }
+           -editable   {
+               if {[set val [regexp $truth $val]]} {
+                   $data(basecmd) configure -state normal
+               } else {
+                   $data(basecmd) configure -state disabled
+               }
+           }
+           -grab       {
+               if {![regexp {^(local|global|none)$} $val junk val]} {
+                   return -code error "bad $key option \"$val\": must be\
+                           local, grab, or none"
+               }
+           }
+           -list       {
+               $data(listbox) delete 0 end
+               eval $data(listbox) insert end $val
+           }
+           -tabexpand  -
+           -prunelist  { set val [regexp $truth $val] }
+           -labelanchor { $data(label) configure -anchor $val }
+           -labeltext  {
+               $data(label) configure -text $val
+               if {[string compare {} $val]} {
+                   grid $data(label)
+               } else {
+                   grid remove $data(label)
+               }
+           }
+           -labelwidth { $data(label) configure -width $val }
+           -listheight { $data(listbox) configure -height $val }
+       }
+       set data($key) $val
+    }
+}
+
+bind Combobox <Double-1>       { %W popup }
+bind Combobox <Escape>         { %W popup }
+bind Combobox <Tab>            { %W expand [%W get]; break }
+
+;proc Combobox_popup {w} {
+    upvar \#0 $w data
+    if {[winfo ismapped $data(toplevel)]} {
+       wm withdraw $data(toplevel)
+       catch {grab release $w}
+       focus $data(entry)
+    } else {
+       uplevel \#0 $data(-postcommand)
+       focus $data(entry)
+       set size [$data(listbox) size]
+       if {$size > $data(-listheight)} {
+           $data(listbox) configure -height $data(-listheight)
+           grid $data(scrollbar)
+       } else {
+           $data(listbox) configure -height $size
+           grid remove $data(scrollbar)
+       }
+       wm geometry $data(toplevel) [winfo width $data(entry)]x[winfo \
+               reqheight $data(toplevel)]+[winfo rootx $data(entry)]+[expr \
+               [winfo rooty $data(entry)]+[winfo reqheight $data(entry)]]
+       update idletasks
+       wm deiconify $data(toplevel)
+       if {[string match local $data(-grab)]} {
+           grab $w
+       } elseif {[string match global $data(-grab)]} {
+           grab -global $w
+       }
+       focus $data(listbox)
+       raise $data(toplevel)
+    }
+}
+
+;proc Combobox_expand {w {str {}}} {
+    upvar \#0 $w data
+    if {!$data(-tabexpand)} return
+    if {[string match {} $str]} { set str [$data(basecmd) get] }
+    set found 0
+    foreach item [$data(listbox) get 0 end] {
+       if {[string match ${str}* $item]} {
+           incr found
+           lappend match $item
+       }
+    }
+    if {$found} {
+       set state [$data(basecmd) cget -state]
+       $data(basecmd) config -state normal
+       $data(basecmd) delete 0 end
+       if {$found>1} {
+           set match [$data(class):BestMatch $match]
+       } else {
+           set match [lindex $match 0]
+       }
+       $data(basecmd) insert end $match
+       $data(basecmd) config -state $state
+    } else { bell }
+}
+
+;proc Combobox_add {w {str {}}} {
+    upvar \#0 $w data
+    if {[string match {} $str]} { set str [$data(basecmd) get] }
+    set i 1
+    if {!$data(-prunelist)} {
+       foreach l [$data(listbox) get 0 end] {
+           if {![string compare $l $str]} { set i 0 ; break }
+       }
+    }
+    if {$i} { $data(listbox) insert end $str }
+}
+
+;proc Combobox_set {w str} {
+    upvar \#0 $w data
+    set var [$data(basecmd) cget -textvar]
+    if {[string compare {} $var] && [uplevel \#0 info exists [list $var]]} {
+       global $var
+       set $var $str
+    } else {
+       set state [$data(basecmd) cget -state]
+       $data(basecmd) config -state normal
+       $data(basecmd) delete 0 end
+       $data(basecmd) insert 0 $str
+       $data(basecmd) config -state $state
+    }
+}
+
+;proc Combobox:get {w i} {
+    upvar \#0 $w data
+    set e $data(basecmd)
+    if {[$data(listbox) size]} {
+       set state [$e cget -state]
+       $e config -state normal
+       $e delete 0 end
+       $e insert end $i
+       $e config -state $state
+       if {[string compare $data(-command) {}]} {
+           uplevel \#0 $data(-command) $i
+       }
+    }
+    wm withdraw $data(toplevel)
+    focus $data(base)
+}
+
+;proc Combobox:BestMatch l {
+    set s [lindex $l 0]
+    if {[llength $l]>1} {
+       set i [expr [string length $s]-1]
+       foreach l $l {
+           while {$i>=0 && [string first $s $l]} {
+               set s [string range $s 0 [incr i -1]]
+           }
+       }
+    }
+    return $s
+}
+
+## Button Bitmap
+##
+image create bitmap Combobox:Image -data {#define downbut_width 14
+#define downbut_height 14
+static char downbut_bits[] = {
+    0x00, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xfc, 0x0f,
+    0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0x1f,
+    0xfe, 0x1f, 0x00, 0x00};
+}
+
+return
diff --git a/tcl/console.tcl b/tcl/console.tcl
new file mode 100644 (file)
index 0000000..f03f047
--- /dev/null
@@ -0,0 +1,2237 @@
+##
+## Copyright 1996-1997 Jeffrey Hobbs
+##
+## source standard_disclaimer.tcl
+## source beer_ware.tcl
+##
+## Based off previous work for TkCon
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     console
+##
+## DESCRIPTION
+##     Implements a console mega-widget
+##
+## ARGUMENTS
+##     console <window pathname> <options>
+##
+## OPTIONS
+##     (Any frame widget option may be used in addition to these)
+##
+##  -blinkcolor color                  DEFAULT: yellow
+##     Specifies the background blink color for brace highlighting.
+##     This doubles as the highlight color for the find box.
+##
+##  -blinkrange TCL_BOOLEAN            DEFAULT: 1
+##     When doing electric brace matching, specifies whether to blink
+##     the entire range or just the matching braces.
+##
+##  -blinktime delay                   DEFAULT: 500
+##     For electric brace matching, specifies the amount of time to
+##     blink the background for.
+##
+##  -grabputs TCL_BOOLEAN              DEFAULT: 1
+##     Whether this console should grab the "puts" default output
+##
+##  -lightbrace TCL_BOOLEAN            DEFAULT: 1
+##     Specifies whether to activate electric brace matching.
+##
+##  -lightcmd TCL_BOOLEAN              DEFAULT: 1
+##     Specifies whether to highlight recognized commands.
+##
+##  -proccolor color                   DEFAULT: darkgreen
+##     Specifies the color to highlight recognized procs.
+##
+##  -promptcolor color                 DEFAULT: brown
+##     Specifies the prompt color.
+##
+##  -stdincolor color                  DEFAULT: black
+##     Specifies the color for "stdin".
+##     This doubles as the console foreground color.
+##
+##  -stdoutcolor color                 DEFAULT: blue
+##     Specifies the color for "stdout".
+##
+##  -stderrcolor color                 DEFAULT: red
+##     Specifies the color for "stderr".
+##
+##  -showmultiple TCL_BOOLEAN          DEFAULT: 1
+##     For file/proc/var completion, specifies whether to display
+##     completions when multiple choices are possible.
+##
+##  -showmenu TCL_BOOLEAN              DEFAULT: 1
+##     Specifies whether to show the menubar.
+##
+##  -subhistory TCL_BOOLEAN            DEFAULT: 1
+##     Specifies whether to allow substitution in the history.
+##
+## RETURNS: the window pathname
+##
+## BINDINGS (these are the bindings for Console, used in the text widget)
+##
+## <<Console_ExpandFile>>      <Key-Tab>
+## <<Console_ExpandProc>>      <Control-Shift-Key-P>
+## <<Console_ExpandVar>>       <Control-Shift-Key-V>
+## <<Console_Tab>>             <Control-Key-i>
+## <<Console_Eval>>            <Key-Return> <Key-KP_Enter>
+##
+## <<Console_Clear>>           <Control-Key-l>
+## <<Console_KillLine>>                <Control-Key-k>
+## <<Console_Transpose>>       <Control-Key-t>
+## <<Console_ClearLine>>       <Control-Key-u>
+## <<Console_SaveCommand>>     <Control-Key-z>
+##
+## <<Console_Previous>>                <Key-Up>
+## <<Console_Next>>            <Key-Down>
+## <<Console_NextImmediate>>   <Control-Key-n>
+## <<Console_PreviousImmediate>>       <Control-Key-p>
+## <<Console_PreviousSearch>>  <Control-Key-r>
+## <<Console_NextSearch>>      <Control-Key-s>
+##
+## <<Console_Exit>>            <Control-Key-q>
+## <<Console_New>>             <Control-Key-N>
+## <<Console_Close>>           <Control-Key-w>
+## <<Console_About>>           <Control-Key-A>
+## <<Console_Help>>            <Control-Key-H>
+## <<Console_Find>>            <Control-Key-F>
+##
+## METHODS
+##     These are the methods that the console megawidget recognizes.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## load ?filename?
+##     Loads the named file into the current interpreter.
+##     If no file is specified, it pops up the file requester.
+##
+## save ?filename?
+##     Saves the console buffer to the named file.
+##     If no file is specified, it pops up the file requester.
+##
+## clear ?percentage?
+##     Clears a percentage of the console buffer (1-100).  If no
+##     percentage is specified, the entire buffer is cleared.
+##
+## error
+##     Displays the last error in the interpreter in a dialog box.
+##
+## hide
+##     Withdraws the console from the screen
+##
+## history ?-newline?
+##     Prints out the history without numbers (basically providing a
+##     list of the commands you've used).
+##
+## show
+##     Deiconifies and raises the console
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are console, yscrollbar, menubar.
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     The procedure console and those beginning with Console are
+## used.  Also, when a widget is created, commands named .$widgetname
+## and Console$widgetname are created.
+##
+## EXAMPLE USAGE:
+##
+## console .con -height 20 -showmenu false
+## pack .con -fill both -expand 1
+##------------------------------------------------------------------------
+
+package require Widget 1.0
+set CONSOLE_VERSION 1.51
+package provide Console $CONSOLE_VERSION
+
+foreach pkg [info loaded {}] {
+    set file [lindex $pkg 0]
+    set name [lindex $pkg 1]
+    if {![catch {set version [package require $name]}]} {
+       if {[string match {} [package ifneeded $name $version]]} {
+           package ifneeded $name $version "load [list $file $name]"
+       }
+    }
+}
+catch {unset file name version}
+
+set Console(WWW) [expr [info exists embed_args] || [info exists browser_args]]
+
+array set Console {
+    type               frame
+    base               {text console console {-wrap char -setgrid 1 \
+           -yscrollcommand [list $data(yscrollbar) set] \
+           -foreground $data(-stdincolor)}}
+    components         {
+       {frame menubar menubar {-relief raised -bd 1}}
+       {scrollbar yscrollbar sy {-takefocus 0 -bd 1 \
+               -command [list $data(console) yview]}}
+    }
+
+    -blinkcolor                {blinkColor     BlinkColor      \#FFFF00}
+    -proccolor         {procColor      ProcColor       \#008800}
+    -promptcolor       {promptColor    PromptColor     \#8F4433}
+    -stdincolor                {stdinColor     StdinColor      \#000000}
+    -stdoutcolor       {stdoutColor    StdoutColor     \#0000FF}
+    -stderrcolor       {stderrColor    StderrColor     \#FF0000}
+    -varcolor          {varColor       VarColor        \#FFC0D0}
+
+    -blinkrange                {blinkRange     BlinkRange      1}
+    -blinktime         {blinkTime      BlinkTime       500}
+    -grabputs          {grabPuts       GrabPuts        1}
+    -lightbrace                {lightBrace     LightBrace      1}
+    -lightcmd          {lightCmd       LightCmd        1}
+    -showmultiple      {showMultiple   ShowMultiple    1}
+    -showmenu          {showMenu       ShowMenu        1}
+    -subhistory                {subhistory     SubHistory      1}
+
+    release    {July 23 1997}
+    contact    "jeff.hobbs@acm.org"
+    docs       "http://www.cs.uoregon.edu/research/tcl/script/tkcon/"
+    slavealias { console }
+    slaveprocs { alias dir dump lremove puts echo unknown tcl_unknown which }
+}
+if {![info exists Console(active)]} { set Console(active) {} }
+set Console(version) $CONSOLE_VERSION
+
+if {$Console(WWW)} {
+    set Console(-prompt) {prompt       Prompt  {[history nextid] % }}
+} else {
+    set Console(-prompt) {prompt       Prompt  \
+           {([file tail [pwd]]) [history nextid] % }}
+}
+
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc Console args {}
+proc console args {}
+widget create Console
+
+array set ConsoleDialog {
+    type       toplevel
+    base       console
+
+    version    1.11
+}
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc ConsoleDialog args {}
+proc consoledialog args {}
+proc console_dialog args {}
+widget create ConsoleDialog
+interp alias {} console_dialog {} ConsoleDialog
+
+;proc ConsoleDialog:construct {w} {
+    upvar \#0 $w data ConsoleDialog class
+
+    wm title $w "Console Dialog $class(version)"
+
+    grid $data(console) -in $w -sticky news
+    grid columnconfig $w 0 -weight 1
+    grid rowconfig $w 0 -weight 1
+}
+
+;proc ConsoleDialog:configure {w args} {
+    ## We have nothing to configure
+    return
+    upvar \#0 $w data
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+       }
+    }
+}
+
+;proc ConsoleDialog_hide w {
+    if {[winfo exists $w]} { wm withdraw $w }
+}
+
+;proc ConsoleDialog_show w {
+    if {[winfo exists $w]} { wm deiconify $w; raise $w }
+}
+
+## console -
+# ARGS:        w       - widget pathname of the Console console
+#      args
+# Calls:       ConsoleInitUI
+# Outputs:     errors found in Console resource file
+##
+;proc Console:construct {w} {
+    upvar \#0 $w data
+
+    global auto_path tcl_pkgPath tcl_interactive
+    set tcl_interactive 0
+
+    ## Private variables
+    array set data {
+       app {} appname {} apptype {} namesp {} deadapp 0
+       cmdbuf {} cmdsave {} errorInfo {}
+       event 1 histid 0 find {} find,case 0 find,reg 0
+    }
+
+    if {![info exists tcl_pkgPath]} {
+       set dir [file join [file dirname [info nameofexec]] lib]
+       if {[string compare {} [info commands @scope]]} {
+           set dir [file join $dir itcl]
+       }
+       catch {source [file join $dir pkgIndex.tcl]}
+    }
+    catch {tclPkgUnknown dummy-name dummy-version}
+
+    ConsoleInitMenus $w
+
+    grid $data(menubar) - -sticky ew
+    grid $data(console) $data(yscrollbar) -sticky news
+    grid columnconfig $w 0 -weight 1
+    grid rowconfig $w 1 -weight 1
+
+    Console:prompt $w "console display active\n"
+
+    set c $data(console)
+    foreach col {prompt stdout stderr stdin proc} {
+       $c tag configure $col -foreground $data(-${col}color)
+    }
+    $c tag configure var -background $data(-varcolor)
+    $c tag configure blink -background $data(-blinkcolor)
+    $c tag configure find -background $data(-blinkcolor)
+
+}
+
+;proc Console:init {w} {
+    upvar \#0 $w data Console class
+    bind $w <Destroy> [bind $class(class) <Destroy>]
+    bindtags $w [list $w [winfo toplevel $w] all]
+    set c $data(console)
+    bindtags $c [list $c Console PostConsole $w all]
+    if {$data(-grabputs) && [lsearch $class(active) $c] == -1} {
+       set class(active) [linsert $class(active) 0 $c]
+    }
+}
+
+;proc Console:destroy w {
+    upvar \#0 $w data Console class
+    set class(active) [lremove $class(active) $data(console)]
+}
+
+;proc Console:configure { W args } {
+    upvar \#0 $W data
+    global Console
+
+    set truth {^(1|yes|true|on)$}
+    set c $data(console)
+    foreach {key val} $args {
+       switch -- $key {
+           -blinkcolor {
+               $c tag config blink -background $val
+               $c tag config find -background $val
+           }
+           -proccolor   { $c tag config proc   -foreground $val }
+           -promptcolor { $c tag config prompt -foreground $val }
+           -stdincolor  {
+               $c tag config stdin -foreground $val
+               $c config -foreground $val
+           }
+           -stdoutcolor { $c tag config stdout -foreground $val }
+           -stderrcolor { $c tag config stderr -foreground $val }
+
+           -blinktime          {
+               if {![regexp {[0-9]+} $val]} {
+                   return -code error "$key option requires an integer value"
+               } elseif {$val < 100} {
+                   return -code error "$key option must be greater than 100"
+               }
+           }
+           -grabputs   {
+               if {[set val [regexp -nocase $truth $val]]} {
+                   set Console(active) [linsert $Console(active) 0 $c]
+               } else {
+                   set Console(active) [lremove -all $Console(active) $c]
+               }
+           }
+           -prompt             {
+               if {[catch {uplevel \#0 [list subst $val]} err]} {
+                   return -code error "\"$val\" threw an error:\n$err"
+               }
+           }
+           -showmenu   {
+               if {[set val [regexp -nocase $truth $val]]} {
+                   grid $data(menubar)
+               } else {
+                   grid remove $data(menubar)
+               }
+           }
+           -lightbrace -
+           -lightcmd   -
+           -showmultiple -
+           -subhistory { set val [regexp -nocase $truth $val] }
+       }
+       set data($key) $val
+    }
+}
+
+;proc Console:exit {w args} {
+    exit
+}
+
+## ConsoleEval - evaluates commands input into console window
+## This is the first stage of the evaluating commands in the console.
+## They need to be broken up into consituent commands (by ConsoleCmdSep) in
+## case a multiple commands were pasted in, then each is eval'ed (by
+## ConsoleEvalCmd) in turn.  Any uncompleted command will not be eval'ed.
+# ARGS:        w       - console text widget
+# Calls:       ConsoleCmdGet, ConsoleCmdSep, ConsoleEvalCmd
+## 
+;proc ConsoleEval {w} {
+    set incomplete [ConsoleCmdSep [ConsoleCmdGet $w] cmds last]
+    $w mark set insert end-1c
+    $w insert end \n
+    if {[llength $cmds]} {
+       foreach c $cmds {ConsoleEvalCmd $w $c}
+       $w insert insert $last {}
+    } elseif {!$incomplete} {
+       ConsoleEvalCmd $w $last
+    }
+    $w see insert
+}
+
+## ConsoleEvalCmd - evaluates a single command, adding it to history
+# ARGS:        w       - console text widget
+#      cmd     - the command to evaluate
+# Calls:       Console:prompt
+# Outputs:     result of command to stdout (or stderr if error occured)
+# Returns:     next event number
+## 
+;proc ConsoleEvalCmd {w cmd} {
+    ## HACK to get $W as we need it
+    set W [winfo parent $w]
+    upvar \#0 $W data
+
+    $w mark set output end
+    if {[string compare {} $cmd]} {
+       set code 0
+       if {$data(-subhistory)} {
+           set ev [ConsoleEvalSlave history nextid]
+           incr ev -1
+           if {[string match !! $cmd]} {
+               set code [catch {ConsoleEvalSlave history event $ev} cmd]
+               if {!$code} {$w insert output $cmd\n stdin}
+           } elseif {[regexp {^!(.+)$} $cmd dummy evnt]} {
+               ## Check last event because history event is broken
+               set code [catch {ConsoleEvalSlave history event $ev} cmd]
+               if {!$code && ![string match ${evnt}* $cmd]} {
+                   set code [catch {ConsoleEvalSlave history event $evnt} cmd]
+               }
+               if {!$code} {$w insert output $cmd\n stdin}
+           } elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $cmd dummy old new]} {
+               set code [catch {ConsoleEvalSlave history event $ev} cmd]
+               if {!$code} {
+                   regsub -all -- $old $cmd $new cmd
+                   $w insert output $cmd\n stdin
+               }
+           }
+       }
+       if {$code} {
+           $w insert output $cmd\n stderr
+       } else {
+           ConsoleEvalSlave history add $cmd
+           if {[catch {ConsoleEvalAttached $cmd} res]} {
+               if {[catch {ConsoleEvalAttached {set errorInfo}} err]} {
+                   set data(errorInfo) "Error getting errorInfo:\n$err"
+               } else {
+                   set data(errorInfo) $err
+               }
+               $w insert output $res\n stderr
+           } elseif {[string compare {} $res]} {
+               $w insert output $res\n stdout
+           }
+       }
+    }
+    Console:prompt $W
+    set data(event) [ConsoleEvalSlave history nextid]
+}
+
+## ConsoleEvalSlave - evaluates the args in the associated slave
+## args should be passed to this procedure like they would be at
+## the command line (not like to 'eval').
+# ARGS:        args    - the command and args to evaluate
+##
+;proc ConsoleEvalSlave {args} {
+    uplevel \#0 $args
+}
+
+## ConsoleEvalAttached
+##
+;proc ConsoleEvalAttached {args} {
+    uplevel \#0 eval $args
+}
+
+## ConsoleCmdGet - gets the current command from the console widget
+# ARGS:        w       - console text widget
+# Returns:     text which compromises current command line
+## 
+;proc ConsoleCmdGet w {
+    if {[string match {} [$w tag nextrange prompt limit end]]} {
+       $w tag add stdin limit end-1c
+       return [$w get limit end-1c]
+    }
+}
+
+## ConsoleCmdSep - separates multiple commands into a list and remainder
+# ARGS:        cmd     - (possible) multiple command to separate
+#      list    - varname for the list of commands that were separated.
+#      rmd     - varname of any remainder (like an incomplete final command).
+#              If there is only one command, it's placed in this var.
+# Returns:     constituent command info in varnames specified by list & rmd.
+## 
+;proc ConsoleCmdSep {cmd list last} {
+    upvar 1 $list cmds $last inc
+    set inc {}
+    set cmds {}
+    foreach c [split [string trimleft $cmd] \n] {
+       if {[string compare $inc {}]} {
+           append inc \n$c
+       } else {
+           append inc [string trimleft $c]
+       }
+       if {[info complete $inc] && ![regexp {[^\\]\\$} $inc]} {
+           if {[regexp "^\[^#\]" $inc]} {lappend cmds $inc}
+           set inc {}
+       }
+    }
+    set i [string compare $inc {}]
+    if {!$i && [string compare $cmds {}] && ![string match *\n $cmd]} {
+       set inc [lindex $cmds end]
+       set cmds [lreplace $cmds end end]
+    }
+    return $i
+}
+
+## Console:prompt - displays the prompt in the console widget
+# ARGS:        w       - console text widget
+# Outputs:     prompt (specified in data(-prompt)) to console
+## 
+;proc Console:prompt {W {pre {}} {post {}} {prompt {}}} {
+    upvar \#0 $W data
+
+    set w $data(console)
+    if {[string compare {} $pre]} { $w insert end $pre stdout }
+    set i [$w index end-1c]
+    if {[string compare {} $data(appname)]} {
+       $w insert end ">$data(appname)< " prompt
+    }
+    if {[string compare {} $prompt]} {
+       $w insert end $prompt prompt
+    } else {
+       $w insert end [ConsoleEvalSlave subst $data(-prompt)] prompt
+    }
+    $w mark set output $i
+    $w mark set insert end
+    $w mark set limit insert
+    $w mark gravity limit left
+    if {[string compare {} $post]} { $w insert end $post stdin }
+    $w see end
+}
+
+## ConsoleAbout - gives about info for Console
+## 
+;proc ConsoleAbout W {
+    global Console
+
+    set w $W.about
+    if {[winfo exists $w]} {
+       wm deiconify $w
+    } else {
+       global tk_patchLevel tcl_patchLevel tcl_platform
+       toplevel $w
+       wm title $w "About Console v$Console(version)"
+       button $w.b -text Dismiss -command [list wm withdraw $w]
+       text $w.text -height 9 -bd 1 -width 60
+       pack $w.b -fill x -side bottom
+       pack $w.text -fill both -side left -expand 1
+       $w.text tag config center -justify center
+       global tcl_platform
+       if {[string compare unix $tcl_platform(platform)] || \
+               [info tclversion] >= 8} {
+           $w.text tag config title -justify center -font {Courier 18 bold}
+       } else {
+           $w.text tag config title -justify center -font *Courier*Bold*18*
+       }
+       $w.text insert 1.0 "About Console v$Console(version)" title \
+               "\n\nCopyright 1995-1997 Jeffrey Hobbs, $Console(contact)\
+               \nhttp://www.cs.uoregon.edu/~jhobbs/\
+               \nRelease Date: v$Console(version), $Console(release)\
+               \nDocumentation available at:\n$Console(docs)\
+               \nUsing: Tcl v$tcl_patchLevel / Tk v$tk_patchLevel" center
+    }
+}
+
+## ConsoleInitMenus - inits the menubar and popup for the console
+# ARGS:        W       - console megawidget
+## 
+;proc ConsoleInitMenus W {
+    upvar \#0 $W data
+
+    set w    $data(menubar)
+    set text $data(console)
+
+    if {[catch {menu $w.pop -tearoff 0}]} {
+       label $w.label -text "Menus not available in plugin mode"
+       pack $w.label
+       return
+    }
+    bind [winfo toplevel $w] <Button-3> "tk_popup $w.pop %X %Y"
+    bind $text <Button-3> "tk_popup $w.pop %X %Y"
+
+    ## Console Menu
+    ## FIX - get the attachment stuff working
+    set n cons
+    set l "Console"
+    pack [menubutton $w.$n  -text $l -un 0 -menu $w.$n.m] -side left
+    $w.pop add cascade -label $l -un 0 -menu $w.pop.$n
+    foreach m [list [menu $w.$n.m -disabledfore $data(-promptcolor)] \
+           [menu $w.pop.$n -disabledfore $data(-promptcolor)]] {
+       $m add command -label "Console $W" -state disabled
+       $m add command -label "Clear Console " -un 1 \
+               -acc [event info <<Console_Clear>>] \
+               -com [list Console_clear $W]
+       $m add command -label "Load File" -und 0 \
+               -command [list Console_load $W]
+       $m add cascade -label "Save ..."  -und 0 -menu $m.save
+       $m add separator
+       $m add cascade -label "Attach Console"  -und 7 -menu $m.apps \
+               -state disabled
+       $m add cascade -label "Attach Namespace" -und 7 -menu $m.name \
+               -state disabled
+       $m add separator
+       $m add command -label "Exit" -un 1 -acc [event info <<Console_Exit>>] \
+               -command [list Console:exit $W]
+
+       ## Save Menu
+       ##
+       set s $m.save
+       menu $s -disabledforeground $data(-promptcolor) -tearoff 0
+       $s add command -label "All"     -und 0 \
+               -command [list Console_save $W all]
+       $s add command -label "History" -und 0 \
+               -command [list Console_save $W history]
+       $s add command -label "Stdin"   -und 3 \
+               -command [list Console_save $W stdin]
+       $s add command -label "Stdout"  -und 3 \
+               -command [list Console_save $W stdout]
+       $s add command -label "Stderr"  -und 3 \
+               -command [list Console_save $W stderr]
+
+       ## Attach Console Menu
+       ##
+       menu $m.apps -disabledforeground $data(-promptcolor) \
+               -postcommand [list ConsoleAttachMenu $m.apps]
+
+       ## Attach Interpreter Menu
+       ##
+       menu $m.int -disabledforeground $data(-promptcolor) -tearoff 0 \
+               -postcommand [list ConsoleAttachMenu $m.int interp]
+
+       ## Attach Namespace Menu
+       ##
+       menu $m.name -disabledforeground $data(-promptcolor) -tearoff 0 \
+               -postcommand [list ConsoleAttachMenu $m.name namespace]
+    }
+
+    ## Edit Menu
+    ##
+    set n edit
+    set l "Edit"
+    pack [menubutton $w.$n  -text $l -un 0 -menu $w.$n.m] -side left
+    $w.pop add cascade -label $l -un 0 -menu $w.pop.$n
+    foreach m [list [menu $w.$n.m] [menu $w.pop.$n]] {
+       $m add command -label "Cut"   -un 1 \
+               -acc [lindex [event info <<Cut>>] 0] \
+               -command [list ConsoleCut $text]
+       $m add command -label "Copy"  -un 1 \
+               -acc [lindex [event info <<Copy>>] 0] \
+               -command [list ConsoleCopy $text]
+       $m add command -label "Paste" -un 0 \
+               -acc [lindex [event info <<Paste>>] 0] \
+               -command [list ConsolePaste $text]
+       $m add separator
+       $m add command -label "Find"  -un 0 \
+               -acc [lindex [event info <<Console_Find>>] 0] \
+               -command [list ConsoleFindBox $W]
+       $m add separator
+       $m add command -label "Last Error" -un 0 -command [list $W error]
+    }
+
+    ## Prefs Menu
+    ##
+    set n pref
+    set l "Prefs"
+    pack [menubutton $w.$n  -text $l -un 0 -menu $w.$n.m] -side left
+    $w.pop add cascade -label $l -un 0 -menu $w.pop.$n
+    foreach m [list [menu $w.$n.m] [menu $w.pop.$n]] {
+       $m add checkbutton -label "Brace Highlighting" -var $W\(-lightbrace\)
+       $m add checkbutton -label "Command Highlighting" -var $W\(-lightcmd\)
+       $m add checkbutton -label "Grab Puts Output" -var $W\(-grabputs\) \
+               -command "Console:configure $W \
+               -grabputs \[set ${W}(-grabputs)\]"
+       $m add checkbutton -label "History Substitution" -var $W\(-subhistory\)
+       $m add checkbutton -label "Show Multiple Matches" \
+               -var $W\(-showmultiple\)
+       $m add checkbutton -label "Show Menubar" -var $W\(-showmenu\) \
+               -command "Console:configure $W \
+               -showmenu \[set ${W}(-showmenu)\]"
+    }
+
+    ## History Menu
+    ##
+    set n hist
+    set l "History"
+    pack [menubutton $w.$n  -text $l -un 0 -menu $w.$n.m] -side left
+    $w.pop add cascade -label $l -un 0 -menu $w.pop.$n
+    foreach m [list $w.$n.m $w.pop.$n] {
+       menu $m -disabledfore $data(-promptcolor) \
+               -postcommand [list ConsoleHistoryMenu $W $m]
+    }
+
+    ## Help Menu
+    ##
+    set n help
+    set l "Help"
+    pack [menubutton $w.$n  -text $l -un 0 -menu $w.$n.m] -side right
+    $w.pop add cascade -label $l -un 0 -menu $w.pop.$n
+    foreach m [list [menu $w.$n.m] [menu $w.pop.$n]] {
+       $m config -disabledfore $data(-promptcolor)
+       $m add command -label "About " -un 0 \
+               -acc [event info <<Console_About>>] \
+               -command [list ConsoleAbout $W]
+    }
+
+    bind $W <<Console_Exit>>   [list Console:exit $W]
+    bind $W <<Console_About>>  [list ConsoleAbout $W]
+    bind $W <<Console_Help>>   [list ConsoleHelp $W]
+    bind $W <<Console_Find>>   [list ConsoleFindBox $W]
+
+    ## Menu items need null PostConsole bindings to avoid the TagProc
+    ##
+    foreach ev [bind $W] {
+       bind PostConsole $ev {
+           # empty
+       }
+    }
+}
+
+## ConsoleHistoryMenu - dynamically build the menu for attached interpreters
+##
+# ARGS:        w       - menu widget
+##
+;proc ConsoleHistoryMenu {W w} {
+    upvar \#0 $W data
+
+    if {![winfo exists $w]} return
+    set id [ConsoleEvalSlave history nextid]
+    if {$data(histid)==$id} return
+    set data(histid) $id
+    $w delete 0 end
+    set con $data(console)
+    while {($id>$data(histid)-10) && \
+           ![catch {ConsoleEvalSlave history event [incr id -1]} tmp]} {
+       set lbl [lindex [split $tmp "\n"] 0]
+       if {[string len $lbl]>32} { set lbl [string range $tmp 0 30]... }
+       $w add command -label "$id: $lbl" -command "
+       $con delete limit end
+       $con insert limit [list $tmp]
+       $con see end
+       ConsoleEval $con
+       "
+    }
+}
+
+## ConsoleFindBox - creates minimal dialog interface to ConsoleFind
+# ARGS:        w       - text widget
+#      str     - optional seed string for data(find)
+##
+;proc ConsoleFindBox {W {str {}}} {
+    upvar \#0 $W data
+
+    set t $data(console)
+    set base $W.find
+    if {![winfo exists $base]} {
+       toplevel $base
+       wm withdraw $base
+       wm title $base "Console Find"
+
+       pack [frame $base.f] -fill x -expand 1
+       label $base.f.l -text "Find:"
+       entry $base.f.e -textvar $W\(find\)
+       pack [frame $base.opt] -fill x
+       checkbutton $base.opt.c -text "Case Sensitive" -var $W\(find,case\)
+       checkbutton $base.opt.r -text "Use Regexp" -var $W\(find,reg\)
+       pack $base.f.l -side left
+       pack $base.f.e $base.opt.c $base.opt.r -side left -fill both -expand 1
+       pack [frame $base.sep -bd 2 -relief sunken -height 4] -fill x
+       pack [frame $base.btn] -fill both
+       button $base.btn.fnd -text "Find" -width 6
+       button $base.btn.clr -text "Clear" -width 6
+       button $base.btn.dis -text "Dismiss" -width 6
+       eval pack [winfo children $base.btn] -padx 4 -pady 2 \
+               -side left -fill both
+
+       focus $base.f.e
+
+       bind $base.f.e <Return> [list $base.btn.fnd invoke]
+       bind $base.f.e <Escape> [list $base.btn.dis invoke]
+    }
+    $base.btn.fnd config -command "Console_find $W \$data(find) \
+           -case \$data(find,case) -reg \$data(find,reg)"
+    $base.btn.clr config -command "
+    $t tag remove find 1.0 end
+    set data(find) {}
+    "
+    $base.btn.dis config -command "
+    $t tag remove find 1.0 end
+    wm withdraw $base
+    "
+    if {[string compare {} $str]} {
+       set data(find) $str
+       $base.btn.fnd invoke
+    }
+
+    if {[string compare normal [wm state $base]]} {
+       wm deiconify $base
+    } else { raise $base }
+    $base.f.e select range 0 end
+}
+
+## Console_find - searches in text widget for $str and highlights it
+## If $str is empty, it just deletes any highlighting
+# ARGS: W      - console widget
+#      str     - string to search for
+#      -case   TCL_BOOLEAN     whether to be case sensitive    DEFAULT: 0
+#      -regexp TCL_BOOLEAN     whether to use $str as pattern  DEFAULT: 0
+##
+;proc ConsoleFind {W str args} {
+    upvar \#0 $W data
+    set t $data(console)
+    $t tag remove find 1.0 end
+    set truth {^(1|yes|true|on)$}
+    set opts  {}
+    foreach {key val} $args {
+       switch -glob -- $key {
+           -c* { if {[regexp -nocase $truth $val]} { set case 1 } }
+           -r* { if {[regexp -nocase $truth $val]} { lappend opts -regexp } }
+           default { return -code error "Unknown option $key" }
+       }
+    }
+    if {![info exists case]} { lappend opts -nocase }
+    if {[string match {} $str]} return
+    $t mark set findmark 1.0
+    while {[string compare {} [set ix [eval $t search $opts -count numc -- \
+           [list $str] findmark end]]]} {
+       $t tag add find $ix ${ix}+${numc}c
+       $t mark set findmark ${ix}+1c
+    }
+    catch {$t see find.first}
+    return [expr [llength [$t tag ranges find]]/2]
+}
+
+## Console:savecommand - saves a command in a buffer for later retrieval
+#
+##
+;proc Console:savecommand {w} {
+    upvar \#0 [winfo parent $w] data
+
+    set tmp $data(cmdsave)
+    set data(cmdsave) [ConsoleCmdGet $w]
+    if {[string match {} $data(cmdsave)]} {
+       set data(cmdsave) $tmp
+    } else {
+       $w delete limit end-1c
+    }
+    $w insert limit $tmp
+    $w see end
+}
+
+## Console_load - sources a file into the console
+# ARGS:        fn      - (optional) filename to source in
+# Returns:     selected filename ({} if nothing was selected)
+## 
+;proc Console_load {W {fn ""}} {
+    set types {
+       {{Tcl Files}    {.tcl .tk}}
+       {{Text Files}   {.txt}}
+       {{All Files}    *}
+    }
+    if {
+       [string match {} $fn] &&
+       ([catch {tk_getOpenFile -filetypes $types \
+           -title "Source File"} fn] || [string match {} $fn])
+    } { return }
+    ConsoleEvalAttached [list source $fn]
+}
+
+## Console_save - saves the console buffer to a file
+## This does not eval in a slave because it's not necessary
+# ARGS:        w       - console text widget
+#      fn      - (optional) filename to save to
+## 
+;proc Console_save {W {fn ""} {type ""}} {
+    upvar \#0 $W data
+
+    set c $data(console)
+    if {![regexp -nocase {^(all|history|stdin|stdout|stderr)$} $type]} {
+       array set s { 0 All 1 History 2 Stdin 3 Stdout 4 Stderr 5 Cancel }
+       ## Allow user to specify what kind of stuff to save
+       set type [tk_dialog $W.savetype "Save Type" \
+               "What part of the console text do you want to save?" \
+               questhead 0 $s(0) $s(1) $s(2) $s(3) $s(4) $s(5)]
+       if {$type == 5 || $type == -1} return
+       set type $s($type)
+    }
+    if {[string match {} $fn]} {
+       set types {
+           {{Text Files}       {.txt}}
+           {{Tcl Files}        {.tcl .tk}}
+           {{All Files}        *}
+       }
+       if {[catch {tk_getSaveFile -filetypes $types -title "Save $type"} fn] \
+               || [string match {} $fn]} return
+    }
+    set type [string tolower $type]
+    switch $type {
+       stdin - stdout - stderr {
+           set data {}
+           foreach {first last} [$c tag ranges $type] {
+               lappend data [$c get $first $last]
+           }
+           set data [join $data \n]
+       }
+       history         { set data [Console_history $W] }
+       all - default   { set data [$c get 1.0 end-1c] }
+    }
+    if {[catch {open $fn w} fid]} {
+       return -code error "Save Error: Unable to open '$fn' for writing\n$fid"
+    }
+    puts $fid $data
+    close $fid
+}
+
+## clear - clears the buffer of the console (not the history though)
+## 
+;proc Console_clear {W {pcnt 100}} {
+    upvar \#0 $W data
+
+    set data(tmp) [ConsoleCmdGet $data(console)]
+    if {![regexp {^[0-9]*$} $pcnt] || $pcnt < 1 || $pcnt > 100} {
+       return -code error \
+               "invalid percentage to clear: must be 1-100 (100 default)"
+    } elseif {$pcnt == 100} {
+       $data(console) delete 1.0 end
+    } else {
+       set tmp [expr $pcnt/100.0*[$data(console) index end]]
+       $data(console) delete 1.0 "$tmp linestart"
+    }
+    Console:prompt $W {} $data(tmp)
+}
+
+;proc Console_error {W} {
+    ## Outputs stack caused by last error.
+    upvar \#0 $W data
+    set info $data(errorInfo)
+    if {[string match {} $info]} { set info {errorInfo empty} }
+    catch {destroy $W.error}
+    set w [toplevel $W.error]
+    wm title $w "Console Last Error"
+    button $w.close -text Dismiss -command [list destroy $w]
+    scrollbar $w.sy -takefocus 0 -bd 1 -command [list $w.text yview]
+    text $w.text -yscrollcommand [list $w.sy set]
+    pack $w.close -side bottom -fill x
+    pack $w.sy -side right -fill y
+    pack $w.text -fill both -expand 1
+    $w.text insert 1.0 $info
+    $w.text config -state disabled
+}
+
+## Console_event - searches for history based on a string
+## Search forward (next) if $int>0, otherwise search back (prev)
+# ARGS:        W       - console widget
+##
+;proc Console_event {W int {str {}}} {
+    upvar \#0 $W data
+
+    if {!$int} return
+    set w $data(console)
+
+    set nextid [ConsoleEvalSlave history nextid]
+    if {[string compare {} $str]} {
+       ## String is not empty, do an event search
+       set event $data(event)
+       if {$int < 0 && $event == $nextid} { set data(cmdbuf) $str }
+       set len [string len $data(cmdbuf)]
+       incr len -1
+       if {$int > 0} {
+           ## Search history forward
+           while {$event < $nextid} {
+               if {[incr event] == $nextid} {
+                   $w delete limit end
+                   $w insert limit $data(cmdbuf)
+                   break
+               } elseif {![catch {ConsoleEvalSlave history event $event} res]\
+                       && ![string compare $data(cmdbuf) \
+                       [string range $res 0 $len]]} {
+                   $w delete limit end
+                   $w insert limit $res
+                   break
+               }
+           }
+           set data(event) $event
+       } else {
+           ## Search history reverse
+           while {![catch {ConsoleEvalSlave \
+                   history event [incr event -1]} res]} {
+               if {![string compare $data(cmdbuf) \
+                       [string range $res 0 $len]]} {
+                   $w delete limit end
+                   $w insert limit $res
+                   set data(event) $event
+                   break
+               }
+           }
+       } 
+    } else {
+       ## String is empty, just get next/prev event
+       if {$int > 0} {
+           ## Goto next command in history
+           if {$data(event) < $nextid} {
+               $w delete limit end
+               if {[incr data(event)] == $nextid} {
+                   $w insert limit $data(cmdbuf)
+               } else {
+                   $w insert limit [ConsoleEvalSlave \
+                           history event $data(event)]
+               }
+           }
+       } else {
+           ## Goto previous command in history
+           if {$data(event) == $nextid} {set data(cmdbuf) [ConsoleCmdGet $w]}
+           if {[catch {ConsoleEvalSlave \
+                   history event [incr data(event) -1]} res]} {
+               incr data(event)
+           } else {
+               $w delete limit end
+               $w insert limit $res
+           }
+       }
+    }
+    $w mark set insert end
+    $w see end
+}
+
+;proc Console_history {W args} {
+    set sub {\2}
+    if {[string match -n* $args]} { append sub "\n" }
+    set h [ConsoleEvalSlave history]
+    regsub -all "( *\[0-9\]+  |\t)(\[^\n\]*\n?)" $h $sub h
+    return $h
+}
+
+##
+## Some procedures to make up for lack of built-in shell commands
+##
+
+## puts
+## This allows me to capture all stdout/stderr to the console window
+# ARGS:        same as usual   
+# Outputs:     the string with a color-coded text tag
+## 
+if {![catch {rename puts console_tcl_puts}]} {
+    ;proc puts args {
+       global Console
+       set w [lindex $Console(active) 0]
+       if {[winfo exists $w]} {
+           set len [llength $args]
+           if {$len==1} {
+               eval $w insert output $args stdout {\n} stdout
+               $w see output
+           } elseif {$len==2 && [regexp {(stdout|stderr|-nonewline)} \
+                   [lindex $args 0] junk tmp]} {
+               if {[string compare $tmp -nonewline]} {
+                   eval $w insert output [lreplace $args 0 0] $tmp {\n} $tmp
+               } else {
+                   eval $w insert output [lreplace $args 0 0] stdout
+               }
+               $w see output
+           } elseif {$len==3 && \
+                   [regexp {(stdout|stderr)} [lreplace $args 2 2] junk tmp]} {
+               if {[string compare [lreplace $args 1 2] -nonewline]} {
+                   eval $w insert output [lrange $args 1 1] $tmp
+               } else {
+                   eval $w insert output [lreplace $args 0 1] $tmp
+               }
+               $w see output
+           } else {
+               global errorCode errorInfo
+               if {[catch "console_tcl_puts $args" msg]} {
+                   regsub console_tcl_puts $msg puts msg
+                   regsub -all console_tcl_puts \
+                           $errorInfo puts errorInfo
+                   error $msg
+               }
+               return $msg
+           }
+           if {$len} update
+       } else {
+           global errorCode errorInfo
+           if {[catch "console_tcl_puts $args" msg]} {
+               regsub console_tcl_puts $msg puts msg
+               regsub -all console_tcl_puts $errorInfo puts errorInfo
+               error $msg
+           }
+           return $msg
+       }
+    }
+}
+
+## echo
+## Relaxes the one string restriction of 'puts'
+# ARGS:        any number of strings to output to stdout
+##
+proc echo args { puts [concat $args] }
+
+## alias - akin to the csh alias command
+## If called with no args, then it dumps out all current aliases
+## If called with one arg, returns the alias of that arg (or {} if none)
+# ARGS:        newcmd  - (optional) command to bind alias to
+#      args    - command and args being aliased
+## 
+proc alias {{newcmd {}} args} {
+    if {[string match {} $newcmd]} {
+       set res {}
+       foreach a [interp aliases] {
+           lappend res [list $a -> [interp alias {} $a]]
+       }
+       return [join $res \n]
+    } elseif {[string match {} $args]} {
+       interp alias {} $newcmd
+    } else {
+       eval interp alias [list {} $newcmd {}] $args
+    }
+}
+
+## dump - outputs variables/procedure/widget info in source'able form.
+## Accepts glob style pattern matching for the names
+# ARGS:        type    - type of thing to dump: must be variable, procedure, widget
+# OPTS: -nocomplain
+#              don't complain if no vars match something
+#      -filter pattern
+#              specifies a glob filter pattern to be used by the variable
+#              method as an array filter pattern (it filters down for
+#              nested elements) and in the widget method as a config
+#              option filter pattern
+#      --      forcibly ends options recognition
+# Returns:     the values of the requested items in a 'source'able form
+## 
+proc dump {type args} {
+    set whine 1
+    set code  ok
+    if {[string match {} $args]} {
+       ## If no args, assume they gave us something to dump and
+       ## we'll try anything
+       set args [list $type]
+       set type any
+    }
+    while {[string match -* $args]} {
+       switch -glob -- [lindex $args 0] {
+           -n* { set whine 0; set args [lreplace $args 0 0] }
+           -f* { set fltr [lindex $args 1]; set args [lreplace $args 0 1] }
+           --  { set args [lreplace $args 0 0]; break }
+           default {return -code error "unknown option \"[lindex $args 0]\""}
+       }
+    }
+    if {$whine && [string match {} $args]} {
+       return -code error "wrong \# args: [lindex [info level 0] 0] type\
+               ?-nocomplain? ?-filter pattern? ?--? pattern ?pattern ...?"
+    }
+    set res {}
+    switch -glob -- $type {
+       c* {
+           # command
+           # outpus commands by figuring out, as well as possible, what it is
+           # this does not attempt to auto-load anything
+           foreach arg $args {
+               if {[string compare {} [set cmds [info comm $arg]]]} {
+                   foreach cmd [lsort $cmds] {
+                       if {[lsearch -exact [interp aliases] $cmd] > -1} {
+                           append res "\#\# ALIAS:   $cmd =>\
+                                   [interp alias {} $cmd]\n"
+                       } elseif {[string compare {} [info procs $cmd]]} {
+                           if {[catch {uplevel dump p -- $cmd} msg] \
+                                   && $whine} { set code error }
+                           append res $msg\n
+                       } else {
+                           append res "\#\# COMMAND: $cmd\n"
+                       }
+                   }
+               } elseif {$whine} {
+                   append res "\#\# No known command $arg\n"
+                   set code error
+               }
+           }
+       }
+       v* {
+           # variable
+           # outputs variables value(s), whether array or simple.
+           if {![info exists fltr]} { set fltr * }
+           foreach arg $args {
+               if {[string match {} \
+                       [set vars [uplevel info vars [list $arg]]]]} {
+                   if {[uplevel info exists $arg]} {
+                       set vars $arg
+                   } elseif {$whine} {
+                       append res "\#\# No known variable $arg\n"
+                       set code error
+                       continue
+                   } else { continue }
+               }
+               foreach var [lsort $vars] {
+                   upvar $var v
+                   if {[array exists v]} {
+                       set nest {}
+                       append res "array set $var \{\n"
+                       foreach i [lsort [array names v $fltr]] {
+                           upvar 0 v\($i\) __ary
+                           if {[array exists __ary]} {
+                               append nest "\#\# NESTED ARRAY ELEMENT: $i\n"
+                               append nest "upvar 0 [list $var\($i\)] __ary;\
+                                       [dump v -filter $fltr __ary]\n"
+                           } else {
+                               append res "    [list $i]\t[list $v($i)]\n"
+                           }
+                       }
+                       append res "\}\n$nest"
+                   } else {
+                       append res [list set $var $v]\n
+                   }
+               }
+           }
+       }
+       p* {
+           # procedure
+           foreach arg $args {
+               if {[string compare {} [set ps [info proc $arg]]] ||
+               ([auto_load $arg] &&
+               [string compare {} [set ps [info proc $arg]]])} {
+                   foreach p [lsort $ps] {
+                       set as {}
+                       foreach a [info args $p] {
+                           if {[info default $p $a tmp]} {
+                               lappend as [list $a $tmp]
+                           } else {
+                               lappend as $a
+                           }
+                       }
+                       append res [list proc $p $as [info body $p]]\n
+                   }
+               } elseif {$whine} {
+                   append res "\#\# No known proc $arg\n"
+                   set code error
+               }
+           }
+       }
+       w* {
+           # widget
+           ## The user should have Tk loaded
+           if {[string match {} [info command winfo]]} {
+               return -code error "winfo not present, cannot dump widgets"
+           }
+           if {![info exists fltr]} { set fltr .* }
+           foreach arg $args {
+               if {[string compare {} [set ws [info command $arg]]]} {
+                   foreach w [lsort $ws] {
+                       if {[winfo exists $w]} {
+                           if {[catch {$w configure} cfg]} {
+                               append res "\#\# Widget $w\
+                                       does not support configure method"
+                               set code error
+                           } else {
+                               append res "\#\# [winfo class $w]\
+                                       $w\n$w configure"
+                               foreach c $cfg {
+                                   if {[llength $c] != 5} continue
+                                   if {[regexp -nocase -- $fltr $c]} {
+                                       append res " \\\n\t[list [lindex $c 0]\
+                                               [lindex $c 4]]"
+                                   }
+                               }
+                               append res \n
+                           }
+                       }
+                   }
+               } elseif {$whine} {
+                   append res "\#\# No known widget $arg\n"
+                   set code error
+               }
+           }
+       }
+       a* {
+           ## any - try to dump as var, then command, then widget...
+           if {
+               [catch {uplevel dump v -- $args} res] &&
+               [catch {uplevel dump c -- $args} res] &&
+               [catch {uplevel dump w -- $args} res]
+           } {
+               set res "dump was unable to resolve type for \"$args\""
+               set code error
+           }
+       }
+       default {
+           return -code error "bad [lindex [info level 0] 0] option\
+                   \"$type\": must be command, procedure, variable, widget"
+       }
+    }
+    return -code $code [string trimr $res \n]
+}
+
+## which - tells you where a command is found
+# ARGS:        cmd     - command name
+# Returns:     where command is found (internal / external / unknown)
+## 
+proc which cmd {
+    if {[string compare {} [info commands $cmd]] || \
+           ([auto_load $cmd] && [string compare {} [info commands $cmd]])} {
+       if {[lsearch -exact [interp aliases] $cmd] > -1} {
+           set result "$cmd: aliased to [alias $cmd]"
+       } elseif {[string compare {} [info procs $cmd]]} {
+           set result "$cmd: procedure"
+       } else {
+           set result "$cmd: command"
+       }
+       global auto_index
+       if {[info exists auto_index($cmd)]} {
+           ## This tells you where the command MIGHT have come from -
+           ## not true if the command was redefined interactively or
+           ## existed before it had to be auto_loaded.  This is just
+           ## provided as a hint at where it MAY have come from
+           append result " ($auto_index($cmd))"
+       }
+       return $result
+    } elseif {[string compare {} [auto_execok $cmd]]} {
+       return [auto_execok $cmd]
+    } else {
+       return -code error "$cmd: command not found"
+    }
+}
+
+## dir - directory list
+# ARGS:        args    - names/glob patterns of directories to list
+# OPTS:        -all    - list hidden files as well (Unix dot files)
+#      -long   - list in full format "permissions size date filename"
+#      -full   - displays / after directories and link paths for links
+# Returns:     a directory listing
+## 
+proc dir {args} {
+    array set s {
+       all 0 full 0 long 0
+       0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx
+    }
+    while {[string match \-* [lindex $args 0]]} {
+       set str [lindex $args 0]
+       set args [lreplace $args 0 0]
+       switch -glob -- $str {
+           -a* {set s(all) 1} -f* {set s(full) 1}
+           -l* {set s(long) 1} -- break
+           default {
+               return -code error "unknown option \"$str\",\
+                       should be one of: -all, -full, -long"
+           }
+       }
+    }
+    set sep [string trim [file join . .] .]
+    if {[string match {} $args]} { set args . }
+    foreach arg $args {
+       if {[file isdir $arg]} {
+           set arg [string trimr $arg $sep]$sep
+           if {$s(all)} {
+               lappend out [list $arg [lsort [glob -nocomplain -- $arg.* $arg*]]]
+           } else {
+               lappend out [list $arg [lsort [glob -nocomplain -- $arg*]]]
+           }
+       } else {
+           lappend out [list [file dirname $arg]$sep \
+                   [lsort [glob -nocomplain -- $arg]]]
+       }
+    }
+    if {$s(long)} {
+       set old [clock scan {1 year ago}]
+       set fmt "%s%9d %s %s\n"
+       foreach o $out {
+           set d [lindex $o 0]
+           append res $d:\n
+           foreach f [lindex $o 1] {
+               file lstat $f st
+               set f [file tail $f]
+               if {$s(full)} {
+                   switch -glob $st(type) {
+                       d* { append f $sep }
+                       l* { append f "@ -> [file readlink $d$sep$f]" }
+                       default { if {[file exec $d$sep$f]} { append f * } }
+                   }
+               }
+               if {[string match file $st(type)]} {
+                   set mode -
+               } else {
+                   set mode [string index $st(type) 0]
+               }
+               foreach j [split [format %o [expr $st(mode)&0777]] {}] {
+                   append mode $s($j)
+               }
+               if {$st(mtime)>$old} {
+                   set cfmt {%b %d %H:%M}
+               } else {
+                   set cfmt {%b %d  %Y}
+               }
+               append res [format $fmt $mode $st(size) \
+                       [clock format $st(mtime) -format $cfmt] $f]
+           }
+           append res \n
+       }
+    } else {
+       foreach o $out {
+           set d [lindex $o 0]
+           append res $d:\n
+           set i 0
+           foreach f [lindex $o 1] {
+               if {[string len [file tail $f]] > $i} {
+                   set i [string len [file tail $f]]
+               }
+           }
+           set i [expr {$i+2+$s(full)}]
+           ## This gets the number of cols in the Console console widget
+           set j [expr {66/$i}]
+           set k 0
+           foreach f [lindex $o 1] {
+               set f [file tail $f]
+               if {$s(full)} {
+                   switch -glob [file type $d$sep$f] {
+                       d* { append f $sep }
+                       l* { append f @ }
+                       default { if {[file exec $d$sep$f]} { append f * } }
+                   }
+               }
+               append res [format "%-${i}s" $f]
+               if {[incr k]%$j == 0} {set res [string trimr $res]\n}
+           }
+           append res \n\n
+       }
+    }
+    return [string trimr $res]
+}
+interp alias {} ls {} dir -full
+
+## lremove - remove items from a list
+# OPTS:        -all    remove all instances of each item
+# ARGS:        l       a list to remove items from
+#      args    items to remove
+##
+proc lremove {args} {
+    set all 0
+    if {[string match \-a* [lindex $args 0]]} {
+       set all 1
+       set args [lreplace $args 0 0]
+    }
+    set l [lindex $args 0]
+    foreach i [join [lreplace $args 0 0]] {
+       if {[set ix [lsearch -exact $l $i]] == -1} continue
+       set l [lreplace $l $ix $ix]
+       if {$all} {
+           while {[set ix [lsearch -exact $l $i]] != -1} {
+               set l [lreplace $l $ix $ix]
+           }
+       }
+    }
+    return $l
+}
+
+
+## Unknown changed to get output into Console window
+# unknown:
+# Invoked automatically whenever an unknown command is encountered.
+# Works through a list of "unknown handlers" that have been registered
+# to deal with unknown commands.  Extensions can integrate their own
+# handlers into the "unknown" facility via "unknown_handle".
+#
+# If a handler exists that recognizes the command, then it will
+# take care of the command action and return a valid result or a
+# Tcl error.  Otherwise, it should return "-code continue" (=2)
+# and responsibility for the command is passed to the next handler.
+#
+# Arguments:
+# args -       A list whose elements are the words of the original
+#              command, including the command name.
+
+proc unknown args {
+    global unknown_handler_order unknown_handlers errorInfo errorCode
+
+    #
+    # Be careful to save error info now, and restore it later
+    # for each handler.  Some handlers generate their own errors
+    # and disrupt handling.
+    #
+    set savedErrorCode $errorCode
+    set savedErrorInfo $errorInfo
+
+    if {![info exists unknown_handler_order] || \
+           ![info exists unknown_handlers]} {
+       set unknown_handlers(tcl) tcl_unknown
+       set unknown_handler_order tcl
+    }
+
+    foreach handler $unknown_handler_order {
+        set status [catch {uplevel $unknown_handlers($handler) $args} result]
+
+        if {$status == 1} {
+            #
+            # Strip the last five lines off the error stack (they're
+            # from the "uplevel" command).
+            #
+            set new [split $errorInfo \n]
+            set new [join [lrange $new 0 [expr [llength $new] - 6]] \n]
+            return -code $status -errorcode $errorCode \
+                   -errorinfo $new $result
+
+        } elseif {$status != 4} {
+            return -code $status $result
+        }
+
+        set errorCode $savedErrorCode
+        set errorInfo $savedErrorInfo
+    }
+
+    set name [lindex $args 0]
+    return -code error "invalid command name \"$name\""
+}
+
+# tcl_unknown:
+# Invoked when a Tcl command is invoked that doesn't exist in the
+# interpreter:
+#
+#      1. See if the autoload facility can locate the command in a
+#         Tcl script file.  If so, load it and execute it.
+#      2. If the command was invoked interactively at top-level:
+#          (a) see if the command exists as an executable UNIX program.
+#              If so, "exec" the command.
+#          (b) see if the command requests csh-like history substitution
+#              in one of the common forms !!, !<number>, or ^old^new.  If
+#              so, emulate csh's history substitution.
+#          (c) see if the command is a unique abbreviation for another
+#              command.  If so, invoke the command.
+#
+# Arguments:
+# args -       A list whose elements are the words of the original
+#              command, including the command name.
+
+proc tcl_unknown args {
+    global auto_noexec auto_noload env unknown_pending tcl_interactive Console
+    global errorCode errorInfo
+
+    # Save the values of errorCode and errorInfo variables, since they
+    # may get modified if caught errors occur below.  The variables will
+    # be restored just before re-executing the missing command.
+
+    set savedErrorCode $errorCode
+    set savedErrorInfo $errorInfo
+    set name [lindex $args 0]
+    if {![info exists auto_noload]} {
+       #
+       # Make sure we're not trying to load the same proc twice.
+       #
+       if {[info exists unknown_pending($name)]} {
+           return -code error "self-referential recursion in \"unknown\" for command \"$name\"";
+       }
+       set unknown_pending($name) pending;
+       set ret [catch {auto_load $name} msg]
+       unset unknown_pending($name);
+       if {$ret} {
+           return -code $ret -errorcode $errorCode \
+                   "error while autoloading \"$name\": $msg"
+       }
+       if {![array size unknown_pending]} {
+           unset unknown_pending
+       }
+       if {$msg} {
+           set errorCode $savedErrorCode
+           set errorInfo $savedErrorInfo
+           set code [catch {uplevel 1 $args} msg]
+           if {$code ==  1} {
+               #
+               # Strip the last five lines off the error stack (they're
+               # from the "uplevel" command).
+               #
+
+               set new [split $errorInfo \n]
+               set new [join [lrange $new 0 [expr [llength $new] - 6]] \n]
+               return -code error -errorcode $errorCode \
+                       -errorinfo $new $msg
+           } else {
+               return -code $code $msg
+           }
+       }
+    }
+    if {[info level] == 1 && [string match {} [info script]] \
+           && [info exists tcl_interactive] && $tcl_interactive} {
+       if {![info exists auto_noexec]} {
+           set new [auto_execok $name]
+           if {[string compare $new ""]} {
+               set errorCode $savedErrorCode
+               set errorInfo $savedErrorInfo
+               return [uplevel exec [list $new] [lrange $args 1 end]]
+               #return [uplevel exec >&@stdout <@stdin $new [lrange $args 1 end]]
+           }
+       }
+       set errorCode $savedErrorCode
+       set errorInfo $savedErrorInfo
+       ##
+       ## History substitution moved into ConsoleEvalCmd
+       ##
+       set ret [catch {set cmds [info commands $name*]} msg]
+       if {![string compare $name "::"]} {
+           set name ""
+       }
+       if {$ret != 0} {
+           return -code $ret -errorcode $errorCode \
+               "error in unknown while checking if \"$name\" is a unique command abbreviation: $msg"
+       }
+       if {[llength $cmds] == 1} {
+           return [uplevel [lreplace $args 0 0 $cmds]]
+       }
+       if {[llength $cmds]} {
+           if {$name == ""} {
+               return -code error "empty command name \"\""
+           } else {
+               return -code error \
+                       "ambiguous command name \"$name\": [lsort $cmds]"
+           }
+       }
+    }
+    return -code continue
+}
+
+switch -glob $tcl_platform(platform) {
+    win* { set META Alt }
+    mac* { set META Command }
+    default { set META Meta }
+}
+
+# ConsoleClipboardKeysyms --
+# This procedure is invoked to identify the keys that correspond to
+# the "copy", "cut", and "paste" functions for the clipboard.
+#
+# Arguments:
+# copy -       Name of the key (keysym name plus modifiers, if any,
+#              such as "Meta-y") used for the copy operation.
+# cut -                Name of the key used for the cut operation.
+# paste -      Name of the key used for the paste operation.
+
+;proc ConsoleClipboardKeysyms {copy cut paste} {
+    bind Console <$copy>       {ConsoleCopy %W}
+    bind Console <$cut>                {ConsoleCut %W}
+    bind Console <$paste>      {ConsolePaste %W}
+}
+
+;proc ConsoleCut w {
+    if {[string match $w [selection own -displayof $w]]} {
+       clipboard clear -displayof $w
+       catch {
+           clipboard append -displayof $w [selection get -displayof $w]
+           if {[$w compare sel.first >= limit]} {$w delete sel.first sel.last}
+       }
+    }
+}
+;proc ConsoleCopy w {
+    if {[string match $w [selection own -displayof $w]]} {
+       clipboard clear -displayof $w
+       catch {clipboard append -displayof $w [selection get -displayof $w]}
+    }
+}
+
+;proc ConsolePaste w {
+    if {
+       ![catch {selection get -displayof $w} tmp] ||
+       ![catch {selection get -displayof $w -type TEXT} tmp] ||
+       ![catch {selection get -displayof $w -selection CLIPBOARD} tmp]
+    } {
+       if {[$w compare insert < limit]} {$w mark set insert end}
+       $w insert insert $tmp
+       $w see insert
+       if {[string match *\n* $tmp]} {ConsoleEval $w}
+    }
+}
+
+## Get all Text bindings into Console
+foreach ev [bind Text] { bind Console $ev [bind Text $ev] }
+## We don't want newline insertion
+bind Console <Control-Key-o> {}
+
+foreach {ev key} {
+    <<Console_Previous>>               <Key-Up>
+    <<Console_Next>>                   <Key-Down>
+    <<Console_NextImmediate>>          <Control-Key-n>
+    <<Console_PreviousImmediate>>      <Control-Key-p>
+    <<Console_PreviousSearch>>         <Control-Key-r>
+    <<Console_NextSearch>>             <Control-Key-s>
+
+    <<Console_Expand>>                 <Key-Tab>
+    <<Console_ExpandFile>>             <Key-Escape>
+    <<Console_ExpandProc>>             <Control-Shift-Key-P>
+    <<Console_ExpandVar>>              <Control-Shift-Key-V>
+    <<Console_Tab>>                    <Control-Key-i>
+    <<Console_Tab>>                    <Meta-Key-i>
+    <<Console_Eval>>                   <Key-Return>
+    <<Console_Eval>>                   <Key-KP_Enter>
+
+    <<Console_Clear>>                  <Control-Key-l>
+    <<Console_KillLine>>               <Control-Key-k>
+    <<Console_Transpose>>              <Control-Key-t>
+    <<Console_ClearLine>>              <Control-Key-u>
+    <<Console_SaveCommand>>            <Control-Key-z>
+
+    <<Console_Exit>>                   <Control-Key-q>
+    <<Console_New>>                    <Control-Key-N>
+    <<Console_Close>>                  <Control-Key-w>
+    <<Console_About>>                  <Control-Key-A>
+    <<Console_Help>>                   <Control-Key-H>
+    <<Console_Find>>                   <Control-Key-F>
+} {
+    event add $ev $key
+    bind Console $key {}
+}
+catch {unset ev key}
+
+## Redefine for Console what we need
+##
+event delete <<Paste>> <Control-V>
+ConsoleClipboardKeysyms <Copy> <Cut> <Paste>
+
+bind Console <Insert> {catch {ConsoleInsert %W [selection get -displayof %W]}}
+
+bind Console <Triple-1> {+
+catch {
+    eval %W tag remove sel [%W tag nextrange prompt sel.first sel.last]
+    %W mark set insert sel.first
+}
+}
+
+bind Console <<Console_Expand>> {
+    if {[%W compare insert > limit]} {Console:expand %W}
+    break
+}
+bind Console <<Console_ExpandFile>> {
+    if {[%W compare insert > limit]} {Console:expand %W path}
+    break
+}
+bind Console <<Console_ExpandProc>> {
+    if {[%W compare insert > limit]} {Console:expand %W proc}
+    break
+}
+bind Console <<Console_ExpandVar>> {
+    if {[%W compare insert > limit]} {Console:expand %W var}
+    break
+}
+bind Console <<Console_Tab>> {
+    if {[%W compare insert >= limit]} {
+       ConsoleInsert %W \t
+    }
+}
+bind Console <<Console_Eval>> {
+    ConsoleEval %W
+}
+bind Console <Delete> {
+    if {[string compare {} [%W tag nextrange sel 1.0 end]] \
+           && [%W compare sel.first >= limit]} {
+       %W delete sel.first sel.last
+    } elseif {[%W compare insert >= limit]} {
+       %W delete insert
+       %W see insert
+    }
+}
+bind Console <BackSpace> {
+    if {[string compare {} [%W tag nextrange sel 1.0 end]] \
+           && [%W compare sel.first >= limit]} {
+       %W delete sel.first sel.last
+    } elseif {[%W compare insert != 1.0] && [%W compare insert > limit]} {
+       %W delete insert-1c
+       %W see insert
+    }
+}
+bind Console <Control-h> [bind Console <BackSpace>]
+
+bind Console <KeyPress> {
+    ConsoleInsert %W %A
+}
+
+bind Console <Control-a> {
+    if {[%W compare {limit linestart} == {insert linestart}]} {
+       tkTextSetCursor %W limit
+    } else {
+       tkTextSetCursor %W {insert linestart}
+    }
+}
+bind Console <Control-d> {
+    if {[%W compare insert < limit]} break
+    %W delete insert
+}
+bind Console <<Console_KillLine>> {
+    if {[%W compare insert < limit]} break
+    if {[%W compare insert == {insert lineend}]} {
+       %W delete insert
+    } else {
+       %W delete insert {insert lineend}
+    }
+}
+bind Console <<Console_Clear>> {
+    Console_clear [winfo parent %W]
+}
+bind Console <<Console_Previous>> {
+    if {[%W compare {insert linestart} != {limit linestart}]} {
+       tkTextSetCursor %W [tkTextUpDownLine %W -1]
+    } else {
+       Console_event [winfo parent %W] -1
+    }
+}
+bind Console <<Console_Next>> {
+    if {[%W compare {insert linestart} != {end-1c linestart}]} {
+       tkTextSetCursor %W [tkTextUpDownLine %W 1]
+    } else {
+       Console_event [winfo parent %W] 1
+    }
+}
+bind Console <<Console_NextImmediate>> {
+    Console_event [winfo parent %W] 1
+}
+bind Console <<Console_PreviousImmediate>> {
+    Console_event [winfo parent %W] -1
+}
+bind Console <<Console_PreviousSearch>> {
+    Console_event [winfo parent %W] -1 [ConsoleCmdGet %W]
+}
+bind Console <<Console_NextSearch>> {
+    Console_event [winfo parent %W] 1 [ConsoleCmdGet %W]
+}
+bind Console <<Console_Transpose>> {
+    ## Transpose current and previous chars
+    if {[%W compare insert > limit]} { tkTextTranspose %W }
+}
+bind Console <<Console_ClearLine>> {
+    ## Clear command line (Unix shell staple)
+    %W delete limit end
+}
+bind Console <<Console_SaveCommand>> {
+    ## Save command buffer (swaps with current command)
+    Console:savecommand %W
+}
+catch {bind Console <Key-Page_Up>   { tkTextScrollPages %W -1 }}
+catch {bind Console <Key-Prior>     { tkTextScrollPages %W -1 }}
+catch {bind Console <Key-Page_Down> { tkTextScrollPages %W 1 }}
+catch {bind Console <Key-Next>      { tkTextScrollPages %W 1 }}
+bind Console <$META-d> {
+    if {[%W compare insert >= limit]} {
+       %W delete insert {insert wordend}
+    }
+}
+bind Console <$META-BackSpace> {
+    if {[%W compare {insert -1c wordstart} >= limit]} {
+       %W delete {insert -1c wordstart} insert
+    }
+}
+bind Console <$META-Delete> {
+    if {[%W compare insert >= limit]} {
+       %W delete insert {insert wordend}
+    }
+}
+bind Console <ButtonRelease-2> {
+    ## Try and get the default selection, then try and get the selection
+    ## type TEXT, then try and get the clipboard if nothing else is available
+    if {
+       (!$tkPriv(mouseMoved) || $tk_strictMotif) &&
+       (![catch {selection get -displayof %W} tkPriv(junk)] ||
+       ![catch {selection get -displayof %W -type TEXT} tkPriv(junk)] ||
+       ![catch {selection get -displayof %W \
+               -selection CLIPBOARD} tkPriv(junk)])
+    } {
+       if {[%W compare @%x,%y < limit]} {
+           %W insert end $tkPriv(junk)
+       } else {
+           %W insert @%x,%y $tkPriv(junk)
+       }
+       if {[string match *\n* $tkPriv(junk)]} {ConsoleEval %W}
+    }
+}
+
+##
+## End Console bindings
+##
+
+##
+## Bindings for doing special things based on certain keys
+##
+bind PostConsole <Key-parenright> {
+    if {[string compare \\ [%W get insert-2c]]} {ConsoleMatchPair %W \( \) limit}
+}
+bind PostConsole <Key-bracketright> {
+    if {[string compare \\ [%W get insert-2c]]} {ConsoleMatchPair %W \[ \] limit}
+}
+bind PostConsole <Key-braceright> {
+    if {[string compare \\ [%W get insert-2c]]} {ConsoleMatchPair %W \{ \} limit}
+}
+bind PostConsole <Key-quotedbl> {
+    if {[string compare \\ [%W get insert-2c]]} {ConsoleMatchQuote %W limit}
+}
+
+bind PostConsole <KeyPress> {
+    if {[string compare {} %A]} { ConsoleTagProc %W }
+}
+
+
+## ConsoleTagProc - tags a procedure in the console if it's recognized
+## This procedure is not perfect.  However, making it perfect wastes
+## too much CPU time...  Also it should check the existence of a command
+## in whatever is the connected slave, not the master interpreter.
+##
+;proc ConsoleTagProc w {
+    upvar \#0 [winfo parent $w] data
+    if {!$data(-lightcmd)} return
+    set exp "\[^\\]\[ \t\n\r\[\{\"\$]"
+    set i [$w search -backwards -regexp $exp insert-1c limit-1c]
+    if {[string compare {} $i]} {append i +2c} {set i limit}
+    regsub -all {[[\\\?\*]} [$w get $i "insert-1c wordend"] {\\\0} c
+    if {[string compare {} [ConsoleEvalAttached info commands [list $c]]]} {
+       $w tag add proc $i "insert-1c wordend"
+    } else {
+       $w tag remove proc $i "insert-1c wordend"
+    }
+    if {[string compare {} [ConsoleEvalAttached info vars [list $c]]]} {
+       $w tag add var $i "insert-1c wordend"
+    } else {
+       $w tag remove var $i "insert-1c wordend"
+    }
+}
+
+## ConsoleMatchPair - blinks a matching pair of characters
+## c2 is assumed to be at the text index 'insert'.
+## This proc is really loopy and took me an hour to figure out given
+## all possible combinations with escaping except for escaped \'s.
+## It doesn't take into account possible commenting... Oh well.  If
+## anyone has something better, I'd like to see/use it.  This is really
+## only efficient for small contexts.
+# ARGS:        w       - console text widget
+#      c1      - first char of pair
+#      c2      - second char of pair
+# Calls:       Console:blink
+## 
+;proc ConsoleMatchPair {w c1 c2 {lim 1.0}} {
+    upvar \#0 [winfo parent $w] data
+    if {!$data(-lightbrace) || $data(-blinktime)<100} return
+    if {[string compare [set ix [$w search -back $c1 insert $lim]] {}]} {
+       while {[string match {\\} [$w get $ix-1c]] && \
+               [string compare [set ix [$w search -back $c1 $ix-1c $lim]] {}]} {}
+       set i1 insert-1c
+       while {[string compare $ix {}]} {
+           set i0 $ix
+           set j 0
+           while {[string compare [set i0 [$w search $c2 $i0 $i1]] {}]} {
+               append i0 +1c
+               if {[string match {\\} [$w get $i0-2c]]} continue
+               incr j
+           }
+           if {!$j} break
+           set i1 $ix
+           while {$j && [string compare \
+                   [set ix [$w search -back $c1 $ix $lim]] {}]} {
+               if {[string match {\\} [$w get $ix-1c]]} continue
+               incr j -1
+           }
+       }
+       if {[string match {} $ix]} { set ix [$w index $lim] }
+    } else { set ix [$w index $lim] }
+    if {$data(-blinkrange)} {
+       Console:blink $w $data(-blinktime) $ix [$w index insert]
+    } else {
+       Console:blink $w $data(-blinktime) $ix $ix+1c \
+               [$w index insert-1c] [$w index insert]
+    }
+}
+
+## ConsoleMatchQuote - blinks between matching quotes.
+## Blinks just the quote if it's unmatched, otherwise blinks quoted string
+## The quote to match is assumed to be at the text index 'insert'.
+# ARGS:        w       - console text widget
+# Calls:       Console:blink
+## 
+;proc ConsoleMatchQuote {w {lim 1.0}} {
+    upvar \#0 [winfo parent $w] data
+    if {!$data(-lightbrace) || $data(-blinktime)<100} return
+    set i insert-1c
+    set j 0
+    while {[string compare {} [set i [$w search -back \" $i $lim]]]} {
+       if {[string match {\\} [$w get $i-1c]]} continue
+       if {!$j} {set i0 $i}
+       incr j
+    }
+    if {[expr $j%2]} {
+       if {$data(-blinkrange)} {
+           Console:blink $w $data(-blinktime) $i0 [$w index insert]
+       } else {
+           Console:blink $w $data(-blinktime) $i0 $i0+1c \
+                   [$w index insert-1c] [$w index insert]
+       }
+    } else {
+       Console:blink $w $data(-blinktime) [$w index insert-1c] \
+               [$w index insert]
+    }
+}
+
+## Console:blink - blinks between 2 indices for a specified duration.
+# ARGS:        w       - console text widget
+#      delay   - millisecs to blink for
+#      args    - indices of regions to blink
+# Outputs:     blinks selected characters in $w
+## 
+;proc Console:blink {w delay args} {
+    eval $w tag add blink $args
+    after $delay eval $w tag remove blink $args
+    return
+}
+
+
+## ConsoleInsert
+## Insert a string into a text console at the point of the insertion cursor.
+## If there is a selection in the text, and it covers the point of the
+## insertion cursor, then delete the selection before inserting.
+# ARGS:        w       - text window in which to insert the string
+#      s       - string to insert (usually just a single char)
+# Outputs:     $s to text widget
+## 
+;proc ConsoleInsert {w s} {
+    if {[string match {} $s] || [string match disabled [$w cget -state]]} {
+       return
+    }
+    if {[$w comp insert < limit]} {
+       $w mark set insert end
+    }
+    catch {
+       if {[$w comp sel.first <= insert] && [$w comp sel.last >= insert]} {
+           $w delete sel.first sel.last
+       }
+    }
+    $w insert insert $s
+    $w see insert
+}
+
+## Console:expand - 
+# ARGS:        w       - text widget in which to expand str
+#      type    - type of expansion (path / proc / variable)
+# Calls:       ConsoleExpand(Pathname|Procname|Variable)
+# Outputs:     The string to match is expanded to the longest possible match.
+#              If data(-showmultiple) is non-zero and the user longest match
+#              equaled the string to expand, then all possible matches are
+#              output to stdout.  Triggers bell if no matches are found.
+# Returns:     number of matches found
+## 
+;proc Console:expand {w {type ""}} {
+    set exp "\[^\\]\[ \t\n\r\[\{\"\$]"
+    set tmp [$w search -backwards -regexp $exp insert-1c limit-1c]
+    if {[string compare {} $tmp]} {append tmp +2c} else {set tmp limit}
+    if {[$w compare $tmp >= insert]} return
+    set str [$w get $tmp insert]
+    switch -glob $type {
+       pa* { set res [ConsoleExpandPathname $str] }
+       pr* { set res [ConsoleExpandProcname $str] }
+       v*  { set res [ConsoleExpandVariable $str] }
+       default {
+           set res {}
+           foreach t {Pathname Procname Variable} {
+               if {[string compare {} [set res [ConsoleExpand$t $str]]]} break
+           }
+       }
+    }
+    set len [llength $res]
+    if {$len} {
+       $w delete $tmp insert
+       $w insert $tmp [lindex $res 0]
+       if {$len > 1} {
+           upvar \#0 [winfo parent $w] data
+           if {$data(-showmultiple) && \
+                   ![string compare [lindex $res 0] $str]} {
+               puts stdout [lreplace $res 0 0]
+           }
+       }
+    } else { bell }
+    return [incr len -1]
+}
+
+## ConsoleExpandPathname - expand a file pathname based on $str
+## This is based on UNIX file name conventions
+# ARGS:        str     - partial file pathname to expand
+# Calls:       ConsoleExpandBestMatch
+# Returns:     list containing longest unique match followed by all the
+#              possible further matches
+## 
+;proc ConsoleExpandPathname str {
+    set pwd [ConsoleEvalAttached pwd]
+    if {[catch {ConsoleEvalAttached [list cd [file dirname $str]]} err]} {
+       return -code error $err
+    }
+    if {[catch {lsort [ConsoleEvalAttached \
+           [list glob [file tail $str]*]]} m]} {
+       set match {}
+    } else {
+       if {[llength $m] > 1} {
+           global tcl_platform
+           if {[string match windows $tcl_platform(platform)]} {
+               ## Windows is screwy because it's case insensitive
+               set tmp [ConsoleExpandBestMatch [string tolower $m] \
+                       [string tolower [file tail $str]]]
+           } else {
+               set tmp [ConsoleExpandBestMatch $m [file tail $str]]
+           }
+           if {[string match ?*/* $str]} {
+               set tmp [file dirname $str]/$tmp
+           } elseif {[string match /* $str]} {
+               set tmp /$tmp
+           }
+           regsub -all { } $tmp {\\ } tmp
+           set match [linsert $m 0 $tmp]
+       } else {
+           ## This may look goofy, but it handles spaces in path names
+           eval append match $m
+           if {[file isdir $match]} {append match /}
+           if {[string match ?*/* $str]} {
+               set match [file dirname $str]/$match
+           } elseif {[string match /* $str]} {
+               set match /$match
+           }
+           regsub -all { } $match {\\ } match
+           ## Why is this one needed and the ones below aren't!!
+           set match [list $match]
+       }
+    }
+    ConsoleEvalAttached [list cd $pwd]
+    return $match
+}
+
+## ConsoleExpandProcname - expand a tcl proc name based on $str
+# ARGS:        str     - partial proc name to expand
+# Calls:       ConsoleExpandBestMatch
+# Returns:     list containing longest unique match followed by all the
+#              possible further matches
+## 
+;proc ConsoleExpandProcname str {
+    set match [ConsoleEvalAttached [list info commands $str*]]
+    if {[llength $match] > 1} {
+       regsub -all { } [ConsoleExpandBestMatch $match $str] {\\ } str
+       set match [linsert $match 0 $str]
+    } else {
+       regsub -all { } $match {\\ } match
+    }
+    return $match
+}
+
+## ConsoleExpandVariable - expand a tcl variable name based on $str
+# ARGS:        str     - partial tcl var name to expand
+# Calls:       ConsoleExpandBestMatch
+# Returns:     list containing longest unique match followed by all the
+#              possible further matches
+## 
+;proc ConsoleExpandVariable str {
+    if {[regexp {([^\(]*)\((.*)} $str junk ary str]} {
+       ## Looks like they're trying to expand an array.
+       set match [ConsoleEvalAttached [list array names $ary $str*]]
+       if {[llength $match] > 1} {
+           set vars $ary\([ConsoleExpandBestMatch $match $str]
+           foreach var $match {lappend vars $ary\($var\)}
+           return $vars
+       } else {set match $ary\($match\)}
+       ## Space transformation avoided for array names.
+    } else {
+       set match [ConsoleEvalAttached [list info vars $str*]]
+       if {[llength $match] > 1} {
+           regsub -all { } [ConsoleExpandBestMatch $match $str] {\\ } str
+           set match [linsert $match 0 $str]
+       } else {
+           regsub -all { } $match {\\ } match
+       }
+    }
+    return $match
+}
+
+## ConsoleExpandBestMatch2 - finds the best unique match in a list of names
+## Improves upon the speed of the below proc only when $l is small
+## or $e is {}.  $e is extra for compatibility with proc below.
+# ARGS:        l       - list to find best unique match in
+# Returns:     longest unique match in the list
+## 
+;proc ConsoleExpandBestMatch2 {l {e {}}} {
+    set s [lindex $l 0]
+    if {[llength $l]>1} {
+       set i [expr [string length $s]-1]
+       foreach l $l {
+           while {$i>=0 && [string first $s $l]} {
+               set s [string range $s 0 [incr i -1]]
+           }
+       }
+    }
+    return $s
+}
+
+## ConsoleExpandBestMatch - finds the best unique match in a list of names
+## The extra $e in this argument allows us to limit the innermost loop a
+## little further.  This improves speed as $l becomes large or $e becomes long.
+# ARGS:        l       - list to find best unique match in
+#      e       - currently best known unique match
+# Returns:     longest unique match in the list
+## 
+;proc ConsoleExpandBestMatch {l {e {}}} {
+    set ec [lindex $l 0]
+    if {[llength $l]>1} {
+       set e  [string length $e]; incr e -1
+       set ei [string length $ec]; incr ei -1
+       foreach l $l {
+           while {$ei>=$e && [string first $ec $l]} {
+               set ec [string range $ec 0 [incr ei -1]]
+           }
+       }
+    }
+    return $ec
+}
+
+
+## ConsoleResource - re'source's this script into current console
+## Meant primarily for my development of this program.  It follows
+## links until the ultimate source is found.
+## 
+set Console(SCRIPT) [info script]
+if {!$Console(WWW)} {
+    while {[string match link [file type $Console(SCRIPT)]]} {
+       set link [file readlink $Console(SCRIPT)]
+       if {[string match relative [file pathtype $link]]} {
+           set Console(SCRIPT) [file join \
+                   [file dirname $Console(SCRIPT)] $link]
+       } else {
+           set Console(SCRIPT) $link
+       }
+    }
+    catch {unset link}
+    if {[string match relative [file pathtype $Console(SCRIPT)]]} {
+       set Console(SCRIPT) [file join [pwd] $Console(SCRIPT)]
+    }
+}
+
+;proc Console:resource {} {
+    global Console
+    uplevel \#0 [list source $Console(SCRIPT)]
+}
diff --git a/tcl/draw.tcl b/tcl/draw.tcl
new file mode 100644 (file)
index 0000000..db49749
--- /dev/null
@@ -0,0 +1,14 @@
+package require Fgis
+set layer [layer create raster -file lesras.epp -title "ðÏÄÚÏÎÁ"\
+   -legfile lesras.leg]
+option add *font -cronyx-times-bold-r-normal--10-*
+label .status
+planchet .test -width 640 -height 480 -status .status
+toolbar .tool .test
+pack .tool -expand y -fill x
+pack .test
+pack .status
+.test show $layer
+.test look add $layer
+bind .test <Button-2> {destroy .test}
+wm protocol . WM_DELETE_WINDOW exit
diff --git a/tcl/getopt.tcl b/tcl/getopt.tcl
new file mode 100644 (file)
index 0000000..bb54857
--- /dev/null
@@ -0,0 +1,206 @@
+#
+# getopt.tcl
+# 
+# Option parsing library for Tcl scripts
+# Copyright (C) SoftWeyr, 1997
+# Author V. Wagner <vitus@agropc.msk.su
+#
+# Distributed under GNU public license. (i.e. compiling into standalone
+# executables or encrypting is prohibited, unless source is provided to users)
+#
+
+#  
+# getopt - recieves an array of possible options with default values
+# and list of options with values, and modifies array according to supplied
+# values
+# ARGUMENTS: arrname - array in calling procedure, whose indices is names of
+# options WITHOUT leading dash and values are default values.
+# if element named "default" exists in array, all unrecognized options
+# would concatenated there in same form, as they was in args
+# args - argument list - can be passed either as one list argument or 
+# sepatate arguments 
+# RETURN VALUE: none
+# SIDE EFFECTS: modifies passed array 
+#
+proc getopt {arrname args} {
+upvar $arrname opt
+if ![array exist opt] {
+  return -code error "Array $arrname doesn't exist"
+}
+if {[llength $args]==1} {eval set args $args}
+if {![llength $args]} return
+if {[llength $args]%2!=0} {error "Odd count of opt. arguments"}
+foreach {option value} $args {
+   if [string match -* $option] {
+   set list [array names opt [string trimleft $option -]*]
+   } else { set list {}}
+   switch -exact [llength $list] {
+       0 { if [info exists opt(default)] {
+             lappend opt(default) $option $value
+          } else {
+              set msg "unknown option $option. Should be one of:"
+              foreach j [array names opt] {append msg " -" $j}
+              return -code error $msg
+          }
+       }
+       1 { set opt($list) $value 
+       }
+       default { 
+         if [set j [lsearch -exact $list [string trimleft $option -]]]!=-1 {
+            set opt([lindex $list $j]) $value
+        } else { 
+            set msg "Ambiguous option $option:"
+            foreach j $list {append msg " -" $j}
+            return -code error $msg
+        }
+       }
+   }
+}
+   return
+}
+
+#  
+# handleopt - recieves an array of possible options and executes given scritp
+# for each of valid option passed , appending opion value to it
+# ARGUMENTS: arrname - array in calling procedure, whose indices is names of
+# options WITHOUT leading dash and values are corresponding scripts 
+# args - argument list - can be passed either as one list argument or 
+# sepatate arguments 
+# if element "default" appears in array, script contained there would
+# be executed for each unrecognized option with option itself and then
+# its value appended
+# RETURN VALUE: return value of last script executed
+# SIDE EFFECTS: execiting of one or more passed scripts 
+# NOTES: if you want simply return value of option, return is good candidate for
+#        script. {return -return} would terminate caller 
+#
+proc handleopt {arrname args} {
+upvar $arrname opt
+if ![array exist opt] {
+  return -code error "Array $arrname doesn't exist"
+}
+if {[llength $args]==1} {eval set args $args}
+if {![llength $args]} return
+if {[llength $args]%2!=0} {error "Odd count of opt. arguments"}
+set result {}
+foreach {option value} $args {
+    if [string match -* $option] {
+       set list [array names opt [string trimleft $option -]*]
+    } else {set list {}}
+    switch -exact [llength $list] {
+       0 { if [info exist opt(default)] {
+            set cmd "$opt(default) [list $option $value]"
+          } else {
+             set msg "unknown option $option. Should be one of:"
+            foreach j [array names opt] {append msg " -" $j}
+            return -code error $msg
+          }
+       }
+       1 { set cmd "$opt($list) [list $value]"}
+       default { 
+           if [set j [lsearch -exact $list [string trimleft $option -]]]!=-1 {
+               set cmd [linsert $opt([lindex $list $j]) end $value]
+           } else { 
+              set msg "Ambiguous option $option:"
+              foreach j $list {append msg " -" $j}
+              return -code error $msg
+           }
+       }
+    }
+    if [catch {uplevel $cmd} result ] {
+        global errorInfo
+        puts $errorInfo
+       return -code error $result
+    }
+}
+return $result
+} 
+# 
+# checks variable for valid boolean value
+# and replaces it with 1, if true or 0 it false. If value is not
+# correct, message is stored in msg and 1 returned. Otherwise 0 is returned
+#
+
+proc checkbooleanopt {var msg} {
+upvar $var test
+set t [string tolower $test]
+set r 0
+if [string length $t] {
+    foreach truth {1 yes on true} {
+      if [string match $t* $truth] {
+       set r 1
+       break
+      }
+    }
+    foreach lie {0 no off false} {
+      if [string match $t* $lie] {
+        if $r {
+          uplevel set $msg [list "Ambiquous boolean value \"$test\""]
+          return 1
+        } else {
+          set test 0
+          return 0
+        }
+      }
+   }    
+}
+if $r {
+  set test 1
+  return 0
+} else {
+  uplevel set $msg [list "Expected boolean value, but got \"$test\""]
+  return 1
+}      
+}
+#
+# checks variable value for matching one (and only one) of given list element
+# and replaces its value with literal value of this element
+# Returns 0 if value is correct, 1 if it is bad. Sets msg to verbose error message
+#
+
+proc checklistopt {var list msg} {
+upvar $var test
+upvar $msg err
+foreach i $list { 
+   set tmp($i) 1
+}
+# Ok, there is literal match
+if [info exists tmp($test)] {return 0}
+# Trying to do glob match
+set num [llength [set found [array names tmp $test*]]]
+if {$num==1} {
+  set test [lindex $found 0]
+  return 0
+} elseif {!$num} {
+  set err "Unknown option $test. Should be one of [join $list ", "]"
+  return 1
+} else {
+  set err "Ambiquous option $test.\n [join $found ", "]"
+  return 1
+}
+}
+# Checks variable value for being integer and (optionally) fall into given range
+# You can use empty string, if you don't want to check for min or max
+# 
+# Returns 0 if no error, 1 if something wrong. Sets msg to verbose error message
+#
+proc checkintopt {var min max msg} {
+upvar $var test
+upvar $msg err
+if ![string length $min] {set min -0x7fffffff}
+if ![string length $max] {set max 0x7fffffff}
+set test [string trim $test]
+if ![regexp {^[+-]?(0[xX][0-9A-Fa-f]+|[1-9][0-9]*|0[0-7]*)$} $test] {
+   set err "Expected integer, but got \"$test\""
+   return 1
+}
+if {$test<$min} {
+  set err  "Expected integer greater than $min, but got $test"
+  return 1
+}
+if {$test>$max} {
+  set err "Expected integer less than $max, but got $test"
+}
+return 0
+}
+package provide getopt 1.1
diff --git a/tcl/help.tcl b/tcl/help.tcl
new file mode 100644 (file)
index 0000000..404205d
--- /dev/null
@@ -0,0 +1,405 @@
+##
+## help.tcl
+## minimal generic help system implemented as a mega-widget
+##
+## Jeffrey Hobbs
+## Initiated: 28 October 1996
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     help_dialog
+##
+## DESCRIPTION
+##     Implements a minimal generic help system dialog
+##
+## ARGUMENTS
+##     help_dialog <window pathname> <options>
+##
+## OPTIONS
+##     (Any help widget option may be used in addition to these)
+##
+## RETURNS: the toplevel window pathname
+##
+## BINDINGS (in addition to default widget bindings)
+##
+## -dismisstext str                    DEFAULT: Dismiss
+##     The text for the dismiss button (hides the Help dialog).  If
+##     text=={}, the button is not shown.
+##
+## METHODS
+##     These are the methods that an instance of this megawidget recognizes.
+## Aside from those listed here, it accepts methods that are valid for text
+## widgets.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are label, dismiss.
+##
+## hide
+##     Hides the help dialog
+##
+## show
+##     Deiconifies the help dialog
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     The procedure help and those beginning with Help are
+## used.  Also, when a widget is created, commands named .$widgetname
+## and HelpDialog$widgetname are created.
+##
+## EXAMPLE USAGE:
+if 0 {
+    helpdialog .h -label "Tiger Help" -title "Tiger Help" -buttons {
+       {Index    index}
+       {Contents http://www.acm.org/}
+    }
+    .h link index http://www.altavista.digital.com/
+    .h show
+}
+##------------------------------------------------------------------------
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     help
+##
+## DESCRIPTION
+##     Implements a minimal generic help system
+##
+## ARGUMENTS
+##     help <window pathname> <options>
+##
+## OPTIONS
+##     (Any frame option may be used in addition to these)
+##
+## RETURNS: the toplevel window pathname
+##
+## BINDINGS (in addition to default widget bindings)
+##
+## -binding event                      DEFAULT: {}
+##     A binding for using the help in a context-sensitive manner.  If
+##     binding is specified, the help dialog will make a bind that event
+##     to all and call the load method with the widget it is over when it
+##     is triggered.  Thus you need to register the widget name as a tag
+##     for it to be recognized in context sensitive help.
+##
+## -buttons buttonlist                 DEFAULT: {}
+##     A list of tuples that define the buttons to display.  Each tuple
+##     must be of the form {"Button Name" tagOrURL}.  For each tuple in
+##     the list, a button is created in the help dialog with the specified
+##     name and its command is set to load the specified tagOrURL.
+##
+## -executable execlist
+## DEFAULT: {{exec netscape -remote "openURL(%s)"} {exec netscape "%s" &}}
+##     A list of lists which represent what commands to evaluate in order
+##     to view the URL.  In the string, %s is replaced with the URL to be
+##     loaded.  %s may not start the string.
+##
+## -inherit TCL_BOOLEAN                        DEFAULT: 1
+##     In combination with a binding specification, tells whether the help
+##     widget should iteratively look for a link associated with a parent
+##     widget when one is not found for the current widget.
+##
+## -label str                          DEFAULT: {}
+##     The text for a label at the top of the dialog.  If text=={}, the
+##     label is not shown.
+##
+## -subst TCL_BOOLEAN                  DEFAULT: 1
+##     Performs a subst on the tagOrURL, allowing you to do delayed
+##     evaluation on the tagOrURL contents.
+##
+## METHODS
+##     These are the methods that an instance of this megawidget recognizes.
+## Aside from those listed here, it accepts methods that are valid for text
+## widgets.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are label.
+##
+## gettag tagOrWidget
+##     Returns an absolute tag reference for a particular tag (following
+##     all links and doing all substs) or {} if no tag exists.
+##
+## link tagOrWidget ?tagOrURL?
+##     Creates a tag for an URL to allow you to easily reference the URL
+##     where URLs are required in other methods for this dialog.
+##     If a widget pathname is specified as the tagOrWidget, then that
+##     will become a tag that will load the specified URL when the help
+##     binding is activated (if -binding is specified) which uses load.
+##     If tagOrURL=={}, the tagOrWidget id is removed.
+##     If it is not specified, the tagOrWidget link is returned.
+##     A subst will be done on the tagOrURL at load time, so be careful
+##     to escape special characters if you don't want them interpreted.
+##     No subst will be done during the link operation though.
+##
+## load tagOrURL
+##     Launches the HTML viewer with the specified tagOrURL.  A gettag
+##     call is done of the tagOrURL link.
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     The procedure help and those beginning with Help are
+## used.  Also, when a widget is created, commands named .$widgetname
+## and Help$widgetname are created.
+##
+## EXAMPLE USAGE:
+if 0 {
+    help .h -label "Tiger Help" -buttons {
+       {Index    index}
+       {Contents http://www.acm.org/}
+    }
+    .h link index http://www.altavista.digital.com/
+    pack .h -fill both -exp 1
+}
+##------------------------------------------------------------------------
+
+#package require Tk
+#package require Megawidget 1.0
+#package require Bookmarks 1.0
+#package require WWW 1.0
+
+#package provide Help 1.0
+
+array set Help {
+    type       frame
+    base       frame
+
+    -executable        {executable     Executable      \
+           {{exec netscape -remote "openURL(%s)"} {exec netscape "%s" &}}}
+    -label     {label          Label           {}}
+    -binding   {binding        Binding         {}}
+    -buttons   {buttons        Buttons         {}}
+    -inherit   {inherit        Inherit         1}
+    -subst     {subst          Subst           1}
+}
+
+if {[string match windows $tcl_platform(platform)]} {
+    set Help(-executable) {executable Executable {{exec netscape "%s" &}}}
+}
+
+if {[info exists env(NETSCAPE_PATH)]} {
+    regsub -all netscape $Help(-executable) \
+           $env(NETSCAPE_PATH) \
+           Help(-executable)
+} elseif {[string match windows $tcl_platform(platform)]} {
+    regsub -all netscape $Help(-executable) \
+           {"c:/program files/netscape/navigator/program/netscape.exe"} \
+           Help(-executable)
+}
+
+array set HelpDialog {
+    type               toplevel
+    base               help
+    components         {{button dismiss} {frame separator}}
+
+    -dismisstext       {dismisstext    DismissText     Dismiss}
+    -title             {title          Title           "Help"}
+}
+## For the indexer to pick up
+proc Help args {}
+proc help args {}
+proc HelpDialog args {}
+proc helpdialog args {}
+proc help_dialog args {}
+widget create Help
+widget create HelpDialog
+interp alias {} help_dialog {} HelpDialog
+
+;proc HelpDialog:construct {w} {
+    upvar \#0 $w data
+    global $w
+    wm title $w $data(-title)
+
+    $data(separator) configure -height 2 -relief ridge -bd 2
+    $data(dismiss) configure -textvariable ${w}(-dismisstext) \
+           -command [list $w hide]
+
+    grid $data(help) -in $w -sticky news
+    grid $data(separator) -in $w -sticky ew
+    grid $data(dismiss) -padx 4 -pady 2 -sticky ew
+    grid columnconfig $w 0 -weight 1
+    grid rowconfig $w 0 -weight 1
+}
+
+;proc HelpDialog:configure {w args} {
+    upvar \#0 $w data
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+           -title      { wm title $w $val }
+       }
+       set data($key) $val
+    }
+}
+
+;proc HelpDialog_hide w { if {[winfo exists $w]} {wm withdraw $w} }
+
+;proc HelpDialog_show w { if {[winfo exists $w]} {wm deiconify $w} }
+
+;proc Help:construct {w} {
+    upvar \#0 $w data
+
+    ## Private variables
+    array set data [list \
+           buttonframe $w.bf \
+           hierframe   $w.hf \
+           labelframe  $w.lf \
+           label       $w.lf.lbl \
+           hierarchy   $w.hf.h \
+           ]
+
+    ## Label Frame
+    frame $data(labelframe)
+    pack [label $data(label) -textvar $w\(-label\)]
+    pack [frame $data(labelframe).sep -height 2 -relief ridge -bd 2] -fill x
+    if {[string comp {} $data(-label)]} { pack $data(labelframe) -fill x }
+
+    ## Button Frame
+    pack [frame $data(buttonframe)] -fill x
+    Help:buttons $w $data(buttonframe) $data(-buttons)
+
+    ## Hierarchy (Bookmark) Frame
+    pack [frame $data(hierframe)] -fill both -exp 1
+}
+
+;proc Help_subwidget {w widget} {
+    upvar \#0 $w data
+    switch -- $widget {
+       base - container - label - hierarchy { return $data($widget) }
+       default { return -code error "No $data(class) subwidget \"$widget\"" }
+    }
+}
+
+;proc Help:configure {w args} {
+    upvar \#0 $w data
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+           -binding    {
+               if {[string comp {} $data($key)]} { bind all $data($key) {} }
+               if {[string comp {} $val]} {
+                   bind all $val "Help_load $w \[winfo contain %X %Y\] 0"
+               }
+               set data($key) $val
+           }
+           -buttons    {
+               set data($key) $val
+               Help:buttons $w $data(buttonframe) $val
+           }
+           -executable { set data($key) $val }
+           -inherit    { set data($key) [regexp -nocase $truth $val] }
+           -label      {
+               set data($key) $val
+               if {[string comp {} $val]} {
+                   pack $data(labelframe) -fill x -before $data(buttonframe)
+               } else {
+                   pack forget $data(labelframe)
+               }
+           }
+       }
+    }
+}
+
+;proc Help:destroy w {
+    upvar \#0 $w data
+    if {[string comp {} $data(-binding)]} { bind all $data(-binding) {} }  
+}
+
+;proc Help:buttons {w f btns} {
+    catch {eval destroy [winfo children $f]}
+    set i 0
+    foreach btn $btns {
+       foreach {b tag list} $btn break
+       button $f.[incr i] -text $b -command "Help_load $w $tag"
+       if {[regexp -nocase {^(1|yes|true|on)$} $list]} {
+           ## tagOrURL represents bookmark page for hierarchy list
+       }
+       pack $f.$i -fill x -side left
+    }
+}
+
+;proc Help_link {w tag {url NULL}} {
+    upvar \#0 $w data
+    if {[string comp NULL $url]} {
+       set i 100
+       while {[info exists data(@$url)] && $i<100} {
+           set url $data(@$url)
+           incr i
+       }
+       set data(@$tag) $url
+    } elseif {[string match {} $url]} {
+       catch {unset data(@$tag)}
+       return
+    }
+    if {[info exists data(@$tag)]} {
+       return $data(@$tag)
+    } else {
+       return -code error "no help link \"$tag\" defined"
+    }
+}
+
+;proc Help_gettag {w tag} {
+    upvar \#0 $w data
+    set found 0
+    while {[info exists data(@$tag)] && $found<100} {
+       incr found
+       if {$data(-subst)} {
+           set tag [uplevel \#0 [list subst $data(@$tag)]]
+       } else {
+           set tag $data(@$tag)
+       }
+    }
+    if {$found} {
+       return $tag
+    } elseif {$data(-inherit) && [winfo exists $tag]} {
+       while {![info exists data(@$tag)] && [string comp . $tag]} {
+           set tag [winfo parent $tag]
+       }
+       if {[info exists data(@$tag)]} { return $data(@$tag) }
+    }
+    return
+}
+
+;proc Help_load {w url {complain 1}} {
+    upvar \#0 $w data
+    set link [Help_gettag $w $url]
+    if {[string comp {} $link]} {
+       Help:load $w $link
+    } elseif {[string match http:/* $url] || [string match file:/* $url]} {
+       Help:load $w $url
+    } elseif {$complain} {
+       return -code error "\"$url\" not recognized as proper URL or help link"
+    }
+}
+
+;proc Help:load {w url} {
+    upvar \#0 $w data
+    regsub -all {([^\\])%s} $data(-executable) "\\1$url" cmds
+    set failed 1
+    foreach cmd $cmds {
+       if {![catch $cmd]} {
+           set failed 0
+           break
+       }
+    }
+    if {$failed} {
+       tk_dialog $w.dialog "Failed to load URL." \
+               "Failed to load URL via any of the commands:\n$cmds\
+               \nMake sure the command exists and is in your path." \
+               warning 0 OK
+    }
+}
+
diff --git a/tcl/hierarchy.tcl b/tcl/hierarchy.tcl
new file mode 100644 (file)
index 0000000..375b9bc
--- /dev/null
@@ -0,0 +1,1253 @@
+##
+## hierarchy.tcl
+## Hierarchical Display Widget
+##
+## Layout routines taken from oooold code, author unkown.
+## Copyright 1995-1997 Jeffrey Hobbs
+##
+## jhobbs@cs.uoregon.edu, http://www.cs.uoregon.edu/~jhobbs/
+##
+## source standard_disclaimer.tcl
+## source beer_ware.tcl
+##
+## Last Update: 28 June 1997
+
+##-----------------------------------------------------------------------
+## PROCEDURE(S)
+##     hierarchy, hierarchy_dir, hierarchy_widget
+##
+## ARGUMENTS && DESCRIPTION
+##
+## hierarchy <window pathname> <options>
+##     Implements a hierarchical listbox
+## hierarchy_dir <window pathname> <options>
+##     Implements a hierarchical listbox using a directory view structure
+##     for the default methods
+## hierarchy_widget <window pathname> <options>
+##     Implements a hierarchical listbox using a widget view structure
+##     for the default methods
+##
+## OPTIONS
+##     (Any canvas option may be used with a hierarchy)
+##
+## -autoscrollbar TCL_BOOLEAN                  DEFAULT: 1
+##     Determines whether scrollbars automagically pop-up or
+##     are permanently there.
+##
+## -browsecmd procedure                                DEFAULT: noop
+##     A command which the widget will execute when the node is expanded
+##     to retrieve the children of a node.  The widget and node path are
+##     appended to the command as a list of node names which
+##     form a path to the node from the root.  Thus the first
+##     element of this list will always be the root node.
+##
+## -command procedure                          DEFAULT: noop
+##     A command which the widget will execute when the node is toggled.
+##     The name of the widget, the node path, and whether the children of
+##     the node are showing (0/1) is appended to the procedure args.
+##
+## -common TCL_BOOLEAN                         DEFAULT: 0
+##     If this is true, when a node gets added to the selection,
+##     all other nodes with the same *name* (regardless of
+##     the path to the node) get selected as well.  The selection
+##     is reported only as a set of node names, not a set of node 
+##     paths.  Thus selection acts like an equivalence over nodes
+##     of the same name.  Useful only in hierarchies where some
+##     nodes in the hierarchy really refer to the same logical object.
+##     NOTE: FEATURE NOT YET IMPLEMENTED
+##
+## -decoration TCL_BOOLEAN                     DEFAULT: 1
+##     If this is true, the "tree" lines are drawn.
+##
+## -expand #                                   DEFAULT: 1
+##     an integer value for an initial depth to expand to.
+##
+## -font fontname                              DEFAULT: fixed
+##     The default font used for the text.
+##
+## -foreground color                           DEFAULT: black
+##     The default foreground color used for text of unselected nodes.
+##
+## -ipad #                                     DEFAULT: 3
+##     The internal space added between the image and the text for a
+##     given node.
+##
+## -nodelook procedure                         DEFAULT: noop
+##     A command the widget will execute to get the look of a node.
+##     The node is appended to the command as a list of
+##     node-names which form a path to the node from the root.
+##     Thus the first element of this list will always be the
+##     root node.  Also appended is a 
+##     boolean value which indicates whether the node's children
+##     are currently displayed.  This allows the node's
+##     look to change if it is "opened" or "closed".
+##
+##     This command must return a 4-tuple list containing:
+##             0. the text to display at the node
+##             1. the font to use for the text
+##             2. an image to display
+##             3. the foreground color to use for the node
+##     If no font (ie. {}) is specified then
+##     the value from -font is used.  If no image is specified
+##     then no image is displayed.
+##     The default is a command to which produces a nice look
+##     for a file manager.  
+##
+## -paddepth #                                 DEFAULT: 12
+##     The indent space added for child branches.
+##
+## -padstack #                                 DEFAULT: 2
+##     The space added between two rows
+##
+## -root rootname                              DEFAULT: {}
+##     The name of the root node of the tree.  Each node
+##     name must be unique amongst the children of each node.
+##
+## -selectbackground color                     DEFAULT: red
+##     The default background color used for the text of selected nodes.
+##
+## -selectmode (single|browse|multiple)                DEFAULT: browse
+##     Like listbox modes, "multiple" is a mix of multiple && extended.
+##
+## -showall TCL_BOOLEAN                                DEFAULT: 0
+##     For directory nodelook, also show Unix '.' (hidden) files/dirs.
+##
+## -showfiles TCL_BOOLEAN                      DEFAULT: 0
+##     Show files as well as directories.
+##
+## -showparent string                          DEFAULT: {}
+##     For hierarchy_dir nodelook, if string != {}, then it will show that
+##     string which will reset the root node to its parent.
+##
+## RETURNS: The window pathname
+##
+## METHODS
+##     These are the methods that the hierachical listbox object recognizes.
+##     (ie - hierachy .h ; .h <method> <args>)
+##     Any unique substring is acceptable
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## close index
+##     Closes the specified index (will trigger -command).
+##
+## curselection
+##     Returns the indices of the selected items.  This differs from the
+##     listbox method because indices here have no implied order.
+##
+## get index ?index ...?
+##     Returns the node paths of the items referenced.  Ranges are not
+##     allowed.  Index specification is like that allowed by the index
+##     method.
+##
+## qget index ?index ...?
+##     As above, but the indices must be that of the item (as returned
+##     by the index or curselection method).
+##
+## index index
+##     Returns the hierarchy numerical index of the item (the numerical
+##     index has no implied order relative to the list items).  index
+##     may be of the form:
+##
+##     number - Specifies the element as a numerical index.
+##     root   - specifies the root item.
+##     string - Specifis an item that has that text in it's node.
+##     @x,y   - Indicates the element that covers the point in
+##             the listbox window specified by x and y (in pixel
+##             coordinates).  If no element covers that point,
+##             then the closest element to that point is used.
+##
+## open index
+##     Opens the specified index (will trigger -command).
+##
+## see index
+##     Ensures that the item specified by the index is viewable.
+##
+## selection option arg
+##     This works like the listbox selection method with the following
+##     exceptions:
+##
+##     The selection clear option can take multiple indices, but not a range.
+##     No arguments to clear means clear all the selected elements.
+##
+##     The selection set option can take multiple indices, but not a range.
+##     The key word 'all' sets the selection for all elements.
+##
+## size
+##     Returns the number of items in the hierarchical listbox.
+##
+## toggle index
+##     Toggles (open or closed) the item specified by index
+##     (triggers -command).
+##
+## BINDINGS
+##     Most Button-1 bindings on the hierarchy work in the same manner
+##     as those for the listbox widget, as defined by the selectmode.
+##     Those that vary are listed below:
+##
+## <Double-Button-1>
+##     Toggles a node in the hierarchy
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     The procedure hierarchy and those beginning with Hierarchy are
+## used.  Also, when a widget is created, commands named .$widgetname
+## and Hierarchy$widgetname are created.
+##
+## Cryptic source code arguments explained:
+## np   == node path
+## cnp  == changed np
+## knp  == kids np
+## xcnp == extra cnp
+##-----------------------------------------------------------------------
+
+package require Widget 1.0
+package provide Hierarchy 1.11
+
+## Create the Hiearchy megawidget class definition
+##
+## In general, we cannot use $data(basecmd) in the construction, but the
+## scrollbar commands won't be called until after it really exists as a
+## proper command
+array set Hierarchy {
+    type               frame
+    base               {canvas canvas canvas {-relief sunken -bd 1 \
+           -highlightthickness 1 \
+           -yscrollcommand [list $data(yscrollbar) set] \
+           -xscrollcommand [list $data(xscrollbar) set]}}
+    components         {
+       {scrollbar xscrollbar sx {-orient h -bd 1 -highlightthickness 1\
+               -command [list $data(basecmd) xview]}}
+       {scrollbar yscrollbar sy {-orient v -bd 1 -highlightthickness 1\
+               -command [list $data(basecmd) yview]}}
+    }
+
+    -autoscrollbar     {autoScrollbar  AutoScrollbar   1}
+    -browsecmd         {browseCmd      BrowseCmd       {}}
+    -command           {command        Command         {}}
+    -decoration                {decoration     Decoration      1}
+    -expand            {expand         Expand          1}
+    -font              {font           Font            fixed}
+    -foreground                {foreground     Foreground      black}
+    -ipad              {ipad           Ipad            3}
+    -nodelook          {nodeLook       NodeLook        {}}
+    -paddepth          {padDepth       PadDepth        12}
+    -padstack          {padStack       PadStack        2}
+    -root              {root           Root            {}}
+    -selectmode                {selectMode     SelectMode      browse}
+    -selectbackground  {selectBackground SelectBackground red}
+    -state             {state          State           normal}
+
+    -showall           {showAll        ShowAll         0}
+    -showparent                {showParent     ShowParent      {}}
+    -showfiles         {showFiles      ShowFiles       0}
+}
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc Hierarchy args {}
+proc hierarchy args {}
+widget create Hierarchy
+
+proc hierarchy_dir {w args} {
+    uplevel hierarchy $w -root [list [pwd]] \
+           -nodelook   Hierarchy:FileLook \
+           -command    Hierarchy:FileActivate \
+           -browsecmd  Hierarchy:FileList \
+           $args
+}
+
+proc hierarchy_widget {w args} {
+    uplevel hierarchy $w -root . \
+           -nodelook   Hierarchy:WidgetLook \
+           -command    Hierarchy:WidgetActivate \
+           -browsecmd  Hierarchy:WidgetList \
+           $args
+}
+
+;proc Hierarchy:construct { w } {
+    upvar \#0 $w data
+
+    ## Private variables
+    array set data [list \
+           hasnodelook 0 \
+           halfpstk    [expr $data(-padstack)/2] \
+           width       400 \
+           ]
+
+    grid $data(canvas) $data(yscrollbar) -sticky news
+    grid $data(xscrollbar) -sticky ew
+    grid columnconfig $w 0 -weight 1
+    grid rowconfig $w 0 -weight 1
+    bind $data(canvas) <Configure> [list Hierarchy:Resize $w %w %h]
+}
+
+;proc Hierarchy:init { w } {
+    upvar \#0 $w data
+
+    set data(:$data(-root),showkids) 0
+    Hierarchy:ExpandNodeN $w $data(-root) $data(-expand)
+    if {[catch {$w see $data(-root)}]} {
+       $data(basecmd) configure -scrollregion "0 0 1 1"
+    }
+}
+
+;proc Hierarchy:configure {w args} {
+    upvar \#0 $w data
+
+    set truth {^(1|yes|true|on)$}
+    set resize 0
+    foreach {key val} $args {
+       switch -- $key {
+           -autoscrollbar {
+               set val [regexp -nocase $truth $val]
+               if {$val} {
+                   set resize 1
+               } else {
+                   grid $data(xscrollbar)
+                   grid $data(yscrollbar)
+               }
+           }
+           -decoration { set val [regexp -nocase $truth $val] }
+           -padstack   { set data(halfpstk) [expr $val/2] }
+           -nodelook   {
+               ## We set this special bool val because it saves some
+               ## computation in ExpandNode, a deeply nested proc
+               set data(hasnodelook) [string compare $val {}]
+           }
+           -root               {
+               if {[info exists data(:$data(-root),showkids)]} {
+                   ## All data about items and selection should be
+                   ## cleared and the items deleted
+                   foreach name [concat [array names data :*] \
+                           [array names data S,*]] {unset data($name)}
+                   $data(basecmd) delete all
+                   set data(-root) $val
+                   set data(:$val,showkids) 0
+                   Hierarchy:ExpandNodeN $w $val $data(-expand)
+                   ## We can reset resize because ExpandNodeN forces it
+                   set resize 0
+                   continue
+               }
+           }
+           -selectbackground {
+               foreach i [array names data S,*] {
+                   $data(basecmd) itemconfigure [string range $i 2 end] \
+                           -fill $val
+               }
+           }
+           -state      {
+               if {![regexp {^(normal|disabled)$} $val junk val]} {
+                   return -code error "bad state value \"$val\":\
+                           must be normal or disabled"
+               }
+           }
+           -showall    -
+           -showfiles  {
+               set val [regexp -nocase $truth $val]
+               if {$val == $data($key)} continue
+               if {[info exists data(:$data(-root),showkids)]} {
+                   foreach i [array names data :*,kids] { unset data($i) }
+                   foreach i [array names data :*,showkids] {
+                       ## FIX - this doesn't really work dynamically
+                       if {$data($i)} {
+                           ## probably requires a call to Hierarchy:Redraw
+                       }
+                   }
+               }
+           }
+       }
+       set data($key) $val
+    }
+    if {$resize} {
+       Hierarchy:Resize $w [winfo width $data(canvas)] \
+               [winfo height $data(canvas)]
+    }
+}
+
+;proc Hierarchy_index { w idx } {
+    upvar \#0 $w data
+    set c $data(basecmd)
+    if {[string match all $idx]} {
+       return [$c find withtag box]
+    } elseif {[regexp {^(root|anchor)$} $idx]} {
+       return [$c find withtag box:$data(-root)]
+    }
+    foreach i [$c find withtag $idx] {
+       if {[string match rec* [$c type $i]]} { return $i }
+    }
+    if {[regexp {@(-?[0-9]+),(-?[0-9]+)} $idx z x y]} {
+       return [$c find closest [$w canvasx $x] [$w canvasy $y] 1 text]
+    }
+    foreach i [$c find withtag box:[lindex $idx 0]] { return $i }
+    return -code error "bad hierarchy index \"$idx\":\
+           must be current, @x,y, a number, or a node name"
+}
+
+;proc Hierarchy_selection { w args } {
+    if {[string match {} $args]} {
+       return -code error \
+               "wrong \# args: should be \"$w selection option args\""
+    }
+    upvar \#0 $w data
+    set err [catch {Hierarchy_index $w [lindex $args 1]} idx]
+    switch -glob -- [lindex $args 0] {
+       an* {
+           ## anchor
+           ## stubbed out - too complicated to support
+       }
+       cl* {
+           ## clear
+           set c $data(basecmd)
+           if {$err} {
+               foreach arg [array names data S,*] { unset data($arg) }
+               $c itemconfig box -fill {}
+           } else {
+               catch {unset data(S,$idx)}
+               $c itemconfig $idx -fill {}
+               foreach idx [lrange $args 2 end] {
+                   if {[catch {Hierarchy_index $w $idx} idx]} {
+                       catch {unset data(S,$idx)}
+                       $c itemconfig $idx -fill {}
+                   }
+               }
+           }
+       }
+       in* {
+           ## includes
+           if {$err} {
+               if {[llength $args]==2} {
+                   return -code error $idx
+               } else {
+                   return -code error "wrong \# args:\
+                           should be \"$w selection includes index\""
+               }
+           }
+           return [info exists data(S,$idx)]
+       }
+       se* {
+           ## set
+           if {$err} {
+               if {[string compare {} $args]} return
+               return -code error "wrong \# args:\
+                       should be \"$w selection set index ?index ...?\""
+           } else {
+               set c $data(basecmd); set col $data(-selectbackground)
+               if {[string match all [lindex $args 1]]} {
+                   foreach i $idx { set data(S,$i) 1 }
+                   $c itemconfig box -fill $col
+               } else {
+                   set data(S,$idx) 1
+                   $c itemconfig $idx -fill $col
+                   foreach idx [lrange $args 2 end] {
+                       if {![catch {Hierarchy_index $w $idx} idx]} {
+                           set data(S,$idx) 1
+                           $c itemconfig $idx -fill $col
+                       }
+                   }
+               }
+           }
+       }
+       default {
+           return -code error "bad selection option \"[lindex $args 0]\":\
+                   must be clear, includes, set"
+       }
+    }
+}
+
+;proc Hierarchy_curselection {w} {
+    upvar \#0 $w data
+
+    set res {}
+    foreach i [array names data S,*] { lappend res [string range $i 2 end] }
+    return $res
+}
+
+;proc Hierarchy_get {w args} {
+    upvar \#0 $w data
+
+    set nps {}
+    foreach arg $args {
+       if {![catch {Hierarchy_index $w $arg} idx] && \
+               [string compare {} $idx]} {
+           set tags [$data(basecmd) gettags $idx]
+           if {[set i [lsearch -glob $tags box:*]]>-1} {
+               lappend nps [string range [lindex $tags $i] 4 end]
+           }
+       }
+    }
+    return $nps
+}
+
+;proc Hierarchy_qget {w args} {
+    upvar \#0 $w data
+
+    ## Quick get.  Avoids expensive Hierarchy_index call
+    set nps {}
+    foreach arg $args {
+       set tags [$data(basecmd) itemcget $arg -tags]
+       if {[set i [lsearch -glob $tags box:*]]>-1} {
+           lappend nps [string range [lindex $tags $i] 4 end]
+       }
+    }
+    return $nps
+}
+
+;proc Hierarchy_see {w args} {
+    upvar \#0 $w data
+
+    if {[catch {Hierarchy_index $w $args} idx]} {
+       return -code error $idx
+    } elseif {[string compare {} $idx]} {
+       set c $data(basecmd)
+       foreach {x y x1 y1} [$c bbox $idx] {top btm} [$c yview] {
+           set stk [lindex [$c cget -scrollregion] 3]
+           set pos [expr (($y1+$y)/2.0)/$stk - ($btm-$top)/2.0]
+       }
+       $c yview moveto $pos
+    }
+}
+
+;proc Hierarchy_size {w} {
+    upvar \#0 $w data
+    return [llength [$data(basecmd) find withtag box]]
+}
+
+## This will be the one called by <Double-Button-1> on the canvas,
+## if -state is normal, so we have to make sure that $w is correct.
+##
+;proc Hierarchy_toggle { w index } {
+    Hierarchy:toggle $w $index toggle
+}
+
+;proc Hierarchy_close { w index } {
+    Hierarchy:toggle $w $index close
+}
+
+;proc Hierarchy_open { w index } {
+    Hierarchy:toggle $w $index open
+}
+
+;proc Hierarchy:toggle { w index which } {
+    if {[string compare Hierarchy [winfo class $w]]} {
+       set w [winfo parent $w]
+    }
+    upvar \#0 $w data
+
+    if {[string match {} [set np [$w get $index]]]} return
+    set np [lindex $np 0]
+
+    set old [$data(basecmd) cget -cursor]
+    $data(basecmd) config -cursor watch
+    update
+    switch $which {
+       close   { Hierarchy:CollapseNodeAll $w $np }
+       open    { Hierarchy:ExpandNodeN $w $np 1 }
+       toggle  {
+           if {$data(:$np,showkids)} {
+               Hierarchy:CollapseNodeAll $w $np
+           } else {
+               Hierarchy:ExpandNodeN $w $np 1
+           }
+       }
+    }
+    if {[string compare {} $data(-command)]} {
+       uplevel \#0 $data(-command) [list $w $np $data(:$np,showkids)]
+    }
+    $data(basecmd) config -cursor $old
+    return
+}
+
+;proc Hierarchy:Resize { w wid hgt } {
+    upvar \#0 $w data
+    set c $data(basecmd)
+    if {[string compare {} [set box [$c bbox image text]]]} {
+       set X [lindex $box 2]
+       if {$data(-autoscrollbar)} {
+           set Y [lindex $box 3]
+           if {$wid>$X} {
+               set X $wid
+               grid remove $data(xscrollbar)
+           } else {
+               grid $data(xscrollbar)
+           }
+           if {$hgt>$Y} {
+               set Y $hgt
+               grid remove $data(yscrollbar)
+           } else {
+               grid $data(yscrollbar)
+           }
+           $c config -scrollregion "0 0 $X $Y"
+       }
+       ## This makes full width highlight boxes
+       ## data(width) is the default width of boxes
+       if {$X>$data(width)} {
+           set data(width) $X
+           foreach b [$c find withtag box] {
+               foreach {x y x1 y1} [$c coords $b] { $c coords $b 0 $y $X $y1 }
+           }
+       }
+    } elseif {$data(-autoscrollbar)} {
+       grid remove $data(xscrollbar) $data(yscrollbar)
+    }
+}
+
+;proc Hierarchy:CollapseNodeAll { w np } {
+    if {[Hierarchy:CollapseNode $w $np]} {
+       upvar \#0 $w data
+       Hierarchy:Redraw $w $np
+       Hierarchy:DiscardChildren $w $np
+       Hierarchy:Resize $w [winfo width $data(canvas)] \
+               [winfo height $data(canvas)]
+    }
+}
+
+;proc Hierarchy:ExpandNodeN { w np n } {
+    upvar \#0 $w data
+    if {[Hierarchy:ExpandNodeN_aux $w $np $n] || \
+           ([string compare $data(-root) {}] && \
+           ![string compare $data(-root) $np])} {
+       Hierarchy:Redraw $w $np
+       Hierarchy:Resize $w [winfo width $data(canvas)] \
+               [winfo height $data(canvas)]
+    }
+}
+
+;proc Hierarchy:ExpandNodeN_aux { w np n } {
+    if {![Hierarchy:ExpandNode $w $np]} { return 0 }
+    if {$n==1} { return 1 }
+    incr n -1
+    upvar \#0 $w data
+    foreach k $data(:$np,kids) {
+       Hierarchy:ExpandNodeN_aux $w "$np [list $k]" $n
+    }
+    return 1
+}
+
+########################################################################
+##
+## Private routines to collapse and expand a single node w/o redrawing
+## Most routines return 0/1 to indicate if any change has occurred
+##
+########################################################################
+
+;proc Hierarchy:ExpandNode { w np } {
+    upvar \#0 $w data
+
+    if {$data(:$np,showkids)} { return 0 }
+    set data(:$np,showkids) 1
+    if {![info exists data(:$np,kids)]} {
+       if {[string compare $data(-browsecmd) {}]} {
+           set data(:$np,kids) [uplevel \#0 $data(-browsecmd) [list $w $np]]
+       } else {
+           set data(:$np,kids) {}
+       }
+    }
+    if $data(hasnodelook) {
+       set data(:$np,look) [uplevel \#0 $data(-nodelook) [list $w $np 1]]
+    } else {
+       set data(:$np,look) {}
+    }
+    if {[string match {} $data(:$np,kids)]} {
+       foreach {txt font img fg} $data(:$np,look) {
+           lappend tags box:$np box $np
+           set c $data(basecmd)
+           if {[string compare $img {}]} {
+               ## Catch just in case the image doesn't exist
+               catch {
+                   $c itemconfigure img:$np -image $img
+                   lappend tags $img
+               }
+           }
+           if {[string compare $txt {}]} {
+               if {[string match {} $font]} { set font $data(-font) }
+               if {[string match {} $fg]}   { set fg $data(-foreground) }
+               $c itemconfigure txt:$np -fill $fg -text $txt -font $font
+               if {[string compare $np $txt]} { lappend tags $txt }
+           }
+           $c itemconfigure box:$np -tags $tags
+           ## We only want to go through once
+           break
+       }
+       return 0
+    }
+    foreach k $data(:$np,kids) {
+       set knp "$np [list $k]"
+       set data(:$knp,showkids) 0
+       if $data(hasnodelook) {
+           set data(:$knp,look) [uplevel \#0 $data(-nodelook) [list $w $knp 0]]
+       } else {
+           set data(:$knp,look) {}
+       }
+    }
+    return 1
+}
+
+;proc Hierarchy:CollapseNode { w np } {
+    upvar \#0 $w data
+    if {!$data(:$np,showkids)} { return 0 }
+    set data(:$np,showkids) 0
+    if {[string match {} $data(:$np,kids)]} { return 0 }
+    if {[string compare $data(-nodelook) {}]} {
+       set data(:$np,look) [uplevel \#0 $data(-nodelook) [list $w $np 0]]
+    } else {
+       set data(:$np,look) {}
+    }
+    foreach k $data(:$np,kids) { Hierarchy:CollapseNode $w "$np [list $k]" }
+    return 1
+}
+
+;proc Hierarchy:DiscardChildren { w np } {
+    upvar \#0 $w data
+    if {[info exists data(:$np,kids)]} {
+       foreach k $data(:$np,kids) {
+           set knp "$np [list $k]"
+           $data(basecmd) delete img:$knp txt:$knp box:$knp
+           foreach i {showkids look stkusg stack iwidth offset} {
+               catch {unset data(:$knp,$i)}
+           }
+           Hierarchy:DiscardChildren $w $knp
+       }
+       unset data(:$np,kids)
+    }
+}
+
+## REDRAW mechanism
+## 2 parts:    recompute offsets of all children from changed node path
+##             then redraw children based on their offsets and look
+##
+;proc Hierarchy:Redraw { w cnp } {
+    upvar \#0 $w data
+
+    set c $data(basecmd)
+    # When a node changes, the positions of a whole lot of things
+    # change.  The size of the scroll region also changes.
+    $c delete decor
+
+    # Calculate the new offset locations of everything
+    Hierarchy:Recompute $w $data(-root) [lrange $cnp 1 end]
+
+    # Next recursively move all the bits around to their correct positions.
+    # We choose an initial point (4,4) to begin at.
+    Hierarchy:Redraw_aux $w $data(-root) 4 4
+
+    # Necessary to make sure find closest gets the right item
+    # ordering: image > text > box
+    after idle "catch { $c raise image text; $c lower box text }"
+}
+
+## RECOMPUTE recurses through the tree working out the relative offsets
+## of children from their parents in terms of stack values.  
+##
+## "cnp" is either empty or a node name which indicates where the only
+## changes have occured in the hierarchy since the last call to Recompute.
+## This is used because when a node is toggled on/off deep in the
+## hierarchy then not all the positions of items need to be recomputed.
+## The only ones that do are everything below the changed node (of
+## course), and also everything which might depend on the stack usage of
+## that node (i.e. everything above it).  Specifically the usages of the
+## changed node's siblings do *not* need to be recomputed.
+##
+;proc Hierarchy:Recompute { w np cnp } {
+    upvar \#0 $w data
+    # If the cnp now has only one element then
+    # it must be one of the children of the current node.
+    # We do not need to Recompute the usages of its siblings if it is.
+    set cnode_is_child [expr [llength $cnp]==1]
+    if {$cnode_is_child} {
+       set cnode [lindex $cnp 0]
+    } else {
+       set xcnp [lrange $cnp 1 end]
+    }
+    
+    # Run through the children, recursively calculating their usage of
+    # stack real-estate, and allocating an intial placement for each child
+    #
+    # Values do not need to be recomputed for siblings of the changed
+    # node and their descendants.  For the cnode itself, in the
+    # recursive call we set the value of cnode to {} to prevent
+    # any further cnode checks.
+
+    set children_stack 0
+    if {$data(:$np,showkids)} { 
+       foreach k $data(:$np,kids) {
+           set knp "$np [list $k]"
+           set data(:$knp,offset) $children_stack
+           if {$cnode_is_child && [string match $cnode $k]} {
+               set data(:$knp,stkusg) [Hierarchy:Recompute $w $knp {}]
+           } elseif {!$cnode_is_child} {
+               set data(:$knp,stkusg) [Hierarchy:Recompute $w $knp $xcnp]
+           }
+           incr children_stack $data(:$knp,stkusg)
+           incr children_stack $data(-padstack)
+       }
+    }
+
+    ## Make the image/text if they don't exist.
+    ## Positioning occurs in Hierarchy:Redraw_aux.
+    ## And calculate the stack usage of our little piece of the world.
+    set img_height 0; set img_width 0; set txt_width 0; set txt_height 0
+
+    foreach {txt font img fg} $data(:$np,look) {
+       lappend tags box:$np box $np
+       set c $data(basecmd)
+       if {[string compare $img {}]} {
+           if {[string match {} [$c find withtag img:$np]]} {
+               $c create image 0 0 -anchor nw -tags [list img:$np image]
+           }
+           ## Catch just in case the image doesn't exist
+           catch {
+               $c itemconfigure img:$np -image $img
+               lappend tags $img
+               foreach {x y img_width img_height} [$c bbox img:$np] {
+                   incr img_width -$x; incr img_height -$y
+               }
+           }
+       }
+       if {[string compare $txt {}]} {
+           if {[string match {} [$c find withtag txt:$np]]} {
+               $c create text 0 0 -anchor nw -tags [list txt:$np text]
+           }
+           if {[string match {} $font]} { set font $data(-font) }
+           if {[string match {} $fg]}   { set fg $data(-foreground) }
+           $c itemconfigure txt:$np -fill $fg -text $txt -font $font
+           if {[string compare $np $txt]} { lappend tags $txt }
+           foreach {x y txt_width txt_height} [$c bbox txt:$np] {
+               incr txt_width -$x; incr txt_height -$y
+           }
+       }
+       if {[string match {} [$c find withtag box:$np]]} {
+           $c create rect 0 0 1 1 -tags [list box:$np box] -outline {}
+       }
+       $c itemconfigure box:$np -tags $tags
+       ## We only want to go through this once
+       break
+    }
+
+    if {$txt_height>$img_height} {
+       set stack $txt_height
+    } else {
+       set stack $img_height
+    }
+
+    # Now reposition the children downward by "stack"
+    set overall_stack [expr $children_stack+$stack]
+
+    if {$data(:$np,showkids)} { 
+       set off [expr $stack+$data(-padstack)]
+       foreach k $data(:$np,kids) {
+           set knp "$np [list $k]"
+           incr data(:$knp,offset) $off
+       }
+    }
+    # remember some facts for locating the image and drawing decor
+    array set data [list :$np,stack $stack :$np,iwidth $img_width]
+
+    return $overall_stack
+}
+
+;proc Hierarchy:Redraw_aux { w np deppos stkpos} {
+    upvar \#0 $w data
+
+    set c $data(basecmd)
+    $c coords img:$np $deppos $stkpos
+    $c coords txt:$np [expr {$deppos+$data(:$np,iwidth)+$data(-ipad)}] $stkpos
+    $c coords box:$np 0 [expr $stkpos-$data(halfpstk)] \
+           $data(width) [expr $stkpos+$data(:$np,stack)+$data(halfpstk)]
+
+    if {!$data(:$np,showkids) || [string match {} $data(:$np,kids)]} return
+
+    set minkid_stkpos 100000
+    set maxkid_stkpos 0
+    set bar_deppos [expr $deppos+$data(-paddepth)/2]
+    set kid_deppos [expr $deppos+$data(-paddepth)]
+
+    foreach k $data(:$np,kids) {
+       set knp "$np [list $k]"
+       set kid_stkpos [expr $stkpos+$data(:$knp,offset)]
+       Hierarchy:Redraw_aux $w $knp $kid_deppos $kid_stkpos
+       
+       if {$data(-decoration)} {
+           if {$kid_stkpos<$minkid_stkpos} {set minkid_stkpos $kid_stkpos}
+           set kid_stkpos [expr $kid_stkpos+$data(:$knp,stack)/2]
+           if {$kid_stkpos>$maxkid_stkpos} {set maxkid_stkpos $kid_stkpos}
+           
+           $c create line $bar_deppos $kid_stkpos $kid_deppos $kid_stkpos \
+                   -width 1 -tags decor
+       }
+    }
+    if {$data(-decoration)} {
+       $c create line $bar_deppos $minkid_stkpos $bar_deppos $maxkid_stkpos \
+               -width 1 -tags decor
+    }
+}
+
+
+##
+## DEFAULT BINDINGS FOR HIERARCHY
+##
+## Since we give no border to the frame, all Hierarchy bindings
+## will always register on the canvas widget
+##
+bind Hierarchy <Double-Button-1> {
+    set w [winfo parent %W]
+    if {[string match normal [$w cget -state]]} {
+       $w toggle @%x,%y
+    }
+}
+bind Hierarchy <ButtonPress-1> {
+    if {[winfo exists %W]} { Hierarchy:BeginSelect [winfo parent %W] @%x,%y }
+}
+bind Hierarchy <B1-Motion> {
+    set tkPriv(x) %x
+    set tkPriv(y) %y
+    Hierarchy:Motion [winfo parent %W] @%x,%y
+}
+bind Hierarchy <ButtonRelease-1> { tkCancelRepeat }
+bind Hierarchy <Shift-1>   { Hierarchy:BeginExtend [winfo parent %W] @%x,%y }
+bind Hierarchy <Control-1> { Hierarchy:BeginToggle [winfo parent %W] @%x,%y }
+bind Hierarchy <B1-Leave> {
+    set tkPriv(x) %x
+    set tkPriv(y) %y
+    Hierarchy:AutoScan [winfo parent %W]
+}
+bind Hierarchy <B1-Enter>      { tkCancelRepeat }
+
+## Should reserve L/R U/D for traversing nodes
+bind Hierarchy <Up>            { %W yview scroll -1 units }
+bind Hierarchy <Down>          { %W yview scroll  1 units }
+bind Hierarchy <Left>          { %W xview scroll -1 units }
+bind Hierarchy <Right>         { %W xview scroll  1 units }
+
+bind Hierarchy <Control-Up>    { %W yview scroll -1 pages }
+bind Hierarchy <Control-Down>  { %W yview scroll  1 pages }
+bind Hierarchy <Control-Left>  { %W xview scroll -1 pages }
+bind Hierarchy <Control-Right> { %W xview scroll  1 pages }
+bind Hierarchy <Prior>         { %W yview scroll -1 pages }
+bind Hierarchy <Next>          { %W yview scroll  1 pages }
+bind Hierarchy <Control-Prior> { %W xview scroll -1 pages }
+bind Hierarchy <Control-Next>  { %W xview scroll  1 pages }
+bind Hierarchy <Home>          { %W xview moveto 0 }
+bind Hierarchy <End>           { %W xview moveto 1 }
+bind Hierarchy <Control-slash> { Hierarchy:SelectAll [winfo parent %W] }
+bind Hierarchy <Control-backslash> { [winfo parent %W] selection clear }
+
+bind Hierarchy <2> {
+    set tkPriv(x) %x
+    set tkPriv(y) %y
+    %W scan mark %x %y
+}
+bind Hierarchy <B2-Motion> {
+    %W scan dragto $tkPriv(x) %y
+}
+
+# Hierarchy:BeginSelect --
+#
+# This procedure is typically invoked on button-1 presses.  It begins
+# the process of making a selection in the hierarchy.  Its exact behavior
+# depends on the selection mode currently in effect for the hierarchy;
+# see the Motif documentation for details.
+#
+# Arguments:
+# w -          The hierarchy widget.
+# el -         The element for the selection operation (typically the
+#              one under the pointer).  Must be in numerical form.
+
+;proc Hierarchy:BeginSelect {w el} {
+    global tkPriv
+    if {[catch {Hierarchy_index $w $el} el]} return
+    $w selection clear
+    $w selection set $el
+    set tkPriv(hierarchyPrev) $el
+}
+
+# Hierarchy:Motion --
+#
+# This procedure is called to process mouse motion events while
+# button 1 is down.  It may move or extend the selection, depending
+# on the hierarchy's selection mode.
+#
+# Arguments:
+# w -          The hierarchy widget.
+# el -         The element under the pointer (must be a number).
+
+;proc Hierarchy:Motion {w el} {
+    global tkPriv
+    if {[catch {Hierarchy_index $w $el} el] || \
+           [string match $el $tkPriv(hierarchyPrev)]} return
+    switch [Hierarchy_cget $w -selectmode] {
+       browse {
+           Hierarchy_selection $w clear 0 end
+           if {![catch {Hierarchy_selection $w set $el}]} {
+               set tkPriv(hierarchyPrev) $el
+           }
+       }
+       multiple {
+           ## This happens when a double-1 occurs and all the index boxes
+           ## have changed
+           if {[catch {Hierarchy_selection $w includes \
+                   $tkPriv(hierarchyPrev)} inc]} {
+               set tkPriv(hierarchyPrev) [Hierarchy_index $w $el]
+               return
+           }
+           if {$inc} {
+               Hierarchy_selection $w set $el
+           } else {
+               Hierarchy_selection $w clear $el
+           }
+           set tkPriv(hierarchyPrev) $el
+       }
+    }
+}
+
+# Hierarchy:BeginExtend --
+#
+# This procedure is typically invoked on shift-button-1 presses.  It
+# begins the process of extending a selection in the hierarchy.  Its
+# exact behavior depends on the selection mode currently in effect
+# for the hierarchy;
+#
+# Arguments:
+# w -          The hierarchy widget.
+# el -         The element for the selection operation (typically the
+#              one under the pointer).  Must be in numerical form.
+
+;proc Hierarchy:BeginExtend {w el} {
+    if {[catch {Hierarchy_index $w $el} el]} return
+    if {[string match multiple [$w cget -selectmode]]} {
+       Hierarchy:Motion $w $el
+    }
+}
+
+# Hierarchy:BeginToggle --
+#
+# This procedure is typically invoked on control-button-1 presses.  It
+# begins the process of toggling a selection in the hierarchy.  Its
+# exact behavior depends on the selection mode currently in effect
+# for the hierarchy;  see the Motif documentation for details.
+#
+# Arguments:
+# w -          The hierarchy widget.
+# el -         The element for the selection operation (typically the
+#              one under the pointer).  Must be in numerical form.
+
+;proc Hierarchy:BeginToggle {w el} {
+    global tkPriv
+    if {[catch {Hierarchy_index $w $el} el]} return
+    if {[string match multiple [$w cget -selectmode]]} {
+       $w selection anchor $el
+       if {[$w selection includes $el]} {
+           $w selection clear $el
+       } else {
+           $w selection set $el
+       }
+       set tkPriv(hierarchyPrev) $el
+    }
+}
+
+# Hierarchy:AutoScan --
+# This procedure is invoked when the mouse leaves an entry window
+# with button 1 down.  It scrolls the window up, down, left, or
+# right, depending on where the mouse left the window, and reschedules
+# itself as an "after" command so that the window continues to scroll until
+# the mouse moves back into the window or the mouse button is released.
+#
+# Arguments:
+# w -          The hierarchy widget.
+
+;proc Hierarchy:AutoScan {w} {
+    global tkPriv
+    if {![winfo exists $w]} return
+    set x $tkPriv(x)
+    set y $tkPriv(y)
+    if {$y>=[winfo height $w]} {
+       $w yview scroll 1 units
+    } elseif {$y<0} {
+       $w yview scroll -1 units
+    } elseif {$x>=[winfo width $w]} {
+       $w xview scroll 2 units
+    } elseif {$x<0} {
+       $w xview scroll -2 units
+    } else {
+       return
+    }
+    #Hierarchy:Motion $w [$w index @$x,$y]
+    set tkPriv(afterId) [after 50 Hierarchy:AutoScan $w]
+}
+
+# Hierarchy:SelectAll
+#
+# This procedure is invoked to handle the "select all" operation.
+# For single and browse mode, it just selects the root element.
+# Otherwise it selects everything in the widget.
+#
+# Arguments:
+# w -          The hierarchy widget.
+
+;proc Hierarchy:SelectAll w {
+    if {[regexp (browse|single) [$w cget -selectmode]]} {
+       $w selection clear
+       $w selection set root
+    } else {
+       $w selection set all
+    }
+}
+
+#------------------------------------------------------------
+# Default nodelook methods
+#------------------------------------------------------------
+
+;proc Hierarchy:FileLook { w np isopen } {
+    upvar \#0 $w data
+    set path [eval file join $np]
+    set file [lindex $np end]
+    set bmp  {}
+    if {[file readable $path]} {
+       if {[file isdirectory $path]} {
+           if {$isopen} {
+               ## We know that kids will always be set by the time
+               ## the isopen is set to 1
+               if {[string compare $data(:$np,kids) {}]} {
+                   set bmp bmp:dir_minus
+               } else {
+                   set bmp bmp:dir
+               }
+           } else {
+               set bmp bmp:dir_plus
+           }
+           if 0 {
+               ## NOTE: accurate, but very expensive
+               if {[string compare [Hierarchy:FileList $w $np] {}]} {
+                   if {$isopen} {set bmp bmp:dir_minus} {set bmp bmp:dir_plus}
+               } else {
+                   set bmp bmp:dir
+               }
+           }
+       }
+       set fg \#000000
+    } elseif {[string compare $data(-showparent) {}] && \
+           [string match $data(-showparent) $file]} {
+       set fg \#0000FF
+       set bmp bmp:up
+    } else {
+       set fg \#a9a9a9
+       if {[file isdirectory $path]} {set bmp bmp:dir}
+    }
+    return [list $file $data(-font) $bmp $fg] 
+}
+
+## Hierarchy:FileList
+# ARGS:        w       hierarchy widget
+#      np      node path       
+# Returns:     directory listing
+##
+;proc Hierarchy:FileList { w np } {
+    set pwd [pwd]
+    if {[catch "cd \[file join $np\]"]} {
+       set list {}
+    } else {
+       global tcl_platform
+       upvar \#0 $w data
+       set str *
+       if {!$data(-showfiles)} { append str / }
+       if {$data(-showall) && [string match unix $tcl_platform(platform)]} {
+           ## NOTE: Use of non-core lremove
+           if {[catch {lsort [concat [glob -nocomplain $str] \
+                   [lremove [glob -nocomplain .$str] {. ..}]]} list]} {
+               return {}
+           }
+       } else {
+           ## The extra catch is necessary for unusual error conditions
+           if {[catch {lsort [glob -nocomplain $str]} list]} {
+               return {}
+           }
+       }
+       set root $data(-root)
+       if {[string compare {} $data(-showparent)] && \
+               [string match $root $np]} {
+           if {![regexp {^(.:)?/+$} $root] && \
+                   [string compare [file dir $root] $root]} {
+               set list [linsert $list 0 $data(-showparent)]
+           }
+       }
+    }
+    cd $pwd
+    return $list
+}
+
+;proc Hierarchy:FileActivate { w np isopen } {
+    upvar \#0 $w data
+    set path [eval file join $np]
+    if {[file isdirectory $path]} return
+    if {[string compare $data(-showparent) {}] && \
+           [string match $data(-showparent) [lindex $np end]]} {
+       $w config -root [file dir $data(-root)]
+    }
+}
+
+;proc Hierarchy:WidgetLook { W np isopen } {
+    upvar \#0 $W data
+    if {$data(-showall)} {
+       set w [lindex $np end]
+    } else {
+       set w [join $np {}]
+       regsub {\.\.} $w {.} w
+    }
+    if {[string compare [winfo children $w] {}]} {set fg blue} {set fg black}
+    return [list "\[[winfo class $w]\] [lindex $np end]" {} {} $fg]
+}
+
+;proc Hierarchy:WidgetList { W np } {
+    upvar \#0 $W data
+    if {$data(-showall)} {
+       set w [lindex $np end]
+    } else {
+       set w [join $np {}]
+       regsub {\.\.} $w {.} w
+    }
+    set kids {}
+    foreach i [lsort [winfo children $w]] {
+       if {$data(-showall)} {
+           lappend kids $i
+       } else {
+           lappend kids [file extension $i]
+       }
+    }
+    return $kids
+}
+
+;proc Hierarchy:WidgetActivate { w np isopen } {}
+
+
+## BITMAPS
+##
+image create bitmap bmp:dir -data {#define folder_width 16
+#define folder_height 12
+static char folder_bits[] = {
+  0x00, 0x1f, 0x80, 0x20, 0x40, 0x20, 0xfc, 0x7f, 0x02, 0x40, 0x02, 0x40,
+  0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0xfe, 0x7f};}
+image create bitmap bmp:dir_plus -data {#define folder_plus_width 16
+  #define folder_plus_height 12
+static char folder_plus_bits[] = {
+  0x00, 0x1f, 0x80, 0x20, 0x40, 0x20, 0xfc, 0x7f, 0x02, 0x40, 0x82, 0x40,
+  0x82, 0x40, 0xe2, 0x43, 0x82, 0x40, 0x82, 0x40, 0x02, 0x40, 0xfe, 0x7f};}
+image create bitmap bmp:dir_minus -data {#define folder_minus_width 16
+#define folder_minus_height 12
+static char folder_minus_bits[] = {
+  0x00, 0x1f, 0x80, 0x20, 0x40, 0x20, 0xfc, 0x7f, 0x02, 0x40, 0x02, 0x40,
+  0x02, 0x40, 0xe2, 0x43, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0xfe, 0x7f};}
+image create bitmap bmp:up -data {#define up.xbm_width 16
+#define up.xbm_height 12
+static unsigned char up.xbm_bits[] = {
+  0x00, 0x00, 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x38, 0x00,
+  0x38, 0x00, 0x38, 0x00, 0xf8, 0x7f, 0xf0, 0x7f, 0xe0, 0x7f, 0x00, 0x00};}
+image create bitmap bmp:text -data {#define text_width 15
+#define text_height 14
+static char text_bits[] = {
+  0xff,0x07,0x01,0x0c,0x01,0x04,0x01,0x24,0xf9,0x7d,0x01,0x78,0x01,0x40,0xf1,
+  0x41,0x01,0x40,0x01,0x40,0xf1,0x41,0x01,0x40,0x01,0x40,0xff,0x7f};}
+
+return
diff --git a/tcl/html_library.tcl b/tcl/html_library.tcl
new file mode 100644 (file)
index 0000000..8bbfd41
--- /dev/null
@@ -0,0 +1,1417 @@
+# Simple HTML display library by Stephen Uhler (stephen.uhler@sun.com)
+# Copyright (c) 1995 by Sun Microsystems
+# Version 0.3 Fri Sep  1 10:47:17 PDT 1995
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# To use this package,  create a text widget (say, .text)
+# and set a variable full of html, (say $html), and issue:
+#      HMinit_win .text
+#      HMparse_html $html "HMrender .text"
+# You also need to supply the routine:
+#   proc HMlink_callback {win href} { ...}
+#      win:  The name of the text widget
+#      href  The name of the link
+# which will be called anytime the user "clicks" on a link.
+# The supplied version just prints the link to stdout.
+# In addition, if you wish to use embedded images, you will need to write
+#   proc HMset_image {handle src}
+#      handle  an arbitrary handle (not really)
+#      src     The name of the image
+# Which calls
+#      HMgot_image $handle $image
+# with the TK image.
+#
+# To return a "used" text widget to its initialized state, call:
+#   HMreset_win .text
+# See "sample.tcl" for sample usage
+##################################################################
+############################################
+# mapping of html tags to text tag properties
+# properties beginning with "T" map directly to text tags
+
+# These are Defined in HTML 2.0
+
+array set HMtag_map {
+       b      {weight bold}
+       blockquote      {style i indent 1 Trindent rindent}
+       bq              {style i indent 1 Trindent rindent}
+       cite   {style i}
+       code   {family courier}
+       dfn    {style i}        
+       dir    {indent 1}
+       dl     {indent 1}
+       em     {style i}
+       h1     {size 24 weight bold}
+       h2     {size 22}                
+       h3     {size 20}        
+       h4     {size 18}
+       h5     {size 16}
+       h6     {style i}
+       i      {style i}
+       kbd    {family courier weight bold}
+       menu     {indent 1}
+       ol     {indent 1}
+       pre    {fill 0 family courier Tnowrap nowrap}
+       samp   {family courier}         
+       strong {weight bold}            
+       tt     {family courier}
+       u        {Tunderline underline}
+       ul     {indent 1}
+       var    {style i}        
+}
+
+# These are in common(?) use, but not defined in html2.0
+
+array set HMtag_map {
+       center {Tcenter center}
+       strike {Tstrike strike}
+       u          {Tunderline underline}
+}
+
+# initial values
+
+set HMtag_map(hmstart) {
+       family times   weight medium   style r   size 14
+       Tcenter ""   Tlink ""   Tnowrap ""   Tunderline ""   list list
+       fill 1   indent "" counter 0 adjust 0
+}
+
+# html tags that insert white space
+
+array set HMinsert_map {
+       blockquote "\n\n" /blockquote "\n"
+       br      "\n"
+       dd      "\n" /dd        "\n"
+       dl      "\n" /dl        "\n"
+       dt      "\n"
+       form "\n"       /form "\n"
+       h1      "\n\n"  /h1     "\n"
+       h2      "\n\n"  /h2     "\n"
+       h3      "\n\n"  /h3     "\n"
+       h4      "\n"    /h4     "\n"
+       h5      "\n"    /h5     "\n"
+       h6      "\n"    /h6     "\n"
+       li   "\n"
+       /dir "\n"
+       /ul "\n"
+       /ol "\n"
+       /menu "\n"
+       p       "\n\n"
+       pre "\n"        /pre "\n"
+}
+
+# tags that are list elements, that support "compact" rendering
+
+array set HMlist_elements {
+       ol 1   ul 1   menu 1   dl 1   dir 1
+}
+############################################
+# initialize the window and stack state
+
+proc HMinit_win {win} {
+       upvar #0 HM$win var
+       
+       HMinit_state $win
+       $win tag configure underline -underline 1
+       $win tag configure center -justify center
+       $win tag configure nowrap -wrap none
+       $win tag configure rindent -rmargin $var(S_tab)c
+       $win tag configure strike -overstrike 1
+       $win tag configure mark -foreground red         ;# list markers
+       $win tag configure list -spacing1 3p -spacing3 3p               ;# regular lists
+       $win tag configure compact -spacing1 0p         ;# compact lists
+       $win tag configure link -borderwidth 2 -foreground blue ;# hypertext links
+       HMset_indent $win $var(S_tab)
+       $win configure -wrap word
+
+       # configure the text insertion point
+       $win mark set $var(S_insert) 1.0
+
+       # for horizontal rules
+       $win tag configure thin -font [HMx_font times 2 medium r]
+       $win tag configure hr -relief sunken -borderwidth 2 -wrap none \
+               -tabs [winfo width $win]
+       bind $win <Configure> {
+               %W tag configure hr -tabs %w
+               %W tag configure last -spacing3 %h
+       }
+
+       # generic link enter callback
+
+       $win tag bind link <1> "HMlink_hit $win %x %y"
+}
+
+# set the indent spacing (in cm) for lists
+# TK uses a "weird" tabbing model that causes \t to insert a single
+# space if the current line position is past the tab setting
+
+proc HMset_indent {win cm} {
+       set tabs [expr $cm / 2.0]
+       $win configure -tabs ${tabs}c
+       foreach i {1 2 3 4 5 6 7 8 9} {
+               set tab [expr $i * $cm]
+               $win tag configure indent$i -lmargin1 ${tab}c -lmargin2 ${tab}c \
+                       -tabs "[expr $tab + $tabs]c [expr $tab + 2*$tabs]c"
+       }
+}
+
+# reset the state of window - get ready for the next page
+# remove all but the font tags, and remove all form state
+
+proc HMreset_win {win} {
+       upvar #0 HM$win var
+       regsub -all { +[^L ][^ ]*} " [$win tag names] " {} tags
+       catch "$win tag delete $tags"
+       eval $win mark unset [$win mark names]
+       $win delete 0.0 end
+       $win tag configure hr -tabs [winfo width $win]
+
+       # configure the text insertion point
+       $win mark set $var(S_insert) 1.0
+
+       # remove form state.  If any check/radio buttons still exists, 
+       # their variables will be magically re-created, and never get
+       # cleaned up.
+       catch unset [info globals HM$win.form*]
+
+       HMinit_state $win
+       return HM$win
+}
+
+# initialize the window's state array
+# Parameters beginning with S_ are NOT reset
+#  adjust_size:                global font size adjuster
+#  unknown:            character to use for unknown entities
+#  tab:                        tab stop (in cm)
+#  stop:               enabled to stop processing
+#  update:             how many tags between update calls
+#  tags:               number of tags processed so far
+#  symbols:            Symbols to use on un-ordered lists
+
+proc HMinit_state {win} {
+       upvar #0 HM$win var
+       array set tmp [array get var S_*]
+       catch {unset var}
+       array set var {
+               stop 0
+               tags 0
+               fill 0
+               list list
+               S_adjust_size 0
+               S_tab 1.0
+               S_unknown \xb7
+               S_update 10
+               S_symbols O*=+-o\xd7\xb0>:\xb7
+               S_insert Insert
+       }
+       array set var [array get tmp]
+}
+
+# alter the parameters of the text state
+# this allows an application to over-ride the default settings
+# it is called as: HMset_state -param value -param value ...
+
+array set HMparam_map {
+       -update S_update
+       -tab S_tab
+       -unknown S_unknown
+       -stop S_stop
+       -size S_adjust_size
+       -symbols S_symbols
+    -insert S_insert
+}
+
+proc HMset_state {win args} {
+       upvar #0 HM$win var
+       global HMparam_map
+       set bad 0
+       if {[catch {array set params $args}]} {return 0}
+       foreach i [array names params] {
+               incr bad [catch {set var($HMparam_map($i)) $params($i)}]
+       }
+       return [expr $bad == 0]
+}
+
+############################################
+# manage the display of html
+
+# HMrender gets called for every html tag
+#   win:   The name of the text widget to render into
+#   tag:   The html tag (in arbitrary case)
+#   not:   a "/" or the empty string
+#   param: The un-interpreted parameter list
+#   text:  The plain text until the next html tag
+
+proc HMrender {win tag not param text} {
+       upvar #0 HM$win var
+       if {$var(stop)} return
+       global HMtag_map HMinsert_map HMlist_elements
+       set tag [string tolower $tag]
+       set text [HMmap_esc $text]
+
+       # manage compact rendering of lists
+       if {[info exists HMlist_elements($tag)]} {
+               set list "list [expr {[HMextract_param $param compact] ? "compact" : "list"}]"
+       } else {
+               set list ""
+       }
+
+       # Allow text to be diverted to a different window (for tables)
+       # this is not currently used
+       if {[info exists var(divert)]} {
+               set win $var(divert)
+               upvar #0 HM$win var
+       }
+
+       # adjust (push or pop) tag state
+       catch {HMstack $win $not "$HMtag_map($tag) $list"}
+
+       # insert white space (with current font)
+       # adding white space can get a bit tricky.  This isn't quite right
+       set bad [catch {$win insert $var(S_insert) $HMinsert_map($not$tag) "space $var(font)"}]
+       if {!$bad && [lindex $var(fill) end]} {
+               set text [string trimleft $text]
+       }
+
+       # to fill or not to fill
+       if {[lindex $var(fill) end]} {
+               set text [HMzap_white $text]
+       }
+
+       # generic mark hook
+       catch {HMmark $not$tag $win $param text} err
+
+       # do any special tag processing
+       catch {HMtag_$not$tag $win $param text} msg
+
+
+       # add the text with proper tags
+
+       set tags [HMcurrent_tags $win]
+       $win insert $var(S_insert) $text $tags
+
+       # We need to do an update every so often to insure interactive response.
+       # This can cause us to re-enter the event loop, and cause recursive
+       # invocations of HMrender, so we need to be careful.
+       if {!([incr var(tags)] % $var(S_update))} {
+               update
+       }
+}
+
+# html tags requiring special processing
+# Procs of the form HMtag_<tag> or HMtag_</tag> get called just before
+# the text for this tag is displayed.  These procs are called inside a 
+# "catch" so it is OK to fail.
+#   win:   The name of the text widget to render into
+#   param: The un-interpreted parameter list
+#   text:  A pass-by-reference name of the plain text until the next html tag
+#          Tag commands may change this to affect what text will be inserted
+#          next.
+
+# A pair of pseudo tags are added automatically as the 1st and last html
+# tags in the document.  The default is <HMstart> and </HMstart>.
+# Append enough blank space at the end of the text widget while
+# rendering so HMgoto can place the target near the top of the page,
+# then remove the extra space when done rendering.
+
+proc HMtag_hmstart {win param text} {
+       upvar #0 HM$win var
+       $win mark gravity $var(S_insert) left
+       $win insert end "\n " last
+       $win mark gravity $var(S_insert) right
+}
+
+proc HMtag_/hmstart {win param text} {
+       $win delete last.first end
+}
+
+# put the document title in the window banner, and remove the title text
+# from the document
+
+proc HMtag_title {win param text} {
+       upvar $text data
+       wm title [winfo toplevel $win] $data
+       set data ""
+}
+
+proc HMtag_hr {win param text} {
+       upvar #0 HM$win var
+       $win insert $var(S_insert) "\n" space "\n" thin "\t" "thin hr" "\n" thin
+}
+
+# list element tags
+
+proc HMtag_ol {win param text} {
+       upvar #0 HM$win var
+       set var(count$var(level)) 0
+}
+
+proc HMtag_ul {win param text} {
+       upvar #0 HM$win var
+       catch {unset var(count$var(level))}
+}
+
+proc HMtag_menu {win param text} {
+       upvar #0 HM$win var
+       set var(menu) ->
+       set var(compact) 1
+}
+
+proc HMtag_/menu {win param text} {
+       upvar #0 HM$win var
+       catch {unset var(menu)}
+       catch {unset var(compact)}
+}
+       
+proc HMtag_dt {win param text} {
+       upvar #0 HM$win var
+       upvar $text data
+       set level $var(level)
+       incr level -1
+       $win insert $var(S_insert) "$data" \
+               "hi [lindex $var(list) end] indent$level $var(font)"
+       set data {}
+}
+
+proc HMtag_li {win param text} {
+       upvar #0 HM$win var
+       set level $var(level)
+       incr level -1
+       set x [string index $var(S_symbols)+-+-+-+-" $level]
+       catch {set x [incr var(count$level)]}
+       catch {set x $var(menu)}
+       $win insert $var(S_insert) \t$x\t "mark [lindex $var(list) end] indent$level $var(font)"
+}
+
+# Manage hypertext "anchor" links.  A link can be either a source (href)
+# a destination (name) or both.  If its a source, register it via a callback,
+# and set its default behavior.  If its a destination, check to see if we need
+# to go there now, as a result of a previous HMgoto request.  If so, schedule
+# it to happen with the closing </a> tag, so we can highlight the text up to
+# the </a>.
+
+proc HMtag_a {win param text} {
+       upvar #0 HM$win var
+
+       # a source
+
+       if {[HMextract_param $param href]} {
+               set var(Tref) [list L:$href]
+               HMstack $win "" "Tlink link"
+               HMlink_setup $win $href
+       }
+
+       # a destination
+
+       if {[HMextract_param $param name]} {
+               set var(Tname) [list N:$name]
+               HMstack $win "" "Tanchor anchor"
+               $win mark set N:$name "$var(S_insert) - 1 chars"
+               $win mark gravity N:$name left
+               if {[info exists var(goto)] && $var(goto) == $name} {
+                       unset var(goto)
+                       set var(going) $name
+               }
+       }
+}
+
+# The application should call here with the fragment name
+# to cause the display to go to this spot.
+# If the target exists, go there (and do the callback),
+# otherwise schedule the goto to happen when we see the reference.
+
+proc HMgoto {win where {callback HMwent_to}} {
+       upvar #0 HM$win var
+       if {[regexp N:$where [$win mark names]]} {
+               $win see N:$where
+               update
+               eval $callback $win [list $where]
+               return 1
+       } else {
+               set var(goto) $where
+               return 0
+       }
+}
+
+# We actually got to the spot, so highlight it!
+# This should/could be replaced by the application
+# We'll flash it orange a couple of times.
+
+proc HMwent_to {win where {count 0} {color orange}} {
+       upvar #0 HM$win var
+       if {$count > 5} return
+       catch {$win tag configure N:$where -foreground $color}
+       update
+       after 200 [list HMwent_to $win $where [incr count] \
+                               [expr {$color=="orange" ? "" : "orange"}]]
+}
+
+proc HMtag_/a {win param text} {
+       upvar #0 HM$win var
+       if {[info exists var(Tref)]} {
+               unset var(Tref)
+               HMstack $win / "Tlink link"
+       }
+
+       # goto this link, then invoke the call-back.
+
+       if {[info exists var(going)]} {
+               $win yview N:$var(going)
+               update
+               HMwent_to $win $var(going)
+               unset var(going)
+       }
+
+       if {[info exists var(Tname)]} {
+               unset var(Tname)
+               HMstack $win / "Tanchor anchor"
+       }
+}
+
+#           Inline Images
+# This interface is subject to change
+# Most of the work is getting around a limitation of TK that prevents
+# setting the size of a label to a widthxheight in pixels
+#
+# Images have the following parameters:
+#    align:  top,middle,bottom
+#    alt:    alternate text
+#    ismap:  A clickable image map
+#    src:    The URL link
+# Netscape supports (and so do we)
+#    width:  A width hint (in pixels)
+#    height:  A height hint (in pixels)
+#    border: The size of the window border
+
+proc HMtag_img {win param text} {
+       upvar #0 HM$win var
+
+       # get alignment
+       array set align_map {top top    middle center    bottom bottom}
+       set align bottom                ;# The spec isn't clear what the default should be
+       HMextract_param $param align
+       catch {set align $align_map([string tolower $align])}
+
+       # get alternate text
+       set alt "<image>"
+       HMextract_param $param alt
+       set alt [HMmap_esc $alt]
+
+       # get the border width
+       set border 1
+       HMextract_param $param border
+
+       # see if we have an image size hint
+       # If so, make a frame the "hint" size to put the label in
+       # otherwise just make the label
+       set item $win.$var(tags)
+       # catch {destroy $item}
+       if {[HMextract_param $param width] && [HMextract_param $param height]} {
+               frame $item -width $width -height $height
+               pack propagate $item 0
+               set label $item.label
+               label $label
+               pack $label -expand 1 -fill both
+       } else {
+               set label $item
+               label $label 
+       }
+
+       $label configure -relief ridge -fg orange -text $alt
+       catch {$label configure -bd $border}
+       $win window create $var(S_insert) -align $align -window $item -pady 2 -padx 2
+
+       # add in all the current tags (this is overkill)
+       set tags [HMcurrent_tags $win]
+       foreach tag $tags {
+               $win tag add $tag $item
+       }
+
+       # set imagemap callbacks
+       if {[HMextract_param $param ismap]} {
+               # regsub -all {[^L]*L:([^ ]*).*}  $tags {\1} link
+               set link [lindex $tags [lsearch -glob $tags L:*]]
+               regsub L: $link {} link
+               global HMevents
+               regsub -all {%} $link {%%} link2
+               foreach i [array names HMevents] {
+                       bind $label <$i> "catch \{%W configure $HMevents($i)\}"
+               }
+               bind $label <1> "+HMlink_callback $win $link2?%x,%y"
+       } 
+
+       # now callback to the application
+       set src ""
+       HMextract_param $param src
+       HMset_image $win $label $src
+       return $label   ;# used by the forms package for input_image types
+}
+
+# The app needs to supply one of these
+proc HMset_image {win handle src} {
+       HMgot_image $handle "can't get\n$src"
+}
+
+# When the image is available, the application should call back here.
+# If we have the image, put it in the label, otherwise display the error
+# message.  If we don't get a callback, the "alt" text remains.
+# if we have a clickable image, arrange for a callback
+
+proc HMgot_image {win image_error} {
+       # if we're in a frame turn on geometry propogation
+       if {[winfo name $win] == "label"} {
+               pack propagate [winfo parent $win] 1
+       }
+       if {[catch {$win configure -image $image_error}]} {
+               $win configure -image {}
+               $win configure -text $image_error
+       }
+}
+
+# Sample hypertext link callback routine - should be replaced by app
+# This proc is called once for each <A> tag.
+# Applications can overwrite this procedure, as required, or
+# replace the HMevents array
+#   win:   The name of the text widget to render into
+#   href:  The HREF link for this <a> tag.
+
+array set HMevents {
+       Enter   {-borderwidth 2 -relief raised }
+       Leave   {-borderwidth 2 -relief flat }
+       1               {-borderwidth 2 -relief sunken}
+       ButtonRelease-1 {-borderwidth 2 -relief raised}
+}
+
+# We need to escape any %'s in the href tag name so the bind command
+# doesn't try to substitute them.
+
+proc HMlink_setup {win href} {
+       global HMevents
+       regsub -all {%} $href {%%} href2
+       foreach i [array names HMevents] {
+               eval {$win tag bind  L:$href <$i>} \
+                       \{$win tag configure \{L:$href2\} $HMevents($i)\}
+       }
+}
+
+# generic link-hit callback
+# This gets called upon button hits on hypertext links
+# Applications are expected to supply ther own HMlink_callback routine
+#   win:   The name of the text widget to render into
+#   x,y:   The cursor position at the "click"
+
+proc HMlink_hit {win x y} {
+       set tags [$win tag names @$x,$y]
+       set link [lindex $tags [lsearch -glob $tags L:*]]
+       # regsub -all {[^L]*L:([^ ]*).*}  $tags {\1} link
+       regsub L: $link {} link
+       HMlink_callback $win $link
+}
+
+# replace this!
+#   win:   The name of the text widget to render into
+#   href:  The HREF link for this <a> tag.
+
+proc HMlink_callback {win href} {
+       puts "Got hit on $win, link $href"
+}
+
+# extract a value from parameter list (this needs a re-do)
+# returns "1" if the keyword is found, "0" otherwise
+#   param:  A parameter list.  It should alredy have been processed to
+#           remove any entity references
+#   key:    The parameter name
+#   val:    The variable to put the value into (use key as default)
+
+proc HMextract_param {param key {val ""}} {
+
+       if {$val == ""} {
+               upvar $key result
+       } else {
+               upvar $val result
+       }
+    set ws "    \n\r"
+    # look for name=value combinations.  Either (') or (") are valid delimeters
+    if {
+      [regsub -nocase [format {.*%s[%s]*=[%s]*"([^"]*).*} $key $ws $ws] $param {\1} value] ||
+      [regsub -nocase [format {.*%s[%s]*=[%s]*'([^']*).*} $key $ws $ws] $param {\1} value] ||
+      [regsub -nocase [format {.*%s[%s]*=[%s]*([^%s]+).*} $key $ws $ws $ws] $param {\1} value] } {
+        set result $value
+        return 1
+    }
+
+       # now look for valueless names
+       # I should strip out name=value pairs, so we don't end up with "name"
+       # inside the "value" part of some other key word - some day
+       
+       set bad \[^a-zA-Z\]+
+       if {[regexp -nocase  "$bad$key$bad" -$param-]} {
+               return 1
+       } else {
+               return 0
+       }
+}
+
+# These next two routines manage the display state of the page.
+
+# Push or pop tags to/from stack.
+# Each orthogonal text property has its own stack, stored as a list.
+# The current (most recent) tag is the last item on the list.
+# Push is {} for pushing and {/} for popping
+
+proc HMstack {win push list} {
+       upvar #0 HM$win var
+       array set tags $list
+       if {$push == ""} {
+               foreach tag [array names tags] {
+                       lappend var($tag) $tags($tag)
+               }
+       } else {
+               foreach tag [array names tags] {
+                       # set cnt [regsub { *[^ ]+$} $var($tag) {} var($tag)]
+                       set var($tag) [lreplace $var($tag) end end]
+               }
+       }
+}
+
+# extract set of current text tags
+# tags starting with T map directly to text tags, all others are
+# handled specially.  There is an application callback, HMset_font
+# to allow the application to do font error handling
+
+proc HMcurrent_tags {win} {
+       upvar #0 HM$win var
+       set font font
+       foreach i {family size weight style} {
+               set $i [lindex $var($i) end]
+               append font :[set $i]
+       }
+       set xfont [HMx_font $family $size $weight $style $var(S_adjust_size)]
+       HMset_font $win $font $xfont
+       set indent [llength $var(indent)]
+       incr indent -1
+       lappend tags $font indent$indent
+       foreach tag [array names var T*] {
+               lappend tags [lindex $var($tag) end]    ;# test
+       }
+       set var(font) $font
+       set var(xfont) [$win tag cget $font -font]
+       set var(level) $indent
+       return $tags
+}
+
+# allow the application to do do better font management
+# by overriding this procedure
+
+proc HMset_font {win tag font} {
+       catch {$win tag configure $tag -font $font} msg
+}
+
+# generate an X font name
+proc HMx_font {family size weight style {adjust_size 0}} {
+       catch {incr size $adjust_size}
+       return "-*-$family-$weight-$style-normal-*-*-${size}0-*-*-*-*-*-*"
+}
+
+# Optimize HMrender (hee hee)
+# This is experimental
+
+proc HMoptimize {} {
+       regsub -all "\n\[       \]*#\[^\n\]*" [info body HMrender] {} body
+       regsub -all ";\[        \]*#\[^\n]*" $body {} body
+       regsub -all "\n\n+" $body \n body
+       proc HMrender {win tag not param text} $body
+}
+############################################
+# Turn HTML into TCL commands
+#   html    A string containing an html document
+#   cmd                A command to run for each html tag found
+#   start      The name of the dummy html start/stop tags
+
+proc HMparse_html {html {cmd HMtest_parse} {start hmstart}} {
+       regsub -all \{ $html {\&ob;} html
+       regsub -all \} $html {\&cb;} html
+       set w " \t\r\n" ;# white space
+       proc HMcl x {return "\[$x\]"}
+       set exp <(/?)([HMcl ^$w>]+)[HMcl $w]*([HMcl ^>]*)>
+       set sub "\}\n$cmd {\\2} {\\1} {\\3} \{"
+       regsub -all $exp $html $sub html
+       eval "$cmd {$start} {} {} \{ $html \}"
+       eval "$cmd {$start} / {} {}"
+}
+
+proc HMtest_parse {command tag slash text_after_tag} {
+       puts "==> $command $tag $slash $text_after_tag"
+}
+
+# Convert multiple white space into a single space
+
+proc HMzap_white {data} {
+       regsub -all "\[ \t\r\n\]+" $data " " data
+       return $data
+}
+
+# find HTML escape characters of the form &xxx;
+
+proc HMmap_esc {text} {
+       if {![regexp & $text]} {return $text}
+       regsub -all {([][$\\])} $text {\\\1} new
+       regsub -all {&#([0-9][0-9]?[0-9]?);?} \
+               $new {[format %c [scan \1 %d tmp;set tmp]]} new
+       regsub -all {&([a-zA-Z]+);?} $new {[HMdo_map \1]} new
+       return [subst $new]
+}
+
+# convert an HTML escape sequence into character
+
+proc HMdo_map {text {unknown ?}} {
+       global HMesc_map
+       set result $unknown
+       catch {set result $HMesc_map($text)}
+       return $result
+}
+
+# table of escape characters (ISO latin-1 esc's are in a different table)
+
+array set HMesc_map {
+   lt <   gt >   amp &   quot \"   copy \xa9
+   reg \xae   ob \x7b   cb \x7d   nbsp \xa0
+}
+#############################################################
+# ISO Latin-1 escape codes
+
+array set HMesc_map {
+       nbsp \xa0 iexcl \xa1 cent \xa2 pound \xa3 curren \xa4
+       yen \xa5 brvbar \xa6 sect \xa7 uml \xa8 copy \xa9
+       ordf \xaa laquo \xab not \xac shy \xad reg \xae
+       hibar \xaf deg \xb0 plusmn \xb1 sup2 \xb2 sup3 \xb3
+       acute \xb4 micro \xb5 para \xb6 middot \xb7 cedil \xb8
+       sup1 \xb9 ordm \xba raquo \xbb frac14 \xbc frac12 \xbd
+       frac34 \xbe iquest \xbf Agrave \xc0 Aacute \xc1 Acirc \xc2
+       Atilde \xc3 Auml \xc4 Aring \xc5 AElig \xc6 Ccedil \xc7
+       Egrave \xc8 Eacute \xc9 Ecirc \xca Euml \xcb Igrave \xcc
+       Iacute \xcd Icirc \xce Iuml \xcf ETH \xd0 Ntilde \xd1
+       Ograve \xd2 Oacute \xd3 Ocirc \xd4 Otilde \xd5 Ouml \xd6
+       times \xd7 Oslash \xd8 Ugrave \xd9 Uacute \xda Ucirc \xdb
+       Uuml \xdc Yacute \xdd THORN \xde szlig \xdf agrave \xe0
+       aacute \xe1 acirc \xe2 atilde \xe3 auml \xe4 aring \xe5
+       aelig \xe6 ccedil \xe7 egrave \xe8 eacute \xe9 ecirc \xea
+       euml \xeb igrave \xec iacute \xed icirc \xee iuml \xef
+       eth \xf0 ntilde \xf1 ograve \xf2 oacute \xf3 ocirc \xf4
+       otilde \xf5 ouml \xf6 divide \xf7 oslash \xf8 ugrave \xf9
+       uacute \xfa ucirc \xfb uuml \xfc yacute \xfd thorn \xfe
+       yuml \xff
+}
+
+##########################################################
+# html forms management commands
+
+# As each form element is located, it is created and rendered.  Additional
+# state is stored in a form specific global variable to be processed at
+# the end of the form, including the "reset" and "submit" options.
+# Remember, there can be multiple forms existing on multiple pages.  When
+# HTML tables are added, a single form could be spread out over multiple
+# text widgets, which makes it impractical to hang the form state off the
+# HM$win structure.  We don't need to check for the existance of required
+# parameters, we just "fail" and get caught in HMrender
+
+# This causes line breaks to be preserved in the inital values
+# of text areas
+array set HMtag_map {
+       textarea    {fill 0}
+}
+
+##########################################################
+# html isindex tag.  Although not strictly forms, they're close enough
+# to be in this file
+
+# is-index forms
+# make a frame with a label, entry, and submit button
+
+proc HMtag_isindex {win param text} {
+       upvar #0 HM$win var
+
+       set item $win.$var(tags)
+       if {[winfo exists $item]} {
+               destroy $item
+       }
+       frame $item -relief ridge -bd 3
+       set prompt "Enter search keywords here"
+       HMextract_param $param prompt
+       label $item.label -text [HMmap_esc $prompt] -font $var(xfont)
+       entry $item.entry
+       bind $item.entry <Return> "$item.submit invoke"
+       button $item.submit -text search -font $var(xfont) -command \
+               [format {HMsubmit_index %s {%s} [HMmap_reply [%s get]]} \
+               $win $param $item.entry]
+       pack $item.label -side top
+       pack $item.entry $item.submit -side left
+
+       # insert window into text widget
+
+       $win insert $var(S_insert) \n isindex
+       HMwin_install $win $item
+       $win insert $var(S_insert) \n isindex
+       bind $item <Visibility> {focus %W.entry}
+}
+
+# This is called when the isindex form is submitted.
+# The default version calls HMlink_callback.  Isindex tags should either
+# be deprecated, or fully supported (e.g. they need an href parameter)
+
+proc HMsubmit_index {win param text} {
+       HMlink_callback $win ?$text
+}
+
+# initialize form state.  All of the state for this form is kept
+# in a global array whose name is stored in the form_id field of
+# the main window array.
+# Parameters: ACTION, METHOD, ENCTYPE
+
+proc HMtag_form {win param text} {
+       upvar #0 HM$win var
+
+       # create a global array for the form
+       set id HM$win.form$var(tags)
+       upvar #0 $id form
+
+       # missing /form tag, simulate it
+       if {[info exists var(form_id)]} {
+               puts "Missing end-form tag !!!! $var(form_id)"
+               HMtag_/form $win {} {}
+       }
+       catch {unset form}
+       set var(form_id) $id
+
+       set form(param) $param          ;# form initial parameter list
+       set form(reset) ""                      ;# command to reset the form
+       set form(reset_button) ""       ;# list of all reset buttons
+       set form(submit) ""                     ;# command to submit the form
+       set form(submit_button) ""      ;# list of all submit buttons
+}
+
+# Where we're done try to get all of the state into the widgets so
+# we can free up the form structure here.  Unfortunately, we can't!
+
+proc HMtag_/form {win param text} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       # make submit button entries for all radio buttons
+       foreach name [array names form radio_*] {
+               regsub radio_ $name {} name
+               lappend form(submit) [list $name \$form(radio_$name)]
+       }
+
+       # process the reset button(s)
+
+       foreach item $form(reset_button) {
+               $item configure -command $form(reset)
+       }
+
+       # no submit button - add one
+       if {$form(submit_button) == ""} {
+               HMinput_submit $win {}
+       }
+
+       # process the "submit" command(s)
+       # each submit button could have its own name,value pair
+
+       foreach item $form(submit_button) {
+               set submit $form(submit)
+               catch {lappend submit $form(submit_$item)}
+               $item configure -command  \
+                               [list HMsubmit_button $win $var(form_id) $form(param) \
+                               $submit]
+       }
+
+       # unset all unused fields here
+       unset form(reset) form(submit) form(reset_button) form(submit_button)
+       unset var(form_id)
+}
+
+###################################################################
+# handle form input items
+# each item type is handled in a separate procedure
+# Each "type" procedure needs to:
+# - create the window
+# - initialize it
+# - add the "submit" and "reset" commands onto the proper Q's
+#   "submit" is subst'd
+#   "reset" is eval'd
+
+proc HMtag_input {win param text} {
+       upvar #0 HM$win var
+
+       set type text   ;# the default
+       HMextract_param $param type
+       set type [string tolower $type]
+       if {[catch {HMinput_$type $win $param} err]} {
+               puts stderr $err
+       }
+}
+
+# input type=text
+# parameters NAME (reqd), MAXLENGTH, SIZE, VALUE
+
+proc HMinput_text {win param {show {}}} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       # make the entry
+       HMextract_param $param name             ;# required
+       set item $win.input_text,$var(tags)
+       set size 20; HMextract_param $param size
+       set maxlength 0; HMextract_param $param maxlength
+       entry $item -width $size -show $show
+
+       # set the initial value
+       set value ""; HMextract_param $param value
+       $item insert 0 $value
+               
+       # insert the entry
+       HMwin_install $win $item
+
+       # set the "reset" and "submit" commands
+       append form(reset) ";$item delete 0 end;$item insert 0 [list $value]"
+       lappend form(submit) [list $name "\[$item get]"]
+
+       # handle the maximum length (broken - no way to cleanup bindtags state)
+       if {$maxlength} {
+               bindtags $item "[bindtags $item] max$maxlength"
+               bind max$maxlength <KeyPress> "%W delete $maxlength end"
+       }
+}
+
+# password fields - same as text, only don't show data
+# parameters NAME (reqd), MAXLENGTH, SIZE, VALUE
+
+proc HMinput_password {win param} {
+       HMinput_text $win $param *
+}
+
+# checkbuttons are missing a "get" option, so we must use a global
+# variable to store the value.
+# Parameters NAME, VALUE, (reqd), CHECKED
+
+proc HMinput_checkbox {win param} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       HMextract_param $param name
+       HMextract_param $param value
+
+       # Set the global variable, don't use the "form" alias as it is not
+       # defined in the global scope of the button
+       set variable $var(form_id)(check_$var(tags))    
+       set item $win.input_checkbutton,$var(tags)
+       checkbutton $item -variable $variable -off {} -on $value -text "  "
+       if {[HMextract_param $param checked]} {
+               $item select
+               append form(reset) ";$item select"
+       } else {
+               append form(reset) ";$item deselect"
+       }
+
+       HMwin_install $win $item
+       lappend form(submit) [list $name \$form(check_$var(tags))]
+}
+
+# radio buttons.  These are like check buttons, but only one can be selected
+
+proc HMinput_radio {win param} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       HMextract_param $param name
+       HMextract_param $param value
+
+       set first [expr ![info exists form(radio_$name)]]
+       set variable $var(form_id)(radio_$name)
+       set variable $var(form_id)(radio_$name)
+       set item $win.input_radiobutton,$var(tags)
+       radiobutton $item -variable $variable -value $value -text " "
+
+       HMwin_install $win $item
+
+       if {$first || [HMextract_param $param checked]} {
+               $item select
+               append form(reset) ";$item select"
+       } else {
+               append form(reset) ";$item deselect"
+       }
+
+       # do the "submit" actions in /form so we only end up with 1 per button grouping
+       # contributing to the submission
+}
+
+# hidden fields, just append to the "submit" data
+# params: NAME, VALUE (reqd)
+
+proc HMinput_hidden {win param} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+       HMextract_param $param name
+       HMextract_param $param value
+       lappend form(submit) [list $name $value]
+}
+
+# handle input images.  The spec isn't very clear on these, so I'm not
+# sure its quite right
+# Use std image tag, only set up our own callbacks
+#  (e.g. make sure ismap isn't set)
+# params: NAME, SRC (reqd) ALIGN
+
+proc HMinput_image {win param} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+       HMextract_param $param name
+       set name                ;# barf if no name is specified
+       set item [HMtag_img $win $param {}]
+       $item configure -relief raised -bd 2 -bg blue
+
+       # make a dummy "submit" button, and invoke it to send the form.
+       # We have to get the %x,%y in the value somehow, so calculate it during
+       # binding, and save it in the form array for later processing
+
+       set submit $win.dummy_submit,$var(tags)
+       if {[winfo exists $submit]} {
+               destroy $submit
+       }
+       button $submit  -takefocus 0;# this never gets mapped!
+       lappend form(submit_button) $submit
+       set form(submit_$submit) [list $name $name.\$form(X).\$form(Y)]
+       
+       $item configure -takefocus 1
+       bind $item <FocusIn> "catch \{$win see $item\}"
+       bind $item <1> "$item configure -relief sunken"
+       bind $item <Return> "
+               set $var(form_id)(X) 0
+               set $var(form_id)(Y) 0
+               $submit invoke  
+       "
+       bind $item <ButtonRelease-1> "
+               set $var(form_id)(X) %x
+               set $var(form_id)(Y) %y
+               $item configure -relief raised
+               $submit invoke  
+       "
+}
+
+# Set up the reset button.  Wait for the /form to attach
+# the -command option.  There could be more that 1 reset button
+# params VALUE
+
+proc HMinput_reset {win param} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       set value reset
+       HMextract_param $param value
+
+       set item $win.input_reset,$var(tags)
+       button $item -text [HMmap_esc $value]
+       HMwin_install $win $item
+       lappend form(reset_button) $item
+}
+
+# Set up the submit button.  Wait for the /form to attach
+# the -command option.  There could be more that 1 submit button
+# params: NAME, VALUE
+
+proc HMinput_submit {win param} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       HMextract_param $param name
+       set value submit
+       HMextract_param $param value
+       set item $win.input_submit,$var(tags)
+       button $item -text [HMmap_esc $value] -fg blue
+       HMwin_install $win $item
+       lappend form(submit_button) $item
+       # need to tie the "name=value" to this button
+       # save the pair and do it when we finish the submit button
+       catch {set form(submit_$item) [list $name $value]}
+}
+
+#########################################################################
+# selection items
+# They all go into a list box.  We don't what to do with the listbox until
+# we know how many items end up in it.  Gather up the data for the "options"
+# and finish up in the /select tag
+# params: NAME (reqd), MULTIPLE, SIZE 
+
+proc HMtag_select {win param text} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+
+       HMextract_param $param name
+       set size 5;  HMextract_param $param size
+       set form(select_size) $size
+       set form(select_name) $name
+       set form(select_values) ""              ;# list of values to submit
+       if {[HMextract_param $param multiple]} {
+               set mode multiple
+       } else {
+               set mode single
+       }
+       set item $win.select,$var(tags)
+    frame $item
+    set form(select_frame) $item
+       listbox $item.list -selectmode $mode -width 0 -exportselection 0
+       HMwin_install $win $item
+}
+
+# select options
+# The values returned in the query may be different from those
+# displayed in the listbox, so we need to keep a separate list of
+# query values.
+#  form(select_default) - contains the default query value
+#  form(select_frame) - name of the listbox's containing frame
+#  form(select_values)  - list of query values
+# params: VALUE, SELECTED
+
+proc HMtag_option {win param text} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+       upvar $text data
+       set frame $form(select_frame)
+
+       # set default option (or options)
+       if {[HMextract_param $param selected]} {
+        lappend form(select_default) [$form(select_frame).list size]
+    }
+    set value [string trimright $data " \n"]
+    $frame.list insert end $value
+       HMextract_param $param value
+       lappend form(select_values) $value
+       set data ""
+}
+# do most of the work here!
+# if SIZE>1, make the listbox.  Otherwise make a "drop-down"
+# listbox with a label in it
+# If the # of items > size, add a scroll bar
+# This should probably be broken up into callbacks to make it
+# easier to override the "look".
+
+proc HMtag_/select {win param text} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+       set frame $form(select_frame)
+       set size $form(select_size)
+       set items [$frame.list size]
+
+       # set the defaults and reset button
+       append form(reset) ";$frame.list selection clear 0  $items"
+       if {[info exists form(select_default)]} {
+               foreach i $form(select_default) {
+                       $frame.list selection set $i
+                       append form(reset) ";$frame.list selection set $i"
+               }
+       } else {
+               $frame.list selection set 0
+               append form(reset) ";$frame.list selection set 0"
+       }
+
+       # set up the submit button. This is the general case.  For single
+       # selections we could be smarter
+
+       for {set i 0} {$i < $size} {incr i} {
+               set value [format {[expr {[%s selection includes %s] ? {%s} : {}}]} \
+                               $frame.list $i [lindex $form(select_values) $i]]
+               lappend form(submit) [list $form(select_name) $value]
+       }
+       
+       # show the listbox - no scroll bar
+
+       if {$size > 1 && $items <= $size} {
+               $frame.list configure -height $items
+               pack $frame.list
+
+       # Listbox with scrollbar
+
+       } elseif {$size > 1} {
+               scrollbar $frame.scroll -command "$frame.list yview"  \
+                               -orient v -takefocus 0
+               $frame.list configure -height $size \
+                       -yscrollcommand "$frame.scroll set"
+               pack $frame.list $frame.scroll -side right -fill y
+
+       # This is a joke!
+
+       } else {
+               scrollbar $frame.scroll -command "$frame.list yview"  \
+                       -orient h -takefocus 0
+               $frame.list configure -height 1 \
+                       -yscrollcommand "$frame.scroll set"
+               pack $frame.list $frame.scroll -side top -fill x
+       }
+
+       # cleanup
+
+       foreach i [array names form select_*] {
+               unset form($i)
+       }
+}
+
+# do a text area (multi-line text)
+# params: COLS, NAME, ROWS (all reqd, but default rows and cols anyway)
+
+proc HMtag_textarea {win param text} {
+       upvar #0 HM$win var
+       upvar #0 $var(form_id) form
+       upvar $text data
+
+       set rows 5; HMextract_param $param rows
+       set cols 30; HMextract_param $param cols
+       HMextract_param $param name
+       set item $win.textarea,$var(tags)
+       frame $item
+       text $item.text -width $cols -height $rows -wrap none \
+                       -yscrollcommand "$item.scroll set" -padx 3 -pady 3
+       scrollbar $item.scroll -command "$item.text yview"  -orient v
+       $item.text insert 1.0 $data
+       HMwin_install $win $item
+       pack $item.text $item.scroll -side right -fill y
+       lappend form(submit) [list $name "\[$item.text get 0.0 end]"]
+       append form(reset) ";$item.text delete 1.0 end; \
+                       $item.text insert 1.0 [list $data]"
+       set data ""
+}
+
+# procedure to install windows into the text widget
+# - win:  name of the text widget
+# - item: name of widget to install
+
+proc HMwin_install {win item} {
+       upvar #0 HM$win var
+       $win window create $var(S_insert) -window $item -align bottom
+       $win tag add indent$var(level) $item
+       set focus [expr {[winfo class $item] != "Frame"}]
+       $item configure -takefocus $focus
+       bind $item <FocusIn> "$win see $item"
+}
+
+#####################################################################
+# Assemble and submit the query
+# each list element in "stuff" is a name/value pair
+# - The names are the NAME parameters of the various fields
+# - The values get run through "subst" to extract the values
+# - We do the user callback with the list of name value pairs
+
+proc HMsubmit_button {win form_id param stuff} {
+       upvar #0 HM$win var
+       upvar #0 $form_id form
+       set query ""
+       foreach pair $stuff {
+               set value [subst [lindex $pair 1]]
+               if {$value != ""} {
+                       set item [lindex $pair 0]
+                       lappend query $item $value
+               }
+       }
+       # this is the user callback.
+       HMsubmit_form $win $param $query
+}
+
+# sample user callback for form submission
+# should be replaced by the application
+# Sample version generates a string suitable for http
+
+proc HMsubmit_form {win param query} {
+       set result ""
+       set sep ""
+       foreach i $query {
+               append result  $sep [HMmap_reply $i]
+               if {$sep != "="} {set sep =} {set sep &}
+       }
+       puts $result
+}
+
+# do x-www-urlencoded character mapping
+# The spec says: "non-alphanumeric characters are replaced by '%HH'"
+set HMalphanumeric     a-zA-Z0-9       ;# definition of alphanumeric character class
+for {set i 1} {$i <= 256} {incr i} {
+    set c [format %c $i]
+    if {![string match \[$HMalphanumeric\] $c]} {
+        set HMform_map($c) %[format %.2x $i]
+    }
+}
+
+# These are handled specially
+array set HMform_map {
+    " " +   \n %0d%0a
+}
+
+# 1 leave alphanumerics characters alone
+# 2 Convert every other character to an array lookup
+# 3 Escape constructs that are "special" to the tcl parser
+# 4 "subst" the result, doing all the array substitutions
+proc HMmap_reply {string} {
+    global HMform_map HMalphanumeric
+    regsub -all \[^$HMalphanumeric\] $string {$HMform_map(&)} string
+    regsub -all \n $string {\\n} string
+    regsub -all \t $string {\\t} string
+    regsub -all {[][{})\\]\)} $string {\\&} string
+    return [subst $string]
+}
+
+# convert a x-www-urlencoded string int a a list of name/value pairs
+
+# 1  convert a=b&c=d... to {a} {b} {c} {d}...
+# 2, convert + to  " "
+# 3, convert %xx to char equiv
+
+proc HMcgiDecode {data} {
+       set data [split $data "&="]
+       foreach i $data {
+               lappend result [cgiMap $i]
+       }
+       return $result
+}
+
+proc HMcgiMap {data} {
+       regsub -all {\+} $data " " data
+       
+       if {[regexp % $data]} {
+               regsub -all {([][$\\])} $data {\\\1} data
+               regsub -all {%([0-9a-fA-F][0-9a-fA-F])} $data  {[format %c 0x\1]} data
+               return [subst $data]
+       } else {
+               return $data
+       }
+}
+
+# There is a bug in the tcl library focus routines that prevents focus
+# from every reaching an un-viewable window.  Use our *own*
+# version of the library routine, until the bug is fixed, make sure we
+# over-ride the library version, and not the otherway around
+
+auto_load tkFocusOK
+proc tkFocusOK w {
+    set code [catch {$w cget -takefocus} value]
+    if {($code == 0) && ($value != "")} {
+    if {$value == 0} {
+        return 0
+    } elseif {$value == 1} {
+        return 1
+    } else {
+        set value [uplevel #0 $value $w]
+        if {$value != ""} {
+        return $value
+        }
+    }
+    }
+    set code [catch {$w cget -state} value]
+    if {($code == 0) && ($value == "disabled")} {
+    return 0
+    }
+    regexp Key|Focus "[bind $w] [bind [winfo class $w]]"
+}
diff --git a/tcl/hypermap b/tcl/hypermap
new file mode 100755 (executable)
index 0000000..27f0bb4
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/bin/wish8.0
+
+package require Fgis
+
+proc loadfile {file} {
+    global basename namestack
+    if [info exist basename] {
+        set file [file join [file dirname $basename] $file]
+        if [info exist namestack] {
+           set namestack [concat [list $basename] $namestack]
+        } else {
+           set namestack [list $basename]
+       }
+    } 
+    if [file exist $file] {
+       set f [open $file]
+       set text [read $f]
+       close $f
+       set basename $file
+       return $text
+    } else {
+       return "<HTML><HEAD><TITLE>File not found</TITLE></HEAD>\
+       <BODY><H1>File not found</H1>File $file cannot be\
+       read</BODY></HTML>"
+    }
+}    
+proc hyper_window {text} {
+  if {[wm state .hyperleg] != "normal"} {
+     wm deiconify .hyperleg
+  } else {
+     raise .hyperleg
+  }
+  HMreset_win .hyperleg.t
+  HMparse_html $text "HMrender .hyperleg.t"
+}  
+
+proc show_hyper {planchet x y} {
+  global main_layer basename namestack
+  catch { unset basename}
+  catch {unset namestack}
+  set value [$main_layer value [$planchet mapx $x]  [$planchet mapy $y] -raw]
+  if [string length $value] {
+     hyper_window [loadfile $value]
+  } else {
+     hyper_window "<HTML>\n\
+     <HEAD><TITLE>No info avalable</TITLE></HEAD>\n\
+     <BODY>\n\
+     <H1>No info avalable</H1>\n\
+     There is no information on this point\n\
+     </BODY>\n\
+     </HTML>"
+  }   
+}     
+     
+    
+set planchet .map
+option add *font -cronyx-times-bold-r-normal--10-*
+frame .menu -relief raised -bd 2
+menubutton .menu.file -text "File" -menu [set m .menu.file.m]
+menu $m
+#$m add command -label "Open..." -command add_layer
+#$m add command -label "Save..." -state disabled -command {save_layer [select_layer]}
+#$m add command -label "Close..." -state disabled -command {close_layer [select_layer]}
+#$m add separator
+$m add command -label "Print..." -command [list fgisPrintDialog $planchet] 
+$m add separator
+$m add command -label "Quit" -command confirmExit
+menubutton .menu.layer -text "Layer" -menu [set m .menu.layer.m]
+menu $m
+$m add command -label "Show..." -command {show_layer [select_layer] } -state disabled
+$m add command -label "Look..." -command select_layers -state disabled
+#$m add command -label "Properties..." -command {edit_layer [select_layer]} -state disabled
+pack .menu.file .menu.layer -side left
+pack .menu -side top -expand y -fill x
+label .status -anchor w
+planchet $planchet -width 640 -height 480 -status .status
+toolbar .tool $planchet 
+pack .tool -expand y -fill x
+pack $planchet 
+pack .status -expand y -fill x
+
+
+button .tool.layer -text "?" -command add_layer
+pack .tool.layer -side left -before .tool.scale
+wm protocol . WM_DELETE_WINDOW confirmExit
+
+toplevel .hyperleg 
+text .hyperleg.t -wrap word -width 80 -height 40 -yscrollcommand\
+       ".hyperleg.y set" 
+scrollbar .hyperleg.y -orient vert -command ".hyperleg.t yview"
+grid .hyperleg.t .hyperleg.y -sticky news
+wm protocol .hyperleg WM_DELETE_WINDOW {wm withdraw .hyperleg}
+wm withdraw .hyperleg
+HMinit_win .hyperleg.t
+bind $planchet <Button-1> {show_hyper $planchet %x %y}
+
+#
+# Define callbacks for html library. Should be done here
+# when html library alderady loaded
+proc HMlink_callback {win href} {
+    HMreset_win $win
+    HMparse_html [loadfile $href ] "HMrender $win"
+}   
+proc HMset_image {win handle src} {
+  global basename
+  if [info exist basename] {
+     set src [file join [file dirname $basename] $src]
+  }  
+  if [file exists $src] {
+    set img [image create photo -file $src]
+    HMgot_image $handle $img
+  }
+}  
+
+proc hyper_layer {file legend} {
+   global main_layer
+   if ![file exists $file] {
+      if [file exists $file.epp] {
+         append file .epp
+      } else {
+         tk_messageBox -message "File $filename doesn't exists" -type ok
+         return
+      }
+   }
+   if ![file exists $legend] {
+       if [file exists $legend.leg] {
+           append legend .leg
+       } else {
+           tk_messageBox -message "File $legend doesn't exists" -type ok
+           return
+       }
+   }
+   set main_layer [layer create raster -file $file -legfile $legend]
+}   
+
+source [lindex $argv 0] 
diff --git a/tcl/layer.tcl b/tcl/layer.tcl
new file mode 100644 (file)
index 0000000..a5d1825
--- /dev/null
@@ -0,0 +1,567 @@
+#
+# layers.tcl 
+# Implements high level layer object 
+# This file is part of fGIS
+#
+
+# Global variable fgisLayerTypes - keeps names of constructor procedures
+# for all defined layer types
+
+array set fgisLayerTypes {
+raster fgisCreateRaster
+chart  fgisCreateChart
+tag    fgisCreateTag
+}
+
+# proc layer - create layer or query information about all layers
+# usage:  
+# layer create type ?name? ?-option value...? - returns name of layer.
+# layer names ?pattern? ?-type type? - returns names of all matching layers
+# layer types  - list available layer types
+# layer type name - return type of given layer
+
+proc layer {option args} {
+global fgisLayerTypes fgisLayerList
+switch -exact -- $option {
+   create { 
+      if ![llength $args] {
+          return -code error "usage: layer create ?name? ?options?"
+      }
+      set tname [lindex $args 0]
+      set type [array names fgisLayerTypes $tname*]
+      switch [llength $type] {
+         1 { # type good - call constructor
+             # drop layer type from args
+             set args [lreplace $args 0 0]
+             # if layer name not supplied, generate one
+             if {![llength $args]||[string match -* [lindex $args 0]]} {
+                 set args [linsert $args 0 [fgisMakeObjectName layer]]
+             } elseif {![fgisCheckName [lindex $args 0]]} {
+                 return -code error "Name \"[lindex $args 0]\" already used"
+             }
+              
+             if [catch [concat $fgisLayerTypes($type) $args] name] {
+                return -code error $name
+             } else {
+                set fgisLayerList($name) $type
+                return $name
+             }
+         }
+         0 { # No matching type found
+             return -code error "Invalid layer type. Should be one of\
+                [join [array names fgisLayerTypes] ", "]"
+         }
+         default { # Too many matching types found
+             return -code error "Ambiquous layer type \"$tname\": $type"
+         }  
+      }
+   }
+  types { # Return list of available types
+     return [array names fgisLayerTypes]
+  }
+  names { # Return list of names
+      if {[llength $args]&&![string match -* [lindex $args 0]]} {
+          # extract glob pattern from arguments
+          set pattern [lindex $args 0]
+          set args [lreplace $args 0 0]
+      } else { # no pattern supplied, use *
+          set pattern * 
+      }
+      if ![llength $args] { # if no other args, return all matching names
+         return [array names fgisLayerList $pattern]
+      } elseif {[llength $args]!=2} { 
+         #check if args are -type list
+         return -code error "wrong # args. should be \"layer names ?pattern?\
+                 ?-type type?\""
+      } elseif {![string match [lindex $args 0]* -type]} {
+         return -code error "wrong option. should be -type"
+      } else {
+         # first, check if all types in list are good
+         # and create array to lookup matching types
+         foreach type [lindex $args 1] {
+           if ![info exists fgisLayerTypes($type)] {
+              return -code error "Invalid layer type \"$type\""
+           }
+           set tmp($type) 1
+         }
+         # then scan list of layers
+        set result {}
+        foreach {name type} [array get fgisLayerList $pattern] {
+           if [info exists tmp($type)] {
+              lappend result $name
+           }
+        }
+        return $result
+     }
+  } 
+  type { # return type of given layer
+         if ![info exists fgisLayerList($args)] {
+             return -code error "Layer $args doesn't exists"
+         } else {
+             return $fgisLayerList($args)
+         }
+  } 
+  exist -
+  exists {
+     if [llength $args]!=1 {
+        return -code error "wrong # args. should be: layer exist name"
+     }
+     return [info exists fgisLayerList([lindex $args 0])]
+  }
+  default { # unrecognized command
+      return -code error "Invalid option. should be one of create, exists,\
+            names, type, types"
+  } 
+}
+}
+
+#
+# Calls method of layer object. Searches in the global array
+# fgisLayerMethods for index "type,method", and, if found, executes it.
+#
+;proc fgisLayerEval {type method object args} {
+   global fgisLayerMethods
+   # get list of methods of type, which match given method name
+   set methods [array names fgisLayerMethods $type,$method*]
+   switch -exact [llength $methods] {
+   0 { # no applicable methods
+       set msg {} 
+       foreach i [array names fgisLayerMethods $type,*] {
+          lappend msg [lindex [split $i ","] 1]
+       }
+       return -code error "Unknown option. should be one of [join $msg ", "]"
+   }
+   1 { 
+       eval $fgisLayerMethods($methods) $object $args 
+   }
+   default { 
+      return -code error "Ambiquous option \"$method\""
+   }
+}
+}
+#
+# creates instance command for layer
+#
+#
+#
+;proc fgisLayerDefine {type object} {
+    global fgisLayerMethods
+    ;proc $object {option args} " 
+ if \[catch {eval fgisLayerEval $type \$option $object \$args} res] {
+    return -code error \$res
+ } else {
+    return \$res
+ }
+"
+}
+#
+# copies name of old object methods to new one
+#
+;proc fgisLayerInherit {father son} {
+   global fgisLayerMethods
+   # copy virtual method table
+   foreach {name value} [array get fgisLayerMethods $father,*] {
+        set fgisLayerMethods($son,[lindex [split $name ","] 1]) $value
+   }
+   # copy field template
+   global fgis${father}Fields fgis${son}Fields
+   array set fgis${son}Fields [array get fgis${father}Fields]
+}
+#
+# Common methods for all layers
+#
+
+#
+# return various info for layer
+#
+;proc fgisLayerInfo {name args} {
+  upvar #0 $name data
+  if [llength $args]!=1 {
+     return -code error "wrong # of args. should be $name info option"
+  }
+  set goodopt {opaque lookable legend limits numeric dimension reclass}
+  if [set idx [lsearch -glob $goodopt $args*]]==-1 {
+     return -code error "invalid option. should be one of [join $goodopt ", "]"
+  }
+  set key [lindex $goodopt $idx]
+  switch -exact $key {
+      legend { 
+        return [expr {[info exist data(legend)]&&[$data(legend) drawable]}]
+      }
+      default {
+        return $data($key)
+      }
+  }
+}
+#
+# Two procedures, which return title and subtitle
+#
+;proc fgisLayerTitle {name args} {
+if [llength $args] {
+  return -code error "wrong # args. should be $name title"
+}
+upvar #0 $name data
+if [info exists data(title)] {
+  return $data(title)
+} else {
+  return $name
+}
+}
+;proc fgisLayerSubtitle {name args} {
+if [llength $args] {
+  return -code error "wrong # args. should be $name title"
+}
+upvar #0 $name data
+if [info exists data(subtitle)] {
+  return $data(subtitle)
+} else {
+  return 
+}
+}
+# 
+# raster layers 
+#
+# table of methods
+array set fgisLayerMethods {
+raster,info fgisLayerInfo
+raster,dump fgisRasterDump
+raster,value fgisRasterValue
+raster,show fgisRasterShow
+raster,hide fgisRasterHide
+raster,configure fgisRasterConfigure
+raster,cget fgisRasterCget
+raster,legclasses fgisRasterLegClasses
+raster,sample fgisRasterSample
+raster,legtext fgisRasterLegtext
+raster,title fgisLayerTitle
+raster,subtitle fgisLayerSubtitle
+raster,delete fgisRasterDelete
+raster,expand fgisRasterExpand
+raster,limits fgisRasterLimits
+raster,redraw fgisRasterRedraw
+}
+# table of fields (more precisely - template of default values
+array set fgisRasterFields {
+opaque 1
+lookable 1
+limits 1
+numeric 0
+dimension 2
+reclass 1
+palette defaultpalette
+plotmode -patterns
+border none
+ovrborder yes
+ovrcolor black
+patterns {}
+title {}
+subtitle {}
+}
+# Other fields exist only in runtime
+# legend - holds name of legend object
+# raster - holds name of raster object
+
+# constructor of raster layer.
+# Options available
+# to specify raster 
+# -raster - recieves handle of raster object
+# -file - recieves epp file
+# to specify reclass
+# -reclass statements -recieves reclass in EPPL-like syntax
+# -table list - recieves reclass as Tcl list
+# to specify legend
+# -legend - recieves legend object handle
+# -legfile - recieves legend file
+# Appearance
+# -palette - recieves palette object
+# -palfile - recieves palette file
+# -patterns - recieves pattern object
+# -symbols - recieves pattern object and switches mode do symbols
+# -borders - recieves none yes or base. Controls opaque mode
+# -ovrborders - same for transparent mode
+# -ovrcolor - color for transparent drawing
+#
+#
+;proc fgisCreateRaster {name args} {
+   upvar #0 $name data
+   global fgisRasterFields
+   array set data [array get fgisRasterFields]
+   eval fgisRasterConfigure $name $args
+   if ![info exists data(raster)] { 
+      error "No raster specified"
+   }
+   fgisLayerDefine raster $name
+   return $name
+}
+#
+# Three small procedures to create object from file.
+# They are needed becouse handleopt doesn't allow ] after option value
+#
+;proc fgisOpenEppFile {filename} {
+  set raster [raster $filename]
+  uplevel fgisSetObj data(raster) nodefault $raster
+}
+;proc fgisOpenLegFile {filename} {
+  uplevel fgisSetObj data(legend) none [legend read $filename]
+}
+;proc fgisOpenClrFile {filename} {
+  uplevel fgisSetObj data(palette) defaultpalette [palette read $filename]
+}
+#
+# All done via handleopt. Only validity of border flags are checked
+# afterward
+#
+;proc fgisRasterConfigure {name args} {
+   upvar #0 $name data
+   array set handlers {
+      raster {set redraw 1; set data(raster) }
+      file {set redraw 1; fgisOpenEppFile}
+      reclass {set redraw 1; $data(raster) reclass}
+      table {set redraw 1; $data(raster) reclass -table}
+      legend {fgisSetObj data(legend) none}
+      legfile {fgisOpenLegFile} 
+      palette {set redraw 1; fgisSetObj data(palette) defaultpalette}
+      palfile {set redraw 1; fgisOpenClrFile}
+      patterns {set redraw 1
+                set data(plotmode) -patterns
+                fgisSetObj  data(patterns) {} }
+      symbols {set redraw 1
+              set data(plotmode) -symbols
+              fgisSetObj data(patterns) {}}
+      border {set redraw 1;fgisSetList data(border) {none yes base}}
+      ovrborder {set redraw 1;fgisSetList data(ovrborder) {none yes base}}
+      ovrcolor {set redraw 1;set data(ovrcolor)}
+      title {set data(title)}
+      subtitle {set data(subtitle)}
+   }
+   set redraw 0 
+   handleopt handlers $args
+   set data(numeric) [expr ![info exists data(legend)]]
+   if $redraw {
+      foreach planchet [array names data .*] {
+        fgisRasterRedraw $name $planchet
+      }
+   }
+   return
+}
+#
+# Return values of certain instance variables,
+# or state information, corresponding to given configuration options
+# See list below.
+#
+;proc fgisRasterCget {name args} {
+if [llength $args]!=1 {
+  return -code error "wrong # args. should be $name cget option"
+}
+if [checklistopt args {-raster -reclass -table -palette -patterns -symbols
+   -legend -border -ovrborder -ovrcolor -title -subtitle -file} msg] {
+   return -code error $msg
+}
+upvar #0 $name data
+switch -exact -- $args {
+    -file { return [$data(raster) filename] }
+    -table { return [$data(raster) reclass]}
+    -reclass {return [$data(raster) reclass -statements]}
+    -symbols -
+    -patterns { 
+       if {$data(plotmode)=="$args"} {
+         return $data(patterns)
+       } else {
+         return 
+       }
+    }
+    default { 
+       regexp -- {-(.*)} $args junk index
+       if [info exists data($index)] {
+         return $data($index)
+       } else { 
+        return
+       }
+    }
+}
+}
+#
+# Returns Tcl script, which creates same layer
+#
+;proc fgisRasterDump {name args} {
+  if [llength $args] {
+     return -code error "wrong # args. should be $name dump"
+  }
+  upvar #0 $name data
+  set opts ""
+  append result "#fGIS Layer file. Layer type: raster\n"
+  if [string length $data(title)] {
+     append result "# Layer: $data(title)\n"
+  }
+  # dumping raster
+  append result "set _raster_ \[raster [$data(raster) filename]"
+  if [string length [set reclass [$data(raster) reclass -statements]]] {
+    append result " -reclass [list $reclass]"
+  }
+  append result "\]\n"
+  # dumping legend
+  if [info exists data(legend)] {
+    append result "set _legend_ \[legend parse [list [$data(legend) print]]]\n"
+    append opts "-legend \$_legend_"
+  }
+  # dumping palette
+  if {$data(palette)!="defaultpalette"} {
+    append result "set _palette_ \[palette set [list [$data(palette) list]]]\n"
+    append opts " -palette \$_palette_"
+  }
+  # dumping patterns
+  if {[string length $data(patterns)]} {
+    append result "set _patterns_ \[patterns set [list \
+             [$data(patterns) list]]]\n"
+    append opts " $data(plotmode) \$_patterns_"
+  }
+  if {[info exists $data(subtitle)]&&[string length $data(subtitle)]} {
+    append opts " -title [list $data(subtitle)]"
+  }
+  # finally, creating layer command
+  append result "layer create raster -raster \$_raster_\\
+    -border $data(border) -ovrborder $data(ovrborder) -ovrcolor\
+    $data(ovrcolor)\\
+    -title [list $data(title)]\\
+    $opts\n"
+  return $result
+}
+  
+
+# Destroys raster, destroys legend, if exists
+# destroys palette, if it is not defaultpalette,
+# destroys patterns if they are not empty
+#
+;proc fgisRasterDelete {name args} {
+  if [llength $args] {
+    return -code error "wrong # args. should be $name delete"
+  }
+  upvar #0 $name data
+  foreach planchet [array names data ".*"] {
+     $planchet hide $name
+  }
+  $data(raster) delete
+  if [info exists data(legend)] {
+     $data(legend) delete
+  }
+  if {$data(palette)!="defaultpalette"} {
+     $data(palette) delete
+  }
+  if [string length $data(patterns)] {
+      $data(patterns) delete
+  }
+  unset data
+  rename $name {}
+  uplevel #0 unset fgisLayerList($name)
+}
+#
+# Redraws layer accodring to information, created by show
+#
+;proc fgisRasterRedraw {name args} {
+    if [llength $args]!=1 {
+      return -code error "Wrong # args. should be $name redraw planchet"
+    }
+    upvar #0 $name data
+    if {![winfo exists $args]||[winfo class $args]!="Canvas"} {
+      return -code error "Invalid planchet $args"
+    }
+    if ![info exists data($args)] {
+      return -code error "Layer $name is not shown on planchet $args"
+    }
+    eval $data($args)
+}
+#
+# Forget, that we was visible in planchet
+#
+;proc fgisRasterHide {name args} {
+    upvar \#0 $name data
+    if ![info exists data($args)] {
+      return -code error "Layer $name is not shown on planchet $args"
+    }
+    unset data($args)
+}
+#
+# Prepares to show itself in planchet
+#     
+;proc fgisRasterShow {name args} {
+    if [llength $args]!=2 {
+      return -code error "Wrong # args. should be $name planchet mode"
+    }
+    set planchet [lindex $args 0]
+    set mode [lindex $args 1]
+    upvar #0 $name data
+    if {![winfo exists $planchet]||[winfo class $planchet]!="Canvas"} {
+      return -code error "Invalid planchet $args"
+    }
+    switch -exact -- $mode {
+    -base { 
+        set item [$planchet create image 0 0 -anchor nw \
+               -image [image create photo -width [winfo reqwidth $planchet]\
+                          -height [winfo reqheight $planchet]] -tags $name]
+        set data($planchet) "fgisRasterColorImage $data(raster) $planchet\
+               $item -border \$data(border) -palette \$data(palette)"
+        $planchet lower $item
+    }
+    -overlay {
+        set item [$planchet create image 0 0 -anchor nw \
+               -image [image create bitmap -width [winfo reqwidth $planchet]\
+                          -height [winfo reqheight $planchet]] -tags $name]
+        set data($planchet) "fgisRasterBWImage $data(raster) $planchet\
+               $item -border \$data(ovrborder) \$data(plotmode)\
+               \$data(pattern) -color $data(ovrcolor)"
+    }
+    default {
+       return -code error "Invalid option. should be either -base or -overlay"
+    }
+    }
+}
+#
+# Returns value of layer (with legend etc)
+#
+;proc fgisRasterValue {name args} {
+   set n [llength $args]
+   if {$n<2||$n>3} {
+      return -code error "wrong # args. should be $name value x y ?option?"
+   } elseif {$n==3} {
+      set flag [lindex $args 2]
+      set goodopt {-raw -list -titled}
+      if [set ind [lsearch -glob $goodopt $flag*]]!=-1 {
+         set flag [lindex $goodopt $ind]
+      } else {
+         return -code error "invalid option. should be one of [join goodopt ","]"
+      }
+   } else {
+      set flag -raw
+   }
+   upvar #0 $name data
+   set value [$data(raster) get [lindex $args 0] [lindex $args 1]]
+   if {$value==[$data(raster) offsite]} return
+   if [info exist data(legend)] {
+      set value [$data(legend) get $value]
+   }
+   switch -exact -- $flag {
+   -raw {return $value}
+   -list {return [list $name $value]}
+   -titled {return "[fgisLayerTitle $name]: $value"}
+   }
+}   
+#
+# Returns limits of raster (planchets are very interested in this)
+#
+;proc fgisRasterLimits {name args} {
+  if [llength $args] {
+    return -code error "wrong # args. should be $name limits"
+  }
+  upvar #0 $name data
+  return [$data(raster) limits]
+}
+
+# 
+# chart layers
+#
+fgisLayerInherit raster chart
+array set fgisLayerMethods {
+chart,dump fgisChartDump
+chart,value fgisChartValue
+chart,configure fgisChartConfigure
+}
diff --git a/tcl/legend.tcl b/tcl/legend.tcl
new file mode 100644 (file)
index 0000000..fe8aeb8
--- /dev/null
@@ -0,0 +1,136 @@
+proc legend {command name} {
+switch -exact $command {
+read {set f [open $name]
+      set string [read -nonewline $f]
+      close $f
+      return [legend parse $string]
+     }
+parse { set legname [fgisMakeObjectName legend "info exists"]
+        upvar \#0 $legname data
+        foreach line [split $name "\n"] {
+            if ![string length $line] continue
+           if ![regexp {^ *(-?[0-9]+) [^ ]* (.*)$} $line junk a b] {
+                 error "Error in legend format"
+            }
+            if {$a==-1} {set a subtitle} elseif {$a==-2} {set a title
+            } elseif {$a<0||$a>65535} {error "Invalid class code $a"}
+            if [ info exists data($a)] {
+                append data($a) " " $b
+            } else { set data($a) $b }
+        } 
+      }     
+set { 
+      set legname [fgisMakeObjectName legend "info exists"]
+      upvar \#0 $legname data 
+      array set data $name
+   }
+default { error "Invalid option. Should be one of set read parse"}
+}
+proc $legname {option args} "eval fgisLegend_\$option $legname \$args"
+return $legname
+}
+;proc fgisLegend_list {name args} {
+   global $name
+   eval array get $name $args
+}
+;proc fgisLegend_get {name class} { 
+      global  fgis
+      upvar \#0 $name data
+      if ![info exists data($class)] {
+         return $fgis(undefined_legend)
+      } else {
+        return  $data($class)
+      } 
+}
+;proc fgisLegend_classes {name} {
+      global $name
+      return [lsort -integer [array names $name {[0-9]*}]]
+        }
+proc fgisLegend_title {name args} {
+  upvar #0 $name data
+  if [llength $args] {
+       set data(title) [lindex $args 0]
+  } elseif [info exists data(title)] {
+      return  $data(title)
+  } else { return }
+} 
+proc fgisLegend_subtitle {name args} { 
+  upvar #0 $name data
+  if [llength $args] {
+       set data(subtitle) [lindex $args 0]
+  } elseif [info exists data(subtitle)] {
+     return  $data(subtitle)
+  } else return
+}             
+proc fgisLegend_print {name args} { 
+upvar \#0 $name data
+    if [info exists data(title)] {
+       set text "-2  $data(title)\n"
+    }
+    if [info exists data(subtitle)] {
+            append text "-1  $data(subtitle)\n"
+    }
+    foreach i [fgisLegend_classes $name] {
+       append text "$i  $data($i)\n"
+    }
+    if {"$args"=="-nonewline"} {
+       return [string trim $text "\n"]
+    } else {
+        return $text
+    }
+} 
+proc fgisLegend_set {name class value} {
+      global $name
+      set $name\($class) $value 
+}
+proc fgisLegend_drawable {name args} { 
+   global $name
+   if ![llength $args] {
+      return [expr ![info exists $name\(nodraw)]]
+   } else  {
+     if [lindex $args 0] {
+       catch {unset $name\(nodraw)}
+     } else {
+       set $name\(nodraw) 1
+     }
+    return
+  }
+}
+
+proc fgisLegend_delete {name} {
+uplevel #0 unset $name
+rename $name {}
+}
+
+proc show_legend {y canvas legend boxcmd} {
+global fgis_font
+set wraplength [expr [$canvas cget -width]-[$canvas canvasx 1c]]
+set boxwidth [expr [$canvas canvasy 4m]-[$canvas canvasy 0m]]
+global $legend
+if [info exists $legend\(title)] {
+  set item [$canvas create text [expr [$canvas cget -width]/2] $y -anchor n\
+          -justify center -width [$canvas cget -width] \
+           -text [set $legend\(title)] -tags title -font $fgis_font(3)]
+  set y [expr [lindex [$canvas bbox $item] 3]+2]
+}
+
+if [info exists $legend\(subtitle)] {
+   set item [$canvas create text 0 $y -anchor nw -justify left\
+           -width [$canvas cget -width] -text [set $legend\(subtitle)]\
+          -tags subtitle -font $fgis_font(2)]
+  set y [expr [lindex [$canvas bbox $item] 3]+2]
+}
+
+foreach i [$legend classes] {
+    eval $boxcmd  $canvas 0 $y 7m [expr $y+$boxwidth] $i
+    $canvas create text 1c $y -anchor nw -justify left -width $wraplength\
+           -text [set $legend\($i)] -tags class$i -font $fgis_font(1)
+    set y [expr [lindex [$canvas bbox class$i] 3]+2]
+}
+$canvas config -scrollregion [list 0 0 [$canvas cget -width] $y]
+}
+
+proc color_box {palette canvas x1 y1 x2 y2 class} {
+$canvas create rectangle  $x1 $y1 $x2 $y2 -fill \
+       [palette get $palette $class] -tags class$class
+}
diff --git a/tcl/lesras.lay b/tcl/lesras.lay
new file mode 100644 (file)
index 0000000..be7708b
--- /dev/null
@@ -0,0 +1,30 @@
+#fGIS Layer file. Layer type: raster
+# Layer:  ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ
+set _raster_ [raster ../testdata/lesras.epp]
+set _legend_ [legend parse {-2   ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ
+1  úÏÎÁ ÁÒËÔÉÞÅÓËÏÊ ÐÕÓÔÙÎÉ
+2  úÏÎÁ ÔÕÎÄÒÙ -ÒÁ×ÎÉÎÎÁÑ
+3  úÏÎÁ ÔÕÎÄÒÙ -ÇÏÒÎÁÑ
+4  úÏÎÁ ÌÅÓÏÔÕÎÄÒÙ
+5  úÏÎÁ ÌÕÇÏ× É ÌÕÇÏ×ÙÈ ÒÅÄËÏÌÅÓÉÊ
+6  ðÏÄÚÏÎÁ ÒÅÄËÏÓÔÏÊÎÏÊ ÔÁÊÇÉ
+7  ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÔÁÊÇÉ
+8  ðÏÄÚÏÎÁ ÓÒÅÄÎÅÊ ÔÁÊÇÉ
+9  ðÏÄÚÏÎÁ ÀÖÎÏÊ ÔÁÊÇÉ
+10  ÐÏÄÚÏÎÁ Ó ÐÒÅÏÂÌÁÄÁÎÉÅÍ È×ÏÊÎÙÈ
+11  ÐÏÄÚÏÎÁ Ó ÏÄÉÎÁËÏ×ÙÍ ÕÞÁÓÔÉÅÍ È×ÏÊÎÙÈ É ÛÉÒÏËÏÌÉÓÔ×ÅÎÎÙÈ
+12  ÐÏÄÚÏÎÁ ÍÏÎÏÄÏÍÉÎÁÎÔÎÙÈ ÌÅÓÏ×
+13  ÐÏÄÚÏÎÁ ÐÏÌÉÄÏÍÉÎÁÎÔÎÙÈ-ÔÅÒÍÏÆÉÌØÎÙÈ ÌÅÓÏ×
+14  ÚÏÎÁ
+15  ÓÅ×ÅÒÎÙÈ ÓÔÅÐÅÊ
+16  ÀÖÎÙÈ ÓÔÅÐÅÊ
+17  ÓÅ×ÅÒÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+18  ÀÖÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+19  ÓÅ×ÅÒÎÏÊ ÐÕÓÔÙÎÉ
+20  ÀÖÎÏÊ ÐÕÓÔÙÎÉ
+}]
+layer create raster -raster $_raster_\
+    -border none -ovrborder yes -ovrcolor black\
+    -title { ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ}\
+    -legend $_legend_
+
diff --git a/tcl/mapview b/tcl/mapview
new file mode 100755 (executable)
index 0000000..773297f
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/wish8.0
+package require Fgis
+set planchet .map
+option add *font -cronyx-times-bold-r-normal--10-*
+frame .menu -relief raised -bd 2
+menubutton .menu.file -text "File" -menu [set m .menu.file.m]
+menu $m
+$m add command -label "Open..." -command add_layer
+$m add command -label "Save..." -state disabled -command {save_layer [select_layer]}
+$m add command -label "Close..." -state disabled -command {close_layer [select_layer]}
+$m add separator
+$m add command -label "Print..." -command [list fgisPrintDialog $planchet] 
+$m add separator
+$m add command -label "Quit" -command confirmExit
+menubutton .menu.layer -text "Layer" -menu [set m .menu.layer.m]
+menu $m
+$m add command -label "Show..." -command {show_layer [select_layer] } -state disabled
+$m add command -label "Look..." -command select_layers -state disabled
+$m add command -label "Properties..." -command {edit_layer [select_layer]} -state disabled
+pack .menu.file .menu.layer -side left
+pack .menu -side top -expand y -fill x
+label .status -anchor w
+planchet $planchet -width 640 -height 480 -status .status
+toolbar .tool $planchet 
+pack .tool -expand y -fill x
+pack $planchet 
+pack .status -expand y -fill x
+
+
+button .tool.layer -text "?" -command add_layer
+pack .tool.layer -side left -before .tool.scale
+wm protocol . WM_DELETE_WINDOW confirmExit
+foreach file $argv  {
+  add_layer $file
+}
diff --git a/tcl/objects.tcl b/tcl/objects.tcl
new file mode 100644 (file)
index 0000000..a23d392
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# objects.tcl
+# some common procedures to implement fGIS objects
+# This file is part of fGIS
+#
+
+
+#
+# generates new unique name which starts with prefix.
+# first name, which is not name of existing Tcl command and
+#  for which test script returns 1 would be returned
+#
+proc fgisMakeObjectName {prefix {test "info exists"}} {
+set i 0
+while 1 {
+  set name $prefix$i
+  if {![string length [info command $prefix$i]]&&
+               ![uplevel #0 $test $prefix$i]} {
+     return $prefix$i
+  }
+  incr i
+}
+}
+# 
+# returns 1 if name can be used for creation of new object
+#
+proc fgisCheckName {name {test "info exists"}} {
+ expr ![string length [info command $name]]&&![uplevel #0 $test $name]
+}
+
+#
+# Sets given variable to object value, if passed value is valid command
+# name.
+# Second argument specifies, how to deal with empty value.
+# none - means unset variable
+# nodefault - raise error
+# any other value is substituted instead of empty string  
+# This procedure DELETES object, stored in var previously, if it is
+# not eqial to default
+#
+
+proc fgisSetObj {var default value} {
+  # first, check if we need to substitute defaults
+  if [string match {} $value] {
+      switch -exact -- $default {
+         none { 
+              if {[uplevel info exists $var]&&
+                            "[uplevel set $var]"!="$default"} {
+                 [uplevel set $var] delete
+              }
+             uplevel unset $var
+             return 
+         }
+         nodefault {
+             return -code error -errorcode [list BADVALUE $var] \
+                 "Empty value not allowed"
+         }
+         default {
+             set value $default
+         }
+      }
+   } else {
+       # check if passed value is valid object. Defaults are
+       # not subject to check - programmer knows, but user knows not
+       if [llength [info command $value]]!=1 {
+          return -code error -errorcode [list BADVALUE $var] \
+               "Invalid object \"$value\""
+       }
+   }
+   if {[uplevel info exists $var]&&"[uplevel set $var]"!="$default"} {
+      [uplevel set $var] delete
+   }
+   uplevel set $var [list $value]
+   return
+}
+
+#
+# fgisSetList - sets given variable to value, if value is
+# one from given list. Otherwise rises error
+# 
+proc fgisSetList {var list value} {
+  if [checklistopt value $list msg] {
+      return -code error -errorcode [list BADVALUE $var] $msg
+  }
+  uplevel set $var [list $value]
+  return
+}
diff --git a/tcl/planchet.tcl b/tcl/planchet.tcl
new file mode 100644 (file)
index 0000000..953abb3
--- /dev/null
@@ -0,0 +1,1011 @@
+#
+# planchet.tcl 
+# definition of planchet widget.
+#
+# This file is part of fGIS tcl library
+# Copyright (c) by SoftWeyr, 1997
+#
+
+#
+# Class options
+# 
+#
+array set Planchet {
+legbox {}
+zoombutton {}
+unzoombuttons {}
+shiftbuttons {{} {} {} {}}
+statusline {}
+scalevar {}
+rulerpos {1c -1c}
+projection {}
+lookwidth 200
+resizable 1
+}
+#this options are got from application defaults
+array set Planchet [list\
+coordformat $fgis(coordformat)\
+orient $fgis(orient)\
+shiftfactor $fgis(shift_factor)\
+]
+
+# This options added here to make getopt eat up them, if they specified, and
+# so they would never passed to canvas command, so planchet would effectively
+# ignore them
+array set Planchet {
+borderwidth 0
+bd 0
+highlightthickness 0
+}
+#
+# bindings
+#
+
+bind Planchet <Configure> "fgisPlanchet:resize %W"
+bind Planchet <Destroy>  "fgisPlanchet:destroy %W"
+bind Planchet <Button-3> "fgisPlanchet:look %W %x %y"
+bind Planchet <Any-Leave> "fgisPlanchet_setstatus %W {} {}"
+bind Planchet <Any-Enter> "fgisPlanchet:setstatus %W %x %y"
+bind Planchet <Any-Motion> "fgisPlanchet:setstatus %W %x %y"
+bind LookToplevel <ButtonRelease-3> "fgisPlanchet:hidelook %W"
+bind LookToplevel <Button-1> "fgisPlanchet:hidelook %W"
+bind Zoom <Any-Motion> break
+bind Zoom <Button-1> "fgisPlanchet_zoom %W %x %y;break"
+bind Zoom <Button-3> "fgisPlanchet_zoom %W cancel;break"
+bind Zoom <Key-Escape> "fgisPlanchet_zoom %W cancel;break"
+bind Zoom <Any-Leave> "break"
+bind Zoom <Any-Enter> "break"
+#
+# create planchet widget
+#
+#
+proc planchet {w args} {
+upvar \#0 $w data
+global Planchet
+#parse options
+array set data [array get Planchet]
+set data(default) {}
+if [catch {getopt data $args} err] {
+  unset data
+  return -code error $err
+} 
+set restargs $data(default)
+unset data(default)
+#check helper widgets, if available
+foreach t {legbox statusline shiftbuttons unzoombuttons zoombutton} {
+   if [catch {fgisSetHelper $w $t $data($t)} err] {
+        unset data
+       return -code error $err
+    }
+}
+#correct value of "resizable" options
+if [checkbooleanopt data(resizable) err] {
+   return -code error $err
+}   
+#create canvas
+if [catch {eval canvas [list $w] $restargs -bd 0\
+         -highlightthickness 0} err] {
+   unset data
+   return -code error $err
+}
+bindtags $w [list $w Planchet [winfo parent $w] all]
+#create widget command
+set data(cmd) .$w
+rename $w $data(cmd)
+;proc $w args "eval fgisPlanchet:eval [list $w] \$args"
+# create look widnow
+
+set data(lookToplevel) [toplevel $w.look -class LookToplevel\
+         -relief raised -bd 3]
+set data(lookLabel) [label $w.look.label -wraplength $data(lookwidth)\
+    -justify left]
+pack $data(lookLabel)
+wm overrideredirect $data(lookToplevel) y
+wm transient $data(lookToplevel) $w
+wm positionfrom $data(lookToplevel) program
+wm withdraw $data(lookToplevel)
+# fill placeholders for layer information
+array set data {
+lookable {}
+overlays {}
+base {}
+limits {}
+zoom {}
+}
+return $w
+}
+
+#
+# fgisPlanchet:eval 
+# -evaluates planchet widget command
+#
+;proc fgisPlanchet:eval {w option args} {
+ upvar \#0 $w data
+  if [string match {} [set arg [info command fgisPlanchet_$option]]] {
+      set arg [info command fgiPlanchet_$option*]
+  }
+  switch -exact [llength $arg] {
+      0 { if [catch {uplevel [list $data(cmd) $option] $args} err] {
+           return -code error $err
+         } else {
+           return $err
+         }
+      }
+      1 {return [uplevel $arg [list $w] $args] }
+      default {
+          return -code error "ambiquous option \"$option\""
+      }
+  }
+}
+
+#
+# fgisPlanchet:destroy 
+# destroys planchet
+#
+
+;proc fgisPlanchet:destroy w {
+  upvar \#0 $w data
+  foreach layer [linsert $data(overlays) end $data(base)] {
+    if [string length $layer] {$layer  hide $w}
+  }
+  catch {rename $w {}}
+  #catch {rename $data(cmd) $w}
+  catch {unset data}
+  return
+}
+#
+# releases grab and hides look window
+#
+;proc fgisPlanchet:hidelook {w} {
+  catch {grab release $w}
+  wm withdraw $w
+}
+#
+# Given point in canvas coordinates, displays window with content
+# of current layers
+#
+;proc fgisPlanchet:look {w x y} {
+    upvar \#0 $w data
+    set text [join [fgisPlanchet_look $w \
+           [fgisPlanchet_mapx $w $x] [fgisPlanchet_mapy $w $y] -titled] "\n"]
+    if ![string length $text] {
+        set text "No info for this point"
+    }  
+    $data(lookLabel) configure -text $text
+    set rootx [expr [winfo rootx $w]+$x+5]
+    if {$rootx>[winfo screenwidth $w]} {
+       set rootx [expr $rootx-10-[winfo reqwidth $data(lookToplevel)]]
+    }
+    set rooty [expr [winfo rooty $w]+$y+5]
+    if {$rooty>[winfo screenwidth $w]} {
+       set rooty [expr $rooty-10-[winfo reqheight $data(lookToplevel)]]
+    }
+    wm geometry $data(lookToplevel)  +$rootx+$rooty
+    wm deiconify $data(lookToplevel)
+    raise $data(lookToplevel)
+    grab $data(lookToplevel)
+}
+#
+# User visible implementation of look. Can be invoked as look planchet
+# subcommand. Gets two map-coordinates and returns list of active layers
+# Forms
+# $planchet look x y ?-titled|-list?
+# $planchet look add $layer
+# $planchet look remove pattern 
+# $planchet look remove all
+# $planchet look list ?pattern?
+# legend text as layer value x y -titled returns
+#
+# Layers that return an empty string are ignored
+#
+;proc fgisPlanchet_look {w x {y {}} {flag -list}} {
+   upvar \#0 $w data
+   switch -exact -- $x {
+      add { 
+         if ![string length $y] {
+             return -code error "Wrong # args. Should be $w look add layer"
+         }
+         if ![layer exists $y] {
+             return -code error "Layer \"$y\" doesn't exist"
+         }
+         if ![$y info lookable] {
+             return -code error "Layer \"$y\" is not lookable"
+         }
+         if [lsearch -exact $data(lookable) $y]!=-1 {
+             return -code error "Layer \"$y\" is already in look list of $w"
+         }    
+         lappend data(lookable) $y
+      }
+      remove {
+         if ![string length $y] {
+           return -code error\
+                 "Wrong # args. Should be $w look remove pattern"
+         }
+         if {"$y"=="all"} {
+             set data(lookable) {}
+         } else {
+          if [lsearch -glob $data(lookable) $y]==-1 {
+              return -code error "No layers match pattern \"$y\""
+          }
+          while {[set index [lsearch -glob $data(lookable) $y]]!=-1} {
+             set data(lookable) [lreplace $data(lookable) $index $index]
+          }
+         }
+      }
+      list {
+         set result {}
+        if [string match {} $y] {set y *}
+        foreach l $data(lookable) {
+           if [string match $y $l] {
+              lappend result $l
+           }
+        }   
+         return $result
+      } 
+      default {
+          set result {}
+         foreach layer $data(lookable) {
+            lappend result [$layer value $x $y $flag]
+         }
+         return $result
+      }      
+   }   
+}
+#
+# Displays mouse coordinates in window.
+# Recalculates pixels to meters and calls $w setstatus
+# If no coordinate defined, displays "No coords"
+#
+
+;proc fgisPlanchet:setstatus {w x y}  {
+upvar \#0 $w data
+if ![llength $data(limits)] {
+   fgisPlanchet_setstatus $w "No coordinates defined"
+} else {
+  fgisPlanchet_setstatus $w [fgisPlanchet_mapx $w $x] [fgisPlanchet_mapy $w $y]
+}
+}
+
+#
+# Changes content of status window, if available
+# possible variants setstatus {} - clears status line
+# setstatus msg - displays $msg
+# setstatus x y - displays coordinates. Map coordinates, not screen!
+;proc fgisPlanchet_setstatus {w x {y {}}} {
+upvar \#0 $w data 
+if ![string length $data(statusline)] {
+   return
+}
+if ![string length $y] {
+  $data(statusline) configure -text $x
+} elseif ![string length $data(projection)] {
+  $data(statusline) configure -text [format $data(coordformat) $x $y]
+} else {
+  $data(statusline) configure -text [$data(projection) format $x $y]
+}
+}
+
+#
+# intercepts widget configure command
+# 
+#
+;proc fgisPlanchet_configure {w args} {
+upvar \#0 $w data
+if ![llength opt] {
+   return [eval $data(cmd) configure]
+}
+array set opt [list\
+    legbox [list fgisSetHelper $w legbox]\
+    zoombutton [list fgisSetHelper $w zoombutton ]\
+    unzoombuttons [list fgisSetHelper $w unzoombuttons ]\
+    shiftbuttons [list fgisSetHelper $w shiftbuttons]\
+    statusline [list fgisSetHelper $w statusline]\
+    scalevar {set data(scalevar)}\
+    rulerpos [list fgisPlanchet:ruler $w]\
+    projection {set data(projection)}\
+    lookwidth [list $data(lookLabel) configure -wraplength]\
+    coordformat "set data(coordformat)"\
+    orient "set data(orient)"\
+    shiftfactor "set data(shiftfactor)"\
+    borderwidth {#}\
+    bd 0\
+    highlightthickness {#}\
+    default "lappend restargs"\
+]
+set restargs {}
+if [catch {handleopt opt $args} res] {
+    return -code error $res
+}
+if [llength $restargs] {
+    if [catch {eval $data(cmd) configure $restargs}] {
+      return -code error $res
+    } 
+}
+}
+#
+# Installs link to helper widget.
+# Strictly internal use
+#
+;proc fgisSetHelper {w type widgets} {
+array set CLASS {
+legbox Canvas
+shiftbuttons Button
+zoombutton Button
+unzoombuttons Button
+statusline Label
+}
+upvar \#0 $w data
+foreach i $widgets {
+    if ![string match {} $i] {
+       if {![winfo exist $i]} {
+         return -code error "Window $i doesn't exist"
+       } elseif {"[winfo class $i]"!="$CLASS($type)"} {
+          return -code error \ 
+          "Wrong window $i. Should be [string tolower $CLASS($type)] widget."
+        }
+    }
+}    
+# additional checks
+switch -exact $type {
+    zoombutton { 
+       if [llength $widgets]>1 {
+          return -code error "-zoombutton allows only one widget"
+       }
+       if {[llength $widgets]&&![llength $data(limits)]} {
+           $widgets configure -state disabled
+       }
+    }
+    shiftbuttons { 
+       if [llength $widgets]!=4 {
+          return -code error "-shiftbuttons requires list of four buttons"
+       }
+       if [string length [join $widgets ""]] {
+          set dir {left down up right} 
+          set j 0
+          foreach i $widgets {
+             if [string compare {} $i] {
+                 $i configure -command [list $w shift [lindex $dir $j]]
+             } else {
+                 return -code error\ 
+                        "-shiftbuttons should all exist or all be empty"
+             }
+             incr j
+          }
+           set data(shiftbuttons) $widgets
+           fgisCheckShifts $w   
+       }
+    }   
+    unzoombuttons {}
+    default { 
+       if [llength $widgets]>1 {
+          return -code error "Only one widget allowed for -$type option"
+       }
+    } 
+}
+uplevel #0 set $w\($type) [list $widgets]
+}
+#                
+# intercert widget cget command
+#
+#
+;proc fgisPlanchet_cget {w args} {
+    upvar \#0 $w data
+    if [llength $args]!=1 {
+     return -code error "Wrong # args. Should be $w cget option"
+    }
+    set arg [array names data [string trimleft $args -]] 
+    set num [llength $arg]
+    if $num==1 {
+      return $data($arg)
+    } elseif $num {
+      return -code error  "Amgiquous option \"$args\""
+    } elseif [catch {$data(cmd) cget $args} result] {
+      return -code error $result
+    } else {
+      return $result
+    }
+}
+#
+#Set up new coordinates of ruler
+#or simply redraws ruler, if shown
+#
+;proc fgisPlanchet:ruler {w {coord {}}} {
+    upvar \#0 $w data
+    if [llength [$data(cmd) find withtag ruler]] {
+       fgisPlanchet_ruler off
+       if [string length $coord] {
+          set tmp $data(rulerpos)
+          set data(rulerpos) $coord
+          if [catch {fgisPlanchet_ruler on} err] {
+             set data(rulerpos) $tmp
+             fgisPlanchet_ruler on
+             return -code error $err
+          }
+       } else {
+        fgisPlanchet_ruler on
+       }
+    }   
+}
+#
+# actually implements ruler command
+#
+#
+;proc fgisPlanchet_ruler {w {flag {}}} {
+upvar \#0 $w data
+switch -exact $flag {
+   {}  {
+        if [llength [$data(cmd) find withtag ruler]] {
+          return on
+       } else {
+         return off
+        }
+   }   
+   off {
+         $data(cmd) delete ruler
+       }
+   on  { #here we actually draw it
+         # parse coordinates
+         global fgis_font
+         foreach {x y} $data(rulerpos) break 
+        if [catch {fgisConvertCoords $data(cmd) x $x [winfo width $w]} x] {
+            return -code error $x
+        }      
+        if [catch {fgisConvertCoords $data(cmd) y $y [winfo height $w]} y] {
+            return -code error $y
+        }
+        if [llength $data(limits)]!=4 { 
+            return -code error "Coordinate system not defined for $w"
+        }
+        set origin_x [fgisPlanchet_mapx $w $x]
+        set origin_y [fgisPlanchet_mapy $w $y]
+        set meters [expr [fgisPlanchet_mapx $w 2c]-[fgisPlanchet_mapx $w 0c]]
+        for {set size 10;set step 2} {abs($size)<$meters } {
+               set size [expr $size*$step]} {
+           set step [expr $step==2?5:2]
+         }
+       $data(cmd) create line $x $y [$w scrx [expr $origin_x+$size]] \
+              $y -width 3  -tags ruler
+       $data(cmd) create text $x [expr $y-5] -anchor s -text 0 -tags ruler \
+              -font $fgis_font(1)
+       if {$size>1000} {
+           set msg "[expr $size/1000]km"
+       } else {
+           set msg "${size}m"
+       }
+       $data(cmd) create text [$w scrx [expr $origin_x+$size]]\
+                [expr $y-5] -anchor s -text $msg -tags ruler \
+                -font $fgis_font(1)
+       for {set xx $origin_x} {$xx<=$size+$origin_x} {
+                      set xx [expr $xx+$size/$step]} { 
+          $data(cmd) create line [$w scrx $xx] $y [$w scrx $xx] [expr $y-4] \
+                 -tags ruler
+        }                
+  } 
+}
+}
+#
+# Converts values given in any cordinate form into pixels
+# if value is negative, corresponding window size is added
+#
+
+;proc fgisConvertCoords {w cmd value limit} {
+   if [regexp -- {-(.*)} $value junk abs] {
+     set negate 1
+     set value $abs
+   } else { set negate 0 }
+   if [catch { expr [$w canvas$cmd $value]-[$w canvas$cmd 0]} value] {
+     return -code error $value
+   }  
+   if $negate {
+     return [expr $limit-$value]
+   } else {
+     return $value
+   } 
+}   
+#
+# Sets limits of planchet coordinate system
+# If limits were defined, pushes them into zoom stack and
+# converts axis directions if neccessary
+#
+;proc fgisPlanchet_limits {w args} {
+    upvar \#0 $w data
+    if [llength $args]==1 {
+      eval set args $args
+    } elseif ![llength $args] {
+       return $data(limits)
+    } 
+    if [string match $args* default] {
+        if {![llength $data(zoom)]} {
+          return -code error "No views stacked"
+       }
+       set data(limits) {}
+       set args [lindex $data(zoom) 0]
+       set data(zoom) {}
+    }
+    if [llength $args]!=4 {
+       return -code error "List of four floating point numbers expected"
+    }
+    foreach {x1 y1 x2 y2} $args break
+    set width [expr $x2-$x1]
+    set height [expr $y2-$y1]
+    if [llength $data(limits)] {
+        foreach b $data(unzoombuttons) {
+         $b config -state normal
+       }
+       if {$width*([lindex $data(limits) 2]-[lindex $data(limits) 0])<0} {
+          set tmp $x2; set x2 $x1; set x1 $tmp
+           set width [expr -$width]
+       }
+       if {$height*([lindex $data(limits) 3]-[lindex $data(limits) 1])<0} {
+           set tmp $y2;set y2 $y1;set y1 $tmp
+            set height [expr -$height]
+       }    
+    } else {
+      foreach b $data(unzoombuttons) {
+         $b config -state disabled
+      }
+      if [string length $data(zoombutton)] {
+         $data(zoombutton) config -state normal
+      }
+    } 
+    if {![llength $data(limits)]&&$data(resizable)} {
+    # Trying to adjust canvas size, preserving area 
+      set area [expr [winfo reqheight $w]*[winfo reqwidth $w]]
+      set ratio [expr abs($width/$height)]
+      set hei [expr sqrt($area/$ratio)]
+      set wid [expr $hei*$ratio]
+      $data(cmd) config -width $wid -height $hei
+    } else {
+    # Trying to expand coordinate limits 
+        if (abs($height/[winfo reqheight $w])<abs($width/[winfo reqwidth $w])) {
+         set newh [expr abs($width)*[winfo reqheight $w]/[winfo reqwidth $w]]
+         if ($height<0) {
+             set y2 [expr $y1-$newh]
+          } else {
+             set y2 [expr  $y1+$newh]
+          }
+        } else {
+          set neww [expr abs($height)*[winfo reqwidth $w]/[winfo reqheight $w]]
+          if ($width<0)  {
+             set x2 [expr $x1-$neww]
+          } else {
+             set x2 [expr $x1+$neww]
+          }
+       }
+          
+      if ![info exists data(this_is_not_zoom)] {
+         lappend  data(zoom) $data(limits)
+      }
+   }
+   set data(limits) [list $x1 $y1 $x2 $y2]
+   fgisManageZoomList $w
+   fgisCheckShifts $w
+   fgisPlanchet:Redraw $w
+}
+#
+# checks all shift directions and enables/disables buttons, if exists
+# strictly internal use, no error checking
+#
+;proc fgisCheckShifts w {
+    upvar \#0 $w data
+    if [string length [join $data(shiftbuttons) ""]] {
+        foreach b $data(shiftbuttons) {
+           $b configure -state disabled
+        }
+       if [llength $data(zoom)] { 
+          foreach {X1 Y1 X2 Y2} [lindex $data(zoom) 0] break
+         foreach {x1 y1 x2 y2} $data(limits) break
+         foreach {left down up right} $data(shiftbuttons) break
+         fgisEnableShift $left $x1 $X1 $X2
+         fgisEnableShift $down $y1 $Y1 $Y2
+         fgisEnableShift $up   $y2 $Y2 $Y1
+         fgisEnableShift $right $x2 $X2 $X1
+        }
+  } 
+}  
+#
+# fgisEnableShift - checks if shift in given direction is possible,
+# and, if so, enables given button
+#
+
+;proc fgisEnableShift {button view lim1 lim2} {
+    if {($view-$lim2)/($lim1-$lim2)<1} {
+       $button config -state normal
+    }
+}    
+#
+# implements scale widget command
+# without arguments returns current scale,
+# with exactly one numeric argument sets scale to specified
+# keeping center of window at same coordinates, otherwise calls canvas scale
+#
+
+;proc fgisPlanchet_scale {w args} {
+   upvar \#0 $w data
+   if {[llength $args]<=1&&[llength $data(limits)]!=4} {
+      return -code error "Coorinate system for $w is not set"
+   }
+   if ![llength $args] {
+      return [format "%0.0f" [expr [$w mapx 1000m]-[$w mapx 0m]]]
+   } 
+   if [llength $args]==1 {
+       # compute coordinates of central point
+       set x [$w mapx [set halfwidth [expr [winfo reqwidth $w]/2]]]
+       set y [$w mapy [set halfheight [expr [winfo reqheight $w]/2]]]
+       # compute width and height in meters
+       set wm [expr $halfwidth/[$data(cmd) canvasx 1000m]-[$data(cmd) canvasx 0m]]
+       if [catch {expr $args*$wm} dx] {
+         return -code error $dx
+       }
+       set hm [expr {$halfheight/[$data(cmd) canvasy 1000m]-
+                    [$data(cmd) canvasy 0m]}]
+       set dy [expr $args*$hm]
+       foreach {x1 y1 x2 y2} $data(limits) break
+       if {$x1>$x2} {set dx [expr -$dx]}
+       set x1 [expr $x - $dx]
+       set x2 [expr $x + $dx]
+       if {$y1>$y2} {set dy [expr -$dy]}
+       set y1 [expr $y - $dy]
+       set y2 [expr $y + $dy]
+       fgisPlanchet_limits $w $x1 $y1 $x2 $y2
+   } elseif [catch {eval $data(cmd) scale $args} err] {
+       return -code error $err
+   }
+}
+
+#
+# handles <Configure> events by expanding coordinate system appropriately
+# and redrawing all layers
+#
+;proc fgisPlanchet:resize {w} {
+upvar \#0 $w data
+set oldw [winfo reqwidth $w]
+set oldh [winfo reqheight $w]
+set nw [winfo width $w]
+set nh [winfo height $w]
+if {$oldw==$nw&&$oldh==$nh} return
+$data(cmd) configure -width $nw -height $nh
+if [llength $data(limits)]==4 {
+  foreach {x1 y1 x2 y2} $data(limits) break
+  set y2 [expr ($y2-$y1)/$oldh*$nh+$y1]
+  set x2 [expr ($x2-$x1)/$oldw*$nw+$x1]
+  set data(limits) [list $x1 $y1 $x2 $y2]
+  fgisCheckShifts $w
+  fgisPlanchet:Redraw $w
+}  
+}  
+
+#
+# implements shift command - shifts viewport shiftfactor share in given
+# direction
+#
+
+;proc fgisPlanchet_shift {w args} {
+    if [llength $args]!=1 {
+       return -code error "Wrong # args. should be $w shift direction"
+    }
+    upvar \#0 $w data
+    if [llength $data(limits)]!=4 {
+      return -code error "Coordinate system for $w not set"
+    }  
+    array set dir {
+    left {-1 0}
+    west {-1 0}
+    right {1 0}
+    east {1 0}
+    up {0 1}
+    north {0 1}
+    down {0 -1}
+    south {0 -1}
+    }
+    set d [array names dir [string tolower $args]*]
+    if [llength $d]>1 {
+      return -code error "Ambiquous direction \"$dir\"."
+    } elseif ![llength $d] {
+      return -code error \
+             "Invalid direction \"$dir\". Should be one of [array names dir]"
+    }
+    set  d $dir($d)
+    
+    foreach {x1 y1 x2 y2} $data(limits) break;
+    set dx [expr ($x2-$x1)*$data(shiftfactor)*[lindex $d 0]]
+    set dy [expr ($y2-$y1)*$data(shiftfactor)*[lindex $d 1]]
+    set data(limits) [list  [expr $x1+$dx] [expr $y1+$dy] [expr $x2+$dx]\
+             [expr $y2+$dy]]
+    fgisCheckShifts $w
+    fgisPlanchet:Redraw $w
+}
+
+#
+# Pops up last zoom from stack
+# does call _limits to ensure that possible window size changes are haldled
+#
+
+;proc fgisPlanchet_unzoom w {
+    upvar \#0 $w data
+    if ![set len [llength $data(zoom)]] {
+      return -code error "No views stacked"
+    }
+    set data(this_is_not_zoom) {}
+    set newlim [lindex $data(zoom) [incr len -1]]
+    set data(zoom) [lreplace $data(zoom) $len end]
+    fgisPlanchet_limits $w $newlim
+    unset data(this_is_not_zoom)
+}
+
+#
+# Checks it zoom stack contain some views with larger scale than current
+# and discards them, becouse unzoom should never enlarge scale.
+# (it was too annoying in Serge Mikhailov's eppedit
+#
+# Here can also be shifting of old views to make them contain new one,
+# but I'm not sure that here is a good way to do so
+#
+
+;proc fgisManageZoomList w {
+    upvar \#0 $w data 
+    set zoom {}
+    set width [expr abs([lindex $data(limits) 2]-[lindex $data(limits) 0])]
+    foreach view $data(zoom) {
+       if {abs([lindex $view 2]-[lindex $view 0])>$width} {
+           lappend zoom $view
+       }
+    }
+    if [llength $zoom] {
+       set data(zoom) $zoom
+    } elseif [llength $data(zoom)] {
+       # always preserve default limits
+       set data(zoom) [list [lindex $data(zoom) 0]]
+    }
+    # update scale variable, if exist
+    if [string length $data(scalevar)] {
+       uplevel \#0 set $data(scalevar) "1:[fgisPlanchet_scale $w]"
+    }
+    # redraw ruler, if it is already visible
+
+}
+
+#
+# Implements zoom widget command.
+# with no options start interactive zooming process
+# with two coords starts interactive zooming with specified point (in
+# canvas coord) as one of corner. With four coords - just does it.
+# with cancel flag - cancels zoom in progress
+#
+;proc fgisPlanchet_zoom {w args} {
+   upvar \#0 $w data
+   switch -exact [llength $args] {
+   0 { 
+       fgisPlanchet_setstatus $w \
+                "Pick first corner. ESC or right button cancels"
+        bind Zoom <Button-1> "fgisPlanchet_zoom %W %x %y;break"
+        bind Zoom <Any-Motion> "break" 
+        bindtags $w [linsert [bindtags $w] 0 Zoom] 
+   }
+   1 { if ![string match $args* cancel] {
+         return -code error "Wrong # args. Should be $w zoom ?x y ?x y?? or\
+            $w zoom cancel"
+       }
+       if {![string match "Zoom*" [lindex [bindtags $w] 0]]} {
+           return -code error "No zoom in progress"
+       }
+       bindtags $w [lrange [bindtags $w] 1 end]
+       $data(cmd) delete zoomer
+       fgisPlanchet_setstatus {}
+   }
+   2 { if {[lindex [bindtags $w] 0]!="Zoom"} {
+           bindtags $w [linsert [bindtags $w] 0 Zoom]]
+       }
+       fgisPlanchet_setstatus $w\
+               "Pick second corner. ESC or right button cancels"
+       set x [lindex $args 0]
+       set y [lindex $args 1]
+       $data(cmd) create rectangle $x $y $x $y -tag zoomer
+       bind Zoom <Button-1> "fgisPlanchet_zoom %W $x $y %x %y;break"
+       bind Zoom <Any-Motion> "%W coord zoomer $x $y %x %y; break"
+   }
+   4 { foreach {x1 y1 x2 y2} $args break
+       if {[lindex [bindtags $w] 0]=="Zoom"} {
+          bindtags $w [lrange [bindtags $w] 1 end]
+       }
+       fgisPlanchet_limits $w [$w mapx $x1] [$w mapy $y1] [$w mapx $x2]\
+            [$w mapy $y2]
+       $data(cmd) delete zoomer
+     } 
+   default {
+     return -code error  "Wrong # args. Should be $w zoom ?x y ?x y?? or\
+            $w zoom cancel"
+   }
+}
+}
+
+#
+# clear - deletes all layers and resets coordinate system. 
+# leaves projection untouched
+#
+
+;proc fgisPlanchet_clear w {
+   upvar \#0 $w data
+   set data(lookable) {}
+   foreach layer [concat $data(overlays) $data(base)] {
+      $layer hide $w
+   } 
+   $data(cmd) delete all
+   set data(limits) {}
+   set data(zoom) {}
+   set data(overlays) {}
+   set data(base) {}
+   if {[string length $data(legbox)]} {$data(legbox) delete all}
+   foreach b [concat $data(unzoombuttons) [list $data(zoombutton)] \
+         $data(shiftbuttons)] {
+     if {[string length $b]&&[winfo exists $b]} {
+         $b configure -state disabled
+     }
+   }   
+}
+
+#
+# layers - returns list of all layers
+# 
+#
+
+;proc fgisPlanchet_layers {w args} {
+    upvar \#0 $w data
+    if [llength $args]>1 {
+       return -code error "Wrong # of args. Should be $w layers ?pattern?"
+    }
+    if ![llength $args] { set args "*"}
+    set result {} 
+    upvar #0 $w data
+    foreach l [concat $data(base) $data(overlays)] {
+      if {[string match $args $l]&&[lsearch -exact $result $l]==-1} {
+        lappend result $l
+      }
+    }
+    return $result
+}
+
+#
+# hide $layer - clears given layer
+#
+#
+;proc fgisPlanchet_hide {w args} {
+   upvar \#0 $w data
+   foreach l $args {
+      set list [fgisPlanchet_layers $w $l]
+      if ![llength $list] {
+         return -code error "No such layer \"$l\" in $w"
+      }
+      foreach ll $list {
+         $ll hide $w
+         $data(cmd) delete $ll
+        if {"$ll"=="$data(base)"} {
+          if {[string length $data(legbox)]} {
+              $data(legbox) delete all
+          }
+          set data(base) {}
+        }
+        if {[set index [lsearch -exact $data(overlays) $ll]]!=-1} {
+           set data(overlays) [lreplace $data(overlays) $index $index]
+        }   
+      }
+   }
+  
+}
+
+#
+# show $layer ?-base|-overlay?
+# displays layer
+#
+;proc fgisPlanchet_show {w args} {
+   upvar \#0 $w data
+   if ![llength $args]&&[llength $args]>2 {
+      return -code error "Wrong # args. Should be $w show layer ?mode?"
+   }
+   set layer [lindex $args 0] 
+   if [llength $args]==1 {
+      if {![llength $data(limits)]&&[$layer info opaque]} {
+        set mode -base
+      } else {
+        set mode -overlay
+      }
+   } else {
+     set mode [lindex $args 1]
+     if [string match $mode* -base] {
+        set mode -base
+        if ![$layer info opaque] {
+           return -code error "Opaque mode is not supporded by $layer"
+        } 
+     } elseif [string match $mode* -overlay] {
+        set mode -overlay
+       if [lsearch -exact $data(overlays) $layer]!=-1 {
+          return -code error "Layer \"$layer\" already visible in $w"
+        }
+     } else {
+        return -code error \
+            "Invalid option \"$mode\". Should be -base or -overlay"
+     }
+   }
+   if ![llength $data(limits)] {
+     if [$layer info limits] {
+       # am I wrong?
+       eval fgisPlanchet_limits $w [$layer limits]
+     } else {
+       return -code error\
+            "Cannot show $layer without defined coordinate system" 
+     }
+   } else {
+     foreach {x1 y1 x2 y2} [$layer limits] break
+     foreach {X1 Y1 X2 Y2} $data(limits) break
+     if {($x2-$x1)*($X2-$X1)<0||($Y2-$Y1)*($y2-$y1)<0} {
+        return -code error "Layer $layer is not compatible with $w"
+     }
+   }
+   $layer show $w $mode
+   if {$mode=="-base"} {
+      if [llength $data(base)] {
+         $data(base)  hide $w
+         $data(cmd) delete $data(base)
+      }
+      set data(base) $layer
+      $data(cmd) lower $layer
+      if {[string length $data(legbox)]&&[winfo exists $data(legbox)]} {
+        drawlegend 0 0 $data(legbox) $layer -base -columns 1 \
+             -width [$data legbox cget -width]
+      }
+   } else {
+     lappend data(overlays) $layer
+   } 
+   fgisPlanchet_setstatus $w "REDRAW: Wait please..."
+   update
+   $layer redraw $w
+   fgisPlanchet_setstatus $w {}
+}
+
+#
+#
+# fgisPlanchet:Redraw - redraws all layers. Very expensive thing.
+# Should be called only if view coords are changed
+#
+;proc fgisPlanchet:Redraw {w} {
+    upvar \#0 $w data
+    fgisPlanchet_setstatus $w "REDRAW: Wait please..."
+    update
+    foreach layer [concat $data(base) $data(overlays)] {
+       $layer redraw $w
+    }
+    fgisPlanchet_setstatus $w {}
+    if {[fgisPlanchet_ruler $w]=="on"} {
+         fgisPlanchet_ruler $w off
+         fgisPlanchet_ruler $w on
+    }    
+    update
+}  
+;proc fgisPlanchet_print {w args} {
+upvar \#0 $w data
+global fgis
+array set opt [list\
+file "|"\
+printer $fgis(printer)\
+colormode $fgis(print_colormode)\
+fontmap fgis_fontmap] 
+
+getopt opt $args
+if [uplevel array exist $opt(fontmap)] {
+    upvar $opt(fontmap) fontmap
+} elseif [uplevel #0 array exist $opt(fontmap)] {
+    upvar $opt(fontmap) fontmap
+} else {
+   return -code error "Array \"$opt(fontmap)\" doesn't exist"
+}
+if {$data(orient)=="landscape"} {set rotate y} else {set rotate n}
+if [catch {if {$opt(file)=="|"} {
+   exec $fgis(printcmd) -P$opt(printer) << [ $data(cmd) postscript\
+      -rotate $rotate -colormode $opt(colormode) -fontmap fontmap
+} else {
+  $data(cmd) postscript -rotate $rotate -colormode $opt(colormode)\
+      -fontmap fontmap -file $opt(file)
+} } err ] {
+  return -code error $err
+}
+}
diff --git a/tcl/progressbar.tcl b/tcl/progressbar.tcl
new file mode 100644 (file)
index 0000000..91046e0
--- /dev/null
@@ -0,0 +1,619 @@
+##
+## Copyright 1996-7 Jeffrey Hobbs
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     progressbar
+##
+## DESCRIPTION
+##     Implements a Progressbar mega-widget
+##
+## ARGUMENTS
+##     progressbar <window pathname> <options>
+##
+## OPTIONS
+##     (Any canvas widget option may be used in addition to these)
+##
+## -indicatorcolor                     DEFAULT: #5ae6fe
+##     The color of the progressbar.  Must be in #rgb format.
+##     This is also the default item start foreground color.
+##
+## -itembackground                     DEFAULT: {}
+##     Default item background color.  {} means transparent.
+##
+## -itemfgfinished                     DEFAULT: #00ff00 (green)
+##     Default item finished foreground color.  Must be in #rgb format.
+##
+## -itemtype                           DEFAULT: document
+##     Default item type (currently 'document' and 'image' are supported).
+##
+## -labelanchor anchor                 DEFAULT: c
+##     Anchor for the label.  Reasonable values are c, w and e.
+##
+## -labeltext string                   DEFAULT: {}
+##     Text for the label
+##
+## -labelwidth #                       DEFAULT: 0 (self-sizing)
+##     Width for the label
+##
+## -maxvalue #                         DEFAULT: 0 (percentage-based)
+##     This represents what the representative max value of the progress
+##     bar is.  If it is 0, the progress bar interprets the -value option
+##     like a percentage (with an implicit 100 value for -maxvalue),
+##     otherwise it is representative of what -value would have to reach
+##     for the progress to be at 100%.
+##
+## -orientation horizontal|vertical    DEFAULT: horizontal
+##     Orientation of the progressbar
+##
+## -showvalue TCL_BOOLEAN              DEFAULT: 1
+##     Whether or not to show the exact value beside the bar (it is
+##     displayed as a percentage of the possible max value).
+##
+## -showerror TCL_BOOLEAN              DEFAULT: 1
+##     Whether to raise an error in the trace on the -variable if the
+##     appropriate range is exceeded.
+##
+## -value #                            DEFAULT: 0
+##     The value of the progress bar.  This will be used to calculate the
+##     overall progress percentage in conjunction with the -maxvalue option.
+##
+## -variable varname                   DEFAULT: {}
+##     A variable from which to get the value for the bar.  This variable
+##     will have a trace set upon it that forces a postive value.  It cannot
+##     be unset until the widget is destroyed or you change this option.
+##
+## RETURNS: the window pathname
+##
+## BINDINGS (in addition to default widget bindings)
+##
+## METHODS
+##     These are the methods that this megawidget recognizes.  Aside from
+##     those listed here, it accepts what is valid for canvas widgets.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## create ?item? ?-option value ...?
+##     Start displaying the progress of an item.  "item" is the
+##     name to associate with the item.  If no name is supplied, a unique
+##     name is generated.  If an item of the same name already exists, then
+##     a new unique name is generated.  Returns the name of the created item.
+##
+## delete item
+##     Remove the given item from the list of items being displayed.
+##     Total progress is updated appropriately.
+##
+## itemconfigure item ?-option value?
+##     Sets option(s) for an item.
+##
+##     VALID ITEM OPTIONS
+##
+##     -background color       Background color of icon associated with item.
+##     -fgstart #rgb           Initial foreground color of item's icon.
+##     -fgfinished #rgb        Final foreground color of item's icon.
+##                             The progressbar changes the shade of the icon
+##                             from the initial to the final color in
+##                             conjunction with the %age of maxvalue.
+##     -maxvalue #     max value that represents 100% of possible value
+##     -type type      item type (document and image currently supported)
+##                     This can only be set at creation.
+##     -value #        current progress toward full value of maxvalue
+##
+## itemcget item -option
+##     Returns the current value of the option for the given item
+##
+## names ?pattern?
+##     Returns the names of the progressbar's constituent items.
+##     An optional pattern can limit the return result.
+##
+## recalculate
+##     Recalculates the value and maxvalue of the progressbar based
+##     on the values of the consituent items, if any.  This is only
+##     necessary when changing from using the progressbar without items
+##     to using it with items.
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are label, canvas.
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     Public procs of $CLASSNAME and [string tolower $CLASSNAME] are used.
+## Other procs that begin with $CLASSNAME are private.  For each widget,
+## commands named .$widgetname and $CLASSNAME$widgetname are created.
+##
+## EXAMPLE USAGE:
+##
+## pack [progressbar .p -labeltext "Usage:" -variable usage] -fill x -exp 1
+## for {set i 0} {$i <= 10} {incr i} { set usage ${i}0; after 1000 }
+##
+##
+##------------------------------------------------------------------------
+
+#package require Widget 1.0
+package provide Progressbar 1.1
+
+array set Progressbar {
+    type               frame
+    base               {canvas canvas canvas {-highlightthickness 0 \
+           -bd 1 -relief ridge -width 100 -height 25}}
+    components         {label}
+
+    -bd                        -borderwidth
+    -borderwidth       {borderWidth    BorderWidth     0}
+    -font              {ALIAS label -font}
+    -fg                        -foreground
+    -foreground                {ALIAS label -foreground}
+    -indicatorcolor    {indicatorColor Color           #5ae6fe}
+    -indicatorcolour   -indicatorcolor
+    -itembackground    {itemBackground Background      {}}
+    -itemfgfinished    {itemForegroundFinished Foreground #00ff00}
+    -itemtype          {itemType       ItemType        document}
+    -labelanchor       {labelAnchor    Anchor          c}
+    -labeltext         {labelText      Text            {}}
+    -labelwidth                {labelWidth     Width           0}
+    -maxvalue          {maxValue       Value           0}
+    -orientation       {orientation    Orientation     horizontal}
+    -relief            {relief         Relief          flat}
+    -showvalue         {showValue      ShowValue       1}
+    -showerror         {showError      ShowError       1}
+    -value             {value          Value           0}
+    -variable          {variable       Variable        {}}
+}
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc Progressbar args {}
+proc progressbar args {}
+widget create Progressbar
+
+;proc Progressbar:construct {w} {
+    upvar \#0 $w data
+
+    ## Private variables
+    array set data {
+       counter         0
+    }
+    set data(items) $data(class)${w}ITEMS
+
+    grid $data(label) $data(canvas) -in $w -sticky ns
+    grid configure $data(canvas) -sticky news
+    grid columnconfig $w 1 -weight 1
+    grid rowconfig $w 0 -weight 1
+    grid remove $data(label)
+
+    bind $data(canvas) <Configure> [list Progressbar:resize $w %w %h]
+}
+
+;proc Progressbar:init {w} {
+    upvar \#0 $w data
+    $data(basecmd) create rect -1 0 0 25 -fill $data(-indicatorcolor) \
+           -tags bar -outline {}
+    $data(basecmd) create text 25 12 -fill $data(-foreground) \
+           -tags text -anchor c
+    $data(basecmd) xview moveto 0
+    $data(basecmd) yview moveto 0
+}
+
+;proc Progressbar:configure { w args } {
+    upvar \#0 $w data
+
+    set truth {^(1|yes|true|on)$}
+    set resize 0
+    set force  0
+    foreach {key val} $args {
+       switch -- $key {
+           -borderwidth - -relief { .$w configure $key $val }
+           -font       {
+               $data(label) configure -font $val
+               $data(basecmd) itemconfigure text -font $val
+           }
+           -foreground         {
+               $data(label) configure -foreground $val
+               $data(basecmd) itemconfigure text -fill $val
+           }
+           -indicatorcolor     {
+               $data(basecmd) itemconfigure bar -fill $val
+           }
+           -labelanchor        { $data(label) configure -anchor $val }
+           -labeltext          {
+               $data(label) configure -text $val
+               if {[string compare {} $val]} {
+                   grid $data(label)
+               } else {
+                   grid remove $data(label)
+               }
+           }
+           -labelwidth         { $data(label) configure -width $val }
+           -maxvalue           {
+               if {![regexp {^[0-9]+$} $val] || $val<0} {
+                   return -code error "$key must be a positive integer"
+               }
+               set force 1
+           }
+           -orientation        {
+               if {[string match h* $val]} {
+                   set val horizontal
+               } elseif {[string match v* $val]} {
+                   set val vertical
+               } else {
+                   return -code error \
+                           "orientation must be horizontal or vertical"
+               }
+               if {[string compare $data($key) $val]} {
+                   set W [$data(basecmd) cget -width]
+                   set H [$data(basecmd) cget -height]
+                   $data(basecmd) configure -height $W -width $H
+                   set resize 1
+               }
+           }
+           -showvalue  {
+               set val [regexp -nocase $truth $val]
+               set resize 1
+           }
+           -showerror  { set val [regexp -nocase $truth $val] }
+           -value      {
+               if {[catch {Progressbar:set $w $val} err] && \
+                       $data(-showerror)} {
+                   return -code error $err
+               }
+               if {$resize} { set resize 0 }
+               if {$force} { set force 0 }
+               continue
+           }
+           -variable   {
+               if {![string compare $val $data(-variable)]} return
+               if {[string compare {} $data(-variable)]} {
+                   uplevel \#0 [list trace vdelete $data(-variable) wu \
+                           "Progressbar:trace $w"]
+                   set data(-variable) {}
+               }
+               if {[string compare {} $val]} {
+                   set data(-variable) $val
+                   upvar \#0 $val var
+                   if {![info exists var] || \
+                           [catch {Progressbar:set $w $var} err]} {
+                           set var $data(-value)
+                   }
+                   uplevel \#0 [list trace var $val wu "Progressbar:trace $w"]
+               }
+               ## avoid the set data($key)
+               continue
+           }
+       }
+       set data($key) $val
+    }
+    if {$force || ($resize && [winfo ismapped $data(canvas)])} {
+       Progressbar:resize $w [winfo width $data(canvas)] \
+               [winfo height $data(canvas)]
+    }
+}
+
+;proc Progressbar:destroy w {
+    upvar \#0 $w data
+    catch { Progressbar:configure $w -variable {} }
+}
+
+;proc Progressbar:trace {w name el op} {
+    upvar \#0 $w data
+    upvar \#0 $data(-variable) var
+    if {[string match u $op]} {
+       set var $data(-value)
+       uplevel \#0 [list trace var $data(-variable) wu "Progressbar:trace $w"]
+    } elseif {[catch {Progressbar:set $w $var} err]} {
+       set var $data(-value)
+       if $data(-showerror) { return -code error $err }
+    }
+}
+
+;proc Progressbar:resize {w W H} {
+    upvar \#0 $w data
+
+    ## Assume a maxvalue of 100 if maxvalue is 0 (works like %age)
+    if {$data(-maxvalue)} {
+       set pcnt [expr {$data(-value)/double($data(-maxvalue))}]
+    } else {
+       set pcnt [expr {$data(-value)/100.0}]
+    }
+    if {[string match h* $data(-orientation)]} {
+       $data(basecmd) coords bar -1 0 [expr {$pcnt*$W}] $H
+    } else {
+       ## Vertical orientation needs testing
+       $data(basecmd) coords bar -1 $H $W [expr {$pcnt*$H}]
+    }
+    if $data(-showvalue) {
+       $data(basecmd) coords text [expr {$W/2}] [expr {$H/2-2}]
+       $data(basecmd) itemconfigure text -text [expr $pcnt*100.0]%
+    } else {
+       $data(basecmd) coords text $W $H
+    }
+}
+
+;proc Progressbar:set {w val} {
+    upvar \#0 $w data
+    if {![regexp {^[0-9]+$} $val] || $val<0} {
+       return -code error "value must be an integer greater than 0"
+    }
+    if {[string comp {} $data(-variable)]} {
+       upvar \#0 $data(-variable) var
+       if {[catch {set var $val} err]} {
+           return -code error $err
+       }
+    }
+    set data(-value) $val
+    Progressbar:resize $w [winfo width $data(canvas)] \
+           [winfo height $data(canvas)]
+}
+
+# Manage progress items.  These may be documents or images.
+# (There needs to be an extensible system to allow other types, eg. Tclets)
+# Each item may have a max value and a current value.
+# The total download progress is calculated from the sums of item sizes.
+
+;proc Progressbar_create {w args} {
+    upvar \#0 $w data
+
+    set cnt [incr data(counter)] 
+    if {[string match -* [lindex $args 0]]} {
+       # Invent a name
+       set item progress$cnt
+    } else {
+       set item [lindex $args 0]
+       set args [lrange $args 1 end]
+       if {[info exists data(I:$item)]} {
+           # Ensure name doesn't already exist
+           return -code error "item \"$item\" already exists"
+       }
+    }
+
+    array set config [list \
+           -background $data(-itembackground) \
+           -fgstart    $data(-indicatorcolor) \
+           -fgfinished $data(-itemfgfinished) \
+           -maxvalue   100 \
+           -type       $data(-itemtype) \
+           -value      0 \
+           ]
+    array set configargs $args
+    if {[info exists configargs(-type)]} {
+       if {[string match {} \
+               [info commands Progressbar:icon:$configargs(-type)]]} {
+           return -code error "invalid item type $configargs(-type)"
+       }
+       set config(-type) $configargs(-type)
+       unset configargs(-type)
+    }
+    incr data(-maxvalue) $config(-maxvalue)
+    incr data(-value) $config(-value)
+    # Add to display
+    set config(image) [image create bitmap $w:$item \
+           -data [Progressbar:icon:$config(-type) cget -data] \
+           -foreground $config(-fgstart) \
+           -background $config(-background)]
+    set config(w) [label $w.item$cnt -image $config(image)]
+    foreach {ncols nrows} [grid size $w] break
+    if {[string match h* $data(-orientation)]} {
+       grid $config(w) -row 0 -column $ncols
+    } else {
+       grid $config(w) -row $nrows -column 0
+    }
+
+    set data(I:$item) [array get config]
+
+    if {[string compare {} $args]} {
+       eval Progressbar_itemconfigure [list $w] [list $item] \
+               [array get configargs]
+    } else {
+       Progressbar:set $w $data(-value)
+    }
+
+    return $item
+}
+
+# Turns #rgb into 3 elem list of decimal vals.
+;proc Progressbar:parse_color c {
+    set c [string tolower $c]
+    if {[regexp {^\#([0-9a-f])([0-9a-f])([0-9a-f])$} $c x r g b]} {
+       # appending "0" right-shifts 4 bits
+       scan "${r}0 ${g}0 ${b}0" "%x %x %x" r g b
+    } else {
+       if {![regexp {^\#([0-9a-f]+)$} $c junk hex] || \
+               [set len [string length $hex]]>12 || $len%3 != 0} {
+           return -code error "bad color value \"$c\""
+       }
+       set len [expr {$len/3}]
+       scan $hex "%${len}x%${len}x%${len}x" r g b
+    }
+    return [list $r $g $b]
+}
+
+## Returns a shade between two colors based on the frac (0.0-1.0)
+;proc Progressbar:shade {orig dest frac} {
+    if {$frac >= 1.0} { return $dest } elseif {$frac <= 0.0} { return $orig }
+    foreach {origR origG origB} [Progressbar:parse_color $orig] \
+           {destR destG destB} [Progressbar:parse_color $dest] {
+       set shade [format "\#%02x%02x%02x" \
+               [expr {int($origR+double($destR-$origR)*$frac)}] \
+               [expr {int($origG+double($destG-$origG)*$frac)}] \
+               [expr {int($origB+double($destB-$origB)*$frac)}]]
+       return $shade
+    }
+}
+
+;proc Progressbar_delete {w args} {
+    upvar \#0 $w data
+
+    foreach item $args {
+       ## Don't complain about unknown items when deleting
+       if {![info exists data(I:$item)]} continue
+
+       array set config $data(I:$item)
+
+       incr data(-value) -$config(-value)
+       incr data(-maxvalue) -$config(-maxvalue)
+       if {$data(-value) < 0} { set data(-value) 0 }
+       if {$data(-maxvalue) < 0} { set data(-maxvalue) 0 }
+
+       destroy $config(w)
+       image delete $config(image)
+       unset data(I:$item)
+    }
+    Progressbar:set $w $data(-value)
+}
+
+## Progressbar_itemconfigure
+## configure a progressar constituent item
+##
+;proc Progressbar_itemconfigure {w item args} {
+    upvar \#0 $w data
+
+    if {![info exists data(I:$item)]} {
+       return -code error "unknown item \"$item\""
+    }
+
+    array set config $data(I:$item)
+    if {[string match {} $args]} { return [array get config -*] }
+
+    set valChanged 0
+    foreach {key val} $args {
+       if {[string match {} [set arg [array names config $key]]]} {
+           set arg [array names config ${key}*]
+       }
+       set num [llength $arg]
+       if {$num==0} {
+           return -code error "unknown option \"$key\", must be:\
+                   [join [array names config -*] {, }]"
+       } elseif {$num>1} {
+           return -code error "ambiguous option \"$args\",\
+                   must be one of: [join $arg {, }]"
+       } else {
+           set key $arg
+       }
+       switch -- $key {
+           -maxvalue   {
+               if {![regexp {^[0-9]+$} $val] || $val<=0} {
+                   return -code error "$key must be an integer greater than 0"
+               }
+               incr data(-maxvalue) [expr {$val-$config(-maxvalue)}]
+               if {$data(-maxvalue) < 0} { set data(-maxvalue) 0 }
+               set valChanged 1
+           }
+           -value      {
+               if {![regexp {^[0-9]+$} $val] || $val<0} {
+                   return -code error "$key must be a postive integer"
+               }
+               incr data(-value) [expr {$val-$config(-value)}]
+               if {$data(-value) < 0} { set data(-value) 0 }
+               set valChanged 1
+           }
+           -type       {
+               ## Should we allow this to be changed?
+               return -code error "-type cannot be changed after creation"
+           }
+           -fgstart    {
+               if {![regexp {^\#([0-9a-f]+)$} $val]} {
+                   return -code error "color value must be in \#rgb format"
+               }
+           }
+           -fgfinished {
+               if {![regexp {^\#([0-9a-f]+)$} $val]} {
+                   return -code error "color value must be in \#rgb format"
+               }
+           }
+       }
+       set config($key) $val
+    }
+    set data(I:$item) [array get config]
+
+    if {$config(-maxvalue)} {
+       $config(image) configure -background $config(-background) \
+               -foreground [Progressbar:shade \
+               $config(-fgstart) $config(-fgfinished) \
+               [expr {double($config(-value))/$config(-maxvalue)}]]
+    }
+    if {$valChanged} { Progressbar:set $w $data(-value) }
+}
+
+## Progressbar_itemcget
+## Returns a single item option
+##
+;proc Progressbar_itemcget {w item opt} {
+    upvar \#0 $w data
+
+    if {![info exists data(I:$item)]} {
+       return -code error "unknown item \"$item\""
+    }
+    array set config $data(I:$item)
+    ## Ensure that we are getting a -'ed value
+    if {![info exists config(-[string range $opt 1 end])]} {
+       return -code error "unknown option \"$opt\""
+    }
+    return $config($opt)
+}
+
+## Progressbar_names
+## Return a list of item names
+##
+;proc Progressbar_names {w {pattern *}} {
+    upvar \#0 $w data
+
+    set items {}
+    foreach name [array names data I:$pattern] {
+       lappend items [string range $name 2 end]
+    }
+    return $items
+}
+
+## Progressbar_recalculate
+## recalculates the percentage based purely on the constituent items
+## If there are no items, it just ensures that -(max)value is >= 0
+##
+;proc Progressbar_recalculate {w} {
+    upvar \#0 $w data
+
+    set items [array names data I:*]
+    if {[string compare {} $items]} {
+       set data(-maxvalue) 0
+       set data(-value) 0
+       foreach item $items {
+           array set config $data($item)
+           if {$config(-value) < 0} {set config(-value) 0}
+           if {$config(-maxvalue) < 0} {set config(-maxvalue) 0}
+           incr data(-value) $config(-value)
+           incr data(-maxvalue) $config(-maxvalue)
+           set data($item) [array get config]
+       }
+    } else {
+       if {$data(-value) < 0} {set data(-value) 0}
+       if {$data(-maxvalue) < 0} {set data(-maxvalue) 0}
+    }
+    Progressbar:set $w $data(-value)
+    return
+}
+
+image create bitmap Progressbar:icon:document -data {#define document_width 20
+#define document_height 23
+static char document_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xfc, 0x1f, 0x00, 0x04, 0x30, 0x00, 0x04, 0x50, 0x00, 0x04, 0x90, 0x00,
+   0x04, 0x10, 0x01, 0x04, 0xf0, 0x03, 0x04, 0x00, 0x02, 0x04, 0x00, 0x02,
+   0x04, 0x00, 0x02, 0x04, 0x00, 0x02, 0x04, 0x00, 0x02, 0x04, 0x00, 0x02,
+   0x04, 0x00, 0x02, 0x04, 0x00, 0x02, 0x04, 0x00, 0x02, 0x04, 0x00, 0x02,
+   0x04, 0x00, 0x02, 0x04, 0x00, 0x02, 0xfc, 0xff, 0x03};
+}
+
+image create bitmap Progressbar:icon:image -data {#define image_width 20
+#define image_height 23
+static char image_bits[] = {
+   0xe0, 0xff, 0xff, 0x20, 0xe0, 0xff, 0xe0, 0xff, 0xff, 0x30, 0xff, 0xff,
+   0xe8, 0xf8, 0xff, 0xdf, 0xf7, 0xff, 0xbb, 0xff, 0xff, 0x7b, 0xff, 0xff,
+   0xfb, 0xfe, 0xff, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff,
+   0xcf, 0x1f, 0xfc, 0x03, 0x0e, 0xf8, 0x20, 0x70, 0xf0, 0x18, 0x80, 0xf1,
+   0x07, 0x00, 0xf0, 0x00, 0x1e, 0xf0, 0xf8, 0x01, 0xf0, 0x00, 0x00, 0xf0,
+   0xc0, 0x7f, 0xf3, 0x00, 0x80, 0xf0, 0x40, 0x00, 0xf0};
+}
+return
diff --git a/tcl/tabnotebook.tcl b/tcl/tabnotebook.tcl
new file mode 100644 (file)
index 0000000..a4c5e3d
--- /dev/null
@@ -0,0 +1,555 @@
+##
+## Copyright 1997 Jeffrey Hobbs, CADIX International
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     tabnote
+##
+## DESCRIPTION
+##     Implements a Tabbed Notebook megawidget
+##
+## ARGUMENTS
+##     tabnote <window pathname> <options>
+##
+## OPTIONS
+##     (Any entry widget option may be used in addition to these)
+##
+## -activebackground color             DEFAULT: {}
+##     The background color given to the active tab.  A value of {}
+##     means these items will pick up the widget's background color.
+##
+## -background color                   DEFAULT: DEFAULT
+##     The background color for the container subwidgets.
+##
+## -browsecmd script                   DEFAULT: {}
+##     A script that is executed each time a tab changes.  It appends
+##     the old tab and the new tab to the script.  An empty string ({})
+##     represents the blank (empty) tab.
+##
+## -disabledbackground color           DEFAULT: #c0c0c0 (dark gray)
+##     The background color given to disabled tabs.
+##
+## -justify justification              DEFAULT: center
+##     The justification applied to the text in multi-line tabs.
+##     Must be one of: left, right, center.
+##
+## -linewidth pixels                   DEFAULT: 1
+##     The width of the line surrounding the tabs.  Must be at least 1.
+##
+## -linecolor color                    DEFAULT: black
+##     The color of the line surrounding the tabs.
+##
+## -normalbackground                   DEFAULT: {}
+##     The background color of items with normal state.  A value of {}
+##     means these items will pick up the widget's background color.
+##
+## -padx pixels                                DEFAULT: 4
+##     The X padding for folder tabs around the items.
+##
+## -pady pixels                                DEFAULT: 2
+##     The Y padding for folder tabs around the items.
+##
+## RETURNS: the window pathname
+##
+## BINDINGS (in addition to default widget bindings)
+##
+## <1> in a tabs activates that tab.
+##
+## METHODS
+##     These are the methods that the Tabnote widget recognizes.  Aside from
+##     these, it accepts methods that are valid for entry widgets.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## activate id
+##     Activates the tab specified by id.  id may either by the unique id
+##     returned by the add command or the string used in the add command.
+##
+## add string ?-window widget? ?-state state?
+##     Adds a tab to the tab notebook with the specified string, unless
+##     the string is the name of an image, in which case the image is used.
+##     Each string must be unique.  The widget specifies a widget to show
+##     when that tab is pressed.  It must be a child of the tab notebook
+##     (required for grid management) and exist prior to the 'add' command
+##     being called.  The optional state can be normal (default), active or
+##     or disabled.  If active is given, then this tab becomes the active
+##     tab.  A unique tab id is returned.
+##
+## delete id
+##     Deletes the tab specified by id.  id may either by the unique id
+##     returned by the add command or the string used in the add command.
+##
+## itemconfigure ?option? ?value option value ...?
+## itemcget option
+##     Configure or retrieve the option of a tab notebook item.
+##
+## name tabId
+##     Returns the text name for a given tabId.
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are hold (a frame), tabs (a canvas), blank (a frame).
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     Public procs of $CLASSNAME and [string tolower $CLASSNAME] are used.
+## Other procs that begin with $CLASSNAME are private.  For each widget,
+## commands named .$widgetname and $CLASSNAME$widgetname are created.
+##
+## EXAMPLE USAGE:
+##
+##
+##------------------------------------------------------------------------
+
+#package require Widget 1.0
+package provide Tabnotebook 1.3
+
+array set Tabnotebook {
+    type               frame
+    base               frame
+    components         {
+       {frame hold hold {-relief raised -bd 1}}
+       {frame blank}
+       {frame hide hide \
+               {-background $data(-background) -height 1 -width 40}}
+       {canvas tabs tabs {-bg $data(-background) \
+               -highlightthickness 0 -takefocus 0}}
+    }
+
+    -activebackground  {activeBackground ActiveBackground {}}
+    -bg                        -background
+    -background                {ALIAS frame -background}
+    -bd                        -borderwidth
+    -borderwidth       {ALIAS frame -borderwidth}
+    -browsecmd         {browseCmd      BrowseCommand   {}}
+    -disabledbackground        {disabledBackground DisabledBackground #a3a3a3}
+    -normalbackground  {normalBackground normalBackground #c3c3c3}
+    -justify           {justify        Justify         center}
+    -minwidth          {minWidth       Width           -1}
+    -minheight         {minHeight      Height          -1}
+    -padx              {padX           PadX            4}
+    -pady              {padY           PadY            2}
+    -relief            {ALIAS frame -relief}
+    -linewidth         {lineWidth      LineWidth       1}
+    -linecolor         {lineColor      LineColor       black}
+}
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc Tabnotebook args {}
+proc tabnotebook args {}
+widget create Tabnotebook
+
+;proc Tabnotebook:construct {w args} {
+    upvar \#0 $w data
+
+    ## Private variables
+    array set data {
+       curtab  {}
+       numtabs 0
+       width   0
+       height  0
+       ids     {}
+    }
+
+    $data(tabs) yview moveto 0
+    $data(tabs) xview moveto 0
+
+    grid $data(tabs) -sticky ew
+    grid $data(hold) -sticky news
+    grid $data(blank) -in $data(hold) -row 0 -column 0 -sticky nsew
+    grid columnconfig $w 0 -weight 1
+    grid rowconfig $w 1 -weight 1
+    grid columnconfig $data(hold) 0 -weight 1
+    grid rowconfig $data(hold) 0 -weight 1
+
+    bind $data(tabs) <Configure> "
+    if {\[string compare $data(tabs) %W\]} return
+    Tabnotebook:resize [list $w] %w
+    "
+    bind $data(tabs) <2>               { %W scan mark %x 0 }
+    bind $data(tabs) <B2-Motion>       {
+       %W scan dragto %x 0
+       Tabnotebook:resize [winfo parent %W] [winfo width %W]
+    }
+}
+
+;proc Tabnotebook:configure { w args } {
+    upvar \#0 $w data
+
+    set truth {^(1|yes|true|on)$}
+    set post {}
+    foreach {key val} $args {
+       switch -- $key {
+           -activebackground {
+               if {[string compare $data(curtab) {}]} {
+                   $data(tabs) itemconfig POLY:$data(curtab) -fill $val
+               }
+               if {[string compare $val {}]} {
+                   $data(hide) config -bg $val
+               } else {
+                   lappend post {$data(hide) config -bg $data(-background)}
+               }
+           }
+           -background {
+               $data(tabs) config -bg $val
+               $data(hold) config -bg $val
+               $data(blank) config -bg $val
+           }
+           -borderwidth {
+               $data(hold) config -bd $val
+               $data(hide) config -height $val
+           }
+           -disabledbackground {
+               foreach i $data(ids) {
+                   if {[string match disabled $data(:$i:-state)]} {
+                       $data(tabs) itemconfig POLY:$i -fill $val
+                   }
+               }
+           }
+           -justify    { $data(tabs) itemconfig TEXT -justify $val }
+           -linewidth  {
+               $data(tabs) itemconfigure LINE -width $val
+           }
+           -linecolor  {
+               $data(tabs) itemconfigure LINE -fill $val
+           }
+           -minwidth   {
+               if {$val >= 0} { grid columnconfig $w 0 -minsize $val }
+           }
+           -minheight  {
+               if {$val >= 0} { grid rowconfig $w 1 -minsize $val }
+           }
+           -normalbackground {
+               foreach i $data(ids) {
+                   if {[string match normal $data(:$i:-state)]} {
+                       $data(tabs) itemconfig POLY:$i -fill $val
+                   }
+               }
+           }
+           -padx - -pady {
+               if {$val <= 0} { set val 1 }
+           }
+           -relief {
+               $data(hold) config -relief $val
+           }
+       }
+       set data($key) $val
+    }
+    if {[string compare $post {}]} {
+       eval [join $post \n]
+    }
+}
+
+;proc Tabnotebook_add { w text args } {
+    upvar \#0 $w data
+
+    set c $data(tabs)
+    if {[string match {} $text]} {
+       return -code error "non-empty text required for noteboook label"
+    } elseif {[string compare {} [$c find withtag ID:$text]]} {
+       return -code error "tab \"$text\" already exists"
+    }
+    array set s {
+       -window {}
+       -state  normal
+    }
+    foreach {key val} $args {
+       switch -glob -- $key {
+           -w* {
+               if {[string compare $val {}]} {
+                   if {![winfo exist $val]} {
+                       return -code error "window \"$val\" does not exist"
+                   } elseif {[string comp $w [winfo parent $val]] && \
+                           [string comp $data(hold) [winfo parent $val]]} {
+                       return -code error "window \"$val\" must be a\
+                               child of the tab notebook ($w)"
+                   }
+               }
+               set s(-window) $val
+           }
+           -s* {
+               if {![regexp {^(normal|disabled|active)$} $val]} {
+                   return -code error "unknown state \"$val\", must be:\
+                           normal, disabled or active"
+               }
+               set s(-state) $val
+           }
+           default {
+               return -code error "unknown option '$key', must be:\
+                       [join [array names s] {, }]"
+           }
+       }
+    }
+    set tabnum [incr data(numtabs)]
+    set px $data(-padx)
+    set py $data(-pady)
+    if {[lsearch -exact [image names] $text] != -1} {
+       set i [$c create image $px $py -image $text -anchor nw \
+               -tags [list IMG ID:$text TAB:$tabnum]]
+    } else {
+       set i [$c create text [expr {$px+1}] $py -text $text -anchor nw \
+               -tags [list TEXT ID:$text TAB:$tabnum] \
+               -justify $data(-justify)]
+    }
+    foreach {x1 y1 x2 y2} [$c bbox $i] {
+       set W  [expr {$x2-$x1+$px}]
+       set FW [expr {$W+$px}]
+       set FH [expr {$y2-$y1+3*$py}]
+    }
+    set diff [expr {$FH-$data(height)}]
+    if {$diff > 0} {
+       $c move all 0 $diff
+       $c move $i 0 -$diff
+       set data(height) $FH
+    }
+    $c create poly 0 $FH $px $py $W $py $FW $FH -fill {} \
+           -tags [list POLY POLY:$tabnum TAB:$tabnum]
+    $c create line 0 $FH $px $py $W $py $FW $FH \
+           -tags [list LINE LINE:$tabnum TAB:$tabnum] \
+           -width $data(-linewidth) -fill $data(-linecolor)
+    $c move TAB:$tabnum $data(width) [expr {($diff<0)?-$diff:0}]
+    $c raise $i
+    $c raise LINE:$tabnum
+    incr data(width) $FW
+    $c config -width $data(width) -height $data(height) \
+           -scrollregion "0 0 $data(width) $data(height)"
+    $c bind TAB:$tabnum <1> [list Tabnotebook_activate $w $tabnum]
+    array set data [list :$tabnum:-window $s(-window) \
+           :$tabnum:-state $s(-state)]
+    if {[string compare $s(-window) {}]} {
+       grid $s(-window) -in $data(hold) -row 0 -column 0 -sticky nsew
+       lower $s(-window)
+    }
+    switch $s(-state) {
+       active  { Tabnotebook_activate $w $tabnum }
+       disabled {$c itemconfig POLY:$tabnum -fill $data(-disabledbackground)}
+       normal  {$c itemconfig POLY:$tabnum -fill $data(-normalbackground)}
+    }
+    lappend data(ids) $tabnum
+    return $tabnum
+}
+
+;proc Tabnotebook_activate { w id } {
+    upvar \#0 $w data
+
+    if {[string compare $id {}]} {
+       set tab [Tabnotebook:verify $w $id]
+       if {[string match disabled $data(:$tab:-state)]} return
+    } else {
+       set tab {}
+    }
+    if {[string match $data(curtab) $tab]} return
+    set c $data(tabs)
+    set oldtab $data(curtab)
+    if {[string compare $oldtab {}]} {
+       $c itemconfig POLY:$oldtab -fill $data(-normalbackground)
+       set data(:$oldtab:-state) normal
+    }
+    set data(curtab) $tab
+    if {[string compare $tab {}]} {
+       set data(:$tab:-state) active
+       $c itemconfig POLY:$tab -fill $data(-activebackground)
+    }
+    if {[info exists data(:$tab:-window)] && \
+           [winfo exists $data(:$tab:-window)]} {
+       raise $data(:$tab:-window)
+    } else {
+       raise $data(blank)
+    }
+    Tabnotebook:resize $w [winfo width $w]
+    if {[string comp $data(-browsecmd) {}]} {
+       uplevel \#0 $data(-browsecmd) \
+               [list [Tabnotebook_name $w $oldtab] [Tabnotebook_name $w $tab]]
+    }
+}
+
+;proc Tabnotebook_delete { w id } {
+    upvar \#0 $w data
+
+    set tab [Tabnotebook:verify $w $id]
+    set c $data(tabs)
+    foreach {x1 y1 x2 y2} [$c bbox TAB:$tab] { set W [expr {$x2-$x1-3}] }
+    $c delete TAB:$tab
+    for { set i [expr {$tab+1}] } { $i <= $data(numtabs) } { incr i } {
+       $c move TAB:$i -$W 0
+    }
+    foreach {x1 y1 x2 y2} [$c bbox all] { set H [expr {$y2-$y1-3}] }
+    if {$H<$data(height)} {
+       $c move all 0 [expr {$H-$data(height)}]
+       set data(height) $H
+    }
+    incr data(width) -$W
+    $c config -width $data(width) -height $data(height) \
+           -scrollregion "0 0 $data(width) $data(height)"
+    set i [lsearch $data(ids) $tab]
+    set data(ids) [lreplace $data(ids) $i $i]
+    catch {grid forget $data(:$tab:-window)}
+    unset data(:$tab:-state) data(:$tab:-window)
+    if {[string match $tab $data(curtab)]} {
+       set data(curtab) {}
+       raise $data(blank)
+    }
+}
+
+;proc Tabnotebook_itemcget { w id key } {
+    upvar \#0 $w data
+
+    set tab [Tabnotebook:verify $w $id]
+    set opt [array names data :$tab:$key*]
+    set len [llength $opt]
+    if {$len == 1} {
+       return $data($opt)
+    } elseif {$len == 0} {
+       set all [array names data :$tab:-*]
+       foreach o $all { lappend opts [lindex [split $o :] end] }
+       return -code error "unknown option \"$key\", must be one of:\
+               [join $opts {, }]"
+    } else {
+       foreach o $opt { lappend opts [lindex [split $o :] end] }
+       return -code error "ambiguous option \"$key\", must be one of:\
+               [join $opts {, }]"
+    }
+}
+
+;proc Tabnotebook_itemconfigure { w id args } {
+    upvar \#0 $w data
+
+    set tab [Tabnotebook:verify $w $id]
+    set len [llength $args]
+    if {$len == 1} {
+       return [uplevel Tabnotebook_itemcget $w $tab $args]
+    } elseif {$len&1} {
+       return -code error "uneven set of key/value pairs in \"$args\""
+    }
+    if {[string match {} $args]} {
+       set all [array names data :$tab:-*]
+       foreach o $all { lappend res [lindex [split $o :] end] $data($o) }
+       return $res
+    }
+    foreach {key val} $args {
+       switch -glob -- $key {
+           -w* {
+               if {[string comp $val {}]} {
+                   if {![winfo exist $val]} {
+                       return -code error "window \"$val\" does not exist"
+                   } elseif {[string comp $w [winfo parent $val]] && \
+                           [string comp $data(hold) [winfo parent $val]]} {
+                       return -code error "window \"$val\" must be a\
+                               child of the tab notebook ($w)"
+                   }
+               }
+               set old $data(:$tab:-window)
+               if {[winfo exists $old]} { grid forget $old }
+               set data(:$tab:-window) $val
+               if {[string comp $val {}]} {
+                   grid $val -in $data(hold) -row 0 -column 0 \
+                           -sticky nsew
+                   lower $val
+               }
+               if {[string match active $data(:$tab:-state)]} {
+                   if {[string comp $val {}]} {
+                       raise $val
+                   } else {
+                       raise $data(blank)
+                   }
+               }
+           }
+           -s* {
+               if {![regexp {^(normal|disabled|active)$} $val]} {
+                   return -code error "unknown state \"$val\", must be:\
+                           normal, disabled or active"
+               }
+               if {[string match $val $data(:$tab:-state)]} return
+               set old $data(:$tab:-state)
+               switch $val {
+                   active              {
+                       set data(:$tab:-state) $val
+                       Tabnotebook_activate $w $tab
+                   }
+                   disabled    {
+                       if {[string match active $old]} {
+                           Tabnotebook_activate $w {}
+                       }
+                       $data(tabs) itemconfig POLY:$tab \
+                               -fill $data(-disabledbackground)
+                       set data(:$tab:-state) $val
+                   }
+                   normal              {
+                       if {[string match active $old]} {
+                           Tabnotebook_activate $w {}
+                       }
+                       $data(tabs) itemconfig POLY:$tab -fill {}
+                       set data(:$tab:-state) $val
+                   }
+               }
+           }
+           default {
+               return -code error "unknown option '$key', must be:\
+                       [join [array names s] {, }]"
+           }
+       }
+    }
+}
+
+## given a tab number, return the text
+;proc Tabnotebook_name { w id } {
+    upvar \#0 $w data
+
+    if {[string match {} $id]} return
+    set text {}
+    foreach item [$data(tabs) find withtag TAB:$id] {
+       set tags [$data(tabs) gettags $item]
+       if {[set i [lsearch -glob $tags {ID:*}]] != -1} {
+           set text [string range [lindex $tags $i] 3 end]
+           break
+       }
+    }
+    return $text
+}
+
+;proc Tabnotebook:resize { w x } {
+    upvar \#0 $w data
+
+    if {[string compare $data(curtab) {}]} {
+       set x [expr {round(-[$data(tabs) canvasx 0])}]
+       foreach {x1 y1 x2 y2} [$data(tabs) bbox TAB:$data(curtab)] {
+           place $data(hide) -y [winfo y $data(hold)] -x [expr {$x1+$x+3}]
+           $data(hide) config -width [expr {$x2-$x1-5}]
+       }
+    } else {
+       place forget $data(hide)
+    }
+}
+
+;proc Tabnotebook:see { w id } {
+    upvar \#0 $w data
+
+    set c $data(tabs)
+    set box [$c bbox $id]
+    if {[string match {} $box]} return
+    foreach {x y x1 y1} $box {left right} [$c xview] \
+           {p q xmax ymax} [$c cget -scrollregion] {
+       set xpos [expr (($x1+$x)/2.0)/$xmax - ($right-$left)/2.0]
+    }
+    $c xview moveto $xpos
+}
+
+;proc Tabnotebook:verify { w id } {
+    upvar \#0 $w data
+
+    set c $data(tabs)
+    if {[string comp {} [set i [$c find withtag ID:$id]]]} {
+       if {[regexp {TAB:([0-9]+)} [$c gettags [lindex $i 0]] junk id]} {
+           return $id
+       }
+    } elseif {[string comp {} [$c find withtag TAB:$id]]} {
+       return $id
+    }
+    return -code error "unrecognized tab \"$id\""
+}
+
diff --git a/tcl/tclIndex b/tcl/tclIndex
new file mode 100644 (file)
index 0000000..711522e
--- /dev/null
@@ -0,0 +1,79 @@
+# Tcl autoload index file, version 2.0
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(widget) [list source [file join $dir widget.tcl]]
+set auto_index(ScrolledText) [list source [file join $dir widget.tcl]]
+set auto_index(scrolledtext) [list source [file join $dir widget.tcl]]
+set auto_index(planchet) [list source [file join $dir planchet.tcl]]
+set auto_index(balloonhelp) [list source [file join $dir balloonhelp.tcl]]
+set auto_index(Tabnotebook) [list source [file join $dir tabnotebook.tcl]]
+set auto_index(tabnotebook) [list source [file join $dir tabnotebook.tcl]]
+set auto_index(Console) [list source [file join $dir console.tcl]]
+set auto_index(console) [list source [file join $dir console.tcl]]
+set auto_index(ConsoleDialog) [list source [file join $dir console.tcl]]
+set auto_index(consoledialog) [list source [file join $dir console.tcl]]
+set auto_index(console_dialog) [list source [file join $dir console.tcl]]
+set auto_index(echo) [list source [file join $dir console.tcl]]
+set auto_index(alias) [list source [file join $dir console.tcl]]
+set auto_index(dump) [list source [file join $dir console.tcl]]
+set auto_index(which) [list source [file join $dir console.tcl]]
+set auto_index(dir) [list source [file join $dir console.tcl]]
+set auto_index(lremove) [list source [file join $dir console.tcl]]
+set auto_index(unknown) [list source [file join $dir console.tcl]]
+set auto_index(tcl_unknown) [list source [file join $dir console.tcl]]
+set auto_index(Calculator) [list source [file join $dir calculator.tcl]]
+set auto_index(calculator) [list source [file join $dir calculator.tcl]]
+set auto_index(Combobox) [list source [file join $dir combobox.tcl]]
+set auto_index(combobox) [list source [file join $dir combobox.tcl]]
+set auto_index(Help) [list source [file join $dir help.tcl]]
+set auto_index(help) [list source [file join $dir help.tcl]]
+set auto_index(HelpDialog) [list source [file join $dir help.tcl]]
+set auto_index(helpdialog) [list source [file join $dir help.tcl]]
+set auto_index(help_dialog) [list source [file join $dir help.tcl]]
+set auto_index(Progressbar) [list source [file join $dir progressbar.tcl]]
+set auto_index(progressbar) [list source [file join $dir progressbar.tcl]]
+set auto_index(Ventry) [list source [file join $dir ventry.tcl]]
+set auto_index(ventry) [list source [file join $dir ventry.tcl]]
+set auto_index(Hierarchy) [list source [file join $dir hierarchy.tcl]]
+set auto_index(hierarchy) [list source [file join $dir hierarchy.tcl]]
+set auto_index(hierarchy_dir) [list source [file join $dir hierarchy.tcl]]
+set auto_index(hierarchy_widget) [list source [file join $dir hierarchy.tcl]]
+set auto_index(layer) [list source [file join $dir layer.tcl]]
+set auto_index(legend) [list source [file join $dir legend.tcl]]
+set {auto_index($legname)} [list source [file join $dir legend.tcl]]
+set auto_index(fgisLegend_title) [list source [file join $dir legend.tcl]]
+set auto_index(fgisLegend_subtitle) [list source [file join $dir legend.tcl]]
+set auto_index(fgisLegend_print) [list source [file join $dir legend.tcl]]
+set auto_index(fgisLegend_set) [list source [file join $dir legend.tcl]]
+set auto_index(fgisLegend_drawable) [list source [file join $dir legend.tcl]]
+set auto_index(fgisLegend_delete) [list source [file join $dir legend.tcl]]
+set auto_index(show_legend) [list source [file join $dir legend.tcl]]
+set auto_index(color_box) [list source [file join $dir legend.tcl]]
+set auto_index(fgisMakeObjectName) [list source [file join $dir objects.tcl]]
+set auto_index(fgisCheckName) [list source [file join $dir objects.tcl]]
+set auto_index(fgisSetObj) [list source [file join $dir objects.tcl]]
+set auto_index(fgisSetList) [list source [file join $dir objects.tcl]]
+set auto_index(getopt) [list source [file join $dir getopt.tcl]]
+set auto_index(handleopt) [list source [file join $dir getopt.tcl]]
+set auto_index(checkbooleanopt) [list source [file join $dir getopt.tcl]]
+set auto_index(checklistopt) [list source [file join $dir getopt.tcl]]
+set auto_index(checkintopt) [list source [file join $dir getopt.tcl]]
+set auto_index(toolbar) [list source [file join $dir toolbar.tcl]]
+set auto_index(__ruler_y) [list source [file join $dir toolbar.tcl]]
+set auto_index(__show_scale) [list source [file join $dir toolbar.tcl]]
+set auto_index(fgisPrintDialog) [list source [file join $dir toolbar.tcl]]
+set auto_index(open_layer) [list source [file join $dir viewer.tcl]]
+set auto_index(show_layer) [list source [file join $dir viewer.tcl]]
+set auto_index(add_layer) [list source [file join $dir viewer.tcl]]
+set auto_index(select_layers) [list source [file join $dir viewer.tcl]]
+set auto_index(setup_look) [list source [file join $dir viewer.tcl]]
+set auto_index(select_layer) [list source [file join $dir viewer.tcl]]
+set auto_index(close_layer) [list source [file join $dir viewer.tcl]]
+set auto_index(save_layer) [list source [file join $dir viewer.tcl]]
+set auto_index(confirmExit) [list source [file join $dir viewer.tcl]]
+set auto_index(HMinit_win) [list source [file join $dir html_library.tcl]]
diff --git a/tcl/toolbar.tcl b/tcl/toolbar.tcl
new file mode 100644 (file)
index 0000000..9903b77
--- /dev/null
@@ -0,0 +1,145 @@
+#
+# toolbar.tcl - some standard interface gadgets for fGIS
+#  
+#
+
+#
+# Creates standard fGIS toolbar for given planchet
+# Planchet should exist, otherwise you'll have hard time passing
+# all toolbar buttons to corresponding planchet options
+# wpath is pathname for frame which would be created for toolbar
+#
+option add *Toolbar*Font -*-times-bold-r-normal--10-* widgetDefault
+
+proc toolbar {wpath planchet} {
+global  fgis
+set $wpath\(ruler) off
+frame $wpath -class Toolbar
+button $wpath.print -image [image create bitmap -data {
+#define printer_width 16
+#define printer_height 16
+static unsigned char printer_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10,
+  0x08, 0x08, 0x08, 0x08, 0xfe, 0x3f, 0x01, 0x40, 0x01, 0x5c, 0x01, 0x40,
+  0x01, 0x40, 0xfe, 0x3f, 0x04, 0x10, 0xfc, 0x1f, };
+}] -padx 0 -pady 0 -command [list fgisPrintDialog $planchet]
+button $wpath.zoom -image [image create bitmap -data {
+#define zoom_width 16
+#define zoom_height 16
+static unsigned char zoom_bits[] = {
+  0x00, 0x0e, 0x80, 0x31, 0x40, 0x4e, 0x40, 0x51, 0xa0, 0xa4, 0xa0, 0xae,
+  0xa0, 0xa4, 0x40, 0x51, 0x40, 0x4e, 0xa0, 0x31, 0x50, 0x0e, 0x28, 0x00,
+  0x14, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x03, 0x00, };
+}] -padx 0 -pady 0 -command "$planchet zoom"
+button $wpath.unzoom -image [image create bitmap -data {
+#define unzoom_width 16
+#define unzoom_height 16
+static unsigned char unzoom_bits[] = {
+  0x00, 0x0e, 0x80, 0x31, 0x40, 0x4e, 0x40, 0x51, 0xa0, 0xa0, 0xa0, 0xae,
+  0xa0, 0xa0, 0x40, 0x51, 0x40, 0x4e, 0xa0, 0x31, 0x50, 0x0e, 0x28, 0x00,
+  0x14, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x03, 0x00, };
+}] -padx 0 -pady 0 -command "$planchet unzoom"
+button $wpath.all -image [image create bitmap -data {
+#define unzoomall_width 16
+#define unzoomall_height 16
+static unsigned char unzoomall_bits[] = {
+  0x00, 0x8e, 0x8c, 0xf1, 0x5a, 0x7e, 0x70, 0x59, 0xa0, 0xae, 0xe0, 0xa7,
+  0xe0, 0xa1, 0xc0, 0x51, 0x70, 0x4f, 0xb8, 0x33, 0x5e, 0x0e, 0x2f, 0x08,
+  0x15, 0x18, 0x0a, 0x30, 0x05, 0x60, 0x03, 0xc0, };
+}] -padx 0 -pady 0 -command "$planchet limits default"
+button $wpath.left -image [image create bitmap -data {
+#define left_width 11
+#define left_height 10
+static unsigned char left_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x01, 0xf8, 0x01, 0xfe, 0x01,
+  0xf8, 0x01, 0xe0, 0x01, 0x80, 0x01, 0x00, 0x00, };
+}] -pady 3 -padx 2 -command "$planchet shift left"
+button $wpath.up -image [image create bitmap -data {
+#define up_width 10
+#define up_height 10
+static unsigned char up_bits[] = {
+  0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, 0x70, 0x00, 0xf8, 0x00,
+  0xf8, 0x00, 0xfc, 0x01, 0xfc, 0x01, 0x00, 0x00, };
+}] -pady 3 -padx 2 -command "$planchet shift up"
+button $wpath.down -image [image create bitmap -data {
+#define down_width 10
+#define down_height 10
+static unsigned char down_bits[] = {
+  0x00, 0x00, 0xfc, 0x01, 0xfc, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0x70, 0x00,
+  0x70, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, };
+}] -padx 2 -pady 3 -command "$planchet shift down"
+button $wpath.right -image [image create bitmap -data {
+#define right_width 11
+#define right_height 10 
+static unsigned char right_bits[] = {
+  0X00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x3c, 0x00, 0xfc, 0x00, 0xfc, 0x03, 
+  0xfc, 0x00, 0x3c, 0x00, 0x0c, 0x00, 0x00, 0x00, };
+}] -padx 2 -pady 3 -command "$planchet shift right"
+checkbutton $wpath.ruler -image [image create bitmap -data {
+#define ruler_width 16
+#define ruler_height 16
+static char ruler_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x40, 0x22, 0x44, 0xfe, 0x7f, 0xfe, 0x7f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+}] -bd 3  -indicatoron 0 -variable $wpath\(ruler) \
+   -onvalue on -offvalue off \
+ -command "$planchet ruler \[set $wpath\(ruler)]"
+upvar #0 $wpath data
+set data(ruler) off 
+label $wpath.scale -textvariable "$wpath\(scale)" 
+pack $wpath.print $wpath.zoom $wpath.unzoom $wpath.all $wpath.ruler -side left
+pack $wpath.scale -side left -padx 20
+pack $wpath.right $wpath.up $wpath.down $wpath.left -side right
+if [winfo exists $planchet] {
+ $planchet configure -zoombutton $wpath.zoom -unzoombuttons\
+          [list $wpath.unzoom $wpath.all] -shiftbuttons \
+          [list $wpath.left $wpath.down $wpath.up $wpath.right]\
+          -scalevar $wpath\(scale) 
+ $planchet ruler off
+}
+}
+
+proc __ruler_y {canvas} {
+return [expr [winfo height $canvas] - [$canvas canvasy 1c]+[$canvas canvasy 0c]]
+}
+
+proc __show_scale {widget var index op} {
+global map_items
+if [llength $map_items($index)]==4 {
+ set canvas [lindex [split $index ","] 0]
+ $widget configure -text "Scale 1:[mapscale $canvas]"
+} else { 
+ $widget configure -text "Scale unknown"
+}
+}
+
+proc fgisPrintDialog planchet {
+global fgis
+set dialog [toplevel $planchet.print]
+wm title $dialog "Print setup"
+wm transient $dialog [winfo toplevel $planchet]
+radiobutton $dialog.l1 -text "Printer" -value {} -variable\
+    fgisPrint(dest) -anchor w\
+ -command  "$dialog.file configure -state disabled;
+   $dialog.printer configure -state normal
+   $dialog.browse configure -state disabled"
+entry $dialog.printer -width 10 -textvar fgis(printer) 
+uplevel set fgisPrint(dest) {}  
+$dialog.printer insert end $fgis(printer)
+radiobutton $dialog.l2 -text "File" -value "-file \$fgisPrint(file)"\
+ -var fgisPrint(dest) -anchor w\
+ -command  "$dialog.file configure -state normal;
+   $dialog.printer configure -state disabled
+   $dialog.browse configure -state normal"
+entry $dialog.file -textvar fgisPrint(file) -width 20 -state disable
+button $dialog.browse -text "Browse.." -command \
+    {set fgisPrint(file) [tk_getSaveFile]} -state disable
+button $dialog.ok -text Ok -command "eval $planchet print \$fgisPrint(dest) ;\
+            destroy $dialog"
+button $dialog.cancel -text Cancel -command "destroy $dialog"
+grid $dialog.l1 - $dialog.printer - - -sticky news
+grid $dialog.l2 - $dialog.file - - $dialog.browse -sticky news
+grid x $dialog.ok - x $dialog.cancel x -sticky news 
+}
+
diff --git a/tcl/ventry.tcl b/tcl/ventry.tcl
new file mode 100644 (file)
index 0000000..348f2aa
--- /dev/null
@@ -0,0 +1,241 @@
+##
+## ventry.tcl
+##
+## self-validating entry widget
+##
+## Copyright 1997 Jeffrey Hobbs, CADIX International
+##
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     ventry
+##
+## DESCRIPTION
+##     Implements a self-validating entry widget
+##
+## ARGUMENTS
+##     ventry <widget> ?options?
+##
+## OPTIONS
+##     
+##
+##
+## RETURNS: the widget name
+##
+## BINDINGS: 
+##
+##------------------------------------------------------------------------
+##
+## Example use at end of file
+##
+
+
+########################################################################
+############################# Ventry ###############################
+########################################################################
+
+array set Ventry {
+    type               frame
+    base               entry
+    components         {label}
+
+    -bd                        -borderwidth
+    -borderwidth       {borderWidth    BorderWidth     0}
+    -invalidcmd                {invalidCmd     InvalidCmd      bell}
+    -labeltext         {labelText      LabelText       {}}
+    -labelwidth                {labelWidth     Width           0}
+    -labelanchor       {ALIAS label -anchor labelAnchor Anchor}
+    -labelfont         {ALIAS label -font labelFont Font}
+    -labelforeground   {ALIAS label -foreground labelForeground Foreground}
+    -relief            {relief         Relief          flat}
+    -validatecmd       -vcmd
+    -vcmd              {validateCmd    ValidateCmd     {}}
+    -validate          {validate       Validate        none}
+    -textvariable      {textVariable   TextVariable    {}}
+}
+
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc Ventry args {}
+proc ventry args {}
+widget create Ventry
+
+;proc Ventry:construct {w args} {
+    upvar \#0 $w data
+
+    set data(flags) {}
+
+    grid $data(label) $data(entry) -in $w -sticky ns
+    grid configure $data(entry) -sticky news
+    grid columnconfig $w 1 -weight 1
+    grid rowconfig $w 0 -weight 1
+    grid remove $data(label)
+
+    bind $data(entry) <FocusIn>  [list Ventry:focus $w in]
+    bind $data(entry) <FocusOut> [list Ventry:focus $w out]
+}
+
+;proc Ventry:configure {w args} {
+    upvar \#0 $w data
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+           -borderwidth - -relief { .$w configure $key $val }
+           -labelanchor        { $data(label) configure -anchor $val }
+           -labelfont          { $data(label) configure -font $val }
+           -labelforeground    { $data(label) configure -foreground $val }
+           -labeltext          {
+               $data(label) configure -text $val
+               if {[string compare {} $val]} {
+                   grid $data(label)
+               } else {
+                   grid remove $data(label)
+               }
+           }
+           -labelwidth         { $data(label) configure -width $val }
+           -validate {
+               if {![regexp {^(focus|focusin|focusout|all|none|key)$} $val]} {
+                   return -code error "Invalid validation type \"$val\""
+               }
+           }
+           -textvariable       { $data(basecmd) configure -textvariable $val }
+       }
+       set data($key) $val
+    }
+}
+
+;proc Ventry_insert {w index string} {
+    upvar \#0 $w data
+
+    if {[regexp {^(all|key)$} $data(-validate)]} {
+       set index [$data(basecmd) index $index]
+       set cur [$data(basecmd) get]
+       set new [string range $cur 0 [expr $index-1]]$string[string range $cur $index end]
+       if {[catch {Ventry:validate $w $string $new $index insert} err]} {
+           return
+       }
+    }
+    return [uplevel [list $data(basecmd) insert $index $string]]
+}
+
+;proc Ventry_delete {w first {last {}}} {
+    upvar \#0 $w data
+
+    if {[regexp {^(all|key)$} $data(-validate)]} {
+       set first [$data(basecmd) index $first]
+       if {[string match {} $last]} {
+           set last [expr $first+1]
+       } else {
+           set last [$data(basecmd) index $last]
+       }
+       set cur [$data(basecmd) get]
+       set new [string range $cur 0 [expr $first-1]][string range $cur $last end]
+       if {[catch {Ventry:validate $w [string range $cur $first \
+               [expr $last-1]] $new $first delete} err]} {
+           return
+       }
+    }
+    return [uplevel [list $data(basecmd) delete $first] $last]
+}
+
+;proc Ventry_validate {w} {
+    upvar \#0 $w data
+
+    set old $data(-validate)
+    set data(-validate) all
+    set code [catch {Ventry:validate $w {} [$data(basecmd) get] \
+           [$data(basecmd) index insert] validate} err]
+    set data(-validate) $old
+    return [expr {$code?0:1}]
+}
+
+;proc Ventry:focus {w which} {
+    upvar \#0 $w data
+
+    if {[regexp "^(all|focus($which)?)\$" $data(-validate)]} {
+       catch {Ventry:validate $w {} [$data(basecmd) get] \
+               [$data(basecmd) index insert] focus$which}
+    }
+}
+
+;proc Ventry:validate {w str new index type} {
+    upvar \#0 $w data
+
+    if {[string match {} $data(-vcmd)] || \
+           [string match none $data(-validate)]} {
+       return
+    }
+    set data(flags) VALIDATING
+
+    set cmd [Ventry:substitute $w $data(-vcmd) $str $new $index $type]
+
+    set code [catch {uplevel \#0 $cmd} result]
+    if {$code != 0 && $code != 2} {
+       global errorInfo
+       append errorInfo "\n\t(in $w validation command)"
+       bgerror $result
+       set code 1
+    } else {
+       set val [regexp {^(1|yes|true|on)$} $result]
+       if $val { set code 0 } else { set code 3 }
+       set result {}
+    }
+
+    # If e->validate has become VALIDATE_NONE during the validation,
+    # it means that a loop condition almost occured.  Do not allow
+    # this validation result to finish.
+    if {[string match none $data(-validate)] || \
+           [string match VALIDATE_VAR $data(flags)]} {
+       set code 1
+    }
+    # If validate will return ERROR, then disallow further validations
+    # Otherwise, if it didn't accept the new string (returned TCL_BREAK)
+    # then eval the invalidCmd (if it's set)
+    if {$code} {
+       if {$code == 3} {
+           ## TCL_BREAK
+           if {[string compare {} $data(-invalidcmd)]} {
+               set cmd [Ventry:substitute $w $data(-invalidcmd) \
+                       $str $new $index $type]
+               if {[catch {uplevel \#0 $cmd} result]} {
+                   global errorInfo
+                   append errorInfo "\n\t(in $w validation command)"
+                   bgerror $result
+                   set code 1
+                   set data(-validate) none
+               }
+           }
+       } else {
+           set data(-validate) none
+       }
+    }
+    set data(flags) {}
+    return -code $code $result
+}
+
+;proc Ventry:substitute {w cmd change newstr index type} {
+    upvar \#0 $w data
+
+    set old $cmd
+    set i [string first % $cmd]
+    if {$i < 0} { return $old }
+    set new [string range $cmd 0 [incr i -1]]
+    while 1 {
+       set c [string index $cmd [incr i 2]]
+       switch $c {
+           d           { append new $type }
+           i           { append new $index }
+           P           { append new [list $newstr] }
+           s           { append new [list [$data(basecmd) get]] }
+           S           { append new [list $change] }
+           v           { append new $data(-validate) }
+           W           { append new [list $w] }
+           {}          { append new %; return $new }
+           default     { append new [list $c] }
+       }
+       set cmd [string range $cmd [incr i] end]
+       set i [string first % $cmd]
+       if {$i < 0} { return $new$cmd }
+       append new [string range $cmd 0 [incr i -1]]
+    }
+}
diff --git a/tcl/viewer.tcl b/tcl/viewer.tcl
new file mode 100644 (file)
index 0000000..d03987f
--- /dev/null
@@ -0,0 +1,200 @@
+# High-level operation with layers
+# 
+#
+
+proc open_layer {filename} {
+global layerFile
+if ![file exists $filename] {
+   if [file exist $filename.epp] {
+      append filename .epp
+   } else { 
+     tk_messageBox -message "File $filename doesn't exists" -type ok
+   }
+}
+if {[file extension $filename]==".epp"} {
+
+set basename [file rootname $filename]
+set layer [layer create raster -file $filename -title $basename ] 
+
+if [file exists $basename.leg] {
+   $layer configure -legfile $basename.leg
+   set legend [$layer cget -legend] 
+   if [string length [$legend title]] {
+    $layer configure -title [$legend title]
+   }
+}
+if [file exists $basename.clr] {
+   $layer configure -palfile $basename.clr
+}
+
+} else {
+ set layer [uplevel #0 source [list $filename]]
+ set layerFile($layer) $filename
+}
+ return $layer
+}
+
+
+#if ![llength $argv] {
+#  set argv [tk_getOpenFile -filetypes {{"Epp files" *.epp}
+#                                       {"fGIS layers" *.lay}}]
+#}
+
+proc show_layer {layer} {
+  global planchet  
+  if ![string length $layer] return
+  wm title . "Mapview: [$layer title]" 
+  $planchet show $layer -base
+}
+
+proc add_layer {{file {}}} {
+  global planchet
+  if ![string length $file] {
+  set file [tk_getOpenFile -filetypes {{"Epp files" *.epp}
+                                       {"fGIS layers" *.lay}}]
+ }
+  if ![string length $file] return
+  set layer [open_layer $file]
+  if ![llength [$planchet layers]] {
+    show_layer $layer 
+  }
+  $planchet look add $layer
+  catch {.menu.file.m entryconfig "Save..." -state normal}
+  catch {.menu.file.m entryconfig "Close..." -state normal}
+  foreach i {1 2 3} {
+    catch {.menu.layer.m entryconfig $i -state normal}
+  }
+
+}
+
+proc select_layers {} {
+  global planchet
+  foreach layer [$planchet look list] {
+    set on($layer) 1
+  }
+  catch {destroy .chooser}
+  toplevel .chooser
+  wm title .chooser "Select layer"
+  frame .chooser.t
+  listbox .chooser.t.l -width 40 -height 10 -yscrollcommand ".chooser.t.y set" -selectmode extended
+  scrollbar .chooser.t.y -orient vert -command ".chooser.t.l yview"
+  pack .chooser.t.l .chooser.t.y -side left  -fill both -expand y 
+  pack .chooser.t -fill both -expand y
+  frame .chooser.b
+  button .chooser.b.ok -padx 10 -text "Apply" -command {setup_look .chooser.t.l}
+  button .chooser.b.cancel -padx 10 -text "Close" -command {destroy .chooser}
+  pack .chooser.b.ok -side left
+  pack .chooser.b.cancel -side left
+  pack .chooser.b 
+  set box .chooser.t.l
+  foreach layer [layer names] {
+     set n [$box size]
+     $box insert end [$layer title]
+     if [info exist on($layer)] {
+       $box selection set $n
+     } 
+  }
+
+}
+
+proc setup_look {box} {
+  global platnchet
+  set layers [layer names]
+  $planchet look remove all
+  foreach n [$box curselection] {
+    $planchet look add [lindex $layers $n]
+  }
+}
+
+proc select_layer {} {
+  global planchet 
+  catch {destroy .chooser}
+  toplevel .chooser
+  wm title .chooser "Select layer"
+  wm transient .chooser
+  frame .chooser.t
+  bind .chooser <Destroy> {set selectedLayer ""}
+  listbox .chooser.t.l -width 40 -height 10 -yscrollcommand ".chooser.t.y set" -exportselection false
+  scrollbar .chooser.t.y -orient vert -command ".chooser.t.l yview"
+  pack .chooser.t.l .chooser.t.y -side left  -fill both -expand y 
+  pack .chooser.t -fill both -expand y
+  frame .chooser.b
+  bind .chooser.t.l <Double-1> {set selectedLayer [.chooser.t.l index active]}
+  button .chooser.b.ok -padx 10 -text "Ok" -command {set selectedLayer [.chooser.t.l curselection]}
+  button .chooser.b.cancel -padx 10 -text "Cancel" -command {set selectedLayer ""}
+  pack .chooser.b.ok -side left
+  pack .chooser.b.cancel -side left
+  pack .chooser.b 
+  set box .chooser.t.l
+  set current [lindex [$planchet layers] 0]
+  foreach layer [layer names] {
+     set n [$box size]
+     $box insert end [$layer title]
+     if {"$layer"=="$current"} {
+       $box selection set $n
+     } 
+  }
+  global selectedLayer
+  vwait selectedLayer
+  if { $selectedLayer == ""} {
+    set result ""
+  } else {
+    set result [lindex [layer names] $selectedLayer]
+  }
+  catch {destroy .chooser}
+  return $result
+}
+  
+proc close_layer {layer} {
+  global modifiedLayers planchet
+  if ![string length $layer] return
+  if [info exist modifiedLayers($layer)] {
+     switch -exact -- [tk_messageBox -title "Warning" -message\
+         "This layer was modified. Save it?" -type yesnocancel] {
+     yes {save_layer $layer}
+     no  {}
+     cancel {return}
+     }
+  }
+  if {[llength [layer names]]==1} {
+      if {[tk_messageBox -title "Warning" -message "This is a last layer.\
+       Closing it would cause mapview to exit. Proceed?"\
+       -type yesno]=="no"} return else exit
+  
+  }
+  catch {$planchet look remove $layer}
+  $layer delete
+  if ![llength [$planchet layers]] {
+     show_layer [lindex [layer names] 0] 
+  }
+}
+
+proc save_layer {layer} {
+global layerFile layerModified
+if ![info exist layerFile($layer)] {
+  regsub -all "\[\t ]+" [$layer title] "_" filename
+  set filename [tk_getSaveFile -defaultextension ".lay" -initialfile $filename.lay] 
+  if ![string length $filename] return
+  set layerFile($layer) $filename
+}
+if [file exists $layerFile($layer)] {
+   set bakname "[file rootname $layerFile].bak"
+   if [file exists $bakname] {
+       file delete $bakname
+   }
+   file rename $layerFile($layer) $bakname
+}
+set f [open $layerFile($layer) w]
+puts $f [$layer dump]
+close $f
+catch {unset layerModified($layer)}
+}
+
+proc confirmExit {} {
+  global argv0
+   if {[tk_messageBox -title confirm -type yesno -message "Exit $argv0. Are
+   you sure"]=="yes"} {
+      destroy .
+   }
+}   
diff --git a/tcl/widget.tcl b/tcl/widget.tcl
new file mode 100644 (file)
index 0000000..373e2e7
--- /dev/null
@@ -0,0 +1,812 @@
+##
+## widget.tcl
+##
+## Barebones requirements for creating and querying megawidgets
+##
+## Copyright 1997 Jeffrey Hobbs, CADIX International
+##
+## Initiated: 5 June 1997
+## Last Update:
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     widget
+##
+## DESCRIPTION
+##     Implements and modifies megawidgets
+##
+## ARGUMENTS
+##     widget <subcommand> ?<args>?
+##
+## <classname> specifies a global array which is the name of a class and
+## contains options database information.
+##
+## create classname
+##     creates the widget class $classname based on the specifications
+##     in the global array of the same name
+##
+## classes ?pattern?
+##     returns the classes created with this command.
+##
+## OPTIONS
+##     none
+##
+## RETURNS: the widget class
+##
+## NAMESPACE & STATE
+##     The global variable WIDGET is used.  The public procedure is
+## 'widget', with other private procedures beginning with 'widget'.
+##
+##------------------------------------------------------------------------
+##
+## For a well-commented example for creating a megawidget using this method,
+## see the ScrolledText example at the end of the file.
+##
+## SHORT LIST OF IMPORTANT THINGS TO KNOW:
+##
+## Specify the "type", "base", & "components" keys of the $CLASS global array
+##
+## In the $w global array that is created for each instance of a megawidget,
+## the following keys are set by the "widget create $CLASS" procedure:
+##   "base", "basecmd", "container", "class", any option specified in the
+##   $CLASS array, each component will have a named key
+##
+## The following public methods are created for you:
+##   "cget", "configure", "destroy", & "subwidget"
+## You need to write the following:
+##   "$CLASS:construct", "$CLASS:configure"
+## You may want the following that will be called when appropriate:
+##   "$CLASS:init" (after initial configuration)
+##   "$CLASS:destroy" (called first thing when widget is being destroyed)
+##
+## All ${CLASS}_* commands are considered public methods.  The megawidget
+## routine will match your options and methods on a unique substring basis.
+##
+## END OF SHORT LIST
+
+package require Tk
+package provide Widget 1.12
+
+global WIDGET
+lappend WIDGET(containers) frame toplevel
+proc widget { cmd args } {
+    switch -glob $cmd {
+       cr*     { return [uplevel widget_create $args] }
+       cl*     { return [uplevel widget_classes $args] }
+       default {
+           return -code error "unknown [lindex [info level 0] 0] subcommand\
+                   \"$cmd\", must be one of: create, classes"
+       }
+    }
+}
+
+;proc widget_classes {{pattern "*"}} {
+    global WIDGET
+    set classes {}
+    foreach name [array names WIDGET C:$pattern] {
+       lappend classes [string range $name 2 end]
+    }
+    return $classes
+}
+
+;proc widget:eval {CLASS w subcmd args} {
+    upvar \#0 $w data
+    if {[string match {} [set arg [info commands ${CLASS}_$subcmd]]]} {
+       set arg [info commands ${CLASS}_$subcmd*]
+    }
+    set num [llength $arg]
+    if {$num==1} {
+       return [uplevel $arg [list $w] $args]
+    } elseif {$num} {
+       regsub -all "${CLASS}_" $arg {} arg
+       return -code error "ambiguous subcommand \"$subcmd\",\
+               could be one of: [join $arg {, }]"
+    } elseif {[catch {uplevel [list $data(basecmd) $subcmd] $args} err]} {
+       return -code error $err
+    } else {
+       return $err
+    }
+}
+
+;proc widget_create:constructor {CLASS} {
+    upvar \#0 $CLASS class
+    global WIDGET
+
+    lappend datacons [list class $CLASS]
+    set basecons {}
+    if {[string compare $class(type) [lindex $class(base) 0]]} {
+       lappend datacons "base \$w.[list [lindex $class(base) 2]]" \
+               "basecmd $CLASS\$w.[list [lindex $class(base) 2]]"
+       set comps "[list $class(base)] $class(components)"
+    } else {
+       lappend datacons "base \$w" "basecmd $CLASS\$w" \
+               "[lindex $class(base) 1] \$w"
+       set comps $class(components)
+    }
+    foreach comp $comps {
+       switch [llength $comp] {
+           0 continue
+           1 { set name [set type [set wid $comp]]; set opts {} }
+           2 {
+               set type [lindex $comp 0]
+               set name [set wid [lindex $comp 1]]
+               set opts {}
+           }
+           default {
+               foreach {type name wid opts} $comp break
+               set opts [string trim $opts]
+           }
+       }
+       lappend datacons "[list $name] \$w.[list $wid]"
+       lappend basecons "$type \$data($name) $opts"
+       if {[string match toplevel $type]} {
+           lappend basecons "wm withdraw \$data($name)"
+       }
+    }
+    set datacons [join $datacons]
+    set basecons [join $basecons "\n    "]
+    
+    ## More of this proc could be configured ahead of time for increased
+    ## construction speed.  It's delicate, so handle with extreme care.
+    ;proc $CLASS {w args} "
+    upvar \#0 \$w data $CLASS class
+    $class(type) \$w -class $CLASS
+    [expr [string match toplevel $class(type)]?{wm withdraw \$w\n}:{}]
+    ## Populate data array with user definable options
+    foreach o \[array names class -*\] {
+       if {\[string match -* \$class(\$o)\]} continue
+       set data(\$o) \[option get \$w \[lindex \$class(\$o) 0\] $CLASS\]
+    }
+
+    ## Populate the data array
+    array set data \[list $datacons\]
+    ## Create all the base and component widgets
+    $basecons
+
+    ## Allow for an initialization proc to be eval'ed
+    ## The user must create one
+    if {\[catch {$CLASS:construct \$w} err\]} {
+       catch {${CLASS}_destroy \$w}
+       return -code error \"megawidget construction error: \$err\"
+    }
+
+    set base \$data(base)
+    if {\[string compare \$base \$w\]} {
+       ## If the base widget is not the container, then we want to rename
+       ## its widget commands and add the CLASS and container bind tables
+       ## to its bindtags in case certain bindings are made
+       rename \$w .\$w
+       rename \$base \$data(basecmd)
+       ## Interp alias is the optimal solution, but exposes
+       ## a bug in Tcl7/8 when renaming aliases
+       #interp alias {} \$base {} widget:eval $CLASS \$w
+       ;proc \$base args \"uplevel widget:eval $CLASS \[list \$w\] \\\$args\"
+       bindtags \$base \[linsert \[bindtags \$base\] 1\
+               [expr {[string match toplevel $class(type)]?{}:{$w}}] $CLASS\]
+    } else {
+       rename \$w \$data(basecmd)
+    }
+    ;proc \$w args \"uplevel widget:eval $CLASS \[list \$w\] \\\$args\"
+    #interp alias {} \$w {} widget:eval $CLASS \$w
+
+    ## Do the configuring here and eval the post initialization procedure
+    if {(\[string compare {} \$args\] && \
+           \[catch {uplevel 1 ${CLASS}_configure \$w \$args} err\]) || \
+           \[catch {$CLASS:init \$w} err\]} {
+       catch { ${CLASS}_destroy \$w }
+       return -code error \"megawidget initialization error: \$err\"
+    }
+
+    return \$w\n"
+    interp alias {} [string tolower $CLASS] {} $CLASS
+
+    ## These are provided so that errors due to lack of the command
+    ## existing don't arise.  Since they are stubbed out here, the
+    ## user can't depend on 'unknown' or 'auto_load' to get this proc.
+    if {[string match {} [info commands $CLASS:construct]]} {
+       ;proc $CLASS:construct {w} {
+           # the user should rewrite this
+           # without the following error, a simple megawidget that was just
+           # a frame would be created by default
+           return -code error "user must write their own\
+                   [lindex [info level 0] 0] function"
+       }
+    }
+    if {[string match {} [info commands $CLASS:init]]} {
+       ;proc $CLASS:init {w} {
+           # the user should rewrite this
+       }
+    }
+}
+
+;proc widget_create {CLASS} {
+    if {![string match {[A-Z]*} $CLASS] || [string match { } $CLASS]} {
+       return -code error "invalid class name \"$CLASS\": it must begin\
+               with a capital letter and contain no spaces"
+    }
+
+    global WIDGET
+    upvar \#0 $CLASS class
+
+    ## First check to see that their container type is valid
+    if {[info exists class(type)]} {
+       ## I'd like to include canvas and text, but they don't accept the
+       ## -class option yet, which would thus require some voodoo on the
+       ## part of the constructor to make it think it was the proper class
+       if {![regexp ^([join $WIDGET(containers) |])\$ $class(type)]} {
+           return -code error "invalid class container type \"$class(type)\",\
+                   must be one of: [join $types {, }]"
+       }
+    } else {
+       ## Frame is the default container type
+       set class(type) frame
+    }
+    ## Then check to see that their base widget type is valid
+    ## We will create a default widget of the appropriate type just in
+    ## case they use the DEFAULT keyword as a default value in their
+    ## megawidget class definition
+    if {[info exists class(base)]} {
+       ## We check to see that we can create the base, that it returns
+       ## the same widget value we put in, and that it accepts cget.
+       if {[string match toplevel [lindex $class(base) 0]] && \
+               [string compare toplevel $class(type)]} {
+           return -code error "\"toplevel\" is not allowed as the base\
+                   widget of a megawidget (perhaps you intended it to\
+                   be the class type)"
+       }
+    } else {
+       ## The container is the default base widget
+       set class(base) $class(type)
+    }
+    set types($class(type)) 0
+    switch [llength $class(base)] {
+       1 { set name [set type [set wid $class(base)]]; set opts {} }
+       2 {
+           set type [lindex $class(base) 0]
+           set name [set wid [lindex $class(base) 1]]
+           set opts {}
+       }
+       default { foreach {type name wid opts} $class(base) break }
+    }
+    set class(base) [list $type $name $wid $opts]
+    if {[regexp {(^[\.A-Z]|[ \.])} $wid]} {
+       return -code error "invalid $CLASS class base widget name \"$wid\":\
+               it cannot begin with a capital letter,\
+               or contain spaces or \".\""
+    }
+    set components(base) [set components($name) $type]
+    set widgets($wid) 0
+    set types($type) 0
+
+    if {![info exists class(components)]} { set class(components) {} }
+    set comps $class(components)
+    set class(components) {}
+    ## Verify component widget list
+    foreach comp $comps {
+       ## We don't care if an opts item exists now
+       switch [llength $comp] {
+           0 continue
+           1 { set name [set type [set wid $comp]] }
+           2 {
+               set type [lindex $comp 0]
+               set name [set wid [lindex $comp 1]]
+           }
+           default { foreach {type name wid} $comp break }
+       }
+       if {[info exists components($name)]} {
+           return -code error "component name \"$name\" occurs twice\
+                   in $CLASS class"
+       }
+       if {[info exists widgets($wid)]} {
+           return -code error "widget name \"$wid\" occurs twice\
+                   in $CLASS class"
+       }
+       if {[regexp {(^[\.A-Z]| |\.$)} $wid]} {
+           return -code error "invalid $CLASS class component widget\
+                   name \"$wid\": it cannot begin with a capital letter,\
+                   contain spaces or start or end with a \".\""
+       }
+       if {[string match *.* $wid] && \
+               ![info exists widgets([file root $wid])]} {
+           ## If the widget name contains a '.', then make sure we will
+           ## have created all the parents first.  [file root $wid] is
+           ## a cheap trick to remove the last .child string from $wid
+           return -code error "no specified parent for $CLASS class\
+                   component widget name \"$wid\""
+       }
+       lappend class(components) $comp
+       set components($name) $type
+       set widgets($wid) 0
+       set types($type) 0
+    }
+
+    ## Go through the megawidget class definition, substituting for ALIAS
+    ## where necessary and setting up the options database for this $CLASS
+    foreach o [array names class -*] {
+       set name [lindex $class($o) 0]
+       switch -glob -- $name {
+           -*  continue
+           ALIAS       {
+               set len [llength $class($o)]
+               if {$len != 3 && $len != 5} {
+                   return -code error "wrong \# args for ALIAS, must be:\
+                           {ALIAS componenttype option\
+                           ?databasename databaseclass?}"
+               }
+               foreach {name type opt dbname dbcname} $class($o) break
+               if {![info exists types($type)]} {
+                   return -code error "cannot create alias \"$o\" to $CLASS\
+                           component type \"$type\" option \"$opt\":\
+                           component type does not exist"
+               } elseif {![info exists config($type)]} {
+                   if {[string compare toplevel $type]} {
+                       set w .__widget__$type
+                       catch {destroy $w}
+                       ## Make sure the component widget type exists,
+                       ## returns the widget name,
+                       ## and accepts configure as a subcommand
+                       if {[catch {$type $w} result] || \
+                               [string compare $result $w] || \
+                               [catch {$w configure} config($type)]} {
+                           ## Make sure we destroy it if it was a bad widget
+                           catch {destroy $w}
+                           ## Or rename it if it was a non-widget command
+                           catch {rename $w {}}
+                           return -code error "invalid widget type \"$type\""
+                       }
+                       catch {destroy $w}
+                   } else {
+                       set config($type) [. configure]
+                   }
+               }
+               set i [lsearch -glob $config($type) "$opt\[ \t\]*"]
+               if {$i == -1} {
+                   return -code error "cannot create alias \"$o\" to $CLASS\
+                           component type \"$type\" option \"$opt\":\
+                           option does not exist"
+               }
+               if {$len==3} {
+                   foreach {opt dbname dbcname def} \
+                           [lindex $config($type) $i] break
+               } elseif {$len==5} {
+                   set def [lindex [lindex $config($type) $i] 3]
+               }
+           }
+           default     {
+               if {[string compare {} $class($o)]} {
+                   foreach {dbname dbcname def} $class($o) break
+               } else {
+                   set dbcname [set dbname [string range $o 1 end]]
+                   set def {}
+               }
+           }
+       }
+       set class($o) [list $dbname $dbcname $def]
+       option add *$CLASS.$dbname $def widgetDefault
+    }
+    ## Ensure that the class is set correctly
+    set class(class) $CLASS
+
+    ## This creates the basic constructor procedure for the class
+    ## Both $CLASS and [string tolower $CLASS] commands will be created
+    widget_create:constructor $CLASS
+
+    ## The user is not supposed to change this proc
+    set comps [lsort [array names components]]
+    ;proc ${CLASS}_subwidget {w widget} "
+    upvar \#0 \$w data
+    switch -- \$widget {
+       [join $comps { - }] { return \$data(\$widget) }
+       default {
+           return -code error \"No \$data(class) subwidget \\\"\$widget\\\",\
+                   must be one of: [join $comps {, }]\"
+       }
+    }
+    "
+
+    ## The [winfo class %W] will work in this Destroy, which is necessary
+    ## to determine if we are destroying the actual megawidget container.
+    ## The ${CLASS}_destroy must occur to remove excess state elements.
+    ## This will break in Tk4.1p1, but work with any other 4.1+ version.
+    bind $CLASS <Destroy> "
+    if {\[string compare {} \[widget classes \[winfo class %W\]\]\]} {
+       catch {\[winfo class %W\]_destroy %W}
+    }
+    "
+
+    ## The user is not supposed to change this proc
+    ## Instead they create a $CLASS:destroy proc
+    ## Some of this may be redundant, but at least it does the job
+    ;proc ${CLASS}_destroy {w} "
+    upvar \#0 \$w data
+    catch { $CLASS:destroy \$w }
+    catch { destroy \$data(base) }
+    catch { destroy \$w }
+    catch { rename \$data(basecmd) {} }
+    catch { rename \$data(base) {} }
+    catch { rename \$w {} }
+    catch { unset data }
+    return\n"
+    
+    if {[string match {} [info commands $CLASS:destroy]]} {
+       ## The user can optionally provide a special destroy handler
+       ;proc $CLASS:destroy {w args}  {
+           # empty
+       }
+    }
+
+    ## The user is not supposed to change this proc
+    ;proc ${CLASS}_cget {w args} {
+       if {[llength $args] != 1} {
+           return -code error "wrong \# args: should be \"$w cget option\""
+       }
+       upvar \#0 $w data [winfo class $w] class
+       if {[info exists class($args)] && [string match -* $class($args)]} {
+           set args $class($args)
+       }
+       if {[string match {} [set arg [array names data $args]]]} {
+           set arg [array names data ${args}*]
+       }
+       set num [llength $arg]
+       if {$num==1} {
+           return $data($arg)
+       } elseif {$num} {
+           return -code error "ambiguous option \"$args\",\
+                   must be one of: [join $arg {, }]"
+       } elseif {[catch {$data(basecmd) cget $args} err]} {
+           return -code error $err
+       } else {
+           return $err
+       }
+    }
+
+    ## The user is not supposed to change this proc
+    ## Instead they create a $CLASS:configure proc
+    ;proc ${CLASS}_configure {w args} {
+       upvar \#0 $w data [winfo class $w] class
+
+       set num [llength $args]
+       if {$num==1} {
+           if {[info exists class($args)] && \
+                   [string match -* $class($args)]} {
+               set args $class($args)
+           }
+           if {[string match {} [set arg [array names data $args]]]} {
+               set arg [array names data ${args}*]
+           }
+           set num [llength $arg]
+           if {$num==1} {
+               ## FIX one-elem config
+               return "[list $arg] $class($arg) [list $data($arg)]"
+           } elseif {$num} {
+               return -code error "ambiguous option \"$args\",\
+                       must be one of: [join $arg {, }]"
+           } elseif {[catch {$data(basecmd) configure $args} err]} {
+               return -code error $err
+           } else {
+               return $err
+           }
+       } elseif {$num} {
+           ## Group the {key val} pairs to be distributed
+           if {$num&1} {
+               set last [lindex $args end]
+               set args [lrange $args 0 [incr num -2]]
+           }
+           set widargs {}
+           set cmdargs {}
+           foreach {key val} $args {
+               if {[info exists class($key)] && \
+                       [string match -* $class($key)]} {
+                   set key $class($key)
+               }
+               if {[string match {} [set arg [array names data $key]]]} {
+                   set arg [array names data $key*]
+               }
+               set len [llength $arg]
+               if {$len==1} {
+                   lappend widargs $arg $val
+               } elseif {$len} {
+                   set ambarg [list $key $arg]
+                   break
+               } else {
+                   lappend cmdargs $key $val
+               }
+           }
+           if {[string compare {} $widargs]} {
+               uplevel $class(class):configure [list $w] $widargs
+           }
+           if {[string compare {} $cmdargs] && [catch \
+                   {uplevel [list $data(basecmd)] configure $cmdargs} err]} {
+               return -code error $err
+           }
+           if {[info exists ambarg]} {
+               return -code error "ambiguous option \"[lindex $ambarg 0]\",\
+                       must be one of: [join [lindex $ambarg 1] {, }]"
+           }
+           if {[info exists last]} {
+               return -code error "value for \"$last\" missing"
+           }
+       } else {
+           foreach opt [$data(basecmd) configure] {
+               set options([lindex $opt 0]) [lrange $opt 1 end]
+           }
+           foreach opt [array names class -*] {
+               if {[string match -* $class($opt)]} {
+                   set options($opt) [string range $class($opt) 1 end]
+               } else {
+                   set options($opt) "$class($opt) [list $data($opt)]"
+               }
+           }
+           foreach opt [lsort [array names options]] {
+               lappend config "$opt $options($opt)"
+           }
+           return $config
+       }
+    }
+
+    if {[string match {} [info commands $CLASS:configure]]} {
+       ## The user is intended to rewrite this one
+       ;proc $CLASS:configure {w args}  {
+           foreach {key val} $args {
+               puts "$w: configure $key to [list $value]"
+           }
+       }
+    }
+
+    set WIDGET(C:$CLASS) {}
+    return $CLASS
+}
+
+
+########################################################################
+########################## EXAMPLES ####################################
+########################################################################
+
+########################################################################
+########################## ScrolledText ################################
+########################################################################
+
+##------------------------------------------------------------------------
+## PROCEDURE
+##     scrolledtext
+##
+## DESCRIPTION
+##     Implements a ScrolledText mega-widget
+##
+## ARGUMENTS
+##     scrolledtext <window pathname> <options>
+##
+## OPTIONS
+##     (Any text widget option may be used in addition to these)
+##
+## -autoscrollbar TCL_BOOLEAN                  DEFAULT: 1
+##     Whether to have dynamic or static scrollbars.
+##
+## RETURNS: the window pathname
+##
+## BINDINGS (in addition to default widget bindings)
+##
+## SUBCOMMANDS
+##     These are the subcmds that an instance of this megawidget recognizes.
+##     Aside from those listed here, it accepts subcmds that are valid for
+##     text widgets.
+##
+## configure ?option? ?value option value ...?
+## cget option
+##     Standard tk widget routines.
+##
+## subwidget widget
+##     Returns the true widget path of the specified widget.  Valid
+##     widgets are text, xscrollbar, yscrollbar.
+##
+## NAMESPACE & STATE
+##     The megawidget creates a global array with the classname, and a
+## global array which is the name of each megawidget created.  The latter
+## array is deleted when the megawidget is destroyed.
+##     Public procs of $CLASSNAME and [string tolower $CLASSNAME] are used.
+## Other procs that begin with $CLASSNAME are private.  For each widget,
+## commands named .$widgetname and $CLASSNAME$widgetname are created.
+##
+## EXAMPLE USAGE:
+##
+## pack [scrolledtext .st -width 40 -height 10] -fill both -exp 1
+##
+##------------------------------------------------------------------------
+
+## Create a global array with that is the name of the class: ScrolledText
+## Each widget created will also have a global array created by the
+## instantiation procedure that is the name of the widget (represented
+## as $w below).  There three special key names in the $CLASS array:
+##
+## type
+##    the type of base container we want to use (frame or toplevel).
+##    This would default to frame.  This widget will be created for us
+##    by the constructor function.  The $w array will have a "container"
+##    key that will point to the exact widget name.
+##
+## base
+##   the base widget type for this class.  This key is optional and
+##   represents what kind of widget will be the base for the class. This
+##   way we know what default methods/options you'll have.  If not
+##   specified, it defaults to the container type.  
+##   To the global $w array, the key "basecmd" will be added by the widget
+##   instantiation function to point to a new proc that will be the direct
+##   accessor command for the base widget ("text" in the case of the
+##   ScrolledText megawidget).  The $w "base" key will be the valid widget
+##   name (for passing to [winfo] and such), but "basecmd" will be the
+##   valid direct accessor function
+##
+## components
+##   the component widgets of the megawidget.  This is a list of tuples
+##   (ie: {{listbox listbox} {scrollbar yscrollbar} {scrollbar xscrollbar}})
+##   where each item is in the form {widgettype name}.  These components
+##   will be created before the $CLASS:construct proc is called and the $w
+##   array will have keys with each name pointing to the appropriate
+##   widget in it.  Use these keys to access your subwidgets.  It is from
+##   this component list and the base and type about that the subwidget
+##   method is created.
+##  
+## Aside from that, any $CLASS key that matches -* will be considered an
+## option that this megawidget handles.  The value can either be a
+## 3-tuple list of the form {databaseName databaseClass defaultValue}, or
+## it can be one element matching -*, which means this key (say -bd) is
+## an alias for the option specified in the value (say -borderwidth)
+## which must be specified fully somewhere else in the class array.
+##
+## If the value is a list beginning with "ALIAS", then the option is derived
+## from a component of the megawidget.  The form of the value must be a list
+## with the elements:
+##     {ALIAS componenttype option ?databasename databaseclass?}
+## An example of this would be inheriting a label components anchor:
+##     {ALIAS label -anchor labelAnchor Anchor}
+## If the databasename is not specified, it determines the final options
+## database info from the component and uses the components default value.
+## Otherwise, just the components default value is used.
+##
+## The $w array will be populated by the instantiation procedure with the
+## default values for all the specified $CLASS options.
+##
+array set ScrolledText {
+    type       frame
+    base       {text text text \
+           {-xscrollcommand [list $data(xscrollbar) set] \
+           -yscrollcommand [list $data(yscrollbar) set]}}
+    components {
+       {scrollbar xscrollbar sx {-orient h -bd 1 -highlightthickness 1 \
+               -command [list $w xview]}}
+       {scrollbar yscrollbar sy {-orient v -bd 1 -highlightthickness 1 \
+               -command [list $w yview]}}
+    }
+
+    -autoscrollbar     {autoScrollbar AutoScrollbar 1}
+}
+
+# Create this to make sure there are registered in auto_mkindex
+# these must come before the [widget create ...]
+proc ScrolledText args {}
+proc scrolledtext args {}
+widget create ScrolledText
+
+## Then we "create" the widget.  This makes all the necessary default widget
+## routines.  It creates the public accessor functions ($CLASSNAME and
+## [string tolower $CLASSNAME]) as well as the public cget, configure, destroy
+## and subwidget methods.  The cget and configure commands work like the
+## regular Tk ones.  The destroy method is superfluous, as megawidgets will
+## respond properly to [destroy $widget] (the Tk destroy command).
+## The subwidget method has the following form:
+##
+##   $widget subwidget name
+##     name    - the component widget name
+##   Returns the widget patch to the component widget name.
+##   Allows the user direct access to your subwidgets.
+##
+## THE USER SHOULD PROVIDE AT LEAST THE FOLLOWING:
+##
+## $CLASSNAME:construct {w}            => return value ignored
+##     w       - the widget name, also the name of the global data array
+## This procedure is called by the public accessor (instantiation) proc
+## right after creating all component widgets and populating the global $w
+## array with all the default option values, the "base" key and the key
+## names for any other components.  The user should then grid/pack all
+## subwidgets into $w.  At this point, the initial configure has not
+## occured, so the widget options are all the default.  If this proc
+## errors, so does the main creation routine, returning your error.
+##
+## $CLASSNAME:configure        {w args}        => return ignored (should be empty)
+##     w       - the widget name, also the name of the global data array
+##     args    - a list of key/vals (already verified to exist)
+## The user should process the key/vals however they require  If this
+## proc errors, so does the main creation routine, returning your error.
+##
+## THE FOLLOWING IS OPTIONAL:
+##
+## $CLASSNAME:init {w}                 => return value ignored
+##     w       - the widget name, also the name of the global data array
+## This procedure is called after the public configure routine and after
+## the "basecmd" key has been added to the $w array.  Ideally, this proc
+## would be used to do any widget specific one-time initialization.
+##
+## $CLASSNAME:destroy {w}              => return ignored (should be empty)
+##     w       - the widget name, also the name of the global data array
+## A default destroy handler is provided that cleans up after the megawidget
+## (all state info), but if special cleanup stuff is needed, you would provide
+## it in this procedure.  This is the first proc called in the default destroy
+## handler.
+##
+
+;proc ScrolledText:construct {w} {
+    upvar \#0 $w data
+
+    grid $data(text) $data(yscrollbar) -sticky news
+    grid $data(xscrollbar) -sticky ew
+    grid columnconfig $w 0 -weight 1
+    grid rowconfig $w 0 -weight 1
+    grid remove $data(yscrollbar) $data(xscrollbar)
+    bind $data(text) <Configure> [list ScrolledText:resize $w 1]
+}
+
+;proc ScrolledText:configure {w args} {
+    upvar \#0 $w data
+    set truth {^(1|yes|true|on)$}
+    foreach {key val} $args {
+       switch -- $key {
+           -autoscrollbar      {
+               set data($key) [regexp -nocase $truth $val]
+               if {$data($key)} {
+                   ScrolledText:resize $w 0
+               } else {
+                   grid $data(xscrollbar)
+                   grid $data(yscrollbar)
+               }
+           }
+       }
+    }
+}
+
+;proc ScrolledText_xview {w args} {
+    upvar \#0 $w data
+    if {[catch {uplevel $data(basecmd) xview $args} err]} {
+       return -code error $err
+    }
+}
+
+;proc ScrolledText_yview {w args} {
+    upvar \#0 $w data
+    if {[catch {uplevel $data(basecmd) yview $args} err]} {
+       return -code error $err
+    } elseif {![winfo ismapped $data(xscrollbar)] && \
+           [string compare {0 1} [$data(basecmd) xview]]} {
+       ## If the xscrollbar was unmapped, but is now needed, show it
+       grid $data(xscrollbar)
+    }
+}
+
+;proc ScrolledText_insert {w args} {
+    upvar \#0 $w data
+    set code [catch {uplevel $data(basecmd) insert $args} err]
+    if {[winfo ismapped $w]} { ScrolledText:resize $w 0 }
+    return -code $code $err
+}
+
+;proc ScrolledText_delete {w args} {
+    upvar \#0 $w data
+    set code [catch {uplevel $data(basecmd) delete $args} err]
+    if {[winfo ismapped $w]} { ScrolledText:resize $w 1 }
+    return -code $code $err
+}
+
+;proc ScrolledText:resize {w d} {
+    upvar \#0 $w data
+    ## Only when deleting should we consider removing the scrollbars
+    if {!$data(-autoscrollbar)} return
+    if {[string compare {0 1} [$data(basecmd) xview]]} {
+       grid $data(xscrollbar)
+    } elseif {$d} {
+       grid remove $data(xscrollbar)
+    }
+    if {[string compare {0 1} [$data(basecmd) yview]]} {
+       grid $data(yscrollbar)
+    } elseif {$d} {
+       grid remove $data(yscrollbar)
+    }
+}
diff --git a/testdata/admin.epp b/testdata/admin.epp
new file mode 100644 (file)
index 0000000..f5ae887
Binary files /dev/null and b/testdata/admin.epp differ
diff --git a/testdata/admin.lay b/testdata/admin.lay
new file mode 100644 (file)
index 0000000..3d307e9
--- /dev/null
@@ -0,0 +1,96 @@
+#fGIS Layer file. Layer type: raster
+# Layer:   áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ
+set _raster_ [raster /home/vitus/fgis/testdata/admin.epp]
+set _legend_ [legend parse {-2    áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ
+1  \9bòÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ
+2  \9bòÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ
+3  \9bòÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ
+4  \9bëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ
+5  \9bòÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ
+6  \9bòÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ
+7  \9bòÅÓÐÕÂÌÉËÁ ëÏÍÉ
+8  \9bòÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ
+9  \9bíÏÒÄÏ×ÓËÁÑ óóò
+10  \9bóÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò
+11  \9bòÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ
+12  \9bòÅÓÐÕÂÌÉËÁ ôÕ×Á
+13  \9bõÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ
+14  \9bþÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ
+15  \9bþÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ
+16  \9bòÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)
+17  \9báÌÔÁÊÓËÉÊ ËÒÁÊ
+18  \9bòÅÓÐÕÂÌÉËÁ áÌÔÁÊ
+19  \9bëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ
+20  \9bòÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ
+21  \9bëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ
+22  \9bòÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ
+23  \9bôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ
+24  \9bü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ
+25  \9bðÒÉÍÏÒÓËÉÊ ËÒÁÊ
+26  \9bóÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ
+27  \9bëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ
+28  \9bèÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ
+29  \9bå×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ
+30  \9báÍÕÒÓËÁÑ
+31  \9báÒÈÁÎÇÅÌØÓËÁÑ
+32  \9bîÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ
+33  \9báÓÔÒÁÈÁÎÓËÁÑ
+34  \9bâÅÌÇÏÒÏÄÓËÁÑ
+35  \9bâÒÑÎÓËÁÑ
+36  \9b÷ÌÁÄÉÍÉÒÓËÁÑ
+37  \9b÷ÏÌÇÏÇÒÁÄÓËÁÑ
+38  \9b÷ÏÌÏÇÏÄÓËÁÑ
+39  \9b÷ÏÒÏÎÅÖÓËÁÑ
+40  \9bîÉÖÅÇÏÒÏÄÓËÁÑ
+41  \9bé×ÁÎÏ×ÓËÁÑ
+42  \9béÒËÕÔÓËÁÑ
+43  \9bõÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ
+44  \9bëÁÌÉÎÉÎÇÒÁÄÓËÁÑ
+45  \9bô×ÅÒÓËÁÑ
+46  \9bëÁÌÕÖÓËÁÑ
+47  \9bëÁÍÞÁÔÓËÁÑ
+48  \9bëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ
+49  \9bëÅÍÅÒÏ×ÓËÁÑ
+50  \9bëÉÒÏ×ÓËÁÑ
+51  \9bëÏÓÔÒÏÍÓËÁÑ
+52  \9bóÁÍÁÒÓËÁÑ
+53  \9bëÕÒÇÁÎÓËÁÑ
+54  \9bëÕÒÓËÁÑ
+55  \9bìÅÎÉÎÇÒÁÄÓËÁÑ
+56  \9bìÉÐÅÃËÁÑ
+57  \9bíÁÇÁÄÁÎÓËÁÑ
+58  \9bþÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ
+59  \9bíÏÓËÏ×ÓËÁÑ
+60  \9bíÕÒÍÁÎÓËÁÑ
+61  \9bîÏ×ÇÏÒÏÄÓËÁÑ
+62  \9bîÏ×ÏÓÉÂÉÒÓËÁÑ
+63  \9bïÍÓËÁÑ
+64  \9bïÒÅÎÂÕÒÇÓËÁÑ
+65  \9bïÒÌÏ×ÓËÁÑ
+66  \9bðÅÎÚÅÎÓËÁÑ
+67  \9bðÅÒÍÓËÁÑ
+68  \9bëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ
+69  \9bðÓËÏ×ÓËÁÑ
+70  \9bòÏÓÔÏ×ÓËÁÑ
+71  \9bòÑÚÁÎÓËÁÑ
+72  \9bóÁÒÁÔÏ×ÓËÁÑ
+73  \9bóÁÈÁÌÉÎÓËÁÑ
+74  \9båËÁÔÅÒÉÎÂÕÒÇÓËÁÑ
+75  \9bóÍÏÌÅÎÓËÁÑ
+76  \9bôÁÍÂÏ×ÓËÁÑ
+77  \9bôÏÍÓËÁÑ
+78  \9bôÕÌØÓËÁÑ
+79  \9bôÀÍÅÎÓËÁÑ
+80  \9bèÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ
+81  \9bñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ
+82  \9bõÌØÑÎÏ×ÓËÁÑ
+83  \9bþÅÌÑÂÉÎÓËÁÑ
+84  \9bþÉÔÉÎÓËÁÑ
+85  \9báÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ
+86  \9bñÒÏÓÌÁ×ÓËÁÑ
+}]
+layer create raster -raster $_raster_\
+    -border none -ovrborder yes -ovrcolor black\
+    -title {  áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ}\
+    -legend $_legend_
+
diff --git a/testdata/admin.leg b/testdata/admin.leg
new file mode 100644 (file)
index 0000000..c7afc12
--- /dev/null
@@ -0,0 +1,87 @@
+-2  áÄÍÉÎÉÓÔÒÁÔÉ×ÎÙÅ ÏÂÌÁÓÔÉ òæ
+85  áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ
+17  áÌÔÁÊÓËÉÊ ËÒÁÊ
+30  áÍÕÒÓËÁÑ
+31  áÒÈÁÎÇÅÌØÓËÁÑ
+33  áÓÔÒÁÈÁÎÓËÁÑ
+34  âÅÌÇÏÒÏÄÓËÁÑ
+35  âÒÑÎÓËÁÑ
+36  ÷ÌÁÄÉÍÉÒÓËÁÑ
+37  ÷ÏÌÇÏÇÒÁÄÓËÁÑ
+38  ÷ÏÌÏÇÏÄÓËÁÑ
+39  ÷ÏÒÏÎÅÖÓËÁÑ
+29  å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ
+74  åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ
+41  é×ÁÎÏ×ÓËÁÑ
+42  éÒËÕÔÓËÁÑ
+ 4  ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ
+44  ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ
+46  ëÁÌÕÖÓËÁÑ
+47  ëÁÍÞÁÔÓËÁÑ
+27  ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ
+49  ëÅÍÅÒÏ×ÓËÁÑ
+50  ëÉÒÏ×ÓËÁÑ
+68  ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ
+48  ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ
+51  ëÏÓÔÒÏÍÓËÁÑ
+19  ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ
+21  ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ
+53  ëÕÒÇÁÎÓËÁÑ
+54  ëÕÒÓËÁÑ
+55  ìÅÎÉÎÇÒÁÄÓËÁÑ
+56  ìÉÐÅÃËÁÑ
+57  íÁÇÁÄÁÎÓËÁÑ
+ 9  íÏÒÄÏ×ÓËÁÑ óóò
+59  íÏÓËÏ×ÓËÁÑ
+60  íÕÒÍÁÎÓËÁÑ
+32  îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ
+40  îÉÖÅÇÏÒÏÄÓËÁÑ
+61  îÏ×ÇÏÒÏÄÓËÁÑ
+62  îÏ×ÏÓÉÂÉÒÓËÁÑ
+63  ïÍÓËÁÑ
+64  ïÒÅÎÂÕÒÇÓËÁÑ
+65  ïÒÌÏ×ÓËÁÑ
+66  ðÅÎÚÅÎÓËÁÑ
+67  ðÅÒÍÓËÁÑ
+25  ðÒÉÍÏÒÓËÉÊ ËÒÁÊ
+69  ðÓËÏ×ÓËÁÑ
+20  òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ
+18  òÅÓÐÕÂÌÉËÁ áÌÔÁÊ
+ 1  òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ
+ 2  òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ
+ 3  òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ
+ 5  òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ
+ 6  òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ
+ 7  òÅÓÐÕÂÌÉËÁ ëÏÍÉ
+ 8  òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ
+16  òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)
+11  òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ
+12  òÅÓÐÕÂÌÉËÁ ôÕ×Á
+22  òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ
+70  òÏÓÔÏ×ÓËÁÑ
+71  òÑÚÁÎÓËÁÑ
+52  óÁÍÁÒÓËÁÑ
+72  óÁÒÁÔÏ×ÓËÁÑ
+73  óÁÈÁÌÉÎÓËÁÑ
+10  óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò
+75  óÍÏÌÅÎÓËÁÑ
+26  óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ
+23  ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ
+76  ôÁÍÂÏ×ÓËÁÑ
+45  ô×ÅÒÓËÁÑ
+77  ôÏÍÓËÁÑ
+78  ôÕÌØÓËÁÑ
+79  ôÀÍÅÎÓËÁÑ
+13  õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ
+82  õÌØÑÎÏ×ÓËÁÑ
+43  õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ
+28  èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ
+80  èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ
+83  þÅÌÑÂÉÎÓËÁÑ
+14  þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ
+84  þÉÔÉÎÓËÁÑ
+15  þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ
+58  þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ
+24  ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ
+81  ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ
+86  ñÒÏÓÌÁ×ÓËÁÑ
diff --git a/testdata/admin_html.leg b/testdata/admin_html.leg
new file mode 100644 (file)
index 0000000..828c43f
--- /dev/null
@@ -0,0 +1,86 @@
+85  html/85.html
+17  html/17.html
+30  html/30.html
+31  html/31.html
+33  html/33.html
+34  html/34.html
+35  html/35.html
+36  html/36.html
+37  html/37.html
+38  html/38.html
+39  html/39.html
+29  html/29.html
+74  html/74.html
+41  html/41.html
+42  html/42.html
+4  html/4.html
+44  html/44.html
+46  html/46.html
+47  html/47.html
+27  html/27.html
+49  html/49.html
+50  html/50.html
+68  html/68.html
+48  html/48.html
+51  html/51.html
+19  html/19.html
+21  html/21.html
+53  html/53.html
+54  html/54.html
+55  html/55.html
+56  html/56.html
+57  html/57.html
+9  html/9.html
+59  html/59.html
+60  html/60.html
+32  html/32.html
+40  html/40.html
+61  html/61.html
+62  html/62.html
+63  html/63.html
+64  html/64.html
+65  html/65.html
+66  html/66.html
+67  html/67.html
+25  html/25.html
+69  html/69.html
+20  html/20.html
+18  html/18.html
+1  html/1.html
+2  html/2.html
+3  html/3.html
+5  html/5.html
+6  html/6.html
+7  html/7.html
+8  html/8.html
+16  html/16.html
+11  html/11.html
+12  html/12.html
+22  html/22.html
+70  html/70.html
+71  html/71.html
+52  html/52.html
+72  html/72.html
+73  html/73.html
+10  html/10.html
+75  html/75.html
+26  html/26.html
+23  html/23.html
+76  html/76.html
+45  html/45.html
+77  html/77.html
+78  html/78.html
+79  html/79.html
+13  html/13.html
+82  html/82.html
+43  html/43.html
+28  html/28.html
+80  html/80.html
+83  html/83.html
+14  html/14.html
+84  html/84.html
+15  html/15.html
+58  html/58.html
+24  html/24.html
+81  html/81.html
+86  html/86.html
diff --git a/testdata/html/1.html b/testdata/html/1.html
new file mode 100644 (file)
index 0000000..8b850b5
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/10.html b/testdata/html/10.html
new file mode 100644 (file)
index 0000000..cbd0a53
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò</TITLE>
+</HEAD>
+<BODY>
+<H1>óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/11.html b/testdata/html/11.html
new file mode 100644 (file)
index 0000000..220f2df
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/12.html b/testdata/html/12.html
new file mode 100644 (file)
index 0000000..62f0f86
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ôÕ×Á</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ôÕ×Á</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ ôÕ×Á&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/13.html b/testdata/html/13.html
new file mode 100644 (file)
index 0000000..9822ac2
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/14.html b/testdata/html/14.html
new file mode 100644 (file)
index 0000000..f82108d
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/15.html b/testdata/html/15.html
new file mode 100644 (file)
index 0000000..e9efbb2
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/16.html b/testdata/html/16.html
new file mode 100644 (file)
index 0000000..666062e
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/17.html b/testdata/html/17.html
new file mode 100644 (file)
index 0000000..e939224
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>áÌÔÁÊÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÌÔÁÊÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;áÌÔÁÊÓËÉÊ ËÒÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/18.html b/testdata/html/18.html
new file mode 100644 (file)
index 0000000..81b98f9
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ áÌÔÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ áÌÔÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ áÌÔÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/19.html b/testdata/html/19.html
new file mode 100644 (file)
index 0000000..4797b9e
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/2.html b/testdata/html/2.html
new file mode 100644 (file)
index 0000000..23f2cba
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/20.html b/testdata/html/20.html
new file mode 100644 (file)
index 0000000..2d6dcc4
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/21.html b/testdata/html/21.html
new file mode 100644 (file)
index 0000000..b154a5b
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/22.html b/testdata/html/22.html
new file mode 100644 (file)
index 0000000..d4157de
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/23.html b/testdata/html/23.html
new file mode 100644 (file)
index 0000000..5237030
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/24.html b/testdata/html/24.html
new file mode 100644 (file)
index 0000000..e3f2f24
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/25.html b/testdata/html/25.html
new file mode 100644 (file)
index 0000000..049d392
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ðÒÉÍÏÒÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÒÉÍÏÒÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ðÒÉÍÏÒÓËÉÊ ËÒÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/26.html b/testdata/html/26.html
new file mode 100644 (file)
index 0000000..e84bfb2
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/27.html b/testdata/html/27.html
new file mode 100644 (file)
index 0000000..d70047a
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/28.html b/testdata/html/28.html
new file mode 100644 (file)
index 0000000..724ebdc
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/29.html b/testdata/html/29.html
new file mode 100644 (file)
index 0000000..63fe5e8
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ</TITLE>
+</HEAD>
+<BODY>
+<H1>å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/3.html b/testdata/html/3.html
new file mode 100644 (file)
index 0000000..8663731
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/30.html b/testdata/html/30.html
new file mode 100644 (file)
index 0000000..056e6ad
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>áÍÕÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÍÕÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;áÍÕÒÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/31.html b/testdata/html/31.html
new file mode 100644 (file)
index 0000000..2c74696
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>áÒÈÁÎÇÅÌØÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÒÈÁÎÇÅÌØÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;áÒÈÁÎÇÅÌØÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/32.html b/testdata/html/32.html
new file mode 100644 (file)
index 0000000..7d9547e
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/33.html b/testdata/html/33.html
new file mode 100644 (file)
index 0000000..0b0c3e6
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>áÓÔÒÁÈÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÓÔÒÁÈÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;áÓÔÒÁÈÁÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/34.html b/testdata/html/34.html
new file mode 100644 (file)
index 0000000..1303828
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>âÅÌÇÏÒÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>âÅÌÇÏÒÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;âÅÌÇÏÒÏÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/35.html b/testdata/html/35.html
new file mode 100644 (file)
index 0000000..3e823f9
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>âÒÑÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>âÒÑÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;âÒÑÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/36.html b/testdata/html/36.html
new file mode 100644 (file)
index 0000000..48f74cb
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>÷ÌÁÄÉÍÉÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÌÁÄÉÍÉÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;÷ÌÁÄÉÍÉÒÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/37.html b/testdata/html/37.html
new file mode 100644 (file)
index 0000000..c4d42ae
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>÷ÏÌÇÏÇÒÁÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÏÌÇÏÇÒÁÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;÷ÏÌÇÏÇÒÁÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/38.html b/testdata/html/38.html
new file mode 100644 (file)
index 0000000..6f6bd39
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>÷ÏÌÏÇÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÏÌÏÇÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;÷ÏÌÏÇÏÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/39.html b/testdata/html/39.html
new file mode 100644 (file)
index 0000000..3b2909a
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>÷ÏÒÏÎÅÖÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÏÒÏÎÅÖÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;÷ÏÒÏÎÅÖÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/4.html b/testdata/html/4.html
new file mode 100644 (file)
index 0000000..1bf78f5
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/40.html b/testdata/html/40.html
new file mode 100644 (file)
index 0000000..50f8574
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>îÉÖÅÇÏÒÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÉÖÅÇÏÒÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;îÉÖÅÇÏÒÏÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/41.html b/testdata/html/41.html
new file mode 100644 (file)
index 0000000..fd9dae2
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>é×ÁÎÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>é×ÁÎÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;é×ÁÎÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/42.html b/testdata/html/42.html
new file mode 100644 (file)
index 0000000..12a4903
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>éÒËÕÔÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>éÒËÕÔÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;éÒËÕÔÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/43.html b/testdata/html/43.html
new file mode 100644 (file)
index 0000000..a9568c6
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ</TITLE>
+</HEAD>
+<BODY>
+<H1>õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/44.html b/testdata/html/44.html
new file mode 100644 (file)
index 0000000..042cb89
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/45.html b/testdata/html/45.html
new file mode 100644 (file)
index 0000000..9737d69
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ô×ÅÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ô×ÅÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ô×ÅÒÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/46.html b/testdata/html/46.html
new file mode 100644 (file)
index 0000000..9f86d26
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÁÌÕÖÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÌÕÖÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÁÌÕÖÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/47.html b/testdata/html/47.html
new file mode 100644 (file)
index 0000000..8abddce
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÁÍÞÁÔÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÍÞÁÔÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÁÍÞÁÔÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/48.html b/testdata/html/48.html
new file mode 100644 (file)
index 0000000..6f6b515
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/49.html b/testdata/html/49.html
new file mode 100644 (file)
index 0000000..0792c69
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÅÍÅÒÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÅÍÅÒÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÅÍÅÒÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/5.html b/testdata/html/5.html
new file mode 100644 (file)
index 0000000..53e2dab
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/50.html b/testdata/html/50.html
new file mode 100644 (file)
index 0000000..8254bd4
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÉÒÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÉÒÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÉÒÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/51.html b/testdata/html/51.html
new file mode 100644 (file)
index 0000000..1cddf65
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÏÓÔÒÏÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÏÓÔÒÏÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÏÓÔÒÏÍÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/52.html b/testdata/html/52.html
new file mode 100644 (file)
index 0000000..8ccddfe
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>óÁÍÁÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÁÍÁÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;óÁÍÁÒÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/53.html b/testdata/html/53.html
new file mode 100644 (file)
index 0000000..3a929ad
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÕÒÇÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÕÒÇÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÕÒÇÁÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/54.html b/testdata/html/54.html
new file mode 100644 (file)
index 0000000..a5286ea
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÕÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÕÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÕÒÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/55.html b/testdata/html/55.html
new file mode 100644 (file)
index 0000000..825b3d0
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ìÅÎÉÎÇÒÁÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ìÅÎÉÎÇÒÁÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ìÅÎÉÎÇÒÁÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/56.html b/testdata/html/56.html
new file mode 100644 (file)
index 0000000..1fb9917
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ìÉÐÅÃËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ìÉÐÅÃËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ìÉÐÅÃËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/57.html b/testdata/html/57.html
new file mode 100644 (file)
index 0000000..b57c740
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>íÁÇÁÄÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>íÁÇÁÄÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;íÁÇÁÄÁÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/58.html b/testdata/html/58.html
new file mode 100644 (file)
index 0000000..e812156
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/59.html b/testdata/html/59.html
new file mode 100644 (file)
index 0000000..6c40f0d
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>íÏÓËÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>íÏÓËÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;íÏÓËÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/6.html b/testdata/html/6.html
new file mode 100644 (file)
index 0000000..4e0624d
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/60.html b/testdata/html/60.html
new file mode 100644 (file)
index 0000000..4c44570
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>íÕÒÍÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>íÕÒÍÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;íÕÒÍÁÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/61.html b/testdata/html/61.html
new file mode 100644 (file)
index 0000000..0ac7e6a
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>îÏ×ÇÏÒÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÏ×ÇÏÒÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;îÏ×ÇÏÒÏÄÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/62.html b/testdata/html/62.html
new file mode 100644 (file)
index 0000000..585303e
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>îÏ×ÏÓÉÂÉÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÏ×ÏÓÉÂÉÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;îÏ×ÏÓÉÂÉÒÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/63.html b/testdata/html/63.html
new file mode 100644 (file)
index 0000000..6deaf77
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ïÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ïÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ïÍÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/64.html b/testdata/html/64.html
new file mode 100644 (file)
index 0000000..8c107df
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ïÒÅÎÂÕÒÇÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ïÒÅÎÂÕÒÇÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ïÒÅÎÂÕÒÇÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/65.html b/testdata/html/65.html
new file mode 100644 (file)
index 0000000..7c6a4c1
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ïÒÌÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ïÒÌÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ïÒÌÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/66.html b/testdata/html/66.html
new file mode 100644 (file)
index 0000000..df0ea6f
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ðÅÎÚÅÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÅÎÚÅÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ðÅÎÚÅÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/67.html b/testdata/html/67.html
new file mode 100644 (file)
index 0000000..2c6f47c
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ðÅÒÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÅÒÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ðÅÒÍÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/68.html b/testdata/html/68.html
new file mode 100644 (file)
index 0000000..41176ca
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/69.html b/testdata/html/69.html
new file mode 100644 (file)
index 0000000..820ba52
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ðÓËÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÓËÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ðÓËÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/7.html b/testdata/html/7.html
new file mode 100644 (file)
index 0000000..d3092e8
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ëÏÍÉ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ëÏÍÉ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ ëÏÍÉ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/70.html b/testdata/html/70.html
new file mode 100644 (file)
index 0000000..fe1e05f
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÏÓÔÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÏÓÔÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÏÓÔÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/71.html b/testdata/html/71.html
new file mode 100644 (file)
index 0000000..0d40339
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÑÚÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÑÚÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÑÚÁÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/72.html b/testdata/html/72.html
new file mode 100644 (file)
index 0000000..39d5afa
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>óÁÒÁÔÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÁÒÁÔÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;óÁÒÁÔÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/73.html b/testdata/html/73.html
new file mode 100644 (file)
index 0000000..96716be
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>óÁÈÁÌÉÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÁÈÁÌÉÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;óÁÈÁÌÉÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/74.html b/testdata/html/74.html
new file mode 100644 (file)
index 0000000..9aa2b37
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/75.html b/testdata/html/75.html
new file mode 100644 (file)
index 0000000..b70308c
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>óÍÏÌÅÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÍÏÌÅÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;óÍÏÌÅÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/76.html b/testdata/html/76.html
new file mode 100644 (file)
index 0000000..a850bd0
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ôÁÍÂÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÁÍÂÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ôÁÍÂÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/77.html b/testdata/html/77.html
new file mode 100644 (file)
index 0000000..bb8c516
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ôÏÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÏÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ôÏÍÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/78.html b/testdata/html/78.html
new file mode 100644 (file)
index 0000000..a369f71
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ôÕÌØÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÕÌØÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ôÕÌØÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/79.html b/testdata/html/79.html
new file mode 100644 (file)
index 0000000..ff04059
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ôÀÍÅÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÀÍÅÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ôÀÍÅÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/8.html b/testdata/html/8.html
new file mode 100644 (file)
index 0000000..61b26fe
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/80.html b/testdata/html/80.html
new file mode 100644 (file)
index 0000000..02dc197
--- /dev/null
@@ -0,0 +1,15 @@
+<HTML>
+<HEAD>
+<TITLE>èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+<P>
+èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ ÏËÒÕÇ Ñ×ÌÑÅÔÓÑ ÞÁÓÔØÀ <A HREF="79.html">
+ôÀÍÅÎÓËÏÊ ÏÂÌÁÓÔÉ</A>
+<img src="../items/wand.gif">
+
+</BODY>
+</HTML>
diff --git a/testdata/html/81.html b/testdata/html/81.html
new file mode 100644 (file)
index 0000000..3a85550
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/82.html b/testdata/html/82.html
new file mode 100644 (file)
index 0000000..02aee9b
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>õÌØÑÎÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>õÌØÑÎÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;õÌØÑÎÏ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/83.html b/testdata/html/83.html
new file mode 100644 (file)
index 0000000..c9b9219
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>þÅÌÑÂÉÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÅÌÑÂÉÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;þÅÌÑÂÉÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/84.html b/testdata/html/84.html
new file mode 100644 (file)
index 0000000..13a4426
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>þÉÔÉÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÉÔÉÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;þÉÔÉÎÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/85.html b/testdata/html/85.html
new file mode 100644 (file)
index 0000000..587d62b
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/86.html b/testdata/html/86.html
new file mode 100644 (file)
index 0000000..87af595
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>ñÒÏÓÌÁ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ñÒÏÓÌÁ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;ñÒÏÓÌÁ×ÓËÁÑ&quot;
+</BODY>
+</HTML>
diff --git a/testdata/html/9.html b/testdata/html/9.html
new file mode 100644 (file)
index 0000000..d80827b
--- /dev/null
@@ -0,0 +1,10 @@
+<HTML>
+<HEAD>
+<TITLE>íÏÒÄÏ×ÓËÁÑ óóò</TITLE>
+</HEAD>
+<BODY>
+<H1>íÏÒÄÏ×ÓËÁÑ óóò</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;íÏÒÄÏ×ÓËÁÑ óóò&quot;
+</BODY>
+</HTML>
diff --git a/testdata/lesras.epp b/testdata/lesras.epp
new file mode 100755 (executable)
index 0000000..5c1d115
Binary files /dev/null and b/testdata/lesras.epp differ
diff --git a/testdata/lesras.lay b/testdata/lesras.lay
new file mode 100644 (file)
index 0000000..be7708b
--- /dev/null
@@ -0,0 +1,30 @@
+#fGIS Layer file. Layer type: raster
+# Layer:  ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ
+set _raster_ [raster ../testdata/lesras.epp]
+set _legend_ [legend parse {-2   ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ
+1  úÏÎÁ ÁÒËÔÉÞÅÓËÏÊ ÐÕÓÔÙÎÉ
+2  úÏÎÁ ÔÕÎÄÒÙ -ÒÁ×ÎÉÎÎÁÑ
+3  úÏÎÁ ÔÕÎÄÒÙ -ÇÏÒÎÁÑ
+4  úÏÎÁ ÌÅÓÏÔÕÎÄÒÙ
+5  úÏÎÁ ÌÕÇÏ× É ÌÕÇÏ×ÙÈ ÒÅÄËÏÌÅÓÉÊ
+6  ðÏÄÚÏÎÁ ÒÅÄËÏÓÔÏÊÎÏÊ ÔÁÊÇÉ
+7  ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÔÁÊÇÉ
+8  ðÏÄÚÏÎÁ ÓÒÅÄÎÅÊ ÔÁÊÇÉ
+9  ðÏÄÚÏÎÁ ÀÖÎÏÊ ÔÁÊÇÉ
+10  ÐÏÄÚÏÎÁ Ó ÐÒÅÏÂÌÁÄÁÎÉÅÍ È×ÏÊÎÙÈ
+11  ÐÏÄÚÏÎÁ Ó ÏÄÉÎÁËÏ×ÙÍ ÕÞÁÓÔÉÅÍ È×ÏÊÎÙÈ É ÛÉÒÏËÏÌÉÓÔ×ÅÎÎÙÈ
+12  ÐÏÄÚÏÎÁ ÍÏÎÏÄÏÍÉÎÁÎÔÎÙÈ ÌÅÓÏ×
+13  ÐÏÄÚÏÎÁ ÐÏÌÉÄÏÍÉÎÁÎÔÎÙÈ-ÔÅÒÍÏÆÉÌØÎÙÈ ÌÅÓÏ×
+14  ÚÏÎÁ
+15  ÓÅ×ÅÒÎÙÈ ÓÔÅÐÅÊ
+16  ÀÖÎÙÈ ÓÔÅÐÅÊ
+17  ÓÅ×ÅÒÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+18  ÀÖÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+19  ÓÅ×ÅÒÎÏÊ ÐÕÓÔÙÎÉ
+20  ÀÖÎÏÊ ÐÕÓÔÙÎÉ
+}]
+layer create raster -raster $_raster_\
+    -border none -ovrborder yes -ovrcolor black\
+    -title { ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ}\
+    -legend $_legend_
+
diff --git a/testdata/lesras.leg b/testdata/lesras.leg
new file mode 100644 (file)
index 0000000..d3877e6
--- /dev/null
@@ -0,0 +1,22 @@
+-2   ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ
+ 1  úÏÎÁ ÁÒËÔÉÞÅÓËÏÊ ÐÕÓÔÙÎÉ
+ 2  úÏÎÁ ÔÕÎÄÒÙ -ÒÁ×ÎÉÎÎÁÑ
+ 3  úÏÎÁ ÔÕÎÄÒÙ -ÇÏÒÎÁÑ
+ 4  úÏÎÁ ÌÅÓÏÔÕÎÄÒÙ
+ 5  úÏÎÁ ÌÕÇÏ× É ÌÕÇÏ×ÙÈ ÒÅÄËÏÌÅÓÉÊ
+ 6  ðÏÄÚÏÎÁ ÒÅÄËÏÓÔÏÊÎÏÊ ÔÁÊÇÉ
+ 7  ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÔÁÊÇÉ
+ 8  ðÏÄÚÏÎÁ ÓÒÅÄÎÅÊ ÔÁÊÇÉ
+ 9  ðÏÄÚÏÎÁ ÀÖÎÏÊ ÔÁÊÇÉ
+ 10 óÅ×ÅÒÎÁÑ ÐÏÄÚÏÎÁ Ó ÐÒÅÏÂÌÁÄÁÎÉÅÍ È×ÏÊÎÙÈ
+ 11 àÖÎÁÑ ÐÏÄÚÏÎÁ Ó ÏÄÉÎÁËÏ×ÙÍ ÕÞÁÓÔÉÅÍ È×ÏÊÎÙÈ É ÛÉÒÏËÏÌÉÓÔ×ÅÎÎÙÈ
+ 12 óÅ×ÅÒÎÁÑ ÐÏÄÚÏÎÁ ÍÏÎÏÄÏÍÉÎÁÎÔÎÙÈ ÌÅÓÏ×
+ 13 àÖÎÁÑ ÐÏÄÚÏÎÁ ÐÏÌÉÄÏÍÉÎÁÎÔÎÙÈ-ÔÅÒÍÏÆÉÌØÎÙÈ ÌÅÓÏ×
+ 14 ìÅÓÏÓÔÅÐÎÁÑ ÚÏÎÁ
+ 15 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÙÈ ÓÔÅÐÅÊ
+ 16 ðÏÄÚÏÎÁ ÀÖÎÙÈ ÓÔÅÐÅÊ
+ 17 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+ 18 ðÏÄÚÏÎÁ ÀÖÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+ 19 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÐÕÓÔÙÎÉ
+ 20 ðÏÄÚÏÎÁ ÀÖÎÏÊ ÐÕÓÔÙÎÉ
+
diff --git a/testdata/mkhtml.tcl b/testdata/mkhtml.tcl
new file mode 100644 (file)
index 0000000..12a6aab
--- /dev/null
@@ -0,0 +1,24 @@
+set f [open admin.leg]
+set out [open admin_html.leg w]
+while {[gets $f line]>=0} {
+  if ![regexp {^ *([0-9]+)  (.*)$} $line all code text] continue
+  if {$code<0} continue
+  set outname "html/$code.html"
+  puts $out "$code  $outname"
+  set f2 [open $outname "w"]
+  puts $f2 "<HTML>
+<HEAD>
+<TITLE>$text</TITLE>
+</HEAD>
+<BODY>
+<H1>$text</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ &quot;$text&quot;
+</BODY>
+</HTML>"
+close $f2
+}
+close $out
+close $f
+
+
diff --git a/testdata/pgrm.epp b/testdata/pgrm.epp
new file mode 100755 (executable)
index 0000000..969e19d
Binary files /dev/null and b/testdata/pgrm.epp differ
diff --git a/testdata/poger.epp b/testdata/poger.epp
new file mode 100755 (executable)
index 0000000..0c6b53d
Binary files /dev/null and b/testdata/poger.epp differ
diff --git a/testdata/soil_mo.clr b/testdata/soil_mo.clr
new file mode 100644 (file)
index 0000000..370d707
--- /dev/null
@@ -0,0 +1,37 @@
+1 0 1000 1000
+2 0 631 631
+3 0 823 823
+4 219 729 729
+5 219 729 490
+6 376 568 376
+7 615 886 537
+8 458 839 250
+9 729 427 219
+10 298 678 0
+11 474 1000 0
+12 839 839 109
+13 933 631 235
+14 964 949 392
+15 1000 886 345
+16 886 760 886
+17 615 729 219
+18 760 870 917
+19 345 792 537
+20 1000 776 568
+21 760 713 631
+22 713 552 870
+23 917 505 917
+24 615 552 964
+25 364 490 156
+26 474 600 141
+27 949 694 345
+28 505 282 505
+29 662 313 662
+30 823 694 662
+31 870 870 870
+32 949 694 600
+33 792 172 807
+34 949 694 345
+35 490 364 729
+254 0 0 1000
+253 600 600 1000
diff --git a/testdata/soil_mo.epp b/testdata/soil_mo.epp
new file mode 100644 (file)
index 0000000..6c405fe
Binary files /dev/null and b/testdata/soil_mo.epp differ
diff --git a/testdata/soil_mo.leg b/testdata/soil_mo.leg
new file mode 100644 (file)
index 0000000..8397de6
--- /dev/null
@@ -0,0 +1,34 @@
+1  Item 1
+2  Item 2
+3  Item 3
+4  Item 4
+5  Item 5
+6  Item 6
+7  Item 7
+8  Item 8
+9  Item 9
+10  Item 10
+11  Item 11
+12  Item 12
+13  Item 13
+14  Item 14
+15  Item 15
+16  Item 16
+17  Item 17
+18  Item 18
+19  Item 19
+20  Item 20
+21  Item 21
+22  Item 22
+23  Item 23
+24  Item 24
+25  Item 25
+26  Item 26
+27  Item 27
+28  Item 28
+29  Item 29
+30  Item 30
+31  Item 31
+32  Item 32
+33  Item 33
+34  Item 34
diff --git a/testdata/test.prj b/testdata/test.prj
new file mode 100644 (file)
index 0000000..ceeae1b
--- /dev/null
@@ -0,0 +1,5 @@
+#! /home/vitus/fgis/tcl/hypermap
+info proc hyper_*
+hyper_layer admin admin_html
+add_layer admin.lay
+add_layer lesras.lay