summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLester Caine <lester@lsces.co.uk>2026-05-14 19:52:12 +0100
committerLester Caine <lester@lsces.co.uk>2026-05-14 19:52:12 +0100
commitf42e735f78f46ce7ea63acb301f57df9eeae4ef9 (patch)
tree451fcb013a8ad2ccf471d534b38d51f266b6021d
parentc105a9834fd9c5a320d41422c50fa84e5bc12084 (diff)
downloadwiki-f42e735f78f46ce7ea63acb301f57df9eeae4ef9.tar.gz
wiki-f42e735f78f46ce7ea63acb301f57df9eeae4ef9.tar.bz2
wiki-f42e735f78f46ce7ea63acb301f57df9eeae4ef9.zip
Move legacy libraries into the relevant package for easier maintenance
-rwxr-xr-xincludes/htmlparser/html_parser_inc.php492
-rwxr-xr-xincludes/htmlparser/htmlgrammar.cmp1
-rwxr-xr-xincludes/htmlparser/htmlgrammar.dat1176
-rwxr-xr-xincludes/htmlparser/htmlgrammarparser.inc478
-rwxr-xr-xincludes/htmlparser/readme.eng.txt19
-rwxr-xr-xincludes/htmlparser/rebuildgrammar.php13
-rwxr-xr-xincludes/tar.class.php467
-rwxr-xr-xincludes/zip_lib.php805
8 files changed, 3451 insertions, 0 deletions
diff --git a/includes/htmlparser/html_parser_inc.php b/includes/htmlparser/html_parser_inc.php
new file mode 100755
index 0000000..5965711
--- /dev/null
+++ b/includes/htmlparser/html_parser_inc.php
@@ -0,0 +1,492 @@
+<?php
+if (!defined("_ECHOSERVER_HTML_PARSER")) {
+define("_ECHOSERVER_HTML_PARSER",1);
+
+class HtmlParser {
+ var $pos,
+ $tagpos,
+ $length,
+ $data,
+ $stacktag,
+ $stacktagpos,
+ $name,
+ $quotstate,
+ $quottype,
+ $parname,
+ $pars,
+ $tagname,
+ $content,
+ $contentpos,
+ $allreadyparsed,
+ $pg,
+ $dc,
+ $nc,
+ $qc,
+ $prevstate,
+ $processtag,
+ $processpar,
+ $processparvalue,
+ $c,
+ $cp,
+ $text,
+ $incomment,
+ $skipto,
+ $tagreg,
+ $wasquot;
+/**********************************************************************************
+ * Class constructor
+ **********************************************************************************/
+ function HtmlParser($data,$grammar,$name="",$datatype=0) {
+ $this->dc=[" ","\t","\r","\n","<",">",'"',"'","=","/"];
+ $this->nc=["<",">","=","/"];
+ $this->qc=['"',"'"];
+ $this->sc=["\r","\n"," ","\t"];
+ $this->prevstate=["state"=>0,"word"=>""];
+ $this->pg=&$grammar;
+ $this->pos=0;
+ $this->stacktag=[];
+ $this->stacktagpos=-1;
+ $this->content=[];
+ $this->content["contentpos"]=-1;
+ $this->c=&$this->content;
+ $this->cp=-1;
+ $this->quotstate=-1;
+ $this->allreadyparsed=0;
+ $this->text="";
+ $this->processtag=0;
+ $this->processpar=0;
+ $this->processparvalue=0;
+ $this->slevel=[0];
+ $this->slevelpos=0;
+ $this->quottype="";
+ $this->skipto="";
+ $this->incomment=0;
+ $this->tagreg=[];
+ $this->wasquot=0;
+
+ if(isset($this->data) && is_array($this->data)) {
+ $this->content=&$data;
+ $this->allreadyparsed=1;
+ return;
+ }
+ clearstatcache();
+ $this->name=$data;
+ if (!$datatype) {
+ $this->name=$name;
+ $this->data=$data;
+ $this->length=strlen($this->data);
+ return;
+ }
+ if (!$fp=fopen($this->name,"rb")) {
+ $this->SetError(1,"Can't open file $this->name.",0,0,"Error");
+ return;
+ }
+ flock($fp,1);
+ $this->data=fread($fp,filesize($this->name));
+ flock($fp,3);
+ fclose($fp);
+ $this->length=strlen($this->data);
+ }
+
+/********************************************************************************************
+ * Get word from data
+ ********************************************************************************************/
+ function GetWord(&$word) {
+ $word="";
+ $this->wasquot=0;
+ if ($this->pos>$this->length) return false;
+ while (1) {
+ if ($this->pos>$this->length) return false;
+ if ($this->pos==$this->length) {
+ $this->pos++;
+ return true;
+ }
+ if ($this->data[$this->pos]=="<") {
+ if ($this->data[$this->pos+1]=="!")
+ if ($this->length>6 && $this->length-$this->pos+1>6) {
+ if (substr($this->data,$this->pos,4)=="<!--") {
+ $this->incomment=1;
+ while($this->pos<$this->length-3) {
+ if (substr($this->data,$this->pos,3)=="-->") {
+ $word.="-->";
+ $this->pos+=3;
+ break;
+ }
+ $word.=$this->data[$this->pos++];
+ }
+ if ($this->incomment) break;
+ }
+ }
+ }
+ if (!$this->processtag) {
+ if ($this->data[$this->pos]=="<") {
+ $this->processtag=1;
+ $this->tagpos=strlen($this->text);
+ } else {
+ $this->text.=$this->data[$this->pos++];
+ continue;
+ }
+ }
+ if (in_array($this->data[$this->pos],$this->dc)) {
+ if (($this->data[$this->pos]=="<" || $this->data[$this->pos]==">") && $this->quotstate==-1 && $this->processparvalue) {
+ $this->processparvalue=0;
+ return true;
+ }
+ if (in_array($this->data[$this->pos],$this->sc) && $this->quotstate==-1) {
+ $this->text.=$this->data[$this->pos++];
+ if (strlen($word)) {
+ if ($this->processparvalue) $this->processparvalue=0;
+ return true;
+ }
+ continue;
+ }
+ if (!strlen($word)) {
+ if (in_array($this->data[$this->pos],$this->qc) && $this->processpar) {
+ if ($this->quotstate==-1) {
+ $this->wasquot=1;
+ $this->quotstate*=-1;
+ $this->quottype=$this->data[$this->pos];
+ $this->text.=$this->data[$this->pos++];
+ continue;
+ } elseif ($this->quottype==$this->data[$this->pos]) {
+ $this->quotstate*=-1;
+ $this->quottype=$this->data[$this->pos];
+ $this->processpar=$this->processparvalue=0;
+ $this->text.=$this->data[$this->pos++];
+ return true;
+ }
+ } elseif (in_array($this->data[$this->pos],$this->nc)) {
+ $word.=$this->data[$this->pos];
+ $this->text.=$this->data[$this->pos++];
+ if ($this->processparvalue)
+ continue;
+
+ return true;
+ }
+ } else {
+ if (in_array($this->data[$this->pos],$this->qc) && $this->processpar) {
+ if ($this->quotstate==1) {
+ if ($this->data[$this->pos]==$this->quottype && $this->processparvalue) {
+ $this->quotstate*=-1;
+ $this->quottype=$this->data[$this->pos];
+ $this->processpar=$this->processparvalue=0;
+ $this->text.=$this->data[$this->pos++];
+// continue;
+ } else {
+ if ($this->data[$this->pos]==$this->quottype) {
+ $this->quotstate*=-1;
+ $this->quottype="";
+ }
+ $word.=$this->data[$this->pos];
+ $this->text.=$this->data[$this->pos++];
+ continue;
+ }
+ }
+ return true;
+ }
+ if (in_array($this->data[$this->pos],$this->nc)) {
+ if ($this->quotstate==-1) {
+ if ($this->processparvalue) {
+ if($this->data[$this->pos]!="/" && $this->data[$this->pos]!="=") return true;
+ $word.=$this->data[$this->pos];
+ $this->text.=$this->data[$this->pos++];
+ continue;
+ }
+ } else {
+ $word.=$this->data[$this->pos];
+ $this->text.=$this->data[$this->pos++];
+ continue;
+ }
+ return true;
+ } elseif ($this->quotstate==-1 && $this->processparvalue && strlen($word)) {
+ if ($this->data[$this->pos]==" ") {
+ $this->text.=$this->data[$this->pos++];
+ $this->processparvalue=0;
+ return true;
+ }
+ }
+
+ }
+ }
+ $word.=$this->data[$this->pos];
+ $this->text.=$this->data[$this->pos++];
+ }
+ return true;
+ }
+
+/********************************************************************************************
+ * Parse HTML code
+ ********************************************************************************************
+<tagname [parname=|parnane=["|']parvalue["|']|parname][/]> |
+<[/]tagname>
+
+in/state 0 1 2 3 4 5 6 7 8
+< 1 -1 -1 -1 -1 -1 -1 -1 -1
+/ -1 7 6 6 6 6 -1 -1 -1
+= -1 -1 -1 4 -1 -1 -1 -1 -1
+> -1 -1 -2 -2 -2 -2 -2 -1 -3
+anyword -1 2 3 3 5 3 -1 8 -1
+
+-3 end parse close tag
+-2 end parse open tag
+-1 error
+ 0 begin parse
+ 1 got '<', waiting '/' or any word as tag name
+ 2 got any word as tagname, waiting '/' or '>' or any word as parameter name
+ 3 got any word as parameter name, waiting '/' or '>' or '=' or any word as parameter name
+ 4 got '=' waiting '/' or '>' or any word as parameter value
+ 5 got any word as parameter value, waiting '/' or '>' or any word as parameter name
+ 6 got '/' waiting '>'
+ 7 got '/', waiting any word as close tagname
+ 8 got any word as close tag name, waiting '>'
+ ********************************************************************************************/
+ function Parse() {
+ $automat=[
+// states 0 1 2 3 4 5 6 7 8
+ "0"=>[ 1, -1, -1, -1, -1, -1, -1, -1, -1],// <
+ "1"=>[-1, 7, 6, 6, 6, 6, -1, -1, -1],// /
+ "2"=>[-1, -1, -1, 4, -1, -1, -1, -1, -1],// =
+ "3"=>[-1, -1, -2, -2, -2, -2, -2, -1, -3],// >
+ "4"=>[-1, 2, 3, 3, 5, 3, -1, 8, -1], // any word
+ ];
+ if (!strlen($this->data)) return;
+ $instates=["<"=>0,"/"=>1,"="=>2,">"=>3];
+ $parcount=0;
+ $state=0;
+ $this->c=&$this->content;
+ $this->cp=&$this->content["contentpos"];
+ $this->stacktag[0]["tag"]=&$this->c;
+ $this->stacktag[0]["level"]=&$this->slevel;
+ $this->stacktag[0]["levelpos"]=0;
+ $this->stacktagpos=0;
+ while(1) {
+ if (!$isword=$this->GetWord($word)) break;
+ $w=strtolower($word);
+ if (!isset($instates[$w]))
+ $instate=4;
+ else
+ $instate=$instates[$w];
+//print htmlspecialchars($word).",$state,$instate,$this->quottype<br>";
+ $state=$automat[$instate][$state];
+ if ($this->wasquot && $state==6) $state=5;
+//print htmlspecialchars($word).",$state<br>";
+ switch($state) {
+ case -3:// end parse close tag
+ if (strlen($this->skipto) && $this->tagname!=$this->skipto) {
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->pars=[];
+ break;
+ }
+ $this->skipto="";
+ $script=($this->tagname=="script") ? 1:0;
+ $this->AddNewText(substr($this->text,0,$this->tagpos),$script);
+ $this->AddNewTag(0);
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->quottype="";
+ $this->quotstate=-1;
+ $this->text="";
+ $this->pars=[];
+ $this->tagpos=0;
+ break;
+ case -2:// end parse open tag
+ if (strlen($this->skipto)) {
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->pars=[];
+ break;
+ }
+ $this->AddNewText(substr($this->text,0,$this->tagpos));
+ $this->AddNewTag(1,$xmlclose);
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->quottype="";
+ $this->quotstate=-1;
+ $this->text="";
+ $this->pars=[];
+ $this->tagpos=0;
+ if (isset($this->pg[$this->tagname]["nohavetags"]) && !strlen($this->skipto)) $this->skipto=$this->tagname;
+ break;
+ case -1:// Error found
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->pars=[];
+ if ($this->incomment) {
+ if (strlen($this->text)) {
+ $this->AddNewText($this->text);
+ $this->text="";
+ $this->tagpos=0;
+ }
+ $this->AddNewText($word,0,1);
+ $this->incomment=0;
+ break;
+ }
+ if ($word=="<") {
+ $state=1;
+ $this->processtag=1;
+ $this->processparvalue=0;
+ $this->tagpos=strlen($this->text)-1;
+ $this->quottype="";
+ $this->quotstate=-1;
+ }
+ break;
+ case 2:// got any word as tagname, waiting '/' or '>' or any word as parameter name
+ $this->tagname=$w;
+ $xmlclose=0;
+ if (!ereg("^[a-zA-Z0-9!_-]+$",$this->tagname) || strlen($this->skipto)) {
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->quottype="";
+ $this->quotstate=-1;
+ $this->pars=[];
+ break;
+ }
+ break;
+ case 3:// got any word as parameter name, waiting '/' or '>' or '=' or any word as parameter name
+ $this->parname=$w;
+ if (!ereg("^[a-zA-Z0-9!_-]+$",$this->parname) || strlen($this->skipto)) {
+ $parcount=$state=$this->processpar=$this->processparvalue=$this->processtag=0;
+ $this->quottype="";
+ $this->quotstate=-1;
+ $this->pars=[];
+ break;
+ }
+ $this->processpar=1;
+ if ($w!="/") {
+ $parcount++;
+ $this->pars[$this->parname]["single"]=1;
+ } else
+ $xmlclose=1;
+ break;
+ case 4:// got '=' waiting '/' or '>' or any word as parameter value
+ $this->processparvalue=1;
+ break;
+ case 5:// got any word as parameter value, waiting '/' or '>' or any word as parameter name
+ if ($this->parname!="/") {
+ unset($this->pars[$this->parname]["single"]);
+ $this->pars[$this->parname]["value"]=$word;
+ $this->pars[$this->parname]["quot"]=$this->quottype;
+ }
+ $this->quottype="";
+ $this->processpar=$this->processparvalue=0;
+ break;
+ case 6:// got '/' waiting '>'
+ $xmlclose=1;
+ break;
+ case 8:// got any word as close tag name, waiting '>'
+ $this->tagname=$w;
+ break;
+ }
+ $this->prevstate["states"]=$state;
+ $this->prevstate["word"]=$word;
+ }
+ if (strlen($this->text)) $this->AddNewText($this->text);
+ }
+/********************************************************************************************
+ * Add new tag
+ ********************************************************************************************/
+ function AddNewTag($open,$xmlclose=0) {
+ $actionclose=0;
+ if (!$open && in_array( $this->tagname, $this->pg ) && $this->pg[$this->tagname]["endtag"]!="absent") $actionclose=1;
+
+ if ($open)
+ for ($i=$this->stacktagpos;$i>0;$i--) {
+ $ct=&$this->stacktag[$i]["tag"];
+ $t=&$ct[$ct["contentpos"]];
+ $tagname=$t["data"]["name"];
+ if (isset($this->pg[$tagname]["closeon"])) {
+ if (isset($this->pg[$tagname]["closeon"]["in"]) && sizeof($this->pg[$tagname]["closeon"]["in"]) && in_array($this->tagname,$this->pg[$tagname]["closeon"]["in"])
+ || isset($this->pg[$tagname]["closeon"]["notin"]) && sizeof($this->pg[$tagname]["closeon"]["notin"]) && !in_array($this->tagname,$this->pg[$tagname]["closeon"]["notin"])) {
+ $actionclose=2;
+ break;
+ }
+ }
+ if ($actionclose!=2) $i=-1;
+ }
+
+ if ($actionclose) {
+ if ($actionclose==1) {
+ $i=$this->FindTag($this->tagname);
+ if ($i>-1)
+ if ($this->tagreg[$this->tagname]!=$this->stacktag[$i]["num"])
+ $i=-1;
+ }
+ if ($i>-1) {
+ $this->c=&$this->stacktag[$i]["tag"];
+ $this->cp=&$this->c["contentpos"];
+ $this->stacktagpos=$i;
+ if ($actionclose==1) {
+ $c=&$this->c[$this->c["contentpos"]]["content"];
+ $cp=&$this->c[$this->c["contentpos"]]["content"]["contentpos"];
+ $cp++;
+ $c[$cp]["type"]="tag";
+ $c[$cp]["data"]["name"]=$this->tagname;
+ $c[$cp]["data"]["type"]="close";
+ if (isset($this->tagreg[$this->tagname]))
+ if ($this->tagreg[$this->tagname])
+ $this->tagreg[$this->tagname]--;
+ $this->stacktag[$this->stacktagpos]["num"]=$this->tagreg[$this->tagname];
+ $this->stacktagpos--;
+ }
+ if ($this->stacktagpos<sizeof($this->stacktag))
+ for ($i=$this->stacktagpos+1;$i<sizeof($this->stacktag);$i++)
+ unset($this->stacktag[$i]);
+ if ($actionclose==1) return;
+ }
+ }
+ $this->cp++;
+ $this->c[$this->cp]["type"]="tag";
+ $this->c[$this->cp]["data"]["name"]=$this->tagname;
+ $this->c[$this->cp]["data"]["type"]=($open) ? "open" : "close";
+ if (!$open)
+ if (isset($this->tagreg[$this->tagname]))
+ if ($this->tagreg[$this->tagname])
+ $this->tagreg[$this->tagname]--;
+ if ($xmlclose) $this->c[$this->cp]["xmlclose"]=1;
+ if (sizeof($this->pars)) $this->c[$this->cp]["pars"]=$this->pars;
+ if ($open && !$xmlclose && in_array( $this->tagname, $this->pg ) && $this->pg[$this->tagname]["endtag"]!="absent") {
+ if (!isset($this->tagreg[$this->tagname])) $this->tagreg[$this->tagname]=0;
+ $this->tagreg[$this->tagname]++;
+ $this->stacktagpos++;
+ $this->stacktag[$this->stacktagpos]["tag"]=&$this->c;
+ $this->stacktag[$this->stacktagpos]["num"]=$this->tagreg[$this->tagname];
+ $this->c[$this->cp]["content"]=[];
+ $this->c[$this->cp]["content"]["contentpos"]=-1;
+ $this->c=&$this->c[$this->cp]["content"];
+ $this->cp=&$this->c["contentpos"];
+ }
+ }
+
+/********************************************************************************************
+ * Add new text
+ ********************************************************************************************/
+ function AddNewText($text,$script=0,$comment=0) {
+ if (!strlen($text)) return;
+ $this->cp++;
+ if (!$comment)
+ $this->c[$this->cp]["type"]="text";
+ else
+ $this->c[$this->cp]["type"]="comment";
+ if ($script) {
+ $inputarray=["/_top/","/top.location.href/","/([ \n]+)?window\.name/","/parent.location/"];
+ $replarray=["_echoserver_file_space","parent.frames('_echoserver_file_space').src","//window.name","parent.frames('_echoserver_file_space').src"];
+/*
+ $text=str_replace("_top","_echoserver_file_space",$text);
+ $text=str_replace("top.location.href","parent.frames('_echoserver_file_space').src",$text);
+ $text=preg_replace("/([ \n]+)?window\.name/","//window.name",$text);
+*/
+ $text=preg_replace($inputarray,$replarray,$text);
+
+ }
+ $this->c[$this->cp]["data"]=$text;
+ $this->text="";
+ }
+
+/********************************************************************************************
+ * Find first tag in stack
+ ********************************************************************************************/
+ function FindTag($tagname) {
+ for($i=$this->stacktagpos;$i>=0;$i--)
+ if ($this->stacktag[$i]["tag"][$this->stacktag[$i]["tag"]["contentpos"]]["data"]["name"]==$tagname)
+ return $i;
+ return -1;
+ }
+}
+
+} //_ECHOSERVER_HTML_PARSER
+?>
diff --git a/includes/htmlparser/htmlgrammar.cmp b/includes/htmlparser/htmlgrammar.cmp
new file mode 100755
index 0000000..f4fcf0e
--- /dev/null
+++ b/includes/htmlparser/htmlgrammar.cmp
@@ -0,0 +1 @@
+a:57:{s:3:"pre";a:4:{s:3:"tag";s:3:"pre";s:6:"endtag";s:7:"present";s:10:"nohavetags";s:0:"";s:4:"pars";a:0:{}}s:2:"hr";a:3:{s:3:"tag";s:2:"hr";s:6:"endtag";s:6:"absent";s:4:"pars";a:3:{s:5:"color";a:1:{s:3:"par";s:5:"color";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:7:"noshade";a:3:{s:3:"par";s:7:"noshade";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}}}s:8:"noframes";a:3:{s:3:"tag";s:8:"noframes";s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:8:"frameset";a:4:{s:3:"tag";s:8:"frameset";s:6:"endtag";s:9:"canabsent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:8:{s:4:"rows";a:1:{s:3:"par";s:4:"rows";}s:4:"cols";a:1:{s:3:"par";s:4:"cols";}s:11:"frameborder";a:1:{s:3:"par";s:11:"frameborder";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:12:"framespacing";a:1:{s:3:"par";s:12:"framespacing";}s:12:"marginheight";a:1:{s:3:"par";s:12:"marginheight";}s:11:"marginwidth";a:1:{s:3:"par";s:11:"marginwidth";}s:8:"noresize";a:1:{s:3:"par";s:8:"noresize";}}}s:5:"frame";a:4:{s:3:"tag";s:5:"frame";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:19:"tags/tag_frame2.gif";s:4:"pars";a:10:{s:4:"name";a:1:{s:3:"par";s:4:"name";}s:6:"target";a:1:{s:3:"par";s:6:"target";}s:9:"scrolling";a:1:{s:3:"par";s:9:"scrolling";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:11:"frameborder";a:1:{s:3:"par";s:11:"frameborder";}s:12:"framespacing";a:1:{s:3:"par";s:12:"framespacing";}s:12:"marginheight";a:1:{s:3:"par";s:12:"marginheight";}s:11:"marginwidth";a:1:{s:3:"par";s:11:"marginwidth";}s:8:"noresize";a:1:{s:3:"par";s:8:"noresize";}s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}}}s:6:"iframe";a:3:{s:3:"tag";s:6:"iframe";s:14:"pictureforedit";s:20:"tags/tag_iframe2.gif";s:4:"pars";a:0:{}}s:4:"html";a:6:{s:3:"tag";s:4:"html";s:6:"endtag";s:7:"present";s:13:"edittagsafter";s:4:"body";s:7:"comment";s:4:"Html";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:0:{}}s:4:"meta";a:4:{s:3:"tag";s:4:"meta";s:6:"endtag";s:6:"absent";s:13:"edittagsafter";s:4:"body";s:4:"pars";a:0:{}}s:6:"script";a:6:{s:3:"tag";s:6:"script";s:10:"nohavetags";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:19:"tags/tag_script.gif";s:14:"edittagsbefore";s:6:"script";s:4:"pars";a:2:{s:8:"language";a:1:{s:3:"par";s:8:"language";}s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}}}s:4:"nobr";a:4:{s:3:"tag";s:4:"nobr";s:7:"closeon";a:2:{s:5:"notin";a:14:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:6:"center";i:3;s:4:"font";i:4;s:1:"i";i:5;s:1:"b";i:6;s:1:"u";i:7;s:2:"tt";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:6:"script";}s:2:"in";a:0:{}}s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:1:"p";a:5:{s:3:"tag";s:1:"p";s:7:"closeon";a:2:{s:5:"notin";a:23:{i:0;s:1:"a";i:1;s:3:"map";i:2;s:4:"area";i:3;s:6:"strong";i:4;s:3:"sup";i:5;s:4:"font";i:6;s:1:"i";i:7;s:1:"b";i:8;s:1:"u";i:9;s:2:"tt";i:10;s:3:"img";i:11;s:1:"s";i:12;s:3:"big";i:13;s:5:"small";i:14;s:6:"strike";i:15;s:4:"nobr";i:16;s:2:"br";i:17;s:6:"script";i:18;s:5:"input";i:19;s:6:"select";i:20;s:8:"textarea";i:21;s:6:"option";i:22;s:6:"button";}s:2:"in";a:0:{}}s:6:"endtag";s:9:"canabsent";s:14:"pictureforedit";s:15:"tags/tag_p2.gif";s:4:"pars";a:1:{s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:24:"_Translator_edit_p_align";}}}s:2:"th";a:3:{s:3:"tag";s:2:"th";s:6:"endtag";s:6:"absent";s:4:"pars";a:1:{s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:25:"_Translator_edit_th_align";}}}s:8:"noscript";a:3:{s:3:"tag";s:8:"noscript";s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:5:"style";a:4:{s:3:"tag";s:5:"style";s:10:"nohavetags";s:0:"";s:6:"endtag";s:7:"present";s:4:"pars";a:0:{}}s:4:"head";a:4:{s:3:"tag";s:4:"head";s:6:"endtag";s:7:"present";s:13:"edittagsafter";s:4:"body";s:4:"pars";a:0:{}}s:6:"center";a:5:{s:3:"tag";s:6:"center";s:6:"endtag";s:7:"present";s:7:"comment";s:6:"Center";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:0:{}}s:3:"img";a:5:{s:3:"tag";s:3:"img";s:6:"endtag";s:6:"absent";s:7:"comment";s:7:"Picture";s:14:"pictureforedit";s:16:"tags/tag_img.gif";s:4:"pars";a:16:{s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:3:"alt";a:1:{s:3:"par";s:3:"alt";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:26:"_Translator_edit_img_align";}s:6:"vspace";a:1:{s:3:"par";s:6:"vspace";}s:6:"hspace";a:1:{s:3:"par";s:6:"hspace";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:6:"usemap";a:2:{s:3:"par";s:6:"usemap";s:10:"editmethod";s:32:"_Translator_edit_standart_usemap";}}}s:1:"a";a:8:{s:3:"tag";s:1:"a";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"edittagsbefore";s:1:"a";s:7:"comment";s:3:"Url";s:14:"pictureforedit";s:14:"tags/tag_a.gif";s:7:"closeon";a:2:{s:5:"notin";a:19:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:6:"center";i:3;s:4:"font";i:4;s:1:"i";i:5;s:1:"b";i:6;s:1:"u";i:7;s:2:"tt";i:8;s:3:"img";i:9;s:1:"s";i:10;s:3:"big";i:11;s:5:"small";i:12;s:6:"strike";i:13;s:4:"nobr";i:14;s:2:"br";i:15;s:6:"script";i:16;s:2:"li";i:17;s:2:"ol";i:18;s:2:"ul";}s:2:"in";a:1:{i:0;s:1:"a";}}s:4:"pars";a:24:{s:4:"href";a:3:{s:3:"par";s:4:"href";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:8:"hreflang";a:1:{s:3:"par";s:8:"hreflang";}s:3:"rel";a:1:{s:3:"par";s:3:"rel";}s:3:"rev";a:1:{s:3:"par";s:3:"rev";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:5:"shape";a:1:{s:3:"par";s:5:"shape";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:8:"tabindex";a:1:{s:3:"par";s:8:"tabindex";}s:6:"target";a:1:{s:3:"par";s:6:"target";}}}s:2:"ul";a:6:{s:3:"tag";s:2:"ul";s:6:"endtag";s:7:"present";s:7:"comment";s:15:"Unsequence list";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"closeon";a:2:{s:5:"notin";a:17:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";i:15;s:2:"li";i:16;s:2:"ol";}s:2:"in";a:3:{i:0;s:5:"table";i:1;s:2:"tr";i:2;s:2:"td";}}s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:4:"type";a:1:{s:3:"par";s:4:"type";}}}s:2:"li";a:7:{s:3:"tag";s:2:"li";s:6:"endtag";s:7:"present";s:7:"comment";s:12:"List element";s:14:"pictureforedit";s:12:"tags/tag.gif";s:13:"nohavesametag";s:0:"";s:7:"closeon";a:2:{s:5:"notin";a:17:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";i:15;s:2:"ol";i:16;s:2:"ul";}s:2:"in";a:1:{i:0;s:2:"li";}}s:4:"pars";a:18:{s:5:"value";a:1:{s:3:"par";s:5:"value";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:4:"type";a:1:{s:3:"par";s:4:"type";}}}s:2:"ol";a:7:{s:3:"tag";s:2:"ol";s:6:"endtag";s:7:"present";s:7:"comment";s:13:"Sequence list";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"closeon";a:2:{s:5:"notin";a:17:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";i:15;s:2:"ol";i:16;s:2:"ul";}s:2:"in";a:1:{i:0;s:2:"ol";}}s:13:"nohavesametag";s:0:"";s:4:"pars";a:18:{s:5:"start";a:1:{s:3:"par";s:5:"start";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:4:"type";a:1:{s:3:"par";s:4:"type";}}}s:5:"title";a:5:{s:3:"tag";s:5:"title";s:6:"endtag";s:7:"present";s:7:"comment";s:11:"Page header";s:14:"pictureforedit";s:12:"tags/tag.gif";s:4:"pars";a:0:{}}s:8:"textarea";a:6:{s:3:"tag";s:8:"textarea";s:10:"nohavetags";s:0:"";s:6:"endtag";s:7:"present";s:7:"comment";s:8:"Textarea";s:14:"pictureforedit";s:21:"tags/tag_textarea.gif";s:4:"pars";a:26:{s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:4:"rows";a:1:{s:3:"par";s:4:"rows";}s:4:"cols";a:1:{s:3:"par";s:4:"cols";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:4:"wrap";a:1:{s:3:"par";s:4:"wrap";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:8:"onselect";a:1:{s:3:"par";s:8:"onselect";}s:8:"onchange";a:1:{s:3:"par";s:8:"onchange";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"tr";a:6:{s:3:"tag";s:2:"tr";s:6:"endtag";s:7:"present";s:7:"comment";s:9:"Table row";s:14:"pictureforedit";s:15:"tags/tag_tr.gif";s:13:"edittagsafter";s:2:"td";s:4:"pars";a:20:{s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:25:"_Translator_edit_td_align";}s:6:"valign";a:2:{s:3:"par";s:6:"valign";s:10:"editmethod";s:26:"_Translator_edit_td_valign";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:10:"background";a:1:{s:3:"par";s:10:"background";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"td";a:6:{s:3:"tag";s:2:"td";s:6:"endtag";s:7:"present";s:7:"comment";s:10:"Table cell";s:14:"pictureforedit";s:15:"tags/tag_td.gif";s:13:"edittagsafter";s:2:"td";s:4:"pars";a:25:{s:7:"colspan";a:1:{s:3:"par";s:7:"colspan";}s:7:"rowspan";a:1:{s:3:"par";s:7:"rowspan";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:10:"background";a:1:{s:3:"par";s:10:"background";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:25:"_Translator_edit_td_align";}s:6:"valign";a:2:{s:3:"par";s:6:"valign";s:10:"editmethod";s:26:"_Translator_edit_td_valign";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:6:"nowrap";a:3:{s:3:"par";s:6:"nowrap";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}}}s:5:"table";a:5:{s:3:"tag";s:5:"table";s:6:"endtag";s:7:"present";s:7:"comment";s:5:"Table";s:14:"pictureforedit";s:18:"tags/tag_table.gif";s:4:"pars";a:26:{s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:10:"background";a:1:{s:3:"par";s:10:"background";}s:11:"cellspacing";a:1:{s:3:"par";s:11:"cellspacing";}s:11:"cellpadding";a:1:{s:3:"par";s:11:"cellpadding";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:11:"bordercolor";a:1:{s:3:"par";s:11:"bordercolor";}s:7:"summary";a:1:{s:3:"par";s:7:"summary";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:28:"_Translator_edit_table_align";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:12:"onkeypressed";a:1:{s:3:"par";s:12:"onkeypressed";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:4:"area";a:5:{s:3:"tag";s:4:"area";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:10:"Map region";s:4:"pars";a:22:{s:4:"href";a:3:{s:3:"par";s:4:"href";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:5:"shape";a:2:{s:3:"par";s:5:"shape";s:10:"editmethod";s:31:"_Translator_edit_standart_shape";}s:6:"coords";a:1:{s:3:"par";s:6:"coords";}s:6:"usemap";a:1:{s:3:"par";s:6:"usemap";}s:3:"alt";a:1:{s:3:"par";s:3:"alt";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:8:"tabindex";a:1:{s:3:"par";s:8:"tabindex";}}}s:4:"span";a:5:{s:3:"tag";s:4:"span";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:4:"span";s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"b";a:7:{s:3:"tag";s:1:"b";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:15:"tags/tag_b2.gif";s:7:"comment";s:1:"B";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"b";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"tt";a:7:{s:3:"tag";s:2:"tt";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"TT";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:2:"tt";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"i";a:7:{s:3:"tag";s:1:"i";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:15:"tags/tag_i2.gif";s:7:"comment";s:1:"I";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"i";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:3:"big";a:7:{s:3:"tag";s:3:"big";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:3:"Big";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:3:"big";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:5:"small";a:7:{s:3:"tag";s:5:"small";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:5:"Small";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:5:"small";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:6:"strike";a:7:{s:3:"tag";s:6:"strike";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:6:"Strike";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:6:"strike";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"s";a:7:{s:3:"tag";s:1:"s";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:1:"S";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"s";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:1:"u";a:7:{s:3:"tag";s:1:"u";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:15:"tags/tag_u2.gif";s:7:"comment";s:1:"U";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:1:"u";}}s:4:"pars";a:13:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:3:"map";a:7:{s:3:"tag";s:3:"map";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:3:"Map";s:7:"closeon";a:2:{s:5:"notin";a:1:{i:0;s:4:"area";}s:2:"in";a:1:{i:0;s:3:"map";}}s:4:"pars";a:1:{s:4:"name";a:1:{s:3:"par";s:4:"name";}}}s:2:"br";a:4:{s:3:"tag";s:2:"br";s:4:"edit";s:1:"0";s:6:"endtag";s:6:"absent";s:4:"pars";a:5:{s:5:"clear";a:1:{s:3:"par";s:5:"clear";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"style";a:1:{s:3:"par";s:5:"style";}}}s:4:"base";a:5:{s:3:"tag";s:4:"base";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:4:"Base";s:4:"pars";a:2:{s:4:"href";a:3:{s:3:"par";s:4:"href";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:6:"target";a:1:{s:3:"par";s:6:"target";}}}s:8:"basefont";a:5:{s:3:"tag";s:8:"basefont";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:8:"Basefont";s:4:"pars";a:7:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:5:"color";a:1:{s:3:"par";s:5:"color";}s:4:"face";a:1:{s:3:"par";s:4:"face";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}}}s:4:"body";a:8:{s:3:"tag";s:4:"body";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:17:"tags/tag_body.gif";s:13:"edittagsafter";s:4:"body";s:7:"comment";s:9:"Page body";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:4:"body";}}s:4:"pars";a:27:{s:10:"background";a:1:{s:3:"par";s:10:"background";}s:4:"text";a:1:{s:3:"par";s:4:"text";}s:4:"link";a:1:{s:3:"par";s:4:"link";}s:5:"vlink";a:1:{s:3:"par";s:5:"vlink";}s:5:"alink";a:1:{s:3:"par";s:5:"alink";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:7:"bgcolor";a:1:{s:3:"par";s:7:"bgcolor";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:9:"topmargin";a:1:{s:3:"par";s:9:"topmargin";}s:10:"leftmargin";a:1:{s:3:"par";s:10:"leftmargin";}s:11:"marginwidth";a:1:{s:3:"par";s:11:"marginwidth";}s:12:"marginheight";a:1:{s:3:"par";s:12:"marginheight";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:6:"onload";a:1:{s:3:"par";s:6:"onload";}s:8:"onunload";a:1:{s:3:"par";s:8:"onunload";}}}s:6:"button";a:7:{s:3:"tag";s:6:"button";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:19:"tags/tag_button.gif";s:7:"comment";s:6:"Button";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"center";i:1;s:4:"font";i:2;s:1:"i";i:3;s:1:"b";i:4;s:1:"u";i:5;s:2:"tt";i:6;s:1:"a";i:7;s:3:"img";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:6:"button";}}s:4:"pars";a:18:{s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"value";a:1:{s:3:"par";s:5:"value";}s:4:"type";a:1:{s:3:"par";s:4:"type";}s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:6:"usemap";a:1:{s:3:"par";s:6:"usemap";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}}}s:3:"div";a:5:{s:3:"tag";s:3:"div";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:16:"tags/tag_div.gif";s:7:"comment";s:8:"Division";s:4:"pars";a:15:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"align";a:2:{s:3:"par";s:5:"align";s:10:"editmethod";s:26:"_Translator_edit_div_align";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:4:"font";a:6:{s:3:"tag";s:4:"font";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:18:"tags/tag_font2.gif";s:7:"comment";s:4:"Font";s:7:"closeon";a:2:{s:5:"notin";a:13:{i:0;s:1:"i";i:1;s:1:"b";i:2;s:1:"u";i:3;s:2:"tt";i:4;s:1:"a";i:5;s:3:"img";i:6;s:1:"s";i:7;s:3:"big";i:8;s:5:"small";i:9;s:6:"strike";i:10;s:4:"nobr";i:11;s:2:"br";i:12;s:6:"script";}s:2:"in";a:0:{}}s:4:"pars";a:9:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:5:"color";a:1:{s:3:"par";s:5:"color";}s:4:"face";a:1:{s:3:"par";s:4:"face";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}}}s:4:"form";a:5:{s:3:"tag";s:4:"form";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:17:"tags/tag_form.gif";s:7:"comment";s:4:"Form";s:4:"pars";a:23:{s:6:"action";a:3:{s:3:"par";s:6:"action";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:6:"method";a:1:{s:3:"par";s:6:"method";}s:7:"enctype";a:1:{s:3:"par";s:7:"enctype";}s:14:"accept-charset";a:1:{s:3:"par";s:14:"accept-charset";}s:6:"accept";a:1:{s:3:"par";s:6:"accept";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:6:"target";a:1:{s:3:"par";s:6:"target";}s:8:"onsubmit";a:1:{s:3:"par";s:8:"onsubmit";}s:7:"onreset";a:1:{s:3:"par";s:7:"onreset";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h1";a:7:{s:3:"tag";s:2:"h1";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"hl";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h1";}}s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h2";a:7:{s:3:"tag";s:2:"h2";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h2";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h2";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h3";a:7:{s:3:"tag";s:2:"h3";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h3";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h3";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h4";a:7:{s:3:"tag";s:2:"h4";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h4";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h4";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h5";a:7:{s:3:"tag";s:2:"h5";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h5";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h5";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:2:"h6";a:7:{s:3:"tag";s:2:"h6";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:4:"nobr";i:13;s:2:"br";i:14;s:6:"script";}s:2:"in";a:1:{i:0;s:2:"h6";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:2:"h6";s:4:"pars";a:17:{s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:5:"input";a:5:{s:3:"tag";s:5:"input";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:18:"tags/tag_input.gif";s:7:"comment";s:18:"Form input element";s:4:"pars";a:38:{s:4:"type";a:2:{s:3:"par";s:4:"type";s:10:"editmethod";s:27:"_Translator_edit_input_type";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"value";a:1:{s:3:"par";s:5:"value";}s:7:"checked";a:3:{s:3:"par";s:7:"checked";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:8:"readonly";a:3:{s:3:"par";s:8:"readonly";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:9:"maxlength";a:1:{s:3:"par";s:9:"maxlength";}s:3:"src";a:3:{s:3:"par";s:3:"src";s:5:"width";s:2:"40";s:6:"height";s:1:"3";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:6:"height";a:1:{s:3:"par";s:6:"height";}s:3:"alt";a:1:{s:3:"par";s:3:"alt";}s:6:"border";a:1:{s:3:"par";s:6:"border";}s:8:"tabindex";a:1:{s:3:"par";s:8:"tabindex";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:8:"onselect";a:1:{s:3:"par";s:8:"onselect";}s:8:"onchange";a:1:{s:3:"par";s:8:"onchange";}s:6:"accept";a:1:{s:3:"par";s:6:"accept";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:5:"align";a:1:{s:3:"par";s:5:"align";}s:5:"shape";a:1:{s:3:"par";s:5:"shape";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:5:"label";a:7:{s:3:"tag";s:5:"label";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:5:"Label";s:7:"closeon";a:1:{s:2:"in";a:1:{i:0;s:5:"label";}}s:4:"pars";a:20:{s:3:"for";a:1:{s:3:"par";s:3:"for";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:6:"select";a:8:{s:3:"tag";s:6:"select";s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"edittagsbefore";s:6:"select";s:14:"pictureforedit";s:19:"tags/tag_select.gif";s:7:"comment";s:6:"Select";s:7:"closeon";a:2:{s:5:"notin";a:1:{i:0;s:6:"option";}s:2:"in";a:1:{i:0;s:6:"select";}}s:4:"pars";a:24:{s:8:"disabled";a:3:{s:3:"par";s:8:"disabled";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:8:"multiple";a:3:{s:3:"par";s:8:"multiple";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}s:4:"name";a:1:{s:3:"par";s:4:"name";}s:4:"size";a:1:{s:3:"par";s:4:"size";}s:5:"width";a:1:{s:3:"par";s:5:"width";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:7:"onfocus";a:1:{s:3:"par";s:7:"onfocus";}s:6:"onblur";a:1:{s:3:"par";s:6:"onblur";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}}}s:6:"option";a:7:{s:3:"tag";s:6:"option";s:7:"closeon";a:2:{s:5:"notin";a:15:{i:0;s:6:"strong";i:1;s:3:"sup";i:2;s:4:"font";i:3;s:1:"i";i:4;s:1:"b";i:5;s:1:"u";i:6;s:2:"tt";i:7;s:1:"a";i:8;s:1:"s";i:9;s:3:"big";i:10;s:5:"small";i:11;s:6:"strike";i:12;s:2:"br";i:13;s:4:"nobr";i:14;s:6:"script";}s:2:"in";a:2:{i:0;s:6:"option";i:1;s:6:"option";}}s:13:"nohavesametag";s:0:"";s:6:"endtag";s:7:"present";s:14:"pictureforedit";s:12:"tags/tag.gif";s:7:"comment";s:6:"Option";s:4:"pars";a:20:{s:4:"name";a:1:{s:3:"par";s:4:"name";}s:5:"value";a:1:{s:3:"par";s:5:"value";}s:9:"accesskey";a:1:{s:3:"par";s:9:"accesskey";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:7:"onclick";a:1:{s:3:"par";s:7:"onclick";}s:10:"ondblclick";a:1:{s:3:"par";s:10:"ondblclick";}s:11:"onmousedown";a:1:{s:3:"par";s:11:"onmousedown";}s:9:"onmouseup";a:1:{s:3:"par";s:9:"onmouseup";}s:11:"onmouseover";a:1:{s:3:"par";s:11:"onmouseover";}s:11:"onmousemove";a:1:{s:3:"par";s:11:"onmousemove";}s:10:"onmouseout";a:1:{s:3:"par";s:10:"onmouseout";}s:10:"onkeypress";a:1:{s:3:"par";s:10:"onkeypress";}s:9:"onkeydown";a:1:{s:3:"par";s:9:"onkeydown";}s:7:"onkeyup";a:1:{s:3:"par";s:7:"onkeyup";}s:8:"selected";a:3:{s:3:"par";s:8:"selected";s:6:"single";s:0:"";s:10:"editmethod";s:40:"_Translator_edit_standart_single_control";}}}s:4:"link";a:4:{s:3:"tag";s:4:"link";s:6:"endtag";s:6:"absent";s:14:"pictureforedit";s:17:"tags/tag_link.gif";s:4:"pars";a:13:{s:3:"rel";a:1:{s:3:"par";s:3:"rel";}s:3:"rev";a:1:{s:3:"par";s:3:"rev";}s:4:"href";a:1:{s:3:"par";s:4:"href";}s:6:"target";a:1:{s:3:"par";s:6:"target";}s:5:"media";a:1:{s:3:"par";s:5:"media";}s:8:"hreflang";a:1:{s:3:"par";s:8:"hreflang";}s:7:"charset";a:1:{s:3:"par";s:7:"charset";}s:5:"title";a:1:{s:3:"par";s:5:"title";}s:3:"dir";a:1:{s:3:"par";s:3:"dir";}s:4:"lang";a:1:{s:3:"par";s:4:"lang";}s:5:"style";a:1:{s:3:"par";s:5:"style";}s:2:"id";a:1:{s:3:"par";s:2:"id";}s:5:"class";a:1:{s:3:"par";s:5:"class";}}}s:21:"EDIT_TAGS_AFTER_TABLE";a:2:{i:0;s:4:"body";i:1;s:2:"td";}} \ No newline at end of file
diff --git a/includes/htmlparser/htmlgrammar.dat b/includes/htmlparser/htmlgrammar.dat
new file mode 100755
index 0000000..8329ad8
--- /dev/null
+++ b/includes/htmlparser/htmlgrammar.dat
@@ -0,0 +1,1176 @@
+/*
+Îïèñàíèå ïàðàìåòðîâ ãðàììàòèêè
+The grammar parameters description.
+
+endtag= "present | canabsent | absent"
+ present - çàêðûòèå òåãà îáÿçàòåëüíî äîëæíî ïðèñóòñòâîâàòü
+ - close tag must present
+
+ canabsent - çàêðûòèå òåãà ìîæåò îòñóòñòâîâàòü, íî ìîæåò è ïðèñóòñòâîâàòü
+ - close tag can absent
+
+ absent - çàêðûòèå òåãà âñåãäà îòñóòñòâóåò
+ - close tag always absent
+
+nohavesametag - òýã íå ìîæåò ñîäåðæàòü â ñåáå ñåáÿ ñàìîãî, åñëè âíóòðè òýãà âñòðå÷àåòñÿ
+ îí ñàì, òî òåã çàêðûâàåòñÿ
+ - tag can't contains itself inside. If it has itself inside then it must
+ be closed before itself
+
+nohavetags - òåã ñîäåðæèò òîëüêî òåêñò. Äàæå åñëè âíóòðè íåãî âñòðå÷àþòñÿ òýãè, òî
+ îíè òðàêòóþòñÿ êàê òåêñò.
+ - tag can has text only. If it has tags inside then these tags will be to interpret
+ as text.
+
+closeon = - "tagname|...|!tagname|..." - ïðèíóäèòåëüíîå çàêðûòèå òýãà ïðè âñòðå÷å îòêðûòèÿ
+ äðóãîãî òåãà. ìîæíî äåëàòü ïåðå÷èñëåíèÿ ìíîæåñòâà òåãîâ èëè îòðèöàíèå ìíîæåñòâà
+ òåãîâ, íàïðèìåð closeon="a|b|i|!form" òî åñòü çàêðûâàòü òåã ïðè âñòðå÷å îòêðûòèÿ
+ òåãîâ A,B,I è åñëè ýòî ê òîìó æå íå òåã FORM
+ - "tagname|...|!tagname|..." - rules for closing tag. |tagname|... list says
+ that tag must to be closed before first tagname if it exist inside it.
+ |!tagname|!.... list says then tag must to be closed if it has not a tagname
+ tag inside. You must combine these lists into one closeon part. For example:
+ closeon="a|b|i|!form" or closeon="a" or closeon="!form".
+
+Âû òàêæå ìîæåòå äîáàâëÿòü ñâîè ïàðàìåòðû â ãðàììàòèêó åñëè Âàì íàäî èñïîëüçîâàòü èõ â äàëüíåéøåì.
+Íàïðèìåð, Âàì íàäî óêàçàòü êàêîé ôóíêöèåé âû áóäåòå îáðàáàòûâàòü òåã óæå ïîñëå ïàðñèíãà
+òîãäà ïèøèòå, íàïðèìåð, function="MyFunction".
+À ïîñëå ïðîöåññà ïàðñèíãà êîäà, ïðîáåãàÿ ïî äåðåâó òýãîâ çàãëÿäûâàåòå â ãðàììàòèêó ýòîãî òåãà
+è, íàïðèìåð, âûçûâàåòå äëÿ íåãî ôóíêöèþ ñ ýòèì èìåíåì.
+Òî÷íî òàê æå ìîæíî äîáàâëÿòü ïàðàìåòðû â îïèñàíèå ïàðàìåòðîâ òåãîâ.
+
+You can add your own parameters into grammar if it needs. For example, you need walk
+through parsed grammar tree and if you meet someone tag you need process it by someone function.
+In this case you can add special parameter for this tag, for example: function="MyFunction" and
+after HTML parse process you will be walk through HTML tree and see into
+grammar when you meet tag, and if it has function field you will call function by name in this field for this tag.
+Using the same method you can add own parameter fields on tag parameters into grammar.
+
+I used this grammar in my HTML tag visualizer and you can see my additional parameter
+"editmethod" for this with function names which I called in my visualizer.
+you can see my additional parameter "pictureforedit" too. It needs for the pictogram for each tag.
+I used so "width" and "height" additional parameters for visualize fields of tag with certain
+width and height.
+
+BUT THESE ADDITIONAL PARAMETERS NOT NEEDS FOR HTML PARSER! IT WILL NEED AFTER ONLY! FOR
+MY SPECIAL NEEDS.
+
+Ïðåêîìïèëåíàÿ ãðàììàòèêà èìååò ñëåäóþùóþ ñòðóêòóðó:
+structure of precompiled grammar is:
+
+array(
+ "tagname"=>array(
+ "internal parameter name"=>value,
+ .....
+ "pars"=>array(
+ "parname"=>array(
+ "parparameter name"=>value,
+ .....
+ ),
+ .....
+ )
+ )
+ ....
+)
+íàïðèìåð, ó âàñ â îòïàðñåíîì äåðåâå åñòü òåã <a ...>. Åãî ïîëíûé íàáîð ïàðàìåòðîâ
+â ïðåêîìïèëåíîé ãðàììàòèêå $grammar ìîæíî ïîñìîòðåòü ñëåäóþùèì îáðàçîì
+
+For example, if you have tag A into parsed tree, then you can see the
+grammar for A tag as
+
+PrintArray($grammar["a"])
+
+à òîëüêî íàáîð ïàðàìåòðîâ òåãà, íàïðèìåð òàê
+
+and parameters only for tag A as
+
+PrintArray($grammar["a"]["pars"])
+*/
+
+<tag="pre"
+ endtag="present"
+ nohavetags
+>
+<tag="hr"
+ endtag="absent"
+ [ par="color" ]
+ [ par="width" ]
+ [ par="noshade" single editmethod="_Translator_edit_standart_single_control"]
+>
+
+<tag="noframes"
+ endtag="present"
+>
+
+<tag="frameset"
+ endtag="canabsent"
+ pictureforedit="tags/tag.gif"
+ [ par=rows ]
+ [ par=cols ]
+ [ par=frameborder ]
+ [ par=border ]
+ [ par=framespacing ]
+ [ par=marginheight ]
+ [ par=marginwidth ]
+ [ par=noresize ]
+>
+
+<tag="frame"
+ endtag="absent"
+ pictureforedit="tags/tag_frame2.gif"
+ [ par=name ]
+ [ par=target ]
+ [ par=scrolling ]
+ [ par=border ]
+ [ par=frameborder ]
+ [ par=framespacing ]
+ [ par=marginheight ]
+ [ par=marginwidth ]
+ [ par=noresize ]
+ [ par=src width="40" height="3" ]
+>
+
+<tag="iframe"
+ pictureforedit="tags/tag_iframe2.gif"
+>
+
+<tag="html"
+ endtag="present"
+ edittagsafter="body"
+ comment="Html"
+ pictureforedit="tags/tag.gif"
+>
+
+<tag="meta"
+ endtag="absent"
+ edittagsafter="body"
+>
+
+<tag="script"
+ nohavetags
+ endtag="present"
+ pictureforedit="tags/tag_script.gif"
+ edittagsbefore="script"
+ [ par="language" ]
+ [ par="src" width="40" height="3" ]
+>
+
+<tag="nobr"
+ closeon="!strong|!sup|!center|!font|!i|!b|!u|!tt|!s|!big|!small|!strike|!br|!script"
+ endtag="present"
+>
+
+<tag="p"
+closeon="!a|!map|!area|!strong|!sup|!font|!i|!b|!u|!tt|!img|!s|!big|!small|!strike|!nobr|!br|!script|!input|!select|!textarea|!option|!button"
+ endtag="canabsent"
+ pictureforedit="tags/tag_p2.gif"
+ [ par="align" editmethod="_Translator_edit_p_align"]
+>
+
+<tag="th"
+ endtag="absent"
+ [ par="align" editmethod="_Translator_edit_th_align"]
+>
+
+<tag="noscript"
+ endtag="present"
+>
+
+<tag="style"
+ nohavetags
+ endtag="present"
+>
+
+<tag="head"
+ endtag="present"
+ edittagsafter="body"
+>
+
+<tag="center"
+ endtag="present"
+ comment="Center"
+ pictureforedit="tags/tag.gif"
+>
+
+<tag="img"
+ endtag="absent"
+ comment="Picture"
+ pictureforedit="tags/tag_img.gif"
+ [ par="src" width="40" height="3" ]
+
+ [ par="alt" ]
+ [ par="width"]
+ [ par="height"]
+ [ par="border"]
+ [ par="name"]
+ [ par="align" editmethod="_Translator_edit_img_align"]
+ [ par="vspace" ]
+ [ par="hspace" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmouseover" ]
+ [ par="onmouseout" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="usemap" editmethod="_Translator_edit_standart_usemap"]
+>
+<tag="a"
+ nohavesametag
+ endtag="present"
+ edittagsbefore="a"
+ comment="Url"
+ pictureforedit="tags/tag_a.gif"
+ closeon="!strong|!sup|!center|!font|!i|!b|!u|!tt|!img|!s|!big|!small|!strike|!nobr|!br|!script|!li|!ol|!ul"
+ [ par="href" width="40" height="3" ]
+ [ par="name" ]
+ [ par="hreflang" ]
+ [ par="rel" ]
+ [ par="rev" ]
+
+ [ par="id"]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="accesskey" ]
+ [ par="shape" ]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="tabindex" ]
+ [ par="target"]
+>
+
+<tag="ul"
+ endtag="present"
+ comment="Unsequence list"
+ pictureforedit="tags/tag.gif"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|!li|!ol|table|tr|td"
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir"]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="type" ]
+>
+
+<tag="li"
+ endtag="present"
+ comment="List element"
+ pictureforedit="tags/tag.gif"
+ nohavesametag
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|!ol|!ul"
+
+ [ par="value" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="type" ]
+>
+
+<tag="ol"
+ endtag="present"
+ comment="Sequence list"
+ pictureforedit="tags/tag.gif"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|!ol|!ul"
+ nohavesametag
+
+ [ par="start" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="type" ]
+>
+
+<tag="title"
+ endtag="present"
+ comment="Page header"
+ pictureforedit="tags/tag.gif"
+>
+
+<tag="textarea"
+ nohavetags
+ endtag="present"
+ comment="Textarea"
+ pictureforedit="tags/tag_textarea.gif"
+
+ [ par="disabled" single editmethod="_Translator_edit_standart_single_control"]
+ [ par="name" ]
+ [ par="rows" ]
+ [ par="cols" ]
+ [ par="accesskey" ]
+ [ par="wrap" ]
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="onselect" ]
+ [ par="onchange" ]
+
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="tr"
+ endtag="present"
+ comment="Table row"
+ pictureforedit="tags/tag_tr.gif"
+ edittagsafter="td"
+
+ [ par="align" editmethod="_Translator_edit_td_align"]
+ [ par="valign" editmethod="_Translator_edit_td_valign"]
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="bgcolor" ]
+ [ par="background" ]
+
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="td"
+ endtag="present"
+ comment="Table cell"
+ pictureforedit="tags/tag_td.gif"
+ edittagsafter="td"
+
+ [ par="colspan" ]
+ [ par="rowspan" ]
+ [ par="width" ]
+ [ par="height" ]
+ [ par="bgcolor" ]
+ [ par="background" ]
+ [ par="align" editmethod="_Translator_edit_td_align" ]
+ [ par="valign" editmethod="_Translator_edit_td_valign" ]
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="nowrap" single editmethod="_Translator_edit_standart_single_control" ]
+>
+
+<tag="table"
+ endtag="present"
+ comment="Table"
+ pictureforedit="tags/tag_table.gif"
+
+ [ par="width" ]
+ [ par="height" ]
+ [ par="bgcolor" ]
+ [ par="background" ]
+ [ par="cellspacing" ]
+ [ par="cellpadding" ]
+ [ par="border" ]
+ [ par="bordercolor" ]
+ [ par="summary" ]
+ [ par="align" editmethod="_Translator_edit_table_align" ]
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypressed" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="area" endtag="absent"
+ pictureforedit="tags/tag.gif"
+ comment="Map region"
+
+ [ par="href" width="40" height="3" ]
+ [ par="shape" editmethod="_Translator_edit_standart_shape" ]
+ [ par="coords" ]
+ [ par="usemap" ]
+ [ par="alt" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="accesskey" ]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="tabindex" ]
+>
+
+<tag="span"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Span"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="b"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag_b2.gif"
+ comment="B"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="tt"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="TT"
+ [ par="id"]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="i"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag_i2.gif"
+ comment="I"
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="big"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Big"
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="small"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Small"
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="strike"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Strike"
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="s"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="S"
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="u"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag_u2.gif"
+ comment="U"
+ [ par="id"]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="map"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Map"
+ closeon="!area"
+ [ par="name" ]
+>
+
+<tag="br"
+ edit="0"
+ endtag="absent"
+ [ par="clear" ]
+ [ par="id" ]
+ [ par="title" ]
+ [ par="class" ]
+ [ par="style" ]
+>
+<tag="base"
+ endtag="absent"
+ pictureforedit="tags/tag.gif"
+ comment="Base"
+ [ par="href" width="40" height="3" ]
+ [ par="target" ]
+>
+
+<tag="basefont"
+ endtag="absent"
+ pictureforedit="tags/tag.gif"
+ comment="Basefont"
+ [ par="id" ]
+ [ par="size" ]
+ [ par="color" ]
+ [ par="face" ]
+ [ par="class" ]
+ [ par="title" ]
+ [ par="style" ]
+>
+
+<tag="body"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag_body.gif"
+ edittagsafter="body"
+ comment="Page body"
+
+ [ par="background" ]
+ [ par="text" ]
+ [ par="link" ]
+ [ par="vlink" ]
+ [ par="alink" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="bgcolor" ]
+ [ par="style" ]
+ [ par="title" ]
+ [ par="lang" ]
+ [ par="style" ]
+ [ par="topmargin"]
+ [ par="leftmargin"]
+ [ par="marginwidth"]
+ [ par="marginheight"]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="onload" ]
+ [ par="onunload" ]
+>
+
+<tag="button"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag_button.gif"
+ comment="Button"
+ closeon="!center|!font|!i|!b|!u|!tt|!a|!img|!s|!big|!small|!strike|!nobr|!br|!script"
+
+ [ par="name" ]
+ [ par="value" ]
+ [ par="type" ]
+ [ par="disabled" single editmethod="_Translator_edit_standart_single_control"]
+ [ par="accesskey" ]
+ [ par="usemap" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+>
+
+<tag="div"
+ endtag="present"
+ pictureforedit="tags/tag_div.gif"
+ comment="Division"
+
+ [ par="id" ]
+ [ par="name" ]
+ [ par="class" ]
+ [ par="align" editmethod="_Translator_edit_div_align"]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="span"
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="span"
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="font"
+ endtag="present"
+ pictureforedit="tags/tag_font2.gif"
+ comment="Font"
+ closeon="!i|!b|!u|!tt|!a|!img|!s|!big|!small|!strike|!nobr|!br|!script"
+
+ [ par="id" ]
+ [ par="size" ]
+ [ par="color" ]
+ [ par="face" ]
+ [ par="class" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="lang" ]
+ [ par="dir" ]
+>
+
+<tag="form"
+ endtag="present"
+ pictureforedit="tags/tag_form.gif"
+ comment="Form"
+
+ [ par="action" width="40" height="3"]
+ [ par="method" ]
+ [ par="enctype" ]
+ [ par="accept-charset" ]
+ [ par="accept" ]
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="style" ]
+ [ par="title" ]
+ [ par="target" ]
+ [ par="onsubmit" ]
+ [ par="onreset" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="h1"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="hl"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang"]
+ [ par="dir"]
+ [ par="style"]
+ [ par="title"]
+ [ par="align"]
+ [ par="onclick"]
+ [ par="ondblclick"]
+ [ par="onmousedown"]
+ [ par="onmouseup"]
+ [ par="onmouseover"]
+ [ par="onmousemove"]
+ [ par="onmouseout"]
+ [ par="onkeypress"]
+ [ par="onkeydown"]
+ [ par="onkeyup"]
+>
+<tag="h2"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="h2"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang"]
+ [ par="dir"]
+ [ par="style"]
+ [ par="title"]
+ [ par="align"]
+ [ par="onclick"]
+ [ par="ondblclick"]
+ [ par="onmousedown"]
+ [ par="onmouseup"]
+ [ par="onmouseover"]
+ [ par="onmousemove"]
+ [ par="onmouseout"]
+ [ par="onkeypress"]
+ [ par="onkeydown"]
+ [ par="onkeyup"]
+>
+<tag="h3"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="h3"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang"]
+ [ par="dir"]
+ [ par="style"]
+ [ par="title"]
+ [ par="align"]
+ [ par="onclick"]
+ [ par="ondblclick"]
+ [ par="onmousedown"]
+ [ par="onmouseup"]
+ [ par="onmouseover"]
+ [ par="onmousemove"]
+ [ par="onmouseout"]
+ [ par="onkeypress"]
+ [ par="onkeydown"]
+ [ par="onkeyup"]
+>
+<tag="h4"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="h4"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang"]
+ [ par="dir"]
+ [ par="style"]
+ [ par="title"]
+ [ par="align"]
+ [ par="onclick"]
+ [ par="ondblclick"]
+ [ par="onmousedown"]
+ [ par="onmouseup"]
+ [ par="onmouseover"]
+ [ par="onmousemove"]
+ [ par="onmouseout"]
+ [ par="onkeypress"]
+ [ par="onkeydown"]
+ [ par="onkeyup"]
+>
+<tag="h5"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="h5"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang"]
+ [ par="dir"]
+ [ par="style"]
+ [ par="title"]
+ [ par="align"]
+ [ par="onclick"]
+ [ par="ondblclick"]
+ [ par="onmousedown"]
+ [ par="onmouseup"]
+ [ par="onmouseover"]
+ [ par="onmousemove"]
+ [ par="onmouseout"]
+ [ par="onkeypress"]
+ [ par="onkeydown"]
+ [ par="onkeyup"]
+>
+<tag="h6"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!nobr|!br|!script"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="h6"
+ [ par="id" ]
+ [ par="class"]
+ [ par="lang"]
+ [ par="dir"]
+ [ par="style"]
+ [ par="title"]
+ [ par="align"]
+ [ par="onclick"]
+ [ par="ondblclick"]
+ [ par="onmousedown"]
+ [ par="onmouseup"]
+ [ par="onmouseover"]
+ [ par="onmousemove"]
+ [ par="onmouseout"]
+ [ par="onkeypress"]
+ [ par="onkeydown"]
+ [ par="onkeyup"]
+>
+
+<tag="input"
+ endtag="absent"
+ pictureforedit="tags/tag_input.gif"
+ comment="Form input element"
+
+ [ par="type" editmethod="_Translator_edit_input_type" ]
+ [ par="name" ]
+ [ par="value" ]
+ [ par="checked" single editmethod="_Translator_edit_standart_single_control" ]
+ [ par="disabled" single editmethod="_Translator_edit_standart_single_control" ]
+ [ par="readonly" single editmethod="_Translator_edit_standart_single_control" ]
+ [ par="size" ]
+ [ par="maxlength" ]
+ [ par="src" width="40" height="3" ]
+ [ par="width"]
+ [ par="height"]
+ [ par="alt" ]
+ [ par="border"]
+ [ par="tabindex"]
+ [ par="accesskey"]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="onselect"]
+ [ par="onchange"]
+ [ par="accept" ]
+
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="align" ]
+ [ par="shape" ]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="onclick" ]
+ [ par="onselect" ]
+ [ par="onchange" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="label"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Label"
+
+ [ par="for" ]
+ [ par="accesskey" ]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="select"
+ nohavesametag
+ endtag="present"
+ edittagsbefore="select"
+ pictureforedit="tags/tag_select.gif"
+ comment="Select"
+ closeon="!option"
+
+ [ par="disabled" single editmethod="_Translator_edit_standart_single_control" ]
+ [ par="multiple" single editmethod="_Translator_edit_standart_single_control" ]
+ [ par="name" ]
+ [ par="size" ]
+ [ par="width" ]
+ [ par="accesskey" ]
+ [ par="onfocus" ]
+ [ par="onblur" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+>
+
+<tag="option"
+ closeon="!strong|!sup|!font|!i|!b|!u|!tt|!a|!s|!big|!small|!strike|!br|!nobr|!script|option"
+ nohavesametag
+ endtag="present"
+ pictureforedit="tags/tag.gif"
+ comment="Option"
+
+ [ par="name" ]
+ [ par="value" ]
+ [ par="accesskey" ]
+ [ par="id" ]
+ [ par="class" ]
+ [ par="lang" ]
+ [ par="dir" ]
+ [ par="title" ]
+ [ par="style" ]
+ [ par="onclick" ]
+ [ par="ondblclick" ]
+ [ par="onmousedown" ]
+ [ par="onmouseup" ]
+ [ par="onmouseover" ]
+ [ par="onmousemove" ]
+ [ par="onmouseout" ]
+ [ par="onkeypress" ]
+ [ par="onkeydown" ]
+ [ par="onkeyup" ]
+ [ par="selected" single editmethod="_Translator_edit_standart_single_control"]
+>
+
+<tag="link"
+ endtag="absent"
+ pictureforedit="tags/tag_link.gif"
+ [ par=rel ]
+ [ par=rev ]
+ [ par=href ]
+ [ par=target ]
+ [ par=media ]
+ [ par=hreflang ]
+ [ par=charset ]
+ [ par=title ]
+ [ par=dir ]
+ [ par=lang ]
+ [ par=style ]
+ [ par=id ]
+ [ par=class ]
+>
diff --git a/includes/htmlparser/htmlgrammarparser.inc b/includes/htmlparser/htmlgrammarparser.inc
new file mode 100755
index 0000000..259fcce
--- /dev/null
+++ b/includes/htmlparser/htmlgrammarparser.inc
@@ -0,0 +1,478 @@
+<?php
+if (!defined("_ECHOSERVER_HTML_GRAMMARPARSER")) {
+define("_ECHOSERVER_HTML_GRAMMARPARSER",1);
+
+class HtmlGrammarParser {
+ var $line,
+ $column,
+ $pos,
+ $length,
+ $data,
+ $pg,
+ $pgpos,
+ $parpos,
+ $incomment,
+ $name,
+ $allreadyparsed,
+ $errors,
+ $errpos,
+ $quotstate,
+ $firstprev,
+ $secondprev,
+ $firststate,
+ $secondstate,
+ $iseof,
+ $mode,
+ $tagname,
+ $parname;
+/**********************************************************************************
+ * Class constructor
+ **********************************************************************************/
+ function HtmlGrammarParser($data) {
+ $this->firstprev=array("state"=>0,"word"=>"");
+ $this->secondprev=array("state"=>0,"word"=>"");
+ $this->line=0;
+ $this->pos=0;
+ $this->errors=array();
+ $this->errpos=-1;
+ $this->incomment=-1;
+ $this->allreadyparsed=0;
+ $this->pg=array();
+ $this->pgpos=-1;
+ $this->quotstate=-1;
+ $this->iseof=false;
+ $this->firststate=0;
+ $this->secondstate=0;
+ $this->mode=1;
+
+ if(gettype($this->data)=="array") {
+ $this->pg=&$data;
+ $this->allreadyparsed=1;
+ return;
+ }
+ clearstatcache();
+ $this->name=$data;
+ if (!file_exists($this->name)) {
+ $this->SetError(1,"File $this->name not exists.",0,0,"Error");
+ return;
+ }
+ if (!$fp=fopen($this->name,"r")) {
+ $this->SetError(1,"Can't open file $this->name.",0,0,"Error");
+ return;
+ }
+ flock($fp,1);
+ $this->data=fread($fp,filesize($this->name));
+ flock($fp,3);
+ fclose($fp);
+ $this->length=strlen($this->data);
+ }
+
+/********************************************************************************************
+ * Store parser's errors and warnings
+ ********************************************************************************************/
+ function SetError($e,$str,$line=0,$column=0,$errtype="Warning") {
+ $this->errors[++$this->errpos]["type"]=$errtype;
+ $this->errors[$this->errpos]["code"]=$e;
+ $this->err=$e;
+ $this->errstr="<b>$errtype:</b> $e, $str";
+ if ($line) {
+ if (strlen($this->name))
+ $this->errstr.="object <font color=\"red\">$this->name</font>";
+ $this->errstr.=" Line <b>$line</b>, Column <b>$column</b>";
+ }
+ $this->errors[$this->errpos]["str"]=$this->errstr."<br>\r\n";
+ }
+
+/********************************************************************************************
+ * Print parser's errors and warnings
+ ********************************************************************************************/
+ function PrintErrors() {
+ for ($i=0;$i<=$this->errpos;$i++)
+ print $this->errors[$i]["str"];
+ }
+
+/********************************************************************************************
+ * Get word from data
+ ********************************************************************************************/
+ function GetWord($word) {
+ $word="";
+ $found=0;
+ $iter=0;
+ if ($this->pos>$this->length)
+ return false;
+ while (!$found) {
+ if ($this->pos>$this->length)
+ return false;
+ if ($this->pos==$this->length) {
+ $this->pos++;
+ return $word;
+ }
+ switch($this->data[$this->pos]) {
+ case "*":
+ if ($this->quotstate==1) {
+ $word.=$this->data[$this->pos++];
+ $this->column++;
+ break;
+ }
+ $this->column++;
+ $this->pos++;
+ if ($word[0]=="/")
+ $found=1;
+ $word.=$this->data[$this->pos-1];
+ break;
+ case "/":
+ if ($this->quotstate==1) {
+ $word.=$this->data[$this->pos++];
+ $this->column++;
+ break;
+ }
+ $this->column++;
+ $this->pos++;
+ if ($word[0]=="*")
+ $found=1;
+ $word.=$this->data[$this->pos-1];
+ break;
+ case " ":
+ case "\r":
+ case "\t":
+ if ($this->quotstate==1) {
+ $word.=$this->data[$this->pos++];
+ $this->column++;
+ break;
+ }
+ $this->column++;
+ $this->pos++;
+ if (strlen($word))
+ $found=1;
+ break;
+ case "\n":
+ if ($this->quotstate==1) {
+ $word.=$this->data[$this->pos++];
+ $this->column++;
+ break;
+ }
+ $this->column=0;
+ $this->line++;
+ $this->pos++;
+ if (strlen($word))
+ $found=1;
+ break;
+ case ">":
+ case "<":
+ case "=":
+ if ($this->quotstate==1) {
+ $word.=$this->data[$this->pos++];
+ $this->column++;
+ } else {
+ if (!strlen($word)) {
+ $word=$this->data[$this->pos++];
+ $this->column++;
+ }
+ $found=1;
+ }
+ break;
+ case "\"":
+ if ($this->pos) {
+ if ($this->data[$this->pos-1]=="\\") {
+ $word.=$this->data[$this->pos++];
+ $this->column++;
+ } else {
+ if (!strlen($word)) {
+ $this->quotstate*=-1;
+ $word=$this->data[$this->pos++];
+ $this->column++;
+ }
+ $found=1;
+ }
+ } else {
+ $word=$this->data[$this->pos++];
+ $this->column++;
+ $found=1;
+ }
+ break;
+ default:
+ $this->column++;
+ $word.=$this->data[$this->pos++];
+ }
+ }
+ return true;
+ }
+
+/********************************************************************************************
+ * Parse grammar first step
+ ********************************************************************************************
+Parse
+< [] [] >
+
+in/state 0 1 2 3
+< 1 -1 -1 1
+[ -1 2 -1 -1
+] -1 -1 1 -1
+> -1 3 -1 -1
+word -1 1 2 -1
+EOF -1 -1 -1 -2
+
+-2 end parse
+ 0 begin parse, waiting '<'
+ 1 got '<' need to parse parameters, or wait '>' or wait '['
+ 2 got '[' or ']' need to parse parameters
+ 3 got '>', waiting eof or '<'
+
+ ********************************************************************************************/
+ function ParseFirst($word) {
+ if ($this->iseof) {
+ $this->firstprev["state"]=0;
+ $this->firstprev["word"]="";
+ return true;
+ }
+ $automat=array(
+ "0"=>array( 1, -1, -1, 1),
+ "1"=>array(-1, 2, -1, -1),
+ "2"=>array(-1, -1, 1, -1),
+ "3"=>array(-1, 3, -1, -1),
+ "4"=>array(-1, 1, 2, -1),
+ "5"=>array(-1, -1, -1, -2)
+ );
+ switch($word) {
+ case "<":
+ $instate=0;
+ $this->pgpos++;
+ $this->parpos=-1;
+ break;
+ case "[":
+ $this->parpos++;
+ $instate=1;
+ break;
+ case "]":
+ $instate=2;
+ break;
+ case ">":
+ $instate=3;
+ break;
+ default:
+ $instate=4;
+ break;
+ }
+ $this->firststate=$automat[$instate][$this->firststate];
+ if ($this->firststate==-1) return false;
+ switch ($this->firststate) {
+ case 1:
+ $this->mode=1;
+ if ($this->firstprev["state"]==1)
+ if (!$this->ParseSecond($word)) return false;
+ break;
+ case 2:
+ switch($this->firstprev["state"]) {
+ case 1:
+ $this->mode=2;
+ break;
+ case 3:
+ case 2:
+ if ($this->firstprev["state"]==2)
+ $this->mode=2;
+ else
+ $this->mode=1;
+ break;
+ }
+ if ($this->firstprev["state"]==2)
+ if (!$this->ParseSecond($word)) return false;
+ break;
+ case 3:
+ if (isset($this->pg[$this->pgpos]["tag"]["nohavesametag"]))
+ $this->pg[$this->pgpos]["tag"]["closeon"]["in"][]=$this->tagname;
+ break;
+ }
+ $this->firstprev["state"]=$this->firststate;
+ $this->firstprev["word"]=$word;
+ return true;
+ }
+
+/********************************************************************************************
+ * Parse grammar second step
+ ********************************************************************************************
+
+Parse
+par1="value" par2=value
+
+in/state 0 1 2 3 4
+= -1 2 -1 3 -1
+" -1 -1 3 4 -1
+word 1 -1 4 3 1
+EOF -1 -1 -1 -1 -1
+
+-3 end parse by '>'
+-2 end parse by ']'
+ 0 begin parse waiting parname
+ 1 got parname, waiting '=' or new parname
+ 2 got '=' waiting any word as value or first '"'
+ 3 collect words to next '"'
+ 4 got parvalue, waiting new parname
+ ********************************************************************************************/
+ function ParseSecond($word) {
+ if ($this->iseof) return false;
+ $automat=array(
+ "0"=>array(-1, 2, -1, 3, -1),
+ "1"=>array(-1, -1, 3, 4, -1),
+ "2"=>array( 1, 1, 4, 3, 1),
+ "3"=>array(-1, -1, -1, -1, -1)
+ );
+ switch($word) {
+ case "=":
+ $instate=0;
+ break;
+ case "\"":
+ $instate=1;
+ break;
+ default:
+ $instate=2;
+ break;
+ }
+ $this->secondstate=$automat[$instate][$this->secondstate];
+ if ($this->secondstate==-1) return false;
+ switch ($this->secondstate) {
+ case 1:
+ $this->parname=$word;
+ if (!ereg("[a-zA-Z_-]+([0-9]+)?",$word)) {
+ $this->SetError(1,"Fatal error.",$this->line,$this->column,"Error");
+ return false;
+ }
+ switch($this->mode) {
+ case 1:
+ $this->pg[$this->pgpos]["tag"][$this->parname]="";
+ break;
+ case 2:
+ $this->pg[$this->pgpos]["pars"][$this->parpos][$this->parname]="";
+ break;
+ }
+ break;
+ case 4:
+ switch($this->mode) {
+ case 1:
+ if ($this->secondprev["state"]==3)
+ $this->pg[$this->pgpos]["tag"][$this->parname]=$this->secondprev["word"];
+ else
+ $this->pg[$this->pgpos]["tag"][$this->parname]=$word;
+ if ($this->parname=="closeon") {
+ $notexists=array();
+ $exists=array();
+ $this->ParseCloseOn($this->pg[$this->pgpos]["tag"][$this->parname],&$notexists,&$exists);
+ $this->pg[$this->pgpos]["tag"][$this->parname]=array();
+ $this->pg[$this->pgpos]["tag"][$this->parname]["notin"]=$notexists;
+ $this->pg[$this->pgpos]["tag"][$this->parname]["in"]=$exists;
+ } elseif ($this->parname=="tag")
+ $this->tagname=$this->pg[$this->pgpos]["tag"]["tag"];
+ break;
+ case 2:
+ if ($this->secondprev["state"]==3)
+ $this->pg[$this->pgpos]["pars"][$this->parpos][$this->parname]=$this->secondprev["word"];
+ else
+ $this->pg[$this->pgpos]["pars"][$this->parpos][$this->parname]=$word;
+ break;
+ }
+ break;
+ }
+ $this->secondprev["state"]=$this->secondstate;
+ $this->secondprev["word"]=$word;
+ return true;
+ }
+
+/********************************************************************************************
+ * Parse closeon structure
+ ********************************************************************************************/
+ function ParseCloseOn($str,$notexists,$exists) {
+ $arr=explode("|",$str);
+ if (!is_array($arr)) {
+ if (!strlen($str))
+ return;
+ else
+ $arr[]=$str;
+ }
+ for ($i=0;$i<sizeof($arr);$i++) {
+ if ($arr[$i][0]=="!")
+ $notexists[]=substr($arr[$i],1,strlen($arr[$i])-1);
+ else
+ $exists[]=$arr[$i];
+ }
+ }
+
+/********************************************************************************************
+ * Parse grammar
+ ********************************************************************************************/
+ function Parse() {
+ if ($this->allreadyparsed) return true;
+ $this->line=1;
+ while(1) {
+ $isword=$this->GetWord(&$word);
+ if (!$isword) $this->iseof=true;
+ switch (strtolower($word)) {
+ case "/*";
+ $this->incomment*=-1;
+ break;
+ case "*/";
+ if ($this->incomment!=1) {
+ $this->SetError(1,"Not found begin of comment operator.",$this->line,$this->column,"Error");
+ return;
+ }
+ $this->incomment*=-1;
+ break;
+ default:
+ if ($this->incomment==1) break;
+ if (!$this->ParseFirst($word)) {
+ $this->SetError(1,"Fatal error",$this->line,$this->column,"Error");
+ return false;
+ }
+ break;
+ }
+ if ($this->iseof) break;
+ }
+ if ($this->incomment==1) {
+ $this->SetError(1,"Not found end of comment operator.",$this->line,$this->column,"Error");
+ return false;
+ }
+ $this->PrepareGrammar();
+ return true;
+ }
+/********************************************************************************************
+ * Prepare grammar for future using
+ ********************************************************************************************/
+ function PrepareGrammar() {
+ $edittagsaftertable=$this->ScanGrammar();
+ $l=sizeof($this->pg);
+ for ($i=0;$i<$l;$i++) {
+ $this->pg[$this->pg[$i]["tag"]["tag"]]=$this->pg[$i]["tag"];
+ if (isset($this->pg[$i]["pars"])) {
+ $n=sizeof($this->pg[$i]["pars"]);
+ for ($j=0;$j<$n;$j++)
+ $this->pg[$this->pg[$i]["tag"]["tag"]]["pars"][$this->pg[$i]["pars"][$j]["par"]]=$this->pg[$i]["pars"][$j];
+ } else
+ $this->pg[$this->pg[$i]["tag"]["tag"]]["pars"]=array();
+ unset($this->pg["$i"]);
+ }
+ $this->pg["EDIT_TAGS_AFTER_TABLE"]=$edittagsaftertable;
+ }
+/********************************************************************************************
+ * Scan grammar for creating edittagsafter table
+ ********************************************************************************************/
+ function ScanGrammar() {
+ $edittagsaftertable=array();
+ for ($i=0;$i<sizeof($this->pg);$i++)
+ if (isset($this->pg[$i]["tag"]["edittagsafter"]))
+ if (!in_array($this->pg[$i]["tag"]["edittagsafter"],$edittagsaftertable)) $edittagsaftertable[]=$this->pg[$i]["tag"]["edittagsafter"];
+ return $edittagsaftertable;
+ }
+/********************************************************************************************
+ * Save precompiled grammar in file
+ ********************************************************************************************/
+ function SaveGrammar($name) {
+ $str=serialize($this->pg);
+ if (!$fp=fopen($name,"w"))
+ print "<br>Error: Can't create file $name. Unable to save grammar.<br>";
+ flock($fp,2);
+ fwrite($fp,$str,strlen($str));
+ flock($fp,3);
+ fclose($fp);
+ }
+}
+
+} //_ECHOSERVER_HTML_GRAMMARPARSER
+?>
diff --git a/includes/htmlparser/readme.eng.txt b/includes/htmlparser/readme.eng.txt
new file mode 100755
index 0000000..96a9da1
--- /dev/null
+++ b/includes/htmlparser/readme.eng.txt
@@ -0,0 +1,19 @@
+testhtmlparser.php - example of using
+rebuildgrammar.php - grammar compiler
+htmlgrammar.dat - grammar
+htmlgrammar.cmp - compiled grammar
+test.html - html file for test the html parser
+common.inc - additional functions
+imgsrcchange.inc - this example shows how to change src parameter for all img tags.
+
+Setup is very simple. You need copy all files into someone catalog on
+your web server and after this call http://..../testhtmlparser.php
+As result you will have start page of Russian PHPClub site which placed into the test.html file.
+This page was formed by tag's tree after parse process. Bellow you can see
+printed tag's tree.
+
+All questions you can send to
+anton@concord.ru
+
+or by ICQ
+3180528
diff --git a/includes/htmlparser/rebuildgrammar.php b/includes/htmlparser/rebuildgrammar.php
new file mode 100755
index 0000000..9b5bdbb
--- /dev/null
+++ b/includes/htmlparser/rebuildgrammar.php
@@ -0,0 +1,13 @@
+<?php
+
+//include ("common.inc");
+
+include ("htmlgrammarparser.inc");
+$p = new HtmlGrammarParser("htmlgrammar.dat");
+$p->Parse();
+$p->PrintErrors();
+$p->SaveGrammar("htmlgrammar.cmp");
+print "Done.";
+//PrintArray($p->pg);
+
+?>
diff --git a/includes/tar.class.php b/includes/tar.class.php
new file mode 100755
index 0000000..a0589d6
--- /dev/null
+++ b/includes/tar.class.php
@@ -0,0 +1,467 @@
+<?php
+/*
+=======================================================================
+Name:
+ tar Class
+Author:
+ Josh Barger <joshb@npt.com>
+Description:
+ This class reads and writes Tape-Archive (TAR) Files and Gzip
+ compressed TAR files, which are mainly used on UNIX systems.
+ This class works on both windows AND unix systems, and does
+ NOT rely on external applications!! Woohoo!
+Usage:
+ Copyright (C) 2002 Josh Barger
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details at:
+ http://www.gnu.org/copyleft/lesser.html
+ If you use this script in your application/website, please
+ send me an e-mail letting me know about it :)
+Bugs:
+ Please report any bugs you might find to my e-mail address
+ at joshb@npt.com. If you have already created a fix/patch
+ for the bug, please do send it to me so I can incorporate it into my release.
+Version History:
+ 1.0 04/10/2002 - InitialRelease
+ 2.0 04/11/2002 - Merged both tarReader and tarWriter
+ classes into one
+ - Added support for gzipped tar files
+ Remember to name for .tar.gz or .tgz
+ if you use gzip compression!
+ :: THIS REQUIRES ZLIB EXTENSION ::
+ - Added additional comments to
+ functions to help users
+ - Added ability to remove files and
+ directories from archive
+ 2.1 04/12/2002 - Fixed serious bug in generating tar
+ - Created another example file
+ - Added check to make sure ZLIB is
+ installed before running GZIP
+ compression on TAR
+ 2.2 05/07/2002 - Added automatic detection of Gzipped
+ tar files (Thanks go to Jrgen Falch
+ for the idea)
+ - Changed "private" functions to have
+ special function names beginning with
+ two underscores
+=======================================================================
+*/
+class tar {
+ // Unprocessed Archive Information
+ public $filename;
+ public $isGzipped;
+ public $tar_file;
+ // Processed Archive Information
+ public $files;
+ public $directories;
+ public $numFiles = 0;
+ public $numDirectories = 0;
+ // Class Constructor -- Does nothing...
+ function tar() {
+ return true;
+ }
+ // Computes the unsigned Checksum of a file's header
+ // to try to ensure valid file
+ // PRIVATE ACCESS FUNCTION
+ function __computeUnsignedChecksum($bytestring) {
+ $unsigned_chksum=0;
+ for($i=0; $i<512; $i++)
+ $unsigned_chksum += ord($bytestring[$i]);
+ for($i=0; $i<8; $i++)
+ $unsigned_chksum -= ord($bytestring[148 + $i]);
+ $unsigned_chksum += ord(" ") * 8;
+ return $unsigned_chksum;
+ }
+ // Converts a NULL padded string to a non-NULL padded string
+ // PRIVATE ACCESS FUNCTION
+ function __parseNullPaddedString($string) {
+ $position = strpos($string,chr(0));
+ return substr($string,0,$position);
+ }
+ // This function parses the current TAR file
+ // PRIVATE ACCESS FUNCTION
+ function __parseTar() {
+ // Read Files from archive
+ $tar_length = strlen($this->tar_file);
+ $main_offset = 0;
+ while($main_offset < $tar_length) {
+ // If we read a block of 512 nulls, we are at the end of the archive
+ if(substr($this->tar_file,$main_offset,512) == str_repeat(chr(0),512))
+ break;
+ // Parse file name
+ $file_name = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset,100));
+ // Parse the file mode
+ $file_mode = substr($this->tar_file,$main_offset + 100,8);
+ // Parse the file user ID
+ $file_uid = octdec(substr($this->tar_file,$main_offset + 108,8));
+ // Parse the file group ID
+ $file_gid = octdec(substr($this->tar_file,$main_offset + 116,8));
+ // Parse the file size
+ $file_size = octdec(substr($this->tar_file,$main_offset + 124,12));
+ // Parse the file update time - unix timestamp format
+ $file_time = octdec(substr($this->tar_file,$main_offset + 136,12));
+ // Parse Checksum
+ $file_chksum = octdec(substr($this->tar_file,$main_offset + 148,6));
+ // Parse user name
+ $file_uname = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 265,32));
+ // Parse Group name
+ $file_gname = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 297,32));
+ // Make sure our file is valid
+ if($this->__computeUnsignedChecksum(substr($this->tar_file,$main_offset,512)) != $file_chksum)
+ return false;
+ // Parse File Contents
+ $file_contents = substr($this->tar_file,$main_offset + 512,$file_size);
+ /* ### Unused Header Information ###
+ $activeFile["typeflag"] = substr($this->tar_file,$main_offset + 156,1);
+ $activeFile["linkname"] = substr($this->tar_file,$main_offset + 157,100);
+ $activeFile["magic"] = substr($this->tar_file,$main_offset + 257,6);
+ $activeFile["version"] = substr($this->tar_file,$main_offset + 263,2);
+ $activeFile["devmajor"] = substr($this->tar_file,$main_offset + 329,8);
+ $activeFile["devminor"] = substr($this->tar_file,$main_offset + 337,8);
+ $activeFile["prefix"] = substr($this->tar_file,$main_offset + 345,155);
+ $activeFile["endheader"] = substr($this->tar_file,$main_offset + 500,12);
+ */
+ if($file_size > 0) {
+ // Increment number of files
+ $this->numFiles++;
+ // Create us a new file in our array
+ $activeFile = &$this->files[];
+ // Asign Values
+ $activeFile["name"] = $file_name;
+ $activeFile["mode"] = $file_mode;
+ $activeFile["size"] = $file_size;
+ $activeFile["time"] = $file_time;
+ $activeFile["user_id"] = $file_uid;
+ $activeFile["group_id"] = $file_gid;
+ $activeFile["user_name"] = $file_uname;
+ $activeFile["group_name"] = $file_gname;
+ $activeFile["checksum"] = $file_chksum;
+ $activeFile["file"] = $file_contents;
+ } else {
+ // Increment number of directories
+ $this->numDirectories++;
+ // Create a new directory in our array
+ $activeDir = &$this->directories[];
+ // Assign values
+ $activeDir["name"] = $file_name;
+ $activeDir["mode"] = $file_mode;
+ $activeDir["time"] = $file_time;
+ $activeDir["user_id"] = $file_uid;
+ $activeDir["group_id"] = $file_gid;
+ $activeDir["user_name"] = $file_uname;
+ $activeDir["group_name"] = $file_gname;
+ $activeDir["checksum"] = $file_chksum;
+ }
+ // Move our offset the number of blocks we have processed
+ $main_offset += 512 + (ceil($file_size / 512) * 512);
+ }
+ return true;
+ }
+ // Read a non gzipped tar file in for processing
+ // PRIVATE ACCESS FUNCTION
+ function __readTar($filename="") {
+ // Set the filename to load
+ if(!$filename)
+ $filename = $this->filename;
+ // Read in the TAR file
+ $fp = fopen($filename,"rb");
+ $this->tar_file = fread($fp,filesize($filename));
+ fclose($fp);
+ if($this->tar_file[0] == chr(31) && $this->tar_file[1] == chr(139) && $this->tar_file[2] == chr(8)) {
+ if(!function_exists("gzinflate"))
+ return false;
+ $this->isGzipped = TRUE;
+ $this->tar_file = gzinflate(substr($this->tar_file,10,-4));
+ }
+ // Parse the TAR file
+ $this->__parseTar();
+ return true;
+ }
+ // Generates a TAR file from the processed data
+ // PRIVATE ACCESS FUNCTION
+ function __generateTAR() {
+ // Clear any data currently in $this->tar_file
+ unset($this->tar_file);
+ $this->tar_file="";
+ // Generate Records for each directory, if we have directories
+ if($this->numDirectories > 0) {
+ foreach($this->directories as $key => $information) {
+ unset($header);
+ // Generate tar header for this directory
+ // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
+ $header .= str_pad($information["name"],100,chr(0));
+ $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct(0),11,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_repeat(" ",8);
+ $header .= "5";
+ $header .= str_repeat(chr(0),100);
+ $header .= str_pad("ustar",6,chr(32));
+ $header .= chr(32) . chr(0);
+ $header .= str_pad("",32,chr(0));
+ $header .= str_pad("",32,chr(0));
+ $header .= str_repeat(chr(0),8);
+ $header .= str_repeat(chr(0),8);
+ $header .= str_repeat(chr(0),155);
+ $header .= str_repeat(chr(0),12);
+ // Compute header checksum
+ $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
+ for($i=0; $i<6; $i++) {
+ $header[(148 + $i)] = substr($checksum,$i,1);
+ }
+ $header[154] = chr(0);
+ $header[155] = chr(32);
+ // Add new tar formatted data to tar file contents
+ $this->tar_file .= $header;
+ }
+ }
+ // Generate Records for each file, if we have files (We should...)
+ if($this->numFiles > 0) {
+ foreach($this->files as $key => $information) {
+ unset($header);
+ $header="";
+ // Generate the TAR header for this file
+ // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
+ $header .= str_pad($information["name"],100,chr(0));
+ $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["size"]),11,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
+ $header .= str_repeat(" ",8);
+ $header .= "0";
+ $header .= str_repeat(chr(0),100);
+ $header .= str_pad("ustar",6,chr(32));
+ $header .= chr(32) . chr(0);
+ $header .= str_pad($information["user_name"],32,chr(0)); // How do I get a file's user name from PHP?
+ $header .= str_pad($information["group_name"],32,chr(0)); // How do I get a file's group name from PHP?
+ $header .= str_repeat(chr(0),8);
+ $header .= str_repeat(chr(0),8);
+ $header .= str_repeat(chr(0),155);
+ $header .= str_repeat(chr(0),12);
+ // Compute header checksum
+ $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
+ for($i=0; $i<6; $i++) {
+ $header[(148 + $i)] = substr($checksum,$i,1);
+ }
+ $header[154] = chr(0);
+ $header[155] = chr(32);
+ // Pad file contents to byte count divisible by 512
+ $file_contents = str_pad($information["file"],(ceil($information["size"] / 512) * 512),chr(0));
+ // Add new tar formatted data to tar file contents
+ $this->tar_file .= $header . $file_contents;
+ }
+ }
+ // Add 512 bytes of NULLs to designate EOF
+ $this->tar_file .= str_repeat(chr(0),512);
+ return true;
+ }
+ // Open a TAR file
+ function openTAR($filename) {
+ // Clear any values from previous tar archives
+ //unset($this->filename);
+ $this->filename="";
+ //unset($this->isGzipped);
+ $this->isGzipped=0;
+ //unset($this->tar_file);
+ $this->tar_file=0;
+ //unset($this->files);
+ $this->files="";
+ //unset($this->directories);
+ //unset($this->numFiles);
+ //unset($this->numDirectories);
+ $this->directories="";
+ $this->numFiles=0;
+ $this->numDirectories=0;
+ // If the tar file doesn't exist...
+ if(!file_exists($filename))
+ return false;
+ $this->filename = $filename;
+ // Parse this file
+ $this->__readTar();
+ return true;
+ }
+ // Appends a tar file to the end of the currently opened tar file
+ function appendTar($filename) {
+ // If the tar file doesn't exist...
+ if(!file_exists($filename))
+ return false;
+ $this->__readTar($filename);
+ return true;
+ }
+ // Retrieves information about a file in the current tar archive
+ function getFile($filename) {
+ if($this->numFiles > 0) {
+ foreach($this->files as $key => $information) {
+ if($information["name"] == $filename)
+ return $information;
+ }
+ }
+ return false;
+ }
+ // Retrieves information about a directory in the current tar archive
+ function getDirectory($dirname) {
+ if($this->numDirectories > 0) {
+ foreach($this->directories as $key => $information) {
+ if($information["name"] == $dirname)
+ return $information;
+ }
+ }
+ return false;
+ }
+ // Check if this tar archive contains a specific file
+ function containsFile($filename) {
+ if($this->numFiles > 0) {
+ foreach($this->files as $key => $information) {
+ if($information["name"] == $filename)
+ return true;
+ }
+ }
+ return false;
+ }
+ // Check if this tar archive contains a specific directory
+ function containsDirectory($dirname) {
+ if($this->numDirectories > 0) {
+ foreach($this->directories as $key => $information) {
+ if($information["name"] == $dirname)
+ return true;
+ }
+ }
+ return false;
+ }
+ // Add a directory to this tar archive
+ function addDirectory($dirname) {
+ if(!file_exists($dirname))
+ return false;
+ // Get directory information
+ $file_information = stat($dirname);
+ // Add directory to processed data
+ $this->numDirectories++;
+ $activeDir = &$this->directories[];
+ $activeDir["name"] = $dirname;
+ $activeDir["mode"] = $file_information["mode"];
+ $activeDir["time"] = $file_information["time"];
+ $activeDir["user_id"] = $file_information["uid"];
+ $activeDir["group_id"] = $file_information["gid"];
+ $activeDir["checksum"] = $checksum;
+ return true;
+ }
+ // Add a file to the tar archive
+ function addFile($filename) {
+ // Make sure the file we are adding exists!
+ if(!file_exists($filename))
+ return false;
+ // Make sure there are no other files in the archive that have this same filename
+ if($this->containsFile($filename))
+ return false;
+ // Get file information
+ $file_information = stat($filename);
+ // Read in the file's contents
+ $fp = fopen($filename,"rb");
+ $file_contents = fread($fp,filesize($filename));
+ fclose($fp);
+ // Add file to processed data
+ $this->numFiles++;
+ $activeFile = &$this->files[];
+ $activeFile["name"] = $filename;
+ $activeFile["mode"] = $file_information["mode"];
+ $activeFile["user_id"] = $file_information["uid"];
+ $activeFile["group_id"] = $file_information["gid"];
+ $activeFile["size"] = $file_information["size"];
+ $activeFile["time"] = $file_information["mtime"];
+ $activeFile["checksum"] = $checksum;
+ $activeFile["user_name"] = "";
+ $activeFile["group_name"] = "";
+ $activeFile["file"] = $file_contents;
+ return true;
+ }
+ // Add a file to the tar archive
+ function addData($filename,$data,$time=0) {
+ global $gBitSystem;
+ // Make sure there are no other files in the archive that have this same filename
+ if($this->containsFile($filename))
+ return false;
+ if (!$time) $time=$gBitSystem->getUTCTime();
+ // Read in the file's contents
+ $file_contents = $data;
+ // Add file to processed data
+ $this->numFiles++;
+ $activeFile = &$this->files[];
+ $activeFile["name"] = $filename;
+ $activeFile["mode"] = octdec("666");
+ $activeFile["user_id"] = "";
+ $activeFile["group_id"] = "";
+ $activeFile["size"] = strlen($data);
+ $activeFile["time"] = $time;
+ if(!isset($checksum)) $checksum=0;
+ $activeFile["checksum"] = $checksum;
+ $activeFile["user_name"] = "";
+ $activeFile["group_name"] = "";
+ $activeFile["file"] = $file_contents;
+ return true;
+ }
+ // Remove a file from the tar archive
+ function removeFile($filename) {
+ if($this->numFiles > 0) {
+ foreach($this->files as $key => $information) {
+ if($information["name"] == $filename) {
+ $this->numFiles--;
+ unset($this->files[$key]);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ // Remove a directory from the tar archive
+ function removeDirectory($dirname) {
+ if($this->numDirectories > 0) {
+ foreach($this->directories as $key => $information) {
+ if($information["name"] == $dirname) {
+ $this->numDirectories--;
+ unset($this->directories[$key]);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ // Write the currently loaded tar archive to disk
+ function saveTar() {
+ if(!$this->filename)
+ return false;
+ // Write tar to current file using specified gzip compression
+ $this->toTar($this->filename,$this->isGzipped);
+ return true;
+ }
+ // Saves tar archive to a different file than the current file
+ function toTar($filename,$useGzip) {
+ if(!$filename)
+ return false;
+ // Encode processed files into TAR file format
+ $this->__generateTar();
+ // GZ Compress the data if we need to
+ if($useGzip) {
+ // Make sure we have gzip support
+ if(!function_exists("gzencode"))
+ return false;
+ $file = gzencode($this->tar_file);
+ } else {
+ $file = $this->tar_file;
+ }
+ // Write the TAR file
+ $fp = fopen($filename,"wb");
+ fwrite($fp,$file);
+ fclose($fp);
+ return true;
+ }
+}
+?>
diff --git a/includes/zip_lib.php b/includes/zip_lib.php
new file mode 100755
index 0000000..a12de78
--- /dev/null
+++ b/includes/zip_lib.php
@@ -0,0 +1,805 @@
+<?php
+/**
+ * GZIP stuff.
+ *
+ * Note that we use gzopen()/gzwrite() instead of gzcompress() even if
+ * gzcompress() is available. Gzcompress() puts out data with
+ * different headers --- in particular it includes an "adler-32"
+ * checksum rather than a "CRC32" checksum. Since we need the CRC-32
+ * checksum, and since not all PHP's have gzcompress(), we'll just
+ * stick with gzopen().
+ */
+function gzip_cleanup() {
+ global $gzip_tmpfile;
+ if ($gzip_tmpfile)
+ @unlink ($gzip_tmpfile);
+}
+function gzip_tempnam() {
+ global $gzip_tmpfile;
+ if (!$gzip_tmpfile) {
+ //FIXME: does this work on non-unix machines?
+ $gzip_tmpfile = tempnam("/tmp", "wkzip");
+ register_shutdown_function ("gzip_cleanup");
+ }
+ return $gzip_tmpfile;
+}
+function gzip_compress($data) {
+ $filename = gzip_tempnam();
+ if (!($fp = gzopen($filename, "wb")))
+ trigger_error(sprintf("%s failed", "gzopen"), E_USER_ERROR);
+ gzwrite($fp, $data, strlen($data));
+ if (!gzclose($fp))
+ trigger_error(sprintf("%s failed", "gzclose"), E_USER_ERROR);
+ $size = filesize($filename);
+ if (!($fp = fopen($filename, "rb")))
+ trigger_error(sprintf("%s failed", "fopen"), E_USER_ERROR);
+ if (!($z = fread($fp, $size)) || strlen($z) != $size)
+ trigger_error(sprintf("%s failed", "fread"), E_USER_ERROR);
+ if (!fclose($fp))
+ trigger_error(sprintf("%s failed", "fclose"), E_USER_ERROR);
+ unlink ($filename);
+ return $z;
+}
+function gzip_uncompress($data) {
+ $filename = gzip_tempnam();
+ if (!($fp = fopen($filename, "wb")))
+ trigger_error(sprintf("%s failed", "fopen"), E_USER_ERROR);
+ fwrite($fp, $data, strlen($data));
+ if (!fclose($fp))
+ trigger_error(sprintf("%s failed", "fclose"), E_USER_ERROR);
+ if (!($fp = gzopen($filename, "rb")))
+ trigger_error(sprintf("%s failed", "gzopen"), E_USER_ERROR);
+ $unz = "";
+ while ($buf = gzread($fp, 4096))
+ $unz .= $buf;
+ if (!gzclose($fp))
+ trigger_error(sprintf("%s failed", "gzclose"), E_USER_ERROR);
+ unlink ($filename);
+ return $unz;
+}
+/**
+ * CRC32 computation. Hacked from Info-zip's zip-2.3 source code.
+ */
+function zip_crc32($str, $crc = 0) {
+ static $zip_crc_table;
+ if (empty($zip_crc_table)) {
+ /* NOTE: The range of PHP ints seems to be -0x80000000 to 0x7fffffff.
+ * So, had to munge these constants.
+ */
+ $zip_crc_table = [
+ 0x00000000,
+ 0x77073096,
+ -0x11f19ed4,
+ -0x66f6ae46,
+ 0x076dc419,
+ 0x706af48f,
+ -0x169c5acb,
+ -0x619b6a5d,
+ 0x0edb8832,
+ 0x79dcb8a4,
+ -0x1f2a16e2,
+ -0x682d2678,
+ 0x09b64c2b,
+ 0x7eb17cbd,
+ -0x1847d2f9,
+ -0x6f40e26f,
+ 0x1db71064,
+ 0x6ab020f2,
+ -0x0c468eb8,
+ -0x7b41be22,
+ 0x1adad47d,
+ 0x6ddde4eb,
+ -0x0b2b4aaf,
+ -0x7c2c7a39,
+ 0x136c9856,
+ 0x646ba8c0,
+ -0x029d0686,
+ -0x759a3614,
+ 0x14015c4f,
+ 0x63066cd9,
+ -0x05f0c29d,
+ -0x72f7f20b,
+ 0x3b6e20c8,
+ 0x4c69105e,
+ -0x2a9fbe1c,
+ -0x5d988e8e,
+ 0x3c03e4d1,
+ 0x4b04d447,
+ -0x2df27a03,
+ -0x5af54a95,
+ 0x35b5a8fa,
+ 0x42b2986c,
+ -0x2444362a,
+ -0x534306c0,
+ 0x32d86ce3,
+ 0x45df5c75,
+ -0x2329f231,
+ -0x542ec2a7,
+ 0x26d930ac,
+ 0x51de003a,
+ -0x3728ae80,
+ -0x402f9eea,
+ 0x21b4f4b5,
+ 0x56b3c423,
+ -0x30456a67,
+ -0x47425af1,
+ 0x2802b89e,
+ 0x5f058808,
+ -0x39f3264e,
+ -0x4ef416dc,
+ 0x2f6f7c87,
+ 0x58684c11,
+ -0x3e9ee255,
+ -0x4999d2c3,
+ 0x76dc4190,
+ 0x01db7106,
+ -0x672ddf44,
+ -0x102aefd6,
+ 0x71b18589,
+ 0x06b6b51f,
+ -0x60401b5b,
+ -0x17472bcd,
+ 0x7807c9a2,
+ 0x0f00f934,
+ -0x69f65772,
+ -0x1ef167e8,
+ 0x7f6a0dbb,
+ 0x086d3d2d,
+ -0x6e9b9369,
+ -0x199ca3ff,
+ 0x6b6b51f4,
+ 0x1c6c6162,
+ -0x7a9acf28,
+ -0x0d9dffb2,
+ 0x6c0695ed,
+ 0x1b01a57b,
+ -0x7df70b3f,
+ -0x0af03ba9,
+ 0x65b0d9c6,
+ 0x12b7e950,
+ -0x74414716,
+ -0x03467784,
+ 0x62dd1ddf,
+ 0x15da2d49,
+ -0x732c830d,
+ -0x042bb39b,
+ 0x4db26158,
+ 0x3ab551ce,
+ -0x5c43ff8c,
+ -0x2b44cf1e,
+ 0x4adfa541,
+ 0x3dd895d7,
+ -0x5b2e3b93,
+ -0x2c290b05,
+ 0x4369e96a,
+ 0x346ed9fc,
+ -0x529877ba,
+ -0x259f4730,
+ 0x44042d73,
+ 0x33031de5,
+ -0x55f5b3a1,
+ -0x22f28337,
+ 0x5005713c,
+ 0x270241aa,
+ -0x41f4eff0,
+ -0x36f3df7a,
+ 0x5768b525,
+ 0x206f85b3,
+ -0x46992bf7,
+ -0x319e1b61,
+ 0x5edef90e,
+ 0x29d9c998,
+ -0x4f2f67de,
+ -0x3828574c,
+ 0x59b33d17,
+ 0x2eb40d81,
+ -0x4842a3c5,
+ -0x3f459353,
+ -0x12477ce0,
+ -0x65404c4a,
+ 0x03b6e20c,
+ 0x74b1d29a,
+ -0x152ab8c7,
+ -0x622d8851,
+ 0x04db2615,
+ 0x73dc1683,
+ -0x1c9cf4ee,
+ -0x6b9bc47c,
+ 0x0d6d6a3e,
+ 0x7a6a5aa8,
+ -0x1bf130f5,
+ -0x6cf60063,
+ 0x0a00ae27,
+ 0x7d079eb1,
+ -0x0ff06cbc,
+ -0x78f75c2e,
+ 0x1e01f268,
+ 0x6906c2fe,
+ -0x089da8a3,
+ -0x7f9a9835,
+ 0x196c3671,
+ 0x6e6b06e7,
+ -0x012be48a,
+ -0x762cd420,
+ 0x10da7a5a,
+ 0x67dd4acc,
+ -0x06462091,
+ -0x71411007,
+ 0x17b7be43,
+ 0x60b08ed5,
+ -0x29295c18,
+ -0x5e2e6c82,
+ 0x38d8c2c4,
+ 0x4fdff252,
+ -0x2e44980f,
+ -0x5943a899,
+ 0x3fb506dd,
+ 0x48b2364b,
+ -0x27f2d426,
+ -0x50f5e4b4,
+ 0x36034af6,
+ 0x41047a60,
+ -0x209f103d,
+ -0x579820ab,
+ 0x316e8eef,
+ 0x4669be79,
+ -0x349e4c74,
+ -0x43997ce6,
+ 0x256fd2a0,
+ 0x5268e236,
+ -0x33f3886b,
+ -0x44f4b8fd,
+ 0x220216b9,
+ 0x5505262f,
+ -0x3a45c442,
+ -0x4d42f4d8,
+ 0x2bb45a92,
+ 0x5cb36a04,
+ -0x3d280059,
+ -0x4a2f30cf,
+ 0x2cd99e8b,
+ 0x5bdeae1d,
+ -0x649b3d50,
+ -0x139c0dda,
+ 0x756aa39c,
+ 0x026d930a,
+ -0x63f6f957,
+ -0x14f1c9c1,
+ 0x72076785,
+ 0x05005713,
+ -0x6a40b57e,
+ -0x1d4785ec,
+ 0x7bb12bae,
+ 0x0cb61b38,
+ -0x6d2d7165,
+ -0x1a2a41f3,
+ 0x7cdcefb7,
+ 0x0bdbdf21,
+ -0x792c2d2c,
+ -0x0e2b1dbe,
+ 0x68ddb3f8,
+ 0x1fda836e,
+ -0x7e41e933,
+ -0x0946d9a5,
+ 0x6fb077e1,
+ 0x18b74777,
+ -0x77f7a51a,
+ -0x00f09590,
+ 0x66063bca,
+ 0x11010b5c,
+ -0x709a6101,
+ -0x079d5197,
+ 0x616bffd3,
+ 0x166ccf45,
+ -0x5ff51d88,
+ -0x28f22d12,
+ 0x4e048354,
+ 0x3903b3c2,
+ -0x5898d99f,
+ -0x2f9fe909,
+ 0x4969474d,
+ 0x3e6e77db,
+ -0x512e95b6,
+ -0x2629a524,
+ 0x40df0b66,
+ 0x37d83bf0,
+ -0x564351ad,
+ -0x2144613b,
+ 0x47b2cf7f,
+ 0x30b5ffe9,
+ -0x42420de4,
+ -0x35453d76,
+ 0x53b39330,
+ 0x24b4a3a6,
+ -0x452fc9fb,
+ -0x3228f96d,
+ 0x54de5729,
+ 0x23d967bf,
+ -0x4c9985d2,
+ -0x3b9eb548,
+ 0x5d681b02,
+ 0x2a6f2b94,
+ -0x4bf441c9,
+ -0x3cf3715f,
+ 0x5a05df1b,
+ 0x2d02ef8d,
+ ];
+ }
+ $crc = ~$crc;
+ for ($i = 0; $i < strlen($str); $i++) {
+ $crc = ($zip_crc_table[($crc ^ ord($str[$i])) & 0xff] ^ (($crc >> 8) & 0xffffff));
+ }
+ return ~$crc;
+}
+define("GZIP_MAGIC", "\037\213");
+define("GZIP_DEFLATE", 010);
+function zip_deflate($content) {
+ // Compress content, and suck information from gzip header.
+ $z = gzip_compress($content);
+ // Suck OS type byte from gzip header. FIXME: this smells bad.
+ extract (unpack("a2magic/Ccomp_type/Cflags/@9/Cos_type", $z));
+ if ($magic != GZIP_MAGIC)
+ trigger_error(sprintf("Bad %s", "gzip magic"), E_USER_ERROR);
+ if ($comp_type != GZIP_DEFLATE)
+ trigger_error(sprintf("Bad %s", "gzip comp type"), E_USER_ERROR);
+ if (($flags & 0x3e) != 0)
+ trigger_error(sprintf("Bad %s", sprintf("flags (0x%02x)", $flags)), E_USER_ERROR);
+ $gz_header_len = 10;
+ $gz_data_len = strlen($z) - $gz_header_len - 8;
+ if ($gz_data_len < 0)
+ trigger_error("not enough gzip output?", E_USER_ERROR);
+ extract (unpack("Vcrc32", substr($z, $gz_header_len + $gz_data_len)));
+ return [
+ substr($z, $gz_header_len, $gz_data_len), // gzipped data
+ $crc32, // crc
+ $os_type, // OS type
+ ];
+}
+function zip_inflate($data, $crc32, $uncomp_size) {
+ if (!function_exists("gzopen")) {
+ global $request;
+ $request->finish(_("Can't inflate data: zlib support not enabled in this PHP"));
+ }
+ // Reconstruct gzip header and ungzip the data.
+ $mtime = time(); //(Bogus mtime)
+ return gzip_uncompress(pack("a2CxV@10", GZIP_MAGIC, GZIP_DEFLATE, $mtime). $data . pack("VV", $crc32, $uncomp_size));
+}
+function unixtime2dostime($unix_time) {
+ if ($unix_time % 1)
+ $unix_time++; // Round up to even seconds.
+ list($year, $month, $mday, $hour, $min, $sec) = explode(" ", date("Y n j G i s", $unix_time));
+ if ($year < 1980)
+ list($year, $month, $mday, $hour, $min, $sec) = [
+ 1980,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ ];
+ $dosdate = (($year - 1980) << 9) | ($month << 5) | $mday;
+ $dostime = ($hour << 11) | ($min << 5) | ($sec >> 1);
+ return [
+ $dosdate,
+ $dostime,
+ ];
+}
+function dostime2unixtime($dosdate, $dostime) {
+ $mday = $dosdate & 0x1f;
+ $month = ($dosdate >> 5) & 0x0f;
+ $year = 1980 + (($dosdate >> 9) & 0x7f);
+ $sec = ($dostime & 0x1f) * 2;
+ $min = ($dostime >> 5) & 0x3f;
+ $hour = ($dostime >> 11) & 0x1f;
+ return mktime($hour, $min, $sec, $month, $mday, $year);
+}
+/**
+ * Class for zipfile creation.
+ */
+define("ZIP_DEFLATE", GZIP_DEFLATE);
+define("ZIP_STORE", 0);
+define("ZIP_CENTHEAD_MAGIC", "PK\001\002");
+define("ZIP_LOCHEAD_MAGIC", "PK\003\004");
+define("ZIP_ENDDIR_MAGIC", "PK\005\006");
+class ZipWriter {
+ function ZipWriter($comment = "", $zipname = "archive.zip") {
+ $this->comment = $comment;
+ $this->nfiles = 0;
+ $this->dir = ""; // "Central directory block"
+ $this->offset = 0; // Current file position.
+ $zipname = addslashes($zipname);
+ header ("Content-Type: application/zip; name=\"$zipname\"");
+ header ("Content-Disposition: attachment; filename=\"$zipname\"");
+ //header( "Content-Disposition: inline; filename=$zipname" );
+ }
+ function addRegularFile($filename, $content, $attrib = false) {
+ if (!$attrib)
+ $attrib = [];
+ $size = strlen($content);
+ if (function_exists("gzopen")) {
+ list($data, $crc32, $os_type) = zip_deflate($content);
+ if (strlen($data) < $size) {
+ $content = $data; // Use compressed data.
+ $comp_type = ZIP_DEFLATE;
+ } else
+ unset ($crc32); // force plain store.
+ }
+ if (!isset($crc32)) {
+ $comp_type = ZIP_STORE;
+ $crc32 = zip_crc32($content);
+ }
+ if (!empty($attrib["write_protected"]))
+ $atx = (0100444 << 16) | 1; // S_IFREG + read permissions to
+ // everybody.
+ else
+ $atx = (0100644 << 16); // Add owner write perms.
+ $ati = $attrib["is_ascii"] ? 1 : 0;
+ if (empty($attrib["mtime"]))
+ $attrib["mtime"] = time();
+ list($mod_date, $mod_time) = unixtime2dostime($attrib["mtime"]);
+ // Construct parts common to "Local file header" and "Central
+ // directory file header."
+ if (!isset($attrib["extra_field"]))
+ $attrib["extra_field"] = "";
+ if (!isset($attrib["file_comment"]))
+ $attrib["file_comment"] = "";
+ $head = pack("vvvvvVVVvv", 20, // Version needed to extract (FIXME: is this right?)
+ 0, // Gen purp bit flag
+ $comp_type, $mod_time, $mod_date, $crc32, strlen($content), $size, strlen($filename), strlen($attrib["extra_field"]), );
+ // Construct the "Local file header"
+ $lheader = ZIP_LOCHEAD_MAGIC . $head . $filename . $attrib["extra_field"];
+ // Construct the "central directory file header"
+ $this->dir .= pack("a4CC", ZIP_CENTHEAD_MAGIC, 23, // Version made by (FIXME: is this right?)
+ $os_type, );
+ $this->dir .= $head;
+ $this->dir .= pack("vvvVV", strlen($attrib["file_comment"]), 0, // Disk number start
+ $ati, // Internal file attributes
+ $atx, // External file attributes
+ $this->offset, ); // Relative offset of local header
+ $this->dir .= $filename . $attrib["extra_field"] . $attrib["file_comment"];
+ // Output the "Local file header" and file contents.
+ echo $lheader;
+ echo $content;
+ $this->offset += strlen($lheader) + strlen($content);
+ $this->nfiles++;
+ }
+ function finish() {
+ // Output the central directory
+ echo $this->dir;
+ // Construct the "End of central directory record"
+ echo ZIP_ENDDIR_MAGIC;
+ echo pack("vvvvVVv", 0, // Number of this disk.
+ 0, // Number of disk with start of c dir
+ $this->nfiles, // Number entries on this disk
+ $this->nfiles, // Number entries
+ strlen($this->dir), // Size of central directory
+ $this->offset, // Offset of central directory
+ strlen($this->comment), );
+ echo $this->comment;
+ }
+}
+/**
+ * Class for reading zip files.
+ *
+ * BUGS:
+ *
+ * Many of the ExitWiki()'s should probably be warn()'s (eg. CRC mismatch).
+ *
+ * Only a subset of zip formats is recognized. (I think that
+ * unsupported formats will be recognized as such rather than silently
+ * munged.)
+ *
+ * We don't read the central directory. This means we don't see the
+ * file attributes (text? read-only?), or file comments.
+ *
+ * Right now we ignore the file mod date and time, since we don't need it.
+ */
+class ZipReader {
+ function ZipReader($zipfile) {
+ if (!is_string($zipfile))
+ $this->fp = $zipfile; // File already open
+ else if (!($this->fp = fopen($zipfile, "rb")))
+ trigger_error(sprintf(_("Can't open zip file '%s' for reading"), $zipfile), E_USER_ERROR);
+ }
+ function _read($nbytes) {
+ $chunk = fread($this->fp, $nbytes);
+ if (strlen($chunk) != $nbytes)
+ trigger_error(_("Unexpected EOF in zip file"), E_USER_ERROR);
+ return $chunk;
+ }
+ function done() {
+ fclose ($this->fp);
+ return false;
+ }
+ function readFile() {
+ $head = $this->_read(30);
+ extract (unpack("a4magic/vreq_version/vflags/vcomp_type" . "/vmod_time/vmod_date" . "/Vcrc32/Vcomp_size/Vuncomp_size" . "/vfilename_len/vextrafld_len", $head));
+ //FIXME: we should probably check $req_version.
+ $attrib["mtime"] = dostime2unixtime($mod_date, $mod_time);
+ if ($magic != ZIP_LOCHEAD_MAGIC) {
+ if ($magic != ZIP_CENTHEAD_MAGIC)
+ // FIXME: better message?
+ ExitWiki (sprintf("Bad header type: %s", $magic));
+ return $this->done();
+ }
+ if (($flags & 0x21) != 0)
+ ExitWiki ("Encryption and/or zip patches not supported.");
+ if (($flags & 0x08) != 0)
+ // FIXME: better message?
+ ExitWiki ("Postponed CRC not yet supported.");
+ $filename = $this->_read($filename_len);
+ if ($extrafld_len != 0)
+ $attrib["extra_field"] = $this->_read($extrafld_len);
+ $data = $this->_read($comp_size);
+ if ($comp_type == ZIP_DEFLATE) {
+ $data = zip_inflate($data, $crc32, $uncomp_size);
+ } else if ($comp_type == ZIP_STORE) {
+ $crc = zip_crc32($data);
+ if ($crc32 != $crc)
+ ExitWiki (sprintf("CRC mismatch %x != %x", $crc, $crc32));
+ } else
+ ExitWiki (sprintf("Compression method %s unsupported", $comp_method));
+ if (strlen($data) != $uncomp_size)
+ ExitWiki (sprintf("Uncompressed size mismatch %d != %d", strlen($data), $uncomp_size));
+ return [
+ $filename,
+ $data,
+ $attrib,
+ ];
+ }
+}
+/**
+ * Routines for Mime mailification of pages.
+ */
+//FIXME: these should go elsewhere (libmime?).
+/**
+ * Routines for quoted-printable en/decoding.
+ */
+function QuotedPrintableEncode($string) {
+ // Quote special characters in line.
+ $quoted = "";
+ while ($string) {
+ // The complicated regexp is to force quoting of trailing spaces.
+ preg_match("/^([ !-<>-~]*)(?:([!-<>-~]$)|(.))/s", $string, $match);
+ $quoted .= $match[1] . $match[2];
+ if (!empty($match[3]))
+ $quoted .= sprintf("=%02X", ord($match[3]));
+ $string = substr($string, strlen($match[0]));
+ }
+ // Split line.
+ // This splits the line (preferably after white-space) into lines
+ // which are no longer than 76 chars (after adding trailing '=' for
+ // soft line break, but before adding \r\n.)
+ return preg_replace('/(?=.{77})(.{10,74}[ \t]|.{71,73}[^=][^=])/s', "\\1=\r\n", $quoted);
+}
+function QuotedPrintableDecode($string) {
+ // Eliminate soft line-breaks.
+ $string = preg_replace('/=[ \t\r]*\n/', "", $string);
+ return quoted_printable_decode($string);
+}
+define("MIME_TOKEN_REGEXP", "[-!#-'*+.0-9A-Z^-~]+");
+function MimeContentTypeHeader($type, $subtype, $params) {
+ $header = "Content-Type: $type/$subtype";
+ reset ($params);
+ while (list($key, $val) = each($params)) {
+ //FIXME: what about non-ascii printables in $val?
+ if (!preg_match("/^" . MIME_TOKEN_REGEXP . "$/", $val))
+ $val = '"' . addslashes($val). '"';
+ $header .= ";\r\n $key=$val";
+ }
+ return "$header\r\n";
+}
+function MimeMultipart($parts) {
+ global $mime_multipart_count;
+ // The string "=_" can not occur in quoted-printable encoded data.
+ $boundary = "=_multipart_boundary_" . ++$mime_multipart_count;
+ $head = MimeContentTypeHeader("multipart", "mixed", ["boundary" => $boundary]);
+ $sep = "\r\n--$boundary\r\n";
+ return $head . $sep . implode($sep, $parts). "\r\n--${boundary}--\r\n";
+}
+/**
+ * For reference see:
+ * http://www.nacs.uci.edu/indiv/ehood/MIME/2045/rfc2045.html
+ * http://www.faqs.org/rfcs/rfc2045.html
+ * (RFC 1521 has been superceeded by RFC 2045 & others).
+ *
+ * Also see http://www.faqs.org/rfcs/rfc2822.html
+ *
+ *
+ * Notes on content-transfer-encoding.
+ *
+ * "7bit" means short lines of US-ASCII.
+ * "8bit" means short lines of octets with (possibly) the high-order bit set.
+ * "binary" means lines are not necessarily short enough for SMTP
+ * transport, and non-ASCII characters may be present.
+ *
+ * Only "7bit", "quoted-printable", and "base64" are universally safe
+ * for transport via e-mail. (Though many MTAs can/will be configured to
+ * automatically convert encodings to a safe type if they receive
+ * mail encoded in '8bit' and/or 'binary' encodings.
+ */
+function MimeifyPageRevision($page) {
+ //$page = $revision->getPage();
+ // FIXME: add 'hits' to $params
+ $params = [
+ "title" => $page["title"],
+ "flags" => "",
+ "author" => !empty( $page["creator_user"] ) ? $page["creator_user"] : NULL,
+ "version" => $page["version"],
+ "lastmodified" => $page["last_modified"],
+ ];
+ $params["author_id"] = $page["ip"];
+ $params["summary"] = $page["comment"];
+ if (isset($page["hits"]))
+ $params["hits"] = $page["hits"];
+ $params["description"] = $page["description"];
+ $params["charset"] = "iso-8859-1";
+ // Non-US-ASCII is not allowed in Mime headers (at least not without
+ // special handling) --- so we urlencode all parameter values.
+ foreach ($params as $key => $val)
+ $params[$key] = rawurlencode($val);
+ $out = MimeContentTypeHeader("application", "x-tikiwiki", $params);
+ $out .= sprintf("Content-Transfer-Encoding: %s\r\n", "binary");
+ $out .= "\r\n";
+ $lines = split("\n", $page["data"]);
+ foreach ($lines as $line) {
+ // This is a dirty hack to allow saving binary text files. See above.
+ $line = rtrim($line);
+ $out .= "$line\r\n";
+ }
+ return $out;
+}
+/**
+ * Routines for parsing Mime-ified phpwiki pages.
+ */
+function ParseRFC822Headers(&$string) {
+ if (preg_match("/^From (.*)\r?\n/", $string, $match)) {
+ $headers["from "] = preg_replace('/^\s+|\s+$/', "", $match[1]);
+ $string = substr($string, strlen($match[0]));
+ }
+ while (preg_match('/^([!-9;-~]+) [ \t]* : [ \t]* ' . '( .* \r?\n (?: [ \t] .* \r?\n)* )/x', $string, $match)) {
+ $headers[strtolower($match[1])] = preg_replace('/^\s+|\s+$/', "", $match[2]);
+ $string = substr($string, strlen($match[0]));
+ }
+ if (empty($headers))
+ return false;
+ if (!preg_match("/^\r?\n/", $string, $match)) {
+ // No blank line after headers.
+ return false;
+ }
+ $string = substr($string, strlen($match[0]));
+ return $headers;
+}
+function ParseMimeContentType($string) {
+ // FIXME: Remove (RFC822 style comments).
+ // Get type/subtype
+ if (!preg_match(':^\s*(' . MIME_TOKEN_REGEXP . ')\s*' . "/" . '\s*(' . MIME_TOKEN_REGEXP . ')\s*:x', $string, $match))
+ ExitWiki (sprintf("Bad %s", "MIME content-type"));
+ $type = strtolower($match[1]);
+ $subtype = strtolower($match[2]);
+ $string = substr($string, strlen($match[0]));
+ $param = [];
+ while (preg_match('/^;\s*(' . MIME_TOKEN_REGEXP . ')\s*=\s*' . "(?:(" . MIME_TOKEN_REGEXP . ')|"((?:[^"\\\\]|\\.)*)") \s*/sx', $string, $match)) {
+ //" <--kludge for brain-dead syntax coloring
+ if (strlen($match[2]))
+ $val = $match[2];
+ else
+ $val = preg_replace('/[\\\\](.)/s', '\\1', $match[3]);
+ $param[strtolower($match[1])] = $val;
+ $string = substr($string, strlen($match[0]));
+ }
+ return [
+ $type,
+ $subtype,
+ $param,
+ ];
+}
+function ParseMimeMultipart($data, $boundary) {
+ if (!$boundary)
+ ExitWiki ("No boundary?");
+ $boundary = preg_quote($boundary);
+ while (preg_match("/^(|.*?\n)--$boundary((?:--)?)[^\n]*\n/s", $data, $match)) {
+ $data = substr($data, strlen($match[0]));
+ if (!isset($parts))
+ $parts = []; // First time through: discard leading chaff
+ else {
+ if ($content = ParseMimeifiedPages($match[1]))
+ for (reset($content); $p = current($content); next($content))
+ $parts[] = $p;
+ }
+ if ($match[2])
+ return $parts; // End boundary found.
+ }
+ ExitWiki ("No end boundary?");
+}
+function GenerateFootnotesFromRefs($params) {
+ $footnotes = [];
+ reset ($params);
+ while (list($p, $reference) = each($params)) {
+ if (preg_match("/^ref([1-9][0-9]*)$/", $p, $m))
+ $footnotes[$m[1]] = sprintf(_("[%d] See [%s]"), $m[1], rawurldecode($reference));
+ }
+ if (sizeof($footnotes) > 0) {
+ ksort ($footnotes);
+ return "-----\n" . "!" . _("References"). "\n" . join("\n%%%\n", $footnotes). "\n";
+ }
+ return "";
+}
+// Convert references in meta-data to footnotes.
+// Only zip archives generated by phpwiki 1.2.x or earlier should have
+// references.
+function ParseMimeifiedPages($data) {
+ if (!($headers = ParseRFC822Headers($data)) || empty($headers["content-type"])) {
+ //trigger_error( sprintf(_("Can't find %s"),'content-type header'),
+ // E_USER_WARNING );
+ return false;
+ }
+ $typeheader = $headers["content-type"];
+ if (!(list($type, $subtype, $params) = ParseMimeContentType($typeheader))) {
+ trigger_error(sprintf("Can't parse %s: (%s)", "content-type", $typeheader), E_USER_WARNING);
+ return false;
+ }
+ if ("$type/$subtype" == "multipart/mixed") {
+ return ParseMimeMultipart($data, $params["boundary"]);
+ } else if ("$type/$subtype" != "application/x-phpwiki") {
+ trigger_error(sprintf("Bad %s", "content-type: $type/$subtype"), E_USER_WARNING);
+ return false;
+ }
+ // FIXME: more sanity checking?
+ $page = [];
+ $pagedata = [];
+ $versiondata = [];
+ foreach ($params as $key => $value) {
+ if (empty($value))
+ continue;
+ $value = rawurldecode($value);
+ switch ($key) {
+ case "pagename":
+ case "version":
+ $page[$key] = $value;
+ break;
+ case "flags":
+ if (preg_match("/PAGE_LOCKED/", $value))
+ $pagedata["locked"] = "yes";
+ break;
+ case "created":
+ case "hits":
+ $pagedata[$key] = $value;
+ break;
+ case "lastmodified":
+ $versiondata["mtime"] = $value;
+ break;
+ case "author":
+ case "author_id":
+ case "summary":
+ case "markup":
+ $versiondata[$key] = $value;
+ break;
+ }
+ }
+ // FIXME: do we need to try harder to find a pagename if we
+ // haven't got one yet?
+ if (!isset($versiondata["author"])) {
+ global $request;
+ $user = $request->getUser();
+ $versiondata["author"] = $user->getId(); //FIXME:?
+ }
+ $encoding = strtolower($headers["content-transfer-encoding"]);
+ if ($encoding == "quoted-printable")
+ $data = QuotedPrintableDecode($data);
+ else if ($encoding && $encoding != "binary")
+ ExitWiki (sprintf("Unknown %s", "encoding type: $encoding"));
+ $data .= GenerateFootnotesFromRefs($params);
+ $page["content"] = preg_replace('/[ \t\r]*\n/', "\n", chop($data));
+ $page["pagedata"] = $pagedata;
+ $page["versiondata"] = $versiondata;
+ return [$page];
+}
+// Local Variables:
+// mode: php
+// tab-width: 8
+// c-basic-offset: 4
+// c-hanging-comment-ender-p: nil
+// indent-tabs-mode: nil
+// End:
+?>