Imported Upstream version 1.8.8
[platform/upstream/doxygen.git] / src / htmlgen.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  * Copyright (C) 1997-2014 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby 
9  * granted. No representations are made about the suitability of this software 
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include <stdlib.h>
19
20 #include <qdir.h>
21 #include <qregexp.h>
22 #include "message.h"
23 #include "htmlgen.h"
24 #include "config.h"
25 #include "util.h"
26 #include "doxygen.h"
27 #include "logos.h"
28 #include "diagram.h"
29 #include "version.h"
30 #include "dot.h"
31 #include "language.h"
32 #include "htmlhelp.h"
33 #include "docparser.h"
34 #include "htmldocvisitor.h"
35 #include "searchindex.h"
36 #include "pagedef.h"
37 #include "debug.h"
38 #include "dirdef.h"
39 #include "vhdldocgen.h"
40 #include "layout.h"
41 #include "image.h"
42 #include "ftvhelp.h"
43 #include "bufstr.h"
44
45
46 //#define DBG_HTML(x) x;
47 #define DBG_HTML(x) 
48
49 static const char defaultHtmlHeader[] =
50 #include "header.html.h"
51 ;
52
53 static const char defaultHtmlFooter[] =
54 #include "footer.html.h"
55 ;
56
57 static const char defaultStyleSheet[] = 
58 #include "doxygen.css.h"
59 ;
60
61 static const char search_functions_script[]=
62 #include "search_functions.php.h"
63 ;
64
65 static const char search_opensearch_script[]=
66 #include "search_opensearch.php.h"
67 ;
68
69 static const char search_styleSheet[] =
70 #include "search.css.h"
71 ;
72
73 static const char search_jquery_script1[]=
74 #include "jquery_p1.js.h"
75 ;
76
77 static const char search_jquery_script2[]=
78 #include "jquery_p2.js.h"
79 ;
80
81 static const char search_jquery_script3[]=
82 #include "jquery_p3.js.h"
83 ;
84
85 static const char search_jquery_script4[]=
86 #include "jquery_ui.js.h"
87 ;
88
89 static const char search_jquery_script5[]=
90 #include "jquery_fx.js.h"
91 ;
92
93 static const char search_jquery_script6[]=
94 #include "jquery_pt.js.h"
95 ;
96
97 static const char svgpan_script[]=
98 #include "svgpan.js.h"
99 ;
100
101 static const char dynsections_script[]=
102 #include "dynsections.js.h"
103 ;
104
105 static const char extsearch_script[]=
106 #include "extsearch.js.h"
107 ;
108
109 static QCString g_header;
110 static QCString g_footer;
111 static QCString g_mathjax_code;
112
113 //------------------------- Pictures for the Tabs ------------------------
114
115 // active tab background luma
116 static unsigned char tab_a_png[36] =
117 {
118    31,  42,  59,  69,  73,  74,  75,  77,  77,
119    77,  79,  80,  80,  82,  81,  83,  84,  86,
120    87,  88,  89,  90,  91,  91,  93,  94,  94,
121    96,  96,  97,  98,  98,  99,  99,  99, 100
122 };
123
124 // normal tab background luma
125 static unsigned char tab_b_png[36] =
126 {
127     218, 228, 235, 233, 230, 227, 225, 222, 221,
128     218, 217, 215, 214, 213, 212, 211, 210, 209,
129     209, 197, 198, 199, 200, 201, 202, 203, 204,
130     205, 207, 209, 211, 213, 217, 219, 206, 188 
131 };
132
133 // hovering tab background luma
134 static unsigned char tab_h_png[36] =
135 {
136     181, 191, 198, 196, 193, 190, 188, 185, 184,
137     181, 180, 178, 177, 176, 175, 174, 173, 172,
138     172, 154, 155, 156, 157, 158, 159, 160, 161,
139     162, 164, 166, 168, 170, 174, 176, 163, 145
140 };
141
142 // shadowed header
143 static unsigned char header_png[12] = 
144 {
145   255, 240, 241, 242, 243, 244, 
146   245, 246, 247, 248, 249, 250
147 };
148
149 // function header
150 static unsigned char func_header_png[56] =
151 {
152   248, 247, 246, 245, 244, 243, 242, 241,
153   240, 239, 238, 237, 236, 235, 234, 233,
154   232, 231, 230, 229, 228, 223, 223, 223,
155   223, 223, 223, 223, 223, 223, 223, 223,
156   224, 224, 224, 224, 225, 225, 225, 225,
157   225, 226, 226, 226, 227, 227, 227, 227,
158   228, 228, 228, 229, 229, 229, 229, 229
159 };
160
161 // tab separator
162 static unsigned char tab_s_png[36] =
163 {
164   187, 186, 185, 183, 182, 181, 180, 178, 176,
165   174, 173, 171, 169, 167, 164, 163, 161, 158,
166   156, 154, 152, 150, 148, 145, 143, 141, 140,
167   138, 136, 134, 131, 131, 128, 126, 125, 124
168 };
169
170 // breadcrumbs luma
171 static unsigned char bc_s_png[240] =
172 {
173   150,187,187,148,148,148,148,148,
174   147,175,186,147,147,147,147,147,
175   146,153,185,185,146,146,146,146,
176   144,144,177,183,144,144,144,144,
177   144,144,159,182,144,144,144,144,
178   143,143,144,179,181,143,143,143,
179   142,142,142,165,180,142,142,142,
180   141,141,141,144,178,178,141,141,
181   139,139,139,139,167,176,139,139,
182   137,137,137,137,146,174,137,137,
183   137,137,137,137,137,169,173,137,
184   135,135,135,135,135,150,171,135,
185   133,133,133,133,133,135,167,169,
186   132,132,132,132,132,132,154,167,
187   129,129,129,129,129,129,140,164,
188   129,129,129,129,129,129,154,163,
189   127,127,127,127,127,128,161,161,
190   125,125,125,125,125,141,158,125,
191   123,123,123,123,123,152,156,123,
192   121,121,121,121,129,154,121,121,
193   120,120,120,120,143,152,120,120,
194   118,118,118,120,150,150,118,118,
195   117,117,117,132,148,117,117,117,
196   114,114,114,142,145,114,114,114,
197   113,113,120,143,113,113,113,113,
198   111,111,133,141,111,111,111,111,
199   110,112,140,140,110,110,110,110,
200   109,124,138,109,109,109,109,109,
201   107,133,136,107,107,107,107,107,
202   111,134,106,106,106,106,106,106
203 };
204
205 // breadcrumbs alpha map
206 static unsigned char bc_s_a_png[240] =
207 {
208   241,241, 21,  0,  0,  0,  0,  0,
209   162,205,117,  0,  0,  0,  0,  0,
210    54,231,225,  3,  0,  0,  0,  0,
211     0,198,215, 78,  0,  0,  0,  0,
212     0, 93,211,186,  0,  0,  0,  0,
213     0,  6,232,235, 42,  0,  0,  0,
214     0,  0,132,203,147,  0,  0,  0,
215     0,  0, 27,242,241, 15,  0,  0,
216     0,  0,  0,168,205,108,  0,  0,
217     0,  0,  0, 63,228,219,  0,  0,
218     0,  0,  0,  0,207,221, 72,  0,
219     0,  0,  0,  0,102,208,177,  0,
220     0,  0,  0,  0,  9,238,240, 36,
221     0,  0,  0,  0,  0,138,201,138,
222     0,  0,  0,  0,  0, 77,187,158,
223     0,  0,  0,  0,  0,159,204,120,
224     0,  0,  0,  0, 15,241,241, 21,
225     0,  0,  0,  0,111,208,171,  0,
226     0,  0,  0,  0,210,222, 66,  0,
227     0,  0,  0, 60,227,219,  0,  0,
228     0,  0,  0,162,204,114,  0,  0,
229     0,  0, 18,238,238, 21,  0,  0,
230     0,  0,114,205,165,  0,  0,  0,
231     0,  0,216,225, 60,  0,  0,  0,
232     0, 66,226,216,  0,  0,  0,  0,
233     0,165,204,111,  0,  0,  0,  0,
234    21,241,241, 18,  0,  0,  0,  0,
235   117,203,159,  0,  0,  0,  0,  0,
236   219,227, 57,  0,  0,  0,  0,  0,
237   211,201,  0,  0,  0,  0,  0,  0
238 };
239
240 // doxygen logo luma
241 static unsigned char doxygen_png[3224] =
242 {
243   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
244   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
245    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255,255,255,255,255,
246    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 91, 91, 91, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
247    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
248    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,253,253,253,253, 32, 32,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255,
249    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,251,251,251,251, 32, 32,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,255,255,255,255,255,255,255,255,
250    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249,249, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249, 32, 32, 32, 32, 32,249, 32, 32, 32, 32, 32,255,255,255,
251    32, 32, 32, 32, 46,132,190,190,147, 61,247,247,247,247, 32, 32,247,247, 32, 32,118,161,190,190,161,118, 32, 32,247, 32, 46, 89, 89, 89, 89, 46, 32,247,247, 32, 89, 89, 89, 89, 61, 89, 89, 89, 89, 46, 32,247, 32, 46, 89, 89, 89, 89, 32,247, 32, 32,118,175,190,161, 89, 61, 89, 89, 89, 61, 32,247,247,247, 32, 32,104,147,190,190,190,132, 89, 32, 32,247,247, 32, 46, 89, 89, 89, 75, 32, 89,161,190,161, 75, 32,255,255,
252    32, 32, 32, 74,230,244,244,244,244,244,244,244,244,244, 32, 32,244, 32, 74,216,244,244,244,244,244,244,216, 74, 32,244, 32,187,244,244,244,159, 32,244, 32,117,244,244,244,230, 46,173,244,244,244,131, 32,244, 32,131,244,244,244,173, 32, 32, 46,173,244,244,244,244,244,230,244,244,244,131, 32,244,244, 32, 74,202,244,244,244,244,244,244,244,173, 46, 32,244, 32, 89,244,244,244,187,145,244,244,244,244,244, 89, 32,255,
253    32, 32, 46,213,241,241,241,241,241,241,241,241,241,241, 32, 32, 32, 60,227,241,241,241,241,241,241,241,241,227, 60, 32, 32, 46,227,241,241,241,102, 32, 60,227,241,241,241, 88, 32,116,241,241,241,199, 32,241, 32,185,241,241,241,116, 32, 32,143,241,241,241,241,241,241,241,241,241,241,130, 32,241, 32, 74,227,241,241,241,199,185,241,241,241,241,171, 32,241, 32, 88,241,241,241,241,241,241,241,241,241,241,199, 32,255,
254    32, 32,128,237,237,237,223,128, 87,128,237,237,237,237, 32, 32, 32,182,237,237,237,196,100,100,196,237,237,237,182, 32,237, 32,100,237,237,237,223, 59,196,237,237,237,141, 32, 32, 46,237,237,237,237, 59, 32, 46,237,237,237,237, 46, 32, 59,237,237,237,237,169, 87, 87,182,237,237,237,128, 32,237, 32,196,237,237,237, 87, 32, 32, 73,223,237,237,237, 73, 32, 32, 87,237,237,237,237,223,182,223,237,237,237,237, 46, 32,
255    32, 32,207,234,234,234,113, 32, 32, 32,234,234,234,234, 32, 32, 59,234,234,234,221, 45, 32, 32, 45,221,234,234,234, 59, 32,234, 32,140,234,234,234,221,234,234,234,194, 32, 32,234, 32,167,234,234,234,126, 32, 99,234,234,234,167, 32, 32,126,234,234,234,180, 32, 32, 32,126,234,234,234,126, 32, 32, 99,234,234,234,167, 32, 32, 32, 32,153,234,234,234,126, 32, 32, 86,234,234,234,207, 45, 32, 45,234,234,234,234, 86, 32,
256    32, 45,231,231,231,218, 32, 32, 32, 32,231,231,231,231, 32, 32, 98,231,231,231,165, 32,231,231, 32,165,231,231,231, 98, 32,231, 32, 45,191,231,231,231,231,231,218, 72, 32,231,231, 32, 98,231,231,231,165, 32,151,231,231,231,112, 32, 32,165,231,231,231,112, 32,231, 32,125,231,231,231,125, 32, 32,138,231,231,231,178,125,125,125,125,178,231,231,231,178, 32, 32, 85,231,231,231,178, 32,255, 32,191,231,231,231, 85, 32,
257    32, 84,227,227,227,175, 32, 32, 32, 32,227,227,227,227, 32, 32,123,227,227,227,123, 32,227,227, 32,123,227,227,227,123, 32,227,227, 32, 71,227,227,227,227,227,123, 32,227,227,227,227, 32,214,227,227,227, 45,201,227,227,227, 45, 32, 32,175,227,227,227, 84, 32,227, 32,123,227,227,227,123, 32, 32,175,227,227,227,227,227,227,227,227,227,227,227,227,175, 32, 32, 84,227,227,227,175, 32,255, 32,175,227,227,227, 84, 32,
258    32, 83,223,223,223,172, 32, 32, 32, 32,223,223,223,223, 32, 32,121,223,223,223,121, 32,223,223, 32,121,223,223,223,121, 32,223,223,223, 32,172,223,223,223,210, 45, 32,223,223,223,223, 32,147,223,223,223,134,223,223,223,147, 32,223, 32,172,223,223,223, 83, 32,223, 32,121,223,223,223,121, 32, 32,172,223,223,223,223,223,223,223,223,223,223,223,223,172, 32, 32, 83,223,223,223,172, 32,255, 32,172,223,223,223, 83, 32,
259    32, 82,220,220,220,170, 32, 32, 32, 32,220,220,220,220, 32, 32,120,220,220,220,120, 32,220,220, 32,120,220,220,220,120, 32,220,220, 32, 95,220,220,220,220,220,132, 32,220,220,220,220, 32, 95,220,220,220,207,220,220,220, 95, 32,220, 32,170,220,220,220,107, 32,220, 32,120,220,220,220,120, 32, 32,170,220,220,220,132, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 82,220,220,220,170, 32,255, 32,170,220,220,220, 82, 32,
260    32, 57,216,216,216,216, 32, 32, 32, 32,216,216,216,216, 32, 32, 81,216,216,216,167, 32,216,216, 32,155,216,216,216, 81, 32,216, 32, 57,204,216,216,216,216,216,216, 93, 32,216,216,216,216, 32,204,216,216,216,216,216,204, 32,216,216, 32,118,216,216,216,167, 32, 32, 32,130,216,216,216,118, 32, 32,118,216,216,216,191, 32, 32,216,216,216, 32, 32, 44, 57, 32, 32, 81,216,216,216,167, 32,255, 32,167,216,216,216, 81, 32,
261    32, 32,189,213,213,213,116, 32, 32, 80,213,213,213,213, 32, 32, 44,201,213,213,213, 68, 32, 32, 68,213,213,213,213, 44, 32, 32, 32,165,213,213,213,165,213,213,213,201, 44, 32,213,213,213, 32,129,213,213,213,213,213,141, 32,213,213, 32, 80,213,213,213,213,165,116,153,213,213,213,213,116, 32, 32, 56,213,213,213,213,153, 56, 32, 32, 32, 44,104,189,116, 32, 32, 80,213,213,213,165, 32,255, 32,165,213,213,213, 80, 32,
262    32, 32,139,210,210,210,210,174,174,210,210,210,210,210, 32, 32, 32,127,210,210,210,198,127,127,198,210,210,210,127, 32,210, 32,115,210,210,210,174, 44,139,210,210,210,163, 32, 32,210,210, 32, 68,210,210,210,210,210, 91, 32,210,210,210, 32,174,210,210,210,210,210,210,210,210,210,210,115, 32,210, 32,127,210,210,210,210,210,174,163,163,210,210,210,115, 32, 32, 79,210,210,210,163, 32,255, 32,163,210,210,210, 79, 32,
263    32, 32, 55,194,206,206,206,206,206,194,206,206,206,206, 32, 32, 32, 44,171,206,206,206,206,206,206,206,206,171, 44, 32, 32, 67,206,206,206,206, 67, 32, 44,183,206,206,206,113, 32,206,206,206, 32,183,206,206,206,194, 32,206,206,206,206, 32, 67,194,206,206,206,206,206,171,206,206,206,113, 32,206, 32, 32,136,206,206,206,206,206,206,206,206,206,206,113, 32, 32, 78,206,206,206,160, 32,255, 32,160,206,206,206, 78, 32,
264    32, 32, 32,100,192,203,203,203,157, 55,203,203,203,203, 32, 32,203, 32, 43,135,203,203,203,203,203,203,135, 43, 32, 32, 43,180,203,203,203,112, 32,203, 32, 66,203,203,203,203, 66, 32,203,203, 32,157,203,203,203,135, 32,203,203,203,203,203, 32, 43,112,157,157,123, 55,112,203,203,203,112, 32,203,203, 32, 32, 78,146,203,203,203,203,203,203,169,123, 55, 32, 32, 78,203,203,203,157, 32,255, 32,157,203,203,203, 78, 32,
265    32, 32, 32, 32, 54,110,110, 88, 32, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 54, 99,110,110, 99, 54, 32, 32,200,200, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,200,200, 32, 54,200,200,200,200, 77, 32,200,200,200,200,200, 32, 32, 32, 32, 32, 32, 32,166,200,200,200, 88, 32,200,200,200,200, 32, 32, 32, 66, 77, 77, 77, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,255, 32, 32, 32, 32, 32, 32,255,
266    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,198,198,198,198, 32, 32, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, 32,109,198,198,198,176, 32,198,198,198,198,198, 32, 98,121, 76, 32, 32, 54,109,198,198,198,198, 43, 32,198,198,198,198,198,198,198, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,255,255,255,255,255,255,255,255,
267    32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 33,159,191,191,191,117, 36, 41, 41, 41, 41, 41, 34,108,191,191,191,191,191,191,191,191,191,117, 36, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
268    32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 78, 38, 64,190,192,192,192, 66, 66, 41, 41, 85,128, 65, 34,107,190,192,192,192,192,192,192,192,139, 48, 39, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
269    32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 96, 36, 95,147,148,148,139, 55, 41, 41, 85,121,128, 91, 38, 75,137,158,190,190,190,170,139, 97, 49, 37, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
270    32, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41, 36, 45, 45, 45, 48, 38, 41, 41, 76, 76, 76, 76, 76, 37, 34, 42, 33, 33, 33, 39, 48, 59, 41, 41, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41,255,
271    32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
272   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
273   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
274 };
275
276 // doxygen logo alpha map
277 static unsigned char doxygen_a_png[3224] =
278 {
279     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
280     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
281     0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 66, 66, 66, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
282     0,  0,  0,  0,  0,  0,  0,  0,  0,145,247,247,247,247,145,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
283     0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
284     0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
285     0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
286     0,  0,  0,  0, 16,115,181,181,132,247,247,247,247,247,247,  0,  0,  0,  0,  0, 99,148,181,181,148, 99,  0,  0,  0,  0, 16, 66, 66, 66, 66, 16,  0,  0,  0,  0, 66, 66, 66, 66, 33, 66, 66, 66, 66, 16,  0,  0,  0, 16, 66, 66, 66, 66,  0,  0,  0,  0, 99,165,181,148, 66, 33, 66, 66, 66, 33,  0,  0,  0,  0,  0,  0, 82,132,181,181,181,115, 66,  0,  0,  0,  0,  0, 16, 66, 66, 66, 49,  0, 66,148,181,148, 49,  0,  0,  0,
287     0,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247,  0,  0,  0,112,214,247,247,247,247,247,247,214,112,  0, 16,247,247,247,247,247,247, 46,  0,  0,145,247,247,247,247,247,247,247,247,247,247, 16,  0, 16,247,247,247,247,247, 66,  0, 63,165,247,247,247,247,247,247,247,247,247,247, 33,  0,  0,  0, 96,198,247,247,247,247,247,247,247,165, 63,  0,  0, 16,247,247,247,247,247,145,247,247,247,247,247,145,  0,  0,
288     0,  0,112,247,247,247,247,247,247,247,247,247,247,247,247,  0,  0,129,247,247,247,247,247,247,247,247,247,247,129,  0,181,247,247,247,247,247,148,  0,129,247,247,247,247,247,247,247,247,247,247,247,115,  0,115,247,247,247,247,247,165, 30,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247, 63,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247, 96,  0,
289     0, 16,247,247,247,247,247,247,247,247,247,247,247,247,247,  0, 79,247,247,247,247,247,247,247,247,247,247,247,247, 79, 79,247,247,247,247,247,247,129,247,247,247,247,247,247,129,247,247,247,247,247,198,  0,181,247,247,247,247,247, 99,145,247,247,247,247,247,247,247,247,247,247,247,247,115,  0, 96,247,247,247,247,247,247,247,247,247,247,247,247,165,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247,198,  0,
290     0,115,247,247,247,247,247,247,247,247,247,247,247,247,247,  0,181,247,247,247,247,247,247,247,247,247,247,247,247,181,  0,129,247,247,247,247,247,247,247,247,247,247,247,145, 16,247,247,247,247,247,247, 33,247,247,247,247,247,247, 33,247,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,198,247,247,247,247,247,198,181,247,247,247,247,247,247, 49, 66,247,247,247,247,247,247,247,247,247,247,247,247,247, 16,
291     0,214,247,247,247,247,247,129, 66,247,247,247,247,247,247, 33,247,247,247,247,247,247, 96, 96,247,247,247,247,247,247, 33,  0,145,247,247,247,247,247,247,247,247,247,198, 30,  0,165,247,247,247,247,247,115,247,247,247,247,247,165,115,247,247,247,247,247,181, 66,115,247,247,247,247,247,115, 82,247,247,247,247,247,165,115,115,148,247,247,247,247,247,115, 66,247,247,247,247,247,247,181,247,247,247,247,247,247, 66,
292    16,247,247,247,247,247,231,  0,  0,247,247,247,247,247,247, 82,247,247,247,247,247,165,  0,  0,165,247,247,247,247,247, 82,  0, 30,247,247,247,247,247,247,247,247,247, 96,  0,  0, 82,247,247,247,247,247,165,247,247,247,247,247, 99,165,247,247,247,247,247, 99,  0,115,247,247,247,247,247,115,132,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,198,247,247,247,247,247, 66,
293    66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0, 96,247,247,247,247,247,247,247,129,  0,  0,  0,  0,231,247,247,247,247,247,247,247,247,247,247, 16,181,247,247,247,247,247, 66,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
294    66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0,  0,181,247,247,247,247,247,247, 30,  0,  0,  0,  0,148,247,247,247,247,247,247,247,247,247,148,  0,181,247,247,247,247,247, 66,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
295    66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0,129,247,247,247,247,247,247,247,145,  0,  0,  0,  0, 82,247,247,247,247,247,247,247,247,247, 82,  0,181,247,247,247,247,247, 99,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 79, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
296    33,247,247,247,247,247,247, 14,  0,247,247,247,247,247,247, 66,247,247,247,247,247,181,  0,  0,165,247,247,247,247,247, 66,  0, 79,247,247,247,247,247,247,247,247,247,129,  0,  0,  0,  0,231,247,247,247,247,247,247,247,231,  0,  0,115,247,247,247,247,247,181,115,165,247,247,247,247,247,115,115,247,247,247,247,247,214, 63,  0,  0,  0, 16,112,247,247, 33, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
297     0,214,247,247,247,247,247,198,198,247,247,247,247,247,247, 16,247,247,247,247,247,247,132,132,247,247,247,247,247,247, 16, 14,181,247,247,247,247,247,247,247,247,247,247, 79,  0,  0,  0,132,247,247,247,247,247,247,247,148,  0,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 33,247,247,247,247,247,247,247,198,181,181,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
298     0,148,247,247,247,247,247,247,247,247,247,247,247,247,247,  0,132,247,247,247,247,247,247,247,247,247,247,247,247,145,  0,145,247,247,247,247,247,247,247,247,247,247,247,181, 14,  0,  0, 49,247,247,247,247,247,247,247, 82,  0,  0,  0,198,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,145,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
299     0, 46,247,247,247,247,247,247,247,247,247,247,247,247,247,  0, 30,247,247,247,247,247,247,247,247,247,247,247,247, 30,112,247,247,247,247,247,247, 96,247,247,247,247,247,247,145,  0,  0,  0,214,247,247,247,247,247,231,  0,  0,  0,  0, 96,247,247,247,247,247,247,247,247,247,247,247,247,115,  0, 30,148,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
300     0,  0,129,247,247,247,247,247,247,247,247,247,247,247,247,  0,  0, 96,247,247,247,247,247,247,247,247,247,247, 96, 16,247,247,247,247,247,247,145,  0,112,247,247,247,247,247,247, 49,  0,  0,181,247,247,247,247,247,148,  0,  0,  0,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247,115,  0,  0, 46,148,247,247,247,247,247,247,247,247,247,247,247, 33, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
301     0,  0,  0,129,247,247,247,247,181,145,247,247,247,247,145,  0,  0,  0, 46,148,247,247,247,247,247,247,148, 46,  0,  0,112,214,247,247,247,145, 14,  0,  0,145,247,247,247,247,145,  0,  0, 33,247,247,247,247,247,247, 66,  0,  0,  0,  0,  0, 99,132,115,181,181,132,198,247,247,247,247,247, 82,  0,  0,  0,  0, 66,165,247,247,247,247,247,247,198,132, 33,  0,  0,145,247,247,247,181, 79,  0, 79,181,247,247,247,145,  0,
302     0,  0,  0,  0, 33,115,115, 82,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33, 99,115,115, 99, 33,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,115,247,247,247,247,247,214,  0,  0,  0,  0,  0, 99,247,247,247,247,247,247,247,247,247,247,247,247, 16,  0,  0,  0,  0,  0,  0,  0, 49, 66, 66, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
303     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,108,224,255,255,255,255,255,255,101,164,255,255,255,143,250,255,255,255,255,255,255,255,255,255,255,255, 98,170,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
304     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,136,251,255,255,255,255,255,255,101,130,255,255,255,153,250,255,255,255,255,255,255,255,255,255,255,121, 98,189,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
305     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,198,252,255,255,255,255,255,164,164,255,255,255,255,176,249,251,255,255,255,255,255,255,255,255,150, 86,192,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
306     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,164,198,255,255,255,255,201,133,164,255,255,255,255,255,145,203,255,255,255,255,255,255,255,117, 79,194,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
307     0, 66,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 73, 73,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 47, 70,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 66,  0,
308     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
309     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
310 };
311
312 // magnifying glass icon (raw png)
313 unsigned char mag_sel_png[] = {
314   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
315   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
316   0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
317   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
318   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
319   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
320   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
321   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
322   0x2a, 0xbd, 0x00, 0x00, 0x01, 0xb9, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
323   0xe4, 0x94, 0xbb, 0x8a, 0x22, 0x41, 0x14, 0x86, 0xbf, 0xda, 0x16, 0x3a,
324   0x10, 0xba, 0x03, 0x2f, 0x78, 0x03, 0x51, 0x11, 0x4c, 0xd4, 0x40, 0xd4,
325   0x37, 0x30, 0x31, 0x30, 0xe9, 0x07, 0xf0, 0x15, 0x14, 0x7c, 0x1e, 0x31,
326   0x37, 0x33, 0x11, 0x73, 0xe9, 0x56, 0x44, 0x84, 0x36, 0xe9, 0x40, 0x50,
327   0x54, 0x14, 0xc4, 0xc0, 0xa8, 0x6d, 0x50, 0x6a, 0x92, 0x1d, 0xd9, 0x9d,
328   0x99, 0x75, 0x0d, 0x26, 0x58, 0xd8, 0x3f, 0xaa, 0xe2, 0xfc, 0xf5, 0xd5,
329   0x39, 0x9c, 0x53, 0x25, 0xa4, 0x94, 0x7c, 0xa7, 0x7e, 0xf0, 0xcd, 0xfa,
330   0xf7, 0x81, 0xbe, 0xf7, 0xc5, 0xf9, 0x7c, 0x96, 0x93, 0xc9, 0x84, 0xe5,
331   0x72, 0xc9, 0x66, 0xb3, 0x21, 0x99, 0x4c, 0x92, 0xcf, 0xe7, 0xa9, 0x54,
332   0x2a, 0x04, 0x02, 0x01, 0xf1, 0x2a, 0x50, 0x48, 0x29, 0x39, 0x9d, 0x4e,
333   0x72, 0x30, 0x18, 0x60, 0x59, 0xd6, 0x27, 0x43, 0xb5, 0x5a, 0xa5, 0xd1,
334   0x68, 0x10, 0x0c, 0x06, 0xc5, 0xcb, 0x19, 0x4e, 0xa7, 0x53, 0x2c, 0xcb,
335   0x22, 0x95, 0x4a, 0x51, 0x2a, 0x95, 0xc8, 0x64, 0x32, 0xac, 0x56, 0x2b,
336   0x66, 0xb3, 0x19, 0x93, 0xc9, 0x84, 0x48, 0x24, 0x42, 0xbd, 0x5e, 0x7f,
337   0xbd, 0x64, 0xdb, 0xb6, 0x01, 0x28, 0x97, 0xcb, 0x54, 0x2a, 0x15, 0x34,
338   0x4d, 0x13, 0xa1, 0x50, 0x48, 0x2a, 0x8a, 0xc2, 0x7a, 0xbd, 0xc6, 0xb6,
339   0x6d, 0xea, 0xf5, 0x3a, 0xa3, 0xd1, 0x48, 0xf6, 0xfb, 0xfd, 0xc7, 0x61,
340   0xc3, 0x30, 0xa8, 0xd5, 0x6a, 0xe2, 0x53, 0x53, 0xb6, 0xdb, 0x2d, 0x00,
341   0xc5, 0x62, 0x11, 0x4d, 0xd3, 0x04, 0x80, 0xa6, 0x69, 0xa2, 0x50, 0x28,
342   0xf0, 0x6b, 0x1c, 0x10, 0x86, 0x61, 0x3c, 0x60, 0x80, 0xf8, 0xb2, 0xcb,
343   0x89, 0x44, 0x02, 0x00, 0xc7, 0x71, 0x00, 0xde, 0x27, 0x5d, 0xfe, 0xdc,
344   0x3f, 0xe2, 0x1f, 0xa0, 0xe2, 0x8f, 0x63, 0x93, 0xcb, 0xe5, 0x00, 0x18,
345   0x8f, 0xc7, 0x98, 0xa6, 0x89, 0xeb, 0xba, 0xd2, 0x34, 0x4d, 0xc6, 0xe3,
346   0x31, 0x00, 0xe9, 0x74, 0x1a, 0x80, 0x5a, 0xad, 0xf6, 0x80, 0x3e, 0xed,
347   0xf2, 0x7a, 0xbd, 0x96, 0xc3, 0xe1, 0x90, 0xf9, 0x7c, 0xfe, 0xa5, 0x29,
348   0x1c, 0x0e, 0xd3, 0xe9, 0x74, 0xd0, 0x75, 0x5d, 0x00, 0x8c, 0x46, 0xa3,
349   0x8f, 0x17, 0xfc, 0x0e, 0xf4, 0x3c, 0x4f, 0xee, 0x76, 0x3b, 0x16, 0x8b,
350   0x05, 0x8e, 0xe3, 0xb0, 0xdf, 0xef, 0x89, 0xc7, 0xe3, 0xa4, 0xd3, 0x69,
351   0x6c, 0xdb, 0xe6, 0x74, 0x3a, 0x11, 0x8d, 0x46, 0x69, 0xb7, 0xdb, 0x0f,
352   0xe8, 0xd3, 0x0c, 0x01, 0x3c, 0xcf, 0x93, 0xae, 0xeb, 0xe2, 0x79, 0x1e,
353   0xb7, 0xdb, 0x0d, 0x9f, 0xcf, 0x87, 0xa2, 0x28, 0x5c, 0x2e, 0x17, 0x7a,
354   0xbd, 0x1e, 0xc7, 0xe3, 0x91, 0x58, 0x2c, 0x46, 0xab, 0xd5, 0x7a, 0x0a,
355   0x7d, 0xbc, 0x14, 0x55, 0x55, 0x85, 0xaa, 0xaa, 0x9f, 0x0c, 0x7e, 0xbf,
356   0x5f, 0x36, 0x9b, 0x4d, 0xba, 0xdd, 0x2e, 0xd7, 0xeb, 0x95, 0xeb, 0xf5,
357   0x8a, 0xae, 0xeb, 0x7f, 0xcf, 0xf0, 0x99, 0x5c, 0xd7, 0x95, 0x87, 0xc3,
358   0x81, 0xfb, 0xfd, 0x4e, 0x36, 0x9b, 0x7d, 0xad, 0xe4, 0xff, 0xe7, 0xfb,
359   0x7a, 0x1b, 0x00, 0x59, 0xa8, 0xba, 0x68, 0xca, 0x4f, 0xc5, 0xa7, 0x00,
360   0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
361 };
362 unsigned int mag_sel_png_len = 563;
363
364 unsigned char mag_png[] = {
365   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
366   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
367   0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
368   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
369   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
370   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
371   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
372   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
373   0x2a, 0xbd, 0x00, 0x00, 0x01, 0x92, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
374   0xe4, 0x94, 0xbb, 0xaa, 0xea, 0x50, 0x10, 0x86, 0xbf, 0xec, 0x08, 0x29,
375   0x36, 0x24, 0x85, 0x17, 0xbc, 0x81, 0x18, 0x11, 0x6c, 0xd4, 0x42, 0x8c,
376   0x0f, 0x61, 0xe1, 0x2b, 0xf8, 0x0a, 0x0a, 0x3e, 0x8f, 0xf8, 0x0c, 0x36,
377   0x62, 0x1f, 0x92, 0x88, 0x88, 0x10, 0x9b, 0x14, 0x42, 0x44, 0x45, 0x41,
378   0x2c, 0xac, 0x92, 0x80, 0xb2, 0x4e, 0x73, 0x94, 0x03, 0xfb, 0xb0, 0x4d,
379   0xb1, 0x8b, 0x03, 0xe7, 0xaf, 0xd6, 0x62, 0xfe, 0xf5, 0x31, 0xc3, 0xcc,
380   0x1a, 0x49, 0x08, 0xc1, 0x4f, 0xea, 0x83, 0x1f, 0xd6, 0xbf, 0x0f, 0x4c,
381   0x3c, 0x0f, 0xd7, 0xeb, 0x55, 0x38, 0x8e, 0xc3, 0x66, 0xb3, 0x61, 0xb7,
382   0xdb, 0x51, 0x2a, 0x95, 0xa8, 0xd7, 0xeb, 0x18, 0x86, 0x41, 0x32, 0x99,
383   0x94, 0xe2, 0x02, 0x25, 0x21, 0x04, 0x97, 0xcb, 0x45, 0x4c, 0xa7, 0x53,
384   0x6c, 0xdb, 0xfe, 0x62, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x52, 0xa9,
385   0x94, 0x14, 0x3b, 0xc3, 0xc5, 0x62, 0x81, 0x6d, 0xdb, 0x94, 0xcb, 0x65,
386   0x5a, 0xad, 0x16, 0x95, 0x4a, 0x85, 0xed, 0x76, 0xcb, 0x72, 0xb9, 0xc4,
387   0x71, 0x1c, 0xb2, 0xd9, 0x2c, 0xdd, 0x6e, 0x37, 0x7e, 0xc9, 0xae, 0xeb,
388   0x02, 0xd0, 0x6e, 0xb7, 0x31, 0x0c, 0x03, 0x55, 0x55, 0xa5, 0x74, 0x3a,
389   0x2d, 0x64, 0x59, 0xc6, 0xf7, 0x7d, 0x5c, 0xd7, 0x8d, 0x0d, 0xfc, 0x00,
390   0xd8, 0xef, 0xf7, 0x00, 0x34, 0x9b, 0x4d, 0x54, 0x55, 0x95, 0x00, 0x54,
391   0x55, 0x95, 0x1a, 0x8d, 0x06, 0x7f, 0xc6, 0x63, 0x03, 0x8b, 0xc5, 0x22,
392   0x00, 0x9e, 0xe7, 0x01, 0x3c, 0x27, 0x5d, 0xfc, 0xbe, 0xbf, 0xe2, 0xb1,
393   0x81, 0xb5, 0x5a, 0x0d, 0x00, 0xd3, 0x34, 0xb1, 0x2c, 0x8b, 0x20, 0x08,
394   0x84, 0x65, 0x59, 0x98, 0xa6, 0x09, 0x80, 0xae, 0xeb, 0xaf, 0x07, 0xf3,
395   0xf9, 0xfc, 0x7d, 0x97, 0x7d, 0xdf, 0x17, 0xb3, 0xd9, 0x8c, 0xd5, 0x6a,
396   0xf5, 0x57, 0x53, 0x26, 0x93, 0x61, 0x34, 0x1a, 0xa1, 0x69, 0x9a, 0x14,
397   0x6b, 0x6c, 0xa2, 0x28, 0x12, 0x87, 0xc3, 0x81, 0xf5, 0x7a, 0x8d, 0xe7,
398   0x79, 0x1c, 0x8f, 0x47, 0x0a, 0x85, 0x02, 0xba, 0xae, 0xe3, 0xba, 0x2e,
399   0x97, 0xcb, 0x85, 0x5c, 0x2e, 0xc7, 0x70, 0x38, 0x7c, 0x0b, 0x95, 0x9e,
400   0xcb, 0x21, 0x8a, 0x22, 0x11, 0x04, 0x01, 0x51, 0x14, 0x71, 0xbf, 0xdf,
401   0x49, 0x24, 0x12, 0xc8, 0xb2, 0xcc, 0xed, 0x76, 0x63, 0x32, 0x99, 0x70,
402   0x3e, 0x9f, 0xc9, 0xe7, 0xf3, 0x0c, 0x06, 0x83, 0x6f, 0xa1, 0xaf, 0x9f,
403   0xa2, 0x28, 0x8a, 0xa4, 0x28, 0xca, 0x17, 0xc3, 0xe7, 0xe7, 0xa7, 0xe8,
404   0xf7, 0xfb, 0x8c, 0xc7, 0x63, 0xc2, 0x30, 0x24, 0x0c, 0x43, 0x34, 0x4d,
405   0x7b, 0x9f, 0xe1, 0x77, 0x0a, 0x82, 0x40, 0x9c, 0x4e, 0x27, 0x1e, 0x8f,
406   0x07, 0xd5, 0x6a, 0x35, 0x5e, 0xc9, 0xff, 0xcf, 0xfa, 0xfa, 0x35, 0x00,
407   0x70, 0xf3, 0xae, 0xcb, 0x89, 0xcd, 0xd2, 0x46, 0x00, 0x00, 0x00, 0x00,
408   0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
409 };
410 unsigned int mag_png_len = 524;
411
412 unsigned char search_l_png[] = {
413   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
414   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
415   0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
416   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
417   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
418   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
419   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
420   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
421   0x2a, 0xbd, 0x00, 0x00, 0x01, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
422   0xac, 0x54, 0x3d, 0xab, 0xda, 0x50, 0x18, 0x7e, 0xce, 0xc9, 0x39, 0x31,
423   0x4d, 0xfc, 0x40, 0x30, 0x46, 0x14, 0xec, 0x50, 0x44, 0x17, 0x2f, 0x9d,
424   0xba, 0x15, 0xda, 0xd1, 0xa1, 0x2e, 0xdd, 0x3b, 0x14, 0x4a, 0xa1, 0x7f,
425   0xa6, 0x74, 0xbd, 0x43, 0xff, 0x84, 0xfd, 0x05, 0x82, 0xda, 0xa5, 0x83,
426   0x1d, 0xdc, 0x8a, 0x88, 0xa0, 0x44, 0x83, 0xc6, 0x28, 0xad, 0x1f, 0x49,
427   0xde, 0x2e, 0x8d, 0x78, 0x6f, 0xaf, 0x34, 0x68, 0x9f, 0xed, 0xbc, 0x70,
428   0x1e, 0x9e, 0x8f, 0xf7, 0x1c, 0x46, 0x44, 0x38, 0x45, 0xaf, 0xd7, 0x63,
429   0xb6, 0x6d, 0xe7, 0x6d, 0xdb, 0x6e, 0xba, 0xae, 0xfb, 0x6e, 0xb3, 0xd9,
430   0xdc, 0x6c, 0xb7, 0xdb, 0x04, 0xe7, 0x1c, 0x8c, 0x31, 0xfc, 0x0b, 0x2c,
431   0x22, 0xec, 0x76, 0xbb, 0xcc, 0xf3, 0xbc, 0xcc, 0x68, 0x34, 0x7a, 0xed,
432   0xba, 0xee, 0x87, 0x6c, 0x36, 0x7b, 0x93, 0xcb, 0xe5, 0x44, 0x3a, 0x9d,
433   0x86, 0xa6, 0x69, 0x50, 0x14, 0x25, 0x3e, 0x61, 0xa7, 0xd3, 0x61, 0xf3,
434   0xf9, 0xfc, 0xc9, 0x78, 0x3c, 0xbe, 0xd5, 0x75, 0xfd, 0x79, 0xa5, 0x52,
435   0x11, 0xa6, 0x69, 0x22, 0x95, 0x4a, 0x41, 0xd3, 0x34, 0x08, 0x21, 0xc0,
436   0x18, 0x8b, 0x45, 0x28, 0x00, 0x60, 0xb5, 0x5a, 0xa5, 0x27, 0x93, 0xc9,
437   0xa7, 0x62, 0xb1, 0xf8, 0xb2, 0x5a, 0xad, 0x22, 0x9f, 0xcf, 0xc3, 0x30,
438   0x0c, 0x48, 0x29, 0xc1, 0x39, 0x47, 0x5c, 0xbb, 0x00, 0x20, 0xda, 0xed,
439   0x36, 0x9f, 0x4e, 0xa7, 0xaf, 0x4c, 0xd3, 0x7c, 0x51, 0xaf, 0xd7, 0x61,
440   0x59, 0x16, 0x74, 0x5d, 0x87, 0x94, 0x12, 0x97, 0x40, 0x2c, 0x16, 0x0b,
441   0x93, 0x88, 0xde, 0xd6, 0x6a, 0x35, 0xdd, 0xb2, 0x2c, 0x18, 0x86, 0x01,
442   0x21, 0x04, 0x2e, 0x05, 0xf7, 0x3c, 0xaf, 0x59, 0x2e, 0x97, 0x9f, 0x45,
443   0xca, 0x38, 0xe7, 0xb8, 0x06, 0x3c, 0x08, 0x82, 0x46, 0xa1, 0x50, 0x78,
444   0x74, 0xad, 0xb2, 0x23, 0xa1, 0x94, 0xf2, 0x69, 0x26, 0x93, 0xe1, 0x51,
445   0x66, 0xf7, 0xf7, 0xd2, 0xf7, 0xfd, 0x07, 0x2f, 0x9e, 0x9b, 0x73, 0x55,
446   0x55, 0xb3, 0x91, 0x55, 0xc6, 0x18, 0xc2, 0x30, 0xbc, 0x1b, 0xf2, 0x19,
447   0xd5, 0xe7, 0xe6, 0x5c, 0x4a, 0x39, 0x06, 0x70, 0x5c, 0x8b, 0xb8, 0xeb,
448   0x71, 0xd6, 0x32, 0x11, 0x75, 0xf6, 0xfb, 0xfd, 0xd1, 0xea, 0xd5, 0xa5,
449   0x10, 0xd1, 0xb7, 0xf5, 0x7a, 0x1d, 0x84, 0x61, 0x08, 0x22, 0xba, 0x9e,
450   0x50, 0x51, 0x94, 0xaf, 0x8e, 0xe3, 0xfc, 0xdc, 0xed, 0x76, 0xf8, 0x1f,
451   0xe0, 0x89, 0x44, 0xe2, 0xc7, 0x72, 0xb9, 0xfc, 0xee, 0x38, 0x0e, 0x7c,
452   0xdf, 0x3f, 0x5a, 0xbf, 0xdf, 0x76, 0x6c, 0xc2, 0x46, 0xa3, 0xf1, 0x2b,
453   0x08, 0x82, 0xdb, 0xe1, 0x70, 0xe8, 0x2c, 0x16, 0x0b, 0x04, 0x41, 0x00,
454   0x22, 0xba, 0xb8, 0x1c, 0xfe, 0x67, 0x05, 0xbe, 0x78, 0x9e, 0xf7, 0x79,
455   0x30, 0x18, 0x8c, 0x67, 0xb3, 0x19, 0x45, 0x25, 0x9d, 0x53, 0x49, 0x44,
456   0x38, 0x1c, 0x0e, 0x38, 0x2d, 0xf3, 0xce, 0x6f, 0x03, 0x60, 0x29, 0x84,
457   0xf8, 0xe8, 0x79, 0x9e, 0xdb, 0xef, 0xf7, 0xdf, 0x97, 0x4a, 0xa5, 0xc7,
458   0xd1, 0x53, 0x54, 0x55, 0x15, 0x52, 0xca, 0xbf, 0x14, 0x0b, 0x21, 0x1e,
459   0x8c, 0x87, 0x9d, 0x1e, 0x5a, 0xad, 0x96, 0x00, 0x50, 0x27, 0xa2, 0x37,
460   0xaa, 0xaa, 0x36, 0x0d, 0xc3, 0x28, 0x26, 0x93, 0x49, 0xa1, 0x69, 0x9a,
461   0xc2, 0x39, 0x8f, 0x95, 0xc1, 0xef, 0x01, 0x00, 0x35, 0xe5, 0xd5, 0x5e,
462   0xd0, 0xed, 0x0c, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
463   0xae, 0x42, 0x60, 0x82
464 };
465 unsigned int search_l_png_len = 604;
466
467 unsigned char search_m_png[] = {
468   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
469   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
470   0x08, 0x02, 0x00, 0x00, 0x00, 0x35, 0x5e, 0x4b, 0x4d, 0x00, 0x00, 0x00,
471   0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xd6, 0xd8, 0xd4, 0x4f, 0x58,
472   0x32, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66,
473   0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20,
474   0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9,
475   0x65, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
476   0x62, 0x2c, 0x2f, 0x2f, 0x67, 0x60, 0x60, 0x60, 0x3c, 0x7e, 0xfc, 0x38,
477   0x88, 0xfa, 0xf8, 0xf1, 0x23, 0x88, 0xfa, 0xff, 0xff, 0x3f, 0x90, 0x62,
478   0x62, 0x00, 0x03, 0x5a, 0x50, 0x2c, 0x10, 0x1b, 0x58, 0x6e, 0xdd, 0xba,
479   0x05, 0xa4, 0x00, 0x02, 0x0c, 0x00, 0xa5, 0x07, 0x0f, 0x3c, 0x7e, 0xe1,
480   0x45, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
481   0x60, 0x82
482 };
483 unsigned int search_m_png_len = 158;
484
485 unsigned char search_r_png[] = {
486   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
487   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13,
488   0x08, 0x06, 0x00, 0x00, 0x00, 0x9d, 0x92, 0x5d, 0xf2, 0x00, 0x00, 0x00,
489   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
490   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
491   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
492   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
493   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
494   0x2a, 0xbd, 0x00, 0x00, 0x01, 0xea, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
495   0xa4, 0xd4, 0xbf, 0xaa, 0x1a, 0x41, 0x14, 0x06, 0xf0, 0x6f, 0xf6, 0x9f,
496   0xb2, 0x0a, 0x6b, 0xa5, 0x56, 0x8b, 0xa4, 0x92, 0xd4, 0x69, 0x7c, 0x03,
497   0xb1, 0x59, 0x49, 0x11, 0x52, 0xdf, 0xbc, 0x43, 0xcc, 0x2b, 0xa4, 0x4c,
498   0x97, 0x67, 0x08, 0xa4, 0x11, 0x2c, 0x52, 0x5c, 0x42, 0x24, 0x60, 0x8a,
499   0x34, 0x29, 0x42, 0x50, 0x41, 0x21, 0xa0, 0x97, 0xd5, 0x55, 0xb3, 0xbb,
500   0xee, 0xb2, 0xce, 0xee, 0xcc, 0x49, 0x91, 0x28, 0xc2, 0x0d, 0xe6, 0xaa,
501   0xa7, 0x9d, 0xc3, 0x8f, 0x73, 0x98, 0xf9, 0x86, 0x75, 0x3a, 0x1d, 0xc2,
502   0x89, 0x12, 0x42, 0x24, 0xf9, 0x7c, 0x7e, 0x5a, 0x2c, 0x16, 0x3f, 0x96,
503   0x4a, 0xa5, 0x5e, 0xb5, 0x5a, 0xfd, 0x52, 0x2e, 0x97, 0xfd, 0x46, 0xa3,
504   0x21, 0x8e, 0xfb, 0xd8, 0x60, 0x30, 0x38, 0x09, 0x65, 0x59, 0x86, 0x24,
505   0x49, 0x10, 0x04, 0x81, 0xf0, 0x3c, 0x6f, 0xb3, 0xd9, 0x6c, 0x7e, 0x58,
506   0x96, 0x75, 0x5b, 0xab, 0xd5, 0xde, 0x34, 0x9b, 0xcd, 0x5f, 0x07, 0xc8,
507   0xf7, 0xfd, 0x93, 0x90, 0x94, 0xf2, 0x80, 0x85, 0x61, 0x88, 0xe5, 0x72,
508   0x49, 0xe3, 0xf1, 0x58, 0xc6, 0x71, 0xfc, 0xc1, 0xb6, 0xed, 0xe7, 0x8e,
509   0xe3, 0x84, 0x00, 0xc0, 0xa4, 0x94, 0x27, 0x21, 0x22, 0x82, 0x94, 0x12,
510   0x52, 0x4a, 0xa4, 0x69, 0x8a, 0x28, 0x8a, 0xb0, 0x58, 0x2c, 0x30, 0x1c,
511   0x0e, 0x85, 0xeb, 0xba, 0xef, 0x6b, 0xb5, 0xda, 0x4d, 0xab, 0xd5, 0x8a,
512   0x34, 0xc6, 0xd8, 0x29, 0x07, 0x8c, 0x31, 0x28, 0x8a, 0x02, 0x22, 0x82,
513   0xae, 0xeb, 0x30, 0x0c, 0x03, 0xb9, 0x5c, 0x0e, 0x86, 0x61, 0xa8, 0x52,
514   0xca, 0xa7, 0xf3, 0xf9, 0xfc, 0x67, 0xbf, 0xdf, 0x7f, 0xa5, 0xe0, 0x81,
515   0xc5, 0x18, 0x03, 0x63, 0x0c, 0x9a, 0xa6, 0xa1, 0x50, 0x28, 0xa0, 0x52,
516   0xa9, 0xa0, 0x5e, 0xaf, 0x6b, 0x00, 0x5e, 0xac, 0xd7, 0xeb, 0x47, 0x0f,
517   0x86, 0x8e, 0x41, 0x55, 0x55, 0x61, 0x9a, 0x26, 0x2a, 0x95, 0x0a, 0x6c,
518   0xdb, 0xb6, 0x82, 0x20, 0x78, 0x76, 0x36, 0xb4, 0xc7, 0xf6, 0x93, 0x55,
519   0xab, 0x55, 0x26, 0x84, 0x78, 0xac, 0x1c, 0x5f, 0xf3, 0xb9, 0xa5, 0xeb,
520   0x3a, 0x2c, 0xcb, 0x82, 0xae, 0xeb, 0xbb, 0x03, 0xa4, 0x69, 0xda, 0xd9,
521   0x53, 0x29, 0x8a, 0x02, 0xd3, 0x34, 0x99, 0x61, 0x18, 0xcb, 0x8b, 0x56,
522   0x3b, 0xc6, 0xfe, 0x4e, 0x76, 0x77, 0x15, 0x44, 0x44, 0xe0, 0x9c, 0x0b,
523   0x22, 0xfa, 0xaa, 0x5c, 0x83, 0x48, 0x29, 0x11, 0x86, 0xe1, 0x86, 0x88,
524   0xbe, 0x5f, 0x35, 0xd1, 0x6e, 0xb7, 0x83, 0xe7, 0x79, 0x3d, 0x55, 0x55,
525   0x7d, 0xd0, 0x05, 0x25, 0xa5, 0x24, 0xce, 0x39, 0x4d, 0x26, 0x93, 0x45,
526   0xb7, 0xdb, 0x7d, 0x42, 0x44, 0x50, 0x2e, 0x59, 0x49, 0x08, 0x81, 0xf5,
527   0x7a, 0x9d, 0x4c, 0xa7, 0xd3, 0x77, 0x42, 0x88, 0x6f, 0x00, 0xa0, 0xed,
528   0x0f, 0xb3, 0x2c, 0x3b, 0xe4, 0xe9, 0x5f, 0xf9, 0x23, 0xfa, 0x93, 0x6d,
529   0xce, 0x39, 0x56, 0xab, 0x95, 0x18, 0x0e, 0x87, 0x9f, 0x82, 0x20, 0x78,
530   0xdd, 0x6e, 0xb7, 0xd3, 0x7b, 0xe9, 0x27, 0xa2, 0x7b, 0x08, 0x11, 0x21,
531   0x4d, 0x53, 0x70, 0xce, 0x11, 0xc7, 0xb1, 0x74, 0x5d, 0xd7, 0x9f, 0xcd,
532   0x66, 0x3d, 0xce, 0xf9, 0x4b, 0xc7, 0x71, 0xee, 0x0e, 0xef, 0x70, 0x34,
533   0x1a, 0xe1, 0x7f, 0xff, 0x51, 0x92, 0x24, 0xd8, 0x6e, 0xb7, 0x61, 0x14,
534   0x45, 0x9f, 0x39, 0xe7, 0x6f, 0x19, 0x63, 0xb7, 0x8e, 0xe3, 0x44, 0xc7,
535   0x7d, 0xbf, 0x07, 0x00, 0x5f, 0x77, 0x46, 0x8c, 0x30, 0x2c, 0xd8, 0x9d,
536   0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
537 };
538 unsigned int search_r_png_len = 612;
539
540 static unsigned char close_png[] = {
541   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
542   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b,
543   0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0xac, 0x77, 0x26, 0x00, 0x00, 0x00,
544   0xd8, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x75, 0x51, 0xbd, 0x12, 0x46,
545   0x40, 0x0c, 0xdc, 0x18, 0x15, 0x0a, 0x14, 0x14, 0x1a, 0x43, 0xeb, 0x35,
546   0xbc, 0x7f, 0xa7, 0x43, 0x67, 0x06, 0x33, 0x28, 0xd0, 0xde, 0x77, 0x7b,
547   0x23, 0x2a, 0xdf, 0x16, 0x97, 0x9f, 0xdb, 0xcb, 0x26, 0x39, 0xc1, 0x83,
548   0x7d, 0xdf, 0xcd, 0xb2, 0x2c, 0xd8, 0xb6, 0x0d, 0xe7, 0x79, 0x22, 0x8a,
549   0x22, 0xc4, 0x71, 0x8c, 0x3c, 0xcf, 0x91, 0xa6, 0xa9, 0x90, 0xe6, 0x8e,
550   0x69, 0x9a, 0xcc, 0x38, 0x8e, 0xb8, 0xae, 0x4b, 0xdf, 0xbe, 0x36, 0x0c,
551   0x43, 0x94, 0x65, 0x89, 0xa2, 0x28, 0xc4, 0x3b, 0x8e, 0xe3, 0x2f, 0x91,
552   0x2f, 0xa8, 0xc2, 0x42, 0x56, 0xd1, 0x78, 0xf3, 0x3c, 0xbb, 0x04, 0x2f,
553   0xda, 0xb6, 0x45, 0x55, 0x55, 0x74, 0x9d, 0x65, 0x2c, 0x22, 0xb8, 0xef,
554   0x1b, 0xeb, 0xba, 0xc2, 0x67, 0x8f, 0x4c, 0x10, 0x7d, 0xdf, 0xa3, 0xae,
555   0x6b, 0xe7, 0xd3, 0x32, 0x56, 0x90, 0xe7, 0x53, 0x46, 0x31, 0x0c, 0x83,
556   0x73, 0x95, 0xa8, 0x31, 0x93, 0x9c, 0xc7, 0xe3, 0xd4, 0x0a, 0xb6, 0xa0,
557   0x44, 0x5a, 0xc6, 0xc6, 0x18, 0x77, 0xcd, 0x41, 0xbd, 0x24, 0x49, 0x94,
558   0xfb, 0x12, 0x59, 0x51, 0x5b, 0xd2, 0x16, 0xed, 0xfa, 0x20, 0xdc, 0x6f,
559   0xd7, 0x75, 0x9f, 0x6b, 0xd3, 0x2a, 0x41, 0x10, 0xa0, 0x69, 0x1a, 0x57,
560   0x59, 0x28, 0x47, 0x99, 0x2f, 0x30, 0xcf, 0x7b, 0xfb, 0x41, 0xcf, 0x1a,
561   0x2c, 0xeb, 0xeb, 0x07, 0x29, 0x9d, 0x65, 0x19, 0x6c, 0xab, 0x6e, 0x5d,
562   0x3f, 0x07, 0x0a, 0x79, 0x90, 0x0e, 0x11, 0x45, 0xc2, 0x00, 0x00, 0x00,
563   0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
564 };
565 static unsigned int close_png_len = 273;
566
567
568 static unsigned char closed_png[81] =
569 {
570   0,  0,  0,  0,142,  0,  0,  0,  0,
571   0,  0,  0,  0,142,142,  0,  0,  0,
572   0,  0,  0,  0,142,142,142,  0,  0,
573   0,  0,  0,  0,142,142,142,142,  0,
574   0,  0,  0,  0,142,142,142,142,142,
575   0,  0,  0,  0,142,142,142,142,  0,
576   0,  0,  0,  0,142,142,142,  0,  0,
577   0,  0,  0,  0,142,142,  0,  0,  0,
578   0,  0,  0,  0,142,  0,  0,  0,  0
579 };
580
581 static unsigned char closed_a_png[81] =
582 {
583   0,  0,  0,  0,255,  0,  0,  0,  0,
584   0,  0,  0,  0,255,255,  0,  0,  0,
585   0,  0,  0,  0,255,255,255,  0,  0,
586   0,  0,  0,  0,255,255,255,255,  0,
587   0,  0,  0,  0,255,255,255,255,255,
588   0,  0,  0,  0,255,255,255,255,  0,
589   0,  0,  0,  0,255,255,255,  0,  0,
590   0,  0,  0,  0,255,255,  0,  0,  0,
591   0,  0,  0,  0,255,  0,  0,  0,  0
592 };
593
594 static unsigned char open_png[81] =
595 {
596     0,  0,  0,  0,  0,  0,  0,  0,  0,
597     0,  0,  0,  0,  0,  0,  0,  0,  0,
598     0,  0,  0,  0,  0,  0,  0,  0,  0,
599     0,  0,  0,  0,  0,  0,  0,  0,  0,
600   142,142,142,142,142,142,142,142,142,
601     0,142,142,142,142,142,142,142,  0,
602     0,  0,142,142,142,142,142,  0,  0,
603     0,  0,  0,142,142,142,  0,  0,  0,
604     0,  0,  0,  0,142,  0,  0,  0,  0
605 };
606
607 static unsigned char open_a_png[81] =
608 {
609     0,  0,  0,  0,  0,  0,  0,  0,  0,
610     0,  0,  0,  0,  0,  0,  0,  0,  0,
611     0,  0,  0,  0,  0,  0,  0,  0,  0,
612     0,  0,  0,  0,  0,  0,  0,  0,  0,
613   255,255,255,255,255,255,255,255,255,
614     0,255,255,255,255,255,255,255,  0,
615     0,  0,255,255,255,255,255,  0,  0,
616     0,  0,  0,255,255,255,  0,  0,  0,
617     0,  0,  0,  0,255,  0,  0,  0,  0
618 };
619
620 static unsigned char bdwn_png[7*8] =
621 {
622     0,  0,  0,142,  0,  0,  0,
623     0,  0,  0,142,  0,  0,  0,
624     0,  0,  0,142,  0,  0,  0,
625   142,  0,  0,142,  0,  0,142,
626   142,142,  0,142,  0,142,142,
627   142,142,142,142,142,142,142,
628     0,142,142,142,142,142,  0,
629     0,  0,142,142,142,  0,  0,
630 };
631
632 static unsigned char bdwn_a_png[7*8] =
633 {
634     0,  0,  0,255,  0,  0,  0,
635     0,  0,  0,255,  0,  0,  0,
636     0,  0,  0,255,  0,  0,  0,
637   128,  0,  0,255,  0,  0,128,
638   255,128,  0,255,  0,128,255,
639   128,255,128,255,128,255,128,
640     0,128,255,255,255,128,  0,
641     0,  0,128,255,128,  0,  0,
642 };
643
644 static unsigned char sync_on_png[576] =
645 {
646   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
647   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
648   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
649   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
650   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
651   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
652   128,128,128,128,128,128,128,128,128,138,128,128,128,128,133,128,128,128,128,128,128,128,128,128,
653   128,128,128,128,128,128,128,129,205,186,128,128,128,128,160,210,134,128,128,128,128,128,128,128,
654   128,128,128,128,128,128,139,217,255,181,128,128,128,128,152,255,229,147,128,128,128,128,128,128,
655   128,128,128,128,128,156,236,255,255,181,128,128,128,128,152,255,255,243,164,128,128,128,128,128,
656   128,128,128,128,175,249,255,255,255,223,196,198,198,197,211,255,255,255,253,186,128,128,128,128,
657   128,128,133,202,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,214,137,128,128,
658   128,128,135,217,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,225,140,128,128,
659   128,128,128,128,189,255,255,255,255,238,224,225,225,224,232,255,255,255,255,201,131,128,128,128,
660   128,128,128,128,128,167,245,255,255,183,128,128,128,128,155,255,255,250,179,128,128,128,128,128,
661   128,128,128,128,128,128,150,231,255,188,128,128,128,128,161,255,238,158,128,128,128,128,128,128,
662   128,128,128,128,128,128,128,136,216,188,128,128,128,128,161,223,142,128,128,128,128,128,128,128,
663   128,128,128,128,128,128,128,128,130,141,128,128,128,128,135,132,128,128,128,128,128,128,128,128,
664   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
665   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
666   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
667   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
668   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
669   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
670 };
671
672 static unsigned char sync_off_png[576] =
673 {
674   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
675   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
676   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
677   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
678   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
679   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
680   128,128,128,128,128,128,128,128,138,128,128,128,128,128,128,133,128,128,128,128,128,128,128,128,
681   128,128,128,128,128,128,129,205,186,128,128,128,128,128,128,160,210,134,128,128,128,128,128,128,
682   128,128,128,128,128,139,217,255,181,128,128,128,128,128,128,152,255,229,147,128,128,128,128,128,
683   128,128,128,128,156,236,255,255,181,128,128,128,128,128,128,152,255,255,243,164,128,128,128,128,
684   128,128,128,175,249,255,255,255,223,196,198,198,128,128,197,211,255,255,255,253,186,128,128,128,
685   128,128,202,255,255,255,255,255,255,255,255,225,128,128,255,255,255,255,255,255,255,214,128,128,
686   128,128,217,255,255,255,255,255,255,255,255,128,128,198,255,255,255,255,255,255,255,225,128,128,
687   128,128,128,189,255,255,255,255,238,224,225,128,128,225,224,232,255,255,255,255,201,128,128,128,
688   128,128,128,128,167,245,255,255,183,128,128,128,128,128,128,155,255,255,250,179,128,128,128,128,
689   128,128,128,128,128,150,231,255,188,128,128,128,128,128,128,161,255,238,158,128,128,128,128,128,
690   128,128,128,128,128,128,136,216,188,128,128,128,128,128,128,161,223,142,128,128,128,128,128,128,
691   128,128,128,128,128,128,128,130,141,128,128,128,128,128,128,135,132,128,128,128,128,128,128,128,
692   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
693   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
694   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
695   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
696   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
697   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
698 };
699
700 static unsigned char sync_a_png[576] =
701 {
702     0,  0,  0,  0,  0,  0,  0, 29, 98,157,207,231,234,211,164,104, 38,  0,  0,  0,  0,  0,  0,  0,
703     0,  0,  0,  0,  0, 21,143,234,255,255,255,255,255,255,255,255,244,155, 33,  0,  0,  0,  0,  0,
704     0,  0,  0,  0, 70,221,255,255,255,255,255,255,255,255,255,255,255,255,235, 93,  0,  0,  0,  0,
705     0,  0,  0, 92,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,116,  0,  0,  0,
706     0,  0, 68,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 96,  0,  0,
707     0, 20,225,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,243, 41,  0,
708     0,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,  1,
709    28,238,255,255,255,255,255,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 42,
710    99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,133,
711   160,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,204,
712   212,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,224,
713   234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,237,255,236,
714   235,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,230,255,236,
715   216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,226,
716   168,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,208,
717   107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,147,
718    39,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 53,
719     0,159,255,255,255,255,255,255,251,255,255,255,255,255,255,255,255,255,255,255,255,255,190,  3,
720     0, 31,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,249, 54,  0,
721     0,  0, 91,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,119,  0,  0,
722     0,  0,  0,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,  0,  0,  0,
723     0,  0,  0,  0, 98,240,255,255,255,255,255,255,255,255,255,255,255,255,248,119,  0,  0,  0,  0,
724     0,  0,  0,  0,  0, 45,168,252,255,255,255,255,255,255,255,255,255,184, 58,  0,  0,  0,  0,  0,
725     0,  0,  0,  0,  0,  0,  0, 45,131,201,222,234,236,224,204,142, 54,  0,  0,  0,  0,  0,  0,  0
726 };
727
728
729 //------------------------------------------------------------------------
730
731 static const char tabs_css[] = 
732 ".tabs, .tabs2, .tabs3 {\n"
733 "    background-image: url('tab_b.png');\n"
734 "    width: 100%;\n"
735 "    z-index: 101;\n"
736 "    font-size: 13px;\n"
737 "    font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;\n"
738 "}\n"
739 "\n"
740 ".tabs2 {\n"
741 "    font-size: 10px;\n"
742 "}\n"
743 ".tabs3 {\n"
744 "    font-size: 9px;\n"
745 "}\n"
746 "\n"
747 ".tablist {\n"
748 "    margin: 0;\n"
749 "    padding: 0;\n"
750 "    display: table;\n"
751 "}\n"
752 "\n"
753 ".tablist li {\n"
754 "    float: left;\n"
755 "    display: table-cell;\n"
756 "    background-image: url('tab_b.png');\n"
757 "    line-height: 36px;\n"
758 "    list-style: none;\n"
759 "}\n"
760 "\n"
761 ".tablist a {\n"
762 "    display: block;\n"
763 "    padding: 0 20px;\n"
764 "    font-weight: bold;\n"
765 "    background-image:url('tab_s.png');\n"
766 "    background-repeat:no-repeat;\n"
767 "    background-position:right;\n"
768 "    color: ##30;\n"
769 "    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n"
770 "    text-decoration: none;\n"
771 "    outline: none;\n"
772 "}\n"
773 "\n"
774 ".tabs3 .tablist a {\n"
775 "    padding: 0 10px;\n"
776 "}\n"
777 "\n"
778 ".tablist a:hover {\n"
779 "    background-image: url('tab_h.png');\n"
780 "    background-repeat:repeat-x;\n"
781 "    color: #fff;\n"
782 "    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
783 "    text-decoration: none;\n"
784 "}\n"
785 "\n"
786 ".tablist li.current a {\n"
787 "    background-image: url('tab_a.png');\n"
788 "    background-repeat:repeat-x;\n"
789 "    color: #fff;\n"
790 "    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
791 "}\n"
792 ;
793
794 struct img_data_item
795 {
796   const char *name;
797   unsigned char *content;
798   unsigned int len;
799 };
800
801
802 static void writeImgData(const char *dir,img_data_item *data)
803 {
804   while (data->name)
805   {
806     QCString fileName;
807     fileName=(QCString)dir+"/"+data->name;
808     QFile f(fileName);
809     if (f.open(IO_WriteOnly))
810     {
811       f.writeBlock((char*)data->content,
812                     data->len>0 ? data->len : qstrlen((char*)data->content));
813     }
814     else
815     {
816       fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
817     }
818     Doxygen::indexList->addImageFile(QCString("/search/")+data->name);
819     data++;
820   }
821 }
822
823 static ColoredImgDataItem colored_tab_data[] =
824 {
825   // file_name      W   H  luma_data        alpha_data
826   { "tab_a.png",    1, 36, tab_a_png,       0 },
827   { "tab_b.png",    1, 36, tab_b_png,       0 },
828   { "tab_h.png",    1, 36, tab_h_png,       0 },
829   { "tab_s.png",    1, 36, tab_s_png,       0 },
830   { "nav_h.png",    1, 12, header_png,      0 },
831   { "nav_f.png",    1, 56, func_header_png, 0 },
832   { "bc_s.png",     8, 30, bc_s_png,        bc_s_a_png },
833   { "doxygen.png", 104,31, doxygen_png,     doxygen_a_png },
834   { "closed.png",   9,  9, closed_png,      closed_a_png },
835   { "open.png",     9,  9, open_png,        open_a_png },
836   { "bdwn.png",     7,  8, bdwn_png,        bdwn_a_png },
837   { "sync_on.png", 24, 24, sync_on_png,     sync_a_png },
838   { "sync_off.png",24, 24, sync_off_png,    sync_a_png },
839   { 0, 0, 0, 0, 0 }
840 };
841
842 static img_data_item search_client_data[] =
843 {
844   // file_name          raw_data          num bytes
845   { "mag_sel.png",      mag_sel_png,      mag_sel_png_len  },
846   { "search_l.png",     search_l_png,     search_l_png_len },
847   { "search_m.png",     search_m_png,     search_m_png_len },
848   { "search_r.png",     search_r_png,     search_r_png_len },
849   { "close.png",        close_png,        close_png_len    },
850   { 0, 0, 0 }
851 };
852
853 static img_data_item search_server_data[] =
854 {
855   // file_name          raw_data          num bytes
856   { "mag.png",          mag_png,          mag_png_len      },
857   { "search_l.png",     search_l_png,     search_l_png_len },
858   { "search_m.png",     search_m_png,     search_m_png_len },
859   { "search_r.png",     search_r_png,     search_r_png_len },
860   { 0, 0, 0 }
861 };
862
863 //------------------------------------------------------------------------
864
865 static void writeClientSearchBox(FTextStream &t,const char *relPath)
866 {
867   t << "        <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
868   t << "        <span class=\"left\">\n";
869   t << "          <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
870   t << "               onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
871   t << "               onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
872   t << "               alt=\"\"/>\n";
873   t << "          <input type=\"text\" id=\"MSearchField\" value=\"" 
874     << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
875   t << "               onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
876   t << "               onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
877   t << "               onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
878   t << "          </span><span class=\"right\">\n";
879   t << "            <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
880     << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
881   t << "          </span>\n";
882   t << "        </div>\n";
883 }
884
885 static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch)
886 {
887   static bool externalSearch = Config_getBool("EXTERNAL_SEARCH");
888   t << "        <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
889   t << "          <div class=\"left\">\n";
890   t << "            <form id=\"FSearchBox\" action=\"" << relPath;
891   if (externalSearch)
892   {
893     t << "search" << Doxygen::htmlFileExtension;
894   }
895   else
896   {
897     t << "search.php";
898   }
899   t << "\" method=\"get\">\n";
900   t << "              <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
901   if (!highlightSearch)
902   {
903     t << "              <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
904       << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
905     t << "                     onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
906     t << "                     onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
907     t << "            </form>\n";
908     t << "          </div><div class=\"right\"></div>\n";
909     t << "        </div>\n";
910   }
911 }
912
913 //------------------------------------------------------------------------
914
915 /// substitute all occurrences of \a src in \a s by \a dst
916 QCString substitute(const char *s,const char *src,const char *dst)
917 {
918   if (s==0 || src==0) return s;
919   const char *p, *q;
920   int srcLen = qstrlen(src);
921   int dstLen = dst ? qstrlen(dst) : 0;
922   int resLen;
923   if (srcLen!=dstLen)
924   {
925     int count;
926     for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++;
927     resLen = (int)(p-s)+qstrlen(p)+count*(dstLen-srcLen);
928   }
929   else // result has same size as s
930   {
931     resLen = qstrlen(s);
932   }
933   QCString result(resLen+1);
934   char *r;
935   for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
936   {
937     int l = (int)(q-p);
938     memcpy(r,p,l);
939     r+=l;
940     if (dst) memcpy(r,dst,dstLen);
941     r+=dstLen;
942   }
943   qstrcpy(r,p);
944   //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
945   return result;
946 }
947 //----------------------------------------------------------------------
948
949 /// Clear a text block \a s from \a begin to \a end markers
950 QCString clearBlock(const char *s,const char *begin,const char *end)
951 {
952   if (s==0 || begin==0 || end==0) return s;
953   const char *p, *q;
954   int beginLen = qstrlen(begin);
955   int endLen = qstrlen(end);
956   int resLen = 0;
957   for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
958   {
959     resLen+=(int)(q-p);
960     p=q+beginLen;
961     if ((q=strstr(p,end))==0)
962     {
963       resLen+=beginLen;
964       break;
965     }
966   }
967   resLen+=qstrlen(p);
968   // resLen is the length of the string without the marked block
969
970   QCString result(resLen+1);
971   char *r;
972   for (r=result.data(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
973   {
974     int l = (int)(q-p);
975     memcpy(r,p,l);
976     r+=l;
977     p=q+beginLen;
978     if ((q=strstr(p,end))==0)
979     {
980       memcpy(r,begin,beginLen);
981       r+=beginLen;
982       break;
983     }
984   }
985   qstrcpy(r,p);
986   return result;
987 }
988 //----------------------------------------------------------------------
989
990 QCString selectBlock(const QCString& s,const QCString &name,bool enable)
991 {
992   const QCString begin = "<!--BEGIN " + name + "-->";
993   const QCString end = "<!--END " + name + "-->";
994   const QCString nobegin = "<!--BEGIN !" + name + "-->";
995   const QCString noend = "<!--END !" + name + "-->";
996
997   QCString result = s;
998   if (enable)
999   {
1000     result = substitute(result, begin, "");
1001     result = substitute(result, end, "");
1002     result = clearBlock(result, nobegin, noend);
1003   }
1004   else
1005   {
1006     result = substitute(result, nobegin, "");
1007     result = substitute(result, noend, "");
1008     result = clearBlock(result, begin, end);
1009   }
1010
1011   return result;
1012 }
1013
1014 static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
1015 {
1016   QGString result;
1017   FTextStream t(&result);
1018   if (serverSide) {
1019     writeServerSearchBox(t, relPath, highlightSearch);
1020   }
1021   else {
1022      writeClientSearchBox(t, relPath);
1023   }
1024   return QCString(result);
1025 }
1026
1027 static QCString removeEmptyLines(const QCString &s)
1028 {
1029   BufStr out(s.length()+1);
1030   char *p=s.data();
1031   if (p)
1032   {
1033     char c;
1034     while ((c=*p++))
1035     {
1036       if (c=='\n')
1037       {
1038         char *e = p;
1039         while (*e==' ' || *e=='\t') e++;
1040         if (*e=='\n') 
1041         {
1042           p=e;
1043         }
1044         else out.addChar(c);
1045       }
1046       else
1047       {
1048         out.addChar(c);
1049       }
1050     }
1051   }
1052   out.addChar('\0');
1053   //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data());
1054   return out.data();
1055 }
1056
1057 static QCString substituteHtmlKeywords(const QCString &s,
1058                                        const QCString &title,
1059                                        const QCString &relPath,
1060                                        const QCString &navPath=QCString())
1061 {
1062   // Build CSS/Javascript tags depending on treeview, search engine settings
1063   QCString cssFile;
1064   QStrList extraCssFile;
1065   QCString generatedBy;
1066   QCString treeViewCssJs;
1067   QCString searchCssJs;
1068   QCString searchBox;
1069   QCString mathJaxJs;
1070   QCString extraCssText;
1071
1072   static QCString projectName = Config_getString("PROJECT_NAME");
1073   static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
1074   static bool treeView = Config_getBool("GENERATE_TREEVIEW");
1075   static bool searchEngine = Config_getBool("SEARCHENGINE");
1076   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
1077   static bool mathJax = Config_getBool("USE_MATHJAX");
1078   static QCString mathJaxFormat = Config_getEnum("MATHJAX_FORMAT");
1079   static bool disableIndex = Config_getBool("DISABLE_INDEX");
1080   static bool hasProjectName = !projectName.isEmpty();
1081   static bool hasProjectNumber = !Config_getString("PROJECT_NUMBER").isEmpty();
1082   static bool hasProjectBrief = !Config_getString("PROJECT_BRIEF").isEmpty();
1083   static bool hasProjectLogo = !Config_getString("PROJECT_LOGO").isEmpty();
1084   static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));
1085
1086   cssFile = Config_getString("HTML_STYLESHEET");
1087   if (cssFile.isEmpty())
1088   {
1089     cssFile = "doxygen.css";
1090   }
1091   else
1092   {
1093     QFileInfo cssfi(cssFile);
1094     if (cssfi.exists())
1095     {
1096       cssFile = cssfi.fileName().utf8();
1097     }
1098     else
1099     {
1100       cssFile = "doxygen.css";
1101     }
1102   }
1103
1104   extraCssText = "";
1105   extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET");
1106   for (uint i=0; i<extraCssFile.count(); ++i)
1107   {
1108     QCString fileName(extraCssFile.at(i));
1109     if (!fileName.isEmpty())
1110     {
1111       QFileInfo fi(fileName);
1112       if (fi.exists())
1113       {
1114         extraCssText += "<link href=\"$relpath^"+stripPath(fileName)+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
1115       }
1116     }
1117   }
1118
1119   if (timeStamp) 
1120   {
1121     generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString("PROJECT_NAME")));
1122   }
1123   else 
1124   {
1125     generatedBy = theTranslator->trGeneratedBy();
1126   }
1127
1128   if (treeView)
1129   {
1130     treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
1131                     "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n"
1132                     "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n"
1133                     "<script type=\"text/javascript\">\n"
1134                     "  $(document).ready(initResizable);\n"
1135                     "  $(window).load(resizeHeight);\n"
1136                     "</script>";
1137   }
1138
1139   if (searchEngine)
1140   {
1141     searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
1142     searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";
1143
1144     if (!serverBasedSearch) 
1145     {
1146       searchCssJs += "<script type=\"text/javascript\">\n"
1147                      "  $(document).ready(function() { searchBox.OnSelectItem(0); });\n"
1148                      "</script>";
1149     }
1150     else 
1151     {
1152       searchCssJs += "<script type=\"text/javascript\">\n"
1153                      "  $(document).ready(function() {\n"
1154                      "    if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
1155                      "  });\n"
1156                      "</script>\n";
1157
1158       // OPENSEARCH_PROVIDER {
1159       searchCssJs += "<link rel=\"search\" href=\"" + relPath +
1160                      "search-opensearch.php?v=opensearch.xml\" "
1161                      "type=\"application/opensearchdescription+xml\" title=\"" +
1162                      (hasProjectName ? projectName : QCString("Doxygen")) + 
1163                      "\"/>";
1164       // OPENSEARCH_PROVIDER }
1165     }
1166     searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
1167   }
1168
1169   if (mathJax)
1170   {
1171     QCString path = Config_getString("MATHJAX_RELPATH");  
1172     if (!path.isEmpty() && path.at(path.length()-1)!='/')  
1173     {   
1174       path+="/";   
1175     }   
1176     if (path.isEmpty() || path.left(2)=="..") // relative path  
1177     {  
1178       path.prepend(relPath);   
1179     }  
1180     mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
1181                 "  MathJax.Hub.Config({\n"
1182                 "    extensions: [\"tex2jax.js\"";
1183     QStrList &mathJaxExtensions = Config_getList("MATHJAX_EXTENSIONS");
1184     const char *s = mathJaxExtensions.first();
1185     while (s)
1186     {
1187       mathJaxJs+= ", \""+QCString(s)+".js\"";
1188       s = mathJaxExtensions.next();
1189     }
1190     if (mathJaxFormat.isEmpty())
1191     {
1192       mathJaxFormat = "HTML-CSS";
1193     }
1194     mathJaxJs += "],\n"
1195                  "    jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
1196                  "});\n";
1197     if (!g_mathjax_code.isEmpty())
1198     {
1199       mathJaxJs += g_mathjax_code;
1200       mathJaxJs += "\n";
1201     }
1202     mathJaxJs += "</script>";
1203     mathJaxJs += "<script src=\"" + path + "MathJax.js\"></script>\n";
1204   }
1205
1206   // first substitute generic keywords
1207   QCString result = substituteKeywords(s,title,
1208         convertToHtml(Config_getString("PROJECT_NAME")),
1209         convertToHtml(Config_getString("PROJECT_NUMBER")),
1210         convertToHtml(Config_getString("PROJECT_BRIEF")));
1211
1212   // additional HTML only keywords
1213   result = substitute(result,"$navpath",navPath);
1214   result = substitute(result,"$stylesheet",cssFile);
1215   result = substitute(result,"$treeview",treeViewCssJs);
1216   result = substitute(result,"$searchbox",searchBox);
1217   result = substitute(result,"$search",searchCssJs);
1218   result = substitute(result,"$mathjax",mathJaxJs);
1219   result = substitute(result,"$generatedby",generatedBy);
1220   result = substitute(result,"$extrastylesheet",extraCssText);
1221   result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only
1222   result = substitute(result,"$relpath^",relPath); //<-- must be last
1223   
1224   // additional HTML only conditional blocks
1225   result = selectBlock(result,"DISABLE_INDEX",disableIndex);
1226   result = selectBlock(result,"GENERATE_TREEVIEW",treeView);
1227   result = selectBlock(result,"SEARCHENGINE",searchEngine);
1228   result = selectBlock(result,"TITLEAREA",titleArea);
1229   result = selectBlock(result,"PROJECT_NAME",hasProjectName);
1230   result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber);
1231   result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief);
1232   result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo);
1233
1234   result = removeEmptyLines(result);
1235
1236   return result;
1237 }
1238
1239 //--------------------------------------------------------------------------
1240
1241 HtmlCodeGenerator::HtmlCodeGenerator()
1242    : m_streamSet(FALSE), m_col(0)
1243 {
1244 }
1245
1246 HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath) 
1247    : m_col(0), m_relPath(relPath)
1248 {
1249   setTextStream(t);
1250 }
1251
1252 void HtmlCodeGenerator::setTextStream(FTextStream &t)
1253 {
1254   m_streamSet = t.device()!=0;
1255   m_t.setDevice(t.device());
1256 }
1257
1258 void HtmlCodeGenerator::setRelativePath(const QCString &path)
1259 {
1260   m_relPath = path;
1261 }
1262
1263 void HtmlCodeGenerator::codify(const char *str)
1264 {
1265   static int tabSize = Config_getInt("TAB_SIZE");
1266   if (str && m_streamSet)
1267   { 
1268     const char *p=str;
1269     char c;
1270     int spacesToNextTabStop;
1271     while (*p)
1272     {
1273       c=*p++;
1274       switch(c)
1275       {
1276         case '\t': spacesToNextTabStop = 
1277                          tabSize - (m_col%tabSize); 
1278                    m_t << Doxygen::spaces.left(spacesToNextTabStop); 
1279                    m_col+=spacesToNextTabStop; 
1280                    break; 
1281         case '\n': m_t << "\n"; m_col=0; 
1282                    break;
1283         case '\r': break;
1284         case '<':  m_t << "&lt;"; m_col++; 
1285                    break;
1286         case '>':  m_t << "&gt;"; m_col++; 
1287                    break;
1288         case '&':  m_t << "&amp;"; m_col++; 
1289                    break;
1290         case '\'': m_t << "&#39;"; m_col++; // &apos; is not valid XHTML
1291                    break;
1292         case '"':  m_t << "&quot;"; m_col++;
1293                    break;
1294         case '\\':
1295                    if (*p=='<')
1296                      { m_t << "&lt;"; p++; }
1297                    else if (*p=='>')
1298                      { m_t << "&gt;"; p++; }
1299                    else
1300                      m_t << "\\";
1301                    m_col++;
1302                    break;
1303         default:   p=writeUtf8Char(m_t,p-1);    
1304                    m_col++;                    
1305                    break;
1306       }
1307     }
1308   }
1309 }
1310
1311 void HtmlCodeGenerator::docify(const char *str)
1312 {
1313   if (str && m_streamSet)
1314   {
1315     const char *p=str;
1316     char c;
1317     while (*p)
1318     {
1319       c=*p++;
1320       switch(c)
1321       {
1322         case '<':  m_t << "&lt;"; break;
1323         case '>':  m_t << "&gt;"; break;
1324         case '&':  m_t << "&amp;"; break;
1325         case '"':  m_t << "&quot;"; break;
1326         case '\\':
1327                    if (*p=='<')
1328                      { m_t << "&lt;"; p++; }
1329                    else if (*p=='>')
1330                      { m_t << "&gt;"; p++; }
1331                    else
1332                      m_t << "\\";
1333                    break;
1334         default:   m_t << c; 
1335       }
1336     }
1337   }
1338 }
1339
1340 void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
1341                                     const char *anchor,int l)
1342 {
1343   if (!m_streamSet) return;
1344   QCString lineNumber,lineAnchor;
1345   lineNumber.sprintf("%5d",l);
1346   lineAnchor.sprintf("l%05d",l);
1347
1348   m_t << "<div class=\"line\">";
1349   m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">"; 
1350   if (filename)
1351   {
1352     _writeCodeLink("line",ref,filename,anchor,lineNumber,0);
1353   }
1354   else
1355   {
1356     codify(lineNumber);
1357   }
1358   m_t << "</span>"; 
1359   m_t << "&#160;";
1360 }
1361
1362 void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f,
1363                                       const char *anchor, const char *name,
1364                                       const char *tooltip)
1365 {
1366   if (!m_streamSet) return;
1367   //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip);
1368   _writeCodeLink("code",ref,f,anchor,name,tooltip);
1369 }
1370
1371 void HtmlCodeGenerator::_writeCodeLink(const char *className,
1372                                       const char *ref,const char *f,
1373                                       const char *anchor, const char *name,
1374                                       const char *tooltip)
1375 {
1376   if (ref) 
1377   {
1378     m_t << "<a class=\"" << className << "Ref\" ";
1379     m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
1380   }
1381   else
1382   {
1383     m_t << "<a class=\"" << className << "\" ";
1384   }
1385   m_t << "href=\"";
1386   m_t << externalRef(m_relPath,ref,TRUE);
1387   if (f) m_t << f << Doxygen::htmlFileExtension;
1388   if (anchor) m_t << "#" << anchor;
1389   m_t << "\"";
1390   if (tooltip) m_t << " title=\"" << tooltip << "\"";
1391   m_t << ">";
1392   docify(name);
1393   m_t << "</a>";
1394   m_col+=qstrlen(name);
1395 }
1396
1397 void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo,
1398                                      const char *decl, const char *desc,
1399                                      const SourceLinkInfo &defInfo,
1400                                      const SourceLinkInfo &declInfo)
1401 {
1402   m_t << "<div class=\"ttc\" id=\"" << id << "\">";
1403   m_t << "<div class=\"ttname\">";
1404   if (!docInfo.url.isEmpty())
1405   {
1406     m_t << "<a href=\"";
1407     m_t << externalRef(m_relPath,docInfo.ref,TRUE);
1408     m_t << docInfo.url << Doxygen::htmlFileExtension;
1409     if (!docInfo.anchor.isEmpty())
1410     {
1411       m_t << "#" << docInfo.anchor;
1412     }
1413     m_t << "\">";
1414   }
1415   docify(docInfo.name);
1416   if (!docInfo.url.isEmpty())
1417   {
1418     m_t << "</a>";
1419   }
1420   m_t << "</div>";
1421   if (decl)
1422   {
1423     m_t << "<div class=\"ttdeci\">";
1424     docify(decl);
1425     m_t << "</div>";
1426   }
1427   if (desc)
1428   {
1429     m_t << "<div class=\"ttdoc\">";
1430     m_t << desc; // desc is already HTML escaped
1431     m_t << "</div>";
1432   }
1433   if (!defInfo.file.isEmpty())
1434   {
1435     m_t << "<div class=\"ttdef\"><b>Definition:</b> ";
1436     if (!defInfo.url.isEmpty())
1437     {
1438       m_t << "<a href=\"";
1439       m_t << externalRef(m_relPath,defInfo.ref,TRUE);
1440       m_t << defInfo.url << Doxygen::htmlFileExtension;
1441       if (!defInfo.anchor.isEmpty())
1442       {
1443         m_t << "#" << defInfo.anchor;
1444       }
1445       m_t << "\">";
1446     }
1447     m_t << defInfo.file << ":" << defInfo.line;
1448     if (!defInfo.url.isEmpty())
1449     {
1450       m_t << "</a>";
1451     }
1452     m_t << "</div>";
1453   }
1454   if (!declInfo.file.isEmpty())
1455   {
1456     m_t << "<div class=\"ttdecl\"><b>Declaration:</b> ";
1457     if (!declInfo.url.isEmpty())
1458     {
1459       m_t << "<a href=\"";
1460       m_t << externalRef(m_relPath,declInfo.ref,TRUE);
1461       m_t << declInfo.url << Doxygen::htmlFileExtension;
1462       if (!declInfo.anchor.isEmpty())
1463       {
1464         m_t << "#" << declInfo.anchor;
1465       }
1466       m_t << "\">";
1467     }
1468     m_t << declInfo.file << ":" << declInfo.line;
1469     if (!declInfo.url.isEmpty())
1470     {
1471       m_t << "</a>";
1472     }
1473     m_t << "</div>";
1474   }
1475   m_t << "</div>" << endl;
1476 }
1477
1478
1479 void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers) 
1480
1481   if (m_streamSet)
1482   {
1483     if (!hasLineNumbers) m_t << "<div class=\"line\">";
1484     m_col=0; 
1485   }
1486 }
1487
1488 void HtmlCodeGenerator::endCodeLine() 
1489
1490   if (m_streamSet) m_t << "</div>\n";
1491 }
1492
1493 void HtmlCodeGenerator::startFontClass(const char *s) 
1494
1495   if (m_streamSet) m_t << "<span class=\"" << s << "\">"; 
1496 }
1497
1498 void HtmlCodeGenerator::endFontClass() 
1499
1500   if (m_streamSet) m_t << "</span>"; 
1501 }
1502
1503 void HtmlCodeGenerator::writeCodeAnchor(const char *anchor) 
1504
1505   if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>"; 
1506 }
1507
1508 //--------------------------------------------------------------------------
1509
1510 HtmlGenerator::HtmlGenerator() : OutputGenerator()
1511 {
1512   dir=Config_getString("HTML_OUTPUT");
1513   m_emptySection=FALSE;
1514 }
1515
1516 HtmlGenerator::~HtmlGenerator()
1517 {
1518   //printf("HtmlGenerator::~HtmlGenerator()\n");
1519 }
1520
1521 void HtmlGenerator::init()
1522 {
1523   QCString dname=Config_getString("HTML_OUTPUT");
1524   QDir d(dname);
1525   if (!d.exists() && !d.mkdir(dname))
1526   {
1527     err("Could not create output directory %s\n",dname.data());
1528     exit(1);
1529   }
1530   //writeLogo(dname);
1531   if (!Config_getString("HTML_HEADER").isEmpty()) 
1532   {
1533     g_header=fileToString(Config_getString("HTML_HEADER"));
1534     //printf("g_header='%s'\n",g_header.data());
1535   }
1536   else 
1537   {
1538     g_header = defaultHtmlHeader;
1539   }
1540
1541   if (!Config_getString("HTML_FOOTER").isEmpty()) 
1542   {
1543     g_footer=fileToString(Config_getString("HTML_FOOTER"));
1544     //printf("g_footer='%s'\n",g_footer.data());
1545   }
1546   else 
1547   {
1548     g_footer = defaultHtmlFooter;
1549   }
1550
1551   if (Config_getBool("USE_MATHJAX"))
1552   {
1553     if (!Config_getString("MATHJAX_CODEFILE").isEmpty()) 
1554     {
1555       g_mathjax_code=fileToString(Config_getString("MATHJAX_CODEFILE"));
1556       //printf("g_mathjax_code='%s'\n",g_mathjax_code.data());
1557     }
1558   }
1559   createSubDirs(d);
1560
1561   QCString fileName=dname+"/tabs.css";
1562   QFile f(fileName);
1563   if (f.open(IO_WriteOnly))
1564   {
1565     FTextStream t(&f);
1566     t << replaceColorMarkers(tabs_css);
1567   }
1568   else
1569   {
1570     fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
1571   }
1572
1573   {
1574     QFile f(dname+"/jquery.js");
1575     if (f.open(IO_WriteOnly))
1576     {
1577       FTextStream t(&f);
1578       t << search_jquery_script1 << search_jquery_script2 << search_jquery_script3;
1579       if (Config_getBool("GENERATE_TREEVIEW"))
1580       {
1581         t << search_jquery_script4 << search_jquery_script5;
1582       }
1583       if (Config_getBool("SOURCE_BROWSER"))
1584       {
1585         t << search_jquery_script6;
1586       }
1587     }
1588   }
1589
1590   if (Config_getBool("INTERACTIVE_SVG"))
1591   {
1592     QFile f(dname+"/svgpan.js");
1593     if (f.open(IO_WriteOnly))
1594     {
1595       FTextStream t(&f);
1596       t << svgpan_script;
1597     }
1598   }
1599
1600   {
1601     QFile f(dname+"/dynsections.js");
1602     if (f.open(IO_WriteOnly))
1603     {
1604       FTextStream t(&f);
1605       t << dynsections_script;
1606       if (Config_getBool("SOURCE_BROWSER") && Config_getBool("SOURCE_TOOLTIPS"))
1607       {
1608         t << endl << 
1609           "$(document).ready(function() {\n"
1610           "  $('.code,.codeRef').each(function() {\n"
1611           "    $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
1612           "    $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
1613           "  });\n"
1614           "});\n";
1615       }
1616     }
1617   }
1618 }
1619
1620 /// Additional initialization after indices have been created
1621 void HtmlGenerator::writeTabData()
1622 {
1623   Doxygen::indexList->addStyleSheetFile("tabs.css");
1624   QCString dname=Config_getString("HTML_OUTPUT");
1625   writeColoredImgData(dname,colored_tab_data);
1626
1627   {
1628     unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 };
1629     unsigned char shadow_alpha[6]  = { 80, 60, 40, 20, 10, 0 };
1630     ColoredImage img(1,6,shadow,shadow_alpha,0,0,100);
1631     img.save(dname+"/nav_g.png");
1632   }
1633 }
1634
1635 void HtmlGenerator::writeSearchData(const char *dir)
1636 {
1637   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
1638   writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data);
1639   QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
1640   QFile f(searchDirName+"/search.css");
1641   if (f.open(IO_WriteOnly))
1642   {
1643     FTextStream t(&f);
1644     QCString searchCss = replaceColorMarkers(search_styleSheet);
1645     searchCss = substitute(searchCss,"$doxygenversion",versionString);
1646     if (Config_getBool("DISABLE_INDEX"))
1647     {
1648       // move up the search box if there are no tabs
1649       searchCss = substitute(searchCss,"margin-top: 8px;","margin-top: 0px;");
1650     }
1651     t << searchCss;
1652   }
1653   Doxygen::indexList->addStyleSheetFile("search/search.css");
1654 }
1655
1656 void HtmlGenerator::writeStyleSheetFile(QFile &file)
1657 {
1658   FTextStream t(&file);
1659   t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
1660 }
1661
1662 void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/)
1663 {
1664   FTextStream t(&file);
1665   t << "<!-- HTML header for doxygen " << versionString << "-->" << endl;
1666   QCString contents(defaultHtmlHeader);
1667   t << contents;
1668 }
1669
1670 void HtmlGenerator::writeFooterFile(QFile &file)
1671 {
1672   FTextStream t(&file);
1673   t << "<!-- HTML footer for doxygen " << versionString << "-->" <<  endl;
1674   QCString contents(defaultHtmlFooter);
1675   t << contents;
1676 }
1677
1678 void HtmlGenerator::startFile(const char *name,const char *,
1679                               const char *title)
1680 {
1681   //printf("HtmlGenerator::startFile(%s)\n",name);
1682   QCString fileName=name;
1683   lastTitle=title;
1684   relPath = relativePathToRoot(fileName);
1685
1686   if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension) 
1687   {
1688     fileName+=Doxygen::htmlFileExtension;
1689   }
1690   startPlainFile(fileName);
1691   m_codeGen.setTextStream(t);
1692   m_codeGen.setRelativePath(relPath);
1693   Doxygen::indexList->addIndexFile(fileName);
1694   
1695   lastFile = fileName;
1696   t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath);
1697
1698   t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
1699     << versionString << " -->" << endl;
1700   //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1701   static bool searchEngine = Config_getBool("SEARCHENGINE");
1702   if (searchEngine /*&& !generateTreeView*/)
1703   {
1704     t << "<script type=\"text/javascript\">\n";
1705     t << "var searchBox = new SearchBox(\"searchBox\", \""
1706       << relPath<< "search\",false,'" << theTranslator->trSearch() << "');\n";
1707     t << "</script>\n";
1708   }
1709   //generateDynamicSections(t,relPath);
1710   m_sectionCount=0;
1711 }
1712
1713 void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath)
1714 {
1715   static bool searchEngine      = Config_getBool("SEARCHENGINE");
1716   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
1717   if (searchEngine && !serverBasedSearch)
1718   {
1719     (void)relPath;
1720     t << "<!-- window showing the filter options -->\n";
1721     t << "<div id=\"MSearchSelectWindow\"\n";
1722     t << "     onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
1723     t << "     onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
1724     t << "     onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
1725     writeSearchCategories(t);
1726     t << "</div>\n";
1727     t << "\n";
1728     t << "<!-- iframe showing the search results (closed by default) -->\n";
1729     t << "<div id=\"MSearchResultsWindow\">\n";
1730     t << "<iframe src=\"javascript:void(0)\" frameborder=\"0\" \n";
1731     t << "        name=\"MSearchResults\" id=\"MSearchResults\">\n";
1732     t << "</iframe>\n";
1733     t << "</div>\n";
1734     t << "\n";
1735   }
1736 }
1737
1738 void HtmlGenerator::writeSearchInfo()
1739 {
1740   writeSearchInfo(t,relPath);
1741 }
1742
1743
1744 QCString HtmlGenerator::writeLogoAsString(const char *path)
1745 {
1746   static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
1747   QCString result;
1748   if (timeStamp)
1749   {
1750     result += theTranslator->trGeneratedAt(
1751                dateToString(TRUE),
1752                Config_getString("PROJECT_NAME")
1753               );
1754   }
1755   else
1756   {
1757     result += theTranslator->trGeneratedBy();
1758   }
1759   result += "&#160;\n<a href=\"http://www.doxygen.org/index.html\">\n"
1760             "<img class=\"footer\" src=\"";
1761   result += path;
1762   result += "doxygen.png\" alt=\"doxygen\"/></a> ";
1763   result += versionString;
1764   result += " ";
1765   return result;
1766 }
1767
1768 void HtmlGenerator::writeLogo()
1769 {
1770   t << writeLogoAsString(relPath);
1771 }
1772
1773 void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle,
1774                               const QCString &relPath,const QCString &navPath)
1775 {
1776   t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
1777 }
1778
1779 void HtmlGenerator::writeFooter(const char *navPath)
1780 {
1781   writePageFooter(t,lastTitle,relPath,navPath);
1782 }
1783
1784 void HtmlGenerator::endFile()
1785 {
1786   endPlainFile();
1787 }
1788
1789 void HtmlGenerator::startProjectNumber()
1790 {
1791   t << "<h3 class=\"version\">";
1792 }
1793
1794 void HtmlGenerator::endProjectNumber()
1795 {
1796   t << "</h3>";
1797 }
1798
1799 void HtmlGenerator::writeStyleInfo(int part)
1800 {
1801   //printf("writeStyleInfo(%d)\n",part);
1802   if (part==0)
1803   {
1804     if (Config_getString("HTML_STYLESHEET").isEmpty()) // write default style sheet
1805     {
1806       //printf("write doxygen.css\n");
1807       startPlainFile("doxygen.css"); 
1808       
1809       // alternative, cooler looking titles
1810       //t << "H1 { text-align: center; border-width: thin none thin none;" << endl;
1811       //t << "     border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl;
1812
1813       t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
1814       endPlainFile();
1815       Doxygen::indexList->addStyleSheetFile("doxygen.css");
1816     }
1817     else // write user defined style sheet
1818     {
1819       QCString cssname=Config_getString("HTML_STYLESHEET");
1820       QFileInfo cssfi(cssname);
1821       if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
1822       {
1823         err("style sheet %s does not exist or is not readable!", Config_getString("HTML_STYLESHEET").data());
1824       }
1825       else
1826       {
1827         // convert style sheet to string
1828         QCString fileStr = fileToString(cssname);
1829         // write the string into the output dir
1830         startPlainFile(cssfi.fileName().utf8());
1831         t << fileStr;
1832         endPlainFile();
1833       }
1834       Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
1835     }
1836     static QStrList extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET");
1837     for (uint i=0; i<extraCssFile.count(); ++i)
1838     {
1839       QCString fileName(extraCssFile.at(i));
1840       if (!fileName.isEmpty())
1841       {
1842         QFileInfo fi(fileName);
1843         if (fi.exists())
1844         {
1845           Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8());
1846         }
1847       }
1848     }
1849   }
1850 }
1851
1852 void HtmlGenerator::startDoxyAnchor(const char *,const char *,
1853                                     const char *anchor, const char *,
1854                                     const char *)
1855 {
1856   t << "<a class=\"anchor\" id=\"" << anchor << "\"></a>";
1857 }
1858
1859 void HtmlGenerator::endDoxyAnchor(const char *,const char *)
1860 {
1861 }
1862
1863 //void HtmlGenerator::newParagraph()
1864 //{
1865 //  t << endl << "<p>" << endl;
1866 //}
1867
1868 void HtmlGenerator::startParagraph()
1869 {
1870   t << endl << "<p>";
1871 }
1872
1873 void HtmlGenerator::endParagraph()
1874 {
1875   t << "</p>" << endl;
1876 }
1877
1878 void HtmlGenerator::writeString(const char *text)
1879 {
1880   t << text;
1881 }
1882
1883 void HtmlGenerator::startIndexListItem()
1884 {
1885   t << "<li>";
1886 }
1887
1888 void HtmlGenerator::endIndexListItem()
1889 {
1890   t << "</li>" << endl;
1891 }
1892
1893 void HtmlGenerator::startIndexItem(const char *ref,const char *f)
1894 {
1895   //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
1896   if (ref || f)
1897   {
1898     if (ref) 
1899     {
1900       t << "<a class=\"elRef\" ";
1901       t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1902     }
1903     else
1904     {
1905       t << "<a class=\"el\" ";
1906     }
1907     t << "href=\"";
1908     t << externalRef(relPath,ref,TRUE);
1909     if (f) t << f << Doxygen::htmlFileExtension << "\">";
1910   }
1911   else
1912   {
1913     t << "<b>";
1914   }
1915 }
1916
1917 void HtmlGenerator::endIndexItem(const char *ref,const char *f)
1918 {
1919   //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
1920   if (ref || f)
1921   {
1922     t << "</a>";
1923   }
1924   else
1925   {
1926     t << "</b>";
1927   }
1928 }
1929
1930 void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
1931                                        const char *path,const char *name)
1932 {
1933   t << "<li>";
1934   if (path) docify(path);
1935   t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
1936   docify(name);
1937   t << "</a> ";
1938 }
1939
1940 void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
1941                                     const char *anchor, const char *name)
1942 {
1943   if (ref) 
1944   {
1945     t << "<a class=\"elRef\" ";
1946     t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1947   }
1948   else
1949   {
1950     t << "<a class=\"el\" ";
1951   }
1952   t << "href=\"";
1953   t << externalRef(relPath,ref,TRUE);
1954   if (f) t << f << Doxygen::htmlFileExtension;
1955   if (anchor) t << "#" << anchor;
1956   t << "\">";
1957   docify(name);
1958   t << "</a>";
1959 }
1960
1961 void HtmlGenerator::startTextLink(const char *f,const char *anchor)
1962 {
1963   t << "<a href=\"";
1964   if (f)   t << relPath << f << Doxygen::htmlFileExtension;
1965   if (anchor) t << "#" << anchor;
1966   t << "\">"; 
1967 }
1968
1969 void HtmlGenerator::endTextLink()
1970 {
1971   t << "</a>";
1972 }
1973
1974 void HtmlGenerator::startHtmlLink(const char *url)
1975 {
1976   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1977   t << "<a ";
1978   if (generateTreeView) t << "target=\"top\" ";
1979   t << "href=\"";
1980   if (url) t << url;
1981   t << "\">"; 
1982 }
1983
1984 void HtmlGenerator::endHtmlLink()
1985 {
1986   t << "</a>";
1987 }
1988
1989 void HtmlGenerator::startGroupHeader(int extraIndentLevel)
1990 {
1991   if (extraIndentLevel==2)
1992   {
1993     t << "<h4 class=\"groupheader\">";
1994   }
1995   else if (extraIndentLevel==1)
1996   {
1997     t << "<h3 class=\"groupheader\">";
1998   }
1999   else // extraIndentLevel==0
2000   {
2001     t << "<h2 class=\"groupheader\">";
2002   }
2003 }
2004
2005 void HtmlGenerator::endGroupHeader(int extraIndentLevel)
2006 {
2007   if (extraIndentLevel==2)
2008   {
2009     t << "</h4>" << endl;
2010   }
2011   else if (extraIndentLevel==1)
2012   {
2013     t << "</h3>" << endl;
2014   }
2015   else
2016   {
2017     t << "</h2>" << endl;
2018   }
2019 }
2020
2021 void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
2022 {
2023   switch(type)
2024   {
2025     case SectionInfo::Page:          t << "\n\n<h1>"; break;
2026     case SectionInfo::Section:       t << "\n\n<h2>"; break;
2027     case SectionInfo::Subsection:    t << "\n\n<h3>"; break;
2028     case SectionInfo::Subsubsection: t << "\n\n<h4>"; break;
2029     case SectionInfo::Paragraph:     t << "\n\n<h5>"; break;
2030     default: ASSERT(0); break;
2031   }
2032   t << "<a class=\"anchor\" id=\"" << lab << "\"></a>";
2033 }
2034
2035 void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
2036 {
2037   switch(type)
2038   {
2039     case SectionInfo::Page:          t << "</h1>"; break;
2040     case SectionInfo::Section:       t << "</h2>"; break;
2041     case SectionInfo::Subsection:    t << "</h3>"; break;
2042     case SectionInfo::Subsubsection: t << "</h4>"; break;
2043     case SectionInfo::Paragraph:     t << "</h5>"; break;
2044     default: ASSERT(0); break;
2045   }
2046 }
2047
2048 void HtmlGenerator::docify(const char *str)
2049 {
2050   docify(str,FALSE);
2051 }
2052
2053 void HtmlGenerator::docify(const char *str,bool inHtmlComment)
2054 {
2055   if (str)
2056   {
2057     const char *p=str;
2058     char c;
2059     while (*p)
2060     {
2061       c=*p++;
2062       switch(c)
2063       {
2064         case '<':  t << "&lt;"; break;
2065         case '>':  t << "&gt;"; break;
2066         case '&':  t << "&amp;"; break;
2067         case '"':  t << "&quot;"; break;
2068         case '-':  if (inHtmlComment) t << "&#45;"; else t << "-"; break;
2069         case '\\':
2070                    if (*p=='<')
2071                      { t << "&lt;"; p++; }
2072                    else if (*p=='>')
2073                      { t << "&gt;"; p++; }
2074                    else
2075                      t << "\\";
2076                    break;
2077         default:   t << c; 
2078       }
2079     }
2080   }
2081 }
2082
2083 void HtmlGenerator::writeChar(char c)
2084 {
2085   char cs[2];
2086   cs[0]=c;
2087   cs[1]=0;
2088   docify(cs);
2089 }
2090
2091 //--- helper function for dynamic sections -------------------------
2092
2093 static void startSectionHeader(FTextStream &t,
2094                                const QCString &relPath,int sectionCount)
2095 {
2096   //t << "<!-- startSectionHeader -->";
2097   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2098   if (dynamicSections)
2099   {
2100     t << "<div id=\"dynsection-" << sectionCount << "\" "
2101          "onclick=\"return toggleVisibility(this)\" "
2102          "class=\"dynheader closed\" "
2103          "style=\"cursor:pointer;\">" << endl;
2104     t << "  <img id=\"dynsection-" << sectionCount << "-trigger\" src=\"" 
2105       << relPath << "closed.png\" alt=\"+\"/> ";
2106   }
2107   else
2108   {
2109     t << "<div class=\"dynheader\">" << endl;
2110   }
2111 }
2112
2113 static void endSectionHeader(FTextStream &t)
2114 {
2115   //t << "<!-- endSectionHeader -->";
2116   t << "</div>" << endl;
2117 }
2118
2119 static void startSectionSummary(FTextStream &t,int sectionCount)
2120 {
2121   //t << "<!-- startSectionSummary -->";
2122   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2123   if (dynamicSections)
2124   {
2125     t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
2126          "class=\"dynsummary\" "
2127          "style=\"display:block;\">" << endl;
2128   }
2129 }
2130
2131 static void endSectionSummary(FTextStream &t)
2132 {
2133   //t << "<!-- endSectionSummary -->";
2134   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2135   if (dynamicSections)
2136   {
2137     t << "</div>" << endl;
2138   }
2139 }
2140
2141 static void startSectionContent(FTextStream &t,int sectionCount)
2142 {
2143   //t << "<!-- startSectionContent -->";
2144   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2145   if (dynamicSections)
2146   {
2147     t << "<div id=\"dynsection-" << sectionCount << "-content\" "
2148          "class=\"dyncontent\" "
2149          "style=\"display:none;\">" << endl;
2150   }
2151   else
2152   {
2153     t << "<div class=\"dyncontent\">" << endl;
2154   }
2155 }
2156
2157 static void endSectionContent(FTextStream &t)
2158 {
2159   //t << "<!-- endSectionContent -->";
2160   t << "</div>" << endl;
2161 }
2162
2163 //----------------------------
2164
2165 void HtmlGenerator::startClassDiagram()
2166 {
2167   startSectionHeader(t,relPath,m_sectionCount);
2168 }
2169
2170 void HtmlGenerator::endClassDiagram(const ClassDiagram &d,
2171                                 const char *fileName,const char *name)
2172 {
2173   endSectionHeader(t);
2174   startSectionSummary(t,m_sectionCount);
2175   endSectionSummary(t);
2176   startSectionContent(t,m_sectionCount);
2177   t << " <div class=\"center\">" << endl;
2178   t << "  <img src=\"";
2179   t << relPath << fileName << ".png\" usemap=\"#";
2180   docify(name);
2181   t << "_map\" alt=\"\"/>" << endl;
2182   t << "  <map id=\"";
2183   docify(name);
2184   t << "_map\" name=\"";
2185   docify(name);
2186   t << "_map\">" << endl;
2187
2188   d.writeImage(t,dir,relPath,fileName);
2189   t << " </div>";
2190   endSectionContent(t);
2191   m_sectionCount++;
2192 }
2193
2194
2195 void HtmlGenerator::startMemberList()  
2196
2197   DBG_HTML(t << "<!-- startMemberList -->" << endl)
2198 }
2199
2200 void HtmlGenerator::endMemberList()    
2201
2202   DBG_HTML(t << "<!-- endMemberList -->" << endl)
2203 }
2204
2205 // anonymous type:
2206 //  0 = single column right aligned
2207 //  1 = double column left aligned
2208 //  2 = single column left aligned
2209 void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId) 
2210
2211   DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
2212   if (m_emptySection)
2213   {
2214     t << "<table class=\"memberdecls\">" << endl;
2215     m_emptySection=FALSE;
2216   }
2217   t << "<tr class=\"memitem:" << anchor;
2218   if (inheritId)
2219   {
2220     t << " inherit " << inheritId;
2221   }
2222   t << "\">";
2223   switch(annoType)
2224   {
2225     case 0:  t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
2226     case 1:  t << "<td class=\"memItemLeft\" >"; break;
2227     case 2:  t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
2228     default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
2229   }
2230 }
2231
2232 void HtmlGenerator::endMemberItem() 
2233
2234   t << "</td></tr>"; 
2235   t << endl; 
2236 }
2237
2238 void HtmlGenerator::startMemberTemplateParams()
2239 {
2240 }
2241
2242 void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId)
2243 {
2244   t << "</td></tr>" << endl;
2245   t << "<tr class=\"memitem:" << anchor;
2246   if (inheritId)
2247   {
2248     t << " inherit " << inheritId;
2249   }
2250   t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
2251 }
2252
2253
2254 void HtmlGenerator::insertMemberAlign(bool templ) 
2255
2256   DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
2257   QCString className = templ ? "memTemplItemRight" : "memItemRight";
2258   t << "&#160;</td><td class=\"" << className << "\" valign=\"bottom\">"; 
2259 }
2260
2261 void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId) 
2262
2263   DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
2264     if (m_emptySection)
2265     {
2266       t << "<table class=\"memberdecls\">" << endl;
2267       m_emptySection=FALSE;
2268     }
2269   t << "<tr class=\"memdesc:" << anchor;
2270   if (inheritId)
2271   {
2272     t << " inherit " << inheritId;
2273   }
2274   t << "\"><td class=\"mdescLeft\">&#160;</td><td class=\"mdescRight\">"; 
2275 }
2276
2277 void HtmlGenerator::endMemberDescription()   
2278
2279   DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
2280   t << "<br /></td></tr>" << endl; 
2281 }
2282
2283 void HtmlGenerator::startMemberSections()
2284 {
2285   DBG_HTML(t << "<!-- startMemberSections -->" << endl)
2286   m_emptySection=TRUE; // we postpone writing <table> until we actually
2287                        // write a row to prevent empty tables, which 
2288                        // are not valid XHTML!
2289 }
2290
2291 void HtmlGenerator::endMemberSections()
2292 {
2293   DBG_HTML(t << "<!-- endMemberSections -->" << endl)
2294   if (!m_emptySection)
2295   {
2296     t << "</table>" << endl;
2297   }
2298 }
2299
2300 void HtmlGenerator::startMemberHeader(const char *anchor)
2301 {
2302   DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
2303   if (!m_emptySection)
2304   {
2305     t << "</table>";
2306     m_emptySection=TRUE;
2307   }
2308   if (m_emptySection)
2309   {
2310     t << "<table class=\"memberdecls\">" << endl;
2311     m_emptySection=FALSE;
2312   }
2313   t << "<tr class=\"heading\"><td colspan=\"2\"><h2 class=\"groupheader\">";
2314   if (anchor)
2315   {
2316     t << "<a name=\"" << anchor << "\"></a>" << endl;
2317   }
2318 }
2319
2320 void HtmlGenerator::endMemberHeader()
2321 {
2322   DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
2323   t << "</h2></td></tr>" << endl;
2324 }
2325
2326 void HtmlGenerator::startMemberSubtitle()
2327 {
2328   DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
2329   t << "<tr><td class=\"ititle\" colspan=\"2\">";
2330 }
2331
2332 void HtmlGenerator::endMemberSubtitle()
2333 {
2334   DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
2335   t << "</td></tr>" << endl;
2336 }
2337
2338 void HtmlGenerator::startIndexList() 
2339
2340   t << "<table>"  << endl; 
2341 }
2342
2343 void HtmlGenerator::endIndexList()
2344 {
2345   t << "</table>" << endl;
2346 }
2347
2348 void HtmlGenerator::startIndexKey() 
2349
2350   // inserted 'class = ...', 02 jan 2002, jh
2351   t << "  <tr><td class=\"indexkey\">"; 
2352 }
2353
2354 void HtmlGenerator::endIndexKey()
2355 {
2356   t << "</td>";
2357 }
2358
2359 void HtmlGenerator::startIndexValue(bool) 
2360
2361   // inserted 'class = ...', 02 jan 2002, jh
2362   t << "<td class=\"indexvalue\">"; 
2363 }
2364
2365 void HtmlGenerator::endIndexValue(const char *,bool)
2366 {
2367   t << "</td></tr>" << endl;
2368 }
2369
2370 void HtmlGenerator::startMemberDocList()
2371 {
2372   DBG_HTML(t << "<!-- startMemberDocList -->" << endl;)
2373 }
2374
2375 void HtmlGenerator::endMemberDocList()
2376 {
2377   DBG_HTML(t << "<!-- endMemberDocList -->" << endl;)
2378 }
2379
2380 void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *,bool) 
2381
2382   DBG_HTML(t << "<!-- startMemberDoc -->" << endl;)
2383  
2384   t << "\n<div class=\"memitem\">" << endl;
2385   t << "<div class=\"memproto\">" << endl;
2386 }
2387
2388 void HtmlGenerator::startMemberDocPrefixItem()
2389 {
2390   DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;)
2391   t << "<div class=\"memtemplate\">" << endl;
2392 }
2393
2394 void HtmlGenerator::endMemberDocPrefixItem()
2395 {
2396   DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;)
2397   t << "</div>" << endl;
2398 }
2399
2400 void HtmlGenerator::startMemberDocName(bool /*align*/)
2401 {
2402   DBG_HTML(t << "<!-- startMemberDocName -->" << endl;)
2403
2404   t << "      <table class=\"memname\">" << endl;
2405     
2406   t << "        <tr>" << endl;
2407   t << "          <td class=\"memname\">";
2408 }
2409
2410 void HtmlGenerator::endMemberDocName()
2411 {
2412   DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
2413   t << "</td>" << endl;
2414 }
2415
2416 void HtmlGenerator::startParameterList(bool openBracket)
2417 {
2418   DBG_HTML(t << "<!-- startParameterList -->" << endl;)
2419   t << "          <td>";
2420   if (openBracket) t << "(";
2421   t << "</td>" << endl;
2422 }
2423
2424 void HtmlGenerator::startParameterType(bool first,const char *key)
2425 {
2426   if (first)
2427   {
2428     DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
2429     t << "          <td class=\"paramtype\">";
2430   }
2431   else
2432   {
2433     DBG_HTML(t << "<!-- startParameterType -->" << endl;)
2434     t << "        <tr>" << endl;
2435     t << "          <td class=\"paramkey\">";
2436     if (key) t << key;
2437     t << "</td>" << endl;
2438     t << "          <td></td>" << endl;
2439     t << "          <td class=\"paramtype\">";
2440   }
2441 }
2442
2443 void HtmlGenerator::endParameterType()
2444 {
2445   DBG_HTML(t << "<!-- endParameterType -->" << endl;)
2446   t << "&#160;</td>" << endl;
2447 }
2448
2449 void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
2450 {
2451   DBG_HTML(t << "<!-- startParameterName -->" << endl;)
2452   t << "          <td class=\"paramname\">";
2453 }
2454
2455 void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
2456 {
2457   DBG_HTML(t << "<!-- endParameterName -->" << endl;)
2458   if (last)
2459   {
2460     if (emptyList)
2461     {
2462       if (closeBracket) t << "</td><td>)";
2463       t << "</td>" << endl;
2464       t << "          <td>";
2465     }
2466     else
2467     {
2468       t << "&#160;</td>" << endl;
2469       t << "        </tr>" << endl;
2470       t << "        <tr>" << endl;
2471       t << "          <td></td>" << endl;
2472       t << "          <td>";
2473       if (closeBracket) t << ")";
2474       t << "</td>" << endl;
2475       t << "          <td></td><td>";
2476     }
2477   }
2478   else
2479   {
2480     t << "</td>" << endl;
2481     t << "        </tr>" << endl;
2482   }
2483 }
2484
2485 void HtmlGenerator::endParameterList()
2486 {
2487   DBG_HTML(t << "<!-- endParameterList -->" << endl;)
2488   t << "</td>" << endl;
2489   t << "        </tr>" << endl;
2490 }
2491
2492 void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket)
2493 {
2494   DBG_HTML(t << "<!-- exceptionEntry -->" << endl;)
2495   t << "</td>" << endl;
2496   t << "        </tr>" << endl;
2497   t << "        <tr>" << endl;
2498   t << "          <td align=\"right\">";
2499   // colspan 2 so it gets both parameter type and parameter name columns
2500   if (prefix)
2501     t << prefix << "</td><td>(</td><td colspan=\"2\">";
2502   else if (closeBracket)
2503     t << "</td><td>)</td><td></td><td>";
2504   else
2505     t << "</td><td></td><td colspan=\"2\">";
2506 }
2507
2508 void HtmlGenerator::endMemberDoc(bool hasArgs)     
2509
2510   DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
2511   if (!hasArgs)
2512   {
2513     t << "        </tr>" << endl;
2514   }
2515   t << "      </table>" << endl;
2516  // t << "</div>" << endl;
2517 }
2518
2519 void HtmlGenerator::startDotGraph()
2520 {
2521   startSectionHeader(t,relPath,m_sectionCount);
2522 }
2523
2524 void HtmlGenerator::endDotGraph(const DotClassGraph &g)
2525 {
2526   bool generateLegend = Config_getBool("GENERATE_LEGEND");
2527   bool umlLook = Config_getBool("UML_LOOK");
2528   endSectionHeader(t);
2529   startSectionSummary(t,m_sectionCount);
2530   endSectionSummary(t);
2531   startSectionContent(t,m_sectionCount);
2532
2533   g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,TRUE,m_sectionCount);
2534   if (generateLegend && !umlLook)
2535   {
2536     t << "<center><span class=\"legend\">[";
2537     startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
2538     t << theTranslator->trLegend();
2539     endHtmlLink();
2540     t << "]</span></center>";
2541   }
2542
2543   endSectionContent(t);
2544   m_sectionCount++;
2545 }
2546
2547 void HtmlGenerator::startInclDepGraph()
2548 {
2549   startSectionHeader(t,relPath,m_sectionCount);
2550 }
2551
2552 void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g)
2553 {
2554   endSectionHeader(t);
2555   startSectionSummary(t,m_sectionCount);
2556   endSectionSummary(t);
2557   startSectionContent(t,m_sectionCount);
2558
2559   g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
2560
2561   endSectionContent(t);
2562   m_sectionCount++;
2563 }
2564
2565 void HtmlGenerator::startGroupCollaboration()
2566 {
2567   startSectionHeader(t,relPath,m_sectionCount);
2568 }
2569
2570 void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
2571 {
2572   endSectionHeader(t);
2573   startSectionSummary(t,m_sectionCount);
2574   endSectionSummary(t);
2575   startSectionContent(t,m_sectionCount);
2576
2577   g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
2578
2579   endSectionContent(t);
2580   m_sectionCount++;
2581 }
2582
2583 void HtmlGenerator::startCallGraph()
2584 {
2585   startSectionHeader(t,relPath,m_sectionCount);
2586 }
2587
2588 void HtmlGenerator::endCallGraph(const DotCallGraph &g)
2589 {
2590   endSectionHeader(t);
2591   startSectionSummary(t,m_sectionCount);
2592   endSectionSummary(t);
2593   startSectionContent(t,m_sectionCount);
2594
2595   g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
2596
2597   endSectionContent(t);
2598   m_sectionCount++;
2599 }
2600
2601 void HtmlGenerator::startDirDepGraph()
2602 {
2603   startSectionHeader(t,relPath,m_sectionCount);
2604 }
2605
2606 void HtmlGenerator::endDirDepGraph(const DotDirDeps &g)
2607 {
2608   endSectionHeader(t);
2609   startSectionSummary(t,m_sectionCount);
2610   endSectionSummary(t);
2611   startSectionContent(t,m_sectionCount);
2612
2613   g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
2614
2615   endSectionContent(t);
2616   m_sectionCount++;
2617 }
2618
2619 void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
2620 {
2621   g.writeGraph(t,dir,fileName);
2622 }
2623
2624 void HtmlGenerator::startMemberGroupHeader(bool)
2625 {
2626   t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
2627 }
2628
2629 void HtmlGenerator::endMemberGroupHeader()
2630 {
2631   t << "</div></td></tr>" << endl;
2632 }
2633
2634 void HtmlGenerator::startMemberGroupDocs()
2635 {
2636   t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
2637 }
2638
2639 void HtmlGenerator::endMemberGroupDocs()
2640 {
2641   t << "</div></td></tr>" << endl;
2642 }
2643
2644 void HtmlGenerator::startMemberGroup()
2645 {
2646 }
2647
2648 void HtmlGenerator::endMemberGroup(bool)
2649 {
2650 }
2651
2652 void HtmlGenerator::startIndent()        
2653
2654   DBG_HTML(t << "<!-- startIndent -->" << endl;)
2655
2656   t << "<div class=\"memdoc\">\n";
2657 }
2658
2659 void HtmlGenerator::endIndent()          
2660
2661   DBG_HTML(t << "<!-- endIndent -->" << endl;)
2662   t << endl << "</div>" << endl << "</div>" << endl; 
2663 }
2664
2665 void HtmlGenerator::addIndexItem(const char *,const char *)
2666 {
2667 }
2668
2669 void HtmlGenerator::writeNonBreakableSpace(int n)
2670 {
2671   int i;
2672   for (i=0;i<n;i++)
2673   {
2674     t << "&#160;";
2675   }
2676 }
2677
2678 void HtmlGenerator::startSimpleSect(SectionTypes,
2679                                 const char *filename,const char *anchor,
2680                                 const char *title)
2681 {
2682   t << "<dl><dt><b>";
2683   if (filename)
2684   {
2685     writeObjectLink(0,filename,anchor,title);
2686   }
2687   else
2688   {
2689     docify(title);
2690   }
2691   t << "</b></dt>";
2692 }
2693
2694 void HtmlGenerator::endSimpleSect()
2695 {
2696   t << "</dl>"; 
2697 }
2698
2699 void HtmlGenerator::startParamList(ParamListTypes,
2700                                 const char *title)
2701 {
2702   t << "<dl><dt><b>";
2703   docify(title);
2704   t << "</b></dt>";
2705 }
2706
2707 void HtmlGenerator::endParamList()
2708 {
2709   t << "</dl>"; 
2710 }
2711
2712 void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
2713 {
2714   HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx);
2715   n->accept(visitor);
2716   delete visitor; 
2717 }
2718
2719 //---------------- helpers for index generation -----------------------------
2720
2721 static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE)
2722 {
2723   if (compact) 
2724   {
2725     if (topLevel)
2726     {
2727       t << "  <div id=\"navrow1\" class=\"tabs\">\n";
2728     }
2729     else
2730     {
2731       t << "  <div id=\"navrow2\" class=\"tabs2\">\n";
2732     }
2733     t << "    <ul class=\"tablist\">\n"; 
2734   }
2735   else 
2736   {
2737     t << "<ul>";
2738   }
2739 }
2740
2741 static void endQuickIndexList(FTextStream &t,bool compact)
2742 {
2743   if (compact) 
2744   {
2745     t << "    </ul>\n";
2746     t << "  </div>\n";
2747   }
2748   else 
2749   {
2750     t << "</ul>\n";
2751   }
2752 }
2753
2754 static void startQuickIndexItem(FTextStream &t,const char *l,
2755                                 bool hl,bool /*compact*/,
2756                                 const QCString &relPath)
2757 {
2758   t << "      <li"; 
2759   if (hl) 
2760   {
2761     t << " class=\"current\"";
2762   }
2763   t << ">";
2764   if (l) t << "<a href=\"" << correctURL(l,relPath) << "\">";
2765   t << "<span>";
2766 }
2767
2768 static void endQuickIndexItem(FTextStream &t,const char *l)
2769 {
2770   t << "</span>";
2771   if (l) t << "</a>";
2772   t << "</li>\n";
2773 }
2774
2775 static QCString fixSpaces(const QCString &s)
2776 {
2777   return substitute(s," ","&#160;");
2778 }
2779
2780 static bool quickLinkVisible(LayoutNavEntry::Kind kind)
2781 {
2782   static bool showFiles = Config_getBool("SHOW_FILES");
2783   static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
2784   switch (kind)
2785   {
2786     case LayoutNavEntry::MainPage:         return TRUE; 
2787     case LayoutNavEntry::User:             return TRUE;                                           
2788     case LayoutNavEntry::UserGroup:        return TRUE;                                           
2789     case LayoutNavEntry::Pages:            return indexedPages>0;
2790     case LayoutNavEntry::Modules:          return documentedGroups>0;
2791     case LayoutNavEntry::Namespaces:       return documentedNamespaces>0 && showNamespaces;
2792     case LayoutNavEntry::NamespaceList:    return documentedNamespaces>0 && showNamespaces;
2793     case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0;
2794     case LayoutNavEntry::Classes:          return annotatedClasses>0;
2795     case LayoutNavEntry::ClassList:        return annotatedClasses>0; 
2796     case LayoutNavEntry::ClassIndex:       return annotatedClasses>0; 
2797     case LayoutNavEntry::ClassHierarchy:   return hierarchyClasses>0;
2798     case LayoutNavEntry::ClassMembers:     return documentedClassMembers[CMHL_All]>0;
2799     case LayoutNavEntry::Files:            return documentedHtmlFiles>0 && showFiles;
2800     case LayoutNavEntry::FileList:         return documentedHtmlFiles>0 && showFiles;
2801     case LayoutNavEntry::FileGlobals:      return documentedFileMembers[FMHL_All]>0;
2802     //case LayoutNavEntry::Dirs:             return documentedDirs>0;
2803     case LayoutNavEntry::Examples:         return Doxygen::exampleSDict->count()>0;
2804   }
2805   return FALSE;
2806 }
2807
2808 static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root)
2809
2810 {
2811   QListIterator<LayoutNavEntry> li(root->children());
2812   LayoutNavEntry *entry;
2813   int count=0;
2814   for (li.toFirst();(entry=li.current());++li)
2815   {
2816     if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2817   }
2818   if (count>0) // at least one item is visible
2819   {
2820     startQuickIndexList(t,FALSE);
2821     for (li.toFirst();(entry=li.current());++li)
2822     {
2823       if (entry->visible() && quickLinkVisible(entry->kind()))
2824       {
2825         QCString url = entry->url();
2826         t << "<li><a href=\"" << relPath << url << "\"><span>";
2827         t << fixSpaces(entry->title());
2828         t << "</span></a>\n";
2829         // recursive into child list
2830         renderQuickLinksAsTree(t,relPath,entry);
2831         t << "</li>";
2832       }
2833     }
2834     endQuickIndexList(t,FALSE);
2835   }
2836 }
2837
2838
2839 static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath,
2840                              LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind,
2841                              bool highlightParent,bool highlightSearch)
2842 {
2843   if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
2844   {
2845     renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
2846   }
2847   if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry
2848   {
2849     bool topLevel = hlEntry->parent()->parent()==0;
2850     QListIterator<LayoutNavEntry> li(hlEntry->parent()->children());
2851     LayoutNavEntry *entry;
2852
2853     int count=0;
2854     for (li.toFirst();(entry=li.current());++li)
2855     {
2856       if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2857     }
2858     if (count>0) // at least one item is visible
2859     {
2860       startQuickIndexList(t,TRUE,topLevel);
2861       for (li.toFirst();(entry=li.current());++li)
2862       {
2863         if (entry->visible() && quickLinkVisible(entry->kind()))
2864         {
2865           QCString url = entry->url();
2866           startQuickIndexItem(t,url,
2867               entry==hlEntry  && 
2868               (entry->children().count()>0 || 
2869                (entry->kind()==kind && !highlightParent)
2870               ),
2871               TRUE,relPath);
2872           t << fixSpaces(entry->title());
2873           endQuickIndexItem(t,url);
2874         }
2875       }
2876       if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
2877       {
2878         static bool searchEngine      = Config_getBool("SEARCHENGINE");
2879         static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
2880         if (searchEngine)
2881         {
2882           t << "      <li>\n";
2883           if (!serverBasedSearch) // pure client side search
2884           {
2885             writeClientSearchBox(t,relPath);
2886             t << "      </li>\n";
2887           }
2888           else // server based search
2889           {
2890             writeServerSearchBox(t,relPath,highlightSearch);
2891             if (!highlightSearch)
2892             {
2893               t << "      </li>\n";
2894             }
2895           }
2896         }
2897         if (!highlightSearch) // on the search page the index will be ended by the
2898           // page itself
2899         {
2900           endQuickIndexList(t,TRUE);
2901         }
2902       }
2903       else // normal case for other rows than first one
2904       {
2905         endQuickIndexList(t,TRUE);
2906       }
2907     }
2908   }
2909 }
2910
2911 static void writeDefaultQuickLinks(FTextStream &t,bool compact,
2912                                    HighlightedItem hli,
2913                                    const char *file,
2914                                    const QCString &relPath)
2915 {
2916   LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry();
2917   LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1;
2918   LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file
2919   bool highlightParent=FALSE;
2920   switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
2921   {
2922     case HLI_Main:             kind = LayoutNavEntry::MainPage;         break;
2923     case HLI_Modules:          kind = LayoutNavEntry::Modules;          break;
2924     //case HLI_Directories:      kind = LayoutNavEntry::Dirs;             break;
2925     case HLI_Namespaces:       kind = LayoutNavEntry::NamespaceList;    altKind = LayoutNavEntry::Namespaces;  break;
2926     case HLI_Hierarchy:        kind = LayoutNavEntry::ClassHierarchy;   break;
2927     case HLI_Classes:          kind = LayoutNavEntry::ClassIndex;       altKind = LayoutNavEntry::Classes;     break;
2928     case HLI_Annotated:        kind = LayoutNavEntry::ClassList;        altKind = LayoutNavEntry::Classes;     break;
2929     case HLI_Files:            kind = LayoutNavEntry::FileList;         altKind = LayoutNavEntry::Files;       break;
2930     case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
2931     case HLI_Functions:        kind = LayoutNavEntry::ClassMembers;     break;
2932     case HLI_Globals:          kind = LayoutNavEntry::FileGlobals;      break;
2933     case HLI_Pages:            kind = LayoutNavEntry::Pages;            break;
2934     case HLI_Examples:         kind = LayoutNavEntry::Examples;         break;
2935     case HLI_UserGroup:        kind = LayoutNavEntry::UserGroup;        break;
2936     case HLI_ClassVisible:     kind = LayoutNavEntry::ClassList;        altKind = LayoutNavEntry::Classes;          
2937                                highlightParent = TRUE; break;
2938     case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList;    altKind = LayoutNavEntry::Namespaces;       
2939                                highlightParent = TRUE; break;
2940     case HLI_FileVisible:      kind = LayoutNavEntry::FileList;         altKind = LayoutNavEntry::Files;            
2941                                highlightParent = TRUE; break;
2942     case HLI_None:   break;
2943     case HLI_Search: break;
2944   }
2945   
2946   if (compact)
2947   {
2948     // find highlighted index item
2949     LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0);
2950     if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; }
2951     if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
2952     {
2953       highlightParent=TRUE;
2954       hlEntry = root->children().getFirst();
2955       if (hlEntry==0) 
2956       {
2957         return; // argl, empty index!
2958       }
2959     }
2960     if (kind==LayoutNavEntry::UserGroup)
2961     {
2962       LayoutNavEntry *e = hlEntry->children().getFirst();
2963       if (e)
2964       {
2965         hlEntry = e; 
2966       }
2967     }
2968     renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search);
2969   }
2970   else
2971   {
2972     renderQuickLinksAsTree(t,relPath,root);
2973   }
2974 }
2975
2976 void HtmlGenerator::endQuickIndices()
2977 {
2978   t << "</div><!-- top -->" << endl;
2979 }
2980
2981 QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath)
2982 {
2983   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2984   QCString result;
2985   // write split bar
2986   if (generateTreeView)
2987   {
2988     result = QCString(
2989     "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n"
2990     "  <div id=\"nav-tree\">\n"
2991     "    <div id=\"nav-tree-contents\">\n"
2992     "      <div id=\"nav-sync\" class=\"sync\"></div>\n"
2993     "    </div>\n"
2994     "  </div>\n"
2995     "  <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
2996     "       class=\"ui-resizable-handle\">\n"
2997     "  </div>\n"
2998     "</div>\n"
2999     "<script type=\"text/javascript\">\n"
3000     "$(document).ready(function(){initNavTree('") + 
3001     QCString(name) + Doxygen::htmlFileExtension + 
3002     QCString("','") + relpath +
3003     QCString("');});\n"
3004     "</script>\n"
3005     "<div id=\"doc-content\">\n");
3006   }
3007   return result;
3008 }
3009
3010 void HtmlGenerator::writeSplitBar(const char *name)
3011 {
3012   t << writeSplitBarAsString(name,relPath);
3013 }
3014
3015 void HtmlGenerator::writeNavigationPath(const char *s)
3016 {
3017   t << substitute(s,"$relpath^",relPath);
3018 }
3019
3020 void HtmlGenerator::startContents()
3021 {
3022   t << "<div class=\"contents\">" << endl;
3023 }
3024
3025 void HtmlGenerator::endContents()
3026 {
3027   t << "</div><!-- contents -->" << endl;
3028 }
3029
3030 void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
3031 {
3032   writeDefaultQuickLinks(t,compact,hli,file,relPath);
3033 }
3034
3035 // PHP based search script
3036 void HtmlGenerator::writeSearchPage()
3037 {
3038   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
3039   static bool disableIndex = Config_getBool("DISABLE_INDEX");
3040   static QCString projectName = Config_getString("PROJECT_NAME");
3041
3042   // OPENSEARCH_PROVIDER {
3043   QCString configFileName = Config_getString("HTML_OUTPUT")+"/search-config.php";
3044   QFile cf(configFileName);
3045   if (cf.open(IO_WriteOnly))
3046   {
3047     FTextStream t(&cf);
3048     t << "<script language=\"php\">\n\n";
3049     t << "$config = array(\n";
3050     t << "  'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
3051     t << "  'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
3052     t << "  'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
3053     t << ");\n\n";
3054     t << "$translator = array(\n";
3055     t << "  'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
3056     t << "  'search_results' => array(\n";  
3057     t << "    0 => \"" << theTranslator->trSearchResults(0) << "\",\n";     
3058     t << "    1 => \"" << theTranslator->trSearchResults(1) << "\",\n";     
3059     t << "    2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";     
3060     t << "  ),\n";
3061     t << "  'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
3062     t << "  'search' => \"" << theTranslator->trSearch() << "\",\n";
3063     t << "  'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n";
3064     t << "  'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
3065     t << ");\n\n";
3066     t << "</script>\n";
3067   }
3068
3069   QCString functionsFileName = Config_getString("HTML_OUTPUT")+"/search-functions.php";
3070   QFile ff(functionsFileName);
3071   if (ff.open(IO_WriteOnly))
3072   {
3073     FTextStream t(&ff);
3074     // Write stuff from search_functions.php source file...
3075     t << search_functions_script;
3076   }
3077
3078   QCString opensearchFileName = Config_getString("HTML_OUTPUT")+"/search-opensearch.php";
3079   QFile of(opensearchFileName);
3080   if (of.open(IO_WriteOnly))
3081   {
3082     FTextStream t(&of);
3083     // Write stuff from search_opensearch.php source file...
3084     t << search_opensearch_script;
3085   }
3086   // OPENSEARCH_PROVIDER }
3087
3088   QCString fileName = Config_getString("HTML_OUTPUT")+"/search.php";
3089   QFile f(fileName);
3090   if (f.open(IO_WriteOnly))
3091   {
3092     FTextStream t(&f);
3093     t << substituteHtmlKeywords(g_header,"Search","");
3094
3095     t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
3096       << versionString << " -->" << endl;
3097     t << "<script type=\"text/javascript\">\n";
3098     t << "var searchBox = new SearchBox(\"searchBox\", \""
3099       << "search\",false,'" << theTranslator->trSearch() << "');\n";
3100     t << "</script>\n";
3101     if (!Config_getBool("DISABLE_INDEX"))
3102     {
3103       writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
3104     }
3105     else
3106     {
3107       t << "</div>" << endl;
3108     }
3109
3110     t << "<script language=\"php\">\n";
3111     t << "require_once \"search-functions.php\";\n";
3112     t << "main();\n";
3113     t << "</script>\n";
3114
3115     // Write empty navigation path, to make footer connect properly
3116     if (generateTreeView)
3117     {
3118       t << "</div><!-- doc-contents -->\n";
3119       //t << "<div id=\"nav-path\" class=\"navpath\">\n";
3120       //t << "  <ul>\n";
3121     }
3122
3123     writePageFooter(t,"Search","","");
3124   }
3125   QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
3126   QFile sf(scriptName);
3127   if (sf.open(IO_WriteOnly))
3128   {
3129     FTextStream t(&sf);
3130     t << extsearch_script;
3131   }
3132   else
3133   {
3134      err("Failed to open file '%s' for writing...\n",scriptName.data());
3135   }
3136 }
3137
3138 void HtmlGenerator::writeExternalSearchPage()
3139 {
3140   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
3141   QCString fileName = Config_getString("HTML_OUTPUT")+"/search"+Doxygen::htmlFileExtension;
3142   QFile f(fileName);
3143   if (f.open(IO_WriteOnly))
3144   {
3145     FTextStream t(&f);
3146     t << substituteHtmlKeywords(g_header,"Search","");
3147
3148     t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
3149       << versionString << " -->" << endl;
3150     t << "<script type=\"text/javascript\">\n";
3151     t << "var searchBox = new SearchBox(\"searchBox\", \""
3152       << "search\",false,'" << theTranslator->trSearch() << "');\n";
3153     t << "</script>\n";
3154     if (!Config_getBool("DISABLE_INDEX"))
3155     {
3156       writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
3157       t << "            <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
3158       t << "            </form>\n";
3159       t << "          </div><div class=\"right\"></div>\n";
3160       t << "        </div>\n";
3161       t << "      </li>\n";
3162       t << "    </ul>\n";
3163       t << "  </div>\n";
3164       t << "</div>\n";
3165     }
3166     else
3167     {
3168       t << "</div>" << endl;
3169     }
3170     t << writeSplitBarAsString("search","");
3171     t << "<div class=\"header\">" << endl;
3172     t << "  <div class=\"headertitle\">" << endl;
3173     t << "    <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl;
3174     t << "  </div>" << endl;
3175     t << "</div>" << endl;
3176     t << "<div class=\"contents\">" << endl;
3177
3178     t << "<div id=\"searchresults\"></div>" << endl;
3179     t << "</div>" << endl;
3180
3181     if (generateTreeView)
3182     {
3183       t << "</div><!-- doc-contents -->" << endl;
3184     }
3185
3186     writePageFooter(t,"Search","","");
3187   }
3188   QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
3189   QFile sf(scriptName);
3190   if (sf.open(IO_WriteOnly))
3191   {
3192     FTextStream t(&sf);
3193     t << "var searchResultsText=["
3194       << "\"" << theTranslator->trSearchResults(0) << "\","
3195       << "\"" << theTranslator->trSearchResults(1) << "\","
3196       << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl;
3197     t << "var serverUrl=\"" << Config_getString("SEARCHENGINE_URL") << "\";" << endl;
3198     t << "var tagMap = {" << endl;
3199     bool first=TRUE;
3200     // add search mappings
3201     QStrList &extraSearchMappings = Config_getList("EXTRA_SEARCH_MAPPINGS");
3202     char *ml=extraSearchMappings.first();
3203     while (ml)
3204     {
3205       QCString mapLine = ml;
3206       int eqPos = mapLine.find('=');
3207       if (eqPos!=-1) // tag command contains a destination
3208       {
3209         QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
3210         QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
3211         if (!tagName.isEmpty())
3212         {
3213           if (!first) t << "," << endl;
3214           t << "  \"" << tagName << "\": \"" << destName << "\"";
3215           first=FALSE;
3216         }
3217       }
3218       ml=extraSearchMappings.next();
3219     }
3220     if (!first) t << endl;
3221     t << "};" << endl << endl;
3222     t << extsearch_script;
3223     t << endl;
3224     t << "$(document).ready(function() {" << endl;
3225     t << "  var query = trim(getURLParameter('query'));" << endl;
3226     t << "  if (query) {" << endl;
3227     t << "    searchFor(query,0,20);" << endl;
3228     t << "  } else {" << endl;
3229     t << "    var results = $('#results');" << endl;
3230     t << "    results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl;
3231     t << "  }" << endl;
3232     t << "});" << endl;
3233   }
3234   else
3235   {
3236      err("Failed to open file '%s' for writing...\n",scriptName.data());
3237   }
3238 }
3239
3240 void HtmlGenerator::startConstraintList(const char *header)
3241 {
3242   t << "<div class=\"typeconstraint\">" << endl;
3243   t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
3244   t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
3245 }
3246
3247 void HtmlGenerator::startConstraintParam()
3248 {
3249   t << "<tr><td valign=\"top\"><em>";
3250 }
3251
3252 void HtmlGenerator::endConstraintParam()
3253 {
3254   t << "</em></td>";
3255 }
3256
3257 void HtmlGenerator::startConstraintType()
3258 {
3259   t << "<td>&#160;:</td><td valign=\"top\"><em>";
3260 }
3261
3262 void HtmlGenerator::endConstraintType()
3263 {
3264   t << "</em></td>";
3265 }
3266
3267 void HtmlGenerator::startConstraintDocs()
3268 {
3269   t << "<td>&#160;";
3270 }
3271
3272 void HtmlGenerator::endConstraintDocs()
3273 {
3274   t << "</td></tr>" << endl;
3275 }
3276
3277 void HtmlGenerator::endConstraintList()
3278 {
3279   t << "</table>" << endl;
3280   t << "</dl>" << endl;
3281   t << "</div>" << endl;
3282 }
3283
3284 void HtmlGenerator::lineBreak(const char *style)
3285 {
3286   if (style)
3287   {
3288     t << "<br class=\"" << style << "\" />" << endl;
3289   }
3290   else
3291   {
3292     t << "<br />" << endl;
3293   }
3294 }
3295
3296 void HtmlGenerator::startHeaderSection()
3297 {
3298   t << "<div class=\"header\">" << endl;
3299 }
3300
3301 void HtmlGenerator::startTitleHead(const char *) 
3302
3303   t << "  <div class=\"headertitle\">" << endl;
3304   startTitle(); 
3305 }
3306
3307 void HtmlGenerator::endTitleHead(const char *,const char *) 
3308
3309   endTitle(); 
3310   t << "  </div>" << endl;
3311 }
3312
3313 void HtmlGenerator::endHeaderSection()
3314 {
3315   t << "</div><!--header-->" << endl;
3316 }
3317
3318 void HtmlGenerator::startInlineHeader()
3319 {
3320   if (m_emptySection)
3321   {
3322     t << "<table class=\"memberdecls\">" << endl;
3323     m_emptySection=FALSE;
3324   }
3325   t << "<tr><td colspan=\"2\"><h3>";
3326 }
3327
3328 void HtmlGenerator::endInlineHeader()
3329 {
3330   t << "</h3></td></tr>" << endl;
3331 }
3332
3333 void HtmlGenerator::startMemberDocSimple()
3334 {
3335   DBG_HTML(t << "<!-- startMemberDocSimple -->" << endl;)
3336   t << "<table class=\"fieldtable\">" << endl;
3337   t << "<tr><th colspan=\"3\">" << theTranslator->trCompoundMembers() << "</th></tr>" << endl;
3338 }
3339
3340 void HtmlGenerator::endMemberDocSimple()
3341 {
3342   DBG_HTML(t << "<!-- endMemberDocSimple -->" << endl;)
3343   t << "</table>" << endl;
3344 }
3345
3346 void HtmlGenerator::startInlineMemberType()
3347 {
3348   DBG_HTML(t << "<!-- startInlineMemberType -->" << endl;)
3349   t << "<tr><td class=\"fieldtype\">" << endl;
3350 }
3351
3352 void HtmlGenerator::endInlineMemberType()
3353 {
3354   DBG_HTML(t << "<!-- endInlineMemberType -->" << endl;)
3355   t << "</td>" << endl;
3356 }
3357
3358 void HtmlGenerator::startInlineMemberName()
3359 {
3360   DBG_HTML(t << "<!-- startInlineMemberName -->" << endl;)
3361   t << "<td class=\"fieldname\">" << endl;
3362 }
3363
3364 void HtmlGenerator::endInlineMemberName()
3365 {
3366   DBG_HTML(t << "<!-- endInlineMemberName -->" << endl;)
3367   t << "</td>" << endl;
3368 }
3369
3370 void HtmlGenerator::startInlineMemberDoc()
3371 {
3372   DBG_HTML(t << "<!-- startInlineMemberDoc -->" << endl;)
3373   t << "<td class=\"fielddoc\">" << endl;
3374 }
3375
3376 void HtmlGenerator::endInlineMemberDoc()
3377 {
3378   DBG_HTML(t << "<!-- endInlineMemberDoc -->" << endl;)
3379   t << "</td></tr>" << endl;
3380 }
3381
3382 void HtmlGenerator::startLabels()
3383 {
3384   DBG_HTML(t << "<!-- startLabels -->" << endl;)
3385   t << "<span class=\"mlabels\">";
3386 }
3387
3388 void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/)
3389 {
3390   DBG_HTML(t << "<!-- writeLabel(" << l << ") -->" << endl;)
3391   //t << "<tt>[" << l << "]</tt>";
3392   //if (!isLast) t << ", ";
3393   t << "<span class=\"mlabel\">" << l << "</span>";
3394 }
3395
3396 void HtmlGenerator::endLabels()
3397 {
3398   DBG_HTML(t << "<!-- endLabels -->" << endl;)
3399   t << "</span>";
3400 }
3401
3402 void HtmlGenerator::writeInheritedSectionTitle(
3403                   const char *id,    const char *ref, 
3404                   const char *file,  const char *anchor,
3405                   const char *title, const char *name)
3406 {
3407   DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;)
3408   QCString a = anchor;
3409   if (!a.isEmpty()) a.prepend("#");
3410   QCString classLink = QCString("<a class=\"el\" href=\"");
3411   if (ref)
3412   {
3413     classLink+= externalLinkTarget() + externalRef(relPath,ref,TRUE);
3414   }
3415   else
3416   {
3417     classLink+=relPath;
3418   }
3419   classLink+=file+Doxygen::htmlFileExtension+a;
3420   classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
3421   t << "<tr class=\"inherit_header " << id << "\">"
3422     << "<td colspan=\"2\" onclick=\"javascript:toggleInherit('" << id << "')\">"
3423     << "<img src=\"" << relPath << "closed.png\" alt=\"-\"/>&#160;" 
3424     << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
3425     << "</td></tr>" << endl;
3426 }
3427
3428 void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
3429 {
3430   if (first)
3431   {
3432     t << "  <div class=\"summary\">\n";
3433   }
3434   else
3435   {
3436     t << " &#124;\n";
3437   }
3438   t << "<a href=\"";
3439   if (file)
3440   {
3441     t << relPath << file;
3442     t << Doxygen::htmlFileExtension;
3443   }
3444   else
3445   {
3446     t << "#";
3447     t << anchor;
3448   }
3449   t << "\">";
3450   t << title;
3451   t << "</a>";
3452 }
3453
3454 void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId)
3455 {
3456   t << "<tr class=\"separator:" << anchor;
3457   if (inheritId)
3458   {
3459     t << " inherit " << inheritId;
3460   }
3461   t << "\"><td class=\"memSeparator\" colspan=\"2\">&#160;</td></tr>\n";
3462 }
3463
3464 void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
3465 {
3466   if (Doxygen::searchIndex)
3467   {
3468     Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
3469   }
3470 }
3471
3472 void HtmlGenerator::addWord(const char *word,bool hiPriority)
3473 {
3474   if (Doxygen::searchIndex)
3475   {
3476     Doxygen::searchIndex->addWord(word,hiPriority);
3477   }
3478 }
3479