Index: unk/FACT++/www/index.css
===================================================================
--- /trunk/FACT++/www/index.css	(revision 13685)
+++ 	(revision )
@@ -1,181 +1,0 @@
-.thead {
-	background: #23a0da url(gradient.png) bottom left repeat-x;
-	color: #09415b;
-	padding: 2px 6px 2px 6px;
-/*	padding: 4px 6px;*/
-	border-color: #1379a8;
-	border-style: solid;
-	border-width: 1px 1px 1px 1px;
-	text-shadow: 0 1px 0 #37b2eb;
-	/*-moz-border-radius: 5px 5px 0 0;*/
-	/*-webkit-border-top-left-radius: 5px;*/
-	/*-webkit-border-top-right-radius: 5px;*/
-	font-size: 13px;
-}
-
-.thead a {
-	color: #09415b;
-	text-decoration: none;
-}
-/*
-.tcat {
-	background: #444;
-	color: #fff;
-	padding: 4px 6px;
-	font-size: 12px;
-}
-
-.tcat a {
-	color: #fff;
-}
-*/
-
-.tcol0 {
-	border-left: 1px solid #ccc;
-	border-bottom: 1px solid #ccc;
-        text-align:left;
-        padding-left:5px;
-        margin:0;
-}
-
-.tcol1 {
-	border-bottom: 1px solid #ccc;
-        padding-left:3px;
-        padding-right:3px;
-        margin:0;
-}
-
-.tcol2 {
-	border-right: 1px solid #ccc;
-	border-bottom: 1px solid #ccc;
-        text-align:right;
-        margin:0;
-        padding-right:5px;
-}
-
-.description {
-        text-align:left;
-}
-
-.tcell1 {
-        font-weight:bolder;
-        text-align:left;
-}
-
-.tcell2 {
-        text-align:right;
-}
-
-
-.tcell3 {
-        text-align:center;
-}
-
-/*
-.trow3 {
-	background: #eee;
-	border-bottom: 1px solid #ccc;
-	padding: 4px;
-}
-*/
-
-.icon_black {
-   -webkit-box-shadow: rgba(255, 255, 255, 0.398438) 0px 1px 0px 0px;
-   /*background-attachment: scroll;*/
-   /*background-clip: border-box;*/
-   background-color: rgba(0, 0, 0, 0);
-   background-image: url(icons-18-black.png);
-   /*background-origin: padding-box;*/
-   background-repeat: no-repeat;
-   box-shadow: rgba(255, 255, 255, 0.398438) 0px 1px 0px 0px;
-   padding: 0;
-   margin:0;
-   white-space: nowrap;
-   width: 18px;
-   height: 18px;
-   zoom: 1;
-}
-
-.icon_white {
-   -webkit-box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;
-   /*background-attachment: scroll;*/
-   /*background-clip: border-box;*/
-   background-color: rgba(0, 0, 0, 0.398438);
-   background-image: url(icons-18-white.png);
-   /*background-origin: padding-box;*/
-   background-repeat: no-repeat;
-   box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;
-   padding: 0;
-   margin:0;
-   white-space: nowrap;
-   width: 18px;
-   height: 18px;
-   zoom: 1;
-}
-
-.icon_color {
-   /*-webkit-box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;*/
-   /*background-attachment: scroll;*/
-   /*background-clip: border-box;*/
-   /*background-color: rgba(0, 0, 0, 0.398438);*/
-   background-image: url(icons.png);
-   /*background-origin: padding-box;*/
-   background-repeat: no-repeat;
-   /*box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;*/
-   padding: 0;
-   margin:0;
-   white-space: nowrap;
-   width: 18px;
-   height: 18px;
-   zoom: 1.5;
-   display:table-cell;
-}
-
-/*
-.trow_shaded {
-	background: #ffdde0;
-	border-bottom: 1px solid #fcc;
-}
-
-.trow_selected td {
-	background: #FFFBD9;
-}
-
-.trow_sep {
-	background: #ddd;
-	color: #555;
-	padding: 4px;
-	text-align: center;
-
-	font-size: 12px;
-	font-weight: bold;
-}
-*/
-.tfoot {
-	background: #737373 url(gradient.png) bottom left repeat-x;
-	color: #fff;
-	border-color: #525252;
-	border-style: solid;
-	border-width: 2px 1px 1px 1px;
-	vertical-align: middle;
-	padding: 0px 6px 4px 6px;
-	/*-moz-border-radius: 0 0 5px 5px;*/
-	/*-webkit-border-bottom-left-radius: 5px;*/
-	/*-webkit-border-bottom-right-radius: 5px;*/
-	text-shadow: 0 -1px 0 #333;
-	font-size: 12px;
-}
-
-.tfoot a {
-	color: #fff;
-	text-decoration: none;
-}
-
-.container
-{
- 	padding: 0;
-        margin: 0;
-        width: 100%;
-        border-left:  1px solid #ccc;
-        border-right: 1px solid #ccc;
-}
Index: unk/FACT++/www/index.html
===================================================================
--- /trunk/FACT++/www/index.html	(revision 13685)
+++ 	(revision )
@@ -1,12 +1,0 @@
-<!DOCTYPE HTML>
-<html>
-
-<head>
-  <title>SmartFACT++</title>
-  <script type="text/javascript" src="index.js"></script>
-  <link rel="stylesheet" type="text/css" href="index.css" />
-  <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
-</head>
-
-<body id="body" onload="onload();" onresize="onresize();"/>
-</html>
Index: unk/FACT++/www/index.js
===================================================================
--- /trunk/FACT++/www/index.js	(revision 13685)
+++ 	(revision )
@@ -1,1360 +1,0 @@
-var debug = false;
-
-var map = [ 393, 390, 391, 394, 1098, 395, 392, 389, 387, 388, 386,
-1001, 1004, 1099, 1101, 1100, 1111, 1108, 286, 283, 377, 375, 376, 383,
-384, 999, 1002, 1005, 1007, 1102, 1104, 1103, 1114, 1113, 1110, 1107,
-285, 282, 280, 374, 372, 373, 380, 381, 382, 385, 1000, 1003, 1006,
-990, 992, 1105, 1089, 1106, 1126, 1125, 1115, 1112, 1109, 287, 284,
-281, 279, 277, 371, 369, 370, 413, 378, 379, 422, 425, 428, 431, 983,
-986, 991, 993, 995, 1090, 1092, 1091, 1129, 1128, 1127, 1138, 1135,
-1150, 1147, 1144, 259, 256, 278, 276, 274, 368, 366, 367, 410, 411,
-412, 419, 420, 423, 426, 429, 981, 984, 987, 989, 994, 996, 998, 1093,
-1095, 1094, 1132, 1131, 1130, 1141, 1140, 1137, 1134, 1149, 1146, 1143,
-258, 255, 253, 275, 273, 271, 365, 363, 364, 407, 408, 409, 416, 417,
-418, 421, 424, 427, 430, 982, 985, 988, 972, 974, 997, 1035, 1037,
-1096, 1080, 1097, 1117, 1116, 1133, 1234, 1233, 1142, 1139, 1136, 1151,
-1148, 1145, 260, 257, 254, 252, 268, 272, 270, 322, 362, 360, 361, 404,
-405, 406, 521, 414, 415, 512, 533, 536, 539, 920, 923, 926, 911, 914,
-973, 975, 977, 1036, 1038, 1040, 1081, 1083, 1082, 1120, 1119, 1118,
-1237, 1236, 1235, 1228, 1225, 1258, 1255, 1252, 205, 202, 199, 196,
-193, 269, 267, 265, 323, 321, 319, 359, 357, 358, 401, 402, 403, 518,
-519, 520, 509, 510, 531, 534, 537, 918, 921, 924, 909, 912, 915, 917,
-976, 978, 980, 1039, 1041, 1043, 1084, 1086, 1085, 1123, 1122, 1121,
-1240, 1239, 1238, 1231, 1230, 1227, 1224, 1257, 1254, 1251, 204, 201,
-198, 195, 192, 190, 266, 264, 262, 320, 318, 316, 356, 354, 355, 398,
-399, 400, 515, 516, 517, 506, 507, 508, 511, 532, 535, 538, 919, 922,
-925, 910, 913, 916, 900, 902, 979, 963, 965, 1042, 1026, 1028, 1087,
-1071, 1088, 1180, 1179, 1124, 1216, 1215, 1241, 1288, 1287, 1232, 1229,
-1226, 1259, 1256, 1253, 206, 203, 200, 197, 194, 191, 189, 187, 263,
-261, 250, 317, 315, 313, 353, 351, 352, 467, 396, 397, 503, 513, 514,
-575, 504, 505, 611, 524, 527, 530, 929, 932, 935, 848, 851, 854, 821,
-824, 901, 903, 905, 964, 966, 968, 1027, 1029, 1031, 1072, 1074, 1073,
-1183, 1182, 1181, 1219, 1218, 1217, 1291, 1290, 1289, 1327, 1324, 1249,
-1246, 1243, 214, 211, 208, 142, 139, 136, 106, 103, 188, 186, 184, 251,
-249, 247, 314, 312, 310, 350, 348, 349, 464, 465, 466, 500, 501, 502,
-572, 573, 574, 608, 609, 522, 525, 528, 927, 930, 933, 846, 849, 852,
-819, 822, 825, 827, 904, 906, 908, 967, 969, 971, 1030, 1032, 1034,
-1075, 1077, 1076, 1186, 1185, 1184, 1222, 1221, 1220, 1294, 1293, 1292,
-1330, 1329, 1326, 1323, 1248, 1245, 1242, 213, 210, 207, 141, 138, 135,
-105, 102, 100, 185, 183, 181, 248, 246, 244, 311, 309, 307, 347, 345,
-346, 461, 462, 463, 497, 498, 499, 569, 570, 571, 605, 606, 607, 610,
-523, 526, 529, 928, 931, 934, 847, 850, 853, 820, 823, 826, 810, 812,
-907, 891, 893, 970, 954, 956, 1033, 1017, 1019, 1078, 1062, 1079, 1171,
-1170, 1187, 1207, 1206, 1223, 1279, 1278, 1295, 1315, 1314, 1331, 1328,
-1325, 1250, 1247, 1244, 215, 212, 209, 143, 140, 137, 107, 104, 101,
-99, 97, 182, 180, 178, 245, 243, 241, 308, 306, 304, 344, 342, 343,
-458, 459, 460, 494, 495, 496, 566, 567, 568, 602, 603, 604, 647, 650,
-653, 656, 659, 662, 665, 857, 860, 863, 839, 842, 845, 830, 833, 811,
-813, 815, 892, 894, 896, 955, 957, 959, 1018, 1020, 1022, 1063, 1065,
-1064, 1174, 1173, 1172, 1210, 1209, 1208, 1282, 1281, 1280, 1318, 1317,
-1316, 1363, 1360, 1375, 1372, 1369, 1384, 1381, 1378, 133, 130, 127,
-124, 121, 118, 115, 112, 98, 96, 94, 179, 177, 175, 242, 240, 238, 305,
-303, 301, 332, 330, 331, 455, 456, 457, 491, 492, 493, 563, 564, 565,
-599, 600, 601, 644, 645, 648, 651, 654, 657, 660, 663, 855, 858, 861,
-837, 840, 843, 828, 831, 834, 836, 814, 816, 818, 895, 897, 899, 958,
-960, 962, 1021, 1023, 1025, 1066, 1068, 1067, 1177, 1176, 1175, 1213,
-1212, 1211, 1285, 1284, 1283, 1321, 1320, 1319, 1366, 1365, 1362, 1359,
-1374, 1371, 1368, 1383, 1380, 1377, 132, 129, 126, 123, 120, 117, 114,
-111, 109, 95, 93, 91, 176, 174, 172, 239, 237, 235, 302, 300, 298, 329,
-327, 328, 452, 453, 454, 488, 489, 490, 560, 561, 562, 596, 597, 598,
-641, 642, 643, 646, 649, 652, 655, 658, 661, 664, 856, 859, 862, 838,
-841, 844, 829, 832, 835, 756, 758, 817, 792, 794, 898, 882, 884, 961,
-945, 947, 1024, 1008, 1010, 1069, 1044, 1070, 1162, 1161, 1178, 1198,
-1197, 1214, 1270, 1269, 1286, 1306, 1305, 1322, 1342, 1341, 1367, 1364,
-1361, 1376, 1373, 1370, 1385, 1382, 1379, 134, 131, 128, 125, 122, 119,
-116, 113, 110, 108, 43, 92, 90, 79, 173, 171, 169, 236, 234, 232, 299,
-297, 295, 326, 324, 325, 449, 450, 451, 485, 486, 487, 557, 558, 559,
-593, 594, 595, 629, 639, 640, 638, 695, 698, 701, 668, 671, 674, 677,
-680, 683, 749, 752, 755, 740, 743, 746, 775, 777, 757, 759, 761, 793,
-795, 797, 883, 885, 887, 946, 948, 950, 1009, 1011, 1013, 1045, 1047,
-1046, 1165, 1164, 1163, 1201, 1200, 1199, 1273, 1272, 1271, 1309, 1308,
-1307, 1345, 1344, 1343, 1353, 1351, 1420, 1417, 1414, 1393, 1390, 1387,
-1402, 1399, 1396, 34, 31, 28, 25, 22, 19, 62, 60, 44, 42, 40, 80, 78,
-76, 170, 168, 166, 233, 231, 229, 296, 294, 292, 341, 339, 340, 446,
-447, 448, 482, 483, 484, 554, 555, 556, 590, 591, 592, 626, 627, 628,
-636, 637, 693, 696, 699, 666, 669, 672, 675, 678, 681, 747, 750, 753,
-738, 741, 744, 774, 776, 778, 779, 760, 762, 764, 796, 798, 800, 886,
-888, 890, 949, 951, 953, 1012, 1014, 1016, 1054, 1057, 1048, 1168,
-1167, 1166, 1204, 1203, 1202, 1276, 1275, 1274, 1312, 1311, 1310, 1348,
-1347, 1346, 1355, 1354, 1352, 1350, 1419, 1416, 1413, 1392, 1389, 1386,
-1401, 1398, 1395, 33, 30, 27, 24, 21, 18, 61, 59, 58, 41, 39, 37, 77,
-75, 73, 167, 165, 163, 230, 228, 226, 293, 291, 289, 338, 336, 337,
-443, 444, 445, 479, 480, 481, 551, 552, 553, 587, 588, 589, 623, 624,
-625, 634, 635, 684, 687, 694, 697, 700, 667, 670, 673, 676, 679, 682,
-748, 751, 754, 739, 742, 745, 787, 789, 791, 780, 765, 763, 769, 770,
-799, 801, 803, 889, 875, 864, 952, 936, 938, 1015, 1053, 1055, 1058,
-1061, 1059, 1050, 1049, 1169, 1153, 1152, 1205, 1188, 1260, 1277, 1297,
-1296, 1313, 1337, 1336, 1349, 1332, 1356, 1412, 1410, 1408, 1421, 1418,
-1415, 1394, 1391, 1388, 1403, 1400, 1397, 35, 32, 29, 26, 23, 20, 65,
-63, 56, 55, 53, 38, 36, 48, 74, 72, 161, 164, 162, 152, 227, 225, 224,
-290, 288, 219, 335, 333, 334, 435, 441, 442, 440, 477, 478, 476, 549,
-550, 548, 585, 586, 615, 621, 622, 620, 631, 632, 633, 685, 688, 691,
-709, 706, 703, 718, 715, 712, 736, 733, 730, 727, 724, 721, 783, 785,
-788, 790, 781, 782, 766, 767, 771, 773, 802, 804, 873, 874, 865, 866,
-937, 939, 940, 942, 1056, 1060, 1052, 1051, 1157, 1156, 1155, 1154,
-1190, 1189, 1262, 1261, 1299, 1298, 1339, 1338, 1334, 1333, 1358, 1357,
-1411, 1409, 1406, 1404, 1424, 1427, 1430, 1433, 1436, 1439, 11, 14, 17,
-2, 5, 8, 69, 67, 64, 57, 54, 52, 51, 50, 47, 89, 88, 84, 160, 159, 151,
-150, 148, 223, 222, 221, 218, 216, 433, 434, 437, 438, 439, 473, 474,
-475, 546, 547, 579, 583, 584, 614, 617, 618, 619, 630, 686, 689, 692,
-708, 705, 702, 717, 714, 711, 735, 732, 729, 726, 723, 720, 784, 786,
-768, 772, 805, 806, 808, 880, 877, 876, 867, 869, 871, 941, 943, 944,
-1160, 1159, 1158, 1194, 1192, 1191, 1263, 1265, 1264, 1302, 1301, 1300,
-1340, 1335, 1407, 1405, 1422, 1425, 1428, 1431, 1434, 1437, 9, 12, 15,
-0, 3, 6, 71, 68, 66, 49, 46, 45, 87, 83, 82, 158, 156, 149, 147, 146,
-144, 220, 217, 432, 436, 469, 470, 471, 472, 543, 545, 577, 578, 582,
-612, 613, 616, 710, 707, 704, 719, 716, 713, 737, 734, 731, 728, 725,
-722, 807, 809, 878, 879, 881, 868, 870, 872, 1196, 1195, 1193, 1268,
-1267, 1266, 1304, 1303, 1423, 1426, 1429, 1432, 1435, 1438, 10, 13, 16,
-1, 4, 7, 86, 85, 81, 157, 155, 154, 153, 145, 468, 540, 541, 542, 544,
-576, 580, 581, 70, 690 ];
-
-/*
-
-<a href="#" onMouseover="playsound(soundfile)">Example 1</a>
-<a href="#" onMouseover="playsound('different.wav')">Example 2</a>
-
-<div id="coolmenu" onMouseover="bindsound('A', soundfile, this)">
-
-<script type="text/javascript">
-
-//
-// JavaScript Sound effect- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
-// Visit http://www.dynamicDrive.com for hundreds of DHTML scripts
-// This notice must stay intact for legal use
-//
-
-var soundfile="sidebar.wav" //path to sound file, or pass in filename directly into playsound()
-
-function playsound(soundfile){
-if (document.all && document.getElementById){
-document.getElementById("soundeffect").src="" //reset first in case of problems
-document.getElementById("soundeffect").src=soundfile
-}
-}
-
-function bindsound(tag, soundfile, masterElement){
-if (!window.event) return
-var source=event.srcElement
-while (source!=masterElement && source.tagName!="HTML"){
-if (source.tagName==tag.toUpperCase()){
-playsound(soundfile)
-break
-}
-source=source.parentElement
-}
-}
-
-</script>
-
-Function "bindsound()" accepts 3 parameters- 1) The tag name of the element to bind the sound to ("A" for <a>, "SPAN" for <span> etc), 2) the sound file to play, whether a variable or path to sound file, and finally, 3), the keyword "this", which should never be modified.
-
-// -----------------------
-<audio controls="controls" height="50px" width="100px">
-  <source src="song.mp3" type="audio/mpeg" />
-  <source src="song.ogg" type="audio/ogg" />
-<embed height="50px" width="100px" src="song.mp3" />
-</audio>
-// ------------------------
-
-*/
-function $(id) { return document.getElementById(id); }
-function trim(str) { return str.replace("/^\s\s*/", '').replace("/\s\s*$/", ''); }
-function valid(str) { if (str==undefined) return false; if (str.length==0) return false; return true;}
-function isSliding() { var z = $("body").getAttribute("data-visible"); return $("table"+z).offsetLeft!=0; }
-
-function cycleCol(el)
-{
-    var col = el.getAttribute("data-color");
-    col++;
-    col %= 31;
-    el.setAttribute("data-color", col);
-    if (col>16)
-        col = 31-col;
-    var hex = col.toString(16);
-    el.style.color = "#"+hex+"0"+hex+"0"+hex+"f";
-}
-
-/*
-function newWindow(newContent) 
-{
-    if (document.referrer != "http://www.referringPageName.html")
-        return;
-
-    winContent = window.open(newContent,
-                             'nextWin',
-                             'right=0,top=20,width=350,height=350,toolbar=no,scrollbars=no,resizable=no');
-                             }*/
-
-function onload()
-{
-    try { new XMLHttpRequest(); }
-    catch(e)
-    {
-        alert("Your browser doesn't support dynamic reload.");
-        return;
-    }
-
-    var name = location.hash.length==0 ? "fact" : location.hash.substr(1);
-
-    /*
-     alert("0 -- "+navigator.appCodeName+"\n"+
-          "1 -- "+navigator.appName+"\n"+
-          "2 -- "+navigator.appVersion+"\n"+
-          "3 -- "+navigator.platform+"\n"+
-          "4 -- "+navigator.userAgent);
-          */
-    loadPage(name, 0, 0);
-}
-
-function onresize()
-{
-    var z = $("body").getAttribute("data-visible");
-    doresize(z);
-}
-
-function loadPage(name, z, dz)
-{
-    var xmlPage = new XMLHttpRequest();
-    xmlPage.open('POST', name+'.table', true);
-    xmlPage.onload = function ()
-    {
-        if (xmlPage.status!=200)
-        {
-            alert("ERROR[0] - HTTP request '"+name+".table': "+xmlPage.statusText+" ["+xmlPage.status+"]");
-            //setTimeout("loadPage('+name+')", 5000);
-            /****** invalidate ******/
-            return;
-        }
-
-        buildPage(name, xmlPage.responseText, z, dz);
-        changePage(z, z+dz);
-
-        //changePage(name, xmlHttp.resposeText);
-        //slideOut(name, xmlHttp.responseText);
-        //displayPage(name, xmlHttp.responseText);
-            //onresize(true);
-    };
-
-    xmlPage.send(null);
-
-    location.hash = name;
-}
-
-function sendCommand(command, debug)
-{
-    var uri = "index.php?";
-    if (debug==true)
-        uri += "debug&";
-    uri += command;
-
-    var xmlCmd = new XMLHttpRequest();
-    xmlCmd.open('POST', uri, true);
-    xmlCmd.onload = function()
-    {
-        if (xmlCmd.status!=200)
-        {
-            alert("ERROR[1] - HTTP request: "+xmlCmd.statusText+" ["+xmlCmd.status+"]");
-            return;
-        }
-
-        if (xmlCmd.responseText.length==0)
-        {
-            alert("No proper acknowledgment of command execution received.");
-            return;
-        }
-
-        var txt = xmlCmd.responseText.split('\n');
-        switch (txt[0])
-        {
-        case "1": alert("dimctrl unreachable."); break;
-        case "2": /*success*/ break;
-        default: alert("Return code '"+txt[0]+"' unknown."); break;
-        }
-        if (txt.length>1)
-            alert(xmlCmd.responseText);
-    };
-    xmlCmd.send(null);
-}
-
-
-function submit(script)
-{
-    var inputs = document.getElementsByTagName("input");
-
-    var args = "start="+script;
-    for (var i=0; i<inputs.length; i++)
-        args += "&"+inputs[i].name+"="+inputs[i].value;
-
-    alert(args);
-
-    sendCommand(args);
-
-}
-
-function buildPage(name, text, oldz, dz)
-{
-    var fname = dz==0 ? "fact" : $("table"+oldz).getAttribute("data-file");
-
-    var z = oldz + dz;
-
-    var lines = text.split('\n');
-
-    if (lines.length==0)
-    {
-        alert("buildPage - received data empty.");
-        return;
-    }
-
-    if (lines[0].length==0)
-    {
-        alert("buildPage - title missing");
-        return;
-    }
-
-    var title = lines[0].split('/');
-
-    var table = $("table"+z);
-    if (table != undefined)
-        $("body").removeChild(table);
-
-    table = document.createElement("table");
-    table.setAttribute("class", "tborder");
-    table.id = "table"+z;
-    table.border = 0;
-    table.cellSpacing = 0;
-    table.cellPadding = "0px";
-    table.width = "100%";
-    table.setAttribute("style", "overflow:hidden;position:fixed;top:0px;left:"+window.innerWidth+"px;");
-
-    // -----------------------------------------------------
-
-    var th = document.createElement("thead");
-    th.colSpan = 3;
-    th.width = "100%";
-    table.appendChild(th);
-
-    var htr = document.createElement("tr");
-    th.appendChild(htr);
-
-    var htd = document.createElement("td");
-    htd.setAttribute("class", "thead");
-    htd.colSpan = 3;
-    htd.width = "100%";
-    htr.appendChild(htd);
-
-    // -------------
-
-    var htab = document.createElement("table");
-    htab.width = "100%";
-    htd.appendChild(htab);
-
-    var hhtr = document.createElement("tr");
-    htab.appendChild(hhtr);
-
-    var htd0 = document.createElement("td");
-    var htd1 = document.createElement("td");
-    var htd2 = document.createElement("td");
-    var htd3 = document.createElement("td");
-    htd0.setAttribute("class", "tcell1");
-    htd1.setAttribute("class", "tcell2");
-    htd2.setAttribute("class", "tcell1");
-    htd2.setAttribute("width", "1px");
-    htd3.setAttribute("class", "tcell1");
-    htd3.setAttribute("width", "1px");
-    hhtr.appendChild(htd3);
-    hhtr.appendChild(htd0);
-    hhtr.appendChild(htd1);
-    hhtr.appendChild(htd2);
-
-    var div1 = document.createElement("div");
-    var div2 = document.createElement("div");
-    var div3 = document.createElement("div");
-    div2.setAttribute("class", "icon_white");
-    div3.setAttribute("class", "icon_white");
-    div2.setAttribute("style", "background-position:-396px 50%;");
-    div3.setAttribute("style", "background-position:-575px 50%;");
-    div3.onclick = function() { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('fact', z, -z); }
-    div2.onclick = function() { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage(fname, z, -dz); }
-
-    var sp0 = document.createElement("span");
-    var sp1 = document.createElement("span");
-    var sp2 = document.createElement("span");
-    sp0.id = "ldot" +z;
-    sp1.id = "title"+z;
-    sp2.id = "rdot" +z;
-    sp1.setAttribute("style", "font-size:large;");
-    sp0.setAttribute("data-color", "3");
-    sp2.setAttribute("data-color", "3");
-    sp0.appendChild(document.createTextNode(" \u2022 "));
-    sp1.appendChild(document.createTextNode(title[0]));
-    sp2.appendChild(document.createTextNode(" \u2022 "));
-    if (title[1]!=undefined)
-        sp1.onclick = function() { submit(title[1]); }
-
-    div1.setAttribute("style", "font-size:small;");
-    div1.id = "reporttime"+z;
-    div1.appendChild(document.createTextNode("---"));
-
-    htd0.appendChild(sp0);
-    htd0.appendChild(sp1);
-    htd0.appendChild(sp2);
-
-    htd1.appendChild(div1);
-    if (dz!=0/* && z+dz!=0*/)
-        htd2.appendChild(div2); // back
-    if (lines[0]!="FACT")
-        htd3.appendChild(div3); // home
-
-    // -----------------------------------------------------
-
-    var tbody = document.createElement("tbody");
-    table.appendChild(tbody);
-
-    // -----------------------------------------------------
-
-    var tf = document.createElement("tfoot");
-    table.appendChild(tf);
-
-    var ftr = document.createElement("tr");
-    tf.appendChild(ftr);
-
-    var ftd = document.createElement("td");
-    ftd.setAttribute("class",   "tfoot");
-    ftd.width = "100%";
-    ftd.colSpan = 3;
-    ftr.appendChild(ftd);
-
-    var ftab = document.createElement("table");
-    ftab.width = "100%";
-    ftd.appendChild(ftab);
-
-    var ftd0 = document.createElement("td");
-    var ftd1 = document.createElement("td");
-
-    ftd0.setAttribute("class", "tcell1");
-    ftd1.setAttribute("class", "tcell2");
-
-    ftab.appendChild(ftd0);
-    ftab.appendChild(ftd1);
-
-    var fdiv0 = document.createElement("span");
-    var fdiv1 = document.createElement("span");
-
-    fdiv0.setAttribute("style", "font-size:large;");
-    fdiv1.setAttribute("style", "font-size:small;");
-    fdiv1.id = "localtime"+z;
-
-    fdiv0.appendChild(document.createTextNode("logbook"));
-    fdiv1.appendChild(document.createTextNode("loading..."));
-
-    ftd0.appendChild(fdiv0);
-    ftd1.appendChild(fdiv1);
-
-    $("body").appendChild(table);
-
-    var counter = 1;
-    for (var i=1; i<lines.length; i++)
-    {
-        lines[i] = trim(lines[i]);
-
-        if (lines[i].length==0 || lines[i][0] == '#')
-            continue;
-
-        var cols = lines[i].split(':');
-        if (cols.length != 3 && cols.length !=4)
-        {
-            alert("Wrong number of columns in line #"+i+" in '"+name+"': '"+lines[i]+"' N(cols)="+cols.length);
-            continue;
-        }
-
-        var check = cols[1].split("=");
-
-        if (check.length>1 && (check[0]=="camera" || check[0]=="hist"))
-        {
-            var data = cols[1].substring(check[0].length+1).split("/");
-
-            var tr = document.createElement("tr");
-            tr.setAttribute("class", "row");
-            //tr.setAttribute("style", "margin:0;padding:0;");
-
-            var td = document.createElement("td");
-            td.setAttribute("class", "container");
-            td.id = "container";
-            td.colSpan = 3;
-            tr.appendChild(td);
-
-            var canv = document.createElement("canvas");
-            canv.id = "canvas"+z;
-            canv.width = "1";
-            canv.height = "1";
-            //canv.onclick = function() { save(); }
-            canv.setAttribute("data-type", check[0]);
-            canv.setAttribute("data-file", data[0]);
-            canv.setAttribute("data-data", cols[1].substring(check[0].length+data[0].length+2));
-//            canv.setAttribute("style", "display:none;");
-            td.appendChild(canv);
-
-            var img = document.createElement("img");
-            img.src = "dummy.png";//needed in firefox
-            img.id = "image"+z;
-            img.setAttribute("style", "width:1px;height:1px;display:none;");
-            td.appendChild(img);
-
-            tbody.appendChild(tr);
-            continue;
-        }
-
-        var tr = document.createElement("tr");
-        tr.setAttribute("class", "row");
-        if (valid(cols[0]))
-            tr.setAttribute("onclick", "this.style.background='#ccb'; loadPage('"+cols[0]+"', "+z+", -1);");
-        if (valid(cols[3]))
-            tr.setAttribute("onclick", "this.style.background='#ccb'; loadPage('"+cols[3]+"', "+z+", +1);");
-
-        var td0 = document.createElement("td");
-        td0.setAttribute("class", "tcol0");
-        if (valid(cols[0]))
-        {
-            var sp = document.createElement("div");
-            sp.setAttribute("class", "icon_black");
-            sp.setAttribute("style", "background-position: -144px 50%;");
-            td0.appendChild(sp);
-        }
-        tr.appendChild(td0);
-
-        var td1 = document.createElement("td");
-        td1.setAttribute("class", "tcol1");
-        td1.width = "100%";
-        tr.appendChild(td1);
-
-        var td2 = document.createElement("td");
-        td2.setAttribute("class", "tcol2");
-        td2.width = "18px";
-        if (valid(cols[3]))
-        {
-            var sp = document.createElement("div");
-            sp.setAttribute("class", "icon_black");
-            sp.setAttribute("style", "background-position: -108px 50%;");
-            td2.appendChild(sp);
-        }
-        tr.appendChild(td2);
-
-        var tab = document.createElement("table");
-        tab.width = "100%";
-        td1.appendChild(tab);
-
-        var innertr = document.createElement("tr");
-        tab.appendChild(innertr);
-
-        var cell1 = document.createElement("td");
-        cell1.setAttribute("class", "tcell1");
-
-        var cell2 = document.createElement("td");
-        cell2.setAttribute("class", "tcell2");
-
-        if (check.length==0 || check[0]!="input")
-        {
-            cell1.appendChild(document.createTextNode(cols[1]));
-
-            if (cols.length>2 && cols[2].length>0)
-            {
-                cell2.id = "data"+counter;
-                cell2.setAttribute("data-form",  cols[2]);
-                cell2.appendChild(document.createTextNode("---"));
-                counter++;
-            }
-            else
-                cell1.setAttribute("class", "description");
-        }
-        else
-        {
-            var opt = check[1].split('/');
-
-            if (opt.length<2)
-                alert("Argument name missing for'"+check[1]+"'");
-
-            cell1.appendChild(document.createTextNode(opt[0]));
-
-            var input = document.createElement("input");
-            input.name = opt[1];
-            input.type = "text";
-            input.maxlength = 80;
-            if (opt.length>2)
-                input.value=opt[2];
-
-            cell2.appendChild(input);
-        }
-
-        innertr.appendChild(cell1);
-        innertr.appendChild(cell2);
-
-        tbody.appendChild(tr);
-    }
-/*
-    if (true)
-    {
-        tr = document.createElement("tr");
-        tr.setAttribute("class", "row");
-
-        td = document.createElement("td");
-        td.colSpan = "3";
-        tr.appendChild(td);
-
-        var sp = document.createElement("div");
-        sp.setAttribute("class", "icon_color");
-        sp.setAttribute("style", "background-position: -144px -14px;");
-        td.appendChild(sp);
-
-        sp = document.createElement("div");
-        sp.setAttribute("class", "icon_color");
-        sp.setAttribute("style", "background-position: -56px -14px;");
-        td.appendChild(sp);
-
-        tr.appendChild(td);
-
-        tbody.appendChild(tr);
-    }
-*/
-    // ---------------------------------------
-    if (debug == true)
-    {
-        tr = document.createElement("tr");
-        tr.setAttribute("class", "row");
-
-        td = document.createElement("td");
-        td.id = "debug"+z;
-        td.colSpan = 3;
-        tr.appendChild(td);
-
-        tbody.appendChild(tr);
-    }
-
-    // ---------------------------------------
-
-    table.setAttribute("data-file", name);
-    doresize(z);
-}
-
-function resizeimpl(z, cnt)
-{
-    // 393 / 482    488/482 / 200   200+482-488
-    var img  = $("image"+z);
-    var canv = $("canvas"+z);
-    if (img == undefined || canv == undefined)
-        return;
-
-    var h = $("table"+z).offsetHeight;
-    if (h == 0)
-        return;
-
-    var W = window.innerWidth;
-    var H = window.innerHeight;
-
-/*
-    if (W==0 || H==0)
-    {
-        var w = $("table"+z).offsetWidth;
-        img.style.width = w+"px";
-        img.style.height= w+"px";
-
-        canv.width  = w;
-        canv.height = w;
-        return;
-    }
-*/
-
-    var ih = H - h + parseInt(img.style.height, 10);
-
-    img.style.width = W +"px";
-    img.style.height= ih+"px";
-
-    canv.width  = W;
-    canv.height = ih;
-
-    // ------ debug -----
-    if (debug == true)
-    {
-        $('debug'+z).innerHTML = "";
-        $('debug'+z).innerHTML += "|W="+W +"/"+H;
-        $('debug'+z).innerHTML += "|H="+h+"/"+$("table"+z).offsetHeight+"/"+img.offsetHeight;
-        $('debug'+z).innerHTML += "|I="+img.style.height+"+"+H+"-"+h;
-    }
-
-    if ($("table"+z).offsetHeight == H || cnt==2)
-    {
-        // ------ debug -----
-        if (debug == true)
-        {
-            $('debug'+z).innerHTML = "";
-            $('debug'+z).innerHTML += "|W="+W +"/"+H;
-            $('debug'+z).innerHTML += "|H="+h+"/"+$("table"+z).offsetHeight+"/"+img.offsetHeight;
-            $('debug'+z).innerHTML += "|I="+img.style.height+"+"+H+"-"+h;
-        }
-        return;
-    }
-
-    resizeimpl(z, ++cnt);
-}
-
-function doresize(z)
-{
-    resizeimpl(z, 0);
-}
-
-var intervalSlide = null;
-
-function changePage(oldz, newz)
-{
-    // No page displayed yet
-    if (oldz==newz)
-    {
-        $("table"+newz).style.left="0px";
-        $("body").setAttribute("data-visible", newz);
-
-        doresize(0);
-
-        //setInterval(refresh_text, 1000);
-        //setInterval(refresh_graphics, 5000);
-
-        refresh_text();
-        refresh_graphics();
-        return;
-    }
-
-    var W = window.innerWidth;
-    if (W==0)
-    {
-        $("table"+newz).style.left="0px";
-        $("body").setAttribute("data-visible", newz);
-        $("body").removeChild($("table"+oldz));
-        return;
-    }
-
-    if (newz>oldz)
-        $("table"+newz).style.left = W+"px";
-    else
-        $("table"+newz).style.left = (-W-1)+"px";
-
-    //window.clearTimeout(timeoutText);
-    //window.clearTimeout(timeoutGraphics);
-
-    $("body").setAttribute("data-visible", newz);
-    intervalSlide = setInterval(function(){doShift(oldz,newz)}, 75);
-}
-
-function doShift(oldz, newz)
-{
-    var t0 = $("table"+oldz);
-    var t1 = $("table"+newz);
-
-    if (t0.style.display=="none")
-    {
-        clearInterval(intervalSlide);
-        $("body").removeChild(t0);
-        return;
-    }
-
-    var x0 = t0.offsetLeft;
-    var x1 = t1.offsetLeft;
-
-    var W = window.innerWidth;
-
-    if (newz<oldz)
-    {
-        x0 += W/5;
-        x1 += W/5;
-    }
-
-    if (newz>oldz)
-    {
-        x0 -= W/5;
-        x1 -= W/5;
-    }
-
-    if ((newz<oldz && x1>=0) || (newz>oldz && x1<=0))
-    {
-        t0.style.display="none";
-        x1 = 0;
-    }
-
-    t0.style.left = x0+"px";
-    t1.style.left = x1+"px";
-}
-
-var timeoutText = null;
-var timeoutGraphics = null;
-
-function refresh_text()
-{
-    var z=$("body").getAttribute("data-visible");
-    var table = $("table"+z);
-
-    // Is sliding or no file defined?
-    var fname = table.getAttribute("data-file");
-    if (isSliding() || !valid(fname))
-    {
-        // invalidate?
-        timeoutText = setTimeout(refresh_text, 1000);
-        return;
-    }
-
-    var xmlText = new XMLHttpRequest();
-    xmlText.open('POST', fname+'.txt', true);
-    xmlText.onload = function ()
-    {
-        if (xmlText.status!=200)
-        {
-            alert("ERROR[1] - HTTP request '"+fname+".txt': "+xmlText.statusText+" ["+xmlText.status+"]");
-            timeoutText = setTimeout(refresh_text, 10000);
-            return;
-        }
-
-        if (!isSliding())
-        {
-            cycleCol($("ldot"+z));
-            update_text(fname, xmlText.responseText);
-        }
-        timeoutText = setTimeout(refresh_text, 3000);
-    };
-    xmlText.send(null);
-}
-
-function strike(e, status)
-{
-    if (!e)
-        return;
-
-    if (!status)
-        e.style.textDecoration="line-through";
-    else
-        e.style.textDecoration="";
-}
-
-/*
-function gray(id, str)
-{
-    var e = $(id);
-    if (!e)
-        return;
-
-    if (valid(str))
-    {
-        e.style.color="#000";
-        e.style.textDecoration="";
-    }
-    else
-    {
-        e.style.color="#daa";
-        e.style.textDecoration="line-through";
-    }
-}
-*/
-var date0 = null;
-
-function update_text(fname, result)
-{
-    var z=$("body").getAttribute("data-visible");
-    var table = $("table"+z);
-
-    if (table.getAttribute("data-file") != fname)
-        return;
-
-    var tokens = result.split('\n');
-
-    // ----------------------------------------------------
-
-    var  time = $("reporttime"+z);
-    var ltime = $("localtime"+z);
-
-    var date1 = new Date();
-
-    if (tokens[0].length!=13)
-    {
-        if (date0 != null)
-            strike(time, date0.getTime()+60000>date1.getTime());
-        // FIXME: Reset display to "---" values -- no connection
-        return;
-    }
-
-    var date2 = new Date();
-    date2.setTime(tokens[0]);
-
-    strike(time, date2.getTime()+60000>date1.getTime());
-
-    date0 = date2;
-
-    var utc = date0.toUTCString();
-
-    time.innerHTML =
-        "&#8226;&nbsp;"+utc.substr(utc.length-12, 8)+"&nbsp;UTC&nbsp;&#8226;"
-    ltime.innerHTML =
-        "&#8226;&nbsp;"+date1.toLocaleString()+"&nbsp;&#8226;";
-
-    // ----------------------------------------------------
-
-    var p = table.tBodies.length==3 ? 1 : 0;
-    var tbody = table.tBodies[p];
-
-    for (var line=1; line<tokens.length; line++)
-    {
-        if (tokens[line].length==0)
-            continue;
-
-        if (tbody.rows[line-1]==undefined)
-            continue;
-
-        var c = tbody.rows[line-1].cells[1];
-        if (c == undefined)
-            continue;
-
-        var e = c.childNodes[0].rows[0].cells[1];
-        if (e == undefined)
-            continue;
-
-        var form = e.getAttribute("data-form");
-        if (form==undefined)
-            continue;
-
-        var cols = tokens[line].split('\t');
-        for (var col=1; col<cols.length; col++)
-            form = form.replace("\$"+(col-1), cols[col].length==0 ? "--" : cols[col]);
-
-        if (cols.length<=1)
-            form = "---";
-
-        var newe = document.createElement("div");
-        newe.innerHTML = form;
-        e.replaceChild(newe, e.lastChild);
-
-        e.parentNode.parentNode.parentNode.parentNode.style.background=cols[0];
-    }
-}
-
-// http://billmill.org/static/canvastutorial/index.html
-// http://www.netmagazine.com/tutorials/learning-basics-html5-canvas
-// http://www.alistapart.com/articles/responsive-web-design/
-
-function refresh_graphics()
-{
-    var z = $("body").getAttribute("data-visible");
-
-    var canvas = $("canvas"+z);
-
-    // Is sliding or no data file defined?
-    var fname = canvas==null ? "" : canvas.getAttribute("data-file");
-    if (isSliding() || !valid(fname))
-    {
-        // invalidate?
-        timeoutGraphics = setTimeout(refresh_graphics, 1000);
-        return;
-    }
-
-    var xmlGfx = new XMLHttpRequest();
-    xmlGfx.open('POST', fname, true);
-    xmlGfx.onload = function()
-    {
-        if (xmlGfx.status!=200)
-        {
-            alert("ERROR[2] - Request '"+fname+"': "+xmlGfx.statusText+" ["+xmlGfx.status+"]");
-            timeoutGraphics = setTimeout(refresh_graphics, 10000);
-            //****** invalidate ******
-            return;
-        }
-
-        if (!isSliding())
-        {
-            cycleCol($("rdot"+z));
-            process_eventdata(xmlGfx.responseText);
-        }
-        timeoutGraphics = setTimeout(refresh_graphics, 5000)
-    };
-    xmlGfx.send(null);
-}
-
-
-function hueToRGB(hue)
-{
-    hue /= 3;
-    hue %= 6;
-
-    if (hue<1) return parseInt(255*hue,     10);
-    if (hue<3) return parseInt(255,         10);
-    if (hue<4) return parseInt(255*(4-hue), 10);
-
-/*
-    if (hue<1*5/4) return parseInt(255*hue*4/5);
-    if (hue<2*5/4) return parseInt(255);
-    if (hue<3*5/4) return parseInt(255*(3*5/4-hue)*4/5);
-*/
-/*
-    if (hue<1.5) return parseInt(255*hue/1.5);
-    if (hue<3.0) return parseInt(255);
-    if (hue<4.5) return parseInt(255*(4.5-hue)/1.5);
-*/
-    return 0.
-}
-
-function hueToHex(flt)
-{
-    var s = hueToRGB(flt).toString(16);
-    return s.length==2 ? s : "0"+s;
-}
-
-function HLStoRGB(hue)
-{
-    hue *= 14;
-
-    var sr = hueToHex(20-hue);
-    var sg = hueToHex(14-hue);
-    var sb = hueToHex(26-hue);
-
-    return sr+sg+sb;
-}
-
-
-function color(col)
-{
-    if (col==65533)
-        col = 0;
-
-    var hue = col/128;
-    return HLStoRGB(hue);
-}
-
-function toHex(str, idx)
-{
-    var ch = str[idx].toString(16);
-    return ch.length==2 ? ch : "0"+ch;
-}
-
-function drawHex(ctx, x, y, col)
-{
-    ctx.fillStyle = "#"+color(col);
-
-    ctx.save();
-
-    ctx.translate(x, y);
-    ctx.scale(1/2, 1/3);
-
-    ctx.beginPath();
-    ctx.moveTo( 1,  1);
-    ctx.lineTo( 0,  2);
-    ctx.lineTo(-1,  1);
-    ctx.lineTo(-1, -1);
-    ctx.lineTo( 0, -2);
-    ctx.lineTo( 1, -1);
-    ctx.fill();
-
-    ctx.restore();
-}
-
-function drawDisc(ctx, x, y, r, col)
-{
-    ctx.fillStyle = "#"+color(col);
-
-    ctx.save();
-
-    ctx.translate(x, y);
-
-    ctx.beginPath();
-    ctx.arc(0, 0, r, 0, Math.PI*2, true);
-    ctx.fill();
-
-    ctx.restore();
-}
-
-function beginDrawCam(scale)
-{
-    var z    = $("body").getAttribute("data-visible");
-    var canv = $("canvas"+z);
-
-    var w = Math.min(canv.width/scale, canv.height/scale);
-
-    var ctx = canv.getContext("2d");
-
-    ctx.save();
-    ctx.translate(canv.width/2, canv.height/2);
-    ctx.scale(w*2, w*2);
-
-    return ctx;
-}
-
-/**
- * @constructor
- */
-function position(s, ring, i)
-{
-    switch (s)
-    {
-    case 1: this.x =  ring     - i*0.5;  this.y =       + i; break;
-    case 2: this.x =  ring*0.5 - i;      this.y =  ring    ; break;
-    case 3: this.x = -ring*0.5 - i*0.5;  this.y =  ring - i; break;
-    case 4: this.x = -ring     + i*0.5;  this.y =       - i; break;
-    case 5: this.x = -ring*0.5 + i;      this.y = -ring    ; break;
-    case 0: this.x =  ring*0.5 + i*0.5;  this.y = -ring + i; break;
-    }
-    this.d = function() { return this.x*this.x + this.y*this.y*3/4; }
-}
-
-function drawFullCam(data)
-{
-    if (data.length!=40 && data.length!=160 && data.length!=320 && data.length!=1440)
-    {
-        alert("Camera - Received data has invalid size ("+data.length+"b)");
-        return;
-    }
-
-    var div = map.length/data.length;
-    var off = data.length==320 ? 0.2 : 0;
-
-    var ctx = beginDrawCam(83);
-    // ctx.rotate(Math.PI/3);
-
-    ctx.scale(1, Math.sqrt(3)/2);
-    ctx.translate(-0.5, 0);
-
-    drawHex(ctx, 0, 0, data.charCodeAt(parseInt(map[0]/div+off, 10)));
-
-    var cnt = 1;
-    for (var ring=1; ring<24; ring++)
-    {
-        for (var s=0; s<6; s++)
-        {
-            for (var i=1; i<=ring; i++)
-            {
-                var pos = new position(s, ring, i);
-                if (pos.d() - pos.x > 395.75)
-                    continue;
-
-                var p = parseInt(map[cnt]/div+off, 10);
-
-                drawHex(ctx, pos.x, pos.y, data.charCodeAt(p));
-                cnt++;
-            }
-        }
-    }
-
-    drawHex(ctx, 7, -22, data.charCodeAt(parseInt(map[1438]/div+off, 10)));
-    drawHex(ctx, 7,  22, data.charCodeAt(parseInt(map[1439]/div+off, 10)));
-
-    ctx.restore();
-}
-
-function drawCam(data)
-{
-    var ctx = beginDrawCam(27);
-    ctx.rotate(Math.PI/6);
-    ctx.scale(1, Math.sqrt(3)/2);
-
-    drawHex(ctx, 0, 0, data.charCodeAt(0));
-
-    var cnt = 1;
-    for (var ring=1; ring<=7; ring++)
-    {
-        for (var s=0; s<6; s++)
-        {
-            for (var i=1; i<=ring; i++)
-            {
-                var pos = new position(s, ring, i);
-                if (pos.d() > 44)
-                    continue;
-
-                if (ring==7)
-                {
-                    if (i==6 && (s==0 || s==3))
-                        continue;
-                    if (i==1 && (s==1 || s==4))
-                        continue;
-                }
-
-                drawHex(ctx, pos.x, pos.y, data.charCodeAt(cnt++));
-            }
-        }
-    }
-
-    ctx.restore();
-}
-
-function drawCamLegend(canv, min, max)
-{
-    var unit = canv.getAttribute("data-data");//.split("/");
-    if (unit.length>0)
-        unit = " "+unit;
-
-    var v0 = parseFloat(min);
-    var v1 = parseFloat(max);
-
-    var diff = v1-v0;
-
-    var cw = canv.width;
-    var ch = canv.height;
-
-    var ctx = canv.getContext("2d");
-
-    ctx.font         = "8pt Arial";
-    ctx.textAlign    = "right";
-    ctx.textBaseline = "top";
-
-    for (var i=0; i<11; i++)
-    {
-        ctx.strokeStyle = "#"+color(16*i);
-        ctx.strokeText((v0+diff*i/10).toPrecision(3)+unit, cw-5, 120-i*12);
-    }
-}
-
-function drawGraph(canv, min, max, data)
-{
-    var unit = canv.getAttribute("data-data");//.split("/");
-    if (unit.length>0)
-        unit = " "+unit;
-
-    var cw = canv.width;
-    var ch = canv.height;
-
-    var ctx = canv.getContext("2d");
-
-    var dw = 3;  // tick width
-
-    var fs = 8;  // font size
-
-    ctx.font      = fs+"pt Arial";
-    ctx.textAlign = "right";
-
-    var dim0 = ctx.measureText(min+unit);
-    var dim1 = ctx.measureText(max+unit);
-
-    var tw = Math.max(dim0.width, dim1.width)+dw+2;
-
-    var ml = 5+tw; // margin left
-    var mr = 10;   // margin right
-
-    var mt = fs/2+5; // margin top
-    var mb = fs/2+4; // margin bottom
-
-    var nx = 20;
-    var ny = 10;
-
-    var w = cw-ml-mr;
-    var h = ch-mt-mb;
-
-    ctx.strokeStyle = "#666";
-
-    // --- data ---
-    ctx.beginPath();
-    ctx.moveTo(ml, ch-mb-data.charCodeAt(0)/128*h);
-    for (var i=1; i<data.length; i++)
-        ctx.lineTo(ml+w/(data.length-1)*i, ch-mb-data.charCodeAt(i)/128*h);
-
-    // --- finalize data ---
-    ctx.lineTo(cw-mr, ch-mb);
-    ctx.lineTo(ml,    ch-mb);
-    ctx.fillStyle = "#"+color(100);
-    ctx.stroke();
-    ctx.fill();
-
-    ctx.beginPath();
-
-    // --- grid ---
-
-    ctx.strokeStyle = "#eee";
-
-    for (var i=1; i<=nx; i++)
-    {
-        ctx.moveTo(ml+w/nx*i, ch-mb);
-        ctx.lineTo(ml+w/nx*i,    mt);
-    }
-    for (var i=0; i<ny; i++)
-    {
-        ctx.moveTo(ml,   mb+h/ny*i);
-        ctx.lineTo(ml+w, mb+h/ny*i);
-    }
-    ctx.stroke();
-    ctx.closePath();
-    ctx.beginPath();
-
-    ctx.strokeStyle = "#000";
-
-    // --- axes ---
-    ctx.moveTo(ml,    mt);
-    ctx.lineTo(ml,    ch-mb);
-    ctx.lineTo(cw-mr, ch-mb);
-
-    for (var i=1; i<=nx; i++)
-    {
-        ctx.moveTo(ml+w/nx*i, ch-mb-dw);
-        ctx.lineTo(ml+w/nx*i, ch-mb+dw);
-    }
-    for (var i=0; i<ny; i++)
-    {
-        ctx.moveTo(ml-dw, mb+h/ny*i);
-        ctx.lineTo(ml+dw, mb+h/ny*i);
-    }
-    ctx.stroke();
-    ctx.closePath();
-
-    ctx.textBaseline = "bottom";
-    ctx.strokeText(min+unit, ml-dw-2, ch-1);
-
-    ctx.textBaseline = "top";
-    ctx.strokeText(max+unit, ml-dw-2, 0);
-}
-
-var gfxtime0 = null;
-
-function process_eventdata(result)
-{
-    if (result.length==0)
-        return;
-
-    var z = $("body").getAttribute("data-visible");
-    var canv = $("canvas"+z);
-    if (canv == undefined)
-        return;
-
-    var type = canv.getAttribute("data-type");
-
-    var ctx = canv.getContext("2d");
-    ctx.clearRect(0, 0, canv.width, canv.height);
-
-    var data = result.split('\n');
-    if (result.length<3)
-        return;
-
-    var l = data[0].length+1+data[1].length+1;
-
-    switch (type)
-    {
-        //case "camera": drawCam(result);     break;
-    case "hist":
-        drawGraph(canv, data[0], data[1], result.substr(l));
-        break;
-    case "camera":
-        drawFullCam(result.substr(l));
-        drawCamLegend(canv, data[0], data[1]);
-        break;
-    }
-
-    var date = new Date();
-    if (gfxtime0 != null && gfxdate0.getTime()+60000>date.getTime())
-    {
-        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
-        ctx.fillRect(0, 0, canv.width, canv.height);
-    }
-
-    //$("image"+z).src = canv.toDataURL("image/png");
-}
-
-function save()
-{
-    var z = $("body").getAttribute("data-visible");
-
-    var canvas = $("canvas"+z);
-    var img    = canvas.toDataURL("image/png");
-
-    img = img.replace("image/png", "image/octet-stream");
-
-    document.location.href = img;
-}
-
-window['onload'] = onload;
Index: unk/FACT++/www/index.php
===================================================================
--- /trunk/FACT++/www/index.php	(revision 13685)
+++ 	(revision )
@@ -1,134 +1,0 @@
-<?PHP
-
-require_once("config.php");
-
-function login()
-{
-    global $ldaphost;
-    global $baseDN;
-    global $groupDN;
-
-    $username = $_SERVER['PHP_AUTH_USER'];
-    $password = $_SERVER['PHP_AUTH_PW'];
-
-    $con = @ldap_connect($ldaphost);
-    if (!$con)
-        return "ldap_connect failed to ".$ldaphost;
-
-    //------------------ Look for user common name
-    $attributes = array('cn', 'mail');
-    $dn         = 'ou=People,'.$baseDN;
-    $filter     = '(uid='.$username.')';
-
-    $sr = @ldap_search($con, $dn, $filter, $attributes);
-    if (!$sr)
-        return "ldap_search failed for dn=".$dn.": ".ldap_error($con);
-
-    $srData = @ldap_get_entries($con, $sr);
-    if ($srData["count"]==0)
-        return "No results returned by ldap_get_entries for dn=".$dn.".";
-
-    $email         =$srData[0]['mail'][0];
-    $userCommonName=$srData[0]['cn'][0];
-    $userDN        =$srData[0]['dn'];
-
-    //------------------ Authenticate user
-    if (!@ldap_bind($con, $userDN, $password))
-        return "ldap_bind failed: ".ldap_error($con);
-
-    //------------------ Check if the user is in FACT ldap group
-    $attributes= array("member");
-    $filter= '(objectClass=*)';
-
-    // Get all members of the group.
-    $sr = @ldap_read($con, $groupDN, $filter, $attributes);
-    if (!$sr)
-        return "ldap_read failed for dn=".$groupDN.": ".ldap_error($con);
-
-    // retrieve the corresponding data
-    $srData = @ldap_get_entries($con, $sr);
-    if ($srData["count"]==0)
-        return "No results returned by ldap_get_entries for dn=".$dn.".";
-
-    @ldap_unbind($con);
-
-    $found = false;
-    foreach ($srData[0]['member'] as $member)
-        if (strpos($member, "cn=".$userCommonName.",")===0)
-            return "";
-
-    return "Sorry, your credentials don't match!";
-}
-// --------------------------------------------------------------------
-
-if (isset($_GET['logout']))
-{
-    if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']))
-        return;
-
-    return header('HTTP/1.0 401 Successfull logout!');
-}
-
-// --------------------------------------------------------------------
-
-if (!isset($_GET['start']) && !isset($_GET['stop']))
-    return header('HTTP/1.0 400 Command not supported');
-
-// --------------------------------------------------------------------
-
-if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']))
-{
-    header('WWW-Authenticate: Basic realm="SmartFACT++"');
-    header('HTTP/1.0 401 Unauthorized');
-    return;
-}
-
-$rc = login();
-if ($rc!="")
-    return header('HTTP/1.0 401 '.$rc);
-
-// --------------------------------------------------------------------
-
-$out = array();
-
-if (isset($_GET['stop']))
-    $str = exec($path."/dimctrl --stop", $out, $rc);
-
-if (isset($_GET['start']))
-{
-    $args = '\"'.$_GET['start'].'\"';
-
-    unset($_GET['start']);
-
-    /*
-     $args = "";
-     foreach ($_GET as $key => $value)
-        $args .= " --arg:".$key."=".$value;
-     $str = exec($path."/dimctrl --exec ".$args, $out, $rc);
-     */
-
-    if (isset($_GET['label']))
-    {
-        if ($_GET['label']>=0)
-            $args .= ":".$_GET['label'];
-        unset($_GET['label']);
-    }
-
-    foreach ($_GET as $key => $value)
-        $args .= ' \"'.$key.'='.$value.'\"';
-
-    $str = exec($path.'/dimctrl --start "'.$args.'"', $out, $rc);
-}
-
-if ($rc!=1 && $rc!=2)
-    return header('HTTP/1.0 500 Execution failed [rc='.$rc."]");
-
-print($rc);
-
-if (isset($_GET['debug']))
-{
-    print("\n");
-    print_r($out);
-}
-
-?>
Index: /trunk/FACT++/www/smartfact/index.css
===================================================================
--- /trunk/FACT++/www/smartfact/index.css	(revision 13686)
+++ /trunk/FACT++/www/smartfact/index.css	(revision 13686)
@@ -0,0 +1,181 @@
+.thead {
+	background: #23a0da url(gradient.png) bottom left repeat-x;
+	color: #09415b;
+	padding: 2px 6px 2px 6px;
+/*	padding: 4px 6px;*/
+	border-color: #1379a8;
+	border-style: solid;
+	border-width: 1px 1px 1px 1px;
+	text-shadow: 0 1px 0 #37b2eb;
+	/*-moz-border-radius: 5px 5px 0 0;*/
+	/*-webkit-border-top-left-radius: 5px;*/
+	/*-webkit-border-top-right-radius: 5px;*/
+	font-size: 13px;
+}
+
+.thead a {
+	color: #09415b;
+	text-decoration: none;
+}
+/*
+.tcat {
+	background: #444;
+	color: #fff;
+	padding: 4px 6px;
+	font-size: 12px;
+}
+
+.tcat a {
+	color: #fff;
+}
+*/
+
+.tcol0 {
+	border-left: 1px solid #ccc;
+	border-bottom: 1px solid #ccc;
+        text-align:left;
+        padding-left:5px;
+        margin:0;
+}
+
+.tcol1 {
+	border-bottom: 1px solid #ccc;
+        padding-left:3px;
+        padding-right:3px;
+        margin:0;
+}
+
+.tcol2 {
+	border-right: 1px solid #ccc;
+	border-bottom: 1px solid #ccc;
+        text-align:right;
+        margin:0;
+        padding-right:5px;
+}
+
+.description {
+        text-align:left;
+}
+
+.tcell1 {
+        font-weight:bolder;
+        text-align:left;
+}
+
+.tcell2 {
+        text-align:right;
+}
+
+
+.tcell3 {
+        text-align:center;
+}
+
+/*
+.trow3 {
+	background: #eee;
+	border-bottom: 1px solid #ccc;
+	padding: 4px;
+}
+*/
+
+.icon_black {
+   -webkit-box-shadow: rgba(255, 255, 255, 0.398438) 0px 1px 0px 0px;
+   /*background-attachment: scroll;*/
+   /*background-clip: border-box;*/
+   background-color: rgba(0, 0, 0, 0);
+   background-image: url(icons-18-black.png);
+   /*background-origin: padding-box;*/
+   background-repeat: no-repeat;
+   box-shadow: rgba(255, 255, 255, 0.398438) 0px 1px 0px 0px;
+   padding: 0;
+   margin:0;
+   white-space: nowrap;
+   width: 18px;
+   height: 18px;
+   zoom: 1;
+}
+
+.icon_white {
+   -webkit-box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;
+   /*background-attachment: scroll;*/
+   /*background-clip: border-box;*/
+   background-color: rgba(0, 0, 0, 0.398438);
+   background-image: url(icons-18-white.png);
+   /*background-origin: padding-box;*/
+   background-repeat: no-repeat;
+   box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;
+   padding: 0;
+   margin:0;
+   white-space: nowrap;
+   width: 18px;
+   height: 18px;
+   zoom: 1;
+}
+
+.icon_color {
+   /*-webkit-box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;*/
+   /*background-attachment: scroll;*/
+   /*background-clip: border-box;*/
+   /*background-color: rgba(0, 0, 0, 0.398438);*/
+   background-image: url(icons.png);
+   /*background-origin: padding-box;*/
+   background-repeat: no-repeat;
+   /*box-shadow: rgba(255, 255, 255, 0.398438) 1px 1px 0px 0px;*/
+   padding: 0;
+   margin:0;
+   white-space: nowrap;
+   width: 18px;
+   height: 18px;
+   zoom: 1.5;
+   display:table-cell;
+}
+
+/*
+.trow_shaded {
+	background: #ffdde0;
+	border-bottom: 1px solid #fcc;
+}
+
+.trow_selected td {
+	background: #FFFBD9;
+}
+
+.trow_sep {
+	background: #ddd;
+	color: #555;
+	padding: 4px;
+	text-align: center;
+
+	font-size: 12px;
+	font-weight: bold;
+}
+*/
+.tfoot {
+	background: #737373 url(gradient.png) bottom left repeat-x;
+	color: #fff;
+	border-color: #525252;
+	border-style: solid;
+	border-width: 2px 1px 1px 1px;
+	vertical-align: middle;
+	padding: 0px 6px 4px 6px;
+	/*-moz-border-radius: 0 0 5px 5px;*/
+	/*-webkit-border-bottom-left-radius: 5px;*/
+	/*-webkit-border-bottom-right-radius: 5px;*/
+	text-shadow: 0 -1px 0 #333;
+	font-size: 12px;
+}
+
+.tfoot a {
+	color: #fff;
+	text-decoration: none;
+}
+
+.container
+{
+ 	padding: 0;
+        margin: 0;
+        width: 100%;
+        border-left:  1px solid #ccc;
+        border-right: 1px solid #ccc;
+}
Index: /trunk/FACT++/www/smartfact/index.html
===================================================================
--- /trunk/FACT++/www/smartfact/index.html	(revision 13686)
+++ /trunk/FACT++/www/smartfact/index.html	(revision 13686)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+  <title>SmartFACT++</title>
+  <script type="text/javascript" src="index.js"></script>
+  <link rel="stylesheet" type="text/css" href="index.css" />
+  <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
+</head>
+
+<body id="body" onload="onload();" onresize="onresize();"/>
+</html>
Index: /trunk/FACT++/www/smartfact/index.js
===================================================================
--- /trunk/FACT++/www/smartfact/index.js	(revision 13686)
+++ /trunk/FACT++/www/smartfact/index.js	(revision 13686)
@@ -0,0 +1,1360 @@
+var debug = false;
+
+var map = [ 393, 390, 391, 394, 1098, 395, 392, 389, 387, 388, 386,
+1001, 1004, 1099, 1101, 1100, 1111, 1108, 286, 283, 377, 375, 376, 383,
+384, 999, 1002, 1005, 1007, 1102, 1104, 1103, 1114, 1113, 1110, 1107,
+285, 282, 280, 374, 372, 373, 380, 381, 382, 385, 1000, 1003, 1006,
+990, 992, 1105, 1089, 1106, 1126, 1125, 1115, 1112, 1109, 287, 284,
+281, 279, 277, 371, 369, 370, 413, 378, 379, 422, 425, 428, 431, 983,
+986, 991, 993, 995, 1090, 1092, 1091, 1129, 1128, 1127, 1138, 1135,
+1150, 1147, 1144, 259, 256, 278, 276, 274, 368, 366, 367, 410, 411,
+412, 419, 420, 423, 426, 429, 981, 984, 987, 989, 994, 996, 998, 1093,
+1095, 1094, 1132, 1131, 1130, 1141, 1140, 1137, 1134, 1149, 1146, 1143,
+258, 255, 253, 275, 273, 271, 365, 363, 364, 407, 408, 409, 416, 417,
+418, 421, 424, 427, 430, 982, 985, 988, 972, 974, 997, 1035, 1037,
+1096, 1080, 1097, 1117, 1116, 1133, 1234, 1233, 1142, 1139, 1136, 1151,
+1148, 1145, 260, 257, 254, 252, 268, 272, 270, 322, 362, 360, 361, 404,
+405, 406, 521, 414, 415, 512, 533, 536, 539, 920, 923, 926, 911, 914,
+973, 975, 977, 1036, 1038, 1040, 1081, 1083, 1082, 1120, 1119, 1118,
+1237, 1236, 1235, 1228, 1225, 1258, 1255, 1252, 205, 202, 199, 196,
+193, 269, 267, 265, 323, 321, 319, 359, 357, 358, 401, 402, 403, 518,
+519, 520, 509, 510, 531, 534, 537, 918, 921, 924, 909, 912, 915, 917,
+976, 978, 980, 1039, 1041, 1043, 1084, 1086, 1085, 1123, 1122, 1121,
+1240, 1239, 1238, 1231, 1230, 1227, 1224, 1257, 1254, 1251, 204, 201,
+198, 195, 192, 190, 266, 264, 262, 320, 318, 316, 356, 354, 355, 398,
+399, 400, 515, 516, 517, 506, 507, 508, 511, 532, 535, 538, 919, 922,
+925, 910, 913, 916, 900, 902, 979, 963, 965, 1042, 1026, 1028, 1087,
+1071, 1088, 1180, 1179, 1124, 1216, 1215, 1241, 1288, 1287, 1232, 1229,
+1226, 1259, 1256, 1253, 206, 203, 200, 197, 194, 191, 189, 187, 263,
+261, 250, 317, 315, 313, 353, 351, 352, 467, 396, 397, 503, 513, 514,
+575, 504, 505, 611, 524, 527, 530, 929, 932, 935, 848, 851, 854, 821,
+824, 901, 903, 905, 964, 966, 968, 1027, 1029, 1031, 1072, 1074, 1073,
+1183, 1182, 1181, 1219, 1218, 1217, 1291, 1290, 1289, 1327, 1324, 1249,
+1246, 1243, 214, 211, 208, 142, 139, 136, 106, 103, 188, 186, 184, 251,
+249, 247, 314, 312, 310, 350, 348, 349, 464, 465, 466, 500, 501, 502,
+572, 573, 574, 608, 609, 522, 525, 528, 927, 930, 933, 846, 849, 852,
+819, 822, 825, 827, 904, 906, 908, 967, 969, 971, 1030, 1032, 1034,
+1075, 1077, 1076, 1186, 1185, 1184, 1222, 1221, 1220, 1294, 1293, 1292,
+1330, 1329, 1326, 1323, 1248, 1245, 1242, 213, 210, 207, 141, 138, 135,
+105, 102, 100, 185, 183, 181, 248, 246, 244, 311, 309, 307, 347, 345,
+346, 461, 462, 463, 497, 498, 499, 569, 570, 571, 605, 606, 607, 610,
+523, 526, 529, 928, 931, 934, 847, 850, 853, 820, 823, 826, 810, 812,
+907, 891, 893, 970, 954, 956, 1033, 1017, 1019, 1078, 1062, 1079, 1171,
+1170, 1187, 1207, 1206, 1223, 1279, 1278, 1295, 1315, 1314, 1331, 1328,
+1325, 1250, 1247, 1244, 215, 212, 209, 143, 140, 137, 107, 104, 101,
+99, 97, 182, 180, 178, 245, 243, 241, 308, 306, 304, 344, 342, 343,
+458, 459, 460, 494, 495, 496, 566, 567, 568, 602, 603, 604, 647, 650,
+653, 656, 659, 662, 665, 857, 860, 863, 839, 842, 845, 830, 833, 811,
+813, 815, 892, 894, 896, 955, 957, 959, 1018, 1020, 1022, 1063, 1065,
+1064, 1174, 1173, 1172, 1210, 1209, 1208, 1282, 1281, 1280, 1318, 1317,
+1316, 1363, 1360, 1375, 1372, 1369, 1384, 1381, 1378, 133, 130, 127,
+124, 121, 118, 115, 112, 98, 96, 94, 179, 177, 175, 242, 240, 238, 305,
+303, 301, 332, 330, 331, 455, 456, 457, 491, 492, 493, 563, 564, 565,
+599, 600, 601, 644, 645, 648, 651, 654, 657, 660, 663, 855, 858, 861,
+837, 840, 843, 828, 831, 834, 836, 814, 816, 818, 895, 897, 899, 958,
+960, 962, 1021, 1023, 1025, 1066, 1068, 1067, 1177, 1176, 1175, 1213,
+1212, 1211, 1285, 1284, 1283, 1321, 1320, 1319, 1366, 1365, 1362, 1359,
+1374, 1371, 1368, 1383, 1380, 1377, 132, 129, 126, 123, 120, 117, 114,
+111, 109, 95, 93, 91, 176, 174, 172, 239, 237, 235, 302, 300, 298, 329,
+327, 328, 452, 453, 454, 488, 489, 490, 560, 561, 562, 596, 597, 598,
+641, 642, 643, 646, 649, 652, 655, 658, 661, 664, 856, 859, 862, 838,
+841, 844, 829, 832, 835, 756, 758, 817, 792, 794, 898, 882, 884, 961,
+945, 947, 1024, 1008, 1010, 1069, 1044, 1070, 1162, 1161, 1178, 1198,
+1197, 1214, 1270, 1269, 1286, 1306, 1305, 1322, 1342, 1341, 1367, 1364,
+1361, 1376, 1373, 1370, 1385, 1382, 1379, 134, 131, 128, 125, 122, 119,
+116, 113, 110, 108, 43, 92, 90, 79, 173, 171, 169, 236, 234, 232, 299,
+297, 295, 326, 324, 325, 449, 450, 451, 485, 486, 487, 557, 558, 559,
+593, 594, 595, 629, 639, 640, 638, 695, 698, 701, 668, 671, 674, 677,
+680, 683, 749, 752, 755, 740, 743, 746, 775, 777, 757, 759, 761, 793,
+795, 797, 883, 885, 887, 946, 948, 950, 1009, 1011, 1013, 1045, 1047,
+1046, 1165, 1164, 1163, 1201, 1200, 1199, 1273, 1272, 1271, 1309, 1308,
+1307, 1345, 1344, 1343, 1353, 1351, 1420, 1417, 1414, 1393, 1390, 1387,
+1402, 1399, 1396, 34, 31, 28, 25, 22, 19, 62, 60, 44, 42, 40, 80, 78,
+76, 170, 168, 166, 233, 231, 229, 296, 294, 292, 341, 339, 340, 446,
+447, 448, 482, 483, 484, 554, 555, 556, 590, 591, 592, 626, 627, 628,
+636, 637, 693, 696, 699, 666, 669, 672, 675, 678, 681, 747, 750, 753,
+738, 741, 744, 774, 776, 778, 779, 760, 762, 764, 796, 798, 800, 886,
+888, 890, 949, 951, 953, 1012, 1014, 1016, 1054, 1057, 1048, 1168,
+1167, 1166, 1204, 1203, 1202, 1276, 1275, 1274, 1312, 1311, 1310, 1348,
+1347, 1346, 1355, 1354, 1352, 1350, 1419, 1416, 1413, 1392, 1389, 1386,
+1401, 1398, 1395, 33, 30, 27, 24, 21, 18, 61, 59, 58, 41, 39, 37, 77,
+75, 73, 167, 165, 163, 230, 228, 226, 293, 291, 289, 338, 336, 337,
+443, 444, 445, 479, 480, 481, 551, 552, 553, 587, 588, 589, 623, 624,
+625, 634, 635, 684, 687, 694, 697, 700, 667, 670, 673, 676, 679, 682,
+748, 751, 754, 739, 742, 745, 787, 789, 791, 780, 765, 763, 769, 770,
+799, 801, 803, 889, 875, 864, 952, 936, 938, 1015, 1053, 1055, 1058,
+1061, 1059, 1050, 1049, 1169, 1153, 1152, 1205, 1188, 1260, 1277, 1297,
+1296, 1313, 1337, 1336, 1349, 1332, 1356, 1412, 1410, 1408, 1421, 1418,
+1415, 1394, 1391, 1388, 1403, 1400, 1397, 35, 32, 29, 26, 23, 20, 65,
+63, 56, 55, 53, 38, 36, 48, 74, 72, 161, 164, 162, 152, 227, 225, 224,
+290, 288, 219, 335, 333, 334, 435, 441, 442, 440, 477, 478, 476, 549,
+550, 548, 585, 586, 615, 621, 622, 620, 631, 632, 633, 685, 688, 691,
+709, 706, 703, 718, 715, 712, 736, 733, 730, 727, 724, 721, 783, 785,
+788, 790, 781, 782, 766, 767, 771, 773, 802, 804, 873, 874, 865, 866,
+937, 939, 940, 942, 1056, 1060, 1052, 1051, 1157, 1156, 1155, 1154,
+1190, 1189, 1262, 1261, 1299, 1298, 1339, 1338, 1334, 1333, 1358, 1357,
+1411, 1409, 1406, 1404, 1424, 1427, 1430, 1433, 1436, 1439, 11, 14, 17,
+2, 5, 8, 69, 67, 64, 57, 54, 52, 51, 50, 47, 89, 88, 84, 160, 159, 151,
+150, 148, 223, 222, 221, 218, 216, 433, 434, 437, 438, 439, 473, 474,
+475, 546, 547, 579, 583, 584, 614, 617, 618, 619, 630, 686, 689, 692,
+708, 705, 702, 717, 714, 711, 735, 732, 729, 726, 723, 720, 784, 786,
+768, 772, 805, 806, 808, 880, 877, 876, 867, 869, 871, 941, 943, 944,
+1160, 1159, 1158, 1194, 1192, 1191, 1263, 1265, 1264, 1302, 1301, 1300,
+1340, 1335, 1407, 1405, 1422, 1425, 1428, 1431, 1434, 1437, 9, 12, 15,
+0, 3, 6, 71, 68, 66, 49, 46, 45, 87, 83, 82, 158, 156, 149, 147, 146,
+144, 220, 217, 432, 436, 469, 470, 471, 472, 543, 545, 577, 578, 582,
+612, 613, 616, 710, 707, 704, 719, 716, 713, 737, 734, 731, 728, 725,
+722, 807, 809, 878, 879, 881, 868, 870, 872, 1196, 1195, 1193, 1268,
+1267, 1266, 1304, 1303, 1423, 1426, 1429, 1432, 1435, 1438, 10, 13, 16,
+1, 4, 7, 86, 85, 81, 157, 155, 154, 153, 145, 468, 540, 541, 542, 544,
+576, 580, 581, 70, 690 ];
+
+/*
+
+<a href="#" onMouseover="playsound(soundfile)">Example 1</a>
+<a href="#" onMouseover="playsound('different.wav')">Example 2</a>
+
+<div id="coolmenu" onMouseover="bindsound('A', soundfile, this)">
+
+<script type="text/javascript">
+
+//
+// JavaScript Sound effect- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
+// Visit http://www.dynamicDrive.com for hundreds of DHTML scripts
+// This notice must stay intact for legal use
+//
+
+var soundfile="sidebar.wav" //path to sound file, or pass in filename directly into playsound()
+
+function playsound(soundfile){
+if (document.all && document.getElementById){
+document.getElementById("soundeffect").src="" //reset first in case of problems
+document.getElementById("soundeffect").src=soundfile
+}
+}
+
+function bindsound(tag, soundfile, masterElement){
+if (!window.event) return
+var source=event.srcElement
+while (source!=masterElement && source.tagName!="HTML"){
+if (source.tagName==tag.toUpperCase()){
+playsound(soundfile)
+break
+}
+source=source.parentElement
+}
+}
+
+</script>
+
+Function "bindsound()" accepts 3 parameters- 1) The tag name of the element to bind the sound to ("A" for <a>, "SPAN" for <span> etc), 2) the sound file to play, whether a variable or path to sound file, and finally, 3), the keyword "this", which should never be modified.
+
+// -----------------------
+<audio controls="controls" height="50px" width="100px">
+  <source src="song.mp3" type="audio/mpeg" />
+  <source src="song.ogg" type="audio/ogg" />
+<embed height="50px" width="100px" src="song.mp3" />
+</audio>
+// ------------------------
+
+*/
+function $(id) { return document.getElementById(id); }
+function trim(str) { return str.replace("/^\s\s*/", '').replace("/\s\s*$/", ''); }
+function valid(str) { if (str==undefined) return false; if (str.length==0) return false; return true;}
+function isSliding() { var z = $("body").getAttribute("data-visible"); return $("table"+z).offsetLeft!=0; }
+
+function cycleCol(el)
+{
+    var col = el.getAttribute("data-color");
+    col++;
+    col %= 31;
+    el.setAttribute("data-color", col);
+    if (col>16)
+        col = 31-col;
+    var hex = col.toString(16);
+    el.style.color = "#"+hex+"0"+hex+"0"+hex+"f";
+}
+
+/*
+function newWindow(newContent) 
+{
+    if (document.referrer != "http://www.referringPageName.html")
+        return;
+
+    winContent = window.open(newContent,
+                             'nextWin',
+                             'right=0,top=20,width=350,height=350,toolbar=no,scrollbars=no,resizable=no');
+                             }*/
+
+function onload()
+{
+    try { new XMLHttpRequest(); }
+    catch(e)
+    {
+        alert("Your browser doesn't support dynamic reload.");
+        return;
+    }
+
+    var name = location.hash.length==0 ? "fact" : location.hash.substr(1);
+
+    /*
+     alert("0 -- "+navigator.appCodeName+"\n"+
+          "1 -- "+navigator.appName+"\n"+
+          "2 -- "+navigator.appVersion+"\n"+
+          "3 -- "+navigator.platform+"\n"+
+          "4 -- "+navigator.userAgent);
+          */
+    loadPage(name, 0, 0);
+}
+
+function onresize()
+{
+    var z = $("body").getAttribute("data-visible");
+    doresize(z);
+}
+
+function loadPage(name, z, dz)
+{
+    var xmlPage = new XMLHttpRequest();
+    xmlPage.open('POST', name+'.table', true);
+    xmlPage.onload = function ()
+    {
+        if (xmlPage.status!=200)
+        {
+            alert("ERROR[0] - HTTP request '"+name+".table': "+xmlPage.statusText+" ["+xmlPage.status+"]");
+            //setTimeout("loadPage('+name+')", 5000);
+            /****** invalidate ******/
+            return;
+        }
+
+        buildPage(name, xmlPage.responseText, z, dz);
+        changePage(z, z+dz);
+
+        //changePage(name, xmlHttp.resposeText);
+        //slideOut(name, xmlHttp.responseText);
+        //displayPage(name, xmlHttp.responseText);
+            //onresize(true);
+    };
+
+    xmlPage.send(null);
+
+    location.hash = name;
+}
+
+function sendCommand(command, debug)
+{
+    var uri = "index.php?";
+    if (debug==true)
+        uri += "debug&";
+    uri += command;
+
+    var xmlCmd = new XMLHttpRequest();
+    xmlCmd.open('POST', uri, true);
+    xmlCmd.onload = function()
+    {
+        if (xmlCmd.status!=200)
+        {
+            alert("ERROR[1] - HTTP request: "+xmlCmd.statusText+" ["+xmlCmd.status+"]");
+            return;
+        }
+
+        if (xmlCmd.responseText.length==0)
+        {
+            alert("No proper acknowledgment of command execution received.");
+            return;
+        }
+
+        var txt = xmlCmd.responseText.split('\n');
+        switch (txt[0])
+        {
+        case "1": alert("dimctrl unreachable."); break;
+        case "2": /*success*/ break;
+        default: alert("Return code '"+txt[0]+"' unknown."); break;
+        }
+        if (txt.length>1)
+            alert(xmlCmd.responseText);
+    };
+    xmlCmd.send(null);
+}
+
+
+function submit(script)
+{
+    var inputs = document.getElementsByTagName("input");
+
+    var args = "start="+script;
+    for (var i=0; i<inputs.length; i++)
+        args += "&"+inputs[i].name+"="+inputs[i].value;
+
+    alert(args);
+
+    sendCommand(args);
+
+}
+
+function buildPage(name, text, oldz, dz)
+{
+    var fname = dz==0 ? "fact" : $("table"+oldz).getAttribute("data-file");
+
+    var z = oldz + dz;
+
+    var lines = text.split('\n');
+
+    if (lines.length==0)
+    {
+        alert("buildPage - received data empty.");
+        return;
+    }
+
+    if (lines[0].length==0)
+    {
+        alert("buildPage - title missing");
+        return;
+    }
+
+    var title = lines[0].split('/');
+
+    var table = $("table"+z);
+    if (table != undefined)
+        $("body").removeChild(table);
+
+    table = document.createElement("table");
+    table.setAttribute("class", "tborder");
+    table.id = "table"+z;
+    table.border = 0;
+    table.cellSpacing = 0;
+    table.cellPadding = "0px";
+    table.width = "100%";
+    table.setAttribute("style", "overflow:hidden;position:fixed;top:0px;left:"+window.innerWidth+"px;");
+
+    // -----------------------------------------------------
+
+    var th = document.createElement("thead");
+    th.colSpan = 3;
+    th.width = "100%";
+    table.appendChild(th);
+
+    var htr = document.createElement("tr");
+    th.appendChild(htr);
+
+    var htd = document.createElement("td");
+    htd.setAttribute("class", "thead");
+    htd.colSpan = 3;
+    htd.width = "100%";
+    htr.appendChild(htd);
+
+    // -------------
+
+    var htab = document.createElement("table");
+    htab.width = "100%";
+    htd.appendChild(htab);
+
+    var hhtr = document.createElement("tr");
+    htab.appendChild(hhtr);
+
+    var htd0 = document.createElement("td");
+    var htd1 = document.createElement("td");
+    var htd2 = document.createElement("td");
+    var htd3 = document.createElement("td");
+    htd0.setAttribute("class", "tcell1");
+    htd1.setAttribute("class", "tcell2");
+    htd2.setAttribute("class", "tcell1");
+    htd2.setAttribute("width", "1px");
+    htd3.setAttribute("class", "tcell1");
+    htd3.setAttribute("width", "1px");
+    hhtr.appendChild(htd3);
+    hhtr.appendChild(htd0);
+    hhtr.appendChild(htd1);
+    hhtr.appendChild(htd2);
+
+    var div1 = document.createElement("div");
+    var div2 = document.createElement("div");
+    var div3 = document.createElement("div");
+    div2.setAttribute("class", "icon_white");
+    div3.setAttribute("class", "icon_white");
+    div2.setAttribute("style", "background-position:-396px 50%;");
+    div3.setAttribute("style", "background-position:-575px 50%;");
+    div3.onclick = function() { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('fact', z, -z); }
+    div2.onclick = function() { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage(fname, z, -dz); }
+
+    var sp0 = document.createElement("span");
+    var sp1 = document.createElement("span");
+    var sp2 = document.createElement("span");
+    sp0.id = "ldot" +z;
+    sp1.id = "title"+z;
+    sp2.id = "rdot" +z;
+    sp1.setAttribute("style", "font-size:large;");
+    sp0.setAttribute("data-color", "3");
+    sp2.setAttribute("data-color", "3");
+    sp0.appendChild(document.createTextNode(" \u2022 "));
+    sp1.appendChild(document.createTextNode(title[0]));
+    sp2.appendChild(document.createTextNode(" \u2022 "));
+    if (title[1]!=undefined)
+        sp1.onclick = function() { submit(title[1]); }
+
+    div1.setAttribute("style", "font-size:small;");
+    div1.id = "reporttime"+z;
+    div1.appendChild(document.createTextNode("---"));
+
+    htd0.appendChild(sp0);
+    htd0.appendChild(sp1);
+    htd0.appendChild(sp2);
+
+    htd1.appendChild(div1);
+    if (dz!=0/* && z+dz!=0*/)
+        htd2.appendChild(div2); // back
+    if (lines[0]!="FACT")
+        htd3.appendChild(div3); // home
+
+    // -----------------------------------------------------
+
+    var tbody = document.createElement("tbody");
+    table.appendChild(tbody);
+
+    // -----------------------------------------------------
+
+    var tf = document.createElement("tfoot");
+    table.appendChild(tf);
+
+    var ftr = document.createElement("tr");
+    tf.appendChild(ftr);
+
+    var ftd = document.createElement("td");
+    ftd.setAttribute("class",   "tfoot");
+    ftd.width = "100%";
+    ftd.colSpan = 3;
+    ftr.appendChild(ftd);
+
+    var ftab = document.createElement("table");
+    ftab.width = "100%";
+    ftd.appendChild(ftab);
+
+    var ftd0 = document.createElement("td");
+    var ftd1 = document.createElement("td");
+
+    ftd0.setAttribute("class", "tcell1");
+    ftd1.setAttribute("class", "tcell2");
+
+    ftab.appendChild(ftd0);
+    ftab.appendChild(ftd1);
+
+    var fdiv0 = document.createElement("span");
+    var fdiv1 = document.createElement("span");
+
+    fdiv0.setAttribute("style", "font-size:large;");
+    fdiv1.setAttribute("style", "font-size:small;");
+    fdiv1.id = "localtime"+z;
+
+    fdiv0.appendChild(document.createTextNode("logbook"));
+    fdiv1.appendChild(document.createTextNode("loading..."));
+
+    ftd0.appendChild(fdiv0);
+    ftd1.appendChild(fdiv1);
+
+    $("body").appendChild(table);
+
+    var counter = 1;
+    for (var i=1; i<lines.length; i++)
+    {
+        lines[i] = trim(lines[i]);
+
+        if (lines[i].length==0 || lines[i][0] == '#')
+            continue;
+
+        var cols = lines[i].split(':');
+        if (cols.length != 3 && cols.length !=4)
+        {
+            alert("Wrong number of columns in line #"+i+" in '"+name+"': '"+lines[i]+"' N(cols)="+cols.length);
+            continue;
+        }
+
+        var check = cols[1].split("=");
+
+        if (check.length>1 && (check[0]=="camera" || check[0]=="hist"))
+        {
+            var data = cols[1].substring(check[0].length+1).split("/");
+
+            var tr = document.createElement("tr");
+            tr.setAttribute("class", "row");
+            //tr.setAttribute("style", "margin:0;padding:0;");
+
+            var td = document.createElement("td");
+            td.setAttribute("class", "container");
+            td.id = "container";
+            td.colSpan = 3;
+            tr.appendChild(td);
+
+            var canv = document.createElement("canvas");
+            canv.id = "canvas"+z;
+            canv.width = "1";
+            canv.height = "1";
+            //canv.onclick = function() { save(); }
+            canv.setAttribute("data-type", check[0]);
+            canv.setAttribute("data-file", data[0]);
+            canv.setAttribute("data-data", cols[1].substring(check[0].length+data[0].length+2));
+//            canv.setAttribute("style", "display:none;");
+            td.appendChild(canv);
+
+            var img = document.createElement("img");
+            img.src = "dummy.png";//needed in firefox
+            img.id = "image"+z;
+            img.setAttribute("style", "width:1px;height:1px;display:none;");
+            td.appendChild(img);
+
+            tbody.appendChild(tr);
+            continue;
+        }
+
+        var tr = document.createElement("tr");
+        tr.setAttribute("class", "row");
+        if (valid(cols[0]))
+            tr.setAttribute("onclick", "this.style.background='#ccb'; loadPage('"+cols[0]+"', "+z+", -1);");
+        if (valid(cols[3]))
+            tr.setAttribute("onclick", "this.style.background='#ccb'; loadPage('"+cols[3]+"', "+z+", +1);");
+
+        var td0 = document.createElement("td");
+        td0.setAttribute("class", "tcol0");
+        if (valid(cols[0]))
+        {
+            var sp = document.createElement("div");
+            sp.setAttribute("class", "icon_black");
+            sp.setAttribute("style", "background-position: -144px 50%;");
+            td0.appendChild(sp);
+        }
+        tr.appendChild(td0);
+
+        var td1 = document.createElement("td");
+        td1.setAttribute("class", "tcol1");
+        td1.width = "100%";
+        tr.appendChild(td1);
+
+        var td2 = document.createElement("td");
+        td2.setAttribute("class", "tcol2");
+        td2.width = "18px";
+        if (valid(cols[3]))
+        {
+            var sp = document.createElement("div");
+            sp.setAttribute("class", "icon_black");
+            sp.setAttribute("style", "background-position: -108px 50%;");
+            td2.appendChild(sp);
+        }
+        tr.appendChild(td2);
+
+        var tab = document.createElement("table");
+        tab.width = "100%";
+        td1.appendChild(tab);
+
+        var innertr = document.createElement("tr");
+        tab.appendChild(innertr);
+
+        var cell1 = document.createElement("td");
+        cell1.setAttribute("class", "tcell1");
+
+        var cell2 = document.createElement("td");
+        cell2.setAttribute("class", "tcell2");
+
+        if (check.length==0 || check[0]!="input")
+        {
+            cell1.appendChild(document.createTextNode(cols[1]));
+
+            if (cols.length>2 && cols[2].length>0)
+            {
+                cell2.id = "data"+counter;
+                cell2.setAttribute("data-form",  cols[2]);
+                cell2.appendChild(document.createTextNode("---"));
+                counter++;
+            }
+            else
+                cell1.setAttribute("class", "description");
+        }
+        else
+        {
+            var opt = check[1].split('/');
+
+            if (opt.length<2)
+                alert("Argument name missing for'"+check[1]+"'");
+
+            cell1.appendChild(document.createTextNode(opt[0]));
+
+            var input = document.createElement("input");
+            input.name = opt[1];
+            input.type = "text";
+            input.maxlength = 80;
+            if (opt.length>2)
+                input.value=opt[2];
+
+            cell2.appendChild(input);
+        }
+
+        innertr.appendChild(cell1);
+        innertr.appendChild(cell2);
+
+        tbody.appendChild(tr);
+    }
+/*
+    if (true)
+    {
+        tr = document.createElement("tr");
+        tr.setAttribute("class", "row");
+
+        td = document.createElement("td");
+        td.colSpan = "3";
+        tr.appendChild(td);
+
+        var sp = document.createElement("div");
+        sp.setAttribute("class", "icon_color");
+        sp.setAttribute("style", "background-position: -144px -14px;");
+        td.appendChild(sp);
+
+        sp = document.createElement("div");
+        sp.setAttribute("class", "icon_color");
+        sp.setAttribute("style", "background-position: -56px -14px;");
+        td.appendChild(sp);
+
+        tr.appendChild(td);
+
+        tbody.appendChild(tr);
+    }
+*/
+    // ---------------------------------------
+    if (debug == true)
+    {
+        tr = document.createElement("tr");
+        tr.setAttribute("class", "row");
+
+        td = document.createElement("td");
+        td.id = "debug"+z;
+        td.colSpan = 3;
+        tr.appendChild(td);
+
+        tbody.appendChild(tr);
+    }
+
+    // ---------------------------------------
+
+    table.setAttribute("data-file", name);
+    doresize(z);
+}
+
+function resizeimpl(z, cnt)
+{
+    // 393 / 482    488/482 / 200   200+482-488
+    var img  = $("image"+z);
+    var canv = $("canvas"+z);
+    if (img == undefined || canv == undefined)
+        return;
+
+    var h = $("table"+z).offsetHeight;
+    if (h == 0)
+        return;
+
+    var W = window.innerWidth;
+    var H = window.innerHeight;
+
+/*
+    if (W==0 || H==0)
+    {
+        var w = $("table"+z).offsetWidth;
+        img.style.width = w+"px";
+        img.style.height= w+"px";
+
+        canv.width  = w;
+        canv.height = w;
+        return;
+    }
+*/
+
+    var ih = H - h + parseInt(img.style.height, 10);
+
+    img.style.width = W +"px";
+    img.style.height= ih+"px";
+
+    canv.width  = W;
+    canv.height = ih;
+
+    // ------ debug -----
+    if (debug == true)
+    {
+        $('debug'+z).innerHTML = "";
+        $('debug'+z).innerHTML += "|W="+W +"/"+H;
+        $('debug'+z).innerHTML += "|H="+h+"/"+$("table"+z).offsetHeight+"/"+img.offsetHeight;
+        $('debug'+z).innerHTML += "|I="+img.style.height+"+"+H+"-"+h;
+    }
+
+    if ($("table"+z).offsetHeight == H || cnt==2)
+    {
+        // ------ debug -----
+        if (debug == true)
+        {
+            $('debug'+z).innerHTML = "";
+            $('debug'+z).innerHTML += "|W="+W +"/"+H;
+            $('debug'+z).innerHTML += "|H="+h+"/"+$("table"+z).offsetHeight+"/"+img.offsetHeight;
+            $('debug'+z).innerHTML += "|I="+img.style.height+"+"+H+"-"+h;
+        }
+        return;
+    }
+
+    resizeimpl(z, ++cnt);
+}
+
+function doresize(z)
+{
+    resizeimpl(z, 0);
+}
+
+var intervalSlide = null;
+
+function changePage(oldz, newz)
+{
+    // No page displayed yet
+    if (oldz==newz)
+    {
+        $("table"+newz).style.left="0px";
+        $("body").setAttribute("data-visible", newz);
+
+        doresize(0);
+
+        //setInterval(refresh_text, 1000);
+        //setInterval(refresh_graphics, 5000);
+
+        refresh_text();
+        refresh_graphics();
+        return;
+    }
+
+    var W = window.innerWidth;
+    if (W==0)
+    {
+        $("table"+newz).style.left="0px";
+        $("body").setAttribute("data-visible", newz);
+        $("body").removeChild($("table"+oldz));
+        return;
+    }
+
+    if (newz>oldz)
+        $("table"+newz).style.left = W+"px";
+    else
+        $("table"+newz).style.left = (-W-1)+"px";
+
+    //window.clearTimeout(timeoutText);
+    //window.clearTimeout(timeoutGraphics);
+
+    $("body").setAttribute("data-visible", newz);
+    intervalSlide = setInterval(function(){doShift(oldz,newz)}, 75);
+}
+
+function doShift(oldz, newz)
+{
+    var t0 = $("table"+oldz);
+    var t1 = $("table"+newz);
+
+    if (t0.style.display=="none")
+    {
+        clearInterval(intervalSlide);
+        $("body").removeChild(t0);
+        return;
+    }
+
+    var x0 = t0.offsetLeft;
+    var x1 = t1.offsetLeft;
+
+    var W = window.innerWidth;
+
+    if (newz<oldz)
+    {
+        x0 += W/5;
+        x1 += W/5;
+    }
+
+    if (newz>oldz)
+    {
+        x0 -= W/5;
+        x1 -= W/5;
+    }
+
+    if ((newz<oldz && x1>=0) || (newz>oldz && x1<=0))
+    {
+        t0.style.display="none";
+        x1 = 0;
+    }
+
+    t0.style.left = x0+"px";
+    t1.style.left = x1+"px";
+}
+
+var timeoutText = null;
+var timeoutGraphics = null;
+
+function refresh_text()
+{
+    var z=$("body").getAttribute("data-visible");
+    var table = $("table"+z);
+
+    // Is sliding or no file defined?
+    var fname = table.getAttribute("data-file");
+    if (isSliding() || !valid(fname))
+    {
+        // invalidate?
+        timeoutText = setTimeout(refresh_text, 1000);
+        return;
+    }
+
+    var xmlText = new XMLHttpRequest();
+    xmlText.open('POST', fname+'.txt', true);
+    xmlText.onload = function ()
+    {
+        if (xmlText.status!=200)
+        {
+            alert("ERROR[1] - HTTP request '"+fname+".txt': "+xmlText.statusText+" ["+xmlText.status+"]");
+            timeoutText = setTimeout(refresh_text, 10000);
+            return;
+        }
+
+        if (!isSliding())
+        {
+            cycleCol($("ldot"+z));
+            update_text(fname, xmlText.responseText);
+        }
+        timeoutText = setTimeout(refresh_text, 3000);
+    };
+    xmlText.send(null);
+}
+
+function strike(e, status)
+{
+    if (!e)
+        return;
+
+    if (!status)
+        e.style.textDecoration="line-through";
+    else
+        e.style.textDecoration="";
+}
+
+/*
+function gray(id, str)
+{
+    var e = $(id);
+    if (!e)
+        return;
+
+    if (valid(str))
+    {
+        e.style.color="#000";
+        e.style.textDecoration="";
+    }
+    else
+    {
+        e.style.color="#daa";
+        e.style.textDecoration="line-through";
+    }
+}
+*/
+var date0 = null;
+
+function update_text(fname, result)
+{
+    var z=$("body").getAttribute("data-visible");
+    var table = $("table"+z);
+
+    if (table.getAttribute("data-file") != fname)
+        return;
+
+    var tokens = result.split('\n');
+
+    // ----------------------------------------------------
+
+    var  time = $("reporttime"+z);
+    var ltime = $("localtime"+z);
+
+    var date1 = new Date();
+
+    if (tokens[0].length!=13)
+    {
+        if (date0 != null)
+            strike(time, date0.getTime()+60000>date1.getTime());
+        // FIXME: Reset display to "---" values -- no connection
+        return;
+    }
+
+    var date2 = new Date();
+    date2.setTime(tokens[0]);
+
+    strike(time, date2.getTime()+60000>date1.getTime());
+
+    date0 = date2;
+
+    var utc = date0.toUTCString();
+
+    time.innerHTML =
+        "&#8226;&nbsp;"+utc.substr(utc.length-12, 8)+"&nbsp;UTC&nbsp;&#8226;"
+    ltime.innerHTML =
+        "&#8226;&nbsp;"+date1.toLocaleString()+"&nbsp;&#8226;";
+
+    // ----------------------------------------------------
+
+    var p = table.tBodies.length==3 ? 1 : 0;
+    var tbody = table.tBodies[p];
+
+    for (var line=1; line<tokens.length; line++)
+    {
+        if (tokens[line].length==0)
+            continue;
+
+        if (tbody.rows[line-1]==undefined)
+            continue;
+
+        var c = tbody.rows[line-1].cells[1];
+        if (c == undefined)
+            continue;
+
+        var e = c.childNodes[0].rows[0].cells[1];
+        if (e == undefined)
+            continue;
+
+        var form = e.getAttribute("data-form");
+        if (form==undefined)
+            continue;
+
+        var cols = tokens[line].split('\t');
+        for (var col=1; col<cols.length; col++)
+            form = form.replace("\$"+(col-1), cols[col].length==0 ? "--" : cols[col]);
+
+        if (cols.length<=1)
+            form = "---";
+
+        var newe = document.createElement("div");
+        newe.innerHTML = form;
+        e.replaceChild(newe, e.lastChild);
+
+        e.parentNode.parentNode.parentNode.parentNode.style.background=cols[0];
+    }
+}
+
+// http://billmill.org/static/canvastutorial/index.html
+// http://www.netmagazine.com/tutorials/learning-basics-html5-canvas
+// http://www.alistapart.com/articles/responsive-web-design/
+
+function refresh_graphics()
+{
+    var z = $("body").getAttribute("data-visible");
+
+    var canvas = $("canvas"+z);
+
+    // Is sliding or no data file defined?
+    var fname = canvas==null ? "" : canvas.getAttribute("data-file");
+    if (isSliding() || !valid(fname))
+    {
+        // invalidate?
+        timeoutGraphics = setTimeout(refresh_graphics, 1000);
+        return;
+    }
+
+    var xmlGfx = new XMLHttpRequest();
+    xmlGfx.open('POST', fname, true);
+    xmlGfx.onload = function()
+    {
+        if (xmlGfx.status!=200)
+        {
+            alert("ERROR[2] - Request '"+fname+"': "+xmlGfx.statusText+" ["+xmlGfx.status+"]");
+            timeoutGraphics = setTimeout(refresh_graphics, 10000);
+            //****** invalidate ******
+            return;
+        }
+
+        if (!isSliding())
+        {
+            cycleCol($("rdot"+z));
+            process_eventdata(xmlGfx.responseText);
+        }
+        timeoutGraphics = setTimeout(refresh_graphics, 5000)
+    };
+    xmlGfx.send(null);
+}
+
+
+function hueToRGB(hue)
+{
+    hue /= 3;
+    hue %= 6;
+
+    if (hue<1) return parseInt(255*hue,     10);
+    if (hue<3) return parseInt(255,         10);
+    if (hue<4) return parseInt(255*(4-hue), 10);
+
+/*
+    if (hue<1*5/4) return parseInt(255*hue*4/5);
+    if (hue<2*5/4) return parseInt(255);
+    if (hue<3*5/4) return parseInt(255*(3*5/4-hue)*4/5);
+*/
+/*
+    if (hue<1.5) return parseInt(255*hue/1.5);
+    if (hue<3.0) return parseInt(255);
+    if (hue<4.5) return parseInt(255*(4.5-hue)/1.5);
+*/
+    return 0.
+}
+
+function hueToHex(flt)
+{
+    var s = hueToRGB(flt).toString(16);
+    return s.length==2 ? s : "0"+s;
+}
+
+function HLStoRGB(hue)
+{
+    hue *= 14;
+
+    var sr = hueToHex(20-hue);
+    var sg = hueToHex(14-hue);
+    var sb = hueToHex(26-hue);
+
+    return sr+sg+sb;
+}
+
+
+function color(col)
+{
+    if (col==65533)
+        col = 0;
+
+    var hue = col/128;
+    return HLStoRGB(hue);
+}
+
+function toHex(str, idx)
+{
+    var ch = str[idx].toString(16);
+    return ch.length==2 ? ch : "0"+ch;
+}
+
+function drawHex(ctx, x, y, col)
+{
+    ctx.fillStyle = "#"+color(col);
+
+    ctx.save();
+
+    ctx.translate(x, y);
+    ctx.scale(1/2, 1/3);
+
+    ctx.beginPath();
+    ctx.moveTo( 1,  1);
+    ctx.lineTo( 0,  2);
+    ctx.lineTo(-1,  1);
+    ctx.lineTo(-1, -1);
+    ctx.lineTo( 0, -2);
+    ctx.lineTo( 1, -1);
+    ctx.fill();
+
+    ctx.restore();
+}
+
+function drawDisc(ctx, x, y, r, col)
+{
+    ctx.fillStyle = "#"+color(col);
+
+    ctx.save();
+
+    ctx.translate(x, y);
+
+    ctx.beginPath();
+    ctx.arc(0, 0, r, 0, Math.PI*2, true);
+    ctx.fill();
+
+    ctx.restore();
+}
+
+function beginDrawCam(scale)
+{
+    var z    = $("body").getAttribute("data-visible");
+    var canv = $("canvas"+z);
+
+    var w = Math.min(canv.width/scale, canv.height/scale);
+
+    var ctx = canv.getContext("2d");
+
+    ctx.save();
+    ctx.translate(canv.width/2, canv.height/2);
+    ctx.scale(w*2, w*2);
+
+    return ctx;
+}
+
+/**
+ * @constructor
+ */
+function position(s, ring, i)
+{
+    switch (s)
+    {
+    case 1: this.x =  ring     - i*0.5;  this.y =       + i; break;
+    case 2: this.x =  ring*0.5 - i;      this.y =  ring    ; break;
+    case 3: this.x = -ring*0.5 - i*0.5;  this.y =  ring - i; break;
+    case 4: this.x = -ring     + i*0.5;  this.y =       - i; break;
+    case 5: this.x = -ring*0.5 + i;      this.y = -ring    ; break;
+    case 0: this.x =  ring*0.5 + i*0.5;  this.y = -ring + i; break;
+    }
+    this.d = function() { return this.x*this.x + this.y*this.y*3/4; }
+}
+
+function drawFullCam(data)
+{
+    if (data.length!=40 && data.length!=160 && data.length!=320 && data.length!=1440)
+    {
+        alert("Camera - Received data has invalid size ("+data.length+"b)");
+        return;
+    }
+
+    var div = map.length/data.length;
+    var off = data.length==320 ? 0.2 : 0;
+
+    var ctx = beginDrawCam(83);
+    // ctx.rotate(Math.PI/3);
+
+    ctx.scale(1, Math.sqrt(3)/2);
+    ctx.translate(-0.5, 0);
+
+    drawHex(ctx, 0, 0, data.charCodeAt(parseInt(map[0]/div+off, 10)));
+
+    var cnt = 1;
+    for (var ring=1; ring<24; ring++)
+    {
+        for (var s=0; s<6; s++)
+        {
+            for (var i=1; i<=ring; i++)
+            {
+                var pos = new position(s, ring, i);
+                if (pos.d() - pos.x > 395.75)
+                    continue;
+
+                var p = parseInt(map[cnt]/div+off, 10);
+
+                drawHex(ctx, pos.x, pos.y, data.charCodeAt(p));
+                cnt++;
+            }
+        }
+    }
+
+    drawHex(ctx, 7, -22, data.charCodeAt(parseInt(map[1438]/div+off, 10)));
+    drawHex(ctx, 7,  22, data.charCodeAt(parseInt(map[1439]/div+off, 10)));
+
+    ctx.restore();
+}
+
+function drawCam(data)
+{
+    var ctx = beginDrawCam(27);
+    ctx.rotate(Math.PI/6);
+    ctx.scale(1, Math.sqrt(3)/2);
+
+    drawHex(ctx, 0, 0, data.charCodeAt(0));
+
+    var cnt = 1;
+    for (var ring=1; ring<=7; ring++)
+    {
+        for (var s=0; s<6; s++)
+        {
+            for (var i=1; i<=ring; i++)
+            {
+                var pos = new position(s, ring, i);
+                if (pos.d() > 44)
+                    continue;
+
+                if (ring==7)
+                {
+                    if (i==6 && (s==0 || s==3))
+                        continue;
+                    if (i==1 && (s==1 || s==4))
+                        continue;
+                }
+
+                drawHex(ctx, pos.x, pos.y, data.charCodeAt(cnt++));
+            }
+        }
+    }
+
+    ctx.restore();
+}
+
+function drawCamLegend(canv, min, max)
+{
+    var unit = canv.getAttribute("data-data");//.split("/");
+    if (unit.length>0)
+        unit = " "+unit;
+
+    var v0 = parseFloat(min);
+    var v1 = parseFloat(max);
+
+    var diff = v1-v0;
+
+    var cw = canv.width;
+    var ch = canv.height;
+
+    var ctx = canv.getContext("2d");
+
+    ctx.font         = "8pt Arial";
+    ctx.textAlign    = "right";
+    ctx.textBaseline = "top";
+
+    for (var i=0; i<11; i++)
+    {
+        ctx.strokeStyle = "#"+color(16*i);
+        ctx.strokeText((v0+diff*i/10).toPrecision(3)+unit, cw-5, 120-i*12);
+    }
+}
+
+function drawGraph(canv, min, max, data)
+{
+    var unit = canv.getAttribute("data-data");//.split("/");
+    if (unit.length>0)
+        unit = " "+unit;
+
+    var cw = canv.width;
+    var ch = canv.height;
+
+    var ctx = canv.getContext("2d");
+
+    var dw = 3;  // tick width
+
+    var fs = 8;  // font size
+
+    ctx.font      = fs+"pt Arial";
+    ctx.textAlign = "right";
+
+    var dim0 = ctx.measureText(min+unit);
+    var dim1 = ctx.measureText(max+unit);
+
+    var tw = Math.max(dim0.width, dim1.width)+dw+2;
+
+    var ml = 5+tw; // margin left
+    var mr = 10;   // margin right
+
+    var mt = fs/2+5; // margin top
+    var mb = fs/2+4; // margin bottom
+
+    var nx = 20;
+    var ny = 10;
+
+    var w = cw-ml-mr;
+    var h = ch-mt-mb;
+
+    ctx.strokeStyle = "#666";
+
+    // --- data ---
+    ctx.beginPath();
+    ctx.moveTo(ml, ch-mb-data.charCodeAt(0)/128*h);
+    for (var i=1; i<data.length; i++)
+        ctx.lineTo(ml+w/(data.length-1)*i, ch-mb-data.charCodeAt(i)/128*h);
+
+    // --- finalize data ---
+    ctx.lineTo(cw-mr, ch-mb);
+    ctx.lineTo(ml,    ch-mb);
+    ctx.fillStyle = "#"+color(100);
+    ctx.stroke();
+    ctx.fill();
+
+    ctx.beginPath();
+
+    // --- grid ---
+
+    ctx.strokeStyle = "#eee";
+
+    for (var i=1; i<=nx; i++)
+    {
+        ctx.moveTo(ml+w/nx*i, ch-mb);
+        ctx.lineTo(ml+w/nx*i,    mt);
+    }
+    for (var i=0; i<ny; i++)
+    {
+        ctx.moveTo(ml,   mb+h/ny*i);
+        ctx.lineTo(ml+w, mb+h/ny*i);
+    }
+    ctx.stroke();
+    ctx.closePath();
+    ctx.beginPath();
+
+    ctx.strokeStyle = "#000";
+
+    // --- axes ---
+    ctx.moveTo(ml,    mt);
+    ctx.lineTo(ml,    ch-mb);
+    ctx.lineTo(cw-mr, ch-mb);
+
+    for (var i=1; i<=nx; i++)
+    {
+        ctx.moveTo(ml+w/nx*i, ch-mb-dw);
+        ctx.lineTo(ml+w/nx*i, ch-mb+dw);
+    }
+    for (var i=0; i<ny; i++)
+    {
+        ctx.moveTo(ml-dw, mb+h/ny*i);
+        ctx.lineTo(ml+dw, mb+h/ny*i);
+    }
+    ctx.stroke();
+    ctx.closePath();
+
+    ctx.textBaseline = "bottom";
+    ctx.strokeText(min+unit, ml-dw-2, ch-1);
+
+    ctx.textBaseline = "top";
+    ctx.strokeText(max+unit, ml-dw-2, 0);
+}
+
+var gfxtime0 = null;
+
+function process_eventdata(result)
+{
+    if (result.length==0)
+        return;
+
+    var z = $("body").getAttribute("data-visible");
+    var canv = $("canvas"+z);
+    if (canv == undefined)
+        return;
+
+    var type = canv.getAttribute("data-type");
+
+    var ctx = canv.getContext("2d");
+    ctx.clearRect(0, 0, canv.width, canv.height);
+
+    var data = result.split('\n');
+    if (result.length<3)
+        return;
+
+    var l = data[0].length+1+data[1].length+1;
+
+    switch (type)
+    {
+        //case "camera": drawCam(result);     break;
+    case "hist":
+        drawGraph(canv, data[0], data[1], result.substr(l));
+        break;
+    case "camera":
+        drawFullCam(result.substr(l));
+        drawCamLegend(canv, data[0], data[1]);
+        break;
+    }
+
+    var date = new Date();
+    if (gfxtime0 != null && gfxdate0.getTime()+60000>date.getTime())
+    {
+        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
+        ctx.fillRect(0, 0, canv.width, canv.height);
+    }
+
+    //$("image"+z).src = canv.toDataURL("image/png");
+}
+
+function save()
+{
+    var z = $("body").getAttribute("data-visible");
+
+    var canvas = $("canvas"+z);
+    var img    = canvas.toDataURL("image/png");
+
+    img = img.replace("image/png", "image/octet-stream");
+
+    document.location.href = img;
+}
+
+window['onload'] = onload;
Index: /trunk/FACT++/www/smartfact/index.php
===================================================================
--- /trunk/FACT++/www/smartfact/index.php	(revision 13686)
+++ /trunk/FACT++/www/smartfact/index.php	(revision 13686)
@@ -0,0 +1,134 @@
+<?PHP
+
+require_once("config.php");
+
+function login()
+{
+    global $ldaphost;
+    global $baseDN;
+    global $groupDN;
+
+    $username = $_SERVER['PHP_AUTH_USER'];
+    $password = $_SERVER['PHP_AUTH_PW'];
+
+    $con = @ldap_connect($ldaphost);
+    if (!$con)
+        return "ldap_connect failed to ".$ldaphost;
+
+    //------------------ Look for user common name
+    $attributes = array('cn', 'mail');
+    $dn         = 'ou=People,'.$baseDN;
+    $filter     = '(uid='.$username.')';
+
+    $sr = @ldap_search($con, $dn, $filter, $attributes);
+    if (!$sr)
+        return "ldap_search failed for dn=".$dn.": ".ldap_error($con);
+
+    $srData = @ldap_get_entries($con, $sr);
+    if ($srData["count"]==0)
+        return "No results returned by ldap_get_entries for dn=".$dn.".";
+
+    $email         =$srData[0]['mail'][0];
+    $userCommonName=$srData[0]['cn'][0];
+    $userDN        =$srData[0]['dn'];
+
+    //------------------ Authenticate user
+    if (!@ldap_bind($con, $userDN, $password))
+        return "ldap_bind failed: ".ldap_error($con);
+
+    //------------------ Check if the user is in FACT ldap group
+    $attributes= array("member");
+    $filter= '(objectClass=*)';
+
+    // Get all members of the group.
+    $sr = @ldap_read($con, $groupDN, $filter, $attributes);
+    if (!$sr)
+        return "ldap_read failed for dn=".$groupDN.": ".ldap_error($con);
+
+    // retrieve the corresponding data
+    $srData = @ldap_get_entries($con, $sr);
+    if ($srData["count"]==0)
+        return "No results returned by ldap_get_entries for dn=".$dn.".";
+
+    @ldap_unbind($con);
+
+    $found = false;
+    foreach ($srData[0]['member'] as $member)
+        if (strpos($member, "cn=".$userCommonName.",")===0)
+            return "";
+
+    return "Sorry, your credentials don't match!";
+}
+// --------------------------------------------------------------------
+
+if (isset($_GET['logout']))
+{
+    if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']))
+        return;
+
+    return header('HTTP/1.0 401 Successfull logout!');
+}
+
+// --------------------------------------------------------------------
+
+if (!isset($_GET['start']) && !isset($_GET['stop']))
+    return header('HTTP/1.0 400 Command not supported');
+
+// --------------------------------------------------------------------
+
+if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']))
+{
+    header('WWW-Authenticate: Basic realm="SmartFACT++"');
+    header('HTTP/1.0 401 Unauthorized');
+    return;
+}
+
+$rc = login();
+if ($rc!="")
+    return header('HTTP/1.0 401 '.$rc);
+
+// --------------------------------------------------------------------
+
+$out = array();
+
+if (isset($_GET['stop']))
+    $str = exec($path."/dimctrl --stop", $out, $rc);
+
+if (isset($_GET['start']))
+{
+    $args = '\"'.$_GET['start'].'\"';
+
+    unset($_GET['start']);
+
+    /*
+     $args = "";
+     foreach ($_GET as $key => $value)
+        $args .= " --arg:".$key."=".$value;
+     $str = exec($path."/dimctrl --exec ".$args, $out, $rc);
+     */
+
+    if (isset($_GET['label']))
+    {
+        if ($_GET['label']>=0)
+            $args .= ":".$_GET['label'];
+        unset($_GET['label']);
+    }
+
+    foreach ($_GET as $key => $value)
+        $args .= ' \"'.$key.'='.$value.'\"';
+
+    $str = exec($path.'/dimctrl --start "'.$args.'"', $out, $rc);
+}
+
+if ($rc!=1 && $rc!=2)
+    return header('HTTP/1.0 500 Execution failed [rc='.$rc."]");
+
+print($rc);
+
+if (isset($_GET['debug']))
+{
+    print("\n");
+    print_r($out);
+}
+
+?>
