--- /dev/null
+
+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
+
+
--- /dev/null
+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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+ -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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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;
+}
--- /dev/null
+/*
+ * 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;
+
+}
+
+
--- /dev/null
+#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
--- /dev/null
+/*
+ *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;
+}
--- /dev/null
+#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
--- /dev/null
+#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;
+ }
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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;
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+
+/* 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;
+}
--- /dev/null
+
+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 ÆÏÒÍÁÔÅ
+ ÐÒÁ×ÉÌØÎÏÇÏ ÒÁÚÍÅÒÁ
+
+
--- /dev/null
+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.
--- /dev/null
+
+÷ ÄÁÎÎÏÍ ÔÅËÓÔÅ ÐÒÅÄÌÁÇÁÅÔÓÑ ÎÏ×ÙÊ ÐÏÄÈÏÄ Ë ÐÒÅÄÓÔÁ×ÌÅÎÉÀ
+ÐÒÏÓÔÒÁÎÓÔ×ÅÎÎÏÊ ÉÎÆÏÒÍÁÃÉÉ. ïÎ ÎÅ ÓÏ×ÓÅÍ ÎÏ×ÙÊ. íÎÏÇÉÅ ÓÕÝÅÓÔ×ÕÀÝÉÅ
+çéó, ÏÓÏÂÅÎÎÏ ÏÒÉÅÎÔÉÒÏ×ÁÎÎÙÅ ÎÁ ÏÂÒÁÂÏÔËÕ ÓÎÉÍËÏ×, ÎÅÑ×ÎÏ ÉÓÐÏÌØÚÕÀÔ
+ÅÇÏ. îÏ ÎÉËÔÏ ÅÝÅ ÎÅ ÐÙÔÁÌÓÑ × Ñ×ÎÏÍ ×ÉÄÅ ÓÆÏÒÍÕÌÉÒÏ×ÁÔØ ÅÇÏ É ÐÏËÁÚÁÔØ
+ÅÇÏ ÄÏÓÔÁÔÏÞÎÏÓÔØ ÄÌÑ ÂÏÌØÛÉÎÓÔ×Á çéó-ÚÁÄÁÞ.
+
+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, ×ËÌÀÞÁÑ ÔÁËÉÅ ËÁË ÒÉÓÏ×ÁÎÉÅ
+ÔÏÞËÉ ÉÌÉ ÌÉÎÉÉ × ÒÅÄÁËÔÏÒÅ
+
+á×ÔÏÍÁÔÉÞÅÓËÁÑ ÁËÔÕÁÌÉÚÁÃÉÑ ËÁÒÔ.
+
+äÌÑ ËÁÒÔ ÓÏÚÄÁÎÎÙÈ × ÒÅÚÕÌØÔÁÔÅ ÏÐÅÒÁÃÉÊ ÏÂÒÁÂÏÔËÉ ÈÒÁÎÉÔÓÑ
+ËÏÍÁÎÄÁ, ÓÏÚÄÁ×ÛÁÑ ËÁÒÔÕ, É ÓÐÉÓÏË ÉÓÈÏÄÎÙÈ ËÁÒÔ. ðÒÉ ×ÉÚÕÁÌÉÚÁÃÉÉ
+ÜÔÏÊ ËÁÒÔÙ ÐÒÏ×ÅÒÑÅÔÓÑ, ÎÅ ÂÙÌÉ ÌÉ ÉÚÍÅÎÅÎÙ ËÁËÉÅ-ÔÏ ÉÚ ÉÓÈÏÄÎÙÈ
+ËÁÒÔ, É ÅÓÌÉ ÄÁ, ÐÒÅÄÌÁÇÁÅÔÓÑ ÐÏ×ÔÏÒÉÔØ ÇÅÎÅÒÁÃÉÀ ËÁÒÔÙ.
+
--- /dev/null
+<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 < X, Y, Value >. 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 "friend widgets" 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>
+
+
+
+
+
+
+
+
+
--- /dev/null
+ æÁÊÌ ÏÐÉÓÁÎÉÑ ÒÅÇÉÏÎÁ
+îÁÚÙ×ÁÅÔÓÑ .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 ÓÐÉÓÏË ÉÍÅÎ ËÁÒÔ - ÉÍÅÎÁ ËÁÒÔ, ËÏÔÏÒÙÅ ÎÁÄÏ ×Ù×ÏÄÉÔØ, ÅÓÌÉ
+ÕËÁÚÁÎÎÁÑ ×Ù×ÏÄÉÔÓÑ ËÁË ÏÓÎÏ×ÎÁÑ
--- /dev/null
+\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}
--- /dev/null
+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
+
--- /dev/null
+%!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
--- /dev/null
+#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
--- /dev/null
+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
--- /dev/null
+#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};
--- /dev/null
+\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}
+
+
--- /dev/null
+\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}
--- /dev/null
+îÅËÏÔÏÒÙÅ ÉÄÅÉ
+
+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 É Ô.Ä.
--- /dev/null
+ ëÏÎÃÅÐÃÉÑ ÒÅÇÉÏÎÁ.
+
+÷ ÏÂÌÁÓÔÉ çéó-ÏÂÒÁÂÏÔËÉ ÐÒÁËÔÉÞÅÓËÉ ÎÉËÏÇÄÁ ÎÅÌØÚÑ ÏÇÒÁÎÉÞÉÔØÓÑ
+ÒÁÓÓÍÏÔÒÅÎÉÅÍ ÏÄÎÏÊ ËÁÒÔÙ ÎÁ ÏÐÒÅÄÅÌÅÎÎÕÀ ÔÅÒÒÉÔÏÒÉÀ, ÏÓÏÂÅÎÎÏ
+ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ËÏÎÃÅÐÃÉÉ ÆÕÎËÃÉÏÎÁÌØÎÙÈ ËÁÒÔ.
+
+ëÒÏÍÅ ÔÏÇÏ, ÄÏÓÔÁÔÏÞÎÏ ÞÁÓÔÏ ×ÏÚÎÉËÁÅÔ ÚÁÄÁÞÁ ÒÁÂÏÔÙ Ó ÎÅÓËÏÌØËÉÍÉ
+ÒÁÚÎÏÍÁÓÛÔÁÂÎÙÍÉ ÕÞÁÓÔËÁÍÉ ÔÅÒÒÉÔÏÒÉÉ.
+
+ðÏÜÔÏÍÕ × fGIS ××ÅÄÅÎÁ ËÏÎÃÅÐÃÉÑ ÒÅÇÉÏÎÁ. òÅÇÉÏÎ ÜÔÏ ÇÒÕÐÐÁ ËÁÒÔ,
+ÏÐÉÓÙ×ÁÀÝÉÈ ÏÄÎÕ É ÔÕ ÖÅ ÔÅÒÒÉÔÏÒÉÀ. ÷ÓÅ ËÁÒÔÙ ÒÅÇÉÏÎÁ ÄÏÌÖÎÙ
+ÉÍÅÔØ ÏÄÉÎÁËÏ×ÕÀ ËÏÏÒÄÉÎÁÔÎÕÀ ÓÉÓÔÅÍÕ (ÐÒÏÅËÃÉÀ), ÈÏÔÑ ÎÉËÔÏ ÎÅ
+ÍÅÛÁÅÔ ÓÏÚÄÁÔØ ÎÅÓËÏÌØËÏ ÒÅÇÉÏÎÏ× fGIS, ÉÍÅÀÝÉÈ ÒÁÚÎÕÀ ÐÒÏÅËÃÉÀ,
+ÄÌÑ ÏÄÎÏÊ É ÔÏÊ ÖÅ ÔÅÒÒÉÔÏÒÉÉ.
+
+ëÏÐÉÒÏ×ÁÎÉÅ ËÁÒÔÙ ÉÚ ÏÄÎÏÇÏ ÒÅÇÉÏÎÁ × ÄÒÕÇÏÊ (ÅÓÔÅÓÔ×ÅÎÎÏ, ÓÒÅÄÓÔ×ÁÍÉ
+fGIS, Á ÎÅ ÓÒÅÄÓÔ×ÁÍÉ ÏÐÅÒÁÃÉÏÎÎÏÊ ÓÉÓÔÅÍÙ) ÐÒÉ×ÏÄÉÔ Ë Á×ÔÏÍÁÔÉÞÅÓËÏÍÕ
+ÉÚÍÅÎÅÎÉÀ ÐÒÏÅËÃÉÉ.
+
+òÅÇÉÏÎÙ ÍÏÇÕÔ ÂÙÔØ ÉÅÒÁÒÈÉÞÅÓËÉ ×ÌÏÖÅÎÙ ÄÒÕÇ × ÄÒÕÇÁ. ðÏÜÔÏÍÕ ÅÝÅ ÏÄÎÉÍ
+Ó×ÏÊÓÔ×ÏÍ ÒÅÇÉÏÎÁ Ñ×ÌÑÅÔÓÑ ËÁÒÔÁ ÅÇÏ ÒÁÚÂÉÅÎÉÑ ÎÁ ÓÕÂÒÅÇÉÏÎÙ.
+ó ÅÅ ÐÏÍÏÝØÀ ÍÏÖÎÏ ÐÅÒÅÊÔÉ × ÒÅÇÉÏÎ, ÄÁÀÝÉÊ ÂÏÌÅÅ ÄÅÔÁÌØÎÕÀ ÈÁÒÁËÔÅÒÉÓÔÉËÕ
+ÐÒÏÓÔÏ ÐÕÔÅÍ ×ÙÂÏÒÁ ÔÏÞËÉ ÎÁ ËÁÒÔÅ.
+
+÷ÎÕÔÒÉ ÒÅÇÉÏÎÁ ËÁÒÔÙ ÍÏÇÕÔ ÂÙÔØ ÏÂßÅÄÉÎÅÎÙ × ÔÅÍÁÔÉÞÅÓËÉÅ ÇÒÕÐÐÙ,
+ÞÔÏ ÏÂÌÅÇÞÁÅÔ ÎÁ×ÉÇÁÃÉÀ ÐÏ ÎÉÍ.
+
+òÅÇÉÏÎÕ ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ËÁÔÁÌÏÇ ÆÁÊÌÏ×ÏÊ ÓÉÓÔÅÍÙ OS, Á ÓÕÂÒÅÇÉÏÎÁÍ -
+ÐÏÄËÁÔÁÌÏÇÉ ÄÁÎÎÏÇÏ ËÁÔÁÌÏÇÁ. ðÏÜÔÏÍÕ ÐÅÒÅÈÏÄ × ×ÙÛÅÌÅÖÁÝÉÊ ÒÅÇÉÏÎ
+×ÓÅÇÄÁ ÏÐÒÅÄÅÌÅÎ ÏÄÎÏÚÎÁÞÎÏ.
+
--- /dev/null
+ðÒÉÎÃÉÐÙ ×ÉÚÕÁÌÉÚÁÃÉÉ fGIS
+
+ïÄÎÉÍ ÉÚ ÏÓÎÏ×ÎÙÈ ÎÅÄÏÓÔÁÔËÏ× ÔÒÁÄÉÃÉÏÎÎÙÈ GIS (ARC/Info, Idrisi, EPPL7)
+Ñ×ÌÑÅÔÓÑ ÒÁÚÄÅÌÅÎÉÅ ÓÏÂÓÔ×ÅÎÎÏ ÜÌÅËÔÒÏÎÎÙÈ ËÁÒÔ (ÐÏËÒÙÔÉÊ) É ËÁÒÔÏÇÒÁÆÉÞÅÓËÉÈ
+ËÏÍÐÏÚÉÃÉÊ, ÐÒÅÄÎÁÚÎÁÞÅÎÎÙÈ ÄÌÑ ÐÒÏÓÍÏÔÒÁ É ÐÅÞÁÔÉ.
+
+÷ ÜÔÏÍ ÐÏÄÈÏÄÅ ÅÓÔØ Ó×ÏÉ ÐÒÅÉÍÕÝÅÓÔ×Á --- ÐÅÒÅÈÏÄ ÏÔ ËÏÒÒÅËÔÎÏ ÐÏÓÔÒÏÅÎÎÏÊ
+ÍÏÄÅÌÉ ÍÅÓÔÎÏÓÔÉ, ËÁËÏ×ÏÊ Ñ×ÌÑÅÔÓÑ ÐÏËÒÙÔÉÅ, Ë ÐÒÏÉÚ×ÅÄÅÎÉÀ ÐÏÌÉÇÒÁÆÉÞÅÓËÏÇÏ
+ÉÓËÕÓÓÔ×Á, ËÁËÏ×ÙÍ Ñ×ÌÑÅÔÓÑ ÂÕÍÁÖÎÁÑ ËÁÒÔÁ, ÚÁÄÁÞÁ ÎÅÐÒÏÓÔÁÑ É, ÎÅÓÏÍÎÅÎÎÏ,
+ÔÒÅÂÕÀÝÁÑ ÕÞÁÓÔÉÑ ÞÅÌÏ×ÅËÁ. ôÅÍ ÎÅ ÍÅÎÅÅ ÄÌÑ ÂÏÌØÛÉÎÓÔ×Á ÐÏÌØÚÏ×ÁÔÅÌÅÊ
+çéó, Ñ×ÌÑÀÝÉÍÉÈÓÑ ÓÐÅÃÉÁÌÉÓÔÁÍÉ × ÐÒÅÄÍÅÔÎÏÊ ÏÂÌÁÓÔÉ, Á ÎÅ ÐÒÏÆÅÓÓÉÏÎÁÌØÎÙÍÉ
+ËÁÒÔÏÇÒÁÆÁÍÉ, ÎÅ×ÏÚÍÏÖÎÏÓÔØ ÍÇÎÏ×ÅÎÎÏ Õ×ÉÄÅÔØ ÒÅÚÕÌØÔÁÔ ÐÒÉÍÅÎÅÎÉÑ ÔÏÊ ÉÌÉ
+ÉÎÏÊ ÏÐÅÒÁÃÉÉ, Ñ×ÌÑÅÔÓÑ ÓÕÝÅÓÔ×ÅÎÎÏÊ ÐÏÍÅÈÏÊ ÐÒÉ ÐÏÓÔÒÏÅÎÉÉ çéó ÍÏÄÅÌÅÊ.
+
+ðÏÜÔÏÍÕ × fGIS ÐÁÒÁÍÅÔÒÙ ×ÉÚÕÁÌÉÚÁÃÉÉ, ÔÁËÉÅ ËÁË ÐÁÌÉÔÒÁ, ÛÔÒÉÈÏ×ËÉ ÉÌÉ
+ÎÁÂÏÒ ÓÌÏÅ×-ÏÒÉÅÎÔÉÒÏ×, ÏÂÌÅÇÞÁÀÝÉÈ ÞÔÅÎÉÅ ÏÓÎÏ×ÎÏÊ ÔÅÍÁÔÉÞÅÓËÏÊ ÉÎÆÏÒÍÁÃÉÉ,
+Ñ×ÌÑÅÔÓÑ ÁÔÒÉÂÕÔÁÍÉ ËÁÒÔÙ É ËÁÖÄÁÑ ËÁÒÔÁ ÍÏÖÅÔ ÂÙÔØ ×ÉÚÕÁÌÉÚÉÒÏ×ÁÎÁ ÉÌÉ
+ÎÁÐÅÞÁÔÁÎÁ ÐÒÏÓÔÏ ÐÕÔÅÍ ÕËÁÚÁÎÉÑ ÅÅ ÉÍÅÎÉ.
--- /dev/null
+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
--- /dev/null
+#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);
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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));
+}
--- /dev/null
+#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);
+}
+
+
+
--- /dev/null
+
+/* 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);
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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;
+}
--- /dev/null
+
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+# 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;
+}
--- /dev/null
+#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
--- /dev/null
+#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},
+};
--- /dev/null
+ 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
--- /dev/null
+#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;
+ }
+}
--- /dev/null
+#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;
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+#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;
+}
--- /dev/null
+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}
--- /dev/null
+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}
+
--- /dev/null
+
+typedef int *PALETTE;
+PALETTE default_palette;
+PALETTE read_palette(FILE *f);
+char *ppm_pixel(PALETTE palette,int index);
+
--- /dev/null
+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,
--- /dev/null
+#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
+
--- /dev/null
+/* 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
--- /dev/null
+#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
--- /dev/null
+/**********************************************************************/
+/* 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 */
+
--- /dev/null
+#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
--- /dev/null
+/* 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 */
--- /dev/null
+#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
--- /dev/null
+/* 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:
+*/
--- /dev/null
+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}
+
--- /dev/null
+æÕÎËÃÉÑ 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 ÄÌÑ ÑÓÎÏÓÔÉ.
--- /dev/null
+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;
+ }
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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));
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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;
+}
+
+
--- /dev/null
+#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;
+}
+
--- /dev/null
+# 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);
+ }
+}
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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;
+}
+
--- /dev/null
+# 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(×ec);
+ t=localtime(×ec);
+ 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;
+}
--- /dev/null
+#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
--- /dev/null
+#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);
+
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 ? ®s : (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:
+*/
--- /dev/null
+/* 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:
+*/
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
+
+
--- /dev/null
+
+/* 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;
+}
--- /dev/null
+%{
+#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;
+}
--- /dev/null
+#
+# 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
--- /dev/null
+#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]);
+
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+# 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
--- /dev/null
+#!/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
--- /dev/null
+.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
+
--- /dev/null
+.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.
--- /dev/null
+.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.
--- /dev/null
+.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.
--- /dev/null
+.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
+
+???
+
--- /dev/null
+.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)
--- /dev/null
+.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
--- /dev/null
+.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
+
+???
--- /dev/null
+.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
+
+???
--- /dev/null
+.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
+
+???
--- /dev/null
+.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).
+
--- /dev/null
+'\" 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.
+
+
+
+
--- /dev/null
+
+.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)
+
+
--- /dev/null
+.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.
--- /dev/null
+.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.
--- /dev/null
+.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
+
+???
--- /dev/null
+package ifneeded Fgis 1.0 "package require Tk; [list load [file join $dir fgis.so] Fgis]"
--- /dev/null
+-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
--- /dev/null
+-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
--- /dev/null
+-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
--- /dev/null
+ -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
--- /dev/null
+-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
--- /dev/null
+ -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
--- /dev/null
+ -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
--- /dev/null
+ -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
--- /dev/null
+-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
--- /dev/null
+ -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
--- /dev/null
+-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
--- /dev/null
+ -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
--- /dev/null
+-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
--- /dev/null
+-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
--- /dev/null
+ -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
--- /dev/null
+ -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
--- /dev/null
+-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
--- /dev/null
+ -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
--- /dev/null
+ -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
--- /dev/null
+#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_
+
--- /dev/null
+## 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)}
+}
--- /dev/null
+## 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"
+ }
+ }
+}
--- /dev/null
+##
+## 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
--- /dev/null
+##
+## 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)]
+}
--- /dev/null
+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
--- /dev/null
+#
+# 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
--- /dev/null
+##
+## 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
+ }
+}
+
--- /dev/null
+##
+## 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
--- /dev/null
+# 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]]"
+}
--- /dev/null
+#!/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]
--- /dev/null
+#
+# 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
+}
--- /dev/null
+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
+}
--- /dev/null
+#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_
+
--- /dev/null
+#!/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
+}
--- /dev/null
+#
+# 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
+}
--- /dev/null
+#
+# 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
+}
+}
--- /dev/null
+##
+## 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
--- /dev/null
+##
+## 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\""
+}
+
--- /dev/null
+# 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]]
--- /dev/null
+#
+# 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
+}
+
--- /dev/null
+##
+## 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]]
+ }
+}
--- /dev/null
+# 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 .
+ }
+}
--- /dev/null
+##
+## 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)
+ }
+}
--- /dev/null
+#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_
+
--- /dev/null
+-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 ñÒÏÓÌÁ×ÓËÁÑ
--- /dev/null
+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
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ âÁÛËÏÒÔÏÓÔÁÎ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò</TITLE>
+</HEAD>
+<BODY>
+<H1>óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "óÅ×ÅÒÏ-ïÓÅÔÉÎÓËÁÑ óóò"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ ôÁÔÁÒÓÔÁÎ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ôÕ×Á</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ôÕ×Á</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ ôÕ×Á"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "õÄÍÕÒÔÓËÁÑ òÅÓÐÕÂÌÉËÁ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "þÅÞÅÎÓËÁÑ É éÎÇÕÛÓËÁÑ ÒÅÓÐÕÂÌÉËÉ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "þÕ×ÁÛÓËÁÑ òÅÓÐÕÂÌÉËÁ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ óÁÈÁ (ñËÕÔÉÑ)"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>áÌÔÁÊÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÌÔÁÊÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "áÌÔÁÊÓËÉÊ ËÒÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ áÌÔÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ áÌÔÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ áÌÔÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÒÁÓÎÏÄÁÒÓËÉÊ ËÒÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ âÕÒÑÔÉÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ áÄÙÇÅÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÒÁÓÎÏÑÒÓËÉÊ ËÒÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ èÁËÁÓÓÉÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ôÁÊÍÙÒÓËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ü×ÅÎËÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ðÒÉÍÏÒÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÒÉÍÏÒÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ðÒÉÍÏÒÓËÉÊ ËÒÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "óÔÁ×ÒÏÐÏÌØÓËÉÊ ËÒÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÁÒÁÞÁÅ×Ï-þÅÒËÅÓÓËÁÑ òÅÓÐÕÂÌÉËÁ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ</TITLE>
+</HEAD>
+<BODY>
+<H1>èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "èÁÂÁÒÏ×ÓËÉÊ ËÒÁÊ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ</TITLE>
+</HEAD>
+<BODY>
+<H1>å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "å×ÒÅÊÓËÁÑ Á×Ô.ÏÂÌÁÓÔØ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ äÁÇÅÓÔÁÎ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>áÍÕÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÍÕÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "áÍÕÒÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>áÒÈÁÎÇÅÌØÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÒÈÁÎÇÅÌØÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "áÒÈÁÎÇÅÌØÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>áÓÔÒÁÈÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÓÔÒÁÈÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "áÓÔÒÁÈÁÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>âÅÌÇÏÒÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>âÅÌÇÏÒÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "âÅÌÇÏÒÏÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>âÒÑÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>âÒÑÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "âÒÑÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>÷ÌÁÄÉÍÉÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÌÁÄÉÍÉÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "÷ÌÁÄÉÍÉÒÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>÷ÏÌÇÏÇÒÁÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÏÌÇÏÇÒÁÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "÷ÏÌÇÏÇÒÁÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>÷ÏÌÏÇÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÏÌÏÇÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "÷ÏÌÏÇÏÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>÷ÏÒÏÎÅÖÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>÷ÏÒÏÎÅÖÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "÷ÏÒÏÎÅÖÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÁÂÁÒÄÉÎÏ-âÁÌËÁÒÓËÁÑ òÅÓÐÕÂÌÉËÁ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>îÉÖÅÇÏÒÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÉÖÅÇÏÒÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "îÉÖÅÇÏÒÏÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>é×ÁÎÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>é×ÁÎÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "é×ÁÎÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>éÒËÕÔÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>éÒËÕÔÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "éÒËÕÔÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ</TITLE>
+</HEAD>
+<BODY>
+<H1>õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "õÓÔØ-ïÒÄÙÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÁÌÉÎÉÎÇÒÁÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ô×ÅÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ô×ÅÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ô×ÅÒÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÁÌÕÖÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÌÕÖÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÁÌÕÖÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÁÍÞÁÔÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÁÍÞÁÔÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÁÍÞÁÔÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÏÒÑËÓËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÅÍÅÒÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÅÍÅÒÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÅÍÅÒÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ ëÁÌÍÙËÉÑ-èÁÌØÍÇ ôÁÎÇÞ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÉÒÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÉÒÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÉÒÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÏÓÔÒÏÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÏÓÔÒÏÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÏÓÔÒÏÍÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>óÁÍÁÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÁÍÁÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "óÁÍÁÒÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÕÒÇÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÕÒÇÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÕÒÇÁÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÕÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÕÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÕÒÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ìÅÎÉÎÇÒÁÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ìÅÎÉÎÇÒÁÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ìÅÎÉÎÇÒÁÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ìÉÐÅÃËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ìÉÐÅÃËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ìÉÐÅÃËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>íÁÇÁÄÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>íÁÇÁÄÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "íÁÇÁÄÁÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "þÕËÏÔÓËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>íÏÓËÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>íÏÓËÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "íÏÓËÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ ëÁÒÅÌÉÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>íÕÒÍÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>íÕÒÍÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "íÕÒÍÁÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>îÏ×ÇÏÒÏÄÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÏ×ÇÏÒÏÄÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "îÏ×ÇÏÒÏÄÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>îÏ×ÏÓÉÂÉÒÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>îÏ×ÏÓÉÂÉÒÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "îÏ×ÏÓÉÂÉÒÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ïÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ïÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ïÍÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ïÒÅÎÂÕÒÇÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ïÒÅÎÂÕÒÇÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ïÒÅÎÂÕÒÇÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ïÒÌÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ïÒÌÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ïÒÌÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ðÅÎÚÅÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÅÎÚÅÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ðÅÎÚÅÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ðÅÒÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÅÒÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ðÅÒÍÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ëÏÍÉ-ðÅÒÍÑÃËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ðÓËÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ðÓËÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ðÓËÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ ëÏÍÉ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ ëÏÍÉ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ ëÏÍÉ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÏÓÔÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÏÓÔÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÏÓÔÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÑÚÁÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÑÚÁÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÑÚÁÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>óÁÒÁÔÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÁÒÁÔÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "óÁÒÁÔÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>óÁÈÁÌÉÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÁÈÁÌÉÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "óÁÈÁÌÉÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "åËÁÔÅÒÉÎÂÕÒÇÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>óÍÏÌÅÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>óÍÏÌÅÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "óÍÏÌÅÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ôÁÍÂÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÁÍÂÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ôÁÍÂÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ôÏÍÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÏÍÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ôÏÍÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ôÕÌØÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÕÌØÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ôÕÌØÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ôÀÍÅÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ôÀÍÅÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ôÀÍÅÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ</TITLE>
+</HEAD>
+<BODY>
+<H1>òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "òÅÓÐÕÂÌÉËÁ íÁÒÉÊ üÌ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ Á×Ô.ÏËÒÕÇ"
+<P>
+èÁÎÔÙ-íÁÎÓÉÊÓËÉÊ ÏËÒÕÇ Ñ×ÌÑÅÔÓÑ ÞÁÓÔØÀ <A HREF="79.html">
+ôÀÍÅÎÓËÏÊ ÏÂÌÁÓÔÉ</A>
+<img src="../items/wand.gif">
+
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ñÍÁÌÏ-îÅÎÅÃËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>õÌØÑÎÏ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>õÌØÑÎÏ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "õÌØÑÎÏ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>þÅÌÑÂÉÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÅÌÑÂÉÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "þÅÌÑÂÉÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>þÉÔÉÎÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>þÉÔÉÎÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "þÉÔÉÎÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ</TITLE>
+</HEAD>
+<BODY>
+<H1>áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "áÇÉÎÓËÉÊ âÕÒÑÔÓËÉÊ Á×Ô.ÏËÒÕÇ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>ñÒÏÓÌÁ×ÓËÁÑ</TITLE>
+</HEAD>
+<BODY>
+<H1>ñÒÏÓÌÁ×ÓËÁÑ</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "ñÒÏÓÌÁ×ÓËÁÑ"
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>íÏÒÄÏ×ÓËÁÑ óóò</TITLE>
+</HEAD>
+<BODY>
+<H1>íÏÒÄÏ×ÓËÁÑ óóò</H1>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "íÏÒÄÏ×ÓËÁÑ óóò"
+</BODY>
+</HTML>
--- /dev/null
+#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_
+
--- /dev/null
+-2 ìÅÓÏÒÁÓÔ. ÒÁÊÏÎÉÒÏ×ÁÎÉÅ
+ 1 úÏÎÁ ÁÒËÔÉÞÅÓËÏÊ ÐÕÓÔÙÎÉ
+ 2 úÏÎÁ ÔÕÎÄÒÙ -ÒÁ×ÎÉÎÎÁÑ
+ 3 úÏÎÁ ÔÕÎÄÒÙ -ÇÏÒÎÁÑ
+ 4 úÏÎÁ ÌÅÓÏÔÕÎÄÒÙ
+ 5 úÏÎÁ ÌÕÇÏ× É ÌÕÇÏ×ÙÈ ÒÅÄËÏÌÅÓÉÊ
+ 6 ðÏÄÚÏÎÁ ÒÅÄËÏÓÔÏÊÎÏÊ ÔÁÊÇÉ
+ 7 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÔÁÊÇÉ
+ 8 ðÏÄÚÏÎÁ ÓÒÅÄÎÅÊ ÔÁÊÇÉ
+ 9 ðÏÄÚÏÎÁ ÀÖÎÏÊ ÔÁÊÇÉ
+ 10 óÅ×ÅÒÎÁÑ ÐÏÄÚÏÎÁ Ó ÐÒÅÏÂÌÁÄÁÎÉÅÍ È×ÏÊÎÙÈ
+ 11 àÖÎÁÑ ÐÏÄÚÏÎÁ Ó ÏÄÉÎÁËÏ×ÙÍ ÕÞÁÓÔÉÅÍ È×ÏÊÎÙÈ É ÛÉÒÏËÏÌÉÓÔ×ÅÎÎÙÈ
+ 12 óÅ×ÅÒÎÁÑ ÐÏÄÚÏÎÁ ÍÏÎÏÄÏÍÉÎÁÎÔÎÙÈ ÌÅÓÏ×
+ 13 àÖÎÁÑ ÐÏÄÚÏÎÁ ÐÏÌÉÄÏÍÉÎÁÎÔÎÙÈ-ÔÅÒÍÏÆÉÌØÎÙÈ ÌÅÓÏ×
+ 14 ìÅÓÏÓÔÅÐÎÁÑ ÚÏÎÁ
+ 15 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÙÈ ÓÔÅÐÅÊ
+ 16 ðÏÄÚÏÎÁ ÀÖÎÙÈ ÓÔÅÐÅÊ
+ 17 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+ 18 ðÏÄÚÏÎÁ ÀÖÎÏÊ ÐÏÌÕÐÕÓÔÙÎÉ
+ 19 ðÏÄÚÏÎÁ ÓÅ×ÅÒÎÏÊ ÐÕÓÔÙÎÉ
+ 20 ðÏÄÚÏÎÁ ÀÖÎÏÊ ÐÕÓÔÙÎÉ
+
--- /dev/null
+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>
+
+üÔÏ ÏÐÉÓÁÎÉÅ ÒÅÇÉÏÎÁ "$text"
+</BODY>
+</HTML>"
+close $f2
+}
+close $out
+close $f
+
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+#! /home/vitus/fgis/tcl/hypermap
+info proc hyper_*
+hyper_layer admin admin_html
+add_layer admin.lay
+add_layer lesras.lay