? parser.patch
Index: htmlparserlib.php
===================================================================
RCS file: htmlparserlib.php
diff -N htmlparserlib.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparserlib.php	4 Jul 2008 07:29:50 -0000
@@ -0,0 +1,850 @@
+<?php
+/*******************************************************************************
+Version: 0.98 ($Rev: 117 $)
+Website: http://sourceforge.net/projects/simplehtmldom/
+Author: S.C. Chen (me578022@gmail.com)
+Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/)
+Contributions by: Yousuke Kumakura (Attribute filters)
+Licensed under The MIT License
+Redistributions of files must retain the above copyright notice.
+*******************************************************************************/
+
+define('HDOM_TYPE_ELEMENT', 1);
+define('HDOM_TYPE_COMMENT', 2);
+define('HDOM_TYPE_TEXT',    3);
+define('HDOM_TYPE_ENDTAG',  4);
+define('HDOM_TYPE_ROOT',    5);
+define('HDOM_TYPE_UNKNOWN', 6);
+define('HDOM_QUOTE_DOUBLE', 0);
+define('HDOM_QUOTE_SINGLE', 1);
+define('HDOM_QUOTE_NO',     3);
+define('HDOM_INFO_BEGIN',   0);
+define('HDOM_INFO_END',     1);
+define('HDOM_INFO_QUOTE',   2);
+define('HDOM_INFO_SPACE',   3);
+define('HDOM_INFO_TEXT',    4);
+define('HDOM_INFO_INNER',   5);
+define('HDOM_INFO_OUTER',   6);
+define('HDOM_INFO_ENDSPACE',7);
+
+// helper functions
+// -----------------------------------------------------------------------------
+// get dom form file
+function file_get_dom() {
+    $dom = new simple_html_dom;
+    $args = func_get_args();
+    $dom->load(call_user_func_array('file_get_contents', $args), true);
+    return $dom;
+}
+
+// get dom form string
+function str_get_dom($str, $lowercase=true) {
+    $dom = new simple_html_dom;
+    $dom->load($str, $lowercase);
+    return $dom;
+}
+
+// simple html dom node
+// -----------------------------------------------------------------------------
+class simple_html_dom_node {
+    public $tag = 'text';
+    public $nodetype = HDOM_TYPE_TEXT;
+    public $attr = array();
+    public $parent = null;
+    public $children = array();
+    public $dom = null;
+    public $nodes = array();
+    public $info = array(
+        HDOM_INFO_BEGIN=>-1,
+        HDOM_INFO_END=>0,
+        HDOM_INFO_TEXT=>'',
+        HDOM_INFO_ENDSPACE=>'',
+        HDOM_INFO_QUOTE=>array(),
+        HDOM_INFO_SPACE=>array()
+    );
+
+    function __construct($dom=null) {
+        $this->dom = $dom;
+    }
+
+    // clean up memory due to php5 circular references memory leak...
+    function clear() {
+        unset($this->tag);
+        unset($this->nodetype);
+        unset($this->attr);
+        unset($this->parent);
+        unset($this->children);
+        unset($this->nodes);
+        unset($this->dom);
+        unset($this->info);
+    }
+
+    // returns the parent of node
+    function parent() {
+        return $this->parent;
+    }
+
+    // returns children of node
+    function children($idx=-1) {
+        if ($idx==-1) return $this->children;
+        if (isset($this->children[$idx])) return $this->children[$idx];
+        return null;
+    }
+
+    // returns the first child of node
+    function first_child() {
+        if (count($this->children)>0) return $this->children[0];
+        return null;
+    }
+
+    // returns the last child of node
+    function last_child() {
+        if (($count=count($this->children))>0) return $this->children[$count-1];
+        return null;
+    }
+
+    // returns the next sibling of node    
+    function next_sibling() {
+        if ($this->parent===null) return null;
+        $idx = 0;
+        $count = count($this->parent->children);
+        while ($idx<$count && $this!==$this->parent->children[$idx])
+            ++$idx;
+        if (++$idx>=$count) return null;
+        return $this->parent->children[$idx];
+    }
+
+    // returns the previous sibling of node
+    function prev_sibling() {
+        if ($this->parent===null) return null;
+        $idx = 0;
+        $count = count($this->parent->children);
+        while ($idx<$count && $this!==$this->parent->children[$idx])
+            ++$idx;
+        if (--$idx<0) return null;
+        return $this->parent->children[$idx];
+    }
+
+    // get dom node's inner html
+    function innertext() {
+        if (isset($this->info[HDOM_INFO_INNER])) return $this->info[HDOM_INFO_INNER];
+        switch ($this->nodetype) {
+            case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+            case HDOM_TYPE_COMMENT: return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+            case HDOM_TYPE_UNKNOWN: return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+        }
+
+        $ret = '';
+        foreach($this->nodes as $n)
+            $ret .= $n->outertext();
+        return $ret;
+    }
+
+    // get dom node's outer text (with tag)
+    function outertext() {
+        if ($this->tag=='root') return $this->dom->save();
+        if (isset($this->info[HDOM_INFO_OUTER])) return $this->info[HDOM_INFO_OUTER];
+
+        // render begin tag
+        $ret = $this->dom->nodes[$this->info[HDOM_INFO_BEGIN]]->makeup();
+
+        // render inner text
+        if (isset($this->info[HDOM_INFO_INNER]))
+            $ret .= $this->info[HDOM_INFO_INNER];
+        else {
+            foreach($this->nodes as $n)
+                $ret .= $n->outertext();
+        }
+        // render end tag
+        if($this->info[HDOM_INFO_END])
+            $ret .= $this->dom->nodes[$this->info[HDOM_INFO_END]]->makeup($this->tag);
+
+        return $ret;
+    }
+
+    // get dom node's plain text
+    function plaintext() {
+        if (isset($this->info[HDOM_INFO_INNER])) return $this->info[HDOM_INFO_INNER];
+        switch ($this->nodetype) {
+            case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+            case HDOM_TYPE_COMMENT: return '';
+            case HDOM_TYPE_UNKNOWN: return '';
+        }
+        if (strcasecmp($this->tag, 'script')==0) return '';
+        if (strcasecmp($this->tag, 'style')==0) return '';
+        $ret = '';
+
+        foreach($this->nodes as $n)
+            $ret .= $n->plaintext();
+
+        return $ret;
+    }
+
+    // build node's text with tag
+    function makeup($tag=null) {
+        if ($tag===null) $tag = $this->tag;
+
+        switch($this->nodetype) {
+            case HDOM_TYPE_TEXT:    return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+            case HDOM_TYPE_COMMENT: return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+            case HDOM_TYPE_UNKNOWN: return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+            case HDOM_TYPE_ENDTAG:  return '</'.$tag.'>';
+        }
+
+        $ret = '<'.$tag;
+        $i = 0;
+
+        foreach($this->attr as $key=>$val) {
+            // skip removed attribute
+            if ($val===null || $val===false) {
+                ++$i; 
+                continue;
+            }
+            $ret .= $this->info[HDOM_INFO_SPACE][$i][0];
+            //no value attr: nowrap, checked selected...
+            if ($val===true)
+                $ret .= $key;
+            else {
+                $quote = '';
+                switch($this->info[HDOM_INFO_QUOTE][$i]) {
+                    case HDOM_QUOTE_DOUBLE: $quote = '"'; break;
+                    case HDOM_QUOTE_SINGLE: $quote = '\''; break;
+                }
+                $ret .= $key.$this->info[HDOM_INFO_SPACE][$i][1].'='.$this->info[HDOM_INFO_SPACE][$i][2].$quote.$val.$quote;
+            }
+            ++$i;
+        }
+        return $ret . $this->info[HDOM_INFO_ENDSPACE] . '>';
+    }
+
+    // find elements by css selector
+    function find($selector, $idx=-1) {
+        $selector = trim($selector);
+        if ($selector=='*') return $this->children;
+
+        $selectors = $this->parse_selector($selector);
+        if (($count=count($selectors))==0) return array();
+        $found_keys = array();
+
+        // find each selector
+        for ($c=0; $c<$count; ++$c) {
+            if (($levle=count($selectors[0]))==0) return array();
+            $head = array($this->info[HDOM_INFO_BEGIN]=>1);
+
+            // handle descendant selectors, no recursive!
+            for ($l=0; $l<$levle; ++$l) {
+                $ret = array();
+                foreach($head as $k=>$v) {
+                    $n = ($k==-1) ? $this->dom->root : $this->dom->nodes[$k];
+                    $n->seek($selectors[$c][$l], $ret);
+                }
+                $head = $ret;
+            }
+
+            foreach($head as $k=>$v) {
+                if (!isset($found_keys[$k]))
+                    $found_keys[$k] = 1;
+            }
+        }
+
+        // sort keys
+        ksort($found_keys);
+
+        $found = array();
+        foreach($found_keys as $k=>$v)
+            $found[] = $this->dom->nodes[$k];
+
+        // return nth-element or array
+        if ($idx<0) return $found;
+        return (isset($found[$idx])) ? $found[$idx] : null;
+    }
+
+    protected function parse_selector($selector_string) {
+        // pattern of CSS selectors, modified from mootools
+        $pattern = "/([A-Za-z0-9_\\-:]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)[\"']?([^\"']*)[\"']?)?])?/";
+
+        // handle multiple selectors
+        $selector_list = split(',', $selector_string);
+        $selectors = array();
+
+        foreach($selector_list as $selector) {
+            $result = array();
+            preg_match_all($pattern, trim($selector), $matches, PREG_SET_ORDER);
+
+            foreach ($matches as $m) {
+                list($tag, $key, $val, $exp) = array($m[1], null, null, '=');
+
+                if ($m[0]=='') continue;
+                if(!empty($m[2])) {$key='id'; $val=$m[2];}
+                if(!empty($m[3])) {$key='class'; $val=$m[3];}
+                if(!empty($m[4])) {$key=$m[4];}
+                if(!empty($m[5])) {$exp=$m[5];}
+                if(!empty($m[6])) {$val=$m[6];}
+
+                // convert to lowercase
+                if ($this->dom->lowercase) {$tag=strtolower($tag); $key=strtolower($key);}
+
+                $result[] = array($tag, $key, $val, $exp);
+            }
+            $selectors[] = $result;
+        }
+        return $selectors;
+    }
+
+    // seek for given conditions
+    protected function seek($selector, &$ret) {
+        list($tag, $key, $val, $exp) = $selector;
+
+        $end = $this->info[HDOM_INFO_END];
+        if ($end==0)
+            $end = $this->parent->info[HDOM_INFO_END]-1;
+
+        for($i=$this->info[HDOM_INFO_BEGIN]+1; $i<$end; ++$i) {
+            $node = $this->dom->nodes[$i];
+            if ($node->nodetype==HDOM_TYPE_ENDTAG) continue;
+            $pass = true;
+
+            // compare tag
+            if ($tag && $tag!=$node->tag) {$pass=false;}
+            // compare key
+            if ($pass && $key && !(isset($node->attr[$key]))) {$pass=false;}
+            // compare value
+            if ($pass && $key && $val) {
+                $check = $this->match($exp, $val, $node->attr[$key]);
+
+                // handle multiple class
+                if (!$check && strcasecmp($key, 'class')==0) {
+                    foreach(explode(' ',$node->attr[$key]) as $k) {
+                        $check = $this->match($exp, $val, $k);
+                        if ($check) break;
+                    }
+                }
+
+                if (!$check)
+                    $pass = false;
+            }
+
+            if ($pass)
+                $ret[$i] = 1;
+        }
+        unset($node);
+    }
+
+    protected function match($exp, $pattern, $value) {
+        $check = true;
+        switch ($exp) {
+            case '=':
+                $check = ($value===$pattern) ? true : false; break;
+            case '!=':
+                $check = ($value!==$pattern) ? true : false; break;
+            case '^=':
+                $check = (preg_match("/^".preg_quote($pattern,'/')."/", $value)) ? true : false; break;
+            case '$=':
+                $check = (preg_match("/".preg_quote($pattern,'/')."$/", $value)) ? true : false; break;
+            case '*=':
+                $check = (preg_match("/".preg_quote($pattern,'/')."/", $value)) ? true : false; break;
+        }
+        return $check;
+    }
+    
+    function __toString() {
+        return $this->outertext();
+    }
+
+    function __get($name) {
+        if (isset($this->attr[$name])) return $this->attr[$name];
+        switch($name) {
+            case 'outertext': return $this->outertext();
+            case 'innertext': return $this->innertext();
+            case 'plaintext': return $this->plaintext();
+            default: return array_key_exists($name, $this->attr);
+        }
+    }
+
+    function __set($name, $value) {
+        switch($name) {
+            case 'outertext': return $this->info[HDOM_INFO_OUTER] = $value;
+            case 'innertext': return $this->info[HDOM_INFO_INNER] = $value;
+            case 'plaintext': return $this->dom->restore_noise($this->info[HDOM_INFO_TEXT]);
+        }
+        if (!isset($this->attr[$name])) {
+            $this->info[HDOM_INFO_SPACE][] = array(' ', '', ''); 
+            $this->info[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
+        }
+        $this->attr[$name] = $value;
+    }
+
+    function __isset($name) {
+        switch($name) {
+            case 'outertext': return true;
+            case 'innertext': return true;
+            case 'plaintext': return true;
+        }
+        //no value attr: nowrap, checked selected...
+        return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]);
+    }
+
+    // camel naming conventions
+    function getAttribute($name) {return $this->__get($name);}
+    function setAttribute($name, $value) {$this->__set($name, $value);}
+    function hasAttribute($name) {return $this->__isset($name);}
+    function removeAttribute($name) {$this->__set($name, null);}
+    function getElementById($id) {return $this->find("#$id", 0);}
+    function getElementsById($id, $idx=-1) {return $this->find("#$id", $idx);}
+    function getElementByTagName($name) {return $this->find($name, 0);}
+    function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);}
+    function parentNode() {return $this->parent();}
+    function childNodes($idx=-1) {return $this->children($idx);}
+    function firstChild() {return $this->first_child();}
+    function lastChild() {return $this->last_child();}
+    function nextSibling() {return $this->next_sibling();}
+    function previousSibling() {return $this->prev_sibling();}
+}
+
+// simple html dom parser
+// -----------------------------------------------------------------------------
+class simple_html_dom {
+    public $nodes = array();
+    public $root = null;
+    public $lowercase = false;
+    protected $html = '';
+    protected $parent = null;
+    protected $pos;
+    protected $char;
+    protected $size;
+    protected $index;
+    public $callback = null;
+    protected $noise = array();
+    // use isset instead of in_array, performance boost about 30%...
+    protected $token_blank = array(' '=>1, "\t"=>1, "\r"=>1, "\n"=>1);
+    protected $token_equal = array(' '=>1, '='=>1, '/'=>1, '>'=>1, '<'=>1);
+    protected $token_slash = array(' '=>1, '/'=>1, '>'=>1, "\r"=>1, "\n"=>1, "\t"=>1);
+    protected $token_attr  = array(' '=>1, '>'=>1);
+    protected $self_closing_tags = array('img'=>1, 'br'=>1, 'input'=>1, 'meta'=>1, 'link'=>1, 'hr'=>1, 'base'=>1, 'embed'=>1, 'spacer'=>1);
+    protected $block_tags = array('div'=>1, 'span'=>1, 'table'=>1, 'form'=>1, 'dl'=>1, 'ol'=>1);
+    protected $optional_closing_tags = array(
+        'tr'=>array('tr'=>1, 'td'=>1, 'th'=>1),
+        'th'=>array('th'=>1),
+        'td'=>array('td'=>1),
+        'ul'=>array('ul'=>1, 'li'=>1),
+        'li'=>array('li'=>1),
+        'dt'=>array('dt'=>1, 'dd'=>1),
+        'dd'=>array('dd'=>1, 'dt'=>1),
+        'p'=>array('p'=>1),
+    );
+
+    // load html from string
+    function load($str, $lowercase=true) {
+        // prepare
+        $this->prepare($str, $lowercase);
+        // strip out comments
+        $this->remove_noise("'<!--(.*?)-->'is", false, false);
+        // strip out <style> tags
+        $this->remove_noise("'<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>'is", false, false);
+        $this->remove_noise("'<\s*style\s*>(.*?)<\s*/\s*style\s*>'is", false, false);
+        // strip out <script> tags
+        $this->remove_noise("'<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>'is", false, false);
+        $this->remove_noise("'<\s*script\s*>(.*?)<\s*/\s*script\s*>'is", false, false);
+        // strip out <pre> tags
+        $this->remove_noise("'<\s*pre[^>]*>(.*?)<\s*/\s*pre\s*>'is", false, false);
+        // strip out <code> tags
+        $this->remove_noise("'<\s*code[^>]*>(.*?)<\s*/\s*code\s*>'is", false, false);
+        // strip out server side scripts
+        $this->remove_noise("'(<\?)(.*?)(\?>)'is", false, false);
+        // parsing
+        while ($this->parse());
+        $this->root->info[HDOM_INFO_END] = $this->index;
+    }
+
+    // load html from file
+    function load_file() {
+        $args = func_get_args();
+        $this->load(call_user_func_array('file_get_contents', $args), true);
+    }
+
+    // set callback function
+    function set_callback($function_name) {
+        $this->callback = $function_name;
+    }
+
+    // save dom as string
+    function save($filepath='') {
+        $ret = '';
+        $count = count($this->nodes);
+
+        $func_callback = $this->callback;
+        for ($i=0; $i<$count; ++$i) {
+            // trigger callback
+            if ($func_callback!==null)
+                $handle =  $func_callback($this->nodes[$i]);
+
+            // outertext defined
+            if (isset($this->nodes[$i]->info[HDOM_INFO_OUTER])) {
+                $ret .= $this->nodes[$i]->info[HDOM_INFO_OUTER];
+                if ($this->nodes[$i]->info[HDOM_INFO_END]>0)
+                    $i = $this->nodes[$i]->info[HDOM_INFO_END];
+                continue;
+            }
+
+            $ret .= $this->nodes[$i]->makeup();
+
+            // innertext defined
+            if (isset($this->nodes[$i]->info[HDOM_INFO_INNER]) && $this->nodes[$i]->info[HDOM_INFO_END]>0) {
+                $ret .= $this->nodes[$i]->info[HDOM_INFO_INNER];
+                if ($this->nodes[$i]->info[HDOM_INFO_END]-1>$i)
+                    $i = $this->nodes[$i]->info[HDOM_INFO_END]-1;
+            }
+        }
+        if ($filepath!=='') file_put_contents($filepath, $ret);
+        return $ret;
+    }
+
+    // find dom node by css selector
+    function find($selector, $idx=-1) {
+        return $this->root->find($selector, $idx);
+    }
+
+    // prepare HTML data and init everything
+    function prepare($str, $lowercase=true) {
+        $this->clear();
+        $this->noise = array();
+        $this->nodes = array();
+        $this->html = $str;
+        $this->lowercase = $lowercase;
+        $this->index = 0;
+        $this->pos = 0;
+        $this->root = new simple_html_dom_node($this);
+        $this->root->tag = 'root';
+        $this->root->nodetype = HDOM_TYPE_ROOT;
+        $this->parent = $this->root;
+        // set the length of content
+        $this->size = strlen($str);
+        if ($this->size>0) $this->char = $this->html[0];
+    }
+
+    // clean up memory due to php5 circular references memory leak...
+    function clear() {
+        foreach($this->nodes as $n) {
+            $n->clear();
+            unset($n);
+        }
+
+        if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);}
+        if (isset($this->root)) {$this->root->clear(); unset($this->root);}
+        unset($this->html);
+        unset($this->noise);
+    }
+
+    // parse html content
+    function parse() {
+        $s = $this->copy_until_char('<');
+        if ($s=='') return $this->read_tag();
+
+        // text
+        $node = new simple_html_dom_node($this);
+        $this->nodes[] = $node;
+        $node->info[HDOM_INFO_BEGIN] = $this->index;
+        $node->info[HDOM_INFO_TEXT] = $s;
+        $node->parent = $this->parent;
+        $this->parent->nodes[] = $node;
+
+        ++$this->index;
+        return $node;
+    }
+
+    // read tag info
+    protected function read_tag() {
+        if ($this->char!='<') {
+            $this->root->info[HDOM_INFO_END] = $this->index;
+            return null;
+        }
+        $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+
+        $node = new simple_html_dom_node($this);
+        $this->nodes[] = $node;
+        $node->info[HDOM_INFO_BEGIN] = $this->index;
+        ++$this->index;
+
+        // end tag
+        if ($this->char=='/') {
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+            $this->skip($this->token_blank);
+            $node->nodetype = HDOM_TYPE_ENDTAG;
+            $node->tag = $this->copy_until_char('>');
+            $tag_lower = strtolower($node->tag);
+            if ($this->lowercase) $node->tag = $tag_lower;
+
+            // mapping parent node
+            if (strtolower($this->parent->tag)!==$tag_lower) {
+                if (isset($this->block_tags[$tag_lower]))  {
+                    $this->parent->info[HDOM_INFO_END] = 0;
+                    while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower)
+                        $this->parent = $this->parent->parent;
+                }
+                else {
+                    $node->nodetype = HDOM_TYPE_ENDTAG;
+                    $node->info[HDOM_INFO_END] = $this->index-1;
+                    $node->info[HDOM_INFO_TEXT] = '</' . $node->tag . '>';
+                    $node->tag = $node->tag;
+                    $this->parent->nodes[] = $node;
+                }
+                $this->parent->info[HDOM_INFO_END] = $this->index-1;
+            }
+            else {
+                $this->parent->info[HDOM_INFO_END] = $this->index-1;
+                $this->parent = $this->parent->parent;
+            }
+
+            $node->parent = $this->parent;
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+            return $node;
+        }
+
+        $node->tag = $this->copy_until($this->token_slash);
+        $node->parent = $this->parent;
+
+        // doctype, cdata & comments...
+        if (isset($node->tag[0]) && $node->tag[0]=='!') {
+            $node->info[HDOM_INFO_TEXT] = '<' . $node->tag . $this->copy_until_char('>');
+
+            if (isset($node->tag[2]) && $node->tag[1]=='-' && $node->tag[2]=='-') {
+                $node->nodetype = HDOM_TYPE_COMMENT;
+                $node->tag = 'comment';
+            } else {
+                $node->nodetype = HDOM_TYPE_UNKNOWN;
+                $node->tag = 'unknown';
+            }
+
+            if ($this->char=='>') $node->info[HDOM_INFO_TEXT].='>';
+            $this->parent->nodes[] = $node;
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+            return $node;
+        }
+
+        // text
+        if (!preg_match("/^[A-Za-z0-9_\\-:]+$/", $node->tag)) {
+            $node->info[HDOM_INFO_TEXT] = '<' . $node->tag . $this->copy_until_char('>');
+            if ($this->char=='>') $node->info[HDOM_INFO_TEXT].='>';
+            $this->parent->nodes[] = $node;
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+            return $node;
+        }
+
+        // begin tag
+        $node->nodetype = HDOM_TYPE_ELEMENT;
+        $tag_lower = strtolower($node->tag);
+        if ($this->lowercase) $node->tag = $tag_lower;
+
+        // handle optional closing tags
+        if (isset($this->optional_closing_tags[$tag_lower]) ) {
+            while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) {
+                $this->parent->info[HDOM_INFO_END] = 0;
+                $this->parent = $this->parent->parent;
+            }
+            $node->parent = $this->parent;
+        }
+        $this->parent->children[] = $node;
+        $this->parent->nodes[] = $node;
+
+        $guard = 0; // prevent infinity loop
+        $space = array($this->copy_skip($this->token_blank), '', '');
+
+        // handle attributes
+        do {
+            if ($this->char!==null && $space[0]=='') break;
+            $name = $this->copy_until($this->token_equal);
+
+            if($guard==$this->pos) {
+                $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+                continue;
+            }
+            $guard = $this->pos;
+
+            // handle endless '<'
+            if($this->pos>=$this->size-1 && $this->char!='>') {
+                $node->nodetype = HDOM_TYPE_TEXT;
+                $node->info[HDOM_INFO_END] = 0;
+                $node->info[HDOM_INFO_TEXT] = '<'.$node->tag . $space[0] . $name;
+                $node->tag = 'text';
+                return $node;
+            }
+
+            if ($name!='/' && $name!='') {
+                $space[1] = $this->copy_skip($this->token_blank);
+                if ($this->lowercase) $name = strtolower($name);
+                if ($this->char=='=') {
+                    $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+                    $this->parse_attr($node, $name, $space);
+                }
+                else {
+                    //no value attr: nowrap, checked selected...
+                    $node->info[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO;
+                    $node->attr[$name] = true;
+                    if ($this->char!='>') $this->char = $this->html[--$this->pos]; // prev
+                }
+                $node->info[HDOM_INFO_SPACE][] = $space;
+                $space = array($this->copy_skip($this->token_blank), '', '');
+            }
+            else
+                break;
+        } while($this->char!='>' && $this->char!='/');
+
+        $node->info[HDOM_INFO_ENDSPACE] = $space[0];
+
+        // check self closing
+        if ($this->copy_until_char_escape('>')=='/') {
+            $node->info[HDOM_INFO_ENDSPACE] .= '/';
+            $node->info[HDOM_INFO_END] = 0;
+        }
+        else {
+            // reset parent
+            if (!isset($this->self_closing_tags[strtolower($node->tag)])) $this->parent = $node;
+        }
+        $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+        return $node;
+    }
+
+    // parse attributes
+    protected function parse_attr($node, $name, &$space) {
+        $space[2] = $this->copy_skip($this->token_blank);
+        switch($this->char) {
+            case '"':
+                $node->info[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
+                $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+                $value = $this->copy_until_char_escape('"');
+                $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+                break;
+            case '\'':
+                $node->info[HDOM_INFO_QUOTE][] = HDOM_QUOTE_SINGLE;
+                $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+                $value = $this->copy_until_char_escape('\'');
+                $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+                break;
+            default:
+                $node->info[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO;
+                $value = $this->copy_until($this->token_attr);
+        }
+        $node->attr[$name] = $this->restore_noise($value);
+    }
+
+    protected function skip($chars) {
+        while ($this->char!==null) {
+            if (!isset($chars[$this->char])) return;
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+        }
+    }
+
+    protected function copy_skip($chars) {
+        $ret = '';
+        while ($this->char!==null) {
+            if (!isset($chars[$this->char])) return $ret;
+            $ret .= $this->char;
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+        }
+        return $ret;
+    }
+
+    protected function copy_until($chars) {
+        $ret = '';
+        while ($this->char!==null) {
+            if (isset($chars[$this->char])) return $ret;
+            $ret .= $this->char;
+            $this->char = (++$this->pos<$this->size) ? $this->html[$this->pos] : null; // next
+        }
+        return $ret;
+    }
+
+    protected function copy_until_char($char) {
+        if ($this->char===null) return '';
+
+        if (($pos = strpos($this->html, $char, $this->pos))===false) {
+            $ret = substr($this->html, $this->pos, $this->size-$this->pos);
+            $this->char = null;
+            $this->pos = $this->size;
+            return $ret;
+        }
+
+        if ($pos==$this->pos) return '';
+
+        $ret = substr($this->html, $this->pos, $pos-$this->pos);
+        $this->char = $this->html[$pos];
+        $this->pos = $pos;
+        return $ret;
+    }
+
+    protected function copy_until_char_escape($char) {
+        if ($this->char===null) return '';
+
+        $start = $this->pos;
+        while(1) {
+            if (($pos = strpos($this->html, $char, $start))===false) {
+                $ret = substr($this->html, $this->pos, $this->size-$this->pos);
+                $this->char = null;
+                $this->pos = $this->size;
+                return $ret;
+            }
+
+            if ($pos==$this->pos) return '';
+
+            if ($this->html[$pos-1]==='\\') {
+                $start = $pos+1;
+                continue;
+            }
+
+            $ret = substr($this->html, $this->pos, $pos-$this->pos);
+            $this->char = $this->html[$pos];
+            $this->pos = $pos;
+            return $ret;
+        }
+    }
+
+    // remove noise from html content
+    function remove_noise($pattern, $remove_tag=true, $remove_contents=true) {
+        $count = preg_match_all($pattern, $this->html, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
+
+        for ($i=$count-1; $i>-1; --$i) {
+            $key = '___noise___'.sprintf('% 3d', count($this->noise));
+            $idx = ($remove_tag) ? 0 : 1;
+            $this->noise[$key] = ($remove_contents) ? '' : $matches[$i][$idx][0];
+            $this->html = substr_replace($this->html, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0]));
+        }
+
+        // reset the length of content
+        $this->size = strlen($this->html);
+        if ($this->size>0)
+            $this->char = $this->html[0];
+    }
+
+    // restore noise to html content
+    function restore_noise($text) {
+        while(($pos=strpos($text, '___noise___'))!==false) {
+            $key = '___noise___'.$text[$pos+11].$text[$pos+12].$text[$pos+13];
+            if (isset($this->noise[$key]))
+                $text = substr($text, 0, $pos).$this->noise[$key].substr($text, $pos+14);
+        }
+        return $text;
+    }
+
+    function __toString() {
+        return $this->save();
+    }
+
+    function __get($name) {
+        switch($name) {
+            case 'outertext': return $this->save();
+            case 'innertext': return $this->root->innertext();
+            case 'plaintext': return $this->root->plaintext();
+        }
+    }
+
+    // camel naming conventions
+    function childNodes($idx=-1) {return $this->root->childNodes($idx);}
+    function firstChild() {return $this->root->first_child();}
+    function lastChild() {return $this->root->last_child();}
+    function getElementById($id) {return $this->find("#$id", 0);}
+    function getElementsById($id, $idx=-1) {return $this->find("#$id", $idx);}
+    function getElementByTagName($name) {return $this->find($name, 0);}
+    function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);}
+    function loadFile() {$args = func_get_args();$this->load(call_user_func_array('file_get_contents', $args), true);}
+}
+?>
\ No newline at end of file
Index: htmlparser/example/example_advanced_selector.php
===================================================================
RCS file: htmlparser/example/example_advanced_selector.php
diff -N htmlparser/example/example_advanced_selector.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/example_advanced_selector.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,57 @@
+<?php
+// example of how to use advanced selector features
+include('../simple_html_dom.php');
+
+// -----------------------------------------------------------------------------
+// descendant selector
+$str = <<<HTML
+<div>
+    <div>
+        <div>ok</div>
+    </div>
+</div>
+HTML;
+
+
+$dom = str_get_dom($str);
+foreach($dom->find('div div div') as $node)
+    echo $node->innertext . '<br>'; // result: "ok"
+
+
+// -----------------------------------------------------------------------------
+// nested selector
+$str = <<<HTML
+<ul id="ul1">
+    <li>item:<span>1</span></li>
+    <li>item:<span>2</span></li>
+</ul>
+<ul id="ul2">
+    <li>item:<span>3</span></li>
+    <li>item:<span>4</span></li>
+</ul>
+HTML;
+
+$dom = str_get_dom($str);
+foreach($dom->find('ul') as $ul) {
+    foreach($ul->find('li') as $li)
+        echo $li->innertext . '<br>';
+}
+
+// -----------------------------------------------------------------------------
+// parsing <form> elements
+$str = <<<HTML
+<form name="form1" method="post" action="">
+    <input type="checkbox" name="checkbox1" value="checkbox1" checked>item1<br>
+    <input type="checkbox" name="checkbox2" value="checkbox2">item2<br>
+    <input type="checkbox" name="checkbox3" value="checkbox3" checked>item3<br>
+</form>
+HTML;
+
+$dom = str_get_dom($str);
+foreach($dom->find('input[type=checkbox]') as $checkbox) {
+    if ($checkbox->checked)
+        echo $checkbox->name . ' is checked<br>';
+    else
+        echo $checkbox->name . ' is not checked<br>';
+}
+?>
\ No newline at end of file
Index: htmlparser/example/example_basic_selector.php
===================================================================
RCS file: htmlparser/example/example_basic_selector.php
diff -N htmlparser/example/example_basic_selector.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/example_basic_selector.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,37 @@
+<?php
+// example of how to use basic selector to retrieve HTML contents
+include('../simple_html_dom.php');
+ 
+// get DOM from URL or file
+$dom = file_get_dom('http://www.google.com/');
+
+// find all link
+foreach($dom->find('a') as $node) 
+    echo $node->href . '<br>';
+
+// find all image
+foreach($dom->find('img') as $node)
+    echo $node->src . '<br>';
+
+// find all image with full tag
+foreach($dom->find('img') as $node)
+    echo $node->outertext . '<br>';
+
+// find all div tags with id=gbar
+foreach($dom->find('div#gbar') as $node)
+    echo $node->innertext . '<br>';
+
+// find all span tags with class=gb1
+foreach($dom->find('span.gb1') as $node)
+    echo $node->outertext . '<br>';
+
+// find all td tags with attribite align=center
+foreach($dom->find('td[align=center]') as $node)
+    echo $node->innertext . '<br>';
+    
+// extract text from table
+echo $dom->find('td[align=center]', 1)->plaintext.'<br><hr>';
+
+// extract text from HTML
+echo $dom->plaintext;
+?>
\ No newline at end of file
Index: htmlparser/example/example_extract_html.php
===================================================================
RCS file: htmlparser/example/example_extract_html.php
diff -N htmlparser/example/example_extract_html.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/example_extract_html.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,5 @@
+<?php
+include_once('../simple_html_dom.php');
+
+echo file_get_dom('http://www.google.com/')->plaintext;
+?>
\ No newline at end of file
Index: htmlparser/example/example_modify_contents.php
===================================================================
RCS file: htmlparser/example/example_modify_contents.php
diff -N htmlparser/example/example_modify_contents.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/example_modify_contents.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,18 @@
+<?php
+// example of how to modify HTML contents
+include('../simple_html_dom.php');
+
+// get DOM from URL or file
+$dom = file_get_dom('http://www.google.com/');
+
+// remove all image
+foreach($dom->find('img') as $node)
+    $node->outertext = '';
+
+// replace all input
+foreach($dom->find('input') as $node)
+    $node->outertext = '[INPUT]';
+
+// dump contents
+echo $dom;
+?>
\ No newline at end of file
Index: htmlparser/example/simple_html_dom_utility.php
===================================================================
RCS file: htmlparser/example/simple_html_dom_utility.php
diff -N htmlparser/example/simple_html_dom_utility.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/simple_html_dom_utility.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,46 @@
+<?php
+include_once('../simple_html_dom.php');
+
+// -----------------------------------------------------------------------------
+// remove HTML comments
+function html_no_comment($url) {
+    // create DOM
+    $dom = file_get_dom($url);
+
+    // remove all comment elements
+    foreach($dom->find('comment') as $e)
+        $e->outertext = '';
+
+    $ret = $dom->save();
+
+    // clean up memory
+    $dom->clear();
+    unset($dom);
+
+    return $ret;
+}
+
+// -----------------------------------------------------------------------------
+// test it!
+echo html_no_comment('http://www.google.com/');
+
+
+// -----------------------------------------------------------------------------
+// search elements that contains an specific text
+function find_contains($dom, $selector, $keyword, $index=-1) {
+    $ret = array();
+    foreach ($dom->find($selector) as $e) {
+        if (strpos($e->innertext, $keyword)!==false)
+            $ret[] = $e;
+    }
+
+    if ($index<0) return $ret;
+    return (isset($ret[$index])) ? $ret[$index] : null;
+}
+
+// -----------------------------------------------------------------------------
+// test it!
+$dom = file_get_dom('http://www.google.com/');
+foreach(find_contains($dom, "a", "Google") as $e)
+    echo $e->outertext."<BR>";
+?>
\ No newline at end of file
Index: htmlparser/example/scraping/example_scraping_digg.php
===================================================================
RCS file: htmlparser/example/scraping/example_scraping_digg.php
diff -N htmlparser/example/scraping/example_scraping_digg.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/scraping/example_scraping_digg.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,44 @@
+<?php
+include_once('../../simple_html_dom.php');
+
+function scraping_digg() {
+    // create DOM
+    $dom = file_get_dom('http://digg.com/');
+
+    // get news block
+    foreach($dom->find('div.news-summary') as $article) {
+        // get title
+        $item['title'] = trim($article->find('h3', 0)->plaintext);
+        // get details
+        $item['details'] = trim($article->find('p', 0)->plaintext);
+        // get intro
+        $item['diggs'] = trim($article->find('li a strong', 0)->plaintext);
+
+        $ret[] = $item;
+    }
+    
+    // clean up memory
+    $dom->clear();
+    unset($dom);
+
+    return $ret;
+}
+
+
+// -----------------------------------------------------------------------------
+// test it!
+
+// "http://digg.com" will check user_agent header...
+ini_set('user_agent', 'My-Application/2.5');
+
+$ret = scraping_digg();
+
+foreach($ret as $v) {
+    echo $v['title'].'<br>';
+    echo '<ul>';
+    echo '<li>'.$v['details'].'</li>';
+    echo '<li>Diggs: '.$v['diggs'].'</li>';
+    echo '</ul>';
+}
+
+?>
\ No newline at end of file
Index: htmlparser/example/scraping/example_scraping_imdb.php
===================================================================
RCS file: htmlparser/example/scraping/example_scraping_imdb.php
diff -N htmlparser/example/scraping/example_scraping_imdb.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/scraping/example_scraping_imdb.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,51 @@
+<?php
+include_once('../../simple_html_dom.php');
+
+function scraping_IMDB($url) {
+    // create DOM
+    $dom = file_get_dom($url);
+
+    // get title
+    $ret['Title'] = $dom->find('title', 0)->innertext;
+
+    // get rating
+    $ret['Rating'] = $dom->find('div[class="general rating"] b', 0)->innertext;
+
+    // get overview
+    foreach($dom->find('div[class="info"]') as $div) {
+        // skip user comments
+        if($div->find('h5', 0)->innertext=='User Comments:')
+            return $ret;
+
+        $key = '';
+        $val = '';
+
+        foreach($div->find('*') as $node) {
+            if ($node->tag=='h5')
+                $key = $node->plaintext;
+
+            if ($node->tag=='a' && $node->plaintext!='more')
+                $val .= trim(str_replace("\n", '', $node->plaintext));
+
+            if ($node->tag=='text')
+                $val .= trim(str_replace("\n", '', $node->plaintext));
+        }
+
+        $ret[$key] = $val;
+    }
+    
+    // clean up memory
+    $dom->clear();
+    unset($dom);
+
+    return $ret;
+}
+
+
+// -----------------------------------------------------------------------------
+// test it!
+$ret = scraping_IMDB('http://imdb.com/title/tt0335266/');
+
+foreach($ret as $k=>$v)
+    echo '<strong>'.$k.' </strong>'.$v.'<br>';
+?>
\ No newline at end of file
Index: htmlparser/example/scraping/example_scraping_slashdot.php
===================================================================
RCS file: htmlparser/example/scraping/example_scraping_slashdot.php
diff -N htmlparser/example/scraping/example_scraping_slashdot.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/example/scraping/example_scraping_slashdot.php	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,38 @@
+<?php
+include_once('../../simple_html_dom.php');
+
+function scraping_slashdot() {
+    // create DOM
+    $dom = file_get_dom('http://slashdot.org/');
+
+    // get article block
+    foreach($dom->find('div.article') as $article) {
+        // get title
+        $item['title'] = trim($article->find('div.title', 0)->plaintext);
+        // get details
+        $item['details'] = trim($article->find('div.details', 0)->plaintext);
+        // get intro
+        $item['intro'] = trim($article->find('div.intro', 0)->plaintext);
+
+        $ret[] = $item;
+    }
+    
+    // clean up memory
+    $dom->clear();
+    unset($dom);
+
+    return $ret;
+}
+
+// -----------------------------------------------------------------------------
+// test it!
+$ret = scraping_slashdot();
+
+foreach($ret as $v) {
+    echo $v['title'].'<br>';
+    echo '<ul>';
+    echo '<li>'.$v['details'].'</li>';
+    echo '<li>'.$v['intro'].'</li>';
+    echo '</ul>';
+}
+?>
\ No newline at end of file
Index: htmlparser/manual/manual.htm
===================================================================
RCS file: htmlparser/manual/manual.htm
diff -N htmlparser/manual/manual.htm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/manual.htm	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,441 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="default.css" rel="stylesheet" type="text/css">
+<title>PHP Simple HTML DOM Parser: Manual</title>
+<link href="css/default.css" rel="stylesheet" type="text/css">
+<link rel="stylesheet" href="css/ui.tabs.css" type="text/css" media="print, projection, screen">
+<script type="text/javascript" src="js/jquery-1.2.3.pack.js"></script>
+<script type="text/javascript" src="js/ui.tabs.pack.js"></script>
+<script language="JavaScript" type="text/JavaScript">
+	$(document).ready(function(){
+		$(function() {$('#container_quickstart > ul').tabs();});
+		$(function() {$('#container_create > ul').tabs();});
+		$(function() {$('#container_find > ul').tabs();});
+		$(function() {$('#container_access > ul').tabs();});
+		$(function() {$('#container_traverse > ul').tabs();});
+		$(function() {$('#container_dump > ul').tabs();});
+		$(function() {$('#container_callback > ul').tabs();});
+	});
+</script>
+</head>
+<body>
+<h1><a name="top"></a>PHP Simple HTML DOM Parser Manual</h1>
+<div id="content">
+  <h2>Index</h2>
+  <ul>
+		<li><a href="#section_quickstart">Quick Start</a></li>
+    <li><a href="#section_create">How to create HTML DOM object?</a></li>
+    <li><a href="#section_find">How to find HTML elements?</a></li>
+    <li><a href="#section_access">How to access the HTML element's attributes?</a> </li>
+    <li><a href="#section_traverse">How to traverse the DOM tree?</a></li>
+    <li><a href="#section_dump">How to dump contents of DOM object?</a></li>
+		<li><a href="#section_callback">How to customize the parsing behavior?</a></li>
+    <li><a href="manual_api.htm">API Reference</a></li>
+    <li><a href="manual_faq.htm">FAQ</a></li>
+  </ul>
+	
+	<a name="section_quickstart"></a>
+  <h2>Quick Start</h2>
+  <a class="top" href="#top">Top</a>
+	<div id="container_quickstart">
+    <ul>
+      <li><a href="#fragment-11"><span>Get HTML elements</span></a></li>
+      <li><a href="#fragment-12"><span>Modify HTML elements</span></a></li>
+      <li><a href="#fragment-13"><span>Extract contents from HTML</span></a></li>
+      <li><a href="#fragment-14"><span>Scraping Slashdot!</span></a></li>
+    </ul>
+    <div id="fragment-11">
+      <div class="code">
+        <span class="comment">// Create DOM from URL or file</span><br>
+        $dom = <strong>file_get_dom</strong>(<span class="var">'http://www.google.com/'</span>);<br>
+        <br>
+        <span class="comment">// Find all images </span><br>
+        foreach($dom-&gt;<strong>find</strong>(<span class="var">'img'</span>) as $element) <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $element-&gt;<strong>src</strong> . <span class="var">'&lt;br&gt;'</span>;<br>
+<br>
+<span class="comment">// Find all links </span><br>
+foreach($dom-&gt;<strong>find</strong>(<span class="var">'a'</span>) as $element) <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $element-&gt;<strong>href</strong> . <span class="var">'&lt;br&gt;'</span>;      </div>
+    </div>
+    <div id="fragment-12">
+      <div class="code">
+        <span class="comment">// Create DOM from string</span><br>
+        $dom = <strong>str_get_dom</strong>(<span class="var">'&lt;div id=&quot;hello&quot;&gt;Hello&lt;/div&gt;&lt;div id=&quot;world&quot;&gt;World&lt;/div&gt;'</span>);<span class="comment"><br>
+        <br>
+        </span>
+        
+$dom-&gt;<strong>find</strong>(<span class="var">'div', 1</span>)-&gt;<strong>class</strong> = <span class="var">'bar'</span>;<br>
+<br>
+$dom-&gt;<strong>find</strong>(<span class="var">'div[id=hello]', 0</span>)-&gt;<strong>innertext</strong> = <span class="var">'foo'</span>;<br>
+        <br>
+        echo $dom; <span class="comment">// Output: &lt;div id=&quot;hello&quot;&gt;<strong>foo</strong>&lt;/div&gt;&lt;div id=&quot;world&quot; <strong>class=&quot;bar&quot;</strong>&gt;World&lt;/div&gt;</span> </div>
+    </div>
+    <div id="fragment-13">
+      <div class="code"><br>
+        <span class="comment">// Dump contents (without tags) from HTML</span><br>
+        echo <strong>file_get_dom</strong>(<span class="var">'http://www.google.com/'</span>)-&gt;<strong>plaintext</strong>;
+				<br><br>
+      </div>
+    </div>
+    <div id="fragment-14">
+      <div class="code">
+        <span class="comment">// Create DOM from URL</span><br>
+        $dom = <strong>file_get_dom</strong>(<span class="var">'http://slashdot.org/'</span>);<br>
+        <br>
+        <span class="comment">// Find all article blocks</span><br>
+        foreach($dom-&gt;<strong>find</strong>(<span class="var">'div.article'</span>) as $article) {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;$item[<span class="var">'title'</span>]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= $article-&gt;<strong>find</strong>(<span class="var">'div.title'</span>, <span class="var">0</span>)-&gt;<strong>plaintext</strong>;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;$item[<span class="var">'intro'</span>]&nbsp;&nbsp;&nbsp;&nbsp;= $article-&gt;<strong>find</strong>(<span class="var">'div.intro'</span>, <span class="var">0</span>)-&gt;<strong>plaintext</strong>;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;$item[<span class="var">'details'</span>]&nbsp;= $article-&gt;<strong>find</strong>(<span class="var">'div.details'</span>, <span class="var">0</span>)-&gt;<strong>plaintext</strong>;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;$articles[] = $item;<br>
+        }<br>
+        <br>
+        print_r($articles);
+      </div>
+    </div>
+  </div>
+	
+  <a name="section_create"></a>
+  <h2>How to create HTML DOM object?</h2>
+  <a class="top" href="#top">Top</a>
+  <div id="container_create">
+    <ul>
+      <li><a href="#frag_create_quick"><span>Quick way</span></a></li>
+      <li><a href="#frag_create_oo"><span>Object-oriented way</span></a></li>
+    </ul>
+    <div id="frag_create_quick">
+      <div class="code"><span class="comment">// Create a DOM object from a string</span><br>
+        $dom = <strong>str_get_dom</strong>(<span class="var">'&lt;html&gt;&lt;body&gt;Hello!&lt;/body&gt;&lt;/html&gt;'</span>);<br>
+        <br>
+        <span class="comment">// Create a DOM object from a URL</span><br>
+        $dom = <strong>file_get_dom</strong>(<span class="var">'http://www.google.com/'</span>);<br>
+        <br>
+        <span class="comment">// Create a DOM object from a HTML file</span><br>
+        $dom = <strong>file_get_dom</strong>(<span class="var">'test.htm'</span>);<span class="comment"><br>
+        </span></div>
+    </div>
+    <div id="frag_create_oo">
+      <div class="code"><span class="comment">// Create a DOM object</span><br>
+        $dom = new <strong>simple_html_dom</strong>();<br>
+        <br>
+        <span class="comment">// Load HTML from a string</span><br>
+        $dom-&gt;<strong>load</strong>(<span class="var">'&lt;html&gt;&lt;body&gt;Hello!&lt;/body&gt;&lt;/html&gt;'</span>);<br>
+        <br>
+        <span class="comment">// Load HTML from a URL </span> <br>
+        $dom-&gt;<strong>load_file</strong>(<span class="var">'http://www.google.com/'</span>);<br>
+        <br>
+        <span class="comment">// Load HTML from a HTML file</span> <br>
+        $dom-&gt;<strong>load_file</strong>(<span class="var">'test.htm'</span>);</div>
+    </div>
+  </div>
+  <a name="section_find"></a>
+  <h2>How to find HTML elements?</h2>
+  <a class="top" href="#top">Top</a>
+  <div id="container_find">
+    <ul>
+      <li><a href="#frag_find_basic"><span>Basics</span></a></li>
+      <li><a href="#frag_find_advanced"><span>Advanced</span></a></li>
+      <li><a href="#frag_find_chain"><span>Descendant selectors</span></a></li>
+      <li><a href="#frag_find_nested"><span>Nested selectors</span></a></li>
+      <li><a href="#frag_find_attr"><span>Attribute Filters</span></a></li>
+      <li><a href="#frag_find_textcomment"><span>Text &amp; Comments</span></a></li>
+    </ul>
+    <div id="frag_find_basic">
+      <div class="code"> <span class="comment">// Find all <strong>anchors</strong>, returns a <strong>array</strong> of element objects</span><br>
+        $ret = $dom-&gt;find(<span class="var">'<strong>a</strong>'</span>);<br>
+        <br>
+        <span class="comment">// Find <strong>(N)th</strong>  <strong>anchor</strong>, returns element object or <strong>null</strong> if not found</span> <span class="comment">(zero based)</span><br>
+        $ret = $dom-&gt;find(<span class="var">'<strong>a</strong>', <strong>0</strong></span>);<br>
+        <br>
+        <span class="comment">// Find all <strong>&lt;div&gt;</strong> which attribute <strong>id=foo</strong></span><br>
+$ret = $dom-&gt;find(<span class="var">'<strong>div[id=foo]</strong>'</span>);        <br>
+        <br>
+        <span class="comment">// Find all <strong>&lt;div&gt;</strong> with the <strong>id</strong> attribute</span><br>
+$ret = $dom-&gt;find(<span class="var">'<strong>div[id]</strong>'</span>);<br>
+<br>
+<span class="comment">// Find all element has attribute<strong> id</strong></span><br>
+$ret = $dom-&gt;find(<span class="var">'<strong>[id]</strong>'</span>);<br>
+      </div>
+    </div>
+    <div id="frag_find_advanced">
+      <div class="code"><span class="comment">// Find all element which <strong>id</strong>=foo</span><br>
+        $ret = $dom-&gt;find(<span class="var">'<strong>#foo</strong>'</span>);<br>
+        <br>
+        <span class=comment>// Find all element which <strong>class</strong>=foo</span><br>
+        $ret = $dom-&gt;find(<span class=var>'<strong>.foo</strong>'</span>);<br>
+        <br>
+        <span class="comment">// Find all <strong>anchors</strong> and <strong>images</strong> </span><br>
+$ret = $dom-&gt;find(<span class="var">'<strong>a, img</strong>'</span>);        <br>
+        <br>
+        <span class="comment">// Find all <strong>anchors</strong> and <strong>images</strong> with the "title" attribute</span><br>
+				$ret = $dom-&gt;find(<span class="var">'<strong>a[title], img[title]</strong>'</span>);<br>
+      </div>
+    </div>
+    <div id="frag_find_attr">
+      <div class="code">
+				Supports these operators in attribute selectors:<br><br>
+        <table cellpadding="1" cellspacing="1">
+          <tr>
+            <th width="25%">Filter</th>
+            <th width="75%">Description</th>
+          </tr>
+          <tr>
+            <td>[attribute]</td>
+            <td>Matches elements that <strong>have</strong> the specified attribute.</td>
+          </tr>
+          <tr>
+            <td>[attribute=value]</td>
+            <td>Matches elements that have the specified attribute with a <strong>certain value</strong>.</td>
+          </tr>
+          <tr>
+            <td>[attribute!=value]</td>
+            <td>Matches elements that <strong>don't have</strong> the specified attribute with a certain value.</td>
+          </tr>
+          <tr>
+            <td>[attribute^=value]</td>
+            <td>Matches elements that have the specified attribute and it <strong>starts</strong> with a certain value.</td>
+          </tr>
+          <tr>
+            <td>[attribute$=value]</td>
+            <td>Matches elements that have the specified attribute and it <strong>ends</strong> with a certain value.</td>
+          </tr>
+          <tr>
+            <td>[attribute*=value]</td>
+            <td>Matches elements that have the specified attribute and it <strong>contains</strong> a certain value.</td>
+          </tr>
+        </table>
+      </div>
+    </div>
+    <div id="frag_find_chain">
+      <div class="code"><span class="comment">// Find all &lt;li&gt; in &lt;ul&gt; </span><br>
+        $es = $dom-&gt;find(<span class="var">'<strong>ul li</strong>'</span>);<br>
+        <br>
+        <span class="comment">// Find Nested &lt;div&gt; </span><span class="comment">tags</span><br>
+        $es = $dom-&gt;find(<span class="var">'<strong>div div div</strong>'</span>); <br>
+        <br>
+        <span class="comment">// Find all &lt;td&gt; in &lt;table&gt; which class=hello </span><br>
+        $es = $dom-&gt;find(<span class="var">'<strong>table.hello td</strong>'</span>);<br>
+        <br>
+        <span class="comment">// Find all td tags with attribite align=center in table tags </span><br>
+        $es = $dom-&gt;find(<span class="var">''<strong>table</strong><strong> td[align=center]</strong>'</span>);<br>
+      </div>
+    </div>
+    <div id="frag_find_textcomment">
+      <div class="code"><span class="comment"> // Find all text blocks </span><br>
+        $es = $dom-&gt;find(<span class="var">'<strong>text</strong>'</span>);<br>
+        <br>
+        <span class="comment">// Find all comment (&lt;!--...--&gt;) blocks </span><br>
+        $es = $dom-&gt;find(<span class="var">'<strong>comment</strong>'</span>);<br>
+      </div>
+    </div>
+    <div id="frag_find_nested">
+      <div class="code"> <span class="comment">// Find all &lt;li&gt; in &lt;ul&gt; </span><br>
+        foreach($dom-&gt;find(<span class="var">'<strong>ul</strong>'</span>) as $ul) <br>
+        {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach($ul-&gt;find(<span class="var">'<strong>li</strong>'</span>) as $li) <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">// do something...</span><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
+        }<br>
+        <br>
+        <span class="comment">// Find first &lt;li&gt; in first &lt;ul&gt;</span> <br>
+        $e = $dom-&gt;find(<span class="var">'<strong>ul</strong>', <strong>0</strong></span>)-&gt;find(<span class="var">'<strong>li</strong>', <strong>0</strong></span>);<br>
+      </div>
+    </div>
+  </div>
+  <a name="section_access"></a>
+  <h2>How to access the HTML element's attributes?</h2>
+  <a class="top" href="#top">Top</a>
+  <div id="container_access">
+    <ul>
+      <li><a href="#frag_access_attr"><span>Get, Set and Remove attributes</span></a></li>
+      <li><a href="#frag_access_special"><span>Magic attributes</span></a></li>
+      <li><a href="#frag_access_tips"><span>Tips</span></a></li>
+    </ul>
+    <div id="frag_access_attr">
+      <div class="code"> 
+        <span class="comment">// <strong>Get</strong> a attribute ( If the attribute is <strong>non-value</strong> attribute (eg. checked, selected...), it will returns <strong>true</strong> or <strong>false</strong>)</span><br>
+        $value = $e-&gt;<strong>href</strong>;<br>
+        <br>
+        <span class="comment">// <strong>Set</strong> a attribute(If the attribute is <strong>non-value</strong> attribute (eg. checked, selected...), set it's value as <strong>true</strong> or <strong>false</strong>)</span><br>
+        $e-&gt;<strong>href</strong> = <span class="var">'my link'</span>;<br>
+        <br>
+        <span class="comment">// <strong>Remove</strong> a attribute, set it's value as null! </span><br>
+        $element-&gt;<strong>href</strong> = <strong><span class="var">null</span></strong>;<br>
+        <br>
+        <span class="comment">// <strong>Determine</strong> whether a attribute exist?</span> <br>
+if(isset($e-&gt;<strong>href</strong>)) <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo <span class="var">'href exist!'</span>;<br>
+      </div>
+    </div>
+    <div id="frag_access_special">
+      <div class="code"> <span class="comment">// Example</span><br>
+        <span class="hl-var">$dom</span><span class="hl-code"> = </span>str_get_dom<span class="hl-brackets">(</span><span class="var">&quot;&lt;div&gt;foo &lt;b&gt;bar&lt;/b&gt;&lt;/div&gt;&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;</span> <br>
+        $e = $dom-&gt;find(<span class="var">&quot;div&quot;</span>, <span class="var">0</span>);<br>
+        <br>
+        echo $e-&gt;<strong>tag</strong>; <span class="comment">// Returns: &quot; <strong>div</strong>&quot;</span><br>
+        echo $e-&gt;<strong>outertext</strong>; <span class="comment">// Returns: &quot; <strong>&lt;div&gt;foo &lt;b&gt;bar&lt;/b&gt;&lt;/div&gt;</strong>&quot;</span><br>
+        echo $e-&gt;<strong>innertext</strong>; <span class="comment">// Returns: &quot; <strong>foo &lt;b&gt;bar&lt;/b&gt;</strong>&quot;</span><br>
+        echo $e-&gt;<strong>plaintext</strong>; <span class="comment">// Returns: &quot; <strong>foo </strong><strong>bar</strong>&quot;<br>
+        <br>
+        </span>
+        <table cellspacing="1" cellpadding="1">
+          <tr bgcolor="#CCCCCC">
+            <th width="25%">Attribute Name</th>
+            <th width="75%">Usage</th>
+          </tr>
+          <tr>
+            <td>$e-&gt;<strong>tag</strong></td>
+            <td>Read or write the <strong>tag name</strong> of element.</td>
+          </tr>
+          <tr>
+            <td>$e-&gt;<strong>outertext</strong></td>
+            <td>Read or write the <strong>outer HTML text </strong> of element.</td>
+          </tr>
+          <tr>
+            <td>$e-&gt;<strong>innertext</strong></td>
+            <td>Read or write the <strong>inner HTML text </strong> of element.</td>
+          </tr>
+          <tr>
+            <td>$e-&gt;<strong>plaintext</strong></td>
+            <td>Read or write the <strong>plain text </strong> of element.</td>
+          </tr>
+        </table>
+      </div>
+    </div>
+    <div id="frag_access_tips">
+      <div class="code"><span class="comment">// Extract contents from HTML </span><br>
+echo <strong>$dom</strong>-&gt;<strong>plaintext</strong>;<br>
+<br> 
+<span class="comment">
+        // <strong>Wrap</strong> a element</span><br>
+        $element-&gt;<strong>outertext</strong> = <span class="var">'&lt;div class=&quot;wrap&quot;&gt;'</span> . $element-&gt;<strong>outertext</strong> . <span class="var">'&lt;div&gt;</span>';<br>
+        <br>
+        <span class="comment">// <strong>Remove</strong> a element, set it's outertext as empty string </span><br>
+        $element-&gt;<strong>outertext</strong> = <span class="var">''</span>;<br>
+        <br>
+        <span class="comment">// <strong>Append</strong> a element</span><br>
+$element-&gt;<strong>outertext</strong> = $element-&gt;<strong>outertext</strong> . <span class="var">'&lt;div&gt;foo</span><span class="var">&lt;div&gt;</span>';<br>
+<br>
+<span class="comment">// <strong>Insert</strong> a element</span><br>
+$element-&gt;<strong>outertext</strong> = <span class="var">'&lt;div&gt;foo</span><span class="var">&lt;div&gt;</span>' . $element-&gt;<strong>outertext</strong>;<br>
+      </div>
+    </div>
+  </div>
+  <a name="section_traverse"></a>
+  <h2>How to traverse the DOM tree?</h2>
+  <a class="top" href="#top">Top</a>
+  <div id="container_traverse">
+    <ul>
+      <li><a href="#frag_traverse_background"><span>Background Knowledge</span></a></li>
+      <li><a href="#frag_traverse_traverse"><span>Traverse the DOM tree</span></a></li>
+    </ul>
+    <div id="frag_traverse_background">
+      <div class="code"> <span class="comment">// If you are not so familiar with HTML DOM, check this <a href="http://php.net/manual/en/book.dom.php" target="_blank"><span class="var">link</span></a> to learn more... </span><br>
+        <br>
+        <span class="comment">// Example</span><br>
+        echo $dom-&gt;<strong>find</strong>(<span class="var">&quot;#div1&quot;, 0</span>)-&gt;<strong>children</strong>(<span class="var">1</span>)-&gt;<strong>children</strong>(<span class="var">1</span>)-&gt;<strong>children</strong>(<span class="var">2</span>)-&gt;<span class="var">id</span>;<br>
+        <span class="comment">// or</span> <br>
+        echo $dom-&gt;<strong>getElementById</strong>(<span class="var">&quot;div1&quot;</span>)-&gt;<strong>childNodes</strong>(<span class="var">1</span>)-&gt;<strong>childNodes</strong>(<span class="var">1</span>)-&gt;<strong>childNodes</strong>(<span class="var">2</span>)-&gt;<strong>getAttribute</strong>(<span class="var">'id'</span>); </div>
+    </div>
+    <div id="frag_traverse_traverse">
+      <div class="code">You can also call methods with <a href="manual_api.htm#camel"><span class="var">Camel naming convertions</span></a>.<br>
+        <table cellspacing="1" cellpadding="1">
+          <tr>
+            <th> Method </th>
+            <th> Description</th>
+          </tr>
+          <tr>
+            <td>
+              <div class="returns">mixed</div>$e-&gt;<strong>children</strong> ( <span class="var">[int $index]</span> ) </td>
+            <td>Returns the Nth <strong>child object</strong> if <strong>index</strong> is set, otherwise return an <strong>array of children</strong>. </td>
+          </tr>
+          <tr>
+            <td>
+              <div class="returns">element</div>$e-&gt;<strong>parent</strong> () </td>
+            <td>Returns the <strong>parent</strong> of element. </td>
+          </tr>
+          <tr>
+            <td>
+              <div class="returns">element</div>$e-&gt;<strong>first_child</strong> () </td>
+            <td>Returns the <strong>first child</strong> of element, or <strong>null</strong> if not found. </td>
+          </tr>
+          <tr>
+            <td>
+              <div class="returns">element</div>$e-&gt;<strong>last_child</strong> () </td>
+            <td>Returns the <strong>last child</strong> of element, or <strong>null</strong> if not found. </td>
+          </tr>
+          <tr>
+            <td>
+              <div class="returns">element</div>$e-&gt;<strong>next_sibling</strong> () </td>
+            <td>Returns the <strong>next sibling</strong> of element, or<strong> null</strong> if not found. </td>
+          </tr>
+          <tr>
+            <td>
+              <div class="returns">element</div>$e-&gt;<strong>prev_sibling</strong> () </td>
+            <td>Returns the <strong>previous sibling</strong> of element, or <strong>null</strong> if not found. </td>
+          </tr>
+        </table>
+      </div>
+    </div>
+    
+  </div>
+  <a name="section_dump"></a>
+  <h2>How to dump contents of DOM object?</h2>
+  <a class="top" href="#top">Top</a>
+  <div id="container_dump">
+    <ul>
+      <li><a href="#frag_dump_quick"><span>Quick way</span></a></li>
+      <li><a href="#frag_dump_oo"><span>Object-oriented way</span></a></li>
+    </ul>
+    <div id="frag_dump_oo">
+      <div class="code"><span class="comment">// </span><span class="comment">Dumps the internal DOM tree back into string </span><br>
+        $str = $dom-&gt;<strong>save</strong>();<br>
+        <br>
+        <span class="comment">// Dumps the internal DOM tree back into a file</span> <br>
+        $dom-&gt;<strong>save</strong>(<span class="var">'result.htm'</span>);</div>
+    </div>
+    <div id="frag_dump_quick">
+      <div class="code"><span class="comment">// </span><span class="comment">Dumps the internal DOM tree back into string </span><br>
+        $str = $dom;<br>
+        <br>
+        <span class="comment">// Print it!</span><br>
+        echo $dom; <br>
+      </div>
+    </div>
+  </div>
+	<a name="section_callback"></a>
+  <h2>How to customize the parsing behavior?</h2>
+  <a class="top" href="#top">Top</a>
+  <div id="container_callback">
+    <ul>
+      <li><a href="#frag_callback"><span>Callback function</span></a></li>
+    </ul>
+    <div id="frag_callback">
+      <div class="code"><span class="comment">// Write a function with parameter &quot;<strong>$element</strong>&quot;</span><br>
+        function my_callback(<span class="var">$element</span>) {<br>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Hide all &lt;b&gt; tags </span><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($element-&gt;tag==<span class="var">'b'</span>)<br> 
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$element-&gt;outertext = '';<br>
+        } <br>
+        <br>
+        <span class="comment">// Register the  callback function with it's <strong>function name</strong></span><br>
+        $dom-&gt;<strong>set_callback</strong>(<span class="var">my_callback'</span>);<br>
+        <br>
+        <span class="comment">// Callback function will be invoked while dumping</span><br>
+        echo $dom;
+      </div>
+    </div>
+  </div>
+
+  <div><br>
+    Author: S.C. Chen (me578022@gmail.com)<br>
+Original idea is from Jose Solorzano's <a href="http://php-html.sourceforge.net/">HTML Parser for PHP 4</a>. <br>
+Contributions by: Yousuke Kumakura (Attribute Filters) <br>
+  </div>
+</div>
+</body>
+</html>
+<!--$Rev: 120 $-->
\ No newline at end of file
Index: htmlparser/manual/manual_api.htm
===================================================================
RCS file: htmlparser/manual/manual_api.htm
diff -N htmlparser/manual/manual_api.htm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/manual_api.htm	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,307 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="default.css" rel="stylesheet" type="text/css">
+<title>PHP Simple HTML DOM Parser: API Reference</title>
+<link href="css/default.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+<h1><a name="top"></a>PHP Simple HTML DOM Parser Manual</h1>
+<div id="content">
+  <h2>Index</h2>
+  <ul>
+    <li><a href="manual.htm">Back</a></li>
+    <li><a href="#api">API Reference</a></li>
+    <li><a href="#camel">Camel naming conventions</a></li>
+  </ul>
+  <a name="api"></a>
+  <h2>API Reference</h2>
+  <a class="top" href="#top">Top</a>
+  <div class="code"> <strong>Helper</strong> functions
+    <table cellspacing="1" cellpadding="1">
+      <tr>
+        <th width="320">Name</th>
+        <th>Description</th>
+      </tr>
+      <tr>
+        <td><span class="returns">dom</span> str_get_dom ( <span class="var">string $content</span> )</td>
+        <td class="description">Creates a DOM object from a <strong>string</strong>.</td>
+      </tr>
+      <tr>
+        <td><span class="returns">dom</span> file_get_dom ( <span class="var">string $filename</span> )</td>
+        <td class="description">Creates a DOM object from a <strong>file</strong> or a <strong>URL</strong>.</td>
+      </tr>
+    </table>
+    <br>
+    <strong>DOM</strong> methods &amp; properties <br>
+    <table cellspacing="1" cellpadding="1">
+      <tr>
+        <th width="320"> Name</th>
+        <th> Description</th>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          plaintext</td>
+        <td class="description">Returns the contents extracted from HTML.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">void</div>
+          clear ()</td>
+        <td class="description">Clean up memory.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">void</div>
+          load ( <span class="var">string $content </span>)</td>
+        <td class="description"> Load contents from a <strong>string</strong>. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          save ( <span class="var">[string $filename]</span> )</td>
+        <td class="description">Dumps the internal DOM tree back into a <strong>string</strong>. If the <strong>$filename</strong> is set, result string will save to file. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">void</div>
+          load_file (<span class="var"> string $filename</span> )</td>
+        <td class="description"> Load contents from a from a <strong>file</strong> or a <strong>URL</strong>.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">void</div>
+          set_callback ( <span class="var">string $function_name </span>)</td>
+        <td class="description">Set a callback function. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">mixed</div>
+          find (<span class="var"> string $selector [, int $index] </span>)</td>
+        <td class="description">Find elements by the <strong>CSS selector</strong>. Returns the Nth element <strong>object</strong> if <strong>index</strong> is set, otherwise return an <strong>array of object</strong>. </td>
+      </tr>
+    </table>
+    <br>
+    <strong>Element</strong> methods &amp; properties <br>
+    <table cellspacing="1" cellpadding="1">
+      <tr>
+        <th width="320">Name</th>
+        <th>Description</th>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          <span class="var">[attribute]</span></td>
+        <td class="description">Read or write element's <strong>attribure value</strong>. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          tag</td>
+        <td class="description">Read or write the <strong>tag name</strong> of element.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          outertext</td>
+        <td class="description">Read or write the <strong>outer HTML text </strong> of element.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          innertext</td>
+        <td class="description">Read or write the <strong>inner HTML text </strong> of element.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">string</div>
+          plaintext</td>
+        <td class="description">Read or write the <strong>plain text </strong> of element.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">mixed</div>
+          find (<span class="var"> string $selector [, int $index] </span>)</td>
+        <td class="description">Find children by the <strong>CSS selector</strong>. Returns the Nth element <strong>object</strong> if <strong>index</strong> is set, otherwise, return an <strong>array</strong> of object. </td>
+      </tr>
+    </table>
+    <strong><br>
+    DOM</strong> traversing<br>
+    <table cellspacing="1" cellpadding="1">
+      <tr>
+        <th width="320">Name</th>
+        <th>Description</th>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;children ( <span class="var">[int $index]</span> ) </td>
+        <td class="description">Returns the Nth <strong>child object</strong> if <strong>index</strong> is set, otherwise return an <strong>array of children</strong>. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;parent () </td>
+        <td class="description">Returns the <strong>parent</strong> of element. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;first_child () </td>
+        <td class="description">Returns the <strong>first child</strong> of element, or <strong>null</strong> if not found. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;last_child () </td>
+        <td class="description">Returns the <strong>last child</strong> of element, or <strong>null</strong> if not found. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;next_sibling () </td>
+        <td class="description">Returns the <strong>next sibling</strong> of element, or<strong> null</strong> if not found. </td>
+      </tr>
+      <tr>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;prev_sibling () </td>
+        <td class="description">Returns the <strong>previous sibling</strong> of element, or <strong>null</strong> if not found. </td>
+      </tr>
+    </table>
+  </div>
+  <a name="camel"></a>
+  <h2>Camel naming convertions</h2>
+  <a class="top" href="#top">Top</a>
+  <div class="code">You can also call methods with W3C STANDARD camel naming convertions.<br>
+    <br>
+    <table cellspacing="1" cellpadding="1">
+      <tr>
+        <th width="50%">Method</th>
+        <th>Mapping</th>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">string</div>
+          $e-&gt;getAttribute ( <span class="var">$name</span> ) </td>
+        <td>
+          <div class="returns">string</div>
+          $e-&gt;<span class="var">attribute</span></td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">void</div>
+          $e-&gt;setAttribute ( <span class="var">$name, $value</span> ) </td>
+        <td>
+          <div class="returns">void</div>
+          $value = $e-&gt;<span class="var">attribute</span></td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">bool</div>
+          $e-&gt;hasAttribute ( <span class="var">$name</span> ) </td>
+        <td>
+          <div class="returns">bool</div>
+          isset($e-&gt;<span class="var">attribute</span>)</td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">void</div>
+          $e-&gt;removeAttribute ( <span class="var">$name</span> ) </td>
+        <td>
+          <div class="returns">void</div>
+          $e-&gt;<span class="var">attribute</span> = null</td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;getElementById ( <span class="var">$id</span> ) </td>
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;find (<span class="var"> &quot;#$id&quot;, 0 </span>)</td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;getElementsById ( <span class="var">$id [,$index] </span> ) </td>
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;find (<span class="var"> &quot;#$id&quot; [, int $index] </span>)</td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;getElementByTagName (<span class="var">$name</span> ) </td>
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;find (<span class="var"> $name, 0 </span>)</td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;getElementsByTagName ( <span class="var">$name [, $index]</span> ) </td>
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;find (<span class="var"> $name [, int $index] </span>)</td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;parentNode () </td>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;parent () </td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;childNodes ( <span class="var">[$index]</span> ) </td>
+        <td>
+          <div class="returns">mixed</div>
+          $e-&gt;children ( <span class="var">[int $index]</span> ) </td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;firstChild () </td>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;first_child () </td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;lastChild () </td>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;last_child () </td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;nextSibling () </td>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;next_sibling () </td>
+      </tr>
+      <tr bgcolor="#EEEEEE">
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;previousSibling () </td>
+        <td>
+          <div class="returns">element</div>
+          $e-&gt;prev_sibling () </td>
+      </tr>
+    </table>
+  </div>
+  <div><br>
+    Author: S.C. Chen (me578022@gmail.com)<br>
+Original idea is from Jose Solorzano's <a href="http://php-html.sourceforge.net/">HTML Parser for PHP 4</a>. <br>
+Contributions by: Yousuke Kumakura (Attribute Filters) <br>
+  </div>
+</div>
+</body>
+</html>
+<!--$Rev: 118 $-->
\ No newline at end of file
Index: htmlparser/manual/manual_faq.htm
===================================================================
RCS file: htmlparser/manual/manual_faq.htm
diff -N htmlparser/manual/manual_faq.htm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/manual_faq.htm	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="default.css" rel="stylesheet" type="text/css">
+<title>PHP Simple HTML DOM Parser: FAQ</title>
+<link href="css/default.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+<h1><a name="top"></a>PHP Simple HTML DOM Parser Manual</h1>
+<div id="content">
+  <h2>FAQ</h2>
+  <ul>
+		<li><a href="manual.htm">Back</a></li>
+    <li><a href="#hosting">Problem with hosting</a></li>
+    <li><a href="#proxy">Behind a proxy</a></li>
+    <li><a href="#memory_leak">Memory leak!</a></li>
+  </ul>
+	<div> <a name="hosting"></a>
+    <h2>Problem with hosting</h2>
+    <a class="top" href="#top">Top</a>
+    <div class="code"> <span class="var">Q:</span> On my local server everything works fine, but when I put it on my esternal server it doesn't work. <br>
+      <br>
+      <span class="var">A:</span> The "file_get_dom" function is a wrapper of "file_get_contents" function,  you must set "<strong>allow_url_fopen</strong>" as <strong>TRUE</strong> in "php.ini" to allow accessing files via HTTP or FTP. However, some hosting venders disabled PHP's "allow_url_fopen" flag for security issues... PHP provides excellent support for "curl" library to do the same job, Use curl to get the page, then call "str_get_dom" to create DOM object. <br>
+      <br>
+      Example: <br>
+       <br>
+      $curl = curl_init(); <br>
+      curl_setopt(<span class="var">$curl, CURLOPT_URL, 'http://????????'</span>);  <br>
+      curl_setopt(<span class="var">$curl, CURLOPT_RETURNTRANSFER, 1</span>);  <br>
+      curl_setopt(<span class="var">$curl, CURLOPT_CONNECTTIMEOUT, 10</span>);  <br>
+      $str = curl_exec(<span class="var">$curl</span>);  <br>
+      curl_close($curl);  <br>
+       <br>
+      $dom= <strong>str_get_dom</strong>($str); <br>
+      ...  </div>
+    <a name="proxy"></a>
+    <div>
+      <h2>Behind a proxy</h2>
+      <a class="top" href="#top">Top</a>
+      <div class="code"> <span class="var">Q:</span> My server is behind a Proxy and i can't use file_get_contents b/c it returns a unauthorized error.<br>
+        <br>
+        <span class="var">A:</span> Thanks for Shaggy to provide the solution. <br>
+         <br>
+        Example: <br>
+         <br>
+        <span class="comment">// Define a context for HTTP. </span><br>
+        $context = array<br>
+        ( <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="var">'http'</span> =&gt; array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="var">'proxy'</span> =&gt; <span class="var">'addresseproxy:portproxy'</span>, <span class="comment">// This needs to be the server and the port of the NTLM Authentication Proxy Server. </span><br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="var"> 'request_fulluri'</span> =&gt; true, <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ), <br>
+        ); <br>
+        <br>
+        $context = <strong>stream_context_create</strong>($context); <br>
+         <br>
+        $dom= <strong>file_get_dom</strong>(<span class="var">'http://www.php.net'</span>, <span class="var">false</span>, <span class="var">$context</span>); <br>
+        ...<br>
+      </div>
+    </div>
+    <a name="memory_leak"></a>
+    <h2>Memory leak!</h2>
+    <a class="top" href="#top">Top</a>
+    <div class="code"> <span class="var">Q:</span> This script is leaking memory seriously... After it finished running, it's not cleaning up dom object properly from memory.. <br>
+      <br>
+      <span class="var">A:</span> Due to php5 circular references memory leak, after creating DOM object, you must call $dom-&gt;clear() to free memory if call file_get_dom() more then once. <br>
+      <br>
+      Example: <br>
+      <br>
+      $dom = file_get_dom(...); <br>
+      <span class="comment">// do something... </span><br>
+      $dom-&gt;clear(); <br>
+      unset($dom);</div>
+    <br>
+    Author: S.C. Chen (me578022@gmail.com)<br>
+Original idea is from Jose Solorzano's <a href="http://php-html.sourceforge.net/">HTML Parser for PHP 4</a>. <br>
+Contributions by: Yousuke Kumakura (Attribute Filters) <br>
+  </div>
+</div>
+</body>
+</html>
+<!--$Rev: 118 $-->
Index: htmlparser/manual/css/default.css
===================================================================
RCS file: htmlparser/manual/css/default.css
diff -N htmlparser/manual/css/default.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/css/default.css	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,113 @@
+/*$Rev: 46 $*/
+
+body {
+margin: 0;
+padding: 0;
+font-family: verdana,arial,helvetica,sans-serif;
+font-size: 11px;
+color: #4F5155;
+}
+
+#content {
+margin: 0 20px 0 20px;
+line-height: 16px;
+padding: 0;
+}
+
+h1 {
+font-size: 18px;
+margin: 0;
+padding: 0 0 2px 0;
+background-color: #D0D0D0;
+text-align: center;
+}
+
+h2 {
+background-color: #727EA3;
+border-right: 1px solid #D0D0D0;
+border-bottom: 1px solid #D0D0D0;
+color: #FFFFFF;
+font-size: 14px;
+font-weight: bold;
+margin: 14px 0 4px 0;
+padding: 1px 10px 1px 10px;
+}
+
+ul {
+margin-top: 0;
+margin-bottom: 0;
+line-height:1.5em;
+list-style-image:url(bullet.gif);
+list-style-type:square;
+}
+
+.top {
+font-size: 11px;
+float: right;
+}
+
+.code {
+font-size: 11px;
+font-family: Monaco, Verdana, Sans-serif;
+line-height: 14px;
+background-color: #f6f6f6;
+border-bottom: 1px solid #D0D0D0;
+border-top: 1px solid #A0A0A0;
+border-left: 1px solid #A0A0A0;
+border-right: 1px solid #D0D0D0;
+color: #002166;
+display: block;
+margin: 2px 0 2px 0;
+padding: 2px 10px 2px 10px;
+}
+
+.code A:link {color: #002166; text-decoration: none; font-weight: bold;}
+.code A:visited {color: #002166; text-decoration: none; font-weight: bold;}
+.code A:active {color: #002166; text-decoration: none; font-weight: bold;}
+.code A:hover {color: #0000ff; text-decoration: underline; font-weight: bold;}
+
+.code .keyword {
+color: #007700;
+}
+
+.code .comment {
+font-size: 10px;
+color: #888;
+}
+
+.code .var {
+color: #770000;
+}
+
+th {
+font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+color: #000000;
+background-color: #CFD4E6;
+margin: 2px 2px 2px 2px;
+padding: 2px 2px 2px 2px;
+font-size: 13px;
+font-weight: normal;
+font-style: normal;
+}
+
+td {
+background-color: #dddddd;
+}
+
+.description {
+font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+font-size: 11px;
+color: #333;
+text-ident: 30px;
+font-style: normal;
+}
+
+.returns {
+font-family: Monaco, Verdana, Sans-serif;
+font-size: 10px;
+color: #888;
+float: left;
+text-align: right;
+margin: 0 4px 0 0;
+width: 48px;
+}
\ No newline at end of file
Index: htmlparser/manual/css/ui.tabs.css
===================================================================
RCS file: htmlparser/manual/css/ui.tabs.css
diff -N htmlparser/manual/css/ui.tabs.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/css/ui.tabs.css	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,116 @@
+/* Caution! Ensure accessibility in print and other media types... */
+@media projection, screen { /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */
+    .ui-tabs-hide {
+        display: none;
+    }
+}
+
+/* Hide useless elements in print layouts... */
+@media print {
+    .ui-tabs-nav {
+        display: none;
+    }
+}
+
+/* Skin */
+.ui-tabs-nav, .ui-tabs-panel {
+    font-family: "Trebuchet MS", Trebuchet, Verdana, Helvetica, Arial, sans-serif;
+    font-size: 12px;
+}
+.ui-tabs-nav {
+    list-style: none;
+    margin: 0;
+    padding: 0 0 0 4px;
+}
+.ui-tabs-nav:after { /* clearing without presentational markup, IE gets extra treatment */
+    display: block;
+    clear: both;
+    content: " ";
+}
+.ui-tabs-nav li {
+    float: left;
+    margin: 0 0 0 1px;
+    min-width: 84px; /* be nice to Opera */
+}
+.ui-tabs-nav a, .ui-tabs-nav a span {
+    display: block;
+    padding: 0 10px;
+    background: url(../img/tab.png) no-repeat;
+}
+.ui-tabs-nav a {
+    margin: 1px 0 0; /* position: relative makes opacity fail for disabled tab in IE */
+    padding-left: 0;
+    color: #27537a;
+    font-weight: bold;
+    line-height: 1.2;
+    text-align: center;
+    text-decoration: none;
+    white-space: nowrap; /* required in IE 6 */    
+    outline: 0; /* prevent dotted border in Firefox */
+}
+.ui-tabs-nav .ui-tabs-selected a {
+    position: relative;
+    top: 1px;
+    z-index: 2;
+    margin-top: 0;
+    color: #000;
+}
+.ui-tabs-nav a span {
+    width: 64px; /* IE 6 treats width as min-width */
+    min-width: 64px;
+    height: 18px; /* IE 6 treats height as min-height */
+    min-height: 18px;
+    padding-top: 6px;
+    padding-right: 0;
+}
+*>.ui-tabs-nav a span { /* hide from IE 6 */
+    width: auto;
+    height: auto;
+}
+.ui-tabs-nav .ui-tabs-selected a span {
+    padding-bottom: 1px;
+}
+.ui-tabs-nav .ui-tabs-selected a, .ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active {
+    background-position: 100% -150px;
+}
+.ui-tabs-nav a, .ui-tabs-nav .ui-tabs-disabled a:hover, .ui-tabs-nav .ui-tabs-disabled a:focus, .ui-tabs-nav .ui-tabs-disabled a:active {
+    background-position: 100% -100px;
+}
+.ui-tabs-nav .ui-tabs-selected a span, .ui-tabs-nav a:hover span, .ui-tabs-nav a:focus span, .ui-tabs-nav a:active span {
+    background-position: 0 -50px;
+}
+.ui-tabs-nav a span, .ui-tabs-nav .ui-tabs-disabled a:hover span, .ui-tabs-nav .ui-tabs-disabled a:focus span, .ui-tabs-nav .ui-tabs-disabled a:active span {
+    background-position: 0 0;
+}
+.ui-tabs-nav .ui-tabs-selected a:link, .ui-tabs-nav .ui-tabs-selected a:visited, .ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { /* @ Opera, use pseudo classes otherwise it confuses cursor... */
+    cursor: text;
+}
+.ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active,
+.ui-tabs-nav .ui-tabs-unselect a:hover, .ui-tabs-nav .ui-tabs-unselect a:focus, .ui-tabs-nav .ui-tabs-unselect a:active { /* @ Opera, we need to be explicit again here now... */
+    cursor: pointer;
+}
+.ui-tabs-disabled {
+    opacity: .4;
+    filter: alpha(opacity=40);
+}
+.ui-tabs-panel {
+    border-top: 1px solid #97a5b0;
+    padding: 2px 4px 2px 4px;
+    background: #fff; /* declare background color for container to avoid distorted fonts in IE while fading */
+    border: 1px solid #D0D0D0;
+    border-bottom: 1px solid #A0A0A0;
+    border-right: 1px solid #A0A0A0;
+}
+.ui-tabs-loading em {
+    padding: 0 0 0 20px;
+    background: url(loading.gif) no-repeat 0 50%;
+}
+
+/* Additional IE specific bug fixes... */
+* html .ui-tabs-nav { /* auto clear, @ IE 6 & IE 7 Quirks Mode */
+    display: inline-block;
+}
+*:first-child+html .ui-tabs-nav  { /* @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */
+    display: inline-block;
+}
+
Index: htmlparser/manual/img/tab.png
===================================================================
RCS file: htmlparser/manual/img/tab.png
diff -N htmlparser/manual/img/tab.png
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/img/tab.png	4 Jul 2008 07:30:17 -0000
@@ -0,0 +1,10 @@
+PNG
+
+   IHDR  ,      e,g   tEXtSoftware Adobe ImageReadyqe<   xPLTE<Uk<WlczE^rrQfy~\rrÌ  IDATxINQEmӷ! /H]WzZ>JY/]ʪNavkU+Ҫ/V}3U_(Hi7JU_)PiշJVZҪV?JU)Di[J,X,X`	,X`,X߄%}^WKօJ۬=!
+a`,,X,X,X`	,X`,X`%XP45nJkYG"zClNʚIVXS8
+k
+'YaM$+)d5pNIVXS8
+k
+'YaM$+)d5pNIVXS8
+k
+'YaM$+)d5w`,X`,X`,X}uQ.YuA.Yu;D ,X`!,X,X`,`X`,X` . qq1    IENDB`
\ No newline at end of file
Index: htmlparser/manual/js/jquery-1.2.3.pack.js
===================================================================
RCS file: htmlparser/manual/js/jquery-1.2.3.pack.js
diff -N htmlparser/manual/js/jquery-1.2.3.pack.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/js/jquery-1.2.3.pack.js	4 Jul 2008 07:30:18 -0000
@@ -0,0 +1,11 @@
+/*
+ * jQuery 1.2.3 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
+ * $Rev: 4663 $
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(J(){7(1e.3N)L w=1e.3N;L E=1e.3N=J(a,b){K 1B E.2l.4T(a,b)};7(1e.$)L D=1e.$;1e.$=E;L u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;L G=/^.[^:#\\[\\.]*$/;E.1n=E.2l={4T:J(d,b){d=d||T;7(d.15){6[0]=d;6.M=1;K 6}N 7(1o d=="25"){L c=u.2O(d);7(c&&(c[1]||!b)){7(c[1])d=E.4a([c[1]],b);N{L a=T.5J(c[3]);7(a)7(a.2w!=c[3])K E().2s(d);N{6[0]=a;6.M=1;K 6}N d=[]}}N K 1B E(b).2s(d)}N 7(E.1q(d))K 1B E(T)[E.1n.21?"21":"3U"](d);K 6.6E(d.1k==1M&&d||(d.5h||d.M&&d!=1e&&!d.15&&d[0]!=10&&d[0].15)&&E.2I(d)||[d])},5h:"1.2.3",87:J(){K 6.M},M:0,22:J(a){K a==10?E.2I(6):6[a]},2F:J(b){L a=E(b);a.54=6;K a},6E:J(a){6.M=0;1M.2l.1g.1i(6,a);K 6},R:J(a,b){K E.R(6,a,b)},4X:J(b){L a=-1;6.R(J(i){7(6==b)a=i});K a},1J:J(c,a,b){L d=c;7(c.1k==4e)7(a==10)K 6.M&&E[b||"1J"](6[0],c)||10;N{d={};d[c]=a}K 6.R(J(i){Q(c 1p d)E.1J(b?6.W:6,c,E.1l(6,d[c],b,i,c))})},1j:J(b,a){7((b==\'27\'||b==\'1R\')&&2M(a)<0)a=10;K 6.1J(b,a,"2o")},1u:J(b){7(1o b!="3V"&&b!=V)K 6.4x().3t((6[0]&&6[0].2i||T).5r(b));L a="";E.R(b||6,J(){E.R(6.3p,J(){7(6.15!=8)a+=6.15!=1?6.6K:E.1n.1u([6])})});K a},5m:J(b){7(6[0])E(b,6[0].2i).5k().3o(6[0]).2c(J(){L a=6;2b(a.1C)a=a.1C;K a}).3t(6);K 6},8w:J(a){K 6.R(J(){E(6).6z().5m(a)})},8p:J(a){K 6.R(J(){E(6).5m(a)})},3t:J(){K 6.3O(18,P,S,J(a){7(6.15==1)6.38(a)})},6q:J(){K 6.3O(18,P,P,J(a){7(6.15==1)6.3o(a,6.1C)})},6o:J(){K 6.3O(18,S,S,J(a){6.1a.3o(a,6)})},5a:J(){K 6.3O(18,S,P,J(a){6.1a.3o(a,6.2B)})},3h:J(){K 6.54||E([])},2s:J(b){L c=E.2c(6,J(a){K E.2s(b,a)});K 6.2F(/[^+>] [^+>]/.17(b)||b.1f("..")>-1?E.57(c):c)},5k:J(e){L f=6.2c(J(){7(E.14.1d&&!E.3E(6)){L a=6.69(P),4Y=T.3s("1x");4Y.38(a);K E.4a([4Y.3d])[0]}N K 6.69(P)});L d=f.2s("*").4R().R(J(){7(6[F]!=10)6[F]=V});7(e===P)6.2s("*").4R().R(J(i){7(6.15==3)K;L c=E.O(6,"2R");Q(L a 1p c)Q(L b 1p c[a])E.16.1b(d[i],a,c[a][b],c[a][b].O)});K f},1E:J(b){K 6.2F(E.1q(b)&&E.3y(6,J(a,i){K b.1P(a,i)})||E.3e(b,6))},56:J(b){7(b.1k==4e)7(G.17(b))K 6.2F(E.3e(b,6,P));N b=E.3e(b,6);L a=b.M&&b[b.M-1]!==10&&!b.15;K 6.1E(J(){K a?E.33(6,b)<0:6!=b})},1b:J(a){K!a?6:6.2F(E.37(6.22(),a.1k==4e?E(a).22():a.M!=10&&(!a.12||E.12(a,"3u"))?a:[a]))},3H:J(a){K a?E.3e(a,6).M>0:S},7j:J(a){K 6.3H("."+a)},5O:J(b){7(b==10){7(6.M){L c=6[0];7(E.12(c,"2k")){L e=c.3T,5I=[],11=c.11,2X=c.U=="2k-2X";7(e<0)K V;Q(L i=2X?e:0,2f=2X?e+1:11.M;i<2f;i++){L d=11[i];7(d.2p){b=E.14.1d&&!d.9J.1A.9y?d.1u:d.1A;7(2X)K b;5I.1g(b)}}K 5I}N K(6[0].1A||"").1r(/\\r/g,"")}K 10}K 6.R(J(){7(6.15!=1)K;7(b.1k==1M&&/5u|5t/.17(6.U))6.3k=(E.33(6.1A,b)>=0||E.33(6.31,b)>=0);N 7(E.12(6,"2k")){L a=b.1k==1M?b:[b];E("98",6).R(J(){6.2p=(E.33(6.1A,a)>=0||E.33(6.1u,a)>=0)});7(!a.M)6.3T=-1}N 6.1A=b})},3q:J(a){K a==10?(6.M?6[0].3d:V):6.4x().3t(a)},6S:J(a){K 6.5a(a).1V()},6Z:J(i){K 6.2K(i,i+1)},2K:J(){K 6.2F(1M.2l.2K.1i(6,18))},2c:J(b){K 6.2F(E.2c(6,J(a,i){K b.1P(a,i,a)}))},4R:J(){K 6.1b(6.54)},O:J(d,b){L a=d.23(".");a[1]=a[1]?"."+a[1]:"";7(b==V){L c=6.5n("8P"+a[1]+"!",[a[0]]);7(c==10&&6.M)c=E.O(6[0],d);K c==V&&a[1]?6.O(a[0]):c}N K 6.1N("8K"+a[1]+"!",[a[0],b]).R(J(){E.O(6,d,b)})},35:J(a){K 6.R(J(){E.35(6,a)})},3O:J(g,f,h,d){L e=6.M>1,3n;K 6.R(J(){7(!3n){3n=E.4a(g,6.2i);7(h)3n.8D()}L b=6;7(f&&E.12(6,"1O")&&E.12(3n[0],"4v"))b=6.3S("1U")[0]||6.38(6.2i.3s("1U"));L c=E([]);E.R(3n,J(){L a=e?E(6).5k(P)[0]:6;7(E.12(a,"1m")){c=c.1b(a)}N{7(a.15==1)c=c.1b(E("1m",a).1V());d.1P(b,a)}});c.R(6A)})}};E.2l.4T.2l=E.2l;J 6A(i,a){7(a.3Q)E.3P({1c:a.3Q,3l:S,1H:"1m"});N E.5g(a.1u||a.6x||a.3d||"");7(a.1a)a.1a.34(a)}E.1s=E.1n.1s=J(){L b=18[0]||{},i=1,M=18.M,5c=S,11;7(b.1k==8d){5c=b;b=18[1]||{};i=2}7(1o b!="3V"&&1o b!="J")b={};7(M==1){b=6;i=0}Q(;i<M;i++)7((11=18[i])!=V)Q(L a 1p 11){7(b===11[a])6w;7(5c&&11[a]&&1o 11[a]=="3V"&&b[a]&&!11[a].15)b[a]=E.1s(b[a],11[a]);N 7(11[a]!=10)b[a]=11[a]}K b};L F="3N"+(1B 3v()).3L(),6t=0,5b={};L H=/z-?4X|86-?84|1w|6k|7Z-?1R/i;E.1s({7Y:J(a){1e.$=D;7(a)1e.3N=w;K E},1q:J(a){K!!a&&1o a!="25"&&!a.12&&a.1k!=1M&&/J/i.17(a+"")},3E:J(a){K a.1F&&!a.1h||a.28&&a.2i&&!a.2i.1h},5g:J(a){a=E.3g(a);7(a){L b=T.3S("6f")[0]||T.1F,1m=T.3s("1m");1m.U="1u/4m";7(E.14.1d)1m.1u=a;N 1m.38(T.5r(a));b.38(1m);b.34(1m)}},12:J(b,a){K b.12&&b.12.2E()==a.2E()},1T:{},O:J(c,d,b){c=c==1e?5b:c;L a=c[F];7(!a)a=c[F]=++6t;7(d&&!E.1T[a])E.1T[a]={};7(b!=10)E.1T[a][d]=b;K d?E.1T[a][d]:a},35:J(c,b){c=c==1e?5b:c;L a=c[F];7(b){7(E.1T[a]){2V E.1T[a][b];b="";Q(b 1p E.1T[a])1Q;7(!b)E.35(c)}}N{1S{2V c[F]}1X(e){7(c.52)c.52(F)}2V E.1T[a]}},R:J(c,a,b){7(b){7(c.M==10){Q(L d 1p c)7(a.1i(c[d],b)===S)1Q}N Q(L i=0,M=c.M;i<M;i++)7(a.1i(c[i],b)===S)1Q}N{7(c.M==10){Q(L d 1p c)7(a.1P(c[d],d,c[d])===S)1Q}N Q(L i=0,M=c.M,1A=c[0];i<M&&a.1P(1A,i,1A)!==S;1A=c[++i]){}}K c},1l:J(b,a,c,i,d){7(E.1q(a))a=a.1P(b,i);K a&&a.1k==51&&c=="2o"&&!H.17(d)?a+"2S":a},1t:{1b:J(c,b){E.R((b||"").23(/\\s+/),J(i,a){7(c.15==1&&!E.1t.3Y(c.1t,a))c.1t+=(c.1t?" ":"")+a})},1V:J(c,b){7(c.15==1)c.1t=b!=10?E.3y(c.1t.23(/\\s+/),J(a){K!E.1t.3Y(b,a)}).6a(" "):""},3Y:J(b,a){K E.33(a,(b.1t||b).3X().23(/\\s+/))>-1}},68:J(b,c,a){L e={};Q(L d 1p c){e[d]=b.W[d];b.W[d]=c[d]}a.1P(b);Q(L d 1p c)b.W[d]=e[d]},1j:J(d,e,c){7(e=="27"||e=="1R"){L b,46={43:"4W",4U:"1Z",19:"3D"},3c=e=="27"?["7O","7M"]:["7J","7I"];J 5E(){b=e=="27"?d.7H:d.7F;L a=0,2N=0;E.R(3c,J(){a+=2M(E.2o(d,"7E"+6,P))||0;2N+=2M(E.2o(d,"2N"+6+"5X",P))||0});b-=24.7C(a+2N)}7(E(d).3H(":4d"))5E();N E.68(d,46,5E);K 24.2f(0,b)}K E.2o(d,e,c)},2o:J(e,k,j){L d;J 3x(b){7(!E.14.2d)K S;L a=T.4c.4K(b,V);K!a||a.4M("3x")==""}7(k=="1w"&&E.14.1d){d=E.1J(e.W,"1w");K d==""?"1":d}7(E.14.2z&&k=="19"){L c=e.W.50;e.W.50="0 7r 7o";e.W.50=c}7(k.1D(/4g/i))k=y;7(!j&&e.W&&e.W[k])d=e.W[k];N 7(T.4c&&T.4c.4K){7(k.1D(/4g/i))k="4g";k=k.1r(/([A-Z])/g,"-$1").2h();L h=T.4c.4K(e,V);7(h&&!3x(e))d=h.4M(k);N{L f=[],2C=[];Q(L a=e;a&&3x(a);a=a.1a)2C.4J(a);Q(L i=0;i<2C.M;i++)7(3x(2C[i])){f[i]=2C[i].W.19;2C[i].W.19="3D"}d=k=="19"&&f[2C.M-1]!=V?"2H":(h&&h.4M(k))||"";Q(L i=0;i<f.M;i++)7(f[i]!=V)2C[i].W.19=f[i]}7(k=="1w"&&d=="")d="1"}N 7(e.4n){L g=k.1r(/\\-(\\w)/g,J(a,b){K b.2E()});d=e.4n[k]||e.4n[g];7(!/^\\d+(2S)?$/i.17(d)&&/^\\d/.17(d)){L l=e.W.26,3K=e.3K.26;e.3K.26=e.4n.26;e.W.26=d||0;d=e.W.7f+"2S";e.W.26=l;e.3K.26=3K}}K d},4a:J(l,h){L k=[];h=h||T;7(1o h.3s==\'10\')h=h.2i||h[0]&&h[0].2i||T;E.R(l,J(i,d){7(!d)K;7(d.1k==51)d=d.3X();7(1o d=="25"){d=d.1r(/(<(\\w+)[^>]*?)\\/>/g,J(b,a,c){K c.1D(/^(aa|a6|7e|a5|4D|7a|a0|3m|9W|9U|9S)$/i)?b:a+"></"+c+">"});L f=E.3g(d).2h(),1x=h.3s("1x");L e=!f.1f("<9P")&&[1,"<2k 74=\'74\'>","</2k>"]||!f.1f("<9M")&&[1,"<73>","</73>"]||f.1D(/^<(9G|1U|9E|9B|9x)/)&&[1,"<1O>","</1O>"]||!f.1f("<4v")&&[2,"<1O><1U>","</1U></1O>"]||(!f.1f("<9w")||!f.1f("<9v"))&&[3,"<1O><1U><4v>","</4v></1U></1O>"]||!f.1f("<7e")&&[2,"<1O><1U></1U><6V>","</6V></1O>"]||E.14.1d&&[1,"1x<1x>","</1x>"]||[0,"",""];1x.3d=e[1]+d+e[2];2b(e[0]--)1x=1x.5o;7(E.14.1d){L g=!f.1f("<1O")&&f.1f("<1U")<0?1x.1C&&1x.1C.3p:e[1]=="<1O>"&&f.1f("<1U")<0?1x.3p:[];Q(L j=g.M-1;j>=0;--j)7(E.12(g[j],"1U")&&!g[j].3p.M)g[j].1a.34(g[j]);7(/^\\s/.17(d))1x.3o(h.5r(d.1D(/^\\s*/)[0]),1x.1C)}d=E.2I(1x.3p)}7(d.M===0&&(!E.12(d,"3u")&&!E.12(d,"2k")))K;7(d[0]==10||E.12(d,"3u")||d.11)k.1g(d);N k=E.37(k,d)});K k},1J:J(d,e,c){7(!d||d.15==3||d.15==8)K 10;L f=E.3E(d)?{}:E.46;7(e=="2p"&&E.14.2d)d.1a.3T;7(f[e]){7(c!=10)d[f[e]]=c;K d[f[e]]}N 7(E.14.1d&&e=="W")K E.1J(d.W,"9u",c);N 7(c==10&&E.14.1d&&E.12(d,"3u")&&(e=="9r"||e=="9o"))K d.9m(e).6K;N 7(d.28){7(c!=10){7(e=="U"&&E.12(d,"4D")&&d.1a)6Q"U 9i 9h\'t 9g 9e";d.9b(e,""+c)}7(E.14.1d&&/6O|3Q/.17(e)&&!E.3E(d))K d.4z(e,2);K d.4z(e)}N{7(e=="1w"&&E.14.1d){7(c!=10){d.6k=1;d.1E=(d.1E||"").1r(/6M\\([^)]*\\)/,"")+(2M(c).3X()=="96"?"":"6M(1w="+c*6L+")")}K d.1E&&d.1E.1f("1w=")>=0?(2M(d.1E.1D(/1w=([^)]*)/)[1])/6L).3X():""}e=e.1r(/-([a-z])/95,J(a,b){K b.2E()});7(c!=10)d[e]=c;K d[e]}},3g:J(a){K(a||"").1r(/^\\s+|\\s+$/g,"")},2I:J(b){L a=[];7(1o b!="93")Q(L i=0,M=b.M;i<M;i++)a.1g(b[i]);N a=b.2K(0);K a},33:J(b,a){Q(L i=0,M=a.M;i<M;i++)7(a[i]==b)K i;K-1},37:J(a,b){7(E.14.1d){Q(L i=0;b[i];i++)7(b[i].15!=8)a.1g(b[i])}N Q(L i=0;b[i];i++)a.1g(b[i]);K a},57:J(a){L c=[],2r={};1S{Q(L i=0,M=a.M;i<M;i++){L b=E.O(a[i]);7(!2r[b]){2r[b]=P;c.1g(a[i])}}}1X(e){c=a}K c},3y:J(c,a,d){L b=[];Q(L i=0,M=c.M;i<M;i++)7(!d&&a(c[i],i)||d&&!a(c[i],i))b.1g(c[i]);K b},2c:J(d,a){L c=[];Q(L i=0,M=d.M;i<M;i++){L b=a(d[i],i);7(b!==V&&b!=10){7(b.1k!=1M)b=[b];c=c.71(b)}}K c}});L v=8Y.8W.2h();E.14={5K:(v.1D(/.+(?:8T|8S|8R|8O)[\\/: ]([\\d.]+)/)||[])[1],2d:/77/.17(v),2z:/2z/.17(v),1d:/1d/.17(v)&&!/2z/.17(v),48:/48/.17(v)&&!/(8L|77)/.17(v)};L y=E.14.1d?"6H":"75";E.1s({8I:!E.14.1d||T.6F=="79",46:{"Q":"8F","8E":"1t","4g":y,75:y,6H:y,3d:"3d",1t:"1t",1A:"1A",2Y:"2Y",3k:"3k",8C:"8B",2p:"2p",8A:"8z",3T:"3T",6C:"6C",28:"28",12:"12"}});E.R({6B:J(a){K a.1a},8y:J(a){K E.4u(a,"1a")},8x:J(a){K E.2Z(a,2,"2B")},8v:J(a){K E.2Z(a,2,"4t")},8u:J(a){K E.4u(a,"2B")},8t:J(a){K E.4u(a,"4t")},8s:J(a){K E.5i(a.1a.1C,a)},8r:J(a){K E.5i(a.1C)},6z:J(a){K E.12(a,"8q")?a.8o||a.8n.T:E.2I(a.3p)}},J(c,d){E.1n[c]=J(b){L a=E.2c(6,d);7(b&&1o b=="25")a=E.3e(b,a);K 6.2F(E.57(a))}});E.R({6y:"3t",8m:"6q",3o:"6o",8l:"5a",8k:"6S"},J(c,b){E.1n[c]=J(){L a=18;K 6.R(J(){Q(L i=0,M=a.M;i<M;i++)E(a[i])[b](6)})}});E.R({8j:J(a){E.1J(6,a,"");7(6.15==1)6.52(a)},8i:J(a){E.1t.1b(6,a)},8h:J(a){E.1t.1V(6,a)},8g:J(a){E.1t[E.1t.3Y(6,a)?"1V":"1b"](6,a)},1V:J(a){7(!a||E.1E(a,[6]).r.M){E("*",6).1b(6).R(J(){E.16.1V(6);E.35(6)});7(6.1a)6.1a.34(6)}},4x:J(){E(">*",6).1V();2b(6.1C)6.34(6.1C)}},J(a,b){E.1n[a]=J(){K 6.R(b,18)}});E.R(["8f","5X"],J(i,c){L b=c.2h();E.1n[b]=J(a){K 6[0]==1e?E.14.2z&&T.1h["5e"+c]||E.14.2d&&1e["8e"+c]||T.6F=="79"&&T.1F["5e"+c]||T.1h["5e"+c]:6[0]==T?24.2f(24.2f(T.1h["5d"+c],T.1F["5d"+c]),24.2f(T.1h["5L"+c],T.1F["5L"+c])):a==10?(6.M?E.1j(6[0],b):V):6.1j(b,a.1k==4e?a:a+"2S")}});L C=E.14.2d&&4s(E.14.5K)<8c?"(?:[\\\\w*4r-]|\\\\\\\\.)":"(?:[\\\\w\\8b-\\8a*4r-]|\\\\\\\\.)",6v=1B 4q("^>\\\\s*("+C+"+)"),6u=1B 4q("^("+C+"+)(#)("+C+"+)"),6s=1B 4q("^([#.]?)("+C+"*)");E.1s({6r:{"":J(a,i,m){K m[2]=="*"||E.12(a,m[2])},"#":J(a,i,m){K a.4z("2w")==m[2]},":":{89:J(a,i,m){K i<m[3]-0},88:J(a,i,m){K i>m[3]-0},2Z:J(a,i,m){K m[3]-0==i},6Z:J(a,i,m){K m[3]-0==i},3j:J(a,i){K i==0},3J:J(a,i,m,r){K i==r.M-1},6n:J(a,i){K i%2==0},6l:J(a,i){K i%2},"3j-4p":J(a){K a.1a.3S("*")[0]==a},"3J-4p":J(a){K E.2Z(a.1a.5o,1,"4t")==a},"83-4p":J(a){K!E.2Z(a.1a.5o,2,"4t")},6B:J(a){K a.1C},4x:J(a){K!a.1C},82:J(a,i,m){K(a.6x||a.81||E(a).1u()||"").1f(m[3])>=0},4d:J(a){K"1Z"!=a.U&&E.1j(a,"19")!="2H"&&E.1j(a,"4U")!="1Z"},1Z:J(a){K"1Z"==a.U||E.1j(a,"19")=="2H"||E.1j(a,"4U")=="1Z"},80:J(a){K!a.2Y},2Y:J(a){K a.2Y},3k:J(a){K a.3k},2p:J(a){K a.2p||E.1J(a,"2p")},1u:J(a){K"1u"==a.U},5u:J(a){K"5u"==a.U},5t:J(a){K"5t"==a.U},59:J(a){K"59"==a.U},3I:J(a){K"3I"==a.U},58:J(a){K"58"==a.U},6j:J(a){K"6j"==a.U},6i:J(a){K"6i"==a.U},2G:J(a){K"2G"==a.U||E.12(a,"2G")},4D:J(a){K/4D|2k|6h|2G/i.17(a.12)},3Y:J(a,i,m){K E.2s(m[3],a).M},7X:J(a){K/h\\d/i.17(a.12)},7W:J(a){K E.3y(E.3G,J(b){K a==b.Y}).M}}},6g:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1B 4q("^([:.#]*)("+C+"+)")],3e:J(a,c,b){L d,2m=[];2b(a&&a!=d){d=a;L f=E.1E(a,c,b);a=f.t.1r(/^\\s*,\\s*/,"");2m=b?c=f.r:E.37(2m,f.r)}K 2m},2s:J(t,p){7(1o t!="25")K[t];7(p&&p.15!=1&&p.15!=9)K[];p=p||T;L d=[p],2r=[],3J,12;2b(t&&3J!=t){L r=[];3J=t;t=E.3g(t);L o=S;L g=6v;L m=g.2O(t);7(m){12=m[1].2E();Q(L i=0;d[i];i++)Q(L c=d[i].1C;c;c=c.2B)7(c.15==1&&(12=="*"||c.12.2E()==12))r.1g(c);d=r;t=t.1r(g,"");7(t.1f(" ")==0)6w;o=P}N{g=/^([>+~])\\s*(\\w*)/i;7((m=g.2O(t))!=V){r=[];L l={};12=m[2].2E();m=m[1];Q(L j=0,3f=d.M;j<3f;j++){L n=m=="~"||m=="+"?d[j].2B:d[j].1C;Q(;n;n=n.2B)7(n.15==1){L h=E.O(n);7(m=="~"&&l[h])1Q;7(!12||n.12.2E()==12){7(m=="~")l[h]=P;r.1g(n)}7(m=="+")1Q}}d=r;t=E.3g(t.1r(g,""));o=P}}7(t&&!o){7(!t.1f(",")){7(p==d[0])d.4l();2r=E.37(2r,d);r=d=[p];t=" "+t.6e(1,t.M)}N{L k=6u;L m=k.2O(t);7(m){m=[0,m[2],m[3],m[1]]}N{k=6s;m=k.2O(t)}m[2]=m[2].1r(/\\\\/g,"");L f=d[d.M-1];7(m[1]=="#"&&f&&f.5J&&!E.3E(f)){L q=f.5J(m[2]);7((E.14.1d||E.14.2z)&&q&&1o q.2w=="25"&&q.2w!=m[2])q=E(\'[@2w="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.12(q,m[3]))?[q]:[]}N{Q(L i=0;d[i];i++){L a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];7(a=="*"&&d[i].12.2h()=="3V")a="3m";r=E.37(r,d[i].3S(a))}7(m[1]==".")r=E.55(r,m[2]);7(m[1]=="#"){L e=[];Q(L i=0;r[i];i++)7(r[i].4z("2w")==m[2]){e=[r[i]];1Q}r=e}d=r}t=t.1r(k,"")}}7(t){L b=E.1E(t,r);d=r=b.r;t=E.3g(b.t)}}7(t)d=[];7(d&&p==d[0])d.4l();2r=E.37(2r,d);K 2r},55:J(r,m,a){m=" "+m+" ";L c=[];Q(L i=0;r[i];i++){L b=(" "+r[i].1t+" ").1f(m)>=0;7(!a&&b||a&&!b)c.1g(r[i])}K c},1E:J(t,r,h){L d;2b(t&&t!=d){d=t;L p=E.6g,m;Q(L i=0;p[i];i++){m=p[i].2O(t);7(m){t=t.7V(m[0].M);m[2]=m[2].1r(/\\\\/g,"");1Q}}7(!m)1Q;7(m[1]==":"&&m[2]=="56")r=G.17(m[3])?E.1E(m[3],r,P).r:E(r).56(m[3]);N 7(m[1]==".")r=E.55(r,m[2],h);N 7(m[1]=="["){L g=[],U=m[3];Q(L i=0,3f=r.M;i<3f;i++){L a=r[i],z=a[E.46[m[2]]||m[2]];7(z==V||/6O|3Q|2p/.17(m[2]))z=E.1J(a,m[2])||\'\';7((U==""&&!!z||U=="="&&z==m[5]||U=="!="&&z!=m[5]||U=="^="&&z&&!z.1f(m[5])||U=="$="&&z.6e(z.M-m[5].M)==m[5]||(U=="*="||U=="~=")&&z.1f(m[5])>=0)^h)g.1g(a)}r=g}N 7(m[1]==":"&&m[2]=="2Z-4p"){L e={},g=[],17=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2O(m[3]=="6n"&&"2n"||m[3]=="6l"&&"2n+1"||!/\\D/.17(m[3])&&"7U+"+m[3]||m[3]),3j=(17[1]+(17[2]||1))-0,d=17[3]-0;Q(L i=0,3f=r.M;i<3f;i++){L j=r[i],1a=j.1a,2w=E.O(1a);7(!e[2w]){L c=1;Q(L n=1a.1C;n;n=n.2B)7(n.15==1)n.4k=c++;e[2w]=P}L b=S;7(3j==0){7(j.4k==d)b=P}N 7((j.4k-d)%3j==0&&(j.4k-d)/3j>=0)b=P;7(b^h)g.1g(j)}r=g}N{L f=E.6r[m[1]];7(1o f=="3V")f=f[m[2]];7(1o f=="25")f=6c("S||J(a,i){K "+f+";}");r=E.3y(r,J(a,i){K f(a,i,m,r)},h)}}K{r:r,t:t}},4u:J(b,c){L d=[];L a=b[c];2b(a&&a!=T){7(a.15==1)d.1g(a);a=a[c]}K d},2Z:J(a,e,c,b){e=e||1;L d=0;Q(;a;a=a[c])7(a.15==1&&++d==e)1Q;K a},5i:J(n,a){L r=[];Q(;n;n=n.2B){7(n.15==1&&(!a||n!=a))r.1g(n)}K r}});E.16={1b:J(f,i,g,e){7(f.15==3||f.15==8)K;7(E.14.1d&&f.53!=10)f=1e;7(!g.2D)g.2D=6.2D++;7(e!=10){L h=g;g=J(){K h.1i(6,18)};g.O=e;g.2D=h.2D}L j=E.O(f,"2R")||E.O(f,"2R",{}),1v=E.O(f,"1v")||E.O(f,"1v",J(){L a;7(1o E=="10"||E.16.5f)K a;a=E.16.1v.1i(18.3R.Y,18);K a});1v.Y=f;E.R(i.23(/\\s+/),J(c,b){L a=b.23(".");b=a[0];g.U=a[1];L d=j[b];7(!d){d=j[b]={};7(!E.16.2y[b]||E.16.2y[b].4j.1P(f)===S){7(f.3F)f.3F(b,1v,S);N 7(f.6b)f.6b("4i"+b,1v)}}d[g.2D]=g;E.16.2a[b]=P});f=V},2D:1,2a:{},1V:J(e,h,f){7(e.15==3||e.15==8)K;L i=E.O(e,"2R"),29,4X;7(i){7(h==10||(1o h=="25"&&h.7T(0)=="."))Q(L g 1p i)6.1V(e,g+(h||""));N{7(h.U){f=h.2q;h=h.U}E.R(h.23(/\\s+/),J(b,a){L c=a.23(".");a=c[0];7(i[a]){7(f)2V i[a][f.2D];N Q(f 1p i[a])7(!c[1]||i[a][f].U==c[1])2V i[a][f];Q(29 1p i[a])1Q;7(!29){7(!E.16.2y[a]||E.16.2y[a].4h.1P(e)===S){7(e.67)e.67(a,E.O(e,"1v"),S);N 7(e.66)e.66("4i"+a,E.O(e,"1v"))}29=V;2V i[a]}}})}Q(29 1p i)1Q;7(!29){L d=E.O(e,"1v");7(d)d.Y=V;E.35(e,"2R");E.35(e,"1v")}}},1N:J(g,c,d,f,h){c=E.2I(c||[]);7(g.1f("!")>=0){g=g.2K(0,-1);L a=P}7(!d){7(6.2a[g])E("*").1b([1e,T]).1N(g,c)}N{7(d.15==3||d.15==8)K 10;L b,29,1n=E.1q(d[g]||V),16=!c[0]||!c[0].36;7(16)c.4J(6.4Z({U:g,2L:d}));c[0].U=g;7(a)c[0].65=P;7(E.1q(E.O(d,"1v")))b=E.O(d,"1v").1i(d,c);7(!1n&&d["4i"+g]&&d["4i"+g].1i(d,c)===S)b=S;7(16)c.4l();7(h&&E.1q(h)){29=h.1i(d,b==V?c:c.71(b));7(29!==10)b=29}7(1n&&f!==S&&b!==S&&!(E.12(d,\'a\')&&g=="4V")){6.5f=P;1S{d[g]()}1X(e){}}6.5f=S}K b},1v:J(c){L a;c=E.16.4Z(c||1e.16||{});L b=c.U.23(".");c.U=b[0];L f=E.O(6,"2R")&&E.O(6,"2R")[c.U],42=1M.2l.2K.1P(18,1);42.4J(c);Q(L j 1p f){L d=f[j];42[0].2q=d;42[0].O=d.O;7(!b[1]&&!c.65||d.U==b[1]){L e=d.1i(6,42);7(a!==S)a=e;7(e===S){c.36();c.44()}}}7(E.14.1d)c.2L=c.36=c.44=c.2q=c.O=V;K a},4Z:J(c){L a=c;c=E.1s({},a);c.36=J(){7(a.36)a.36();a.7S=S};c.44=J(){7(a.44)a.44();a.7R=P};7(!c.2L)c.2L=c.7Q||T;7(c.2L.15==3)c.2L=a.2L.1a;7(!c.4S&&c.5w)c.4S=c.5w==c.2L?c.7P:c.5w;7(c.64==V&&c.63!=V){L b=T.1F,1h=T.1h;c.64=c.63+(b&&b.2v||1h&&1h.2v||0)-(b.62||0);c.7N=c.7L+(b&&b.2x||1h&&1h.2x||0)-(b.60||0)}7(!c.3c&&((c.4f||c.4f===0)?c.4f:c.5Z))c.3c=c.4f||c.5Z;7(!c.7b&&c.5Y)c.7b=c.5Y;7(!c.3c&&c.2G)c.3c=(c.2G&1?1:(c.2G&2?3:(c.2G&4?2:0)));K c},2y:{21:{4j:J(){5M();K},4h:J(){K}},3C:{4j:J(){7(E.14.1d)K S;E(6).2j("4P",E.16.2y.3C.2q);K P},4h:J(){7(E.14.1d)K S;E(6).3w("4P",E.16.2y.3C.2q);K P},2q:J(a){7(I(a,6))K P;18[0].U="3C";K E.16.1v.1i(6,18)}},3B:{4j:J(){7(E.14.1d)K S;E(6).2j("4O",E.16.2y.3B.2q);K P},4h:J(){7(E.14.1d)K S;E(6).3w("4O",E.16.2y.3B.2q);K P},2q:J(a){7(I(a,6))K P;18[0].U="3B";K E.16.1v.1i(6,18)}}}};E.1n.1s({2j:J(c,a,b){K c=="4H"?6.2X(c,a,b):6.R(J(){E.16.1b(6,c,b||a,b&&a)})},2X:J(d,b,c){K 6.R(J(){E.16.1b(6,d,J(a){E(6).3w(a);K(c||b).1i(6,18)},c&&b)})},3w:J(a,b){K 6.R(J(){E.16.1V(6,a,b)})},1N:J(c,a,b){K 6.R(J(){E.16.1N(c,a,6,P,b)})},5n:J(c,a,b){7(6[0])K E.16.1N(c,a,6[0],S,b);K 10},2g:J(){L b=18;K 6.4V(J(a){6.4N=0==6.4N?1:0;a.36();K b[6.4N].1i(6,18)||S})},7D:J(a,b){K 6.2j(\'3C\',a).2j(\'3B\',b)},21:J(a){5M();7(E.2Q)a.1P(T,E);N E.3A.1g(J(){K a.1P(6,E)});K 6}});E.1s({2Q:S,3A:[],21:J(){7(!E.2Q){E.2Q=P;7(E.3A){E.R(E.3A,J(){6.1i(T)});E.3A=V}E(T).5n("21")}}});L x=S;J 5M(){7(x)K;x=P;7(T.3F&&!E.14.2z)T.3F("5W",E.21,S);7(E.14.1d&&1e==3b)(J(){7(E.2Q)K;1S{T.1F.7B("26")}1X(3a){3z(18.3R,0);K}E.21()})();7(E.14.2z)T.3F("5W",J(){7(E.2Q)K;Q(L i=0;i<T.4L.M;i++)7(T.4L[i].2Y){3z(18.3R,0);K}E.21()},S);7(E.14.2d){L a;(J(){7(E.2Q)K;7(T.39!="5V"&&T.39!="1y"){3z(18.3R,0);K}7(a===10)a=E("W, 7a[7A=7z]").M;7(T.4L.M!=a){3z(18.3R,0);K}E.21()})()}E.16.1b(1e,"3U",E.21)}E.R(("7y,7x,3U,7w,5d,4H,4V,7v,"+"7G,7u,7t,4P,4O,7s,2k,"+"58,7K,7q,7p,3a").23(","),J(i,b){E.1n[b]=J(a){K a?6.2j(b,a):6.1N(b)}});L I=J(a,c){L b=a.4S;2b(b&&b!=c)1S{b=b.1a}1X(3a){b=c}K b==c};E(1e).2j("4H",J(){E("*").1b(T).3w()});E.1n.1s({3U:J(g,d,c){7(E.1q(g))K 6.2j("3U",g);L e=g.1f(" ");7(e>=0){L i=g.2K(e,g.M);g=g.2K(0,e)}c=c||J(){};L f="4Q";7(d)7(E.1q(d)){c=d;d=V}N{d=E.3m(d);f="61"}L h=6;E.3P({1c:g,U:f,1H:"3q",O:d,1y:J(a,b){7(b=="1W"||b=="5U")h.3q(i?E("<1x/>").3t(a.4b.1r(/<1m(.|\\s)*?\\/1m>/g,"")).2s(i):a.4b);h.R(c,[a.4b,b,a])}});K 6},7n:J(){K E.3m(6.5T())},5T:J(){K 6.2c(J(){K E.12(6,"3u")?E.2I(6.7m):6}).1E(J(){K 6.31&&!6.2Y&&(6.3k||/2k|6h/i.17(6.12)||/1u|1Z|3I/i.17(6.U))}).2c(J(i,c){L b=E(6).5O();K b==V?V:b.1k==1M?E.2c(b,J(a,i){K{31:c.31,1A:a}}):{31:c.31,1A:b}}).22()}});E.R("5S,6d,5R,6D,5Q,6m".23(","),J(i,o){E.1n[o]=J(f){K 6.2j(o,f)}});L B=(1B 3v).3L();E.1s({22:J(d,b,a,c){7(E.1q(b)){a=b;b=V}K E.3P({U:"4Q",1c:d,O:b,1W:a,1H:c})},7l:J(b,a){K E.22(b,V,a,"1m")},7k:J(c,b,a){K E.22(c,b,a,"3i")},7i:J(d,b,a,c){7(E.1q(b)){a=b;b={}}K E.3P({U:"61",1c:d,O:b,1W:a,1H:c})},85:J(a){E.1s(E.4I,a)},4I:{2a:P,U:"4Q",2U:0,5P:"4o/x-7h-3u-7g",5N:P,3l:P,O:V,6p:V,3I:V,49:{3M:"4o/3M, 1u/3M",3q:"1u/3q",1m:"1u/4m, 4o/4m",3i:"4o/3i, 1u/4m",1u:"1u/a7",4G:"*/*"}},4F:{},3P:J(s){L f,2W=/=\\?(&|$)/g,1z,O;s=E.1s(P,s,E.1s(P,{},E.4I,s));7(s.O&&s.5N&&1o s.O!="25")s.O=E.3m(s.O);7(s.1H=="4E"){7(s.U.2h()=="22"){7(!s.1c.1D(2W))s.1c+=(s.1c.1D(/\\?/)?"&":"?")+(s.4E||"7d")+"=?"}N 7(!s.O||!s.O.1D(2W))s.O=(s.O?s.O+"&":"")+(s.4E||"7d")+"=?";s.1H="3i"}7(s.1H=="3i"&&(s.O&&s.O.1D(2W)||s.1c.1D(2W))){f="4E"+B++;7(s.O)s.O=(s.O+"").1r(2W,"="+f+"$1");s.1c=s.1c.1r(2W,"="+f+"$1");s.1H="1m";1e[f]=J(a){O=a;1W();1y();1e[f]=10;1S{2V 1e[f]}1X(e){}7(h)h.34(g)}}7(s.1H=="1m"&&s.1T==V)s.1T=S;7(s.1T===S&&s.U.2h()=="22"){L i=(1B 3v()).3L();L j=s.1c.1r(/(\\?|&)4r=.*?(&|$)/,"$a4="+i+"$2");s.1c=j+((j==s.1c)?(s.1c.1D(/\\?/)?"&":"?")+"4r="+i:"")}7(s.O&&s.U.2h()=="22"){s.1c+=(s.1c.1D(/\\?/)?"&":"?")+s.O;s.O=V}7(s.2a&&!E.5H++)E.16.1N("5S");7((!s.1c.1f("a3")||!s.1c.1f("//"))&&s.1H=="1m"&&s.U.2h()=="22"){L h=T.3S("6f")[0];L g=T.3s("1m");g.3Q=s.1c;7(s.7c)g.a2=s.7c;7(!f){L l=S;g.9Z=g.9Y=J(){7(!l&&(!6.39||6.39=="5V"||6.39=="1y")){l=P;1W();1y();h.34(g)}}}h.38(g);K 10}L m=S;L k=1e.78?1B 78("9X.9V"):1B 76();k.9T(s.U,s.1c,s.3l,s.6p,s.3I);1S{7(s.O)k.4C("9R-9Q",s.5P);7(s.5C)k.4C("9O-5A-9N",E.4F[s.1c]||"9L, 9K 9I 9H 5z:5z:5z 9F");k.4C("X-9C-9A","76");k.4C("9z",s.1H&&s.49[s.1H]?s.49[s.1H]+", */*":s.49.4G)}1X(e){}7(s.6Y)s.6Y(k);7(s.2a)E.16.1N("6m",[k,s]);L c=J(a){7(!m&&k&&(k.39==4||a=="2U")){m=P;7(d){6I(d);d=V}1z=a=="2U"&&"2U"||!E.6X(k)&&"3a"||s.5C&&E.6J(k,s.1c)&&"5U"||"1W";7(1z=="1W"){1S{O=E.6W(k,s.1H)}1X(e){1z="5x"}}7(1z=="1W"){L b;1S{b=k.5q("6U-5A")}1X(e){}7(s.5C&&b)E.4F[s.1c]=b;7(!f)1W()}N E.5v(s,k,1z);1y();7(s.3l)k=V}};7(s.3l){L d=53(c,13);7(s.2U>0)3z(J(){7(k){k.9t();7(!m)c("2U")}},s.2U)}1S{k.9s(s.O)}1X(e){E.5v(s,k,V,e)}7(!s.3l)c();J 1W(){7(s.1W)s.1W(O,1z);7(s.2a)E.16.1N("5Q",[k,s])}J 1y(){7(s.1y)s.1y(k,1z);7(s.2a)E.16.1N("5R",[k,s]);7(s.2a&&!--E.5H)E.16.1N("6d")}K k},5v:J(s,a,b,e){7(s.3a)s.3a(a,b,e);7(s.2a)E.16.1N("6D",[a,s,e])},5H:0,6X:J(r){1S{K!r.1z&&9q.9p=="59:"||(r.1z>=6T&&r.1z<9n)||r.1z==6R||r.1z==9l||E.14.2d&&r.1z==10}1X(e){}K S},6J:J(a,c){1S{L b=a.5q("6U-5A");K a.1z==6R||b==E.4F[c]||E.14.2d&&a.1z==10}1X(e){}K S},6W:J(r,b){L c=r.5q("9k-U");L d=b=="3M"||!b&&c&&c.1f("3M")>=0;L a=d?r.9j:r.4b;7(d&&a.1F.28=="5x")6Q"5x";7(b=="1m")E.5g(a);7(b=="3i")a=6c("("+a+")");K a},3m:J(a){L s=[];7(a.1k==1M||a.5h)E.R(a,J(){s.1g(3r(6.31)+"="+3r(6.1A))});N Q(L j 1p a)7(a[j]&&a[j].1k==1M)E.R(a[j],J(){s.1g(3r(j)+"="+3r(6))});N s.1g(3r(j)+"="+3r(a[j]));K s.6a("&").1r(/%20/g,"+")}});E.1n.1s({1G:J(c,b){K c?6.2e({1R:"1G",27:"1G",1w:"1G"},c,b):6.1E(":1Z").R(J(){6.W.19=6.5s||"";7(E.1j(6,"19")=="2H"){L a=E("<"+6.28+" />").6y("1h");6.W.19=a.1j("19");7(6.W.19=="2H")6.W.19="3D";a.1V()}}).3h()},1I:J(b,a){K b?6.2e({1R:"1I",27:"1I",1w:"1I"},b,a):6.1E(":4d").R(J(){6.5s=6.5s||E.1j(6,"19");6.W.19="2H"}).3h()},6N:E.1n.2g,2g:J(a,b){K E.1q(a)&&E.1q(b)?6.6N(a,b):a?6.2e({1R:"2g",27:"2g",1w:"2g"},a,b):6.R(J(){E(6)[E(6).3H(":1Z")?"1G":"1I"]()})},9f:J(b,a){K 6.2e({1R:"1G"},b,a)},9d:J(b,a){K 6.2e({1R:"1I"},b,a)},9c:J(b,a){K 6.2e({1R:"2g"},b,a)},9a:J(b,a){K 6.2e({1w:"1G"},b,a)},99:J(b,a){K 6.2e({1w:"1I"},b,a)},97:J(c,a,b){K 6.2e({1w:a},c,b)},2e:J(l,k,j,h){L i=E.6P(k,j,h);K 6[i.2P===S?"R":"2P"](J(){7(6.15!=1)K S;L g=E.1s({},i);L f=E(6).3H(":1Z"),4A=6;Q(L p 1p l){7(l[p]=="1I"&&f||l[p]=="1G"&&!f)K E.1q(g.1y)&&g.1y.1i(6);7(p=="1R"||p=="27"){g.19=E.1j(6,"19");g.32=6.W.32}}7(g.32!=V)6.W.32="1Z";g.40=E.1s({},l);E.R(l,J(c,a){L e=1B E.2t(4A,g,c);7(/2g|1G|1I/.17(a))e[a=="2g"?f?"1G":"1I":a](l);N{L b=a.3X().1D(/^([+-]=)?([\\d+-.]+)(.*)$/),1Y=e.2m(P)||0;7(b){L d=2M(b[2]),2A=b[3]||"2S";7(2A!="2S"){4A.W[c]=(d||1)+2A;1Y=((d||1)/e.2m(P))*1Y;4A.W[c]=1Y+2A}7(b[1])d=((b[1]=="-="?-1:1)*d)+1Y;e.45(1Y,d,2A)}N e.45(1Y,a,"")}});K P})},2P:J(a,b){7(E.1q(a)||(a&&a.1k==1M)){b=a;a="2t"}7(!a||(1o a=="25"&&!b))K A(6[0],a);K 6.R(J(){7(b.1k==1M)A(6,a,b);N{A(6,a).1g(b);7(A(6,a).M==1)b.1i(6)}})},94:J(b,c){L a=E.3G;7(b)6.2P([]);6.R(J(){Q(L i=a.M-1;i>=0;i--)7(a[i].Y==6){7(c)a[i](P);a.72(i,1)}});7(!c)6.5p();K 6}});L A=J(b,c,a){7(!b)K 10;c=c||"2t";L q=E.O(b,c+"2P");7(!q||a)q=E.O(b,c+"2P",a?E.2I(a):[]);K q};E.1n.5p=J(a){a=a||"2t";K 6.R(J(){L q=A(6,a);q.4l();7(q.M)q[0].1i(6)})};E.1s({6P:J(b,a,c){L d=b&&b.1k==92?b:{1y:c||!c&&a||E.1q(b)&&b,2u:b,3Z:c&&a||a&&a.1k!=91&&a};d.2u=(d.2u&&d.2u.1k==51?d.2u:{90:8Z,9D:6T}[d.2u])||8X;d.5y=d.1y;d.1y=J(){7(d.2P!==S)E(6).5p();7(E.1q(d.5y))d.5y.1i(6)};K d},3Z:{70:J(p,n,b,a){K b+a*p},5j:J(p,n,b,a){K((-24.8V(p*24.8U)/2)+0.5)*a+b}},3G:[],3W:V,2t:J(b,c,a){6.11=c;6.Y=b;6.1l=a;7(!c.47)c.47={}}});E.2t.2l={4y:J(){7(6.11.30)6.11.30.1i(6.Y,[6.2J,6]);(E.2t.30[6.1l]||E.2t.30.4G)(6);7(6.1l=="1R"||6.1l=="27")6.Y.W.19="3D"},2m:J(a){7(6.Y[6.1l]!=V&&6.Y.W[6.1l]==V)K 6.Y[6.1l];L r=2M(E.1j(6.Y,6.1l,a));K r&&r>-8Q?r:2M(E.2o(6.Y,6.1l))||0},45:J(c,b,d){6.5B=(1B 3v()).3L();6.1Y=c;6.3h=b;6.2A=d||6.2A||"2S";6.2J=6.1Y;6.4B=6.4w=0;6.4y();L e=6;J t(a){K e.30(a)}t.Y=6.Y;E.3G.1g(t);7(E.3W==V){E.3W=53(J(){L a=E.3G;Q(L i=0;i<a.M;i++)7(!a[i]())a.72(i--,1);7(!a.M){6I(E.3W);E.3W=V}},13)}},1G:J(){6.11.47[6.1l]=E.1J(6.Y.W,6.1l);6.11.1G=P;6.45(0,6.2m());7(6.1l=="27"||6.1l=="1R")6.Y.W[6.1l]="8N";E(6.Y).1G()},1I:J(){6.11.47[6.1l]=E.1J(6.Y.W,6.1l);6.11.1I=P;6.45(6.2m(),0)},30:J(a){L t=(1B 3v()).3L();7(a||t>6.11.2u+6.5B){6.2J=6.3h;6.4B=6.4w=1;6.4y();6.11.40[6.1l]=P;L b=P;Q(L i 1p 6.11.40)7(6.11.40[i]!==P)b=S;7(b){7(6.11.19!=V){6.Y.W.32=6.11.32;6.Y.W.19=6.11.19;7(E.1j(6.Y,"19")=="2H")6.Y.W.19="3D"}7(6.11.1I)6.Y.W.19="2H";7(6.11.1I||6.11.1G)Q(L p 1p 6.11.40)E.1J(6.Y.W,p,6.11.47[p])}7(b&&E.1q(6.11.1y))6.11.1y.1i(6.Y);K S}N{L n=t-6.5B;6.4w=n/6.11.2u;6.4B=E.3Z[6.11.3Z||(E.3Z.5j?"5j":"70")](6.4w,n,0,1,6.11.2u);6.2J=6.1Y+((6.3h-6.1Y)*6.4B);6.4y()}K P}};E.2t.30={2v:J(a){a.Y.2v=a.2J},2x:J(a){a.Y.2x=a.2J},1w:J(a){E.1J(a.Y.W,"1w",a.2J)},4G:J(a){a.Y.W[a.1l]=a.2J+a.2A}};E.1n.5L=J(){L b=0,3b=0,Y=6[0],5l;7(Y)8M(E.14){L d=Y.1a,41=Y,1K=Y.1K,1L=Y.2i,5D=2d&&4s(5K)<8J&&!/a1/i.17(v),2T=E.1j(Y,"43")=="2T";7(Y.6G){L c=Y.6G();1b(c.26+24.2f(1L.1F.2v,1L.1h.2v),c.3b+24.2f(1L.1F.2x,1L.1h.2x));1b(-1L.1F.62,-1L.1F.60)}N{1b(Y.5G,Y.5F);2b(1K){1b(1K.5G,1K.5F);7(48&&!/^t(8H|d|h)$/i.17(1K.28)||2d&&!5D)2N(1K);7(!2T&&E.1j(1K,"43")=="2T")2T=P;41=/^1h$/i.17(1K.28)?41:1K;1K=1K.1K}2b(d&&d.28&&!/^1h|3q$/i.17(d.28)){7(!/^8G|1O.*$/i.17(E.1j(d,"19")))1b(-d.2v,-d.2x);7(48&&E.1j(d,"32")!="4d")2N(d);d=d.1a}7((5D&&(2T||E.1j(41,"43")=="4W"))||(48&&E.1j(41,"43")!="4W"))1b(-1L.1h.5G,-1L.1h.5F);7(2T)1b(24.2f(1L.1F.2v,1L.1h.2v),24.2f(1L.1F.2x,1L.1h.2x))}5l={3b:3b,26:b}}J 2N(a){1b(E.2o(a,"a8",P),E.2o(a,"a9",P))}J 1b(l,t){b+=4s(l)||0;3b+=4s(t)||0}K 5l}})();',62,631,'||||||this|if||||||||||||||||||||||||||||||||||||||function|return|var|length|else|data|true|for|each|false|document|type|null|style||elem||undefined|options|nodeName||browser|nodeType|event|test|arguments|display|parentNode|add|url|msie|window|indexOf|push|body|apply|css|constructor|prop|script|fn|typeof|in|isFunction|replace|extend|className|text|handle|opacity|div|complete|status|value|new|firstChild|match|filter|documentElement|show|dataType|hide|attr|offsetParent|doc|Array|trigger|table|call|break|height|try|cache|tbody|remove|success|catch|start|hidden||ready|get|split|Math|string|left|width|tagName|ret|global|while|map|safari|animate|max|toggle|toLowerCase|ownerDocument|bind|select|prototype|cur||curCSS|selected|handler|done|find|fx|duration|scrollLeft|id|scrollTop|special|opera|unit|nextSibling|stack|guid|toUpperCase|pushStack|button|none|makeArray|now|slice|target|parseFloat|border|exec|queue|isReady|events|px|fixed|timeout|delete|jsre|one|disabled|nth|step|name|overflow|inArray|removeChild|removeData|preventDefault|merge|appendChild|readyState|error|top|which|innerHTML|multiFilter|rl|trim|end|json|first|checked|async|param|elems|insertBefore|childNodes|html|encodeURIComponent|createElement|append|form|Date|unbind|color|grep|setTimeout|readyList|mouseleave|mouseenter|block|isXMLDoc|addEventListener|timers|is|password|last|runtimeStyle|getTime|xml|jQuery|domManip|ajax|src|callee|getElementsByTagName|selectedIndex|load|object|timerId|toString|has|easing|curAnim|offsetChild|args|position|stopPropagation|custom|props|orig|mozilla|accepts|clean|responseText|defaultView|visible|String|charCode|float|teardown|on|setup|nodeIndex|shift|javascript|currentStyle|application|child|RegExp|_|parseInt|previousSibling|dir|tr|state|empty|update|getAttribute|self|pos|setRequestHeader|input|jsonp|lastModified|_default|unload|ajaxSettings|unshift|getComputedStyle|styleSheets|getPropertyValue|lastToggle|mouseout|mouseover|GET|andSelf|relatedTarget|init|visibility|click|absolute|index|container|fix|outline|Number|removeAttribute|setInterval|prevObject|classFilter|not|unique|submit|file|after|windowData|deep|scroll|client|triggered|globalEval|jquery|sibling|swing|clone|results|wrapAll|triggerHandler|lastChild|dequeue|getResponseHeader|createTextNode|oldblock|checkbox|radio|handleError|fromElement|parsererror|old|00|Modified|startTime|ifModified|safari2|getWH|offsetTop|offsetLeft|active|values|getElementById|version|offset|bindReady|processData|val|contentType|ajaxSuccess|ajaxComplete|ajaxStart|serializeArray|notmodified|loaded|DOMContentLoaded|Width|ctrlKey|keyCode|clientTop|POST|clientLeft|clientX|pageX|exclusive|detachEvent|removeEventListener|swap|cloneNode|join|attachEvent|eval|ajaxStop|substr|head|parse|textarea|reset|image|zoom|odd|ajaxSend|even|before|username|prepend|expr|quickClass|uuid|quickID|quickChild|continue|textContent|appendTo|contents|evalScript|parent|defaultValue|ajaxError|setArray|compatMode|getBoundingClientRect|styleFloat|clearInterval|httpNotModified|nodeValue|100|alpha|_toggle|href|speed|throw|304|replaceWith|200|Last|colgroup|httpData|httpSuccess|beforeSend|eq|linear|concat|splice|fieldset|multiple|cssFloat|XMLHttpRequest|webkit|ActiveXObject|CSS1Compat|link|metaKey|scriptCharset|callback|col|pixelLeft|urlencoded|www|post|hasClass|getJSON|getScript|elements|serialize|black|keyup|keypress|solid|change|mousemove|mouseup|dblclick|resize|focus|blur|stylesheet|rel|doScroll|round|hover|padding|offsetHeight|mousedown|offsetWidth|Bottom|Top|keydown|clientY|Right|pageY|Left|toElement|srcElement|cancelBubble|returnValue|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|ajaxSetup|font|size|gt|lt|uFFFF|u0128|417|Boolean|inner|Height|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|contentWindow|contentDocument|wrap|iframe|children|siblings|prevAll|nextAll|prev|wrapInner|next|parents|maxLength|maxlength|readOnly|readonly|reverse|class|htmlFor|inline|able|boxModel|522|setData|compatible|with|1px|ie|getData|10000|ra|it|rv|PI|cos|userAgent|400|navigator|600|slow|Function|Object|array|stop|ig|NaN|fadeTo|option|fadeOut|fadeIn|setAttribute|slideToggle|slideUp|changed|slideDown|be|can|property|responseXML|content|1223|getAttributeNode|300|method|protocol|location|action|send|abort|cssText|th|td|cap|specified|Accept|With|colg|Requested|fast|tfoot|GMT|thead|1970|Jan|attributes|01|Thu|leg|Since|If|opt|Type|Content|embed|open|area|XMLHTTP|hr|Microsoft|onreadystatechange|onload|meta|adobeair|charset|http|1_|img|br|plain|borderLeftWidth|borderTopWidth|abbr'.split('|'),0,{}))
\ No newline at end of file
Index: htmlparser/manual/js/ui.tabs.pack.js
===================================================================
RCS file: htmlparser/manual/js/ui.tabs.pack.js
diff -N htmlparser/manual/js/ui.tabs.pack.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/manual/js/ui.tabs.pack.js	4 Jul 2008 07:30:18 -0000
@@ -0,0 +1,10 @@
+/*
+ * Tabs 3 - New Wave Tabs
+ *
+ * Copyright (c) 2007 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Tabs
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(6($){$.4=$.4||{};$.2o.3=6(){7 b=1K 1q[0]==\'1X\'&&1q[0];7 c=b&&1P.1N.2g.2c(1q,1)||1q;l b==\'C\'?$.m(2[0],\'4-3\').$3.C:2.I(6(){5(b){7 a=$.m(2,\'4-3\');a[b].2n(a,c)}D 2l $.4.3(2,c[0]||{})})};$.4.3=6(e,f){7 d=2;2.q=e;2.8=$.1H({p:0,S:f.p===L,12:\'1A\',t:[],G:L,1l:\'2B&#2x;\',K:y,1R:\'4-3-\',1j:{},X:L,1Q:\'<E><a x="#{x}"><1h>#{1g}</1h></a></E>\',1v:\'<1L></1L>\',1f:\'4-3-2f\',w:\'4-3-p\',1t:\'4-3-S\',Q:\'4-3-t\',U:\'4-3-1e\',M:\'4-3-Y\',1s:\'4-3-2Y\'},f);5(f.p===L)2.8.p=L;2.8.12+=\'.4-3\';2.8.G=$.G&&$.G.28==2V&&2.8.G;$(e).1b(\'2T.4-3\',6(b,c,a){5((/^p/).27(c))d.1o(a);D{d.8[c]=a;d.11()}}).1b(\'2Q.4-3\',6(a,b){l d.8[b]});$.m(e,\'4-3\',2);2.11(1a)};$.1H($.4.3.1N,{1z:6(a){l a.22&&a.22.V(/\\s/g,\'1Z\').V(/[^A-2A-2y-9\\-1Z:\\.]/g,\'\')||2.8.1R+$.m(a)},4:6(a,b){l{2w:2,8:2.8,2v:a,1e:b}},11:6(f){2.$u=$(\'E:2s(a[x])\',2.q);2.$3=2.$u.1i(6(){l $(\'a\',2)[0]});2.$k=$([]);7 e=2,o=2.8;2.$3.I(6(i,a){5(a.H&&a.H.V(\'#\',\'\'))e.$k=e.$k.17(a.H);D 5($(a).W(\'x\')!=\'#\'){$.m(a,\'x.4-3\',a.x);$.m(a,\'z.4-3\',a.x);7 b=e.1z(a);a.x=\'#\'+b;7 c=$(\'#\'+b);5(!c.C){c=$(o.1v).W(\'16\',b).v(o.U).2m(e.$k[i-1]||e.q);c.m(\'15.4-3\',1a)}e.$k=e.$k.17(c)}D o.t.1O(i+1)});5(f){$(2.q).J(o.1f)||$(2.q).v(o.1f);2.$k.I(6(){7 a=$(2);a.J(o.U)||a.v(o.U)});2.$3.I(6(i,a){5(1w.H){5(a.H==1w.H){o.p=i;5($.O.14||$.O.2k){7 b=$(1w.H),1M=b.W(\'16\');b.W(\'16\',\'\');1u(6(){b.W(\'16\',1M)},2j)}2i(0,0);l y}}D 5(o.G){7 c=2h($.G(\'4-3\'+$.m(e.q)),10);5(c&&e.$3[c]){o.p=c;l y}}D 5(e.$u.F(i).J(o.w)){o.p=i;l y}});2.$k.v(o.M);2.$u.B(o.w);5(!o.S){2.$k.F(o.p).N().B(o.M);2.$u.F(o.p).v(o.w)}7 h=!o.S&&$.m(2.$3[o.p],\'z.4-3\');5(h)2.z(o.p);o.t=$.2e(o.t.2d($.1i(2.$u.T(\'.\'+o.Q),6(n,i){l e.$u.Z(n)}))).1J();$(2b).1b(\'2a\',6(){e.$3.1d(\'.4-3\');e.$u=e.$3=e.$k=L})}29(7 i=0,E;E=2.$u[i];i++)$(E)[$.1I(i,o.t)!=-1&&!$(E).J(o.w)?\'v\':\'B\'](o.Q);5(o.K===y)2.$3.1r(\'K.4-3\');7 j,R,1c={\'2X-2W\':0,1G:1},1F=\'2U\';5(o.X&&o.X.28==1P)j=o.X[0]||1c,R=o.X[1]||1c;D j=R=o.X||1c;7 g={1p:\'\',2S:\'\',2R:\'\'};5(!$.O.14)g.1E=\'\';6 1D(b,c,a){c.26(j,j.1G||1F,6(){c.v(o.M).13(g);5($.O.14&&j.1E)c[0].24.T=\'\';5(a)1C(b,a,c)})}6 1C(b,a,c){5(R===1c)a.13(\'1p\',\'1B\');a.26(R,R.1G||1F,6(){a.B(o.M).13(g);5($.O.14&&R.1E)a[0].24.T=\'\';$(e.q).P(\'N.4-3\',[e.4(b,a[0])])})}6 23(c,a,d,b){a.v(o.w).2P().B(o.w);1D(c,d,b)}2.$3.1d(\'.4-3\').1b(o.12,6(){7 b=$(2).2O(\'E:F(0)\'),$Y=e.$k.T(\':2N\'),$N=$(2.H);5((b.J(o.w)&&!o.S)||b.J(o.Q)||$(e.q).P(\'1o.4-3\',[e.4(2,$N[0])])===y){2.1k();l y}e.8.p=e.$3.Z(2);5(o.S){5(b.J(o.w)){e.8.p=L;b.B(o.w);e.$k.1y();1D(2,$Y);2.1k();l y}D 5(!$Y.C){e.$k.1y();7 a=2;e.z(e.$3.Z(2),6(){b.v(o.w).v(o.1t);1C(a,$N)});2.1k();l y}}5(o.G)$.G(\'4-3\'+$.m(e.q),e.8.p,o.G);e.$k.1y();5($N.C){7 a=2;e.z(e.$3.Z(2),6(){23(a,b,$Y,$N)})}D 2M\'21 2K 2J: 2H 2G 2F.\';5($.O.14)2.1k();l y});5(!(/^1A/).27(o.12))2.$3.1b(\'1A.4-3\',6(){l y})},17:6(d,e,f){5(f==1Y)f=2.$3.C;7 o=2.8;7 a=$(o.1Q.V(/#\\{x\\}/,d).V(/#\\{1g\\}/,e));a.m(\'15.4-3\',1a);7 b=d.2D(\'#\')==0?d.V(\'#\',\'\'):2.1z($(\'a:2C-2z\',a)[0]);7 c=$(\'#\'+b);5(!c.C){c=$(o.1v).W(\'16\',b).v(o.U).v(o.M);c.m(\'15.4-3\',1a)}5(f>=2.$u.C){a.1W(2.q);c.1W(2.q.2E)}D{a.1V(2.$u[f]);c.1V(2.$k[f])}o.t=$.1i(o.t,6(n,i){l n>=f?++n:n});2.11();5(2.$3.C==1){a.v(o.w);c.B(o.M);7 g=$.m(2.$3[0],\'z.4-3\');5(g)2.z(f,g)}$(2.q).P(\'17.4-3\',[2.4(2.$3[f],2.$k[f])])},19:6(a){7 o=2.8,$E=2.$u.F(a).19(),$1e=2.$k.F(a).19();5($E.J(o.w)&&2.$3.C>1)2.1o(a+(a+1<2.$3.C?1:-1));o.t=$.1i($.1U(o.t,6(n,i){l n!=a}),6(n,i){l n>=a?--n:n});2.11();$(2.q).P(\'19.4-3\',[2.4($E.2I(\'a\')[0],$1e[0])])},25:6(a){7 o=2.8;5($.1I(a,o.t)==-1)l;7 b=2.$u.F(a).B(o.Q);5($.O.2u){b.13(\'1p\',\'2L-1B\');1u(6(){b.13(\'1p\',\'1B\')},0)}o.t=$.1U(o.t,6(n,i){l n!=a});$(2.q).P(\'25.4-3\',[2.4(2.$3[a],2.$k[a])])},20:6(a){7 b=2,o=2.8;5(a!=o.p){2.$u.F(a).v(o.Q);o.t.1O(a);o.t.1J();$(2.q).P(\'20.4-3\',[2.4(2.$3[a],2.$k[a])])}},1o:6(a){5(1K a==\'1X\')a=2.$3.Z(2.$3.T(\'[x$=\'+a+\']\')[0]);2.$3.F(a).2t(2.8.12)},z:6(d,b){7 e=2,o=2.8,$a=2.$3.F(d),a=$a[0],1T=b==1Y|| b===y,18=$a.m(\'z.4-3\');b=b|| 6(){};5(!18|| ($.m(a,\'K.4-3\')&&!1T)){b();l}5(o.1l){7 g=$(\'1h\',a),1g=g.1n();g.1n(\'<1S>\'+o.1l+\'</1S>\')}7 c=6(){e.$3.T(\'.\'+o.1s).I(6(){$(2).B(o.1s);5(o.1l)$(\'1h\',2).1n(1g)});e.1m=L};7 f=$.1H({},o.1j,{18:18,1x:6(r,s){$(a.H).1n(r);c();b();5(o.K)$.m(a,\'K.4-3\',1a);$(e.q).P(\'z.4-3\',[e.4(e.$3[d],e.$k[d])]);o.1j.1x&&o.1j.1x(r,s)}});5(2.1m){2.1m.2r();c()}$a.v(o.1s);1u(6(){e.1m=$.2q(f)},0)},18:6(a,b){2.$3.F(a).1r(\'K.4-3\').m(\'z.4-3\',b)},15:6(){7 o=2.8;$(2.q).1d(\'.4-3\').B(o.1f).1r(\'4-3\');2.$3.I(6(){7 b=$.m(2,\'x.4-3\');5(b)2.x=b;7 c=$(2).1d(\'.4-3\');$.I([\'x\',\'z\',\'K\'],6(i,a){c.1r(a+\'.4-3\')})});2.$u.17(2.$k).I(6(){5($.m(2,\'15.4-3\'))$(2).19();D $(2).B([o.w,o.1t,o.Q,o.U,o.M].2p(\' \'))})}})})(21);',62,185,'||this|tabs|ui|if|function|var|options||||||||||||panels|return|data|||selected|element|||disabled|lis|addClass|selectedClass|href|false|load||removeClass|length|else|li|eq|cookie|hash|each|hasClass|cache|null|hideClass|show|browser|triggerHandler|disabledClass|showFx|unselect|filter|panelClass|replace|attr|fx|hide|index||tabify|event|css|msie|destroy|id|add|url|remove|true|bind|baseFx|unbind|panel|navClass|label|span|map|ajaxOptions|blur|spinner|xhr|html|select|display|arguments|removeData|loadingClass|unselectClass|setTimeout|panelTemplate|location|success|stop|tabId|click|block|showTab|hideTab|opacity|baseDuration|duration|extend|inArray|sort|typeof|div|toShowId|prototype|push|Array|tabTemplate|idPrefix|em|bypassCache|grep|insertBefore|appendTo|string|undefined|_|disable|jQuery|title|switchTab|style|enable|animate|test|constructor|for|unload|window|call|concat|unique|nav|slice|parseInt|scrollTo|500|opera|new|insertAfter|apply|fn|join|ajax|abort|has|trigger|safari|tab|instance|8230|z0|child|Za|Loading|first|indexOf|parentNode|identifier|fragment|Mismatching|find|Tabs|UI|inline|throw|visible|parents|siblings|getData|height|overflow|setData|normal|Function|width|min|loading'.split('|'),0,{}))
\ No newline at end of file
Index: htmlparser/simpletest/testhtmlparserlib.php
===================================================================
RCS file: htmlparser/simpletest/testhtmlparserlib.php
diff -N htmlparser/simpletest/testhtmlparserlib.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ htmlparser/simpletest/testhtmlparserlib.php	4 Jul 2008 07:30:18 -0000
@@ -0,0 +1,61 @@
+<?php // $Id: testgradecategory.php,v 1.19 2008/06/02 21:05:51 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.org                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ * Unit tests for the HTML parser library.
+ *
+ * @author nicolasconnault@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodlecore
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+require_once($CFG->libdir . '/htmlparserlib.php');
+
+class htmlparserlib_test extends UnitTestCase {
+    function setUp() {
+
+    }
+
+    function tearDown() {
+
+    }
+
+    function testWellFormedHTML() {
+        $dom = new simple_html_dom();
+        $valid_html = '<html><head><title>Valid page</title></head>
+            <body><h1>Heading1</h1><a href="link.html">Link</a></body></html>';
+        $dom->load($valid_html);
+        $links = $dom->find('a');
+        $headings = $dom->find('h1');
+        $paragraphs = $dom->find('p');
+        $this->assertEqual(1, count($links));
+        $this->assertEqual(1, count($headings));
+        $this->assertEqual(0, count($paragraphs));
+    }
+}
