More svn:eol-style=native for XHTML files.
[htmlpurifier-web.git] / index.xhtml
blobca2b448113f96c730330faeccd657c6668605e62
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4 <html xmlns="http://www.w3.org/1999/xhtml"
5 xmlns:xi="http://www.w3.org/2001/XInclude"
6 xmlns:xc="urn:xhtml-compiler"
7 xmlns:rss="urn:xhtml-compiler:RSSGenerator"
8 xmlns:svn="urn:xhtml-compiler:Subversion"
9 svn:head-url="$HeadURL$"
10 svn:revision="$Revision$"
11 xml:lang="en" lang="en">
12 <head>
13 <title>HTML Purifier - Filter your HTML the standards-compliant way!</title>
14 <xi:include href="common-meta.xml" xpointer="xpointer(/*/node())" />
15 <link rel="stylesheet" href="index.css" type="text/css" />
16 <meta name="description"
17 content="HTML filter that guards against XSS and ensures standards-compliant output." />
18 <meta name="keywords"
19 content="HTMLPurifier, HTML Purifier, HTML, filter, filtering, standards, compliant, w3c, XSS, PHP, security, library, open source, LGPL, whitelist" />
20 <link rel="alternate" type="application/rss+xml"
21 title="News - HTML Purifier" href="news.rss"
22 rss:for="news-container"
23 rss:description="Recent news and updates on HTML Purifier" />
24 <link rel="alternate" type="application/rss+xml" xc:rss-from-svn="yes"
25 title="Changelog for index.html" href="index.rss" />
26 </head>
27 <body>
29 <img src="logo.png" id="logo" alt="HTML Purifier" />
30 <h1 id="header"><span class="html">HTML</span>
31 <span class="purifier">Purifier</span></h1>
33 <div id="navigation">
34 <h2>Navigation</h2>
35 <ol>
36 <li><a href="#News">News</a></li>
37 <li><a href="#Plugins">Plugins</a></li>
38 <li><a href="#Demo">Demo</a></li>
39 <li><strong><a href="#Download">Download</a></strong></li>
40 <li><a href="#Resources">Resources</a></li>
41 <li><a href="phorum/">Forum</a></li>
42 <li><a href="#Contact">Contact</a></li>
43 </ol>
44 </div>
46 <div id="content">
48 <a href="#Download"><img src="download.png" class="download-button" alt="Download HTML Purifier" /></a>
50 <p><strong>HTML Purifier</strong> is a standards-compliant
51 <abbr>HTML</abbr> filter library written in
52 <abbr>PHP</abbr>. HTML Purifier will not only remove all malicious
53 code (better known as <abbr>XSS</abbr>) with a thoroughly audited,
54 secure <em>yet</em> permissive <strong><a
55 href="http://hp.jpsband.org/live/smoketests/printDefinition.php">whitelist</a></strong>,
56 it will also make sure your documents are
57 <strong>standards compliant</strong>, something only achievable with a
58 comprehensive knowledge of <abbr>W3C</abbr>'s specifications.
59 Tired of using BBCode due to the current landscape of deficient or
60 insecure <abbr>HTML</abbr> filters? Have a
61 <strong><acronym>WYSIWYG</acronym></strong> editor but never been able to use it? Looking
62 for high-quality, standards-compliant, open-source components for that
63 application you're building? HTML Purifier is for you!</p>
65 <blockquote class="fancy">
66 <div class="quote">
67 I'd just like to say we use HTML Purifier in <a href="http://www.iris.ac/">IRIS</a> for
68 filtering emails against XSS attacks and we've been more than impressed.
69 </div>
70 <div class="origin">&mdash; Chris Corbyn, <em>Senior IRIS Developer</em></div>
71 </blockquote>
73 <h2 id="Background">Background</h2>
75 <p>There are a number of open-source <abbr>HTML</abbr> filtering solutions out
76 there on the web already
77 (i.e. <acronym>PEAR</acronym>'s
78 <a href="http://pear.php.net/package/HTML_Safe">HTML_Safe</a>,
79 <a href="http://sourceforge.net/projects/kses">kses</a>
80 and
81 <a href="http://simon.incutio.com/archive/2003/02/23/safeHtmlChecker">
82 SafeHtmlChecker.class.php</a>). What sets HTML Purifier apart from them?
83 Aren't all of these choices <q>secure</q>?</p>
85 <p>When it comes to <abbr>HTML</abbr>, <strong>attention to
86 detail</strong> is key. Does the library demonstrate an in-depth
87 knowledge of the <abbr>DTD</abbr> that defines
88 <abbr>HTML</abbr>? Does it perform its filtering off a robust
89 whitelist rather than a usually out-dated blacklist? Does it go through
90 the care to check every single attribute in the document for validity?
91 Does it actually understand tag markup, or pay lip-service with a series
92 of deficient regexes and str_replace's?</p>
94 <p>Somewhere along the way, all of HTML Purifier's predecessors fall
95 flat. HTML_Safe dooms itself to attacks of the future by using a
96 blacklist. Configurable filters like kses and PHP Input Filter still
97 cannot validate the contents inside attributes. With all these gaps in
98 coverage, none of the usual libraries come close to achieving
99 <strong>standards-compliance</strong>. There is a user-unfriendly,
100 draconic <abbr>XML</abbr>-based filter called Safe HTML Checker,
101 but even it forgets that <code>&lt;a&gt;</code> tags cannot be nested
102 within each other!</p>
104 <p><strong>Know thy enemy.</strong> Wily hackers have a huge arsenal of
105 <abbr>XSS</abbr> hidden within the depths of the
106 <abbr>HTML</abbr> specification. HTML Purifier takes its
107 effectiveness from the fact that it will decompose the whole document
108 into tokens, and rigorously process the tokens by removing
109 non-whitelisted elements, transforming bad practice tags like font into
110 span, properly checking the nesting of tags and their children and
111 validating all attributes according to their <abbr>RFC</abbr>s.
112 HTML Purifier's comprehensive algorithms are complemented by a
113 <strong>breadth of knowledge</strong>, ensuring that richly formatted
114 documents pass through unstripped.</p>
116 <p><a href="comparison.html"><img src="compare.png" class="compare-button" alt="Compare HTML Purifier with other filters" /></a></p>
118 <p>To my knowledge, there is nothing else in the wild that offers
119 protection from <abbr>XSS</abbr>, standards-compliance, and the
120 corrective processing of poorly formed <abbr>HTML</abbr>
121 simultaneously. Don't take my word for it though:
122 do your research. Investigate the other libraries, and decide for
123 yourself who you would prefer to be the <strong>gatekeeper</strong> to
124 your system.</p>
126 <p>To find out more, you can read the
127 <a href="comparison.html"><strong>Comparison</strong></a>
128 for a play-by-play analysis of the major filter libraries currently
129 out there.</p>
131 <blockquote class="fancy">
132 <div class="quote">
133 [Y]ou save my day by allowing me not to write another damned HTML parser.
134 </div>
135 <div class="origin">
136 &mdash; Joseph Halter, <em>Technical Director at Akira Web</em>
137 </div>
138 </blockquote>
141 <h2 id="News">News</h2>
143 <div id="news-container" class="news">
145 <div class="item" id="news-1.6.0-released">
146 <h3 class="title">HTML Purifier 1.6.0 released</h3>
147 <div class="date">Sun, 01 April 2007 23:40:59 EDT</div>
149 <div class="body">
150 <p>Sorry, no April Fool's joke this year. To compensate, we have
151 the 1.6.0 <q>Long Overdue</q> release. This version contains support
152 for a number of deprecated attributes HTML Purifier should have
153 had from the very beginning, including the name, bgcolor, border,
154 width and height attributes. The <abbr>CSS</abbr> property 'height',
155 rel and rev attributes and ID blacklist regexps are also available.
156 In addition, HTML Purifier will give a friendly error message
157 when you try to enable an element or attribute that doesn't exist.</p>
159 <p>All in all, this is a fairly compact release, but it does
160 address some common requests brought up in the Forums, so I suggest
161 you upgrade anyway. You can check <a
162 href="http://hp.jpsband.org/svnroot/htmlpurifier/tags/1.6.0/NEWS">News</a>
163 for a complete changelog, but there's not much else.</p>
164 </div>
165 </div>
167 <div class="item" id="news-keep-me-updated">
168 <h3 class="title">A note to you distributors</h3>
169 <div class="date">Wed, 28 March 2007 21:05:12 EDT</div>
171 <div class="body">
172 <p>Yes, <strong>TikiWiki</strong> and <strong>PHProjekt</strong>,
173 I'm looking at you. I am absolutely delighted that these two fairly
174 popular and robust open-source projects are using my library.
175 However, I am not at all pleased at the fact that you have not
176 been keeping up to date with HTML Purifier releases.</p>
177 <ul>
178 <li>TikiWiki: <a href="http://tikiwiki.cvs.sourceforge.net/tikiwiki/tiki/lib/HTMLPurifier.php?view=log">1.3.0</a></li>
179 <li>PHProjekt: <a href="http://thinkforge.org/plugins/scmcvs/cvsweb.php/phprojekt50/lib/html/library/HTMLPurifier.php?cvsroot=phprojekt5">1.3.2</a></li>
180 </ul>
181 <p>I entreat yea, please sign up for the announcement list and
182 keep my library up-to-date! It's not difficult, I keep backwards
183 compatibility, and it makes your users happy! Especially that
184 <acronym>DOM</acronym> <abbr>XML</abbr> bug, which seems was
185 far more serious than I originally thought it was. That is all.</p>
186 </div>
187 </div>
189 <div class="item" id="news-pear-channel">
190 <h3 class="title"><acronym>PEAR</acronym> channel available</h3>
191 <div class="date">Sat, 24 March 2007 20:27:42 EDT</div>
193 <div class="body">
194 <p>At the prompting of Lars Olesen, HTML Purifier now
195 has its very own <acronym>PEAR</acronym> channel. This means that
196 installing HTML Purifier is as simple as:</p>
197 <pre class="command">pear channel-discover hp.jpsband.org
198 pear install hp/HTMLPurifier</pre>
199 </div>
200 </div>
202 <div class="item" id="news-1.5.0-released">
203 <h3 class="title">HTML Purifier 1.5.0 released</h3>
204 <div class="date">Fri, 23 March 2007 22:42:12 EDT</div>
206 <div class="body">
207 <p>The 1.5.0 major bugfix
208 release is available today. There have been some major internal
209 refactoring efforts, but these changes are invisible to you.</p>
211 <p>Entrepid souls wanting to test out the new
212 <code>HTMLModuleManager</code> class can check out the
213 <code>HTMLModule</code>s. Also, I will personally assist anyone
214 who has modified <code>HTMLDefinition.php</code>. <strong>If you
215 have patched any files, please consult the Support forums before
216 upgrading.</strong></p>
218 <p>And now, the goodies:</p>
220 <ul>
221 <li><strong><abbr>XHTML</abbr> 1.1-style modularization of
222 <code>HTMLDefinition</code>.</strong> Instead of one monster,
223 huge <code>HTMLDefinition</code> class, the file has been
224 partitioned into modular bits organized into categories
225 like <q>Hypertext</q>, <q>Lists</q> and <q>Tables</q>. The
226 design of these modules makes it possible to arbitrarily
227 add your own elements without ever having to patch a core
228 file. However, the interface is unintuitive, not
229 documented, and definitely going to change. Keep your eyes
230 on this one.</li>
231 <li>Rudimentary internationalization system implemented. It's
232 not used yet, but will become the foundation of a projected
233 error reporting feature HTML Purifier will be getting soon.</li>
234 <li><code>x</code> subtag now allowed in language codes.</li>
235 <li>Buggy chameleon support for <code>ins</code> and <code>del</code>
236 fixed.</li>
237 <li>Element by element AllowedAttribute declaration now possible
238 for global attributes. Instead of <code>*.class</code>, you can write
239 <code>span.class</code> (the old syntax still works, and enables
240 the attribute for all elements).</li>
241 <li>Fatal error when <abbr>PHP</abbr>4 <acronym>DOM</acronym>
242 <abbr>XML</abbr> extension was loaded now fixed. <strong>Update:</strong>
243 It seems that a lot of users run into this problem, as I know at least
244 five cases. Upgrade to 1.5.0 and it will be fixed, I promise!</li>
245 <li>Youtube filter regexp now multiline.</li>
246 </ul>
247 <p>...as well as an assortment of some code refactoring (all
248 bugfixes are covered above). See <a
249 href="http://hp.jpsband.org/svnroot/htmlpurifier/tags/1.5.0/NEWS">News</a>
250 for a complete changelog.</p>
251 </div>
252 </div>
255 <div class="item" id="news-rss-feed">
256 <h3 class="title"><abbr>RSS</abbr> feed!</h3>
257 <div class="date">Sat, 17 March 2007 5:42:12 EDT</div>
259 <div class="body">
260 <p>We have a shiny new <abbr>RSS</abbr> feed
261 at <a href="news.rss">news.rss</a>, which is hooked up to this
262 news feed. Subscribe for release notifications as well as random
263 news about HTML Purifier.</p>
264 </div>
265 </div>
267 </div> <!-- end news-container -->
269 <h2 id="Plugins">Plugins</h2>
271 <p>HTML Purifier is a great library to integrate with existing
272 <abbr>CMS</abbr>es and other applications or <acronym>WYSIWYG</acronym>
273 editors. Currently, we have plugins for:</p>
275 <ul>
276 <li><a href="http://bart.motd.be/projects/html-purifier-drupal-module">Drupal HTML Purifier Module</a> (beta) by Bart Jansens</li>
277 <li><a href="http://hp.jpsband.org/svnroot/htmlpurifier/trunk/plugins/modx.txt">MODx Content Management System</a></li>
278 </ul>
280 <blockquote class="fancy">
281 <div class="quote">
282 This plugin is on top of my favorite list[.] I am going to heavily
283 depend on it since my clients insist on having <acronym>WYSIWYG</acronym> and I insist on
284 having pages that validate and are semantically sound.
285 </div>
286 <div class="origin">
287 &mdash; David Molliere, <em>MODx Marketing &amp; Design Team</em>
288 </div>
289 </blockquote>
291 <p>Plugins for other major applications gladly accepted!</p>
294 <h2 id="Demo">Demo</h2>
296 <p>Enter your <abbr>HTML</abbr> and see how it will be filtered!</p>
297 <form id="filter" action="http://hp.jpsband.org/live/docs/examples/demo.php?post" method="post">
298 <fieldset>
299 <legend>HTML Purifier Input</legend>
300 <textarea name="html" cols="50" rows="10" id="html"></textarea>
301 <div><abbr>XHTML</abbr> 1.0 Strict output? <input type="checkbox" value="1" name="strict" /></div>
302 <div>
303 <input type="submit" value="Submit" name="submit" class="button" />
304 </div>
305 </fieldset>
306 </form>
308 <p>...or try these sample inputs:</p>
310 <ul>
311 <li><a href="http://hp.jpsband.org/live/docs/examples/demo.php?get&amp;html=%3Cimg+src%3D%22javascript%3Aevil%28%29%3B%22+onload%3D%22evil%28%29%3B%22+%2F%3E">Malicious code removed</a></li>
312 <li><a href="http://hp.jpsband.org/live/docs/examples/demo.php?html=%3Cb%3EBold&amp;submit=Submit">Missing end tags fixed</a></li>
313 <li><a href="http://hp.jpsband.org/live/docs/examples/demo.php?html=%3Cb%3EInline+%3Cdel%3Econtext+%3Cdiv%3ENo+block+allowed%3C%2Fdiv%3E%3C%2Fdel%3E%3C%2Fb%3E&amp;submit=Submit">Illegal nesting fixed</a></li>
314 <li><a href="http://hp.jpsband.org/live/docs/examples/demo.php?html=%3Ccenter%3ECentered%3C%2Fcenter%3E&amp;strict=1&amp;submit=Submit">Deprecated tags converted</a></li>
315 <li><a href="http://hp.jpsband.org/live/docs/examples/demo.php?html=%3Cspan+style%3D%22color%3A%23COW%3Bfloat%3Aaround%3Btext-decoration%3Ablink%3B%22%3EText%3C%2Fspan%3E&amp;submit=Submit"><abbr>CSS</abbr> validated</a></li>
316 <li><a href="http://hp.jpsband.org/live/docs/examples/demo.php?html=%3Ctable%3E%0D%0A++%3Ccaption%3E%0D%0A++++Cool+table%0D%0A++%3C%2Fcaption%3E%0D%0A++%3Ctfoot%3E%0D%0A++++%3Ctr%3E%0D%0A++++++%3Cth%3EI+can+do+so+much%21%3C%2Fth%3E%0D%0A++++%3C%2Ftr%3E%0D%0A++%3C%2Ftfoot%3E%0D%0A++%3Ctr%3E%0D%0A++++%3Ctd+style%3D%22font-size%3A16pt%3B%0D%0A++++++color%3A%23F00%3Bfont-family%3Asans-serif%3B%0D%0A++++++text-align%3Acenter%3B%22%3EWow%3C%2Ftd%3E%0D%0A++%3C%2Ftr%3E%0D%0A%3C%2Ftable%3E&amp;submit=Submit">Rich formatting preserved</a></li>
317 </ul>
319 <h2 id="Download">Download</h2>
321 <p>The current version is
322 <strong>1.6.0</strong>. Pick your distribution:</p>
324 <ul>
325 <li><a class="download" href="releases/htmlpurifier-1.6.0.tar.gz">HTML Purifier 1.6.0 (.tar.gz)</a> [<a href="releases/htmlpurifier-1.6.0.tar.gz.sig">sig</a>]</li>
326 <li><a class="download" href="releases/htmlpurifier-1.6.0.zip">HTML Purifier 1.6.0 (.zip)</a> [<a href="releases/htmlpurifier-1.6.0.zip.sig">sig</a>]</li>
327 <li><a class="download" href="releases/htmlpurifier-1.6.0-strict.tar.gz">HTML Purifier 1.6.0 PHP5-strict (.tar.gz)</a> [<a href="releases/htmlpurifier-1.6.0-strict.tar.gz.sig">sig</a>]</li>
328 <li><a class="download" href="releases/htmlpurifier-1.6.0-strict.zip">HTML Purifier 1.6.0 PHP5-strict (.zip)</a> [<a href="releases/htmlpurifier-1.6.0-strict.zip.sig">sig</a>]</li>
329 </ul>
331 <p>The <abbr>PHP</abbr>5-strict version is exactly the same
332 as the regular version with a few tweaks
333 to prevent it from complaining with
334 <a href="http://php.net/manual/en/ref.errorfunc.php#e-strict">E_STRICT</a>
335 warnings.This library is open-source, licensed under the
336 <a href="http://www.gnu.org/licenses/lgpl.html"><abbr>LGPL</abbr> v2.1+</a>.</p>
338 <p>HTML Purifier is also available as a <acronym>PEAR</acronym> package.
339 You can install it by executing:</p>
341 <pre class="command">pear channel-discover hp.jpsband.org
342 pear install hp/HTMLPurifier</pre>
344 <p>You can also grab the latest developmental code from our Subversion
345 repository. Simply execute this command:</p>
347 <pre class="command">svn co http://hp.jpsband.org/svnroot/htmlpurifier/trunk ./</pre>
349 <p>...or <a href="http://hp.jpsband.org/svnroot/htmlpurifier/trunk/">browse
350 anonymously</a> at that address. Previous releases can be obtained by browsing
351 the <a href="releases/">release directory</a>
352 or checking code out of the
353 <a href="http://hp.jpsband.org/svnroot/htmlpurifier/tags/">tags/
354 directory</a>.</p>
356 <p><acronym>SHA-1</acronym> checksums:</p>
358 <pre>
359 088569ae55d99bdbbee6031215ecc26f60489b70 htmlpurifier-1.6.0-strict.tar.gz
360 3deb033d6b20c22e7883cf2f7f719605fe6dd161 htmlpurifier-1.6.0-strict.zip
361 b4eed7787b84b7a86b24beaa5394616600780ceb htmlpurifier-1.6.0.tar.gz
362 3e375e83bc782e031362ce49c559e0d4f2511b6f htmlpurifier-1.6.0.zip
363 </pre>
365 <p>There are also <tt>.sig</tt> files which you can use to cryptographically verify
366 that the release is from me, Edward Z. Yang. You can find
367 my <a href="http://www.thewritingpot.com/gpgpubkey.asc">public key
368 here (0x869C48DA)</a>. My key's fingerprint is:
369 <tt>3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA</tt>.</p>
371 <p>Verify with these commands:</p>
373 <pre class="command">gpg --verify <strong>$filename</strong>.sig</pre>
375 <p>You can be notified of new releases by a low-traffic announce list. Subscribe
376 here:</p>
378 <form method="post" action="http://scripts.dreamhost.com/add_list.cgi">
379 <input type="hidden" name="list" value="htmlpurifier@jpsband.org" />
380 <input type="hidden" name="domain" value="jpsband.org" />
381 <input type="hidden" name="emailit" value="1" />
382 <div>Name: <input name="name" /> E-mail: <input name="email" /></div>
383 <div><input type="submit" name="submit" value="Suscribe to Announcement List" />
384 <input type="submit" name="unsub" value="Unsubscribe" /></div>
385 </form>
387 <h2 id="Resources">Resources</h2>
388 <ul>
389 <li><strong><a href="http://hp.jpsband.org/live/docs/">End-User
390 Documentation</a></strong> &mdash; In-depth documents on how to get
391 the most out of HTML Purifier.</li>
392 <li><a href="mantis/">Mantis Bugtracker</a> &mdash; Found a bug? Report
393 it here!</li>
394 <li><a href="phorum/">Support Forum</a> &mdash; Talk about all things
395 HTML Purifier.</li>
396 <li><a href="http://hp.jpsband.org/live/smoketests/printDefinition.php">Print
397 Definition</a> &mdash; If you want to actually see what HTML Purifier's
398 filtering rules are, look no further than to this page. You can even
399 experiment with the configuration to see how things respond to different
400 directives.</li>
401 <li><a href="http://hp.jpsband.org/live/smoketests/xssAttacks.php"><abbr>XSS</abbr>
402 Attacks Smoketest</a> &mdash; Tests how well HTML Purifier fares
403 against RSnake's famous cheatsheet of <abbr>XSS</abbr> attacks.</li>
404 <li><a href="http://hp.jpsband.org/live/TODO">Roadmap</a>
405 &mdash; Subject to lots of delays, but it's a glimpse of the future</li>
406 <li><a href="http://hp.jpsband.org/live/art/">Artwork</a>
407 &mdash; Extra media goodies.</li>
408 <li><a href="http://hp.jpsband.org/live/configdoc/plain.html">Configuration
409 documentation</a> &mdash; See the <code>INSTALL</code> document on how to
410 configure your HTML Purifier installation.</li>
411 <li><a href="http://hp.jpsband.org/doxygen/html/">Doxygen-generated
412 Documentation</a> &mdash; No class left undocumented! Cross-referenced
413 code! A must-read for any prospective HTML Purifier hacker.
414 (close by, <a href="http://hp.jpsband.org/phpdoc/">PHPDoc-generated
415 Documentation.</a>)</li>
416 </ul>
418 <h2 id="Propaganda">Spread the Word!</h2>
420 <p>Help spread awareness about HTML Purifier by:</p>
422 <ul>
423 <li><a
424 href="http://del.icio.us/post?v=4&amp;noui&amp;url=http://hp.jpsband.org/&amp;title=HTML%20Purifier%20-%20Filter%20your%20HTML%20the%20standards-compliant%20way!"
425 id="delicious">Bookmarking this website</a> on your <strong>del.icio.us</strong> account, and/or</li>
426 <li>
427 <div>Including this little <strong>label</strong> on your website:
428 <a href="http://hp.jpsband.org/"><img
429 src="http://hp.jpsband.org/live/art/powered.png"
430 alt="Powered by HTML Purifier" border="0" /></a>, with this code:
431 </div>
432 <pre>&lt;a href=&quot;http://hp.jpsband.org/&quot;&gt;&lt;img
433 src=&quot;http://hp.jpsband.org/live/art/powered.png&quot;
434 alt=&quot;Powered by HTML Purifier&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</pre>
435 </li>
436 </ul>
438 <h2 id="Contact">Contact</h2>
440 <p>You can send me an email at
441 <a href="mailto:htmlpurifier@jpsband.org">htmlpurifier@jpsband.org</a>.
442 However, I prefer that you use the forums for asking general support
443 questions (response time will be the same, I promise!)
444 Any emails I receive will be considered public: if I think a
445 solution I thought up to help you would be particularly useful to others,
446 expect it to show up on the website.</p>
448 </div>
450 </body>
451 </html>