--- /dev/null
+
+.editbox {
+ border-width: 0;
+ margin: .0em;
+ padding: 0;
+ font-family: monospace;
+ font-size: 12px;
+ color: black;
+ background-color: #fff;
+}
+
+.editbox p {
+ margin: 0;
+}
+
+
+/* Syntax highlighting */
+
+span.part {
+ color: #666;
+}
+
+span.other {
+ color: black;
+}
+
+span.reserved, .t3e_autoCompleteBox ul li span.word_reserved {
+ color: #770088;
+}
+
+span.keyword, .t3e_autoCompleteBox ul li span.word_keyword {
+ color: #0000cc;
+ font-weight: bold;
+ font-size: 0.95em;
+}
+
+span.keyword2, .t3e_autoCompleteBox ul li span.word_keyword2 {
+ color: #0000cc;
+}
+
+span.keyword3, .t3e_autoCompleteBox ul li span.word_keyword3 {
+ color: #0000ff;
+}
+
+
+span.prop {
+ color: #00f;
+}
+
+span.operator {
+ color: #f00;
+}
+span.punctuation {
+ color: #c00;
+}
+
+span.atom {
+ color: #448888;
+}
+
+span.variable {
+ color: black;
+}
+
+/*
+span.variabledef {
+ color: #0000FF;
+}
+
+span.localvariable {
+ color: #004499;
+}
+
+span.property {
+ color: black;
+}
+*/
+
+span.comment {
+ color: #AA7700;
+}
+
+span.string {
+ color: #AA2222;
+}
+
+/* unparsed code */
+pre.code, .editbox {
+ color: #666;
+}
+
+
+/* around the editor */
+.t3e_outerdiv {
+ border: 1px solid gray;
+ position: relative;
+ background-color: #EFEFF4;
+ background-image: url('../icons/loader_eeeeee.gif');
+ background-position: 49% 50%;
+ background-repeat: no-repeat;
+}
+.t3e_modalOverlay {
+ position: absolute;
+ top: 0; left: 0;
+ background-color: #EFEFF4;
+ background-image: url('../icons/loader_eeeeee.gif');
+ background-position: 49% 50%;
+ background-repeat: no-repeat;
+ z-index:200;
+ width: 100%;
+ height: 100%;
+}
+.t3e_autoCompleteBox {
+ position: absolute;
+ top: 0; left: 0;
+ background-color: #EFEFF4;
+ z-index:190;
+ border:2px solid silver;
+ padding:0px;
+}
+.t3e_autoCompleteBox ul{
+ list-style-type: none;
+ padding:0px;
+ margin:0px;
+
+}
+.t3e_autoCompleteBox ul li{
+ padding-left:2px;
+ padding-right:2px;
+ font-weight:bold;
+ cursor: pointer; cursor: hand;
+}
+.t3e_autoCompleteBox ul li.active{
+ padding-left:2px;
+ padding-right:2px;
+ font-weight:bold;
+ background-color: #cfcfcf;
+}
+.t3e_fullscreen {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+.t3e_linenum_wrap {
+ width: 4em;
+ position: absolute; top: 0pt; left: 0pt;
+ overflow: hidden;
+}
+.t3e_linenum {
+ font-size: 12px;
+ font-family: monospace;
+ padding: 0 3px 0 0;
+ margin: 0;
+ background-color: #EFEFF4;
+ color: #000;
+ width: 3em;
+ float: left;
+ text-align: right;
+ list-style-type: none;
+}
+
+.t3e_linenum li {
+ padding: 0 3px 0 0;
+ margin: 0;
+}
+
+.t3e_iframe_wrap {
+ margin: 0 0 0 4em;
+}
+
+.t3e_iframe {
+ display: block;
+ /* width: 100%; */
+ padding: 0;
+}
+
+.t3e_footer_wrap {
+ clear: both;
+ width: 100%;
+ font-size: 0.9em;
+ padding-right: 20px;
+}
+
+.t3e_footer_item {
+ float: right;
+ height: 16px;
+ border-left: 1px solid gray;
+ padding: 4px 14px 0 14px;
+}
+
+
+.t3e_clickable {
+ cursor:pointer;cursor:hand;
+}
+
+
+.t3e_footer_overlay {
+ position: absolute; bottom: 20px; right: 17px;
+ opacity: 0.85;
+ background-color: #EFEFF4;
+ width: 180px;
+ height: 70%;
+ padding: 5px 0px 10px 0px;
+ border-left: 1px solid gray;
+ border-right: 1px solid gray;
+ border-top: 1px solid gray;
+ z-index: 100;
+}
+.t3e_footer_overlay#t3e_footer_overlay_options {
+ height: 8em;
+}
+.t3e_footer_overlay ul {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+}
+.t3e_footer_overlay ul li {
+ color: #212121;
+ padding: 2px 6px 2px 6px;
+ cursor:pointer;cursor:hand;
+}
+.t3e_footer_overlay ul li label {
+ cursor:pointer;cursor:hand;
+ }
+.t3e_footer_overlay ul li:hover {
+ background-color: #cfcfcf;
+}
+
+#t3e_modalOverlay_help {
+ background-image: none;
+ width: 90%;
+ height: 80%;
+ top: 10%;
+ left: 5%;
+ padding: 10px;
+ border: 1px solid gray;
+}
+
+.t3e_footeritem_active {
+ background-color: #cfcfcf;
+}
\ No newline at end of file
--- /dev/null
+
+Licence of t3editor
+===================
+
+/***************************************************************
+* Copyright notice
+*
+* (c) 2007 Tobias Liebig <mail_typo3@etobi.de>
+* All rights reserved
+*
+* This script is part of the TYPO3 project. The TYPO3 project is
+* free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* The GNU General Public License can be found at
+* http://www.gnu.org/copyleft/gpl.html.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* This script is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+t3editor is written by Tobias Liebig.
+
+Many thanks for help on the conceptual work, testing, feedback and providing several patches
+to Vitaly Dutchak, Thomas Hempel and all the other people.
+
+t3editor is based on Codemirror by Marijn Haverbeke http://marijn.haverbeke.de/codemirror/
+Thanks Marjin!
+Codemirror uses MochiKit. See http://mochikit.com/ for licence.
+
+
+This is the original licence:
+
+/***************************************************************
+ Copyright (c) 2007 Marijn Haverbeke
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+ Marijn Haverbeke
+ marijnh at gmail
+***************************************************************/
+
--- /dev/null
+/***
+
+ MochiKit.MochiKit 1.4 : PACKED VERSION
+
+ THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
+ diff against the source tree, not this file.
+
+ See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+ (c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Base");
+}
+if(typeof (MochiKit)=="undefined"){
+MochiKit={};
+}
+if(typeof (MochiKit.Base)=="undefined"){
+MochiKit.Base={};
+}
+if(typeof (MochiKit.__export__)=="undefined"){
+MochiKit.__export__=(MochiKit.__compat__||(typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined"));
+}
+MochiKit.Base.VERSION="1.4";
+MochiKit.Base.NAME="MochiKit.Base";
+MochiKit.Base.update=function(_1,_2){
+if(_1===null){
+_1={};
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+if(typeof (o)!="undefined"&&o!==null){
+for(var k in o){
+_1[k]=o[k];
+}
+}
+}
+return _1;
+};
+MochiKit.Base.update(MochiKit.Base,{__repr__:function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+},toString:function(){
+return this.__repr__();
+},camelize:function(_6){
+var _7=_6.split("-");
+var cc=_7[0];
+for(var i=1;i<_7.length;i++){
+cc+=_7[i].charAt(0).toUpperCase()+_7[i].substring(1);
+}
+return cc;
+},counter:function(n){
+if(arguments.length===0){
+n=1;
+}
+return function(){
+return n++;
+};
+},clone:function(_b){
+var me=arguments.callee;
+if(arguments.length==1){
+me.prototype=_b;
+return new me();
+}
+},_flattenArray:function(_d,_e){
+for(var i=0;i<_e.length;i++){
+var o=_e[i];
+if(o instanceof Array){
+arguments.callee(_d,o);
+}else{
+_d.push(o);
+}
+}
+return _d;
+},flattenArray:function(lst){
+return MochiKit.Base._flattenArray([],lst);
+},flattenArguments:function(lst){
+var res=[];
+var m=MochiKit.Base;
+var _15=m.extend(null,arguments);
+while(_15.length){
+var o=_15.shift();
+if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
+for(var i=o.length-1;i>=0;i--){
+_15.unshift(o[i]);
+}
+}else{
+res.push(o);
+}
+}
+return res;
+},extend:function(_18,obj,_1a){
+if(!_1a){
+_1a=0;
+}
+if(obj){
+var l=obj.length;
+if(typeof (l)!="number"){
+if(typeof (MochiKit.Iter)!="undefined"){
+obj=MochiKit.Iter.list(obj);
+l=obj.length;
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+if(!_18){
+_18=[];
+}
+for(var i=_1a;i<l;i++){
+_18.push(obj[i]);
+}
+}
+return _18;
+},updatetree:function(_1d,obj){
+if(_1d===null){
+_1d={};
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+if(typeof (o)!="undefined"&&o!==null){
+for(var k in o){
+var v=o[k];
+if(typeof (_1d[k])=="object"&&typeof (v)=="object"){
+arguments.callee(_1d[k],v);
+}else{
+_1d[k]=v;
+}
+}
+}
+}
+return _1d;
+},setdefault:function(_23,obj){
+if(_23===null){
+_23={};
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+for(var k in o){
+if(!(k in _23)){
+_23[k]=o[k];
+}
+}
+}
+return _23;
+},keys:function(obj){
+var _29=[];
+for(var _2a in obj){
+_29.push(_2a);
+}
+return _29;
+},values:function(obj){
+var _2c=[];
+for(var _2d in obj){
+_2c.push(obj[_2d]);
+}
+return _2c;
+},items:function(obj){
+var _2f=[];
+var e;
+for(var _31 in obj){
+var v;
+try{
+v=obj[_31];
+}
+catch(e){
+continue;
+}
+_2f.push([_31,v]);
+}
+return _2f;
+},_newNamedError:function(_33,_34,_35){
+_35.prototype=new MochiKit.Base.NamedError(_33.NAME+"."+_34);
+_33[_34]=_35;
+},operator:{truth:function(a){
+return !!a;
+},lognot:function(a){
+return !a;
+},identity:function(a){
+return a;
+},not:function(a){
+return ~a;
+},neg:function(a){
+return -a;
+},add:function(a,b){
+return a+b;
+},sub:function(a,b){
+return a-b;
+},div:function(a,b){
+return a/b;
+},mod:function(a,b){
+return a%b;
+},mul:function(a,b){
+return a*b;
+},and:function(a,b){
+return a&b;
+},or:function(a,b){
+return a|b;
+},xor:function(a,b){
+return a^b;
+},lshift:function(a,b){
+return a<<b;
+},rshift:function(a,b){
+return a>>b;
+},zrshift:function(a,b){
+return a>>>b;
+},eq:function(a,b){
+return a==b;
+},ne:function(a,b){
+return a!=b;
+},gt:function(a,b){
+return a>b;
+},ge:function(a,b){
+return a>=b;
+},lt:function(a,b){
+return a<b;
+},le:function(a,b){
+return a<=b;
+},seq:function(a,b){
+return a===b;
+},sne:function(a,b){
+return a!==b;
+},ceq:function(a,b){
+return MochiKit.Base.compare(a,b)===0;
+},cne:function(a,b){
+return MochiKit.Base.compare(a,b)!==0;
+},cgt:function(a,b){
+return MochiKit.Base.compare(a,b)==1;
+},cge:function(a,b){
+return MochiKit.Base.compare(a,b)!=-1;
+},clt:function(a,b){
+return MochiKit.Base.compare(a,b)==-1;
+},cle:function(a,b){
+return MochiKit.Base.compare(a,b)!=1;
+},logand:function(a,b){
+return a&&b;
+},logor:function(a,b){
+return a||b;
+},contains:function(a,b){
+return b in a;
+}},forwardCall:function(_73){
+return function(){
+return this[_73].apply(this,arguments);
+};
+},itemgetter:function(_74){
+return function(arg){
+return arg[_74];
+};
+},typeMatcher:function(){
+var _76={};
+for(var i=0;i<arguments.length;i++){
+var typ=arguments[i];
+_76[typ]=typ;
+}
+return function(){
+for(var i=0;i<arguments.length;i++){
+if(!(typeof (arguments[i]) in _76)){
+return false;
+}
+}
+return true;
+};
+},isNull:function(){
+for(var i=0;i<arguments.length;i++){
+if(arguments[i]!==null){
+return false;
+}
+}
+return true;
+},isUndefinedOrNull:function(){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+if(!(typeof (o)=="undefined"||o===null)){
+return false;
+}
+}
+return true;
+},isEmpty:function(obj){
+return !MochiKit.Base.isNotEmpty.apply(this,arguments);
+},isNotEmpty:function(obj){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+if(!(o&&o.length)){
+return false;
+}
+}
+return true;
+},isArrayLike:function(){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+var typ=typeof (o);
+if((typ!="object"&&!(typ=="function"&&typeof (o.item)=="function"))||o===null||typeof (o.length)!="number"||o.nodeType===3){
+return false;
+}
+}
+return true;
+},isDateLike:function(){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+if(typeof (o)!="object"||o===null||typeof (o.getTime)!="function"){
+return false;
+}
+}
+return true;
+},xmap:function(fn){
+if(fn===null){
+return MochiKit.Base.extend(null,arguments,1);
+}
+var _87=[];
+for(var i=1;i<arguments.length;i++){
+_87.push(fn(arguments[i]));
+}
+return _87;
+},map:function(fn,lst){
+var m=MochiKit.Base;
+var itr=MochiKit.Iter;
+var _8d=m.isArrayLike;
+if(arguments.length<=2){
+if(!_8d(lst)){
+if(itr){
+lst=itr.list(lst);
+if(fn===null){
+return lst;
+}
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+if(fn===null){
+return m.extend(null,lst);
+}
+var _8e=[];
+for(var i=0;i<lst.length;i++){
+_8e.push(fn(lst[i]));
+}
+return _8e;
+}else{
+if(fn===null){
+fn=Array;
+}
+var _90=null;
+for(i=1;i<arguments.length;i++){
+if(!_8d(arguments[i])){
+if(itr){
+return itr.list(itr.imap.apply(null,arguments));
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+var l=arguments[i].length;
+if(_90===null||_90>l){
+_90=l;
+}
+}
+_8e=[];
+for(i=0;i<_90;i++){
+var _92=[];
+for(var j=1;j<arguments.length;j++){
+_92.push(arguments[j][i]);
+}
+_8e.push(fn.apply(this,_92));
+}
+return _8e;
+}
+},xfilter:function(fn){
+var _95=[];
+if(fn===null){
+fn=MochiKit.Base.operator.truth;
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+if(fn(o)){
+_95.push(o);
+}
+}
+return _95;
+},filter:function(fn,lst,_9a){
+var _9b=[];
+var m=MochiKit.Base;
+if(!m.isArrayLike(lst)){
+if(MochiKit.Iter){
+lst=MochiKit.Iter.list(lst);
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+if(fn===null){
+fn=m.operator.truth;
+}
+if(typeof (Array.prototype.filter)=="function"){
+return Array.prototype.filter.call(lst,fn,_9a);
+}else{
+if(typeof (_9a)=="undefined"||_9a===null){
+for(var i=0;i<lst.length;i++){
+var o=lst[i];
+if(fn(o)){
+_9b.push(o);
+}
+}
+}else{
+for(i=0;i<lst.length;i++){
+o=lst[i];
+if(fn.call(_9a,o)){
+_9b.push(o);
+}
+}
+}
+}
+return _9b;
+},_wrapDumbFunction:function(_9f){
+return function(){
+switch(arguments.length){
+case 0:
+return _9f();
+case 1:
+return _9f(arguments[0]);
+case 2:
+return _9f(arguments[0],arguments[1]);
+case 3:
+return _9f(arguments[0],arguments[1],arguments[2]);
+}
+var _a0=[];
+for(var i=0;i<arguments.length;i++){
+_a0.push("arguments["+i+"]");
+}
+return eval("(func("+_a0.join(",")+"))");
+};
+},methodcaller:function(_a2){
+var _a3=MochiKit.Base.extend(null,arguments,1);
+if(typeof (_a2)=="function"){
+return function(obj){
+return _a2.apply(obj,_a3);
+};
+}else{
+return function(obj){
+return obj[_a2].apply(obj,_a3);
+};
+}
+},method:function(_a6,_a7){
+var m=MochiKit.Base;
+return m.bind.apply(this,m.extend([_a7,_a6],arguments,2));
+},compose:function(f1,f2){
+var _ab=[];
+var m=MochiKit.Base;
+if(arguments.length===0){
+throw new TypeError("compose() requires at least one argument");
+}
+for(var i=0;i<arguments.length;i++){
+var fn=arguments[i];
+if(typeof (fn)!="function"){
+throw new TypeError(m.repr(fn)+" is not a function");
+}
+_ab.push(fn);
+}
+return function(){
+var _af=arguments;
+for(var i=_ab.length-1;i>=0;i--){
+_af=[_ab[i].apply(this,_af)];
+}
+return _af[0];
+};
+},bind:function(_b1,_b2){
+if(typeof (_b1)=="string"){
+_b1=_b2[_b1];
+}
+var _b3=_b1.im_func;
+var _b4=_b1.im_preargs;
+var _b5=_b1.im_self;
+var m=MochiKit.Base;
+if(typeof (_b1)=="function"&&typeof (_b1.apply)=="undefined"){
+_b1=m._wrapDumbFunction(_b1);
+}
+if(typeof (_b3)!="function"){
+_b3=_b1;
+}
+if(typeof (_b2)!="undefined"){
+_b5=_b2;
+}
+if(typeof (_b4)=="undefined"){
+_b4=[];
+}else{
+_b4=_b4.slice();
+}
+m.extend(_b4,arguments,2);
+var _b7=function(){
+var _b8=arguments;
+var me=arguments.callee;
+if(me.im_preargs.length>0){
+_b8=m.concat(me.im_preargs,_b8);
+}
+var _ba=me.im_self;
+if(!_ba){
+_ba=this;
+}
+return me.im_func.apply(_ba,_b8);
+};
+_b7.im_self=_b5;
+_b7.im_func=_b3;
+_b7.im_preargs=_b4;
+return _b7;
+},bindMethods:function(_bb){
+var _bc=MochiKit.Base.bind;
+for(var k in _bb){
+var _be=_bb[k];
+if(typeof (_be)=="function"){
+_bb[k]=_bc(_be,_bb);
+}
+}
+},registerComparator:function(_bf,_c0,_c1,_c2){
+MochiKit.Base.comparatorRegistry.register(_bf,_c0,_c1,_c2);
+},_primitives:{"boolean":true,"string":true,"number":true},compare:function(a,b){
+if(a==b){
+return 0;
+}
+var _c5=(typeof (a)=="undefined"||a===null);
+var _c6=(typeof (b)=="undefined"||b===null);
+if(_c5&&_c6){
+return 0;
+}else{
+if(_c5){
+return -1;
+}else{
+if(_c6){
+return 1;
+}
+}
+}
+var m=MochiKit.Base;
+var _c8=m._primitives;
+if(!(typeof (a) in _c8&&typeof (b) in _c8)){
+try{
+return m.comparatorRegistry.match(a,b);
+}
+catch(e){
+if(e!=m.NotFound){
+throw e;
+}
+}
+}
+if(a<b){
+return -1;
+}else{
+if(a>b){
+return 1;
+}
+}
+var _c9=m.repr;
+throw new TypeError(_c9(a)+" and "+_c9(b)+" can not be compared");
+},compareDateLike:function(a,b){
+return MochiKit.Base.compare(a.getTime(),b.getTime());
+},compareArrayLike:function(a,b){
+var _ce=MochiKit.Base.compare;
+var _cf=a.length;
+var _d0=0;
+if(_cf>b.length){
+_d0=1;
+_cf=b.length;
+}else{
+if(_cf<b.length){
+_d0=-1;
+}
+}
+for(var i=0;i<_cf;i++){
+var cmp=_ce(a[i],b[i]);
+if(cmp){
+return cmp;
+}
+}
+return _d0;
+},registerRepr:function(_d3,_d4,_d5,_d6){
+MochiKit.Base.reprRegistry.register(_d3,_d4,_d5,_d6);
+},repr:function(o){
+if(typeof (o)=="undefined"){
+return "undefined";
+}else{
+if(o===null){
+return "null";
+}
+}
+try{
+if(typeof (o.__repr__)=="function"){
+return o.__repr__();
+}else{
+if(typeof (o.repr)=="function"&&o.repr!=arguments.callee){
+return o.repr();
+}
+}
+return MochiKit.Base.reprRegistry.match(o);
+}
+catch(e){
+if(typeof (o.NAME)=="string"&&(o.toString==Function.prototype.toString||o.toString==Object.prototype.toString)){
+return o.NAME;
+}
+}
+try{
+var _d8=(o+"");
+}
+catch(e){
+return "["+typeof (o)+"]";
+}
+if(typeof (o)=="function"){
+o=_d8.replace(/^\s+/,"");
+var idx=o.indexOf("{");
+if(idx!=-1){
+o=o.substr(0,idx)+"{...}";
+}
+}
+return _d8;
+},reprArrayLike:function(o){
+var m=MochiKit.Base;
+return "["+m.map(m.repr,o).join(", ")+"]";
+},reprString:function(o){
+return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
+},reprNumber:function(o){
+return o+"";
+},registerJSON:function(_de,_df,_e0,_e1){
+MochiKit.Base.jsonRegistry.register(_de,_df,_e0,_e1);
+},evalJSON:function(){
+return eval("("+MochiKit.Base._filterJSON(arguments[0])+")");
+},_filterJSON:function(s){
+var m=s.match(/^\s*\/\*(.*)\*\/\s*$/);
+if(m){
+return m[1];
+}
+return s;
+},serializeJSON:function(o){
+var _e5=typeof (o);
+if(_e5=="number"||_e5=="boolean"){
+return o+"";
+}else{
+if(o===null){
+return "null";
+}
+}
+var m=MochiKit.Base;
+var _e7=m.reprString;
+if(_e5=="string"){
+return _e7(o);
+}
+var me=arguments.callee;
+var _e9;
+if(typeof (o.__json__)=="function"){
+_e9=o.__json__();
+if(o!==_e9){
+return me(_e9);
+}
+}
+if(typeof (o.json)=="function"){
+_e9=o.json();
+if(o!==_e9){
+return me(_e9);
+}
+}
+if(_e5!="function"&&typeof (o.length)=="number"){
+var res=[];
+for(var i=0;i<o.length;i++){
+var val=me(o[i]);
+if(typeof (val)!="string"){
+val="undefined";
+}
+res.push(val);
+}
+return "["+res.join(", ")+"]";
+}
+try{
+_e9=m.jsonRegistry.match(o);
+if(o!==_e9){
+return me(_e9);
+}
+}
+catch(e){
+if(e!=m.NotFound){
+throw e;
+}
+}
+if(_e5=="undefined"){
+throw new TypeError("undefined can not be serialized as JSON");
+}
+if(_e5=="function"){
+return null;
+}
+res=[];
+for(var k in o){
+var _ee;
+if(typeof (k)=="number"){
+_ee="\""+k+"\"";
+}else{
+if(typeof (k)=="string"){
+_ee=_e7(k);
+}else{
+continue;
+}
+}
+val=me(o[k]);
+if(typeof (val)!="string"){
+continue;
+}
+res.push(_ee+":"+val);
+}
+return "{"+res.join(", ")+"}";
+},objEqual:function(a,b){
+return (MochiKit.Base.compare(a,b)===0);
+},arrayEqual:function(_f1,arr){
+if(_f1.length!=arr.length){
+return false;
+}
+return (MochiKit.Base.compare(_f1,arr)===0);
+},concat:function(){
+var _f3=[];
+var _f4=MochiKit.Base.extend;
+for(var i=0;i<arguments.length;i++){
+_f4(_f3,arguments[i]);
+}
+return _f3;
+},keyComparator:function(key){
+var m=MochiKit.Base;
+var _f8=m.compare;
+if(arguments.length==1){
+return function(a,b){
+return _f8(a[key],b[key]);
+};
+}
+var _fb=m.extend(null,arguments);
+return function(a,b){
+var _fe=0;
+for(var i=0;(_fe===0)&&(i<_fb.length);i++){
+var key=_fb[i];
+_fe=_f8(a[key],b[key]);
+}
+return _fe;
+};
+},reverseKeyComparator:function(key){
+var _102=MochiKit.Base.keyComparator.apply(this,arguments);
+return function(a,b){
+return _102(b,a);
+};
+},partial:function(func){
+var m=MochiKit.Base;
+return m.bind.apply(this,m.extend([func,undefined],arguments,1));
+},listMinMax:function(_107,lst){
+if(lst.length===0){
+return null;
+}
+var cur=lst[0];
+var _10a=MochiKit.Base.compare;
+for(var i=1;i<lst.length;i++){
+var o=lst[i];
+if(_10a(o,cur)==_107){
+cur=o;
+}
+}
+return cur;
+},objMax:function(){
+return MochiKit.Base.listMinMax(1,arguments);
+},objMin:function(){
+return MochiKit.Base.listMinMax(-1,arguments);
+},findIdentical:function(lst,_10e,_10f,end){
+if(typeof (end)=="undefined"||end===null){
+end=lst.length;
+}
+if(typeof (_10f)=="undefined"||_10f===null){
+_10f=0;
+}
+for(var i=_10f;i<end;i++){
+if(lst[i]===_10e){
+return i;
+}
+}
+return -1;
+},mean:function(){
+var sum=0;
+var m=MochiKit.Base;
+var args=m.extend(null,arguments);
+var _115=args.length;
+while(args.length){
+var o=args.shift();
+if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
+_115+=o.length-1;
+for(var i=o.length-1;i>=0;i--){
+sum+=o[i];
+}
+}else{
+sum+=o;
+}
+}
+if(_115<=0){
+throw new TypeError("mean() requires at least one argument");
+}
+return sum/_115;
+},median:function(){
+var data=MochiKit.Base.flattenArguments(arguments);
+if(data.length===0){
+throw new TypeError("median() requires at least one argument");
+}
+data.sort(compare);
+if(data.length%2==0){
+var _119=data.length/2;
+return (data[_119]+data[_119-1])/2;
+}else{
+return data[(data.length-1)/2];
+}
+},findValue:function(lst,_11b,_11c,end){
+if(typeof (end)=="undefined"||end===null){
+end=lst.length;
+}
+if(typeof (_11c)=="undefined"||_11c===null){
+_11c=0;
+}
+var cmp=MochiKit.Base.compare;
+for(var i=_11c;i<end;i++){
+if(cmp(lst[i],_11b)===0){
+return i;
+}
+}
+return -1;
+},nodeWalk:function(node,_121){
+var _122=[node];
+var _123=MochiKit.Base.extend;
+while(_122.length){
+var res=_121(_122.shift());
+if(res){
+_123(_122,res);
+}
+}
+},nameFunctions:function(_125){
+var base=_125.NAME;
+if(typeof (base)=="undefined"){
+base="";
+}else{
+base=base+".";
+}
+for(var name in _125){
+var o=_125[name];
+if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
+try{
+o.NAME=base+name;
+}
+catch(e){
+}
+}
+}
+},queryString:function(_129,_12a){
+if(typeof (MochiKit.DOM)!="undefined"&&arguments.length==1&&(typeof (_129)=="string"||(typeof (_129.nodeType)!="undefined"&&_129.nodeType>0))){
+var kv=MochiKit.DOM.formContents(_129);
+_129=kv[0];
+_12a=kv[1];
+}else{
+if(arguments.length==1){
+if(typeof (_129.length)=="number"&&_129.length==2){
+return arguments.callee(_129[0],_129[1]);
+}
+var o=_129;
+_129=[];
+_12a=[];
+for(var k in o){
+var v=o[k];
+if(typeof (v)=="function"){
+continue;
+}else{
+if(typeof (v)!="string"&&typeof (v.length)=="number"){
+for(var i=0;i<v.length;i++){
+_129.push(k);
+_12a.push(v[i]);
+}
+}else{
+_129.push(k);
+_12a.push(v);
+}
+}
+}
+}
+}
+var rval=[];
+var len=Math.min(_129.length,_12a.length);
+var _132=MochiKit.Base.urlEncode;
+for(var i=0;i<len;i++){
+v=_12a[i];
+if(typeof (v)!="undefined"&&v!==null){
+rval.push(_132(_129[i])+"="+_132(v));
+}
+}
+return rval.join("&");
+},parseQueryString:function(_133,_134){
+var qstr=(_133.charAt(0)=="?")?_133.substring(1):_133;
+var _136=qstr.replace(/\+/g,"%20").split(/(\&\;|\&\#38\;|\&|\&)/);
+var o={};
+var _138;
+if(typeof (decodeURIComponent)!="undefined"){
+_138=decodeURIComponent;
+}else{
+_138=unescape;
+}
+if(_134){
+for(var i=0;i<_136.length;i++){
+var pair=_136[i].split("=");
+var name=_138(pair.shift());
+if(!name){
+continue;
+}
+var arr=o[name];
+if(!(arr instanceof Array)){
+arr=[];
+o[name]=arr;
+}
+arr.push(_138(pair.join("=")));
+}
+}else{
+for(i=0;i<_136.length;i++){
+pair=_136[i].split("=");
+var name=pair.shift();
+if(!name){
+continue;
+}
+o[_138(name)]=_138(pair.join("="));
+}
+}
+return o;
+}});
+MochiKit.Base.AdapterRegistry=function(){
+this.pairs=[];
+};
+MochiKit.Base.AdapterRegistry.prototype={register:function(name,_13e,wrap,_140){
+if(_140){
+this.pairs.unshift([name,_13e,wrap]);
+}else{
+this.pairs.push([name,_13e,wrap]);
+}
+},match:function(){
+for(var i=0;i<this.pairs.length;i++){
+var pair=this.pairs[i];
+if(pair[1].apply(this,arguments)){
+return pair[2].apply(this,arguments);
+}
+}
+throw MochiKit.Base.NotFound;
+},unregister:function(name){
+for(var i=0;i<this.pairs.length;i++){
+var pair=this.pairs[i];
+if(pair[0]==name){
+this.pairs.splice(i,1);
+return true;
+}
+}
+return false;
+}};
+MochiKit.Base.EXPORT=["flattenArray","noop","camelize","counter","clone","extend","update","updatetree","setdefault","keys","values","items","NamedError","operator","forwardCall","itemgetter","typeMatcher","isCallable","isUndefined","isUndefinedOrNull","isNull","isEmpty","isNotEmpty","isArrayLike","isDateLike","xmap","map","xfilter","filter","methodcaller","compose","bind","bindMethods","NotFound","AdapterRegistry","registerComparator","compare","registerRepr","repr","objEqual","arrayEqual","concat","keyComparator","reverseKeyComparator","partial","merge","listMinMax","listMax","listMin","objMax","objMin","nodeWalk","zip","urlEncode","queryString","serializeJSON","registerJSON","evalJSON","parseQueryString","findValue","findIdentical","flattenArguments","method","average","mean","median"];
+MochiKit.Base.EXPORT_OK=["nameFunctions","comparatorRegistry","reprRegistry","jsonRegistry","compareDateLike","compareArrayLike","reprArrayLike","reprString","reprNumber"];
+MochiKit.Base._exportSymbols=function(_146,_147){
+if(!MochiKit.__export__){
+return;
+}
+var all=_147.EXPORT_TAGS[":all"];
+for(var i=0;i<all.length;i++){
+_146[all[i]]=_147[all[i]];
+}
+};
+MochiKit.Base.__new__=function(){
+var m=this;
+m.noop=m.operator.identity;
+m.forward=m.forwardCall;
+m.find=m.findValue;
+if(typeof (encodeURIComponent)!="undefined"){
+m.urlEncode=function(_14b){
+return encodeURIComponent(_14b).replace(/\'/g,"%27");
+};
+}else{
+m.urlEncode=function(_14c){
+return escape(_14c).replace(/\+/g,"%2B").replace(/\"/g,"%22").rval.replace(/\'/g,"%27");
+};
+}
+m.NamedError=function(name){
+this.message=name;
+this.name=name;
+};
+m.NamedError.prototype=new Error();
+m.update(m.NamedError.prototype,{repr:function(){
+if(this.message&&this.message!=this.name){
+return this.name+"("+m.repr(this.message)+")";
+}else{
+return this.name+"()";
+}
+},toString:m.forwardCall("repr")});
+m.NotFound=new m.NamedError("MochiKit.Base.NotFound");
+m.listMax=m.partial(m.listMinMax,1);
+m.listMin=m.partial(m.listMinMax,-1);
+m.isCallable=m.typeMatcher("function");
+m.isUndefined=m.typeMatcher("undefined");
+m.merge=m.partial(m.update,null);
+m.zip=m.partial(m.map,null);
+m.average=m.mean;
+m.comparatorRegistry=new m.AdapterRegistry();
+m.registerComparator("dateLike",m.isDateLike,m.compareDateLike);
+m.registerComparator("arrayLike",m.isArrayLike,m.compareArrayLike);
+m.reprRegistry=new m.AdapterRegistry();
+m.registerRepr("arrayLike",m.isArrayLike,m.reprArrayLike);
+m.registerRepr("string",m.typeMatcher("string"),m.reprString);
+m.registerRepr("numbers",m.typeMatcher("number","boolean"),m.reprNumber);
+m.jsonRegistry=new m.AdapterRegistry();
+var all=m.concat(m.EXPORT,m.EXPORT_OK);
+m.EXPORT_TAGS={":common":m.concat(m.EXPORT_OK),":all":all};
+m.nameFunctions(this);
+};
+MochiKit.Base.__new__();
+if(MochiKit.__export__){
+compare=MochiKit.Base.compare;
+compose=MochiKit.Base.compose;
+serializeJSON=MochiKit.Base.serializeJSON;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.Base);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.DOM");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.DOM depends on MochiKit.Base!";
+}
+if(typeof (MochiKit.DOM)=="undefined"){
+MochiKit.DOM={};
+}
+MochiKit.DOM.NAME="MochiKit.DOM";
+MochiKit.DOM.VERSION="1.4";
+MochiKit.DOM.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.DOM.toString=function(){
+return this.__repr__();
+};
+MochiKit.DOM.EXPORT=["removeEmptyTextNodes","formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","isChildNode","getNodeAttribute","removeNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","insertSiblingNodesAfter","insertSiblingNodesBefore","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","scrapeText","isParent","getFirstParentByTagAndClassName","makeClipping","undoClipping","makePositioned","undoPositioned","getFirstElementByTagAndClassName"];
+MochiKit.DOM.EXPORT_OK=["domConverters"];
+MochiKit.DOM.DEPRECATED=[["computedStyle","MochiKit.Style.getStyle","1.4"],["elementDimensions","MochiKit.Style.getElementDimensions","1.4"],["elementPosition","MochiKit.Style.getElementPosition","1.4"],["hideElement","MochiKit.Style.hideElement","1.4"],["setElementDimensions","MochiKit.Style.setElementDimensions","1.4"],["setElementPosition","MochiKit.Style.setElementPosition","1.4"],["setDisplayForElement","MochiKit.Style.setDisplayForElement","1.4"],["setOpacity","MochiKit.Style.setOpacity","1.4"],["showElement","MochiKit.Style.showElement","1.4"],["Coordinates","MochiKit.Style.Coordinates","1.4"],["Dimensions","MochiKit.Style.Dimensions","1.4"]];
+MochiKit.DOM.getViewportDimensions=new Function(""+"if (!MochiKit[\"Style\"]) {"+" throw new Error(\"This function has been deprecated and depends on MochiKit.Style.\");"+"}"+"return MochiKit.Style.getViewportDimensions.apply(this, arguments);");
+MochiKit.Base.update(MochiKit.DOM,{currentWindow:function(){
+return MochiKit.DOM._window;
+},currentDocument:function(){
+return MochiKit.DOM._document;
+},withWindow:function(win,func){
+var self=MochiKit.DOM;
+var _152=self._document;
+var _153=self._window;
+var rval;
+try{
+self._window=win;
+self._document=win.document;
+rval=func();
+}
+catch(e){
+self._window=_153;
+self._document=_152;
+throw e;
+}
+self._window=_153;
+self._document=_152;
+return rval;
+},formContents:function(elem){
+var _156=[];
+var _157=[];
+var m=MochiKit.Base;
+var self=MochiKit.DOM;
+if(typeof (elem)=="undefined"||elem===null){
+elem=self._document.body;
+}else{
+elem=self.getElement(elem);
+}
+m.nodeWalk(elem,function(elem){
+var name=elem.name;
+if(m.isNotEmpty(name)){
+var _15c=elem.tagName.toUpperCase();
+if(_15c==="INPUT"&&(elem.type=="radio"||elem.type=="checkbox")&&!elem.checked){
+return null;
+}
+if(_15c==="SELECT"){
+if(elem.type=="select-one"){
+if(elem.selectedIndex>=0){
+var opt=elem.options[elem.selectedIndex];
+var v=opt.value;
+if(!v){
+var h=opt.outerHTML;
+if(h&&!h.match(/^[^>]+\svalue\s*=/i)){
+v=opt.text;
+}
+}
+_156.push(name);
+_157.push(v);
+return null;
+}
+_156.push(name);
+_157.push("");
+return null;
+}else{
+var opts=elem.options;
+if(!opts.length){
+_156.push(name);
+_157.push("");
+return null;
+}
+for(var i=0;i<opts.length;i++){
+var opt=opts[i];
+if(!opt.selected){
+continue;
+}
+var v=opt.value;
+if(!v){
+var h=opt.outerHTML;
+if(h&&!h.match(/^[^>]+\svalue\s*=/i)){
+v=opt.text;
+}
+}
+_156.push(name);
+_157.push(v);
+}
+return null;
+}
+}
+if(_15c==="FORM"||_15c==="P"||_15c==="SPAN"||_15c==="DIV"){
+return elem.childNodes;
+}
+_156.push(name);
+_157.push(elem.value||"");
+return null;
+}
+return elem.childNodes;
+});
+return [_156,_157];
+},withDocument:function(doc,func){
+var self=MochiKit.DOM;
+var _165=self._document;
+var rval;
+try{
+self._document=doc;
+rval=func();
+}
+catch(e){
+self._document=_165;
+throw e;
+}
+self._document=_165;
+return rval;
+},registerDOMConverter:function(name,_168,wrap,_16a){
+MochiKit.DOM.domConverters.register(name,_168,wrap,_16a);
+},coerceToDOM:function(node,ctx){
+var m=MochiKit.Base;
+var im=MochiKit.Iter;
+var self=MochiKit.DOM;
+if(im){
+var iter=im.iter;
+var _171=im.repeat;
+var map=m.map;
+}
+var _173=self.domConverters;
+var _174=arguments.callee;
+var _175=m.NotFound;
+while(true){
+if(typeof (node)=="undefined"||node===null){
+return null;
+}
+if(typeof (node)=="function"&&typeof (node.length)=="number"&&!(node instanceof Function)){
+node=im.list(node);
+}
+if(typeof (node.nodeType)!="undefined"&&node.nodeType>0){
+return node;
+}
+if(typeof (node)=="number"||typeof (node)=="boolean"){
+node=node.toString();
+}
+if(typeof (node)=="string"){
+return self._document.createTextNode(node);
+}
+if(typeof (node.__dom__)=="function"){
+node=node.__dom__(ctx);
+continue;
+}
+if(typeof (node.dom)=="function"){
+node=node.dom(ctx);
+continue;
+}
+if(typeof (node)=="function"){
+node=node.apply(ctx,[ctx]);
+continue;
+}
+if(im){
+var _176=null;
+try{
+_176=iter(node);
+}
+catch(e){
+}
+if(_176){
+return map(_174,_176,_171(ctx));
+}
+}
+try{
+node=_173.match(node,ctx);
+continue;
+}
+catch(e){
+if(e!=_175){
+throw e;
+}
+}
+return self._document.createTextNode(node.toString());
+}
+return undefined;
+},isChildNode:function(node,_178){
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+node=self.getElement(node);
+}
+if(typeof (_178)=="string"){
+_178=self.getElement(_178);
+}
+if(node===_178){
+return true;
+}
+while(node&&node.tagName.toUpperCase()!="BODY"){
+node=node.parentNode;
+if(node===_178){
+return true;
+}
+}
+return false;
+},setNodeAttribute:function(node,attr,_17c){
+var o={};
+o[attr]=_17c;
+try{
+return MochiKit.DOM.updateNodeAttributes(node,o);
+}
+catch(e){
+}
+return null;
+},getNodeAttribute:function(node,attr){
+var self=MochiKit.DOM;
+var _181=self.attributeArray.renames[attr];
+node=self.getElement(node);
+try{
+if(_181){
+return node[_181];
+}
+return node.getAttribute(attr);
+}
+catch(e){
+}
+return null;
+},removeNodeAttribute:function(node,attr){
+var self=MochiKit.DOM;
+var _185=self.attributeArray.renames[attr];
+node=self.getElement(node);
+try{
+if(_185){
+return node[_185];
+}
+return node.removeAttribute(attr);
+}
+catch(e){
+}
+return null;
+},updateNodeAttributes:function(node,_187){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+}
+if(_187){
+var _18a=MochiKit.Base.updatetree;
+if(self.attributeArray.compliant){
+for(var k in _187){
+var v=_187[k];
+if(typeof (v)=="object"&&typeof (elem[k])=="object"){
+if(k=="style"&&MochiKit.Style){
+MochiKit.Style.setStyle(elem,v);
+}else{
+_18a(elem[k],v);
+}
+}else{
+if(k.substring(0,2)=="on"){
+if(typeof (v)=="string"){
+v=new Function(v);
+}
+elem[k]=v;
+}else{
+elem.setAttribute(k,v);
+}
+}
+}
+}else{
+var _18d=self.attributeArray.renames;
+for(var k in _187){
+v=_187[k];
+var _18e=_18d[k];
+if(k=="style"&&typeof (v)=="string"){
+elem.style.cssText=v;
+}else{
+if(typeof (_18e)=="string"){
+elem[_18e]=v;
+}else{
+if(typeof (elem[k])=="object"&&typeof (v)=="object"){
+if(k=="style"&&MochiKit.Style){
+MochiKit.Style.setStyle(elem,v);
+}else{
+_18a(elem[k],v);
+}
+}else{
+if(k.substring(0,2)=="on"){
+if(typeof (v)=="string"){
+v=new Function(v);
+}
+elem[k]=v;
+}else{
+elem.setAttribute(k,v);
+}
+}
+}
+}
+}
+}
+}
+return elem;
+},appendChildNodes:function(node){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+}
+var _192=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
+var _193=MochiKit.Base.concat;
+while(_192.length){
+var n=_192.shift();
+if(typeof (n)=="undefined"||n===null){
+}else{
+if(typeof (n.nodeType)=="number"){
+elem.appendChild(n);
+}else{
+_192=_193(n,_192);
+}
+}
+}
+return elem;
+},insertSiblingNodesBefore:function(node){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+}
+var _198=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
+var _199=elem.parentNode;
+var _19a=MochiKit.Base.concat;
+while(_198.length){
+var n=_198.shift();
+if(typeof (n)=="undefined"||n===null){
+}else{
+if(typeof (n.nodeType)=="number"){
+_199.insertBefore(n,elem);
+}else{
+_198=_19a(n,_198);
+}
+}
+}
+return _199;
+},insertSiblingNodesAfter:function(node){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+}
+var _19f=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
+if(elem.nextSibling){
+return self.insertSiblingNodesBefore(elem.nextSibling,_19f);
+}else{
+return self.appendChildNodes(elem.parentNode,_19f);
+}
+},replaceChildNodes:function(node){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+arguments[0]=elem;
+}
+var _1a3;
+while((_1a3=elem.firstChild)){
+elem.removeChild(_1a3);
+}
+if(arguments.length<2){
+return elem;
+}else{
+return self.appendChildNodes.apply(this,arguments);
+}
+},createDOM:function(name,_1a5){
+var elem;
+var self=MochiKit.DOM;
+var m=MochiKit.Base;
+if(typeof (_1a5)=="string"||typeof (_1a5)=="number"){
+var args=m.extend([name,null],arguments,1);
+return arguments.callee.apply(this,args);
+}
+if(typeof (name)=="string"){
+var _1aa=self._xhtml;
+if(_1a5&&!self.attributeArray.compliant){
+var _1ab="";
+if("name" in _1a5){
+_1ab+=" name=\""+self.escapeHTML(_1a5.name)+"\"";
+}
+if(name=="input"&&"type" in _1a5){
+_1ab+=" type=\""+self.escapeHTML(_1a5.type)+"\"";
+}
+if(_1ab){
+name="<"+name+_1ab+">";
+_1aa=false;
+}
+}
+var d=self._document;
+if(_1aa&&d===document){
+elem=d.createElementNS("http://www.w3.org/1999/xhtml",name);
+}else{
+elem=d.createElement(name);
+}
+}else{
+elem=name;
+}
+if(_1a5){
+self.updateNodeAttributes(elem,_1a5);
+}
+if(arguments.length<=2){
+return elem;
+}else{
+var args=m.extend([elem],arguments,2);
+return self.appendChildNodes.apply(this,args);
+}
+},createDOMFunc:function(){
+var m=MochiKit.Base;
+return m.partial.apply(this,m.extend([MochiKit.DOM.createDOM],arguments));
+},removeElement:function(elem){
+var e=MochiKit.DOM.getElement(elem);
+e.parentNode.removeChild(e);
+return e;
+},swapDOM:function(dest,src){
+var self=MochiKit.DOM;
+dest=self.getElement(dest);
+var _1b3=dest.parentNode;
+if(src){
+src=self.getElement(src);
+_1b3.replaceChild(src,dest);
+}else{
+_1b3.removeChild(dest);
+}
+return src;
+},getElement:function(id){
+var self=MochiKit.DOM;
+if(arguments.length==1){
+return ((typeof (id)=="string")?self._document.getElementById(id):id);
+}else{
+return MochiKit.Base.map(self.getElement,arguments);
+}
+},getElementsByTagAndClassName:function(_1b6,_1b7,_1b8){
+var self=MochiKit.DOM;
+if(typeof (_1b6)=="undefined"||_1b6===null){
+_1b6="*";
+}
+if(typeof (_1b8)=="undefined"||_1b8===null){
+_1b8=self._document;
+}
+_1b8=self.getElement(_1b8);
+var _1ba=(_1b8.getElementsByTagName(_1b6)||self._document.all);
+if(typeof (_1b7)=="undefined"||_1b7===null){
+return MochiKit.Base.extend(null,_1ba);
+}
+var _1bb=[];
+for(var i=0;i<_1ba.length;i++){
+var _1bd=_1ba[i];
+var cls=_1bd.className;
+if(!cls){
+continue;
+}
+var _1bf=cls.split(" ");
+for(var j=0;j<_1bf.length;j++){
+if(_1bf[j]==_1b7){
+_1bb.push(_1bd);
+break;
+}
+}
+}
+return _1bb;
+},_newCallStack:function(path,once){
+var rval=function(){
+var _1c4=arguments.callee.callStack;
+for(var i=0;i<_1c4.length;i++){
+if(_1c4[i].apply(this,arguments)===false){
+break;
+}
+}
+if(once){
+try{
+this[path]=null;
+}
+catch(e){
+}
+}
+};
+rval.callStack=[];
+return rval;
+},addToCallStack:function(_1c6,path,func,once){
+var self=MochiKit.DOM;
+var _1cb=_1c6[path];
+var _1cc=_1cb;
+if(!(typeof (_1cb)=="function"&&typeof (_1cb.callStack)=="object"&&_1cb.callStack!==null)){
+_1cc=self._newCallStack(path,once);
+if(typeof (_1cb)=="function"){
+_1cc.callStack.push(_1cb);
+}
+_1c6[path]=_1cc;
+}
+_1cc.callStack.push(func);
+},addLoadEvent:function(func){
+var self=MochiKit.DOM;
+self.addToCallStack(self._window,"onload",func,true);
+},focusOnLoad:function(_1cf){
+var self=MochiKit.DOM;
+self.addLoadEvent(function(){
+_1cf=self.getElement(_1cf);
+if(_1cf){
+_1cf.focus();
+}
+});
+},setElementClass:function(_1d1,_1d2){
+var self=MochiKit.DOM;
+var obj=self.getElement(_1d1);
+if(self.attributeArray.compliant){
+obj.setAttribute("class",_1d2);
+}else{
+obj.setAttribute("className",_1d2);
+}
+},toggleElementClass:function(_1d5){
+var self=MochiKit.DOM;
+for(var i=1;i<arguments.length;i++){
+var obj=self.getElement(arguments[i]);
+if(!self.addElementClass(obj,_1d5)){
+self.removeElementClass(obj,_1d5);
+}
+}
+},addElementClass:function(_1d9,_1da){
+var self=MochiKit.DOM;
+var obj=self.getElement(_1d9);
+var cls=obj.className;
+if(cls==undefined||cls.length===0){
+self.setElementClass(obj,_1da);
+return true;
+}
+if(cls==_1da){
+return false;
+}
+var _1de=cls.split(" ");
+for(var i=0;i<_1de.length;i++){
+if(_1de[i]==_1da){
+return false;
+}
+}
+self.setElementClass(obj,cls+" "+_1da);
+return true;
+},removeElementClass:function(_1e0,_1e1){
+var self=MochiKit.DOM;
+var obj=self.getElement(_1e0);
+var cls=obj.className;
+if(cls==undefined||cls.length===0){
+return false;
+}
+if(cls==_1e1){
+self.setElementClass(obj,"");
+return true;
+}
+var _1e5=cls.split(" ");
+for(var i=0;i<_1e5.length;i++){
+if(_1e5[i]==_1e1){
+_1e5.splice(i,1);
+self.setElementClass(obj,_1e5.join(" "));
+return true;
+}
+}
+return false;
+},swapElementClass:function(_1e7,_1e8,_1e9){
+var obj=MochiKit.DOM.getElement(_1e7);
+var res=MochiKit.DOM.removeElementClass(obj,_1e8);
+if(res){
+MochiKit.DOM.addElementClass(obj,_1e9);
+}
+return res;
+},hasElementClass:function(_1ec,_1ed){
+var obj=MochiKit.DOM.getElement(_1ec);
+var cls=obj.className;
+if(!cls){
+return false;
+}
+var _1f0=cls.split(" ");
+for(var i=1;i<arguments.length;i++){
+var good=false;
+for(var j=0;j<_1f0.length;j++){
+if(_1f0[j]==arguments[i]){
+good=true;
+break;
+}
+}
+if(!good){
+return false;
+}
+}
+return true;
+},escapeHTML:function(s){
+return s.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">");
+},toHTML:function(dom){
+return MochiKit.DOM.emitHTML(dom).join("");
+},emitHTML:function(dom,lst){
+if(typeof (lst)=="undefined"||lst===null){
+lst=[];
+}
+var _1f8=[dom];
+var self=MochiKit.DOM;
+var _1fa=self.escapeHTML;
+var _1fb=self.attributeArray;
+while(_1f8.length){
+dom=_1f8.pop();
+if(typeof (dom)=="string"){
+lst.push(dom);
+}else{
+if(dom.nodeType==1){
+lst.push("<"+dom.tagName.toLowerCase());
+var _1fc=[];
+var _1fd=_1fb(dom);
+for(var i=0;i<_1fd.length;i++){
+var a=_1fd[i];
+_1fc.push([" ",a.name,"=\"",_1fa(a.value),"\""]);
+}
+_1fc.sort();
+for(i=0;i<_1fc.length;i++){
+var _200=_1fc[i];
+for(var j=0;j<_200.length;j++){
+lst.push(_200[j]);
+}
+}
+if(dom.hasChildNodes()){
+lst.push(">");
+_1f8.push("</"+dom.tagName.toLowerCase()+">");
+var _202=dom.childNodes;
+for(i=_202.length-1;i>=0;i--){
+_1f8.push(_202[i]);
+}
+}else{
+lst.push("/>");
+}
+}else{
+if(dom.nodeType==3){
+lst.push(_1fa(dom.nodeValue));
+}
+}
+}
+}
+return lst;
+},scrapeText:function(node,_204){
+var rval=[];
+(function(node){
+var cn=node.childNodes;
+if(cn){
+for(var i=0;i<cn.length;i++){
+arguments.callee.call(this,cn[i]);
+}
+}
+var _209=node.nodeValue;
+if(typeof (_209)=="string"){
+rval.push(_209);
+}
+})(MochiKit.DOM.getElement(node));
+if(_204){
+return rval;
+}else{
+return rval.join("");
+}
+},removeEmptyTextNodes:function(_20a){
+_20a=MochiKit.DOM.getElement(_20a);
+for(var i=0;i<_20a.childNodes.length;i++){
+var node=_20a.childNodes[i];
+if(node.nodeType==3&&!/\S/.test(node.nodeValue)){
+node.parentNode.removeChild(node);
+}
+}
+},makeClipping:function(_20d){
+_20d=MochiKit.DOM.getElement(_20d);
+var _20e=_20d.style.overflow;
+if((MochiKit.Style.getStyle(_20d,"overflow")||"visible")!="hidden"){
+_20d.style.overflow="hidden";
+}
+return _20e;
+},undoClipping:function(_20f,_210){
+_20f=MochiKit.DOM.getElement(_20f);
+if(!_210){
+return;
+}
+_20f.style.overflow=_210;
+},makePositioned:function(_211){
+_211=MochiKit.DOM.getElement(_211);
+var pos=MochiKit.Style.getStyle(_211,"position");
+if(pos=="static"||!pos){
+_211.style.position="relative";
+if(/Opera/.test(navigator.userAgent)){
+_211.style.top=0;
+_211.style.left=0;
+}
+}
+},undoPositioned:function(_213){
+_213=MochiKit.DOM.getElement(_213);
+if(_213.style.position=="relative"){
+_213.style.position=_213.style.top=_213.style.left=_213.style.bottom=_213.style.right="";
+}
+},getFirstElementByTagAndClassName:function(_214,_215,_216){
+var self=MochiKit.DOM;
+if(typeof (_214)=="undefined"||_214===null){
+_214="*";
+}
+if(typeof (_216)=="undefined"||_216===null){
+_216=self._document;
+}
+_216=self.getElement(_216);
+var _218=(_216.getElementsByTagName(_214)||self._document.all);
+if(typeof (_215)=="undefined"||_215===null){
+return _218[0];
+}
+for(var i=0;i<_218.length;i++){
+var _21a=_218[i];
+var _21b=_21a.className.split(" ");
+for(var j=0;j<_21b.length;j++){
+if(_21b[j]==_215){
+return _21a;
+}
+}
+}
+},getFirstParentByTagAndClassName:function(elem,_21e,_21f){
+var self=MochiKit.DOM;
+elem=self.getElement(elem);
+if(typeof (_21e)=="undefined"||_21e===null){
+_21e="*";
+}else{
+_21e=_21e.toUpperCase();
+}
+if(typeof (_21f)=="undefined"||_21f===null){
+_21f=null;
+}
+var _221="";
+var _222="";
+while(elem&&elem.tagName){
+elem=elem.parentNode;
+if(_21e=="*"&&_21f===null){
+return elem;
+}
+_221=elem.className.split(" ");
+_222=elem.tagName.toUpperCase();
+if(_21f===null&&_21e==_222){
+return elem;
+}else{
+if(_21f!==null){
+for(var i=0;i<_221.length;i++){
+if(_21e=="*"&&_221[i]==_21f){
+return elem;
+}else{
+if(_21e==_222&&_221[i]==_21f){
+return elem;
+}
+}
+}
+}
+}
+}
+return elem;
+},isParent:function(_224,_225){
+if(!_224.parentNode||_224==_225){
+return false;
+}
+if(_224.parentNode==_225){
+return true;
+}
+return MochiKit.DOM.isParent(_224.parentNode,_225);
+},__new__:function(win){
+var m=MochiKit.Base;
+if(typeof (document)!="undefined"){
+this._document=document;
+var _228="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+this._xhtml=(document.documentElement&&document.createElementNS&&document.documentElement.namespaceURI===_228);
+}else{
+if(MochiKit.MockDOM){
+this._document=MochiKit.MockDOM.document;
+}
+}
+this._window=win;
+this.domConverters=new m.AdapterRegistry();
+var _229=this._document.createElement("span");
+var _22a;
+if(_229&&_229.attributes&&_229.attributes.length>0){
+var _22b=m.filter;
+_22a=function(node){
+return _22b(_22a.ignoreAttrFilter,node.attributes);
+};
+_22a.ignoreAttr={};
+var _22d=_229.attributes;
+var _22e=_22a.ignoreAttr;
+for(var i=0;i<_22d.length;i++){
+var a=_22d[i];
+_22e[a.name]=a.value;
+}
+_22a.ignoreAttrFilter=function(a){
+return (_22a.ignoreAttr[a.name]!=a.value);
+};
+_22a.compliant=false;
+_22a.renames={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor","readonly":"readOnly","colspan":"colSpan","bgcolor":"bgColor","cellspacing":"cellSpacing","cellpadding":"cellPadding"};
+}else{
+_22a=function(node){
+return node.attributes;
+};
+_22a.compliant=true;
+_22a.renames={};
+}
+this.attributeArray=_22a;
+var _233=function(_234,arr){
+var _236=arr[1].split(".");
+var str="";
+var obj={};
+str+="if (!MochiKit."+_236[1]+") { throw new Error(\"";
+str+="This function has been deprecated and depends on MochiKit.";
+str+=_236[1]+".\");}";
+str+="return MochiKit."+_236[1]+"."+arr[0];
+str+=".apply(this, arguments);";
+obj[_236[2]]=new Function(str);
+MochiKit.Base.update(MochiKit[_234],obj);
+};
+for(var i;i<MochiKit.DOM.DEPRECATED.length;i++){
+_233("DOM",MochiKit.DOM.DEPRECATED[i]);
+}
+var _239=this.createDOMFunc;
+this.UL=_239("ul");
+this.OL=_239("ol");
+this.LI=_239("li");
+this.TD=_239("td");
+this.TR=_239("tr");
+this.TBODY=_239("tbody");
+this.THEAD=_239("thead");
+this.TFOOT=_239("tfoot");
+this.TABLE=_239("table");
+this.TH=_239("th");
+this.INPUT=_239("input");
+this.SPAN=_239("span");
+this.A=_239("a");
+this.DIV=_239("div");
+this.IMG=_239("img");
+this.BUTTON=_239("button");
+this.TT=_239("tt");
+this.PRE=_239("pre");
+this.H1=_239("h1");
+this.H2=_239("h2");
+this.H3=_239("h3");
+this.BR=_239("br");
+this.HR=_239("hr");
+this.LABEL=_239("label");
+this.TEXTAREA=_239("textarea");
+this.FORM=_239("form");
+this.P=_239("p");
+this.SELECT=_239("select");
+this.OPTION=_239("option");
+this.OPTGROUP=_239("optgroup");
+this.LEGEND=_239("legend");
+this.FIELDSET=_239("fieldset");
+this.STRONG=_239("strong");
+this.CANVAS=_239("canvas");
+this.$=this.getElement;
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+}});
+MochiKit.DOM.__new__(((typeof (window)=="undefined")?this:window));
+if(MochiKit.__export__){
+withWindow=MochiKit.DOM.withWindow;
+withDocument=MochiKit.DOM.withDocument;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.DOM);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Style");
+dojo.require("MochiKit.Base");
+dojo.require("MochiKit.DOM");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+JSAN.use("MochiKit.DOM",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Style depends on MochiKit.Base!";
+}
+try{
+if(typeof (MochiKit.DOM)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Style depends on MochiKit.DOM!";
+}
+if(typeof (MochiKit.Style)=="undefined"){
+MochiKit.Style={};
+}
+MochiKit.Style.NAME="MochiKit.Style";
+MochiKit.Style.VERSION="1.4";
+MochiKit.Style.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Style.toString=function(){
+return this.__repr__();
+};
+MochiKit.Style.EXPORT_OK=[];
+MochiKit.Style.EXPORT=["setStyle","setOpacity","getStyle","getElementDimensions","elementDimensions","setElementDimensions","getElementPosition","elementPosition","setElementPosition","setDisplayForElement","hideElement","showElement","getViewportDimensions","getViewportPosition","Dimensions","Coordinates"];
+MochiKit.Style.Dimensions=function(w,h){
+this.w=w;
+this.h=h;
+};
+MochiKit.Style.Dimensions.prototype.__repr__=function(){
+var repr=MochiKit.Base.repr;
+return "{w: "+repr(this.w)+", h: "+repr(this.h)+"}";
+};
+MochiKit.Style.Dimensions.prototype.toString=function(){
+return this.__repr__();
+};
+MochiKit.Style.Coordinates=function(x,y){
+this.x=x;
+this.y=y;
+};
+MochiKit.Style.Coordinates.prototype.__repr__=function(){
+var repr=MochiKit.Base.repr;
+return "{x: "+repr(this.x)+", y: "+repr(this.y)+"}";
+};
+MochiKit.Style.Coordinates.prototype.toString=function(){
+return this.__repr__();
+};
+MochiKit.Base.update(MochiKit.Style,{getStyle:function(elem,_241){
+var dom=MochiKit.DOM;
+var d=dom._document;
+elem=dom.getElement(elem);
+_241=MochiKit.Base.camelize(_241);
+if(!elem||elem==d){
+return undefined;
+}
+if(_241=="opacity"&&elem.filters){
+var _244=(MochiKit.Style.getStyle(elem,"filter")||"").match(/alpha\(opacity=(.*)\)/);
+if(_244&&_244[1]){
+return parseFloat(_244[1])/100;
+}
+return 1;
+}
+var _245=elem.style?elem.style[_241]:null;
+if(!_245){
+if(d.defaultView&&d.defaultView.getComputedStyle){
+var css=d.defaultView.getComputedStyle(elem,null);
+_241=_241.replace(/([A-Z])/g,"-$1").toLowerCase();
+_245=css?css.getPropertyValue(_241):null;
+}else{
+if(elem.currentStyle){
+_245=elem.currentStyle[_241];
+}
+}
+}
+if(_241=="opacity"){
+_245=parseFloat(_245);
+}
+if(/Opera/.test(navigator.userAgent)&&(MochiKit.Base.find(["left","top","right","bottom"],_241)!=-1)){
+if(MochiKit.Style.getStyle(elem,"position")=="static"){
+_245="auto";
+}
+}
+return _245=="auto"?null:_245;
+},setStyle:function(elem,_248){
+elem=MochiKit.DOM.getElement(elem);
+for(var name in _248){
+if(name=="opacity"){
+MochiKit.Style.setOpacity(elem,_248[name]);
+}else{
+elem.style[MochiKit.Base.camelize(name)]=_248[name];
+}
+}
+},setOpacity:function(elem,o){
+elem=MochiKit.DOM.getElement(elem);
+var self=MochiKit.Style;
+if(o==1){
+var _24d=/Gecko/.test(navigator.userAgent)&&!(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
+elem.style["opacity"]=_24d?0.999999:1;
+if(/MSIE/.test(navigator.userAgent)){
+elem.style["filter"]=self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"");
+}
+}else{
+if(o<0.00001){
+o=0;
+}
+elem.style["opacity"]=o;
+if(/MSIE/.test(navigator.userAgent)){
+elem.style["filter"]=self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"")+"alpha(opacity="+o*100+")";
+}
+}
+},getElementPosition:function(elem,_24f){
+var self=MochiKit.Style;
+var dom=MochiKit.DOM;
+elem=dom.getElement(elem);
+if(!elem||(!(elem.x&&elem.y)&&(!elem.parentNode===null||self.getStyle(elem,"display")=="none"))){
+return undefined;
+}
+var c=new self.Coordinates(0,0);
+var box=null;
+var _254=null;
+var d=MochiKit.DOM._document;
+var de=d.documentElement;
+var b=d.body;
+if(!elem.parentNode&&elem.x&&elem.y){
+c.x+=elem.x||0;
+c.y+=elem.y||0;
+}else{
+if(elem.getBoundingClientRect){
+box=elem.getBoundingClientRect();
+c.x+=box.left+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
+c.y+=box.top+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
+}else{
+if(elem.offsetParent){
+c.x+=elem.offsetLeft;
+c.y+=elem.offsetTop;
+_254=elem.offsetParent;
+if(_254!=elem){
+while(_254){
+c.x+=_254.offsetLeft;
+c.y+=_254.offsetTop;
+_254=_254.offsetParent;
+}
+}
+var ua=navigator.userAgent.toLowerCase();
+if((typeof (opera)!="undefined"&&parseFloat(opera.version())<9)||(ua.indexOf("AppleWebKit")!=-1&&self.getStyle(elem,"position")=="absolute")){
+c.x-=b.offsetLeft;
+c.y-=b.offsetTop;
+}
+}
+}
+}
+if(typeof (_24f)!="undefined"){
+_24f=arguments.callee(_24f);
+if(_24f){
+c.x-=(_24f.x||0);
+c.y-=(_24f.y||0);
+}
+}
+if(elem.parentNode){
+_254=elem.parentNode;
+}else{
+_254=null;
+}
+while(_254){
+var _259=_254.tagName.toUpperCase();
+if(_259==="BODY"||_259==="HTML"){
+break;
+}
+var disp=self.getStyle(_254,"display");
+if(disp!="inline"&&disp!="table-row"){
+c.x-=_254.scrollLeft;
+c.y-=_254.scrollTop;
+}
+if(_254.parentNode){
+_254=_254.parentNode;
+}else{
+_254=null;
+}
+}
+return c;
+},setElementPosition:function(elem,_25c,_25d){
+elem=MochiKit.DOM.getElement(elem);
+if(typeof (_25d)=="undefined"){
+_25d="px";
+}
+var _25e={};
+var _25f=MochiKit.Base.isUndefinedOrNull;
+if(!_25f(_25c.x)){
+_25e["left"]=_25c.x+_25d;
+}
+if(!_25f(_25c.y)){
+_25e["top"]=_25c.y+_25d;
+}
+MochiKit.DOM.updateNodeAttributes(elem,{"style":_25e});
+},getElementDimensions:function(elem){
+var self=MochiKit.Style;
+var dom=MochiKit.DOM;
+if(typeof (elem.w)=="number"||typeof (elem.h)=="number"){
+return new self.Dimensions(elem.w||0,elem.h||0);
+}
+elem=dom.getElement(elem);
+if(!elem){
+return undefined;
+}
+var disp=self.getStyle(elem,"display");
+if(disp!="none"&&disp!==""&&typeof (disp)!="undefined"){
+return new self.Dimensions(elem.offsetWidth||0,elem.offsetHeight||0);
+}
+var s=elem.style;
+var _265=s.visibility;
+var _266=s.position;
+s.visibility="hidden";
+s.position="absolute";
+s.display="";
+var _267=elem.offsetWidth;
+var _268=elem.offsetHeight;
+s.display="none";
+s.position=_266;
+s.visibility=_265;
+return new self.Dimensions(_267,_268);
+},setElementDimensions:function(elem,_26a,_26b){
+elem=MochiKit.DOM.getElement(elem);
+if(typeof (_26b)=="undefined"){
+_26b="px";
+}
+var _26c={};
+var _26d=MochiKit.Base.isUndefinedOrNull;
+if(!_26d(_26a.w)){
+_26c["width"]=_26a.w+_26b;
+}
+if(!_26d(_26a.h)){
+_26c["height"]=_26a.h+_26b;
+}
+MochiKit.DOM.updateNodeAttributes(elem,{"style":_26c});
+},setDisplayForElement:function(_26e,_26f){
+var _270=MochiKit.Base.extend(null,arguments,1);
+var _271=MochiKit.DOM.getElement;
+for(var i=0;i<_270.length;i++){
+_26f=_271(_270[i]);
+if(_26f){
+_26f.style.display=_26e;
+}
+}
+},getViewportDimensions:function(){
+var d=new MochiKit.Style.Dimensions();
+var w=MochiKit.DOM._window;
+var b=MochiKit.DOM._document.body;
+if(w.innerWidth){
+d.w=w.innerWidth;
+d.h=w.innerHeight;
+}else{
+if(b.parentElement.clientWidth){
+d.w=b.parentElement.clientWidth;
+d.h=b.parentElement.clientHeight;
+}else{
+if(b&&b.clientWidth){
+d.w=b.clientWidth;
+d.h=b.clientHeight;
+}
+}
+}
+return d;
+},getViewportPosition:function(){
+var c=new MochiKit.Style.Coordinates(0,0);
+var d=MochiKit.DOM._document;
+var de=d.documentElement;
+var db=d.body;
+if(de&&(de.scrollTop||de.scrollLeft)){
+c.x=de.scrollLeft;
+c.y=de.scrollTop;
+}else{
+if(db){
+c.x=db.scrollLeft;
+c.y=db.scrollTop;
+}
+}
+return c;
+},__new__:function(){
+var m=MochiKit.Base;
+this.elementPosition=this.getElementPosition;
+this.elementDimensions=this.getElementDimensions;
+this.hideElement=m.partial(this.setDisplayForElement,"none");
+this.showElement=m.partial(this.setDisplayForElement,"block");
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+}});
+MochiKit.Style.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.Style);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Signal");
+dojo.require("MochiKit.Base");
+dojo.require("MochiKit.DOM");
+dojo.require("MochiKit.Style");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+JSAN.use("MochiKit.DOM",[]);
+JSAN.use("MochiKit.Style",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Signal depends on MochiKit.Base!";
+}
+try{
+if(typeof (MochiKit.DOM)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Signal depends on MochiKit.DOM!";
+}
+try{
+if(typeof (MochiKit.Style)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Signal depends on MochiKit.Style!";
+}
+if(typeof (MochiKit.Signal)=="undefined"){
+MochiKit.Signal={};
+}
+MochiKit.Signal.NAME="MochiKit.Signal";
+MochiKit.Signal.VERSION="1.4";
+MochiKit.Signal._observers=[];
+MochiKit.Signal.Event=function(src,e){
+this._event=e||window.event;
+this._src=src;
+};
+MochiKit.Base.update(MochiKit.Signal.Event.prototype,{__repr__:function(){
+var repr=MochiKit.Base.repr;
+var str="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target());
+if(this.type()&&this.type().indexOf("key")===0||this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu"){
+str+=", modifier(): "+"{alt: "+repr(this.modifier().alt)+", ctrl: "+repr(this.modifier().ctrl)+", meta: "+repr(this.modifier().meta)+", shift: "+repr(this.modifier().shift)+", any: "+repr(this.modifier().any)+"}";
+}
+if(this.type()&&this.type().indexOf("key")===0){
+str+=", key(): {code: "+repr(this.key().code)+", string: "+repr(this.key().string)+"}";
+}
+if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
+str+=", mouse(): {page: "+repr(this.mouse().page)+", client: "+repr(this.mouse().client);
+if(this.type()!="mousemove"){
+str+=", button: {left: "+repr(this.mouse().button.left)+", middle: "+repr(this.mouse().button.middle)+", right: "+repr(this.mouse().button.right)+"}}";
+}else{
+str+="}";
+}
+}
+if(this.type()=="mouseover"||this.type()=="mouseout"){
+str+=", relatedTarget(): "+repr(this.relatedTarget());
+}
+str+="}";
+return str;
+},toString:function(){
+return this.__repr__();
+},src:function(){
+return this._src;
+},event:function(){
+return this._event;
+},type:function(){
+return this._event.type||undefined;
+},target:function(){
+return this._event.target||this._event.srcElement;
+},_relatedTarget:null,relatedTarget:function(){
+if(this._relatedTarget!==null){
+return this._relatedTarget;
+}
+var elem=null;
+if(this.type()=="mouseover"){
+elem=(this._event.relatedTarget||this._event.fromElement);
+}else{
+if(this.type()=="mouseout"){
+elem=(this._event.relatedTarget||this._event.toElement);
+}
+}
+if(elem!==null){
+this._relatedTarget=elem;
+return elem;
+}
+return undefined;
+},_modifier:null,modifier:function(){
+if(this._modifier!==null){
+return this._modifier;
+}
+var m={};
+m.alt=this._event.altKey;
+m.ctrl=this._event.ctrlKey;
+m.meta=this._event.metaKey||false;
+m.shift=this._event.shiftKey;
+m.any=m.alt||m.ctrl||m.shift||m.meta;
+this._modifier=m;
+return m;
+},_key:null,key:function(){
+if(this._key!==null){
+return this._key;
+}
+var k={};
+if(this.type()&&this.type().indexOf("key")===0){
+if(this.type()=="keydown"||this.type()=="keyup"){
+k.code=this._event.keyCode;
+k.string=(MochiKit.Signal._specialKeys[k.code]||"KEY_UNKNOWN");
+this._key=k;
+return k;
+}else{
+if(this.type()=="keypress"){
+k.code=0;
+k.string="";
+if(typeof (this._event.charCode)!="undefined"&&this._event.charCode!==0&&!MochiKit.Signal._specialMacKeys[this._event.charCode]){
+k.code=this._event.charCode;
+k.string=String.fromCharCode(k.code);
+}else{
+if(this._event.keyCode&&typeof (this._event.charCode)=="undefined"){
+k.code=this._event.keyCode;
+k.string=String.fromCharCode(k.code);
+}
+}
+this._key=k;
+return k;
+}
+}
+}
+return undefined;
+},_mouse:null,mouse:function(){
+if(this._mouse!==null){
+return this._mouse;
+}
+var m={};
+var e=this._event;
+if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
+m.client=new MochiKit.Style.Coordinates(0,0);
+if(e.clientX||e.clientY){
+m.client.x=(!e.clientX||e.clientX<0)?0:e.clientX;
+m.client.y=(!e.clientY||e.clientY<0)?0:e.clientY;
+}
+m.page=new MochiKit.Style.Coordinates(0,0);
+if(e.pageX||e.pageY){
+m.page.x=(!e.pageX||e.pageX<0)?0:e.pageX;
+m.page.y=(!e.pageY||e.pageY<0)?0:e.pageY;
+}else{
+var de=MochiKit.DOM._document.documentElement;
+var b=MochiKit.DOM._document.body;
+m.page.x=e.clientX+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
+m.page.y=e.clientY+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
+}
+if(this.type()!="mousemove"){
+m.button={};
+m.button.left=false;
+m.button.right=false;
+m.button.middle=false;
+if(e.which){
+m.button.left=(e.which==1);
+m.button.middle=(e.which==2);
+m.button.right=(e.which==3);
+}else{
+m.button.left=!!(e.button&1);
+m.button.right=!!(e.button&2);
+m.button.middle=!!(e.button&4);
+}
+}
+this._mouse=m;
+return m;
+}
+return undefined;
+},stop:function(){
+this.stopPropagation();
+this.preventDefault();
+},stopPropagation:function(){
+if(this._event.stopPropagation){
+this._event.stopPropagation();
+}else{
+this._event.cancelBubble=true;
+}
+},preventDefault:function(){
+if(this._event.preventDefault){
+this._event.preventDefault();
+}else{
+if(this._confirmUnload===null){
+this._event.returnValue=false;
+}
+}
+},_confirmUnload:null,confirmUnload:function(msg){
+if(this.type()=="beforeunload"){
+this._confirmUnload=msg;
+this._event.returnValue=msg;
+}
+}});
+MochiKit.Signal._specialMacKeys={3:"KEY_ENTER",63289:"KEY_NUM_PAD_CLEAR",63276:"KEY_PAGE_UP",63277:"KEY_PAGE_DOWN",63275:"KEY_END",63273:"KEY_HOME",63234:"KEY_ARROW_LEFT",63232:"KEY_ARROW_UP",63235:"KEY_ARROW_RIGHT",63233:"KEY_ARROW_DOWN",63302:"KEY_INSERT",63272:"KEY_DELETE"};
+(function(){
+var _287=MochiKit.Signal._specialMacKeys;
+for(i=63236;i<=63242;i++){
+_287[i]="KEY_F"+(i-63236+1);
+}
+})();
+MochiKit.Signal._specialKeys={8:"KEY_BACKSPACE",9:"KEY_TAB",12:"KEY_NUM_PAD_CLEAR",13:"KEY_ENTER",16:"KEY_SHIFT",17:"KEY_CTRL",18:"KEY_ALT",19:"KEY_PAUSE",20:"KEY_CAPS_LOCK",27:"KEY_ESCAPE",32:"KEY_SPACEBAR",33:"KEY_PAGE_UP",34:"KEY_PAGE_DOWN",35:"KEY_END",36:"KEY_HOME",37:"KEY_ARROW_LEFT",38:"KEY_ARROW_UP",39:"KEY_ARROW_RIGHT",40:"KEY_ARROW_DOWN",44:"KEY_PRINT_SCREEN",45:"KEY_INSERT",46:"KEY_DELETE",59:"KEY_SEMICOLON",91:"KEY_WINDOWS_LEFT",92:"KEY_WINDOWS_RIGHT",93:"KEY_SELECT",106:"KEY_NUM_PAD_ASTERISK",107:"KEY_NUM_PAD_PLUS_SIGN",109:"KEY_NUM_PAD_HYPHEN-MINUS",110:"KEY_NUM_PAD_FULL_STOP",111:"KEY_NUM_PAD_SOLIDUS",144:"KEY_NUM_LOCK",145:"KEY_SCROLL_LOCK",186:"KEY_SEMICOLON",187:"KEY_EQUALS_SIGN",188:"KEY_COMMA",189:"KEY_HYPHEN-MINUS",190:"KEY_FULL_STOP",191:"KEY_SOLIDUS",192:"KEY_GRAVE_ACCENT",219:"KEY_LEFT_SQUARE_BRACKET",220:"KEY_REVERSE_SOLIDUS",221:"KEY_RIGHT_SQUARE_BRACKET",222:"KEY_APOSTROPHE"};
+(function(){
+var _288=MochiKit.Signal._specialKeys;
+for(var i=48;i<=57;i++){
+_288[i]="KEY_"+(i-48);
+}
+for(i=65;i<=90;i++){
+_288[i]="KEY_"+String.fromCharCode(i);
+}
+for(i=96;i<=105;i++){
+_288[i]="KEY_NUM_PAD_"+(i-96);
+}
+for(i=112;i<=123;i++){
+_288[i]="KEY_F"+(i-112+1);
+}
+})();
+MochiKit.Signal.Ident=function(_28a){
+this.source=_28a.source;
+this.signal=_28a.signal;
+this.listener=_28a.listener;
+this.isDOM=_28a.isDOM;
+this.objOrFunc=_28a.objOrFunc;
+this.funcOrStr=_28a.funcOrStr;
+this.connected=_28a.connected;
+};
+MochiKit.Signal.Ident.prototype={};
+MochiKit.Base.update(MochiKit.Signal,{__repr__:function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+},toString:function(){
+return this.__repr__();
+},_unloadCache:function(){
+var self=MochiKit.Signal;
+var _28c=self._observers;
+for(var i=0;i<_28c.length;i++){
+if(_28c[i].signal!=="onload"&&_28c[i].signal!=="onunload"){
+self._disconnect(_28c[i]);
+}
+}
+},_listener:function(src,sig,func,obj,_292){
+var self=MochiKit.Signal;
+var E=self.Event;
+if(!_292){
+return MochiKit.Base.bind(func,obj);
+}
+obj=obj||src;
+if(typeof (func)=="string"){
+if(sig==="onload"||sig==="onunload"){
+return function(_295){
+obj[func].apply(obj,[new E(src,_295)]);
+var _296=new MochiKit.Signal.Ident({source:src,signal:sig,objOrFunc:obj,funcOrStr:func});
+MochiKit.Signal._disconnect(_296);
+};
+}else{
+return function(_297){
+obj[func].apply(obj,[new E(src,_297)]);
+};
+}
+}else{
+if(sig==="onload"||sig==="onunload"){
+return function(_298){
+func.apply(obj,[new E(src,_298)]);
+MochiKit.Signal.disconnect(src,sig,func);
+var _299=new MochiKit.Signal.Ident({source:src,signal:sig,objOrFunc:func});
+MochiKit.Signal._disconnect(_299);
+};
+}else{
+return function(_29a){
+func.apply(obj,[new E(src,_29a)]);
+};
+}
+}
+},_browserAlreadyHasMouseEnterAndLeave:function(){
+return /MSIE/.test(navigator.userAgent);
+},_mouseEnterListener:function(src,sig,func,obj){
+var E=MochiKit.Signal.Event;
+return function(_2a0){
+var e=new E(src,_2a0);
+try{
+e.relatedTarget().nodeName;
+}
+catch(err){
+return;
+}
+e.stop();
+if(MochiKit.DOM.isChildNode(e.relatedTarget(),src)){
+return;
+}
+e.type=function(){
+return sig;
+};
+if(typeof (func)=="string"){
+return obj[func].apply(obj,[e]);
+}else{
+return func.apply(obj,[e]);
+}
+};
+},_getDestPair:function(_2a2,_2a3){
+var obj=null;
+var func=null;
+if(typeof (_2a3)!="undefined"){
+obj=_2a2;
+func=_2a3;
+if(typeof (_2a3)=="string"){
+if(typeof (_2a2[_2a3])!="function"){
+throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
+}
+}else{
+if(typeof (_2a3)!="function"){
+throw new Error("'funcOrStr' must be a function or string");
+}
+}
+}else{
+if(typeof (_2a2)!="function"){
+throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
+}else{
+func=_2a2;
+}
+}
+return [obj,func];
+},connect:function(src,sig,_2a8,_2a9){
+src=MochiKit.DOM.getElement(src);
+var self=MochiKit.Signal;
+if(typeof (sig)!="string"){
+throw new Error("'sig' must be a string");
+}
+var _2ab=self._getDestPair(_2a8,_2a9);
+var obj=_2ab[0];
+var func=_2ab[1];
+if(typeof (obj)=="undefined"||obj===null){
+obj=src;
+}
+var _2ae=!!(src.addEventListener||src.attachEvent);
+if(_2ae&&(sig==="onmouseenter"||sig==="onmouseleave")&&!self._browserAlreadyHasMouseEnterAndLeave()){
+var _2af=self._mouseEnterListener(src,sig.substr(2),func,obj);
+if(sig==="onmouseenter"){
+sig="onmouseover";
+}else{
+sig="onmouseout";
+}
+}else{
+var _2af=self._listener(src,sig,func,obj,_2ae);
+}
+if(src.addEventListener){
+src.addEventListener(sig.substr(2),_2af,false);
+}else{
+if(src.attachEvent){
+src.attachEvent(sig,_2af);
+}
+}
+var _2b0=new MochiKit.Signal.Ident({source:src,signal:sig,listener:_2af,isDOM:_2ae,objOrFunc:_2a8,funcOrStr:_2a9,connected:true});
+self._observers.push(_2b0);
+if(!_2ae&&typeof (src.__connect__)=="function"){
+var args=MochiKit.Base.extend([_2b0],arguments,1);
+src.__connect__.apply(src,args);
+}
+return _2b0;
+},_disconnect:function(_2b2){
+if(!_2b2.connected){
+return;
+}
+_2b2.connected=false;
+if(!_2b2.isDOM){
+return;
+}
+var src=_2b2.source;
+var sig=_2b2.signal;
+var _2b5=_2b2.listener;
+if(src.removeEventListener){
+src.removeEventListener(sig.substr(2),_2b5,false);
+}else{
+if(src.detachEvent){
+src.detachEvent(sig,_2b5);
+}else{
+throw new Error("'src' must be a DOM element");
+}
+}
+},disconnect:function(_2b6){
+var self=MochiKit.Signal;
+var _2b8=self._observers;
+var m=MochiKit.Base;
+if(arguments.length>1){
+var src=MochiKit.DOM.getElement(arguments[0]);
+var sig=arguments[1];
+var obj=arguments[2];
+var func=arguments[3];
+for(var i=_2b8.length-1;i>=0;i--){
+var o=_2b8[i];
+if(o.source===src&&o.signal===sig&&o.objOrFunc===obj&&o.funcOrStr===func){
+self._disconnect(o);
+if(!self._lock){
+_2b8.splice(i,1);
+}else{
+self._dirty=true;
+}
+return true;
+}
+}
+}else{
+var idx=m.findIdentical(_2b8,_2b6);
+if(idx>=0){
+self._disconnect(_2b6);
+if(!self._lock){
+_2b8.splice(idx,1);
+}else{
+self._dirty=true;
+}
+return true;
+}
+}
+return false;
+},disconnectAllTo:function(_2c1,_2c2){
+var self=MochiKit.Signal;
+var _2c4=self._observers;
+var _2c5=self._disconnect;
+var _2c6=self._lock;
+var _2c7=self._dirty;
+if(typeof (_2c2)==="undefined"){
+_2c2=null;
+}
+for(var i=_2c4.length-1;i>=0;i--){
+var _2c9=_2c4[i];
+if(_2c9.objOrFunc===_2c1&&(_2c2===null||_2c9.funcOrStr===_2c2)){
+_2c5(_2c9);
+if(_2c6){
+_2c7=true;
+}else{
+_2c4.splice(i,1);
+}
+}
+}
+self._dirty=_2c7;
+},disconnectAll:function(src,sig){
+src=MochiKit.DOM.getElement(src);
+var m=MochiKit.Base;
+var _2cd=m.flattenArguments(m.extend(null,arguments,1));
+var self=MochiKit.Signal;
+var _2cf=self._disconnect;
+var _2d0=self._observers;
+var i,_2d2;
+var _2d3=self._lock;
+var _2d4=self._dirty;
+if(_2cd.length===0){
+for(i=_2d0.length-1;i>=0;i--){
+_2d2=_2d0[i];
+if(_2d2.source===src){
+_2cf(_2d2);
+if(!_2d3){
+_2d0.splice(i,1);
+}else{
+_2d4=true;
+}
+}
+}
+}else{
+var sigs={};
+for(i=0;i<_2cd.length;i++){
+sigs[_2cd[i]]=true;
+}
+for(i=_2d0.length-1;i>=0;i--){
+_2d2=_2d0[i];
+if(_2d2.source===src&&_2d2.signal in sigs){
+_2cf(_2d2);
+if(!_2d3){
+_2d0.splice(i,1);
+}else{
+_2d4=true;
+}
+}
+}
+}
+self._dirty=_2d4;
+},signal:function(src,sig){
+var self=MochiKit.Signal;
+var _2d9=self._observers;
+src=MochiKit.DOM.getElement(src);
+var args=MochiKit.Base.extend(null,arguments,2);
+var _2db=[];
+self._lock=true;
+for(var i=0;i<_2d9.length;i++){
+var _2dd=_2d9[i];
+if(_2dd.source===src&&_2dd.signal===sig&&_2dd.connected){
+try{
+_2dd.listener.apply(src,args);
+}
+catch(e){
+_2db.push(e);
+}
+}
+}
+self._lock=false;
+if(self._dirty){
+self._dirty=false;
+for(var i=_2d9.length-1;i>=0;i--){
+if(!_2d9[i].connected){
+_2d9.splice(i,1);
+}
+}
+}
+if(_2db.length==1){
+throw _2db[0];
+}else{
+if(_2db.length>1){
+var e=new Error("Multiple errors thrown in handling 'sig', see errors property");
+e.errors=_2db;
+throw e;
+}
+}
+}});
+MochiKit.Signal.EXPORT_OK=[];
+MochiKit.Signal.EXPORT=["connect","disconnect","signal","disconnectAll","disconnectAllTo"];
+MochiKit.Signal.__new__=function(win){
+var m=MochiKit.Base;
+this._document=document;
+this._window=win;
+this._lock=false;
+this._dirty=false;
+try{
+this.connect(window,"onunload",this._unloadCache);
+}
+catch(e){
+}
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+MochiKit.Signal.__new__(this);
+if(MochiKit.__export__){
+connect=MochiKit.Signal.connect;
+disconnect=MochiKit.Signal.disconnect;
+disconnectAll=MochiKit.Signal.disconnectAll;
+signal=MochiKit.Signal.signal;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.Signal);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Iter");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Iter depends on MochiKit.Base!";
+}
+if(typeof (MochiKit.Iter)=="undefined"){
+MochiKit.Iter={};
+}
+MochiKit.Iter.NAME="MochiKit.Iter";
+MochiKit.Iter.VERSION="1.4";
+MochiKit.Base.update(MochiKit.Iter,{__repr__:function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+},toString:function(){
+return this.__repr__();
+},registerIteratorFactory:function(name,_2e2,_2e3,_2e4){
+MochiKit.Iter.iteratorRegistry.register(name,_2e2,_2e3,_2e4);
+},iter:function(_2e5,_2e6){
+var self=MochiKit.Iter;
+if(arguments.length==2){
+return self.takewhile(function(a){
+return a!=_2e6;
+},_2e5);
+}
+if(typeof (_2e5.next)=="function"){
+return _2e5;
+}else{
+if(typeof (_2e5.iter)=="function"){
+return _2e5.iter();
+}
+}
+try{
+return self.iteratorRegistry.match(_2e5);
+}
+catch(e){
+var m=MochiKit.Base;
+if(e==m.NotFound){
+e=new TypeError(typeof (_2e5)+": "+m.repr(_2e5)+" is not iterable");
+}
+throw e;
+}
+},count:function(n){
+if(!n){
+n=0;
+}
+var m=MochiKit.Base;
+return {repr:function(){
+return "count("+n+")";
+},toString:m.forwardCall("repr"),next:m.counter(n)};
+},cycle:function(p){
+var self=MochiKit.Iter;
+var m=MochiKit.Base;
+var lst=[];
+var _2f0=self.iter(p);
+return {repr:function(){
+return "cycle(...)";
+},toString:m.forwardCall("repr"),next:function(){
+try{
+var rval=_2f0.next();
+lst.push(rval);
+return rval;
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+if(lst.length===0){
+this.next=function(){
+throw self.StopIteration;
+};
+}else{
+var i=-1;
+this.next=function(){
+i=(i+1)%lst.length;
+return lst[i];
+};
+}
+return this.next();
+}
+}};
+},repeat:function(elem,n){
+var m=MochiKit.Base;
+if(typeof (n)=="undefined"){
+return {repr:function(){
+return "repeat("+m.repr(elem)+")";
+},toString:m.forwardCall("repr"),next:function(){
+return elem;
+}};
+}
+return {repr:function(){
+return "repeat("+m.repr(elem)+", "+n+")";
+},toString:m.forwardCall("repr"),next:function(){
+if(n<=0){
+throw MochiKit.Iter.StopIteration;
+}
+n-=1;
+return elem;
+}};
+},next:function(_2f6){
+return _2f6.next();
+},izip:function(p,q){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+var next=self.next;
+var _2fc=m.map(self.iter,arguments);
+return {repr:function(){
+return "izip(...)";
+},toString:m.forwardCall("repr"),next:function(){
+return m.map(next,_2fc);
+}};
+},ifilter:function(pred,seq){
+var m=MochiKit.Base;
+seq=MochiKit.Iter.iter(seq);
+if(pred===null){
+pred=m.operator.truth;
+}
+return {repr:function(){
+return "ifilter(...)";
+},toString:m.forwardCall("repr"),next:function(){
+while(true){
+var rval=seq.next();
+if(pred(rval)){
+return rval;
+}
+}
+return undefined;
+}};
+},ifilterfalse:function(pred,seq){
+var m=MochiKit.Base;
+seq=MochiKit.Iter.iter(seq);
+if(pred===null){
+pred=m.operator.truth;
+}
+return {repr:function(){
+return "ifilterfalse(...)";
+},toString:m.forwardCall("repr"),next:function(){
+while(true){
+var rval=seq.next();
+if(!pred(rval)){
+return rval;
+}
+}
+return undefined;
+}};
+},islice:function(seq){
+var self=MochiKit.Iter;
+var m=MochiKit.Base;
+seq=self.iter(seq);
+var _308=0;
+var stop=0;
+var step=1;
+var i=-1;
+if(arguments.length==2){
+stop=arguments[1];
+}else{
+if(arguments.length==3){
+_308=arguments[1];
+stop=arguments[2];
+}else{
+_308=arguments[1];
+stop=arguments[2];
+step=arguments[3];
+}
+}
+return {repr:function(){
+return "islice("+["...",_308,stop,step].join(", ")+")";
+},toString:m.forwardCall("repr"),next:function(){
+var rval;
+while(i<_308){
+rval=seq.next();
+i++;
+}
+if(_308>=stop){
+throw self.StopIteration;
+}
+_308+=step;
+return rval;
+}};
+},imap:function(fun,p,q){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+var _312=m.map(self.iter,m.extend(null,arguments,1));
+var map=m.map;
+var next=self.next;
+return {repr:function(){
+return "imap(...)";
+},toString:m.forwardCall("repr"),next:function(){
+return fun.apply(this,map(next,_312));
+}};
+},applymap:function(fun,seq,self){
+seq=MochiKit.Iter.iter(seq);
+var m=MochiKit.Base;
+return {repr:function(){
+return "applymap(...)";
+},toString:m.forwardCall("repr"),next:function(){
+return fun.apply(self,seq.next());
+}};
+},chain:function(p,q){
+var self=MochiKit.Iter;
+var m=MochiKit.Base;
+if(arguments.length==1){
+return self.iter(arguments[0]);
+}
+var _31d=m.map(self.iter,arguments);
+return {repr:function(){
+return "chain(...)";
+},toString:m.forwardCall("repr"),next:function(){
+while(_31d.length>1){
+try{
+return _31d[0].next();
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+_31d.shift();
+}
+}
+if(_31d.length==1){
+var arg=_31d.shift();
+this.next=m.bind("next",arg);
+return this.next();
+}
+throw self.StopIteration;
+}};
+},takewhile:function(pred,seq){
+var self=MochiKit.Iter;
+seq=self.iter(seq);
+return {repr:function(){
+return "takewhile(...)";
+},toString:MochiKit.Base.forwardCall("repr"),next:function(){
+var rval=seq.next();
+if(!pred(rval)){
+this.next=function(){
+throw self.StopIteration;
+};
+this.next();
+}
+return rval;
+}};
+},dropwhile:function(pred,seq){
+seq=MochiKit.Iter.iter(seq);
+var m=MochiKit.Base;
+var bind=m.bind;
+return {"repr":function(){
+return "dropwhile(...)";
+},"toString":m.forwardCall("repr"),"next":function(){
+while(true){
+var rval=seq.next();
+if(!pred(rval)){
+break;
+}
+}
+this.next=bind("next",seq);
+return rval;
+}};
+},_tee:function(_328,sync,_32a){
+sync.pos[_328]=-1;
+var m=MochiKit.Base;
+var _32c=m.listMin;
+return {repr:function(){
+return "tee("+_328+", ...)";
+},toString:m.forwardCall("repr"),next:function(){
+var rval;
+var i=sync.pos[_328];
+if(i==sync.max){
+rval=_32a.next();
+sync.deque.push(rval);
+sync.max+=1;
+sync.pos[_328]+=1;
+}else{
+rval=sync.deque[i-sync.min];
+sync.pos[_328]+=1;
+if(i==sync.min&&_32c(sync.pos)!=sync.min){
+sync.min+=1;
+sync.deque.shift();
+}
+}
+return rval;
+}};
+},tee:function(_32f,n){
+var rval=[];
+var sync={"pos":[],"deque":[],"max":-1,"min":-1};
+if(arguments.length==1||typeof (n)=="undefined"||n===null){
+n=2;
+}
+var self=MochiKit.Iter;
+_32f=self.iter(_32f);
+var _tee=self._tee;
+for(var i=0;i<n;i++){
+rval.push(_tee(i,sync,_32f));
+}
+return rval;
+},list:function(_336){
+var rval;
+if(_336 instanceof Array){
+return _336.slice();
+}
+if(typeof (_336)=="function"&&!(_336 instanceof Function)&&typeof (_336.length)=="number"){
+rval=[];
+for(var i=0;i<_336.length;i++){
+rval.push(_336[i]);
+}
+return rval;
+}
+var self=MochiKit.Iter;
+_336=self.iter(_336);
+var rval=[];
+try{
+while(true){
+rval.push(_336.next());
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+return rval;
+}
+return undefined;
+},reduce:function(fn,_33b,_33c){
+var i=0;
+var x=_33c;
+var self=MochiKit.Iter;
+_33b=self.iter(_33b);
+if(arguments.length<3){
+try{
+x=_33b.next();
+}
+catch(e){
+if(e==self.StopIteration){
+e=new TypeError("reduce() of empty sequence with no initial value");
+}
+throw e;
+}
+i++;
+}
+try{
+while(true){
+x=fn(x,_33b.next());
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+return x;
+},range:function(){
+var _340=0;
+var stop=0;
+var step=1;
+if(arguments.length==1){
+stop=arguments[0];
+}else{
+if(arguments.length==2){
+_340=arguments[0];
+stop=arguments[1];
+}else{
+if(arguments.length==3){
+_340=arguments[0];
+stop=arguments[1];
+step=arguments[2];
+}else{
+throw new TypeError("range() takes 1, 2, or 3 arguments!");
+}
+}
+}
+if(step===0){
+throw new TypeError("range() step must not be 0");
+}
+return {next:function(){
+if((step>0&&_340>=stop)||(step<0&&_340<=stop)){
+throw MochiKit.Iter.StopIteration;
+}
+var rval=_340;
+_340+=step;
+return rval;
+},repr:function(){
+return "range("+[_340,stop,step].join(", ")+")";
+},toString:MochiKit.Base.forwardCall("repr")};
+},sum:function(_344,_345){
+if(typeof (_345)=="undefined"||_345===null){
+_345=0;
+}
+var x=_345;
+var self=MochiKit.Iter;
+_344=self.iter(_344);
+try{
+while(true){
+x+=_344.next();
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+return x;
+},exhaust:function(_348){
+var self=MochiKit.Iter;
+_348=self.iter(_348);
+try{
+while(true){
+_348.next();
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+},forEach:function(_34a,func,self){
+var m=MochiKit.Base;
+if(arguments.length>2){
+func=m.bind(func,self);
+}
+if(m.isArrayLike(_34a)){
+try{
+for(var i=0;i<_34a.length;i++){
+func(_34a[i]);
+}
+}
+catch(e){
+if(e!=MochiKit.Iter.StopIteration){
+throw e;
+}
+}
+}else{
+self=MochiKit.Iter;
+self.exhaust(self.imap(func,_34a));
+}
+},every:function(_34f,func){
+var self=MochiKit.Iter;
+try{
+self.ifilterfalse(func,_34f).next();
+return false;
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+return true;
+}
+},sorted:function(_352,cmp){
+var rval=MochiKit.Iter.list(_352);
+if(arguments.length==1){
+cmp=MochiKit.Base.compare;
+}
+rval.sort(cmp);
+return rval;
+},reversed:function(_355){
+var rval=MochiKit.Iter.list(_355);
+rval.reverse();
+return rval;
+},some:function(_357,func){
+var self=MochiKit.Iter;
+try{
+self.ifilter(func,_357).next();
+return true;
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+return false;
+}
+},iextend:function(lst,_35b){
+if(MochiKit.Base.isArrayLike(_35b)){
+for(var i=0;i<_35b.length;i++){
+lst.push(_35b[i]);
+}
+}else{
+var self=MochiKit.Iter;
+_35b=self.iter(_35b);
+try{
+while(true){
+lst.push(_35b.next());
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+}
+return lst;
+},groupby:function(_35e,_35f){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+if(arguments.length<2){
+_35f=m.operator.identity;
+}
+_35e=self.iter(_35e);
+var pk=undefined;
+var k=undefined;
+var v;
+function fetch(){
+v=_35e.next();
+k=_35f(v);
+}
+function eat(){
+var ret=v;
+v=undefined;
+return ret;
+}
+var _366=true;
+var _367=m.compare;
+return {repr:function(){
+return "groupby(...)";
+},next:function(){
+while(_367(k,pk)===0){
+fetch();
+if(_366){
+_366=false;
+break;
+}
+}
+pk=k;
+return [k,{next:function(){
+if(v==undefined){
+fetch();
+}
+if(_367(k,pk)!==0){
+throw self.StopIteration;
+}
+return eat();
+}}];
+}};
+},groupby_as_array:function(_368,_369){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+if(arguments.length<2){
+_369=m.operator.identity;
+}
+_368=self.iter(_368);
+var _36c=[];
+var _36d=true;
+var _36e;
+var _36f=m.compare;
+while(true){
+try{
+var _370=_368.next();
+var key=_369(_370);
+}
+catch(e){
+if(e==self.StopIteration){
+break;
+}
+throw e;
+}
+if(_36d||_36f(key,_36e)!==0){
+var _372=[];
+_36c.push([key,_372]);
+}
+_372.push(_370);
+_36d=false;
+_36e=key;
+}
+return _36c;
+},arrayLikeIter:function(_373){
+var i=0;
+return {repr:function(){
+return "arrayLikeIter(...)";
+},toString:MochiKit.Base.forwardCall("repr"),next:function(){
+if(i>=_373.length){
+throw MochiKit.Iter.StopIteration;
+}
+return _373[i++];
+}};
+},hasIterateNext:function(_375){
+return (_375&&typeof (_375.iterateNext)=="function");
+},iterateNextIter:function(_376){
+return {repr:function(){
+return "iterateNextIter(...)";
+},toString:MochiKit.Base.forwardCall("repr"),next:function(){
+var rval=_376.iterateNext();
+if(rval===null||rval===undefined){
+throw MochiKit.Iter.StopIteration;
+}
+return rval;
+}};
+}});
+MochiKit.Iter.EXPORT_OK=["iteratorRegistry","arrayLikeIter","hasIterateNext","iterateNextIter",];
+MochiKit.Iter.EXPORT=["StopIteration","registerIteratorFactory","iter","count","cycle","repeat","next","izip","ifilter","ifilterfalse","islice","imap","applymap","chain","takewhile","dropwhile","tee","list","reduce","range","sum","exhaust","forEach","every","sorted","reversed","some","iextend","groupby","groupby_as_array"];
+MochiKit.Iter.__new__=function(){
+var m=MochiKit.Base;
+if(typeof (StopIteration)!="undefined"){
+this.StopIteration=StopIteration;
+}else{
+this.StopIteration=new m.NamedError("StopIteration");
+}
+this.iteratorRegistry=new m.AdapterRegistry();
+this.registerIteratorFactory("arrayLike",m.isArrayLike,this.arrayLikeIter);
+this.registerIteratorFactory("iterateNext",this.hasIterateNext,this.iterateNextIter);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+MochiKit.Iter.__new__();
+if(MochiKit.__export__){
+reduce=MochiKit.Iter.reduce;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.Iter);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Async");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Async depends on MochiKit.Base!";
+}
+if(typeof (MochiKit.Async)=="undefined"){
+MochiKit.Async={};
+}
+MochiKit.Async.NAME="MochiKit.Async";
+MochiKit.Async.VERSION="1.4";
+MochiKit.Async.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Async.toString=function(){
+return this.__repr__();
+};
+MochiKit.Async.Deferred=function(_379){
+this.chain=[];
+this.id=this._nextId();
+this.fired=-1;
+this.paused=0;
+this.results=[null,null];
+this.canceller=_379;
+this.silentlyCancelled=false;
+this.chained=false;
+};
+MochiKit.Async.Deferred.prototype={repr:function(){
+var _37a;
+if(this.fired==-1){
+_37a="unfired";
+}else{
+if(this.fired===0){
+_37a="success";
+}else{
+_37a="error";
+}
+}
+return "Deferred("+this.id+", "+_37a+")";
+},toString:MochiKit.Base.forwardCall("repr"),_nextId:MochiKit.Base.counter(),cancel:function(){
+var self=MochiKit.Async;
+if(this.fired==-1){
+if(this.canceller){
+this.canceller(this);
+}else{
+this.silentlyCancelled=true;
+}
+if(this.fired==-1){
+this.errback(new self.CancelledError(this));
+}
+}else{
+if((this.fired===0)&&(this.results[0] instanceof self.Deferred)){
+this.results[0].cancel();
+}
+}
+},_resback:function(res){
+this.fired=((res instanceof Error)?1:0);
+this.results[this.fired]=res;
+this._fire();
+},_check:function(){
+if(this.fired!=-1){
+if(!this.silentlyCancelled){
+throw new MochiKit.Async.AlreadyCalledError(this);
+}
+this.silentlyCancelled=false;
+return;
+}
+},callback:function(res){
+this._check();
+if(res instanceof MochiKit.Async.Deferred){
+throw new Error("Deferred instances can only be chained if they are the result of a callback");
+}
+this._resback(res);
+},errback:function(res){
+this._check();
+var self=MochiKit.Async;
+if(res instanceof self.Deferred){
+throw new Error("Deferred instances can only be chained if they are the result of a callback");
+}
+if(!(res instanceof Error)){
+res=new self.GenericError(res);
+}
+this._resback(res);
+},addBoth:function(fn){
+if(arguments.length>1){
+fn=MochiKit.Base.partial.apply(null,arguments);
+}
+return this.addCallbacks(fn,fn);
+},addCallback:function(fn){
+if(arguments.length>1){
+fn=MochiKit.Base.partial.apply(null,arguments);
+}
+return this.addCallbacks(fn,null);
+},addErrback:function(fn){
+if(arguments.length>1){
+fn=MochiKit.Base.partial.apply(null,arguments);
+}
+return this.addCallbacks(null,fn);
+},addCallbacks:function(cb,eb){
+if(this.chained){
+throw new Error("Chained Deferreds can not be re-used");
+}
+this.chain.push([cb,eb]);
+if(this.fired>=0){
+this._fire();
+}
+return this;
+},_fire:function(){
+var _385=this.chain;
+var _386=this.fired;
+var res=this.results[_386];
+var self=this;
+var cb=null;
+while(_385.length>0&&this.paused===0){
+var pair=_385.shift();
+var f=pair[_386];
+if(f===null){
+continue;
+}
+try{
+res=f(res);
+_386=((res instanceof Error)?1:0);
+if(res instanceof MochiKit.Async.Deferred){
+cb=function(res){
+self._resback(res);
+self.paused--;
+if((self.paused===0)&&(self.fired>=0)){
+self._fire();
+}
+};
+this.paused++;
+}
+}
+catch(err){
+_386=1;
+if(!(err instanceof Error)){
+err=new MochiKit.Async.GenericError(err);
+}
+res=err;
+}
+}
+this.fired=_386;
+this.results[_386]=res;
+if(cb&&this.paused){
+res.addBoth(cb);
+res.chained=true;
+}
+}};
+MochiKit.Base.update(MochiKit.Async,{evalJSONRequest:function(req){
+return MochiKit.Base.evalJSON(req.responseText);
+},succeed:function(_38e){
+var d=new MochiKit.Async.Deferred();
+d.callback.apply(d,arguments);
+return d;
+},fail:function(_390){
+var d=new MochiKit.Async.Deferred();
+d.errback.apply(d,arguments);
+return d;
+},getXMLHttpRequest:function(){
+var self=arguments.callee;
+if(!self.XMLHttpRequest){
+var _393=[function(){
+return new XMLHttpRequest();
+},function(){
+return new ActiveXObject("Msxml2.XMLHTTP");
+},function(){
+return new ActiveXObject("Microsoft.XMLHTTP");
+},function(){
+return new ActiveXObject("Msxml2.XMLHTTP.4.0");
+},function(){
+throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
+}];
+for(var i=0;i<_393.length;i++){
+var func=_393[i];
+try{
+self.XMLHttpRequest=func;
+return func();
+}
+catch(e){
+}
+}
+}
+return self.XMLHttpRequest();
+},_xhr_onreadystatechange:function(d){
+var m=MochiKit.Base;
+if(this.readyState==4){
+try{
+this.onreadystatechange=null;
+}
+catch(e){
+try{
+this.onreadystatechange=m.noop;
+}
+catch(e){
+}
+}
+var _398=null;
+try{
+_398=this.status;
+if(!_398&&m.isNotEmpty(this.responseText)){
+_398=304;
+}
+}
+catch(e){
+}
+if(_398==200||_398==201||_398==204||_398==304||_398==1223){
+d.callback(this);
+}else{
+var err=new MochiKit.Async.XMLHttpRequestError(this,"Request failed");
+if(err.number){
+d.errback(err);
+}else{
+d.errback(err);
+}
+}
+}
+},_xhr_canceller:function(req){
+try{
+req.onreadystatechange=null;
+}
+catch(e){
+try{
+req.onreadystatechange=MochiKit.Base.noop;
+}
+catch(e){
+}
+}
+req.abort();
+},sendXMLHttpRequest:function(req,_39c){
+if(typeof (_39c)=="undefined"||_39c===null){
+_39c="";
+}
+var m=MochiKit.Base;
+var self=MochiKit.Async;
+var d=new self.Deferred(m.partial(self._xhr_canceller,req));
+try{
+req.onreadystatechange=m.bind(self._xhr_onreadystatechange,req,d);
+req.send(_39c);
+}
+catch(e){
+try{
+req.onreadystatechange=null;
+}
+catch(ignore){
+}
+d.errback(e);
+}
+return d;
+},doXHR:function(url,opts){
+var self=MochiKit.Async;
+return self.callLater(0,self._doXHR,url,opts);
+},_doXHR:function(url,opts){
+var m=MochiKit.Base;
+opts=m.update({method:"GET",sendContent:""},opts);
+var self=MochiKit.Async;
+var req=self.getXMLHttpRequest();
+if(opts.queryString){
+var qs=m.queryString(opts.queryString);
+if(qs){
+url+="?"+qs;
+}
+}
+if("username" in opts){
+req.open(opts.method,url,true,opts.username,opts.password);
+}else{
+req.open(opts.method,url,true);
+}
+if(req.overrideMimeType&&opts.mimeType){
+req.overrideMimeType(opts.mimeType);
+}
+if(opts.headers){
+var _3a9=opts.headers;
+if(!m.isArrayLike(_3a9)){
+_3a9=m.items(_3a9);
+}
+for(var i=0;i<_3a9.length;i++){
+var _3ab=_3a9[i];
+var name=_3ab[0];
+var _3ad=_3ab[1];
+req.setRequestHeader(name,_3ad);
+}
+}
+return self.sendXMLHttpRequest(req,opts.sendContent);
+},_buildURL:function(url){
+if(arguments.length>1){
+var m=MochiKit.Base;
+var qs=m.queryString.apply(null,m.extend(null,arguments,1));
+if(qs){
+return url+"?"+qs;
+}
+}
+return url;
+},doSimpleXMLHttpRequest:function(url){
+var self=MochiKit.Async;
+url=self._buildURL.apply(self,arguments);
+return self.doXHR(url);
+},loadJSONDoc:function(url){
+var self=MochiKit.Async;
+url=self._buildURL.apply(self,arguments);
+var d=self.doXHR(url,{"mimeType":"text/plain","headers":[["Accept","application/json"]]});
+d=d.addCallback(self.evalJSONRequest);
+return d;
+},wait:function(_3b6,_3b7){
+var d=new MochiKit.Async.Deferred();
+var m=MochiKit.Base;
+if(typeof (_3b7)!="undefined"){
+d.addCallback(function(){
+return _3b7;
+});
+}
+var _3ba=setTimeout(m.bind("callback",d),Math.floor(_3b6*1000));
+d.canceller=function(){
+try{
+clearTimeout(_3ba);
+}
+catch(e){
+}
+};
+return d;
+},callLater:function(_3bb,func){
+var m=MochiKit.Base;
+var _3be=m.partial.apply(m,m.extend(null,arguments,1));
+return MochiKit.Async.wait(_3bb).addCallback(function(res){
+return _3be();
+});
+}});
+MochiKit.Async.DeferredLock=function(){
+this.waiting=[];
+this.locked=false;
+this.id=this._nextId();
+};
+MochiKit.Async.DeferredLock.prototype={__class__:MochiKit.Async.DeferredLock,acquire:function(){
+var d=new MochiKit.Async.Deferred();
+if(this.locked){
+this.waiting.push(d);
+}else{
+this.locked=true;
+d.callback(this);
+}
+return d;
+},release:function(){
+if(!this.locked){
+throw TypeError("Tried to release an unlocked DeferredLock");
+}
+this.locked=false;
+if(this.waiting.length>0){
+this.locked=true;
+this.waiting.shift().callback(this);
+}
+},_nextId:MochiKit.Base.counter(),repr:function(){
+var _3c1;
+if(this.locked){
+_3c1="locked, "+this.waiting.length+" waiting";
+}else{
+_3c1="unlocked";
+}
+return "DeferredLock("+this.id+", "+_3c1+")";
+},toString:MochiKit.Base.forwardCall("repr")};
+MochiKit.Async.DeferredList=function(list,_3c3,_3c4,_3c5,_3c6){
+MochiKit.Async.Deferred.apply(this,[_3c6]);
+this.list=list;
+var _3c7=[];
+this.resultList=_3c7;
+this.finishedCount=0;
+this.fireOnOneCallback=_3c3;
+this.fireOnOneErrback=_3c4;
+this.consumeErrors=_3c5;
+var cb=MochiKit.Base.bind(this._cbDeferred,this);
+for(var i=0;i<list.length;i++){
+var d=list[i];
+_3c7.push(undefined);
+d.addCallback(cb,i,true);
+d.addErrback(cb,i,false);
+}
+if(list.length===0&&!_3c3){
+this.callback(this.resultList);
+}
+};
+MochiKit.Async.DeferredList.prototype=new MochiKit.Async.Deferred();
+MochiKit.Async.DeferredList.prototype._cbDeferred=function(_3cb,_3cc,_3cd){
+this.resultList[_3cb]=[_3cc,_3cd];
+this.finishedCount+=1;
+if(this.fired==-1){
+if(_3cc&&this.fireOnOneCallback){
+this.callback([_3cb,_3cd]);
+}else{
+if(!_3cc&&this.fireOnOneErrback){
+this.errback(_3cd);
+}else{
+if(this.finishedCount==this.list.length){
+this.callback(this.resultList);
+}
+}
+}
+}
+if(!_3cc&&this.consumeErrors){
+_3cd=null;
+}
+return _3cd;
+};
+MochiKit.Async.gatherResults=function(_3ce){
+var d=new MochiKit.Async.DeferredList(_3ce,false,true,false);
+d.addCallback(function(_3d0){
+var ret=[];
+for(var i=0;i<_3d0.length;i++){
+ret.push(_3d0[i][1]);
+}
+return ret;
+});
+return d;
+};
+MochiKit.Async.maybeDeferred=function(func){
+var self=MochiKit.Async;
+var _3d5;
+try{
+var r=func.apply(null,MochiKit.Base.extend([],arguments,1));
+if(r instanceof self.Deferred){
+_3d5=r;
+}else{
+if(r instanceof Error){
+_3d5=self.fail(r);
+}else{
+_3d5=self.succeed(r);
+}
+}
+}
+catch(e){
+_3d5=self.fail(e);
+}
+return _3d5;
+};
+MochiKit.Async.EXPORT=["AlreadyCalledError","CancelledError","BrowserComplianceError","GenericError","XMLHttpRequestError","Deferred","succeed","fail","getXMLHttpRequest","doSimpleXMLHttpRequest","loadJSONDoc","wait","callLater","sendXMLHttpRequest","DeferredLock","DeferredList","gatherResults","maybeDeferred","doXHR"];
+MochiKit.Async.EXPORT_OK=["evalJSONRequest"];
+MochiKit.Async.__new__=function(){
+var m=MochiKit.Base;
+var ne=m.partial(m._newNamedError,this);
+ne("AlreadyCalledError",function(_3d9){
+this.deferred=_3d9;
+});
+ne("CancelledError",function(_3da){
+this.deferred=_3da;
+});
+ne("BrowserComplianceError",function(msg){
+this.message=msg;
+});
+ne("GenericError",function(msg){
+this.message=msg;
+});
+ne("XMLHttpRequestError",function(req,msg){
+this.req=req;
+this.message=msg;
+try{
+this.number=req.status;
+}
+catch(e){
+}
+});
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+MochiKit.Async.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.Async);
+
+
--- /dev/null
+/* JavaScript parser
+ *
+ * A parser that can be plugged into the CodeMirror system has to
+ * implement the following interface: It is a function that, when
+ * called with a string stream (stringstream.js) as an argument,
+ * returns a MochiKit-style iterator (object with a 'next' method).
+ * This iterator, when called, consumes some input from the string
+ * stream, and returns a token object. Token objects must have a
+ * 'value' property (the text they represent), a 'style' property (the
+ * CSS style that should be used to colour them). Tokens for newline
+ * characters must also have a 'lexicalContext' property, which has an
+ * 'indentation' method that can be used to determine the proper
+ * indentation level for the next line. This method optionally takes
+ * the first character of the next line as an argument, which it can
+ * use to adjust the indentation level.
+ *
+ * So far this should be easy. The hard part is that the iterator
+ * produced by the parse function must also have a 'copy' method. This
+ * method, called without arguments, returns a function representing
+ * the current state of the parser. When this function is later called
+ * with a string stream as its argument, it returns a parser iterator
+ * object that resumes parsing using the old state and the new input
+ * stream. It may assume that only one parser is active at a time, and
+ * clobber the state of the old parser (the implementation below
+ * certianly does).
+ */
+
+// Parse function for JavaScript. Makes use of the tokenizer from
+// tokenizejavascript.js. Note that your parsers do not have to be
+// this complicated -- if you don't want to recognize local variables,
+// in many languages it is enough to just look for braces, semicolons,
+// parentheses, etc, and know when you are inside a string or comment.
+var parseJavaScript = function() {
+ // Token types that can be considered to be atoms.
+ var atomicTypes = setObject("atom", "number", "variable", "string", "regexp");
+
+ // Constructor for the lexical context objects.
+ function JSLexical(indented, column, type, align, prev) {
+ // indentation at start of this line
+ this.indented = indented;
+ // column at which this scope was opened
+ this.column = column;
+ // type of scope ('vardef', 'stat' (statement), '[', '{', or '(')
+ this.type = type;
+ // '[', '{', or '(' blocks that have any text after their opening
+ // character are said to be 'aligned' -- any lines below are
+ // indented all the way to the opening character.
+ if (align != null)
+ this.align = align;
+ // Parent scope, if any.
+ this.prev = prev;
+ }
+ // My favourite JavaScript indentation rules.
+ JSLexical.prototype.indentation = function(firstChar) {
+ var closing = firstChar == this.type;
+ if (this.type == "vardef")
+ return this.indented + 4;
+ if (this.type == "stat")
+ return this.indented + 2;
+ else if (this.align)
+ return this.column - (closing ? 1 : 0);
+ else
+ return this.indented + (closing ? 0 : 2);
+ }
+
+ // The parser-iterator-producing function itself.
+ return function(input){
+ // Wrap the input in a token stream
+ var tokens = tokenizeJavaScript(input);
+ // The parser state. cc is a stack of actions that have to be
+ // performed to finish the current statement. For example we might
+ // know that we still need to find a closing parenthesis and a
+ // semicolon. Actions at the end of the stack go first. It is
+ // initialized with an infinitely looping action that consumes
+ // whole statements.
+ var cc = [statements];
+ // Context contains information about the current local scope, the
+ // variables defined in that, and the scopes above it.
+ var context = null;
+ // The lexical scope, used mostly for indentation.
+ var lexical = new JSLexical(-2, 0, "block", false);
+ // Current column, and the indentation at the start of the current
+ // line. Used to create lexical scope objects.
+ var column = 0;
+ var indented = 0;
+ // Variables which are used by the mark, cont, and pass functions
+ // below to communicate with the driver loop in the 'next'
+ // function.
+ var consume, marked;
+
+ // The iterator object.
+ var parser = {next: next, copy: copy};
+
+ function next(){
+ // Start by performing any 'lexical' actions (adjusting the
+ // lexical variable), or the operations below will be working
+ // with the wrong lexical state.
+ while(cc[cc.length - 1].lex)
+ cc.pop()();
+
+ // Fetch a token.
+ var token = tokens.next();
+ // Adjust column and indented.
+ if (token.type == "whitespace" && column == 0)
+ indented = token.value.length;
+ column += token.value.length;
+ if (token.type == "newline"){
+ indented = column = 0;
+ // If the lexical scope's align property is still undefined at
+ // the end of the line, it is an un-aligned scope.
+ if (!("align" in lexical))
+ lexical.align = false;
+ // Newline tokens get a lexical context associated with them,
+ // which is used for indentation.
+ token.lexicalContext = lexical;
+ }
+ // No more processing for meaningless tokens.
+ if (token.type == "whitespace" || token.type == "newline" || token.type == "comment")
+ return token;
+ // When a meaningful token is found and the lexical scope's
+ // align is undefined, it is an aligned scope.
+ if (!("align" in lexical))
+ lexical.align = true;
+
+ // Execute actions until one 'consumes' the token and we can
+ // return it. Marked is used to
+ while(true){
+ consume = marked = false;
+ // Take and execute the topmost action.
+ cc.pop()(token.type, token.name);
+ if (consume){
+ // Marked is used to change the style of the current token.
+ if (marked)
+ token.style = marked;
+ // Here we differentiate between local and global variables.
+ else if (token.type == "variable" && inScope(token.name))
+ token.style = "localvariable";
+ return token;
+ }
+ }
+ }
+
+ // This makes a copy of the parser state. It stores all the
+ // stateful variables in a closure, and returns a function that
+ // will restore them when called with a new input stream. Note
+ // that the cc array has to be copied, because it is contantly
+ // being modified. Lexical objects are not mutated, and context
+ // objects are not mutated in a harmful way, so they can be shared
+ // between runs of the parser.
+ function copy(){
+ var _context = context, _lexical = lexical, _cc = cc.concat([]), _regexp = tokens.regexp, _comment = tokens.inComment;
+
+ return function(input){
+ context = _context;
+ lexical = _lexical;
+ cc = _cc.concat([]); // copies the array
+ column = indented = 0;
+ tokens = tokenizeJavaScript(input);
+ tokens.regexp = _regexp;
+ tokens.inComment = _comment;
+ return parser;
+ };
+ }
+
+ // Helper function for pushing a number of actions onto the cc
+ // stack in reverse order.
+ function push(fs){
+ for (var i = fs.length - 1; i >= 0; i--)
+ cc.push(fs[i]);
+ }
+ // cont and pass are used by the action functions to add other
+ // actions to the stack. cont will cause the current token to be
+ // consumed, pass will leave it for the next action.
+ function cont(){
+ push(arguments);
+ consume = true;
+ }
+ function pass(){
+ push(arguments);
+ consume = false;
+ }
+ // Used to change the style of the current token.
+ function mark(style){
+ marked = style;
+ }
+
+ // Push a new scope. Will automatically link the the current
+ // scope.
+ function pushcontext(){
+ context = {prev: context, vars: {"this": true, "arguments": true}};
+ }
+ // Pop off the current scope.
+ function popcontext(){
+ context = context.prev;
+ }
+ // Register a variable in the current scope.
+ function register(varname){
+ if (context){
+ mark("variabledef");
+ context.vars[varname] = true;
+ }
+ }
+ // Check whether a variable is defined in the current scope.
+ function inScope(varname){
+ var cursor = context;
+ while (cursor) {
+ if (cursor.vars[varname])
+ return true;
+ cursor = cursor.prev;
+ }
+ return false;
+ }
+
+ // Push a new lexical context of the given type.
+ function pushlex(type){
+ var result = function(){
+ lexical = new JSLexical(indented, column, type, null, lexical)
+ };
+ result.lex = true;
+ return result;
+ }
+ // Pop off the current lexical context.
+ function poplex(){
+ lexical = lexical.prev;
+ }
+ poplex.lex = true;
+ // The 'lex' flag on these actions is used by the 'next' function
+ // to know they can (and have to) be ran before moving on to the
+ // next token.
+
+ // Creates an action that discards tokens until it finds one of
+ // the given type.
+ function expect(wanted){
+ return function(type){
+ if (type == wanted) cont();
+ else cont(arguments.callee);
+ };
+ }
+
+ // Looks for a statement, and then calls itself.
+ function statements(type){
+ return pass(statement, statements);
+ }
+ // Dispatches various types of statements based on the type of the
+ // current token.
+ function statement(type){
+ if (type == "var") cont(pushlex("vardef"), vardef1, expect(";"), poplex);
+ else if (type == "keyword a") cont(pushlex("stat"), expression, statement, poplex);
+ else if (type == "keyword b") cont(pushlex("stat"), statement, poplex);
+ else if (type == "{") cont(pushlex("}"), block, poplex);
+ else if (type == "function") cont(functiondef);
+ else if (type == "for") cont(pushlex("stat"), expect("("), pushlex(")"), forspec1, expect(")"), poplex, statement, poplex);
+ else if (type == "case") cont(expression, expect(":"));
+ else if (type == "variable") cont(pushlex("stat"), maybelabel);
+ else if (type == "catch") cont(pushlex("stat"), pushcontext, expect("("), funarg, expect(")"), statement, poplex, popcontext);
+ else pass(pushlex("stat"), expression, expect(";"), poplex);
+ }
+ // Dispatch expression types.
+ function expression(type){
+ if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
+ else if (type == "function") cont(functiondef);
+ else if (type == "keyword c") cont(expression);
+ else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex);
+ else if (type == "operator") cont(expression);
+ else if (type == "[") cont(pushlex("]"), commasep(expression), expect("]"), poplex);
+ else if (type == "{") cont(pushlex("}"), commasep(objprop), expect("}"), poplex);
+ }
+ // Called for places where operators, function calls, or
+ // subscripts are valid. Will skip on to the next action if none
+ // is found.
+ function maybeoperator(type){
+ if (type == "operator") cont(expression);
+ else if (type == "(") cont(pushlex(")"), expression, commasep(expression), expect(")"), poplex);
+ else if (type == ".") cont(property, maybeoperator);
+ else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex);
+ }
+ // When a statement starts with a variable name, it might be a
+ // label. If no colon follows, it's a regular statement.
+ function maybelabel(type){
+ if (type == ":") cont(poplex, statement);
+ else pass(maybeoperator, expect(";"), poplex);
+ }
+ // Property names need to have their style adjusted -- the
+ // tokenizer think they are variables.
+ function property(type){
+ if (type == "variable") {mark("property"); cont();}
+ }
+ // This parses a property and its value in an object literal.
+ function objprop(type){
+ if (type == "variable") mark("property");
+ if (atomicTypes.hasOwnProperty(type)) cont(expect(":"), expression);
+ }
+ // Parses a comma-separated list of the things that are recognized
+ // by the 'what' argument.
+ function commasep(what){
+ function proceed(type) {
+ if (type == ",") cont(what, proceed);
+ };
+ return function() {
+ pass(what, proceed);
+ };
+ }
+ // Look for statements until a closing brace is found.
+ function block(type){
+ if (type == "}") cont();
+ else pass(statement, block);
+ }
+ // Variable definitions are split into two actions -- 1 looks for
+ // a name or the end of the definition, 2 looks for an '=' sign or
+ // a comma.
+ function vardef1(type, value){
+ if (type == "variable"){register(value); cont(vardef2);}
+ else cont();
+ }
+ function vardef2(type){
+ if (type == "operator") cont(expression, vardef2);
+ else if (type == ",") cont(vardef1);
+ }
+ // For loops.
+ function forspec1(type, value){
+ if (type == "var") cont(vardef1, forspec2);
+ else cont(expression, forspec2);
+ }
+ function forspec2(type){
+ if (type == ",") cont(forspec1);
+ if (type == ";") cont(expression, expect(";"), expression);
+ }
+ // A function definition creates a new context, and the variables
+ // in its argument list have to be added to this context.
+ function functiondef(type, value){
+ if (type == "variable"){register(value); cont(functiondef);}
+ else if (type == "(") cont(pushcontext, commasep(funarg), expect(")"), statement, popcontext);
+ }
+ function funarg(type, value){
+ if (type == "variable"){register(value); cont();}
+ }
+
+ return parser;
+ }
+}();
--- /dev/null
+/* TypoScript parser
+ *
+ * based on parsejavascript.js by Marijn Haverbeke
+ *
+ * A parser that can be plugged into the CodeMirror system has to
+ * implement the following interface: It is a function that, when
+ * called with a string stream (stringstream.js) as an argument,
+ * returns a MochiKit-style iterator (object with a 'next' method).
+ * This iterator, when called, consumes some input from the string
+ * stream, and returns a token object. Token objects must have a
+ * 'value' property (the text they represent), a 'style' property (the
+ * CSS style that should be used to colour them). Tokens for newline
+ * characters must also have a 'lexicalContext' property, which has an
+ * 'indentation' method that can be used to determine the proper
+ * indentation level for the next line. This method optionally takes
+ * the first character of the next line as an argument, which it can
+ * use to adjust the indentation level.
+ *
+ * So far this should be easy. The hard part is that the iterator
+ * produced by the parse function must also have a 'copy' method. This
+ * method, called without arguments, returns a function representing
+ * the current state of the parser. When this function is later called
+ * with a string stream as its argument, it returns a parser iterator
+ * object that resumes parsing using the old state and the new input
+ * stream. It may assume that only one parser is active at a time, and
+ * clobber the state of the old parser (the implementation below
+ * certianly does).
+ */
+
+// Parse function for TypoScript. Makes use of the tokenizer from
+// tokenizetyposcript.js. Note that your parsers do not have to be
+// this complicated -- if you don't want to recognize local variables,
+// in many languages it is enough to just look for braces, semicolons,
+// parentheses, etc, and know when you are inside a string or comment.
+var parseTypoScript = function() {
+ // Token types that can be considered to be atoms.
+ var atomicTypes = setObject("atom", "number", "variable", "string", "regexp");
+
+ // Constructor for the lexical context objects.
+ function TSLexical(indented, column, type, align, prev) {
+ // indentation at start of this line
+ this.indented = indented;
+ // column at which this scope was opened
+ this.column = column;
+ // type of scope ('vardef', 'stat' (statement), '[', '{', or '(')
+ this.type = type;
+ // '[', '{', or '(' blocks that have any text after their opening
+ // character are said to be 'aligned' -- any lines below are
+ // indented all the way to the opening character.
+ if (align != null)
+ this.align = align;
+ // Parent scope, if any.
+ this.prev = prev;
+ }
+ // My favourite indentation rules.
+ TSLexical.prototype.indentation = function(firstChar) {
+ var closing = firstChar == this.type;
+ if (this.type == "}")
+ return this.indented + 2;
+
+ else if (this.align)
+ return this.column - (closing ? 1 : 0);
+ else
+ return this.indented + (closing ? 0 : 2);
+ }
+
+ // The parser-iterator-producing function itself.
+ return function(input){
+ // Wrap the input in a token stream
+ var tokens = tokenizeTypoScript(input);
+ // The parser state. cc is a stack of actions that have to be
+ // performed to finish the current statement. For example we might
+ // know that we still need to find a closing parenthesis and a
+ // semicolon. Actions at the end of the stack go first. It is
+ // initialized with an infinitely looping action that consumes
+ // whole statements.
+ var cc = [statements];
+ // Context contains information about the current local scope, the
+ // variables defined in that, and the scopes above it.
+ var context = null;
+ // The lexical scope, used mostly for indentation.
+ var lexical = new TSLexical(-2, 0, "block", false);
+ // Current column, and the indentation at the start of the current
+ // line. Used to create lexical scope objects.
+ var column = 0;
+ var indented = 0;
+ // Variables which are used by the mark, cont, and pass functions
+ // below to communicate with the driver loop in the 'next'
+ // function.
+ var consume, marked;
+
+ // The iterator object.
+ var parser = {next: next, copy: copy};
+
+ function next(){
+ // Start by performing any 'lexical' actions (adjusting the
+ // lexical variable), or the operations below will be working
+ // with the wrong lexical state.
+ while(cc[cc.length - 1].lex)
+ cc.pop()();
+
+ // Fetch a token.
+ var token = tokens.next();
+ // Adjust column and indented.
+ if (token.type == "whitespace" && column == 0)
+ indented = token.value.length;
+ column += token.value.length;
+ if (token.type == "newline"){
+ indented = column = 0;
+ // If the lexical scope's align property is still undefined at
+ // the end of the line, it is an un-aligned scope.
+ if (!("align" in lexical))
+ lexical.align = false;
+ // Newline tokens get a lexical context associated with them,
+ // which is used for indentation.
+ token.lexicalContext = lexical;
+ }
+ // No more processing for meaningless tokens.
+ if (token.type == "whitespace" || token.type == "newline" || token.type == "comment")
+ return token;
+ // When a meaningful token is found and the lexical scope's
+ // align is undefined, it is an aligned scope.
+ if (!("align" in lexical))
+ lexical.align = true;
+
+ // Execute actions until one 'consumes' the token and we can
+ // return it. Marked is used to
+ while(true){
+ consume = marked = false;
+ // Take and execute the topmost action.
+ cc.pop()(token.type, token.name);
+ if (consume){
+ // Marked is used to change the style of the current token.
+ if (marked)
+ token.style = marked;
+
+ return token;
+ }
+ }
+ }
+
+ // This makes a copy of the parser state. It stores all the
+ // stateful variables in a closure, and returns a function that
+ // will restore them when called with a new input stream. Note
+ // that the cc array has to be copied, because it is contantly
+ // being modified. Lexical objects are not mutated, and context
+ // objects are not mutated in a harmful way, so they can be shared
+ // between runs of the parser.
+ function copy(){
+ var _context = context, _lexical = lexical, _cc = cc.concat([]), _regexp = tokens.regexp, _comment = tokens.inComment;
+
+ return function(input){
+ context = _context;
+ lexical = _lexical;
+ cc = _cc.concat([]); // copies the array
+ column = indented = 0;
+ tokens = tokenizeTypoScript(input);
+ tokens.regexp = _regexp;
+ tokens.inComment = _comment;
+ return parser;
+ };
+ }
+
+ // Helper function for pushing a number of actions onto the cc
+ // stack in reverse order.
+ function push(fs){
+ for (var i = fs.length - 1; i >= 0; i--)
+ cc.push(fs[i]);
+ }
+ // cont and pass are used by the action functions to add other
+ // actions to the stack. cont will cause the current token to be
+ // consumed, pass will leave it for the next action.
+ function cont(){
+ push(arguments);
+ consume = true;
+ }
+ function pass(){
+ push(arguments);
+ consume = false;
+ }
+ // Used to change the style of the current token.
+ function mark(style){
+ marked = style;
+ }
+
+ // Push a new scope. Will automatically link the the current
+ // scope.
+ function pushcontext(){
+ context = {prev: context, vars: {"this": true, "arguments": true}};
+ }
+ // Pop off the current scope.
+ function popcontext(){
+ context = context.prev;
+ }
+ // Register a variable in the current scope.
+ function register(varname){
+ if (context){
+ mark("variabledef");
+ context.vars[varname] = true;
+ }
+ }
+
+
+ // Push a new lexical context of the given type.
+ function pushlex(type){
+ var result = function(){
+ lexical = new TSLexical(indented, column, type, null, lexical)
+ };
+ result.lex = true;
+ return result;
+ }
+ // Pop off the current lexical context.
+ function poplex(){
+ lexical = lexical.prev;
+ }
+ poplex.lex = true;
+ // The 'lex' flag on these actions is used by the 'next' function
+ // to know they can (and have to) be ran before moving on to the
+ // next token.
+
+ // Creates an action that discards tokens until it finds one of
+ // the given type.
+ function expect(wanted){
+ return function(type){
+ if (type == wanted) cont();
+ else cont(arguments.callee);
+ };
+ }
+
+ // Looks for a statement, and then calls itself.
+ function statements(type){
+ return pass(statement, statements);
+ }
+ // Dispatches various types of statements based on the type of the
+ // current token.
+ function statement(type){
+ if (type == "{") cont(pushlex("{"), block, poplex);
+ // else if (type == "[") cont(pushlex("]"), condition, poplex);
+ else cont();
+ }
+
+ // Dispatch expression types.
+ function expression(type){
+ if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
+ else if (type == "function") cont(functiondef);
+ else if (type == "keyword c") cont(expression);
+ else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex);
+ else if (type == "operator") cont(expression);
+ else if (type == "[") cont(pushlex("]"), commasep(expression), expect("]"), poplex);
+ else if (type == "{") cont(pushlex("}"), commasep(objprop), expect("}"), poplex);
+ }
+ // Called for places where operators, function calls, or
+ // subscripts are valid. Will skip on to the next action if none
+ // is found.
+ function maybeoperator(type){
+ if (type == "operator") cont(expression);
+ else if (type == "(") cont(pushlex(")"), expression, commasep(expression), expect(")"), poplex);
+ else if (type == ".") cont(property, maybeoperator);
+ else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex);
+ }
+ // When a statement starts with a variable name, it might be a
+ // label. If no colon follows, it's a regular statement.
+ function maybelabel(type){
+ if (type == ":") cont(poplex, statement);
+ else pass(maybeoperator, expect(";"), poplex);
+ }
+ // Property names need to have their style adjusted -- the
+ // tokenizer think they are variables.
+ function property(type){
+ if (type == "variable") {mark("property"); cont();}
+ }
+ // This parses a property and its value in an object literal.
+ function objprop(type){
+ if (type == "variable") mark("property");
+ if (atomicTypes.hasOwnProperty(type)) cont(expect(":"), expression);
+ }
+ // Parses a comma-separated list of the things that are recognized
+ // by the 'what' argument.
+ function commasep(what){
+ function proceed(type) {
+ if (type == ",") cont(what, proceed);
+ };
+ return function() {
+ pass(what, proceed);
+ };
+ }
+
+ // Look for statements until a closing brace is found.
+ function block(type){
+ if (type == "}") cont();
+ else pass(statement, block);
+ }
+
+ // Look for statements until a closing brace is found.
+ function condition(type){
+ if (type == "]") cont();
+ else pass(statement, block);
+ }
+
+
+ // Variable definitions are split into two actions -- 1 looks for
+ // a name or the end of the definition, 2 looks for an '=' sign or
+ // a comma.
+ function vardef1(type, value){
+ if (type == "variable"){register(value); cont(vardef2);}
+ else cont();
+ }
+ function vardef2(type){
+ if (type == "operator") cont(expression, vardef2);
+ else if (type == ",") cont(vardef1);
+ }
+ // For loops.
+ function forspec1(type, value){
+ if (type == "var") cont(vardef1, forspec2);
+ else cont(expression, forspec2);
+ }
+ function forspec2(type){
+ if (type == ",") cont(forspec1);
+ if (type == ";") cont(expression, expect(";"), expression);
+ }
+ // A function definition creates a new context, and the variables
+ // in its argument list have to be added to this context.
+ function functiondef(type, value){
+ if (type == "variable"){register(value); cont(functiondef);}
+ else if (type == "(") cont(pushcontext, commasep(funarg), expect(")"), statement, popcontext);
+ }
+ function funarg(type, value){
+ if (type == "variable"){register(value); cont();}
+ }
+
+ return parser;
+ }
+}();
--- /dev/null
+/* Functionality for finding, storing, and re-storing selections
+ *
+ * This does not provide a generic API, just the minimal functionality
+ * required by the CodeMirror system.
+ */
+
+// Namespace object.
+var select = {};
+
+(function() {
+ var ie_selection = document.selection && document.selection.createRangeCollection;
+
+ // Find the 'top-level' (defined as 'a direct child of the node
+ // passed as the top argument') node that the given node is
+ // contained in. Return null if the given node is not inside the top
+ // node.
+ function topLevelNodeAt(node, top) {
+ while (node && node.parentNode != top)
+ node = node.parentNode;
+ return node;
+ }
+
+ // Find the top-level node that contains the node before this one.
+ function topLevelNodeBefore(node, top) {
+ if (!node){
+ return null;
+ }
+ while (!node.previousSibling && node.parentNode != top){
+ node = node.parentNode;
+ }
+
+ return topLevelNodeAt(node.previousSibling, top);
+ }
+
+ // Most functions are defined in two ways, one for the IE selection
+ // model, one for the W3C one.
+ if (ie_selection) {
+ // Store the current selection in such a way that it can be
+ // restored after we manipulated the DOM tree. For IE, we store
+ // pixel coordinates.
+ select.markSelection = function (win) {
+ var selection = win.document.selection;
+ var start = selection.createRange(), end = start.duplicate();
+ start.collapse(true);
+ end.collapse(false);
+
+ var body = win.document.body;
+ // And we better hope no fool gave this window a padding or a
+ // margin, or all these computations will be in vain.
+ return {start: {x: start.boundingLeft + body.scrollLeft - 1,
+ y: start.boundingTop + body.scrollTop},
+ end: {x: end.boundingLeft + body.scrollLeft - 1,
+ y: end.boundingTop + body.scrollTop},
+ window: win};
+ };
+
+ // Restore a stored selection.
+ select.selectMarked = function(sel) {
+ if (!sel)
+ return;
+ var range1 = sel.window.document.body.createTextRange(), range2 = range1.duplicate();
+ range1.moveToPoint(sel.start.x, sel.start.y);
+ range2.moveToPoint(sel.end.x, sel.end.y);
+ range1.setEndPoint("EndToStart", range2);
+ range1.select();
+ };
+
+ // Not needed in IE model -- see W3C model.
+ select.replaceSelection = function(){};
+
+ // A Cursor object represents a top-level node that the cursor is
+ // currently in or after. It is not possible to reliably get more
+ // detailed information, but just this node is enough for most
+ // purposes.
+ select.Cursor = function(container) {
+ this.container = container;
+ this.doc = container.ownerDocument;
+ var selection = this.doc.selection;
+ this.valid = !!selection;
+ if (this.valid) {
+ var range = selection.createRange();
+ range.collapse(false);
+ var around = range.parentElement();
+ if (around && isAncestor(container, around)) {
+ this.start = topLevelNodeAt(around, container);
+ }
+ else {
+ range.pasteHTML("<span id='// temp //'></span>");
+ var temp = this.doc.getElementById("// temp //");
+ this.start = topLevelNodeBefore(temp, container);
+ if (temp)
+ removeElement(temp);
+ }
+ }
+ };
+
+ // Place the cursor after this.start. This is only useful when
+ // manually moving the cursor instead of restoring it to its old
+ // position.
+ select.Cursor.prototype.focus = function () {
+ var range = this.doc.body.createTextRange();
+ range.moveToElementText(this.start || this.container);
+ range.collapse(!this.start);
+ range.select();
+ };
+
+
+ // Used to normalize the effect of the enter key, since browsers
+ // do widely different things when pressing enter in designMode.
+ select.insertNewlineAtCursor = function(window) {
+ var selection = window.document.selection;
+ if (selection) {
+ var range = selection.createRange();
+ range.pasteHTML("<br/>");
+ range.collapse(false);
+ range.select();
+ }
+ };
+
+ // Insert a custom string at current cursor position (added for t3editor)
+ select.insertTextAtCursor = function(window,text) {
+ var selection = window.document.selection;
+ if (selection) {
+ var range = selection.createRange();
+ range.pasteHTML(text);
+ range.collapse(false);
+ range.select();
+ }
+ };
+
+ }
+ // W3C model
+ else {
+ // Well, Opera isn't even supported at the moment, but it almost
+ // is, and this is used to fix an issue with getting the scroll
+ // position.
+ var opera_scroll = !window.scrollX && !window.scrollY;
+
+ // Store start and end nodes, and offsets within these, and refer
+ // back to the selection object from those nodes, so that this
+ // object can be updated when the nodes are replaced before the
+ // selection is restored.
+ select.markSelection = function (win) {
+ var selection = win.getSelection();
+ if (!selection || selection.rangeCount == 0)
+ return null;
+ var range = selection.getRangeAt(0);
+
+ var result = {start: {node: range.startContainer, offset: range.startOffset},
+ end: {node: range.endContainer, offset: range.endOffset},
+ window: win,
+ scrollX: opera_scroll && win.document.body.scrollLeft,
+ scrollY: opera_scroll && win.document.body.scrollTop};
+
+ // We want the nodes right at the cursor, not one of their
+ // ancestors with a suitable offset. This goes down the DOM tree
+ // until a 'leaf' is reached (or is it *up* the DOM tree?).
+ function normalize(point){
+ while (point.node.nodeType != 3 && point.node.nodeName != "BR") {
+ var newNode = point.node.childNodes[point.offset] || point.node.nextSibling;
+ point.offset = 0;
+ while (!newNode && point.node.parentNode) {
+ point.node = point.node.parentNode;
+ newNode = point.node.nextSibling;
+ }
+ point.node = newNode;
+ if (!newNode)
+ break;
+ }
+ }
+
+ normalize(result.start);
+ normalize(result.end);
+ // Make the links back to the selection object (see
+ // replaceSelection).
+ if (result.start.node)
+ result.start.node.selectStart = result.start;
+ if (result.end.node)
+ result.end.node.selectEnd = result.end;
+
+ return result;
+ };
+
+ // Helper for selecting a range object.
+ function selectRange(range, window) {
+ var selection = window.getSelection();
+ selection.removeAllRanges();
+ selection.addRange(range);
+ };
+
+ select.selectMarked = function (sel) {
+ if (!sel)
+ return;
+ var win = sel.window;
+ var range = win.document.createRange();
+
+ function setPoint(point, which) {
+ if (point.node) {
+ // Remove the link back to the selection.
+ delete point.node["select" + which];
+ // Some magic to generalize the setting of the start and end
+ // of a range.
+ if (point.offset == 0)
+ range["set" + which + "Before"](point.node);
+ else
+ range["set" + which](point.node, point.offset);
+ }
+ else {
+ range.setStartAfter(win.document.body.lastChild || win.document.body);
+ }
+ }
+
+ // Have to restore the scroll position of the frame in Opera.
+ if (opera_scroll){
+ sel.window.document.body.scrollLeft = sel.scrollX;
+ sel.window.document.body.scrollTop = sel.scrollY;
+ }
+ try {
+ setPoint(sel.start, "Start");
+ setPoint(sel.end, "End");
+ selectRange(range, win);
+ } catch(e) {}
+ };
+
+ // This is called by the code in codemirror.js whenever it is
+ // replacing a part of the DOM tree. The function sees whether the
+ // given oldNode is part of the current selection, and updates
+ // this selection if it is. Because nodes are often only partially
+ // replaced, the length of the part that gets replaced has to be
+ // taken into account -- the selection might stay in the oldNode
+ // if the newNode is smaller than the selection's offset. The
+ // offset argument is needed in case the selection does move to
+ // the new object, and the given length is not the whole length of
+ // the new node (part of it might have been used to replace
+ // another node).
+ select.replaceSelection = function(oldNode, newNode, length, offset) {
+ function replace(which) {
+ var selObj = oldNode["select" + which];
+ if (selObj) {
+ if (selObj.offset > length) {
+ selObj.offset -= length;
+ }
+ else {
+ newNode["select" + which] = selObj;
+ delete oldNode["select" + which];
+ selObj.node = newNode;
+ selObj.offset += (offset || 0);
+ }
+ }
+ }
+ replace("Start");
+ replace("End");
+ };
+
+ // Finding the top-level node at the cursor in the W3C is, as you
+ // can see, quite an involved process. [Some of this can probably
+ // be simplified, but I'm afraid to touch it now that it finally
+ // works.]
+ select.Cursor = function(container) {
+ this.container = container;
+ this.win = container.ownerDocument.defaultView;
+ var selection = this.win.getSelection();
+ this.valid = selection && selection.rangeCount > 0;
+ if (this.valid) {
+ var range = selection.getRangeAt(0);
+ var end = range.endContainer;
+ // For text nodes, we look at the node itself if the cursor is
+ // inside, or at the node before it if the cursor is at the
+ // start.
+
+ if (end.nodeType == 3){
+ if (range.endOffset > 0)
+ this.start = topLevelNodeAt(end, this.container);
+ else
+ this.start = topLevelNodeBefore(end, this.container);
+ }
+ // Occasionally, browsers will return the HTML node as
+ // selection (Opera does this all the time, which is the
+ // reason this editor does not work on that browser). If the
+ // offset is 0, we take the start of the frame ('after null'),
+ // otherwise, we take the last node.
+ else if (end.nodeName == "HTML") {
+ this.start = (range.endOffset == 1 ? null : container.lastChild);
+ }
+ // If the given node is our 'container', we just look up the
+ // correct node by using the offset.
+ else if (end == container) {
+ if (range.endOffset == 0)
+ this.start = null;
+ else
+ this.start = end.childNodes[range.endOffset - 1];
+ }
+ // In any other case, we have a regular node. If the cursor is
+ // at the end of the node, we use the node itself, if it is at
+ // the start, we use the node before it, and in any other
+ // case, we look up the child before the cursor and use that.
+ else {
+ if (range.endOffset == end.childNodes.length)
+ this.start = topLevelNodeAt(end, this.container);
+ else if (range.endOffset == 0)
+ this.start = topLevelNodeBefore(end, this.container);
+ else
+ this.start = topLevelNodeAt(end.childNodes[range.endOffset - 1], this.container);
+ }
+ }
+ };
+
+ select.Cursor.prototype.focus = function() {
+ var sel = this.win.getSelection();
+ var range = this.win.document.createRange();
+ range.setStartBefore(this.container.firstChild || this.container);
+ if (this.start)
+ range.setEndAfter(this.start);
+ else
+ range.setEndBefore(this.container.firstChild || this.container);
+
+ range.collapse(false);
+ selectRange(range, this.win);
+ };
+
+
+
+ select.insertNewlineAtCursor = function(window) {
+ var selection = window.getSelection();
+ if (selection && selection.rangeCount > 0) {
+ var range = selection.getRangeAt(0);
+ var br = withDocument(window.document, BR);
+ range.insertNode(br);
+ range.setEndAfter(br);
+ range.collapse(false);
+ selectRange(range, window);
+ }
+ };
+
+ // added for t3editor
+ select.insertTextAtCursor = function(window,text) {
+ var selection = window.getSelection();
+ if (selection && selection.rangeCount > 0) {
+ var range = selection.getRangeAt(0);
+ // var br = withDocument(window.document, BR);
+ textnode = window.document.createTextNode(text);
+ range.insertNode(textnode);
+ range.setEndAfter(textnode);
+ range.collapse(false);
+ selectRange(range, window);
+ }
+ };
+ }
+
+ // Search backwards through the top-level nodes until the next BR or
+ // the start of the frame.
+ select.Cursor.prototype.startOfLine = function() {
+ var start = this.start || this.container.firstChild;
+ while (start && start.nodeName != "BR")
+ start = start.previousSibling;
+ return start;
+ };
+}());
--- /dev/null
+/* String streams are the things fed to parsers (which can feed them
+ * to a tokenizer if they want). They provide peek and next methods
+ * for looking at the current character (next 'consumes' this
+ * character, peek does not), and a get method for retrieving all the
+ * text that was consumed since the last time get was called.
+ */
+
+// Make a stream out of a single string. Not used by the editor, but
+// very useful for testing your parser.
+function singleStringStream(string) {
+ var pos = 0, start = 0;
+
+ function peek() {
+ if (pos < string.length)
+ return string.charAt(pos);
+ else
+ return null;
+ }
+
+ function next() {
+ if (pos >= string.length)
+ throw StopIteration;
+ return string.charAt(pos++);
+ }
+
+ function get() {
+ var result = string.slice(start, pos);
+ start = pos;
+ return result;
+ }
+
+ return {peek: peek, next: next, get: get};
+}
+
+// Make a string stream out of an iterator that returns strings. This
+// is applied to the result of traverseDOM (see codemirror.js), and
+// the resulting stream is fed to the parser.
+function multiStringStream(source){
+ source = iter(source);
+ var current = "", pos = 0;
+ var peeked = null, accum = "";
+ var result = {peek: peek, next: next, get: get};
+
+ function peek(){
+ if (!peeked)
+ peeked = nextOr(result, null);
+ return peeked;
+ }
+ function next(){
+ if (peeked){
+ var temp = peeked;
+ peeked = null;
+ return temp;
+ }
+ while (pos == current.length){
+ accum += current;
+ current = ""; // In case source.next() throws
+ pos = 0;
+ current = source.next();
+ }
+ return current.charAt(pos++);
+ }
+ function get(){
+ var temp = accum;
+ var realPos = peeked ? pos - 1 : pos;
+ accum = "";
+ if (realPos > 0){
+ temp += current.slice(0, realPos);
+ current = current.slice(realPos);
+ pos = peeked ? 1 : 0;
+ }
+ return temp;
+ }
+
+ return result;
+}
--- /dev/null
+/***************************************************************
+* Copyright notice
+*
+* (c) 2007 Tobias Liebig <mail_typo3@etobi.de>
+* All rights reserved
+*
+* This script is part of the TYPO3 project. The TYPO3 project is
+* free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* The GNU General Public License can be found at
+* http://www.gnu.org/copyleft/gpl.html.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* This script is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/* t3editor.js is based on codemirror.js from the Codemirror editor.
+ * See LICENSE file for further informations
+ */
+
+
+
+/**
+ * Browser checks
+ * inspired by tinyMCE
+ */
+var ua = navigator.userAgent;
+var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
+var isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1);
+var isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);
+var isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1);
+var isGecko = ua.indexOf('Gecko') != -1; // Will also be true on Safari
+var isSafari = ua.indexOf('Safari') != -1;
+var isOpera = window['opera'] && opera.buildNumber ? true : false;
+var isMac = ua.indexOf('Mac') != -1;
+var isNS7 = ua.indexOf('Netscape/7') != -1;
+var isNS71 = ua.indexOf('Netscape/7.1') != -1;
+
+
+
+// collection of all t3editor instances on the current page
+var t3e_instances = {};
+
+
+
+/* CodeMirror main module
+ *
+ * Implements the CodeMirror constructor and prototype, which take care
+ * of initializing the editor and managing the highlighting and
+ * indentation, and some functions for transforming arbitrary DOM
+ * structures into plain sequences of <span> and <br> elements.
+ */
+
+// The MirrorOptions object is used to specify a default
+// configuration. If you specify such an object before loading this
+// file, the values you put into it will override the defaults given
+// below.
+var t3eOptions = window.t3eOptions || {};
+
+// safeKeys specifies the set of keys that will probably not modify
+// the content of the editor, and thus do not have to be responded to.
+// You usually won't have to change this.
+// reindentKeys gives the keys that should cause the editor to
+// re-indent the current line
+// reindentAfterKeys works like reindentKeys, but in this case the
+// key's normal effect is first allowed to take place. Use this for
+// keys that might change the indentation level of the current line.
+// stylesheet is the filename of the stylesheet that should be used to
+// colour the code in the editor.
+// parser should refer to a function that, when given a string stream
+// (see stringstream.js), produces an object that acts as a stream of
+// tokens plus some other functionality. See parsejavascript.js for an
+// example and more information.
+// linesPerPass is the maximum amount of lines that the highlighter
+// tries to colour in one shot. Setting this too high will cause the
+// code to 'freeze' the browser for noticeable intervals.
+// passDelay gives the amount of milliseconds between colouring passes
+setdefault(t3eOptions,
+ {safeKeys: setObject("KEY_ARROW_UP", "KEY_ARROW_DOWN", "KEY_ARROW_LEFT", "KEY_ARROW_RIGHT", "KEY_END", "KEY_HOME",
+ "KEY_PAGE_UP", "KEY_PAGE_DOWN", "KEY_SHIFT", "KEY_CTRL", "KEY_ALT", "KEY_SELECT"),
+ reindentKeys: setObject("KEY_TAB"),
+ reindentAfterKeys: setObject("KEY_RIGHT_SQUARE_BRACKET"),
+ stylesheet: PATH_t3e+"css/t3editor.css",
+ parser: parseTypoScript,
+ linesPerPass: 10,
+ passDelay: 500,
+ autoComplete: true,
+ acWords:5});
+// These default options can be overridden by passing a set of options
+// to a specific CodeMirror constructor.
+
+var t3editor = function(){
+ // The HTML elements whose content should be suffixed by a newline
+ // when converting them to flat text.
+ var newlineElements = setObject("P", "DIV", "LI");
+
+ // Helper function for traverseDOM. Flattens an arbitrary DOM node
+ // into an array of textnodes and <br> tags.
+ function simplifyDOM(root) {
+ var doc = root.ownerDocument;
+ var result = [];
+ var leaving = false;
+
+ function simplifyNode(node) {
+ leaving = false;
+
+ if (node.nodeType == 3) {
+ node.nodeValue = node.nodeValue.replace(/[\n\r]/g, "").replace(/[\t ]/g, nbsp);
+ result.push(node);
+ }
+ else if (node.nodeName == "BR" && node.childNodes.length == 0) {
+ result.push(node);
+ }
+ else {
+ forEach(node.childNodes, simplifyNode);
+ if (!leaving && newlineElements.hasOwnProperty(node.nodeName)) {
+ leaving = true;
+ el = withDocument(doc, SPAN);
+ result.push(withDocument(doc, BR));
+ }
+ }
+ }
+
+ simplifyNode(root);
+ return result;
+ }
+
+ // Creates a MochiKit-style iterator that goes over a series of DOM
+ // nodes. The values it yields are strings, the textual content of
+ // the nodes. It makes sure that all nodes up to and including the
+ // one whose text is being yielded have been 'normalized' to be just
+ // <span> and <br> elements.
+ // See the story.html file for some short remarks about the use of
+ // continuation-passing style in this iterator.
+ function traverseDOM(start){
+ function yield(value, c){cc = c; return value;}
+ function push(fun, arg, c){return function(){return fun(arg, c);};}
+ function stop(){cc = stop; throw StopIteration;};
+ var cc = push(scanNode, start, stop);
+ var owner = start.ownerDocument;
+
+ // Create a function that can be used to insert nodes after the
+ // one given as argument.
+ function pointAt(node){
+ var parent = node.parentNode;
+ var next = node.nextSibling;
+ if (next)
+ return function(newnode){parent.insertBefore(newnode, next);};
+ else
+ return function(newnode){parent.appendChild(newnode);};
+ }
+ var point = null;
+
+ // Insert a normalized node at the current point. If it is a text
+ // node, wrap it in a <span>, and give that span a currentText
+ // property -- this is used to cache the nodeValue, because
+ // directly accessing nodeValue is horribly slow on some browsers.
+ // The dirty property is used by the highlighter to determine
+ // which parts of the document have to be re-highlighted.
+ function insertPart(part){
+ var text = "\n";
+ if (part.nodeType == 3) {
+ text = part.nodeValue;
+ part = withDocument(owner, partial(SPAN, {"class": "part"}, part));
+ part.currentText = text;
+ }
+ part.dirty = true;
+ point(part);
+ return text;
+ }
+
+ // Extract the text and newlines from a DOM node, insert them into
+ // the document, and yield the textual content. Used to replace
+ // non-normalized nodes.
+ function writeNode(node, c){
+ var toYield = [];
+ forEach(simplifyDOM(node), function(part) {
+ toYield.push(insertPart(part));
+ });
+ return yield(toYield.join(""), c);
+ }
+
+ // Check whether a node is a normalized <span> element.
+ function partNode(node){
+ if (node.nodeName == "SPAN" && node.childNodes.length == 1 && node.firstChild.nodeType == 3){
+ node.currentText = node.firstChild.nodeValue;
+ return true;
+ }
+ return false;
+ }
+
+ // Handle a node. Add its successor to the continuation if there
+ // is one, find out whether the node is normalized. If it is,
+ // yield its content, otherwise, normalize it (writeNode will take
+ // care of yielding).
+ function scanNode(node, c){
+ if (node.nextSibling)
+ c = push(scanNode, node.nextSibling, c);
+
+ if (partNode(node)){
+ return yield(node.currentText, c);
+ }
+ else if (node.nodeName == "BR") {
+ return yield("\n", c);
+ }
+ else {
+ point = pointAt(node);
+ removeElement(node);
+ return writeNode(node, c);
+ }
+ }
+
+ // MochiKit iterators are objects with a next function that
+ // returns the next value or throws StopIteration when there are
+ // no more values.
+ return {next: function(){return cc();}};
+ } // traverseDOM
+
+ var nbspRegexp = new RegExp(nbsp, "g");
+
+
+
+ function t3editor(theTextarea, index, options) {
+
+ // Use passed options, if any, to override defaults.
+ this.options = options || {}
+ setdefault(this.options, t3eOptions);
+
+ //History Array
+ this.history = [];
+ //Max History Size
+ this.historySize = 100;
+ //Init history position
+ this.currHistoryPosition = -1;
+
+ // memorize the textarea
+ this.textarea = $(theTextarea);
+
+ this.documentname = this.textarea.readAttribute('alt');
+
+ // count index (helpful if more than one editor is on the page)
+ this.index = index;
+
+ // create the wrapping div
+ this.outerdiv = $(createDOM("DIV", {
+ "class": "t3e_outerdiv",
+ "id": "t3e_"+this.textarea.getAttribute('id')
+ }));
+
+ // place the div before the textarea
+ this.textarea.parentNode.insertBefore(this.outerdiv,$(this.textarea));
+
+ // an overlay that covers the whole editor
+ this.modalOverlay = $(createDOM("DIV", {
+ "class": "t3e_modalOverlay",
+ "id": "t3e_modalOverlay_wait"
+ }));
+ this.modalOverlay.hide();
+ this.modalOverlay.setStyle(this.outerdiv.getDimensions());
+ this.modalOverlay.setStyle({opacity: 0.5});
+ this.outerdiv.appendChild(this.modalOverlay);
+
+ this.helpOverlay = $(createDOM("DIV", {
+ "class": "t3e_modalOverlay",
+ "id": "t3e_modalOverlay_help"
+ }));
+ this.helpOverlay.innerHTML = "<h2>t3editor</h2>"+
+ "<p>put some helpful text here</p><br/><br/>"+
+ "<p>Hotkeys:</p>"+
+ "<p>"+
+ "<strong>CTRL-S</strong> send code to server<br/>"+
+ "<strong>CTRL-F11</strong> toggle fullscreen mode<br/>"+
+ "<strong>CTRL-SPACE</strong> auto-complete (based on letters at current cursor-position)<br/>"+
+ "<strong>CTRL-Z</strong> undo<br/>"+
+ "<strong>CTRL-Y</strong> redo<br/>"+
+ "</p><br/>"+
+ "<p><a href='javascript:void(0)' onclick='t3e_instances["+this.index+"].toggleHelp();'>click here to close this help window</a></p>"+
+ "";
+ this.helpOverlay.hide();
+ this.outerdiv.appendChild(this.helpOverlay);
+
+ // wrapping the ilnenumbers
+ this.linenum_wrap = $(createDOM("DIV", {
+ "class": "t3e_linenum_wrap"
+ }));
+ // the "linenumber" list itself
+ this.linenum = $(createDOM("DL", {
+ "class": "t3e_linenum"
+ }));
+ this.linenum_wrap.appendChild(this.linenum);
+ this.outerdiv.appendChild(this.linenum_wrap);
+
+ //autocomplete box
+ this.autoCompleteBox = $(createDOM("DIV",{"class":"t3e_autoCompleteBox"}));
+ this.autoCompleteBox.hide();
+ this.outerdiv.appendChild(this.autoCompleteBox);
+
+ // wrapping the iframe
+ this.iframe_wrap = $(createDOM("DIV", {
+ "class": "t3e_iframe_wrap"
+ }));
+
+ // the iframe (the actual "editor")
+ // display: block occasionally suppresses some Firefox bugs, so we
+ // always add it, redundant as it sounds.
+ this.iframe = $(createDOM("IFRAME", {
+ "style": "border: 0; display: block;",
+ "class": "t3e_iframe"
+ }));
+
+ this.iframe_wrap.appendChild(this.iframe);
+ this.outerdiv.appendChild(this.iframe_wrap);
+
+ // wrapping the footer/statusline
+ this.footer_wrap = $(createDOM("DIV", {
+ "class": "t3e_footer_wrap"
+ }));
+ this.outerdiv.appendChild(this.footer_wrap);
+
+ // this.fitem_resize = this.createFooterItem('#', false);
+ // this.footer_wrap.appendChild(this.fitem_resize);
+
+ // footer item: show help Window
+ // TODO make this more flexible! And get rid of inline css and unsed options!
+ this.fitem_help = this.createFooterItem('Help', true, 'toggleHelp');
+ this.footer_wrap.appendChild(this.fitem_help);
+
+
+ // footer item: options menu
+ this.fitem_options_overlay = $(createDOM("DIV", {
+ "class": "t3e_footer_overlay",
+ "id": "t3e_footer_overlay_options"
+ }));
+
+ // TODO make this more flexible! And get rid of inline css and unsed options!
+ this.fitem_options_overlay.innerHTML = '<ul>'+
+ // '<li style="color:grey"><input type="checkbox" disabled="disabled" /> Syntax highlighting</li>'+
+ '<li><input type="checkbox" onclick="t3e_instances['+this.index+'].fitem_options_overlay.hide();t3e_instances['+this.index+'].toggleAutoComplete();" id="t3e_autocomplete" checked="checked" /><label for="t3e_autocomplete">AutoCompletion</label></li>'+
+ '<li><span onclick="t3e_instances['+this.index+'].fitem_options_overlay.hide();t3e_instances['+this.index+'].footeritem_demo_click();">Test snippets</span></li>'+
+ '<li><input type="checkbox" onclick="t3e_instances['+this.index+'].fitem_options_overlay.hide();t3e_instances['+this.index+'].toggleFullscreen();" id="t3e_fullscreen" /> <label for="t3e_fullscreen">Fullscreen</label></li>'+
+ // '<li style="color:grey"><input type="checkbox" disabled="disabled" /> other fancy stuff</li>'+
+ '</ul>';
+ this.fitem_options_overlay.hide();
+ this.fitem_options = this.createFooterItem('Options', true, this.fitem_options_overlay);
+ this.footer_wrap.appendChild(this.fitem_options);
+ this.footer_wrap.appendChild(this.fitem_options_overlay);
+
+
+ // footer item: status field (total line numbers)
+ this.fitem_status = this.createFooterItem('', false);
+ this.footer_wrap.appendChild(this.fitem_status);
+
+ // footer item: "name" of the document (taken from textarea alt-attribut), and save indicator
+ this.fitem_name = this.createFooterItem(this.documentname, false);
+ this.footer_wrap.appendChild(this.fitem_name);
+
+
+
+ // window and document objects from the iframe
+ this.win = this.iframe.contentWindow;
+ this.doc = this.win.document;
+
+ // make the iframe "editable"
+ this.doc.designMode = "on";
+
+ this.doc.open();
+ this.doc.write("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"" + t3eOptions.stylesheet + "\"/></head>" +
+ "<body class=\"editbox\" spellcheck=\"false\"></body></html>");
+ this.doc.close();
+
+
+ // new Resizable(this.outerdiv,{handle:$(this.fitem_resize)});
+
+ // An array of known dirty nodes, nodes that have been modified
+ // since they were last parsed.
+ this.dirty = [];
+
+ // dimensions
+ this.width = $(this.textarea).getDimensions().width;
+ this.height = $(this.textarea).getDimensions().height;
+
+ var content = this.textarea.value;
+
+ // hide the textarea
+ this.textarea.hide();
+
+ // Some browsers immediately produce a <body> in a new <iframe>,
+ // others only do so later and fire an onload event when they do.
+ if (this.doc.body) {
+ this.init(content);
+ } else {
+ connect(this.iframe, "onload", bind(function(){disconnectAll(this.iframe, "onload"); this.init(content);}, this));
+ }
+ }
+
+
+
+ t3editor.prototype = {
+
+ textModified: false, // editor-content has been modified
+ saveAjaxEvent: null, // Event for save code with ajax
+
+ // Called after we are sure that our frame has a body
+ init: function (code) {
+ this.container = this.doc.body;
+
+ // fetch key press events
+ connect(this.doc, "onkeydown", method(this, "keyDown"));
+ connect(this.doc, "onkeyup", method(this, "keyUp"));
+
+ // fetch scroll events for updateing line numbers
+ connect(this.doc, "onscroll", method(this, "scroll"));
+ connect(this.win, "onscroll", method(this, "scroll"));
+
+ //fetch mouse click event
+ connect(this.doc, "onclick", method(this, "click"));
+
+ // get the form object (needed for Ajax saving)
+ var form = $(this.textarea.form)
+ this.saveButtons = form.getInputs('submit', 'submit');
+
+ // initialize ajax saving events
+ this.saveAjaxEvent = this.saveAjax.bind(this);
+ this.saveButtons.each(function(button) {
+ Event.observe(button,'click',this.saveAjaxEvent);
+ }.bind(this));
+
+ // resize the editor
+ this.resize(this.width, this.height);
+
+ //Import code to editor. If code is empty the method importCode put a BR or SPAN into the codewindow - dependence on browser
+ this.importCode(code);
+
+ // set focus
+ this.win.focus();
+ var cursor = new select.Cursor(this.container);
+ cursor.focus();
+
+ },
+
+ // for demonstation only!
+ footeritem_demo_click: function() {
+ // insertNewlineAtCursor(this.win);
+
+ // focus editor and cursor
+ this.win.focus();
+ var cursor = new select.Cursor(this.container);
+ cursor.start = this.cursorObj;
+ cursor.focus();
+
+ select.insertTextAtCursor(this.win, "page = PAGE");select.insertNewlineAtCursor(this.win);
+ select.insertTextAtCursor(this.win, "page {"); select.insertNewlineAtCursor(this.win);
+ select.insertTextAtCursor(this.win, " 10 = TEXT");select.insertNewlineAtCursor(this.win);
+ select.insertTextAtCursor(this.win, " 10.value = Hello World!"); select.insertNewlineAtCursor(this.win);
+ select.insertTextAtCursor(this.win, "}"); select.insertNewlineAtCursor(this.win);
+
+ this.markCursorDirty();
+ this.scheduleHighlight();
+
+ // this.doc.execCommand("undo", false, null);
+ },
+
+ // toggle between the textarea and t3editor
+ toggleView: function(checkboxEnabled) {
+ if (checkboxEnabled) {
+ this.textarea.value = this.getCode();
+ this.outerdiv.hide();
+ this.textarea.show();
+ this.saveButtons.each(function(button) {
+ Event.stopObserving(button,'click',this.saveAjaxEvent);
+ }.bind(this));
+ } else {
+ this.importCode(this.textarea.value);
+ this.textarea.hide();
+ this.outerdiv.show();
+ this.saveButtons.each(function(button) {
+ Event.observe(button,'click',this.saveAjaxEvent);
+ }.bind(this));
+ }
+ },
+
+ // create an item for the footer line and connect an event
+ createFooterItem: function(title, mouseover, clickAction) {
+ var item = $(createDOM("DIV", {
+ "class": "t3e_footer_item"
+ }));
+ item.innerHTML = title;
+
+ if (mouseover) {
+ item.addClassName('t3e_clickable');
+ Event.observe(item, "mouseover", function(e){Event.element(e).addClassName('t3e_footeritem_active');} );
+ Event.observe(item, "mouseout", function(e){Event.element(e).removeClassName('t3e_footeritem_active');} );
+ }
+
+ if (typeof clickAction == 'object') { // display an overlay
+ Event.observe(item, "click", function(e){ clickAction.toggle(); } );
+
+ } else if (typeof clickAction == 'string' && clickAction != '') { // execute a method
+ connect(item, "onclick", method(this, clickAction+''));
+ }
+
+ return item;
+ },
+
+ // resize the editor
+ resize: function(width, height) {
+ if (this.outerdiv) {
+
+ // TODO: make it more flexible, get rid of "hardcoded" numbers!
+
+ newheight = (height - 1);
+ newwidth = (width + 11);
+ if (isMSIE) newwidth = newwidth + 8;
+
+ this.outerdiv.setStyle({
+ height: newheight,
+ width: newwidth
+ });
+
+ this.linenum_wrap.setStyle({
+ height: (height - 22) // less footer height (TODO)
+ });
+
+ numwwidth = this.linenum_wrap.getWidth();
+ if (isMSIE) numwwidth = numwwidth - 17;
+ if (!isMSIE) numwwidth = numwwidth - 11;
+
+ this.iframe.setStyle({
+ height: (height - 22), // less footer height (TODO)
+ width: (width - numwwidth)
+ });
+
+ this.modalOverlay.setStyle(this.outerdiv.getDimensions());
+ }
+ },
+
+ // toggle between normal view and fullscreen mode
+ toggleFullscreen : function() {
+ if (this.outerdiv.hasClassName('t3e_fullscreen')) {
+ // turn fullscreen off
+ this.outerdiv.removeClassName('t3e_fullscreen');
+ h = this.textarea.getDimensions().height;
+ w = this.textarea.getDimensions().width;
+
+ // hide the scrollbar of the body
+ $$('body')[0].setStyle({overflow : ''});
+
+ } else {
+ // turn fullscreen on
+ this.outerdiv.addClassName('t3e_fullscreen');
+ h = window.innerHeight ? window.innerHeight : $$('body')[0].getHeight();
+ w = window.innerWidth ? window.innerWidth : $$('body')[0].getWidth();
+
+ // TODO: proof if this is needed anymore
+ w = w - 13;
+
+ // hide the scrollbar of the body
+ $$('body')[0].setStyle({overflow : 'hidden'});
+ }
+
+ this.resize(w,h);
+ },
+
+ toggleHelp: function() {
+ this.modalOverlay.toggle();
+ this.helpOverlay.toggle();\r
+ },
+
+
+ //toggle AutoCompletation beetwen on and off
+ toggleAutoComplete : function() {
+ this.options.autoComplete = (this.options.autoComplete)?false:true;
+ },
+
+ //autocomplete box
+ autoComplete : function() {
+ this.clicked = false;
+ //get lastword into this.lastWord
+ this.getLastWord();
+ // init vars for up/down moving in word list
+ this.ac_up = 0;
+ this.ac_down = this.options.acWords-1;
+
+ //refresh cursorObj
+ var cursor = new select.Cursor(this.container);
+ this.cursorObj = cursor.start;
+ //init currWord, used in word list. Contain selected word
+ this.currWord = -1;
+
+ // If lastword is not empty and not space - continue
+ if (this.lastWord!=' ' && this.lastWord){
+ // get list of words
+ this.words = this.getCompleteWordsByTrigger(this.lastWord.toLowerCase());
+ // if words are found - show box
+ if (this.words.length > 0){
+ // make UL list of completation words
+ var html = '<ul>';
+ for (i=0;i<this.words.length;i++){
+ html+= '<li style="height:16px;vertical-align:middle;" id="ac_word_'+i+'" onclick="t3e_instances['+this.index+'].clicked=true;t3e_instances['+this.index+'].insertCurrWordAtCursor();" onmouseover="t3e_instances['+this.index+'].highlightCurrWord('+i+');"><span class="word_'+this.words[i].type+'">'+this.words[i].word+'</span></li>';
+ }
+ html+='</ul>';
+ //put HTML and show box
+ this.autoCompleteBox.innerHTML = html;
+ this.autoCompleteBox.show();
+ this.autoCompleteBox.scrollTop = 0;
+ // init styles
+ if (this.words.length > this.options.acWords){
+ this.autoCompleteBox.style.overflowY = 'scroll';
+ if (isGecko){
+ this.autoCompleteBox.style.height = (this.options.acWords*($("ac_word_0").offsetHeight))+'px';
+ }else{
+ this.autoCompleteBox.style.height = (this.options.acWords*($("ac_word_0").offsetHeight))+4+'px';
+ this.autoCompleteBox.style.width = this.autoCompleteBox.offsetWidth+20+'px';
+ }
+
+ }else{
+ this.autoCompleteBox.style.overflowY = 'auto';
+ this.autoCompleteBox.style.height = 'auto';
+ this.autoCompleteBox.style.width = 'auto'; // '0px';
+ }
+
+ // positioned box to word
+ this.autoCompleteBox.style.left = Position.cumulativeOffset(this.iframe)[0]-Position.cumulativeOffset(this.outerdiv)[0]+Position.cumulativeOffset(cursor.start)[0]+cursor.start.offsetWidth;
+ this.autoCompleteBox.style.top = Position.cumulativeOffset(this.iframe)[1]-Position.cumulativeOffset(this.outerdiv)[1]+Position.cumulativeOffset(cursor.start)[1]+cursor.start.offsetHeight-this.container.scrollTop;
+ // set flag to 1 - needed for continue typing word.
+ this.ac = 1;
+ //highlight first word in list
+ this.highlightCurrWord(0);
+ }
+ }
+ },
+ // Get word where cursor focused
+ getLastWord : function (){
+ var cursor = new select.Cursor(this.container);
+ if (cursor.start){
+ this.lastTrigger = this.lastWord;
+ this.lastWord = (cursor.start.innerHTML)?cursor.start.innerHTML:'';
+ }
+ },
+
+ // highlighitng word in autocomplete box by id
+ highlightCurrWord : function (id) {
+ if (this.currWord!=-1){
+ $('ac_word_'+this.currWord).className = '';
+ }
+ $('ac_word_'+id).className = 'active';
+ this.currWord = id;
+ },
+
+ //insert selected word into text from autocompletebox
+ insertCurrWordAtCursor: function (){
+ var trigger = this.lastWord;
+ var insertText = this.words[this.currWord].word;
+ //if MSIE and select word my mouse click
+ var cursor = new select.Cursor(this.container);
+ if (isMSIE && this.clicked){
+ if (trigger.length > 0){
+ this.cursorObj.innerHTML = insertText;
+ this.win.focus();
+ cursor.start = this.cursorObj;
+ cursor.focus();
+ this.highlightAtCursor(cursor);
+ }
+ }
+ // if Safari browser
+ else if (isSafari){
+ if (trigger.length > 0){
+ this.cursorObj.innerHTML = insertText;
+ if (this.clicked){
+ this.win.focus();
+ }
+ cursor.start = this.cursorObj;
+ cursor.focus();
+ this.highlightAtCursor(cursor);
+ }
+ }
+ //for all others times
+ else{
+ if (trigger.length > 0){
+ cursor.start.innerHTML = '';
+ }
+ select.insertTextAtCursor (this.win,insertText);
+ if (this.clicked){
+ this.win.focus();
+ }
+ cursor.focus();
+ this.highlightAtCursor(cursor);
+ }
+ // set ac flag to 0 - autocomplete is finish
+ this.ac = 0;
+ //hide box
+ this.autoCompleteBox.hide();
+ },
+ //return words for autocomplete by trigger (part of word)
+ getCompleteWordsByTrigger : function (trigger){
+ result = [];
+
+ for(word in typoscriptWords){
+ lword = word.toLowerCase();
+ if (lword.indexOf(trigger) === 0){
+ var wordObj = new Object();
+ wordObj.word = word;
+ wordObj.type = typoscriptWords[word];
+ result.push(wordObj);
+ }
+ }
+ return result;
+ },
+
+ //move cursor in autcomplete box up
+ autoCompleteBoxMoveUpCursor : function () {
+ // if previous position was first - then move cursor to last word if not than position --
+ if (this.currWord == 0){
+ var id = this.words.length-1;
+ }else{
+ var id = this.currWord-1;
+ }
+ // hightlight new cursor position
+ this.highlightCurrWord (id);
+ //update id of first and last showing words and scroll box
+ if (this.currWord < this.ac_up || this.currWord == (this.words.length-1)){
+ this.ac_up = this.currWord;
+ this.ac_down = this.currWord+(this.options.acWords-1);
+ if (this.ac_up === this.words.length-1){
+ this.ac_down = this.words.length-1;
+ this.ac_up = this.ac_down-(this.options.acWords-1);
+ }
+ this.autoCompleteBox.scrollTop = this.ac_up*16;
+ }
+ },
+ //move cursor in autocomplete box down
+ autoCompleteBoxMoveDownCursor : function () {
+ // if previous position was last word in list - then move cursor to first word if not than position ++
+ if (this.currWord == this.words.length-1){
+ var id = 0;
+ }else{
+ var id = this.currWord+1;
+ }
+ // hightlight new cursor position
+ this.highlightCurrWord (id);
+ //update id of first and last showing words and scroll box
+ if (this.currWord > this.ac_down || this.currWord==0){
+ this.ac_down = this.currWord;
+ this.ac_up = this.currWord-(this.options.acWords-1);
+ if (this.ac_down == 0){
+ this.ac_up = 0;
+ this.ac_down = this.options.acWords-1;
+ }
+ this.autoCompleteBox.scrollTop = this.ac_up*16;
+ }
+ },
+ // put code to history
+ pushToHistory:function () {
+ var obj = {};
+ //create SPAN mark of cursor
+ var cursorEl = this.win.document.createElement("SPAN");
+ cursorEl.id = "cursor";
+ this.refreshCursorObj();
+ // added mark to code
+ if (this.initable){
+ if (!this.cursorObj){
+ if (this.container.firstChild){
+ this.win.document.body.insertBefore(cursorEl,this.container.firstChild);
+ }
+ }else{
+ this.win.document.body.insertBefore(cursorEl,this.cursorObj);
+ }
+ }else{
+ this.win.document.body.appendChild(cursorEl);
+ }
+ //save code and text to history object
+ obj.code = this.container.innerHTML;
+ obj.text = this.getCode();
+ // check if was undo/redo than refresh history array
+ if (this.currHistoryPosition+1 < this.history.length){
+ this.history = this.history.slice (0,this.currHistoryPosition+1);
+ this.currHistoryPosition = this.history.length-1;
+ }
+ //push history oject to history array
+ this.history.push(obj);
+ this.currHistoryPosition++;
+ //check limit of history size
+ if (this.currHistoryPosition > this.historySize){
+ this.history = this.history.slice ((this.history.length-this.historySize-1));
+ this.currHistoryPosition = this.history.length-1;
+ }
+ },
+
+ //undo function
+ undo: function () {
+ //check if position in history not first
+ if (this.currHistoryPosition > 0){
+ this.currHistoryPosition--;
+ var obj = this.history[this.currHistoryPosition];
+ if (!obj){return ;}
+ //insert code from history
+ this.container.innerHTML = obj.code;
+ //focus cursor to next el of marked span
+ var cursor = new select.Cursor(this.container);
+ var cursorEl = this.win.document.getElementById('cursor');
+ if (cursorEl){
+ cursor.start = cursorEl.nextSibling;
+ cursor.focus();
+ }
+ }
+
+ },
+
+ //redo function
+ redo: function () {
+ //check if position in history not last
+ if (this.currHistoryPosition < this.history.length){
+ this.currHistoryPosition++;
+ var obj = this.history[this.currHistoryPosition];
+ if (!obj){return ;}
+ //insert code from history
+ this.container.innerHTML = obj.code;
+ //focus cursor to next el of marked span
+ var cursor = new select.Cursor(this.container);
+ var cursorEl = this.win.document.getElementById('cursor');
+ if (cursorEl){
+ cursor.start = cursorEl.nextSibling;
+ cursor.focus();
+ }
+ }
+
+ },
+ // check changes in history
+ checkHistoryChanges:function () {
+
+ var code = this.container.innerHTML;
+ if (this.undoable == 1){
+ this.undoable = 0;
+ return ;
+ }
+ if (this.redoable == 1){
+ this.redoable = 0;
+ return ;
+ }
+ if (!this.history[this.currHistoryPosition]){
+ this.pushToHistory();
+ return ;
+ }
+ if (this.getCode(code) != this.history[this.currHistoryPosition].text){
+ this.pushToHistory();
+ }
+
+ },
+
+ // update the line numbers
+ updateLinenum: function() {
+ var theMatch = this.container.innerHTML.match(/<br/gi);
+ if (!theMatch) {
+ theMatch = '1';
+ } else if (isMSIE) {
+ theMatch.push('1');
+ }
+
+ var bodyContentLineCount = theMatch.length;
+ disLineCount = this.linenum.childNodes.length;
+ while (disLineCount != bodyContentLineCount) {
+ if (disLineCount > bodyContentLineCount) {
+ this.linenum.removeChild(this.linenum.lastChild);
+ disLineCount--;
+ } else if (disLineCount < bodyContentLineCount) {
+ ln = $(document.createElement('dt'));
+ ln.update(disLineCount+1+'.');
+ ln.addClassName(disLineCount%2==1?'even':'odd');
+ ln.setAttribute('id','ln'+(disLineCount+1));
+ this.linenum.appendChild(ln);
+ disLineCount++;
+ }
+ }
+
+ this.fitem_status.update(bodyContentLineCount + ' lines');
+ this.fitem_name.update(this.documentname + (this.textModified?' <span alt="document has been modified">*</span>':''));
+ },
+
+ // scroll the line numbers
+ scroll: function() {
+ var scrOfX = 0, scrOfY = 0;
+ if( typeof( this.win.pageYOffset ) == 'number' ) {
+ // Netscape compliant
+ scrOfY = this.win.pageYOffset;
+ scrOfX = this.win.pageXOffset;
+ } else if( this.doc.body && ( this.doc.body.scrollLeft || this.doc.body.scrollTop ) ) {
+ // DOM compliant
+ scrOfY = this.doc.body.scrollTop;
+ scrOfX = this.doc.body.scrollLeft;
+ } else if( this.doc.documentElement && ( this.doc.documentElement.scrollLeft || this.doc.documentElement.scrollTop ) ) {
+ // IE6 standards compliant mode
+ scrOfY = this.doc.documentElement.scrollTop;
+ scrOfX = this.doc.documentElement.scrollLeft;
+ }
+ this.linenum_wrap.scrollTop = scrOfY;
+ },
+
+ // click event. Refresh cursor object. if autocomplete is not finish - finish it and hide box
+ click: function() {
+ if (this.ac === 1){this.ac = 0;this.autoCompleteBox.hide();}
+ this.refreshCursorObj();
+ },
+
+ // Split a chunk of code into lines, put them in the frame, and
+ // schedule them to be coloured.
+ importCode: function(code) {
+ replaceChildNodes(this.container);
+
+ if (code == "\n" || code == "\r\n" || code == "\r"){code = '';}
+ var lines = code.replace(/[ \t]/g, nbsp).replace(/\r\n?/g, "\n").split("\n");
+
+ for (var i = 0; i != lines.length; i++) {
+ if (i > 0)
+ this.container.appendChild(withDocument(this.doc, BR));
+ var line = lines[i];
+ if (line.length > 0)
+ this.container.appendChild(this.doc.createTextNode(line));
+ }
+ if (code == "") {
+ var empty = this.win.document.createElement('BR');//(isGecko && !isSafari)?this.win.document.createElement('BR'):this.win.document.createElement('SPAN');
+ this.container.appendChild(empty);
+ }
+
+ if (this.container.firstChild){
+ this.addDirtyNode(this.container.firstChild);
+ this.scheduleHighlight(); // this.highlightDirty();
+ }
+ this.updateLinenum();
+ },
+
+ // Extract the code from the editor.
+ getCode: function() {
+ if (!this.container.firstChild)
+ return "";
+
+ var accum = [];
+ forEach(traverseDOM(this.container.firstChild), method(accum, "push"));
+ return accum.join("").replace(nbspRegexp, " ");
+ },
+
+ // Intercept enter and any keys that are specified to re-indent
+ // the current line.
+ keyDown: function(event) {
+ var name = event.key().string;
+
+ if (name == "KEY_ENTER") {
+ event.stop();
+ if (this.ac === 1) {
+ this.insertCurrWordAtCursor();
+ } else if (!isMac) {
+ select.insertNewlineAtCursor(this.win);
+ this.indentAtCursor();
+ }
+ this.updateLinenum();
+
+ } else if (name == "KEY_S" && event.modifier().ctrl) { // save via ajax request
+ this.saveAjax();
+ event.stop();
+ return;
+
+ } else if (name == "KEY_F11" && event.modifier().ctrl) { // toogle fullscreen mode
+ this.toggleFullscreen();
+ event.stop();
+ return;
+
+ } else if (name == "KEY_SPACEBAR" && event.modifier().ctrl && this.options.autoComplete){ // call autocomplete if autocomplete turn on
+ this.autoComplete();
+ event.stop();
+ } else if (name=="KEY_ARROW_UP" && this.ac == 1){ // move up cursor in autocomplete box
+ event.stop();
+ window.setTimeout('t3e_instances['+this.index+'].autoCompleteBoxMoveUpCursor()',100);
+ } else if (name=="KEY_ARROW_DOWN" && this.ac == 1){ // move down cursor in autocomplete box
+ event.stop();
+ window.setTimeout('t3e_instances['+this.index+'].autoCompleteBoxMoveDownCursor();',100);
+ } else if (name=="KEY_ESCAPE" && this.ac === 1){ // if autocomplete box is showing. by ESC press it's hide and autocomplete is finish
+ this.ac = 0;
+ this.autoCompleteBox.hide();
+ } else if (name=='KEY_Z' && event.modifier().ctrl){
+ this.undoable = 1;
+ this.undo();
+ event.stop();
+ } else if (name=='KEY_Y' && event.modifier().ctrl){
+ this.redoable = 1;
+ this.redo();
+ event.stop();
+ }
+ },
+
+ // Re-indent when a key in options.reindentAfterKeys is released,
+ // mark the node at the cursor dirty when a non-safe key is
+ // released.
+ keyUp: function(event) {
+ var name = event.key().string;
+ if (this.options.reindentAfterKeys.hasOwnProperty(name))
+ this.indentAtCursor();
+ else if (!this.options.safeKeys.hasOwnProperty(name)) {
+ this.markCursorDirty();
+ this.checkTextModified();
+ }
+
+ if (this.ac===1){ // if autocomplete now is not finish, but started and continue typing - refresh autocomplete box
+ this.getLastWord();
+ if (this.lastTrigger!=this.lastWord){
+ this.autoCompleteBox.hide();
+ this.ac = 0;
+ this.autoComplete();
+ }
+ }
+
+ if (name == "KEY_ENTER" || name == "KEY_BACKSPACE" || name == "KEY_DELETE" ){
+ this.updateLinenum();
+ }
+
+ this.refreshCursorObj();
+ },
+
+ refreshCursorObj: function () {
+ var cursor = new select.Cursor(this.container);
+ this.cursorObj = cursor.start;
+ },
+
+
+ // check if code in editor has been modified since last saving
+ checkTextModified: function() {
+ if (!this.textModified) {
+ this.textModified = true;
+ this.updateLinenum();
+ }
+ },
+
+
+ // send ajax request to save the code
+ saveAjax: function(event) {
+ if (event) {
+ // event = new Event(event);
+ Event.stop(event);
+ }
+
+ this.modalOverlay.show();
+ this.textarea.value = this.getCode();
+
+ /* erst ab prototype 1.5.1
+ Form.request($(this.textarea.form),{
+ onComplete: function(){ alert('Form data saved!'); }
+ });
+ */
+
+ formdata = "submitAjax=1&" + Form.serialize($(this.textarea.form));
+
+ var myAjax = new Ajax.Request(
+ $(this.textarea.form).action,
+ { method: "post",
+ parameters: formdata,
+ onComplete: this.saveAjaxOnSuccess.bind(this)
+ });
+ },
+
+ // callback if ajax saving was successful
+ saveAjaxOnSuccess: function(ajaxrequest) {
+ if (ajaxrequest.status == 200
+ && ajaxrequest.responseText == "OK") {
+ this.textModified = false;
+ this.updateLinenum();
+ } else {
+ // TODO: handle if session is timed out
+ alert("An error occured while saving the data.");
+ };
+ this.modalOverlay.hide();
+
+ },
+
+
+ // Ensure that the start of the line the cursor is on is parsed
+ // and coloured properly, so that the correct indentation can be
+ // computed.
+ highlightAtCursor: function(cursor) {
+ if (cursor.valid) {
+ var node = cursor.start || this.container.firstChild;
+ if (node) {
+ // If the node is a text node, it will be recognized as
+ // dirty anyway, and some browsers do not allow us to add
+ // properties to text nodes.
+ if (node.nodeType != 3)
+ node.dirty = true;
+ // Store selection, highlight, restore selection.
+ var sel = select.markSelection(this.win);
+ this.highlight(node);
+ select.selectMarked(sel);
+ // Cursor information is probably no longer valid after
+ // highlighting.
+ cursor = new select.Cursor(this.container);
+ }
+ }
+ return cursor;
+ },
+
+ // Adjust the amount of whitespace at the start of the line that
+ // the cursor is on so that it is indented properly.
+ indentAtCursor: function() {
+ var cursor = new select.Cursor(this.container);
+ // The line has to have up-to-date lexical information, so we
+ // highlight it first.
+ cursor = this.highlightAtCursor(cursor);
+ // If we couldn't determine the place of the cursor, there's
+ // nothing to indent.
+ if (!cursor.valid)
+ return;
+
+ // start is the <br> before the current line, or null if this is
+ // the first line.
+ var start = cursor.startOfLine();
+ // whiteSpace is the whitespace span at the start of the line,
+ // or null if there is no such node.
+ var whiteSpace = start ? start.nextSibling : this.container.lastChild;
+ if (whiteSpace && !hasClass(whiteSpace, "whitespace"))
+ whiteSpace = null;
+
+ // Sometimes the first character on a line can influence the
+ // correct indentation, so we retrieve it.
+ var firstText = whiteSpace ? whiteSpace.nextSibling : start ? start.nextSibling : this.container.firstChild;
+ var firstChar = (start && firstText && firstText.currentText) ? firstText.currentText.charAt(0) : "";
+
+ // Ask the lexical context for the correct indentation, and
+ // compute how much this differs from the current indentation.
+
+ var indent = start ? start.lexicalContext.indentation(firstChar) : 0;
+ var indentDiff = indent - (whiteSpace ? whiteSpace.currentText.length : 0);
+
+ // If there is too much, this is just a matter of shrinking a span.
+ if (indentDiff < 0) {
+ whiteSpace.currentText = repeatString(nbsp, indent);
+ whiteSpace.firstChild.nodeValue = whiteSpace.currentText;
+ }
+ // Not enough...
+ else if (indentDiff > 0) {
+ // If there is whitespace, we grow it.
+ if (whiteSpace) {
+ whiteSpace.currentText += repeatString(nbsp, indentDiff);
+ whiteSpace.firstChild.nodeValue = whiteSpace.currentText;
+ }
+ // Otherwise, we have to add a new whitespace node.
+ else {
+ whiteSpace = withDocument(this.doc, function(){return SPAN({"class": "part whitespace"}, repeatString(nbsp, indentDiff))});
+ if (start)
+ insertAfter(whiteSpace, start);
+ else
+ insertAtStart(whiteSpace, this.containter);
+ }
+ // If the cursor is at the start of the line, move it to after
+ // the whitespace.
+ if (cursor.start == start)
+ cursor.start = whiteSpace;
+ }
+
+ if (cursor.start == whiteSpace)
+ cursor.focus();
+ },
+
+ // highlight is a huge function defined below.
+ highlight: highlight,
+
+ // Find the node that the cursor is in, mark it as dirty, and make
+ // sure a highlight pass is scheduled.
+ markCursorDirty: function() {
+ var cursor = new select.Cursor(this.container);
+ if (cursor.valid) {
+ var node = cursor.start || this.container.firstChild;
+ if (node) {
+ this.addDirtyNode(node);
+ this.scheduleHighlight();
+ }
+ }
+ },
+
+ // Add a node to the set of dirty nodes, if it isn't already in
+ // there.
+ addDirtyNode: function(node) {
+ if (this.dirty.indexOf(node) == -1) {
+ if (node.nodeType != 3)
+ node.dirty = true;
+ this.dirty.push(node);
+ }
+ },
+
+ // Cause a highlight pass to happen in options.passDelay
+ // milliseconds. Clear the existing timeout, if one exists. This
+ // way, the passes do not happen while the user is typing, and
+ // should as unobtrusive as possible.
+ scheduleHighlight: function() {
+ if (this.highlightTimeout) clearTimeout(this.highlightTimeout);
+ this.highlightTimeout = setTimeout(bind(this.highlightDirty, this), this.options.passDelay);
+ },
+
+ // Fetch one dirty node, and remove it from the dirty set.
+ getDirtyNode: function() {
+ while (this.dirty.length > 0) {
+ var found = this.dirty.pop();
+ // If the node has been coloured in the meantime, or is no
+ // longer in the document, it should not be returned.
+ if ((found.dirty || found.nodeType == 3) && found.parentNode)
+ return found;
+ }
+ return null;
+ },
+
+ // Pick dirty nodes, and highlight them, until
+ // options.linesPerPass lines have been highlighted. The highlight
+ // method will continue to next lines as long as it finds dirty
+ // nodes. It returns an object indicating the amount of lines
+ // left, and information about the place where it stopped. If
+ // there are dirty nodes left after this function has spent all
+ // its lines, it shedules another highlight to finish the job.
+ highlightDirty: function() {
+ var lines = this.options.linesPerPass;
+ var sel = select.markSelection(this.win);
+ var start;
+ while (lines > 0 && (start = this.getDirtyNode())){
+ var result = this.highlight(start, lines);
+ if (result) {
+ lines = result.left;
+ if (result.node && result.dirty)
+ this.addDirtyNode(result.node);
+ }
+ }
+ select.selectMarked(sel);
+ if (start)
+ this.scheduleHighlight();
+ }
+ }
+
+ // The function that does the actual highlighting/colouring (with
+ // help from the parser and the DOM normalizer). Its interface is
+ // rather overcomplicated, because it is used in different
+ // situations: ensuring that a certain line is highlighted, or
+ // highlighting up to X lines starting from a certain point. The
+ // 'from' argument gives the node at which it should start. If this
+ // is null, it will start at the beginning of the frame. When a
+ // number of lines is given with the 'lines' argument, it will colour
+ // no more than that amount. If at any time it comes across a
+ // 'clean' line (no dirty nodes), it will stop.
+ function highlight(from, lines){
+ var container = this.container;
+ var document = this.doc;
+// this.updateLinenum();
+
+ if (!container.firstChild)
+ return;
+ // Backtrack to the first node before from that has a partial
+ // parse stored.
+ while (from && !from.parserFromHere)
+ from = from.previousSibling;
+ // If we are at the end of the document, do nothing.
+ if (from && !from.nextSibling)
+ return;
+
+ // Check whether a part (<span> node) and the corresponding token
+ // match.
+ function correctPart(token, part){
+ return !part.reduced && part.currentText == token.value && hasClass(part, token.style);
+ }
+ // Shorten the text associated with a part by chopping off
+ // characters from the front. Note that only the currentText
+ // property gets changed. For efficiency reasons, we leave the
+ // nodeValue alone -- we set the reduced flag to indicate that
+ // this part must be replaced.
+ function shortenPart(part, minus){
+ part.currentText = part.currentText.substring(minus);
+ part.reduced = true;
+ }
+ // Create a part corresponding to a given token.
+ function tokenPart(token){
+ var part = withDocument(document, partial(SPAN, {"class": "part " + token.style}, token.value));
+ part.currentText = token.value;
+ return part;
+ }
+
+ // Get the token stream. If from is null, we start with a new
+ // parser from the start of the frame, otherwise a partial parse
+ // is resumed.
+ var parsed = from ? from.parserFromHere(multiStringStream(traverseDOM(from.nextSibling)))
+ : this.options.parser(multiStringStream(traverseDOM(container.firstChild)));
+
+ // parts is a wrapper that makes it possible to 'delay' going to
+ // the next DOM node until we are completely done with the one
+ // before it. This is necessary because we are constantly poking
+ // around in the DOM tree, and if the next node is fetched to
+ // early it might get replaced before it is used.
+ var parts = {
+ current: null,
+ forward: false,
+ // Get the current part.
+ get: function(){
+ if (!this.current)
+ this.current = from ? from.nextSibling : container.firstChild;
+ else if (this.forward)
+ this.current = this.current.nextSibling;
+ this.forward = false;
+ return this.current;
+ },
+ // Advance to the next part (do not fetch it yet).
+ next: function(){
+ if (this.forward)
+ this.get();
+ this.forward = true;
+ },
+ // Remove the current part from the DOM tree, and move to the
+ // next.
+ remove: function(){
+ this.current = this.get().previousSibling;
+ container.removeChild(this.current ? this.current.nextSibling : container.firstChild);
+ this.forward = true;
+ },
+ // Advance to the next part that is not empty, discarding empty
+ // parts.
+ nextNonEmpty: function(){
+ var part = this.get();
+ while (part.nodeName == "SPAN" && part.currentText == ""){
+ var old = part;
+ this.remove();
+ part = this.get();
+ // Adjust selection information, if any. See select.js for
+ // details.
+ select.replaceSelection(old.firstChild, part.firstChild || part, 0, 0);
+ }
+ return part;
+ }
+ };
+
+ var lineDirty = false;
+
+ // This forEach loops over the tokens from the parsed stream, and
+ // at the same time uses the parts object to proceed through the
+ // corresponding DOM nodes.
+ forEach(parsed, function(token){
+ var part = parts.nextNonEmpty();
+ if (token.value == "\n"){
+ // The idea of the two streams actually staying synchronized
+ // is such a long shot that we explicitly check.
+ if (part.nodeName != "BR")
+ throw "Parser out of sync. Expected BR.";
+ if (part.dirty || !part.lexicalContext)
+ lineDirty = true;
+ // Every <br> gets a copy of the parser state and a lexical
+ // context assigned to it. The first is used to be able to
+ // later resume parsing from this point, the second is used
+ // for indentation.
+ part.parserFromHere = parsed.copy();
+ part.lexicalContext = token.lexicalContext;
+ part.dirty = false;
+ // A clean line means we are done. Throwing a StopIteration is
+ // the way to break out of a MochiKit forEach loop.
+ if ((lines !== undefined && --lines <= 0) || !lineDirty)
+ throw StopIteration;
+ lineDirty = false;
+ parts.next();
+ }
+ else {
+ if (part.nodeName != "SPAN")
+ throw "Parser out of sync. Expected SPAN.";
+ if (part.dirty)
+ lineDirty = true;
+
+ // If the part matches the token, we can leave it alone.
+ if (correctPart(token, part)){
+ part.dirty = false;
+ parts.next();
+ }
+ // Otherwise, we have to fix it.
+ else {
+ lineDirty = true;
+ // Insert the correct part.
+ var newPart = tokenPart(token);
+ container.insertBefore(newPart, part);
+ var tokensize = token.value.length;
+ var offset = 0;
+ // Eat up parts until the text for this token has been
+ // removed, adjusting the stored selection info (see
+ // select.js) in the process.
+ while (tokensize > 0) {
+ part = parts.get();
+ var partsize = part.currentText.length;
+ select.replaceSelection(part.firstChild, newPart.firstChild, tokensize, offset);
+ if (partsize > tokensize){
+ shortenPart(part, tokensize);
+ tokensize = 0;
+ }
+ else {
+ tokensize -= partsize;
+ offset += partsize;
+ parts.remove();
+ }
+ }
+ }
+ }
+ });
+ this.refreshCursorObj();
+ this.initable = 1;
+ window.setTimeout ('t3e_instances['+this.index+'].checkHistoryChanges();',100);
+ // The function returns some status information that is used by
+ // hightlightDirty to determine whether and where it has to
+ // continue.
+ return {left: lines,
+ node: parts.get(),
+ dirty: lineDirty};
+ }
+
+ return t3editor;
+}();
+
+
+// ------------------------------------------------------------------------
+
+
+
+function t3editor_toggleEditor(checkbox,index) {
+ if (index == undefined) {
+ $$('textarea.t3editor').each(
+ function(textarea,i) {
+ t3editor_toggleEditor(checkbox,i);
+ }
+ ); \r
+ } else {
+ if (t3e_instances[index] != undefined) {
+ var t3e = t3e_instances[index];
+ t3e.toggleView(checkbox.checked);
+ } else if (!checkbox.checked) {
+ var t3e = new t3editor($$('textarea.t3editor')[index], index);
+ t3e_instances[index] = t3e;
+ }\r
+ }
+}
+
+// ------------------------------------------------------------------------
+
+
+/**
+ * everything ready: turn textareas into fancy editors
+ */
+Event.observe(window,'load',function() {
+ $$('textarea.t3editor').each(
+ function(textarea,i) {
+ if ($('t3editor_disableEditor_'+(i+1)+'_checkbox') && !$('t3editor_disableEditor_'+(i+1)+'_checkbox').checked) {
+ var t3e = new t3editor(textarea,i);
+ t3e_instances[i] = t3e;
+ }
+ }
+ );
+});
--- /dev/null
+/* Tokenizer for JavaScript code */
+
+var tokenizeJavaScript = function(){
+ // A map of JavaScript's keywords. The a/b/c keyword distinction is
+ // very rough, but it gives the parser enough information to parse
+ // correct code correctly (we don't care much how we parse incorrect
+ // code). The style information included in these objects is used by
+ // the highlighter to pick the correct CSS style for a token.
+ var keywords = function(){
+ function result(type, style){
+ return {type: type, style: style};
+ }
+ // keywords that take a parenthised expression, and then a
+ // statement (if)
+ var keywordA = result("keyword a", "keyword");
+ // keywords that take just a statement (else)
+ var keywordB = result("keyword b", "keyword");
+ // keywords that optionally take an expression, and form a
+ // statement (return)
+ var keywordC = result("keyword c", "keyword");
+ var operator = result("operator", "keyword");
+ var atom = result("atom", "atom");
+ return {
+ "if": keywordA, "switch": keywordA, "while": keywordA, "with": keywordA,
+ "else": keywordB, "do": keywordB, "try": keywordB, "finally": keywordB,
+ "return": keywordC, "break": keywordC, "continue": keywordC, "new": keywordC, "delete": keywordC, "throw": keywordC,
+ "in": operator, "typeof": operator, "instanceof": operator,
+ "var": result("var", "keyword"), "function": result("function", "keyword"), "catch": result("catch", "keyword"),
+ "for": result("for", "keyword"), "case": result("case", "keyword"),
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
+ };
+ }();
+
+ // Some helper regexp matchers.
+ var isOperatorChar = matcher(/[\+\-\*\&\%\/=<>!\?]/);
+ var isDigit = matcher(/[0-9]/);
+ var isHexDigit = matcher(/[0-9A-Fa-f]/);
+ var isWordChar = matcher(/[\w\$_]/);
+ function isWhiteSpace(ch){
+ // Unfortunately, IE's regexp matcher thinks non-breaking spaces
+ // aren't whitespace. Also, in our scheme newlines are no
+ // whitespace (they are another special case).
+ return ch != "\n" && (ch == nbsp || /\s/.test(ch));
+ }
+
+ // This function produces a MochiKit-style iterator that tokenizes
+ // the output of the given stringstream (see stringstream.js).
+ // Tokens are objects with a type, style, and value property. The
+ // value contains the textual content of the token. Because this may
+ // include trailing whitespace (for efficiency reasons), some
+ // tokens, such a variable names, also have a name property
+ // containing their actual textual value.
+ return function(source){
+ // Produce a value to return. Automatically skips and includes any
+ // whitespace. The base argument is prepended to the value
+ // property and assigned to the name property -- this is used when
+ // the caller has already extracted the text from the stream
+ // himself.
+ function result(type, style, base){
+ nextWhile(isWhiteSpace);
+ var value = {type: type, style: style, value: (base ? base + source.get() : source.get())};
+ if (base) value.name = base;
+ return value;
+ }
+
+ // Advance the text stream over characters for which test returns
+ // true. (The characters that are 'consumed' like this can later
+ // be retrieved by calling source.get()).
+ function nextWhile(test){
+ var next;
+ while((next = source.peek()) && test(next))
+ source.next();
+ }
+ // Advance the stream until the given character (not preceded by a
+ // backslash) is encountered (or a newline is found).
+ function nextUntilUnescaped(end){
+ var escaped = false;
+ var next;
+ while((next = source.peek()) && next != "\n"){
+ source.next();
+ if (next == end && !escaped)
+ break;
+ escaped = next == "\\";
+ }
+ }
+
+ function readHexNumber(){
+ source.next(); // skip the 'x'
+ nextWhile(isHexDigit);
+ return result("number", "atom");
+ }
+ function readNumber(){
+ nextWhile(isDigit);
+ if (source.peek() == "."){
+ source.next();
+ nextWhile(isDigit);
+ }
+ if (source.peek() == "e" || source.peek() == "E"){
+ source.next();
+ if (source.peek() == "-")
+ source.next();
+ nextWhile(isDigit);
+ }
+ return result("number", "atom");
+ }
+ // Read a word, look it up in keywords. If not found, it is a
+ // variable, otherwise it is a keyword of the type found.
+ function readWord(){
+ nextWhile(isWordChar);
+ var word = source.get();
+ var known = keywords.hasOwnProperty(word) && keywords.propertyIsEnumerable(word) && keywords[word];
+ return known ? result(known.type, known.style, word) : result("variable", "variable", word);
+ }
+ function readRegexp(){
+ nextUntilUnescaped("/");
+ nextWhile(matcher(/[gi]/));
+ return result("regexp", "string");
+ }
+ // Mutli-line comments are tricky. We want to return the newlines
+ // embedded in them as regular newline tokens, and then continue
+ // returning a comment token for every line of the comment. So
+ // some state has to be saved (inComment) to indicate whether we
+ // are inside a /* */ sequence.
+ function readMultilineComment(start){
+ this.inComment = true;
+ var maybeEnd = (start == "*");
+ while(true){
+ var next = source.peek();
+ if (next == "\n")
+ break;
+ source.next();
+ if (next == "/" && maybeEnd){
+ this.inComment = false;
+ break;
+ }
+ maybeEnd = (next == "*");
+ }
+ return result("comment", "comment");
+ }
+
+ // Fetch the next token. Dispatches on first character in the
+ // stream, or first two characters when the first is a slash. The
+ // || things are a silly trick to keep simple cases on a single
+ // line.
+ function next(){
+ var token = null;
+ var ch = source.next();
+ if (ch == "\n")
+ token = {type: "newline", style: "whitespace", value: source.get()};
+ else if (this.inComment)
+ token = readMultilineComment.call(this, ch);
+ else if (isWhiteSpace(ch))
+ token = nextWhile(isWhiteSpace) || result("whitespace", "whitespace");
+ else if (ch == "\"" || ch == "'")
+ token = nextUntilUnescaped(ch) || result("string", "string");
+ // with punctuation, the type of the token is the symbol itself
+ else if (/[\[\]{}\(\),;\:\.]/.test(ch))
+ token = result(ch, "punctuation");
+ else if (ch == "0" && (source.peek() == "x" || source.peek() == "X"))
+ token = readHexNumber();
+ else if (isDigit(ch))
+ token = readNumber();
+ else if (ch == "/"){
+ next = source.peek();
+ if (next == "*")
+ token = readMultilineComment.call(this, ch);
+ else if (next == "/")
+ token = nextUntilUnescaped(null) || result("comment", "comment");
+ else if (this.regexp)
+ token = readRegexp();
+ else
+ token = nextWhile(isOperatorChar) || result("operator", "operator");
+ }
+ else if (isOperatorChar(ch))
+ token = nextWhile(isOperatorChar) || result("operator", "operator");
+ else
+ token = readWord();
+
+ // JavaScript's syntax rules for when a slash might be the start
+ // of a regexp and when it is just a division operator are kind
+ // of non-obvious. This decides, based on the current token,
+ // whether the next token could be a regular expression.
+ if (token.style != "whitespace" && token != "comment")
+ this.regexp = token.type == "operator" || token.type == "keyword c" || token.type.match(/[\[{}\(,;:]/);
+ return token;
+ }
+
+ // Wrap it in an iterator. The state (regexp and inComment) is
+ // exposed because a parser will need to save it when making a
+ // copy of its state.
+ return {next: next, regexp: true, inComment: false};
+ }
+}();
--- /dev/null
+/* Tokenizer for TypoScript code
+ *
+ * based on tokenizejavascript.js by Marijn Haverbeke
+ */
+
+// List of "reserved" word in typoscript and a css-class
+var typoscriptWords = {
+ '_CSS_DEFAULT_STYLE' : 'keyword',
+ '_DEFAULT_PI_VARS' : 'keyword',
+ '_GIFBUILDER' : 'keyword',
+ '_LOCAL_LANG' : 'keyword',
+ 'CARRAY' : 'keyword',
+ 'CASE' : 'keyword',
+ 'CLEARGIF' : 'keyword',
+ 'COA' : 'keyword',
+ 'COA_INT' : 'keyword',
+ 'COBJ_ARRAY' : 'keyword',
+ 'COLUMNS' : 'keyword',
+ 'CONFIG' : 'keyword',
+ 'CONSTANTS' : 'keyword',
+ 'CONTENT' : 'keyword',
+ 'CTABLE' : 'keyword',
+ 'CType' : 'keyword',
+ 'DB' : 'keyword',
+ 'DOCUMENT_BODY' : 'keyword',
+ 'EDITPANEL' : 'keyword',
+ 'EFFECT' : 'keyword',
+ 'FE_DATA' : 'keyword',
+ 'FE_TABLE' : 'keyword',
+ 'FEData' : 'keyword',
+ 'FILE' : 'keyword',
+ 'FORM' : 'keyword',
+ 'FRAME' : 'keyword',
+ 'FRAMESET' : 'keyword',
+ 'GIFBUILDER' : 'keyword',
+ 'global' : 'keyword',
+ 'globalString' : 'keyword',
+ 'globalVar' : 'keyword',
+ 'GMENU' : 'keyword',
+ 'GMENU_FOLDOUT' : 'keyword',
+ 'GMENU_LAYERS' : 'keyword',
+ 'GP' : 'keyword',
+ 'HMENU' : 'keyword',
+ 'HRULER' : 'keyword',
+ 'HTML' : 'keyword',
+ 'IENV' : 'keyword',
+ 'IMAGE' : 'keyword',
+ 'IMG_RESOURCE' : 'keyword',
+ 'IMGMENU' : 'keyword',
+ 'IMGMENUITEM' : 'keyword',
+ 'IMGTEXT' : 'keyword',
+ 'INCLUDE_TYPOSCRIPT' : 'keyword',
+ 'includeLibs' : 'keyword',
+ 'JSMENU' : 'keyword',
+ 'JSMENUITEM' : 'keyword',
+ 'LIT' : 'keyword',
+ 'LOAD_REGISTER' : 'keyword',
+ 'META' : 'keyword',
+ 'MULTIMEDIA' : 'keyword',
+ 'OTABLE' : 'keyword',
+ 'PAGE' : 'keyword',
+ 'PAGE_TARGET' : 'keyword',
+ 'PAGE_TSCONFIG_ID' : 'keyword',
+ 'PAGE_TSCONFIG_IDLIST' : 'keyword',
+ 'PAGE_TSCONFIG_STR' : 'keyword',
+ 'PHP_SCRIPT' : 'keyword',
+ 'PHP_SCRIPT_EXT' : 'keyword',
+ 'PHP_SCRIPT_INT' : 'keyword',
+ 'RECORDS' : 'keyword',
+ 'REMOTE_ADDR' : 'keyword',
+ 'RESTORE_REGISTER' : 'keyword',
+ 'RTE' : 'keyword',
+ 'SEARCHRESULT' : 'keyword',
+ 'SHARED' : 'keyword',
+ 'TCAdefaults' : 'keyword',
+ 'TCEFORM' : 'keyword',
+ 'TCEMAIN' : 'keyword',
+ 'TEMPLATE' : 'keyword',
+ 'TEXT' : 'keyword',
+ 'TMENU' : 'keyword',
+ 'TMENU_LAYERS' : 'keyword',
+ 'TMENUITEM' : 'keyword',
+ 'TSFE' : 'keyword',
+ 'USER' : 'keyword',
+ 'USER_INT' : 'keyword',
+ 'userFunc' : 'keyword',
+
+ '_offset' : 'reserved',
+ 'absRefPrefix' : 'reserved',
+ 'accessibility' : 'reserved',
+ 'accessKey' : 'reserved',
+ 'addAttributes' : 'reserved',
+ 'addExtUrlsAndShortCuts' : 'reserved',
+ 'addItems' : 'reserved',
+ 'additionalHeaders' : 'reserved',
+ 'additionalParams' : 'reserved',
+ 'addParams' : 'reserved',
+ 'addQueryString' : 'reserved',
+ 'adjustItemsH' : 'reserved',
+ 'adjustSubItemsH' : 'reserved',
+ 'adminPanelStyles' : 'reserved',
+ 'after' : 'reserved',
+ 'afterImg' : 'reserved',
+ 'afterImgLink' : 'reserved',
+ 'afterImgTagParams' : 'reserved',
+ 'afterROImg' : 'reserved',
+ 'afterWrap' : 'reserved',
+ 'age' : 'reserved',
+ 'alertPopups' : 'reserved',
+ 'align' : 'reserved',
+ 'allow' : 'reserved',
+ 'allowCaching' : 'reserved',
+ 'allowedAttribs' : 'reserved',
+ 'allowedClasses' : 'reserved',
+ 'allowedCols' : 'reserved',
+ 'allowEdit' : 'reserved',
+ 'allowedNewTables' : 'reserved',
+ 'allowNew' : 'reserved',
+ 'allowTags' : 'reserved',
+ 'allowTVlisting' : 'reserved',
+ 'allSaveFunctions' : 'reserved',
+ 'allStdWrap' : 'reserved',
+ 'allWrap' : 'reserved',
+ 'alternateBgColors' : 'reserved',
+ 'alternativeSortingField' : 'reserved',
+ 'alternativeTempPath' : 'reserved',
+ 'altImgResource' : 'reserved',
+ 'altLabels' : 'reserved',
+ 'altTarget' : 'reserved',
+ 'altText' : 'reserved',
+ 'altUrl' : 'reserved',
+ 'altUrl_noDefaultParams' : 'reserved',
+ 'altWrap' : 'reserved',
+ 'always' : 'reserved',
+ 'alwaysActivePIDlist' : 'reserved',
+ 'alwaysLink' : 'reserved',
+ 'alwaysShowClickMenuInTopFrame' : 'reserved',
+ 'andWhere' : 'reserved',
+ 'angle' : 'reserved',
+ 'antiAlias' : 'reserved',
+ 'append' : 'reserved',
+ 'applyTotalH' : 'reserved',
+ 'applyTotalW' : 'reserved',
+ 'archive' : 'reserved',
+ 'archiveTypoLink' : 'reserved',
+ 'arrayReturnMode' : 'reserved',
+ 'arrowACT' : 'reserved',
+ 'arrowImgParams' : 'reserved',
+ 'arrowNO' : 'reserved',
+ 'ATagAfterWrap' : 'reserved',
+ 'ATagBeforeWrap' : 'reserved',
+ 'ATagParams' : 'reserved',
+ 'ATagTitle' : 'reserved',
+ 'attribute' : 'reserved',
+ 'autoInsertPID' : 'reserved',
+ 'autoLevels' : 'reserved',
+ 'autonumber' : 'reserved',
+ 'backColor' : 'reserved',
+ 'background' : 'reserved',
+ 'badMess' : 'reserved',
+ 'baseURL' : 'reserved',
+ 'before' : 'reserved',
+ 'beforeImg' : 'reserved',
+ 'beforeImgLink' : 'reserved',
+ 'beforeImgTagParams' : 'reserved',
+ 'beforeROImg' : 'reserved',
+ 'beforeWrap' : 'reserved',
+ 'begin' : 'reserved',
+ 'beLoginLinkIPList' : 'reserved',
+ 'beLoginLinkIPList_login' : 'reserved',
+ 'beLoginLinkIPList_logout' : 'reserved',
+ 'bgCol' : 'reserved',
+ 'bgImg' : 'reserved',
+ 'blankStrEqFalse' : 'reserved',
+ 'blur' : 'reserved',
+ 'bm' : 'reserved',
+ 'bodyTag' : 'reserved',
+ 'bodyTagAdd' : 'reserved',
+ 'bodyTagCObject' : 'reserved',
+ 'bodyTagMargins' : 'reserved',
+ 'bodytext' : 'reserved',
+ 'border' : 'reserved',
+ 'borderCol' : 'reserved',
+ 'bordersWithin' : 'reserved',
+ 'borderThick' : 'reserved',
+ 'bottomBackColor' : 'reserved',
+ 'bottomContent' : 'reserved',
+ 'bottomHeight' : 'reserved',
+ 'bottomImg' : 'reserved',
+ 'bottomImg_mask' : 'reserved',
+ 'br' : 'reserved',
+ 'brTag' : 'reserved',
+ 'bullet' : 'reserved',
+ 'bulletlist' : 'reserved',
+ 'bytes' : 'reserved',
+ 'cache_clearAtMidnight' : 'reserved',
+ 'cache_period' : 'reserved',
+ 'caption' : 'reserved',
+ 'caption_stdWrap' : 'reserved',
+ 'captionAlign' : 'reserved',
+ 'captionHeader' : 'reserved',
+ 'captionSplit' : 'reserved',
+ 'case' : 'reserved',
+ 'casesensitiveComp' : 'reserved',
+ 'cellpadding' : 'reserved',
+ 'cellspacing' : 'reserved',
+ 'centerImgACT' : 'reserved',
+ 'centerImgCUR' : 'reserved',
+ 'centerImgNO' : 'reserved',
+ 'centerLeftImgACT' : 'reserved',
+ 'centerLeftImgCUR' : 'reserved',
+ 'centerLeftImgNO' : 'reserved',
+ 'centerRightImgACT' : 'reserved',
+ 'centerRightImgCUR' : 'reserved',
+ 'centerRightImgNO' : 'reserved',
+ 'char' : 'reserved',
+ 'charcoal' : 'reserved',
+ 'charMapConfig' : 'reserved',
+ 'check' : 'reserved',
+ 'class' : 'reserved',
+ 'classesAnchor' : 'reserved',
+ 'classesCharacter' : 'reserved',
+ 'classesImage' : 'reserved',
+ 'classesParagraph' : 'reserved',
+ 'classicPageEditMode' : 'reserved',
+ 'clear' : 'reserved',
+ 'clearCache' : 'reserved',
+ 'clearCache_disable' : 'reserved',
+ 'clearCache_pageGrandParent' : 'reserved',
+ 'clearCache_pageSiblingChildren' : 'reserved',
+ 'clearCacheCmd' : 'reserved',
+ 'clearCacheLevels' : 'reserved',
+ 'clearCacheOfPages' : 'reserved',
+ 'clickMenuTimeOut' : 'reserved',
+ 'clickTitleMode' : 'reserved',
+ 'clipboardNumberPads' : 'reserved',
+ 'cMargins' : 'reserved',
+ 'cObjNum' : 'reserved',
+ 'collapse' : 'reserved',
+ 'color' : 'reserved',
+ 'color1' : 'reserved',
+ 'color2' : 'reserved',
+ 'color3' : 'reserved',
+ 'color4' : 'reserved',
+ 'colors' : 'reserved',
+ 'colour' : 'reserved',
+ 'colPos_list' : 'reserved',
+ 'colRelations' : 'reserved',
+ 'cols' : 'reserved',
+ 'colSpace' : 'reserved',
+ 'comment_auto' : 'reserved',
+ 'commentWrap' : 'reserved',
+ 'compensateFieldWidth' : 'reserved',
+ 'compX' : 'reserved',
+ 'compY' : 'reserved',
+ 'condensedMode' : 'reserved',
+ 'conf' : 'reserved',
+ 'constants' : 'reserved',
+ 'content_from_pid_allowOutsideDomain' : 'reserved',
+ 'contextMenu' : 'reserved',
+ 'copyLevels' : 'reserved',
+ 'count_HMENU_MENUOBJ' : 'reserved',
+ 'count_menuItems' : 'reserved',
+ 'count_MENUOBJ' : 'reserved',
+ 'create' : 'reserved',
+ 'createFoldersInEB' : 'reserved',
+ 'crop' : 'reserved',
+ 'csConv' : 'reserved',
+ 'CSS_inlineStyle' : 'reserved',
+ 'current' : 'reserved',
+ 'curUid' : 'reserved',
+ 'cWidth' : 'reserved',
+ 'data' : 'reserved',
+ 'dataWrap' : 'reserved',
+ 'date' : 'reserved',
+ 'date_stdWrap' : 'reserved',
+ 'datePrefix' : 'reserved',
+ 'debug' : 'reserved',
+ 'debugData' : 'reserved',
+ 'debugFunc' : 'reserved',
+ 'debugItemConf' : 'reserved',
+ 'debugRenumberedObject' : 'reserved',
+ 'default' : 'reserved',
+ 'defaultAlign' : 'reserved',
+ 'defaultCmd' : 'reserved',
+ 'defaultFileUploads' : 'reserved',
+ 'defaultHeaderType' : 'reserved',
+ 'defaultOutput' : 'reserved',
+ 'defaults' : 'reserved',
+ 'defaultType' : 'reserved',
+ 'delete' : 'reserved',
+ 'denyTags' : 'reserved',
+ 'depth' : 'reserved',
+ 'DESC' : 'reserved',
+ 'dimensions' : 'reserved',
+ 'directionLeft' : 'reserved',
+ 'directionUp' : 'reserved',
+ 'disableAdvanced' : 'reserved',
+ 'disableAllHeaderCode' : 'reserved',
+ 'disableAltText' : 'reserved',
+ 'disableBigButtons' : 'reserved',
+ 'disableCacheSelector' : 'reserved',
+ 'disableCharsetHeader' : 'reserved',
+ 'disableCMlayers' : 'reserved',
+ 'disabled' : 'reserved',
+ 'disableDelete' : 'reserved',
+ 'disableDocModuleInAB' : 'reserved',
+ 'disableDocSelector' : 'reserved',
+ 'disableHideAtCopy' : 'reserved',
+ 'disableIconLinkToContextmenu' : 'reserved',
+ 'disableItems' : 'reserved',
+ 'disableNewContentElementWizard' : 'reserved',
+ 'disableNoMatchingValueElement' : 'reserved',
+ 'disablePageExternalUrl' : 'reserved',
+ 'disablePrefixComment' : 'reserved',
+ 'disablePrependAtCopy' : 'reserved',
+ 'disableSearchBox' : 'reserved',
+ 'disableSingleTableView' : 'reserved',
+ 'disableTabInTextarea' : 'reserved',
+ 'displayActiveOnLoad' : 'reserved',
+ 'displayContent' : 'reserved',
+ 'displayFieldIcons' : 'reserved',
+ 'displayIcons' : 'reserved',
+ 'displayMessages' : 'reserved',
+ 'displayQueries' : 'reserved',
+ 'displayRecord' : 'reserved',
+ 'displayTimes' : 'reserved',
+ 'distributeX' : 'reserved',
+ 'distributeY' : 'reserved',
+ 'DIV' : 'reserved',
+ 'doctype' : 'reserved',
+ 'doctypeSwitch' : 'reserved',
+ 'doktype' : 'reserved',
+ 'doNotLinkIt' : 'reserved',
+ 'doNotShowLink' : 'reserved',
+ 'doNotStripHTML' : 'reserved',
+ 'dontCheckPid' : 'reserved',
+ 'dontFollowMouse' : 'reserved',
+ 'dontHideOnMouseUp' : 'reserved',
+ 'dontLinkIfSubmenu' : 'reserved',
+ 'dontShowPalettesOnFocusInAB' : 'reserved',
+ 'dontWrapInTable' : 'reserved',
+ 'doubleBrTag' : 'reserved',
+ 'doublePostCheck' : 'reserved',
+ 'dWorkArea' : 'reserved',
+ 'edge' : 'reserved',
+ 'edit_docModuleUplaod' : 'reserved',
+ 'edit_docModuleUpload' : 'reserved',
+ 'edit_RTE' : 'reserved',
+ 'edit_showFieldHelp' : 'reserved',
+ 'edit_wideDocument' : 'reserved',
+ 'editFieldsAtATime' : 'reserved',
+ 'editFormsOnPage' : 'reserved',
+ 'editIcons' : 'reserved',
+ 'editNoPopup' : 'reserved',
+ 'editPanel' : 'reserved',
+ 'elements' : 'reserved',
+ 'emailMeAtLogin' : 'reserved',
+ 'emailMess' : 'reserved',
+ 'emboss' : 'reserved',
+ 'enable' : 'reserved',
+ 'encapsLines' : 'reserved',
+ 'encapsLinesStdWrap' : 'reserved',
+ 'encapsTagList' : 'reserved',
+ 'entryLevel' : 'reserved',
+ 'equalH' : 'reserved',
+ 'everybody' : 'reserved',
+ 'excludeDoktypes' : 'reserved',
+ 'excludeUidList' : 'reserved',
+ 'expAll' : 'reserved',
+ 'expand' : 'reserved',
+ 'explode' : 'reserved',
+ 'ext' : 'reserved',
+ 'externalBlocks' : 'reserved',
+ 'extTarget' : 'reserved',
+ 'face' : 'reserved',
+ 'fe_adminLib' : 'reserved',
+ 'field' : 'reserved',
+ 'fieldOrder' : 'reserved',
+ 'fieldRequired' : 'reserved',
+ 'fields' : 'reserved',
+ 'fieldWrap' : 'reserved',
+ 'file' : 'reserved',
+ 'file1' : 'reserved',
+ 'file2' : 'reserved',
+ 'file3' : 'reserved',
+ 'file4' : 'reserved',
+ 'file5' : 'reserved',
+ 'filelink' : 'reserved',
+ 'filelist' : 'reserved',
+ 'firstLabel' : 'reserved',
+ 'firstLabelGeneral' : 'reserved',
+ 'fixAttrib' : 'reserved',
+ 'flip' : 'reserved',
+ 'flop' : 'reserved',
+ 'foldSpeed' : 'reserved',
+ 'foldTimer' : 'reserved',
+ 'fontColor' : 'reserved',
+ 'fontFile' : 'reserved',
+ 'fontOffset' : 'reserved',
+ 'fontSize' : 'reserved',
+ 'fontSizeMultiplicator' : 'reserved',
+ 'fontTag' : 'reserved',
+ 'forceDisplayFieldIcons' : 'reserved',
+ 'forceDisplayIcons' : 'reserved',
+ 'forceNoPopup' : 'reserved',
+ 'forceTemplateParsing' : 'reserved',
+ 'forceTypeValue' : 'reserved',
+ 'format' : 'reserved',
+ 'frame' : 'reserved',
+ 'frameReloadIfNotInFrameset' : 'reserved',
+ 'frameSet' : 'reserved',
+ 'freezeMouseover' : 'reserved',
+ 'ftu' : 'reserved',
+ 'function' : 'reserved',
+ 'gamma' : 'reserved',
+ 'gapBgCol' : 'reserved',
+ 'gapLineCol' : 'reserved',
+ 'gapLineThickness' : 'reserved',
+ 'gapWidth' : 'reserved',
+ 'get' : 'reserved',
+ 'getBorder' : 'reserved',
+ 'getLeft' : 'reserved',
+ 'getRight' : 'reserved',
+ 'globalNesting' : 'reserved',
+ 'goodMess' : 'reserved',
+ 'gray' : 'reserved',
+ 'group' : 'reserved',
+ 'groupBy' : 'reserved',
+ 'groupid' : 'reserved',
+ 'header' : 'reserved',
+ 'header_layout' : 'reserved',
+ 'headerComment' : 'reserved',
+ 'headerData' : 'reserved',
+ 'headerSpace' : 'reserved',
+ 'headTag' : 'reserved',
+ 'height' : 'reserved',
+ 'helpText' : 'reserved',
+ 'hidden' : 'reserved',
+ 'hiddenFields' : 'reserved',
+ 'hide' : 'reserved',
+ 'hideButCreateMap' : 'reserved',
+ 'hideMenuTimer' : 'reserved',
+ 'hideMenuWhenNotOver' : 'reserved',
+ 'hidePStyleItems' : 'reserved',
+ 'hideRecords' : 'reserved',
+ 'hideSubmoduleIcons' : 'reserved',
+ 'highColor' : 'reserved',
+ 'history' : 'reserved',
+ 'hover' : 'reserved',
+ 'hoverStyle' : 'reserved',
+ 'HTMLparser' : 'reserved',
+ 'HTMLparser_tags' : 'reserved',
+ 'htmlSpecialChars' : 'reserved',
+ 'htmlTag_dir' : 'reserved',
+ 'htmlTag_langKey' : 'reserved',
+ 'htmlTag_setParams' : 'reserved',
+ 'http' : 'reserved',
+ 'icon' : 'reserved',
+ 'icon_image_ext_list' : 'reserved',
+ 'icon_link' : 'reserved',
+ 'iconCObject' : 'reserved',
+ 'ifEmpty' : 'reserved',
+ 'image' : 'reserved',
+ 'image_compression' : 'reserved',
+ 'image_effects' : 'reserved',
+ 'image_frames' : 'reserved',
+ 'imageLinkWrap' : 'reserved',
+ 'imagePath' : 'reserved',
+ 'images' : 'reserved',
+ 'imageWrapIfAny' : 'reserved',
+ 'imgList' : 'reserved',
+ 'imgMap' : 'reserved',
+ 'imgMapExtras' : 'reserved',
+ 'imgMax' : 'reserved',
+ 'imgNameNotRandom' : 'reserved',
+ 'imgNamePrefix' : 'reserved',
+ 'imgObjNum' : 'reserved',
+ 'imgParams' : 'reserved',
+ 'imgPath' : 'reserved',
+ 'imgStart' : 'reserved',
+ 'import' : 'reserved',
+ 'inc' : 'reserved',
+ 'includeCSS' : 'reserved',
+ 'includeLibrary' : 'reserved',
+ 'includeNotInMenu' : 'reserved',
+ 'incT3Lib_htmlmail' : 'reserved',
+ 'index' : 'reserved',
+ 'index_descrLgd' : 'reserved',
+ 'index_enable' : 'reserved',
+ 'index_externals' : 'reserved',
+ 'inlineStyle2TempFile' : 'reserved',
+ 'innerStdWrap' : 'reserved',
+ 'innerStdWrap_all' : 'reserved',
+ 'innerWrap' : 'reserved',
+ 'innerWrap2' : 'reserved',
+ 'input' : 'reserved',
+ 'inputLevels' : 'reserved',
+ 'insertClassesFromRTE' : 'reserved',
+ 'insertData' : 'reserved',
+ 'insertDmailerBoundaries' : 'reserved',
+ 'intensity' : 'reserved',
+ 'intTarget' : 'reserved',
+ 'intval' : 'reserved',
+ 'invert' : 'reserved',
+ 'IProcFunc' : 'reserved',
+ 'itemArrayProcFunc' : 'reserved',
+ 'itemH' : 'reserved',
+ 'items' : 'reserved',
+ 'itemsProcFunc' : 'reserved',
+ 'iterations' : 'reserved',
+ 'join' : 'reserved',
+ 'JSWindow' : 'reserved',
+ 'JSwindow_params' : 'reserved',
+ 'jumpurl' : 'reserved',
+ 'jumpUrl' : 'reserved',
+ 'jumpurl_enable' : 'reserved',
+ 'jumpurl_mailto_disable' : 'reserved',
+ 'jumpUrl_transferSession' : 'reserved',
+ 'keep' : 'reserved',
+ 'keepEntries' : 'reserved',
+ 'keepNonMatchedTags' : 'reserved',
+ 'key' : 'reserved',
+ 'label' : 'reserved',
+ 'labelStdWrap' : 'reserved',
+ 'labelWrap' : 'reserved',
+ 'lang' : 'reserved',
+ 'language' : 'reserved',
+ 'language_alt' : 'reserved',
+ 'languageField' : 'reserved',
+ 'layer_menu_id' : 'reserved',
+ 'layerStyle' : 'reserved',
+ 'left' : 'reserved',
+ 'leftIcons' : 'reserved',
+ 'leftImgACT' : 'reserved',
+ 'leftImgCUR' : 'reserved',
+ 'leftImgNO' : 'reserved',
+ 'leftjoin' : 'reserved',
+ 'leftOffset' : 'reserved',
+ 'levels' : 'reserved',
+ 'leveluid' : 'reserved',
+ 'limit' : 'reserved',
+ 'line' : 'reserved',
+ 'lineColor' : 'reserved',
+ 'lineThickness' : 'reserved',
+ 'linkPrefix' : 'reserved',
+ 'linkTitleToSelf' : 'reserved',
+ 'linkVars' : 'reserved',
+ 'linkWrap' : 'reserved',
+ 'listNum' : 'reserved',
+ 'listOnlyInSingleTableView' : 'reserved',
+ 'lm' : 'reserved',
+ 'locale_all' : 'reserved',
+ 'localNesting' : 'reserved',
+ 'locationData' : 'reserved',
+ 'lockFilePath' : 'reserved',
+ 'lockPosition' : 'reserved',
+ 'lockPosition_addSelf' : 'reserved',
+ 'lockPosition_adjust' : 'reserved',
+ 'lockToIP' : 'reserved',
+ 'longdescURL' : 'reserved',
+ 'lowColor' : 'reserved',
+ 'lower' : 'reserved',
+ 'LR' : 'reserved',
+ 'mailto' : 'reserved',
+ 'main' : 'reserved',
+ 'mainScript' : 'reserved',
+ 'makelinks' : 'reserved',
+ 'markerWrap' : 'reserved',
+ 'mask' : 'reserved',
+ 'max' : 'reserved',
+ 'maxAge' : 'reserved',
+ 'maxAgeDays' : 'reserved',
+ 'maxChars' : 'reserved',
+ 'maxH' : 'reserved',
+ 'maxHeight' : 'reserved',
+ 'maxItems' : 'reserved',
+ 'maxW' : 'reserved',
+ 'maxWidth' : 'reserved',
+ 'maxWInText' : 'reserved',
+ 'mayNotCreateEditShortcuts' : 'reserved',
+ 'menu_type' : 'reserved',
+ 'menuBackColor' : 'reserved',
+ 'menuHeight' : 'reserved',
+ 'menuName' : 'reserved',
+ 'menuOffset' : 'reserved',
+ 'menuWidth' : 'reserved',
+ 'message_page_is_being_generated' : 'reserved',
+ 'message_preview' : 'reserved',
+ 'meta' : 'reserved',
+ 'metaCharset' : 'reserved',
+ 'method' : 'reserved',
+ 'min' : 'reserved',
+ 'minH' : 'reserved',
+ 'minItems' : 'reserved',
+ 'minW' : 'reserved',
+ 'mode' : 'reserved',
+ 'moduleMenuCollapsable' : 'reserved',
+ 'MP_defaults' : 'reserved',
+ 'MP_disableTypolinkClosestMPvalue' : 'reserved',
+ 'MP_mapRootPoints' : 'reserved',
+ 'name' : 'reserved',
+ 'navFrameResizable' : 'reserved',
+ 'navFrameWidth' : 'reserved',
+ 'nesting' : 'reserved',
+ 'netprintApplicationLink' : 'reserved',
+ 'neverHideAtCopy' : 'reserved',
+ 'newPageWiz' : 'reserved',
+ 'newRecordFromTable' : 'reserved',
+ 'newWindow' : 'reserved',
+ 'newWizards' : 'reserved',
+ 'next' : 'reserved',
+ 'niceText' : 'reserved',
+ 'nicetext' : 'reserved',
+ 'no_cache' : 'reserved',
+ 'no_search' : 'reserved',
+ 'noAttrib' : 'reserved',
+ 'noBlur' : 'reserved',
+ 'noCache' : 'reserved',
+ 'noCols' : 'reserved',
+ 'noCreateRecordsLink' : 'reserved',
+ 'noLink' : 'reserved',
+ 'noLinkUnderline' : 'reserved',
+ 'noMatchingValue_label' : 'reserved',
+ 'noMenuMode' : 'reserved',
+ 'nonCachedSubst' : 'reserved',
+ 'nonTypoTagStdWrap' : 'reserved',
+ 'nonTypoTagUserFunc' : 'reserved',
+ 'nonWrappedTag' : 'reserved',
+ 'noOrderBy' : 'reserved',
+ 'noPageTitle' : 'reserved',
+ 'noRows' : 'reserved',
+ 'noScaleUp' : 'reserved',
+ 'noStretchAndMarginCells' : 'reserved',
+ 'noThumbsInEB' : 'reserved',
+ 'noThumbsInRTEimageSelect' : 'reserved',
+ 'notification_email_charset' : 'reserved',
+ 'notification_email_encoding' : 'reserved',
+ 'notification_email_urlmode' : 'reserved',
+ 'noTrimWrap' : 'reserved',
+ 'noValueInsert' : 'reserved',
+ 'obj' : 'reserved',
+ 'offset' : 'reserved',
+ 'offsetWrap' : 'reserved',
+ 'onlineWorkspaceInfo' : 'reserved',
+ 'onlyCurrentPid' : 'reserved',
+ 'opacity' : 'reserved',
+ 'orderBy' : 'reserved',
+ 'outerWrap' : 'reserved',
+ 'outline' : 'reserved',
+ 'outputLevels' : 'reserved',
+ 'override' : 'reserved',
+ 'overrideAttribs' : 'reserved',
+ 'overrideEdit' : 'reserved',
+ 'overrideId' : 'reserved',
+ 'overridePageModule' : 'reserved',
+ 'overrideWithExtension' : 'reserved',
+ 'pageFrameObj' : 'reserved',
+ 'pageGenScript' : 'reserved',
+ 'pageTitleFirst' : 'reserved',
+ 'parameter' : 'reserved',
+ 'params' : 'reserved',
+ 'parseFunc' : 'reserved',
+ 'parser' : 'reserved',
+ 'password' : 'reserved',
+ 'path' : 'reserved',
+ 'permissions' : 'reserved',
+ 'pid_list' : 'reserved',
+ 'pidInList' : 'reserved',
+ 'pixelSpaceFontSizeRef' : 'reserved',
+ 'plaintextLib' : 'reserved',
+ 'plainTextStdWrap' : 'reserved',
+ 'postCObject' : 'reserved',
+ 'postLineBlanks' : 'reserved',
+ 'postLineChar' : 'reserved',
+ 'postLineLen' : 'reserved',
+ 'postUserFunc' : 'reserved',
+ 'postUserFuncInt' : 'reserved',
+ 'preBlanks' : 'reserved',
+ 'preCObject' : 'reserved',
+ 'prefix' : 'reserved',
+ 'prefixComment' : 'reserved',
+ 'prefixLocalAnchors' : 'reserved',
+ 'prefixRelPathWith' : 'reserved',
+ 'preIfEmptyListNum' : 'reserved',
+ 'preLineBlanks' : 'reserved',
+ 'preLineChar' : 'reserved',
+ 'preLineLen' : 'reserved',
+ 'prepend' : 'reserved',
+ 'preserveEntities' : 'reserved',
+ 'preUserFunc' : 'reserved',
+ 'prev' : 'reserved',
+ 'previewBorder' : 'reserved',
+ 'prevnextToSection' : 'reserved',
+ 'printheader' : 'reserved',
+ 'prioriCalc' : 'reserved',
+ 'proc' : 'reserved',
+ 'processScript' : 'reserved',
+ 'properties' : 'reserved',
+ 'protect' : 'reserved',
+ 'protectLvar' : 'reserved',
+ 'publish_levels' : 'reserved',
+ 'QEisDefault' : 'reserved',
+ 'quality' : 'reserved',
+ 'radio' : 'reserved',
+ 'radioWrap' : 'reserved',
+ 'range' : 'reserved',
+ 'rawUrlEncode' : 'reserved',
+ 'recipient' : 'reserved',
+ 'recursive' : 'reserved',
+ 'recursiveDelete' : 'reserved',
+ 'redirect' : 'reserved',
+ 'redirectToURL' : 'reserved',
+ 'reduceColors' : 'reserved',
+ 'register' : 'reserved',
+ 'relativeToParentLayer' : 'reserved',
+ 'relativeToTriggerItem' : 'reserved',
+ 'relPathPrefix' : 'reserved',
+ 'remap' : 'reserved',
+ 'remapTag' : 'reserved',
+ 'removeBadHTML' : 'reserved',
+ 'removeDefaultJS' : 'reserved',
+ 'removeIfEquals' : 'reserved',
+ 'removeIfFalse' : 'reserved',
+ 'removeItems' : 'reserved',
+ 'removeObjectsOfDummy' : 'reserved',
+ 'removePrependedNumbers' : 'reserved',
+ 'removeTags' : 'reserved',
+ 'removeWrapping' : 'reserved',
+ 'renderCharset' : 'reserved',
+ 'renderWrap' : 'reserved',
+ 'reset' : 'reserved',
+ 'resources' : 'reserved',
+ 'resultObj' : 'reserved',
+ 'returnLast' : 'reserved',
+ 'returnUrl' : 'reserved',
+ 'rightImgACT' : 'reserved',
+ 'rightImgCUR' : 'reserved',
+ 'rightImgNO' : 'reserved',
+ 'rightjoin' : 'reserved',
+ 'rm' : 'reserved',
+ 'rmTagIfNoAttrib' : 'reserved',
+ 'RO_chBgColor' : 'reserved',
+ 'rotate' : 'reserved',
+ 'rows' : 'reserved',
+ 'rowSpace' : 'reserved',
+ 'RTEfullScreenWidth' : 'reserved',
+ 'rules' : 'reserved',
+ 'sample' : 'reserved',
+ 'saveClipboard' : 'reserved',
+ 'saveDocNew' : 'reserved',
+ 'secondRow' : 'reserved',
+ 'section' : 'reserved',
+ 'sectionIndex' : 'reserved',
+ 'select' : 'reserved',
+ 'select_key' : 'reserved',
+ 'selectFields' : 'reserved',
+ 'separator' : 'reserved',
+ 'set' : 'reserved',
+ 'setContentToCurrent' : 'reserved',
+ 'setCurrent' : 'reserved',
+ 'setfixed' : 'reserved',
+ 'setFixedHeight' : 'reserved',
+ 'setFixedWidth' : 'reserved',
+ 'setJS_mouseOver' : 'reserved',
+ 'setJS_openPic' : 'reserved',
+ 'setOnly' : 'reserved',
+ 'shadow' : 'reserved',
+ 'sharpen' : 'reserved',
+ 'shear' : 'reserved',
+ 'short' : 'reserved',
+ 'shortcut' : 'reserved',
+ 'shortcut_onEditId_dontSetPageTree' : 'reserved',
+ 'shortcut_onEditId_keepExistingExpanded' : 'reserved',
+ 'shortcutFrame' : 'reserved',
+ 'shortcutGroups' : 'reserved',
+ 'shortcutIcon' : 'reserved',
+ 'show' : 'reserved',
+ 'showAccessRestrictedPages' : 'reserved',
+ 'showActive' : 'reserved',
+ 'showClipControlPanelsDespiteOfCMlayers' : 'reserved',
+ 'showFirst' : 'reserved',
+ 'showHiddenPages' : 'reserved',
+ 'showHiddenRecords' : 'reserved',
+ 'showHistory' : 'reserved',
+ 'showPageIdWithTitle' : 'reserved',
+ 'showTagFreeClasses' : 'reserved',
+ 'simulateDate' : 'reserved',
+ 'simulateStaticDocuments' : 'reserved',
+ 'simulateStaticDocuments_addTitle' : 'reserved',
+ 'simulateStaticDocuments_dontRedirectPathInfoError' : 'reserved',
+ 'simulateStaticDocuments_noTypeIfNoTitle' : 'reserved',
+ 'simulateStaticDocuments_pEnc' : 'reserved',
+ 'simulateStaticDocuments_pEnc_onlyP' : 'reserved',
+ 'simulateUserGroup' : 'reserved',
+ 'singlePid' : 'reserved',
+ 'site_author' : 'reserved',
+ 'site_reserved' : 'reserved',
+ 'sitetitle' : 'reserved',
+ 'siteUrl' : 'reserved',
+ 'size' : 'reserved',
+ 'smallFormFields' : 'reserved',
+ 'solarize' : 'reserved',
+ 'sorting' : 'reserved',
+ 'source' : 'reserved',
+ 'space' : 'reserved',
+ 'spaceAfter' : 'reserved',
+ 'spaceBefore' : 'reserved',
+ 'spaceBelowAbove' : 'reserved',
+ 'spaceLeft' : 'reserved',
+ 'spaceRight' : 'reserved',
+ 'spacing' : 'reserved',
+ 'spamProtectEmailAddresses' : 'reserved',
+ 'spamProtectEmailAddresses_atSubst' : 'reserved',
+ 'spamProtectEmailAddresses_lastDotSubst' : 'reserved',
+ 'special' : 'reserved',
+ 'splitChar' : 'reserved',
+ 'splitRendering' : 'reserved',
+ 'src' : 'reserved',
+ 'startInTaskCenter' : 'reserved',
+ 'stayFolded' : 'reserved',
+ 'stdheader' : 'reserved',
+ 'stdWrap' : 'reserved',
+ 'stdWrap2' : 'reserved',
+ 'strftime' : 'reserved',
+ 'stripHtml' : 'reserved',
+ 'styles' : 'reserved',
+ 'stylesheet' : 'reserved',
+ 'submenuObjSuffixes' : 'reserved',
+ 'subMenuOffset' : 'reserved',
+ 'submit' : 'reserved',
+ 'subst_elementUid' : 'reserved',
+ 'substMarksSeparately' : 'reserved',
+ 'substring' : 'reserved',
+ 'swirl' : 'reserved',
+ 'sword' : 'reserved',
+ 'sword_noMixedCase' : 'reserved',
+ 'SWORD_PARAMS' : 'reserved',
+ 'sword_standAlone' : 'reserved',
+ 'sys_language_mode' : 'reserved',
+ 'sys_language_overlay' : 'reserved',
+ 'sys_language_softMergeIfNotBlank' : 'reserved',
+ 'sys_language_uid' : 'reserved',
+ 'table' : 'reserved',
+ 'tableCellColor' : 'reserved',
+ 'tableParams' : 'reserved',
+ 'tables' : 'reserved',
+ 'tableStdWrap' : 'reserved',
+ 'tableStyle' : 'reserved',
+ 'tableWidth' : 'reserved',
+ 'tags' : 'reserved',
+ 'target' : 'reserved',
+ 'TDparams' : 'reserved',
+ 'templateContent' : 'reserved',
+ 'templateFile' : 'reserved',
+ 'text' : 'reserved',
+ 'textarea' : 'reserved',
+ 'textMargin' : 'reserved',
+ 'textMargin_outOfText' : 'reserved',
+ 'textMaxLength' : 'reserved',
+ 'textObjNum' : 'reserved',
+ 'textPos' : 'reserved',
+ 'textStyle' : 'reserved',
+ 'thickness' : 'reserved',
+ 'thumbnailsByDefault' : 'reserved',
+ 'tile' : 'reserved',
+ 'time_stdWrap' : 'reserved',
+ 'tipafriendLib' : 'reserved',
+ 'title' : 'reserved',
+ 'titleLen' : 'reserved',
+ 'titleTagFunction' : 'reserved',
+ 'titleText' : 'reserved',
+ 'tm' : 'reserved',
+ 'token' : 'reserved',
+ 'topOffset' : 'reserved',
+ 'totalWidth' : 'reserved',
+ 'transparentBackground' : 'reserved',
+ 'transparentColor' : 'reserved',
+ 'trim' : 'reserved',
+ 'tsdebug_tree' : 'reserved',
+ 'type' : 'reserved',
+ 'typeNum' : 'reserved',
+ 'types' : 'reserved',
+ 'typolinkCheckRootline' : 'reserved',
+ 'uidInList' : 'reserved',
+ 'unset' : 'reserved',
+ 'uploadFieldsInTopOfEB' : 'reserved',
+ 'uploads' : 'reserved',
+ 'upper' : 'reserved',
+ 'useCacheHash' : 'reserved',
+ 'useLargestItemX' : 'reserved',
+ 'useLargestItemY' : 'reserved',
+ 'user' : 'reserved',
+ 'userdefined' : 'reserved',
+ 'userfunction' : 'reserved',
+ 'userid' : 'reserved',
+ 'userIdColumn' : 'reserved',
+ 'USERNAME_substToken' : 'reserved',
+ 'userProc' : 'reserved',
+ 'value' : 'reserved',
+ 'valueArray' : 'reserved',
+ 'wave' : 'reserved',
+ 'where' : 'reserved',
+ 'width' : 'reserved',
+ 'wiz' : 'reserved',
+ 'wordSpacing' : 'reserved',
+ 'workArea' : 'reserved',
+ 'wrap' : 'reserved',
+ 'wrap1' : 'reserved',
+ 'wrap2' : 'reserved',
+ 'wrap3' : 'reserved',
+ 'wrapAfterTags' : 'reserved',
+ 'wrapAlign' : 'reserved',
+ 'wrapFieldName' : 'reserved',
+ 'wrapItemAndSub' : 'reserved',
+ 'wrapNonWrappedLines' : 'reserved',
+ 'wraps' : 'reserved',
+ 'xhtml_cleaning' : 'reserved',
+ 'xmlprologue' : 'reserved',
+ 'xPosOffset' : 'reserved',
+ 'yPosOffset' : 'reserved',
+
+ 'admPanel' : 'keyword2',
+ 'alt_print' : 'keyword2',
+ 'auth' : 'keyword2',
+ 'browser' : 'keyword2',
+ 'cache' : 'keyword2',
+ 'CHECK' : 'keyword2',
+ 'cObj' : 'keyword2',
+ 'cObject' : 'keyword2',
+ 'COMMENT' : 'keyword2',
+ 'config' : 'keyword2',
+ 'content' : 'keyword2',
+ 'copy' : 'keyword2',
+ 'CSS_inlineStyle' : 'keyword2',
+ 'cut' : 'keyword2',
+ 'dataArray' : 'keyword2',
+ 'dayofmonth' : 'keyword2',
+ 'dayofweek' : 'keyword2',
+ 'db_list' : 'keyword2',
+ 'device' : 'keyword2',
+ 'dynCSS' : 'keyword2',
+ 'edit' : 'keyword2',
+ 'edit_access' : 'keyword2',
+ 'edit_pageheader' : 'keyword2',
+ 'folder' : 'keyword2',
+ 'folderTree' : 'keyword2',
+ 'foldoutMenu' : 'keyword2',
+ 'Functions' : 'keyword2',
+ 'gmenu_foldout' : 'keyword2',
+ 'gmenu_layers' : 'keyword2',
+ 'hostname' : 'keyword2',
+ 'hour' : 'keyword2',
+ 'imgList' : 'keyword2',
+ 'imgResource' : 'keyword2',
+ 'imgText' : 'keyword2',
+ 'info' : 'keyword2',
+ 'IP' : 'keyword2',
+ 'jsmenu' : 'keyword2',
+ 'JSwindow' : 'keyword2',
+ 'LABEL' : 'keyword2',
+ 'layout' : 'keyword2',
+ 'lib' : 'keyword2',
+ 'loginUser' : 'keyword2',
+ 'marks' : 'keyword2',
+ 'minute' : 'keyword2',
+ 'mod' : 'keyword2',
+ 'module' : 'keyword2',
+ 'month' : 'keyword2',
+ 'move_wizard' : 'keyword2',
+ 'new' : 'keyword2',
+ 'new_wizard' : 'keyword2',
+ 'noResultObj' : 'keyword2',
+ 'numRows' : 'keyword2',
+ 'options' : 'keyword2',
+ 'page' : 'keyword2',
+ 'pageTree' : 'keyword2',
+ 'paste' : 'keyword2',
+ 'perms' : 'keyword2',
+ 'PIDinRootline' : 'keyword2',
+ 'PIDupinRootline' : 'keyword2',
+ 'plugin' : 'keyword2',
+ 'postform' : 'keyword2',
+ 'postform_newThread' : 'keyword2',
+ 'preview' : 'keyword2',
+ 'publish' : 'keyword2',
+ 'RADIO' : 'keyword2',
+ 'renderObj' : 'keyword2',
+ 'REQ' : 'keyword2',
+ 'RTE' : 'keyword2',
+ 'RTE_compliant' : 'keyword2',
+ 'select' : 'keyword2',
+ 'setup' : 'keyword2',
+ 'split' : 'keyword2',
+ 'stat' : 'keyword2',
+ 'stat_apache' : 'keyword2',
+ 'stat_apache_logfile' : 'keyword2',
+ 'stat_apache_noHost' : 'keyword2',
+ 'stat_apache_notExtended' : 'keyword2',
+ 'stat_apache_pagenames' : 'keyword2',
+ 'stat_excludeBEuserHits' : 'keyword2',
+ 'stat_excludeIPList' : 'keyword2',
+ 'stat_mysql' : 'keyword2',
+ 'stat_titleLen' : 'keyword2',
+ 'stat_typeNumList' : 'keyword2',
+ 'stdWrap' : 'keyword2',
+ 'subparts' : 'keyword2',
+ 'system' : 'keyword2',
+ 'temp' : 'keyword2',
+ 'template' : 'keyword2',
+ 'treeLevel' : 'keyword2',
+ 'tsdebug' : 'keyword2',
+ 'typolink' : 'keyword2',
+ 'url' : 'keyword2',
+ 'useragent' : 'keyword2',
+ 'userFunc' : 'keyword2',
+ 'version' : 'keyword2',
+ 'view' : 'keyword2',
+ 'workOnSubpart' : 'keyword2',
+
+ 'ACT' : 'keyword3',
+ 'ACTIFSUB' : 'keyword3',
+ 'ACTIFSUBRO' : 'keyword',
+ 'ACTRO' : 'keyword3',
+ 'all' : 'keyword3',
+ 'arrowACT' : 'keyword3',
+ 'arrowNO' : 'keyword3',
+ 'ascii' : 'keyword3',
+ 'atLeast' : 'keyword3',
+ 'atMost' : 'keyword3',
+ 'BE' : 'keyword3',
+ 'be_groups' : 'keyword3',
+ 'be_users' : 'keyword3',
+ 'BOX' : 'keyword3',
+ 'browse' : 'keyword3',
+ 'bullets' : 'keyword3',
+ 'CUR' : 'keyword3',
+ 'CURIFSUB' : 'keyword3',
+ 'CURIFSUBRO' : 'keyword3',
+ 'CURRO' : 'keyword3',
+ 'default' : 'keyword3',
+ 'description' : 'keyword3',
+ 'directory' : 'keyword3',
+ 'directReturn' : 'keyword3',
+ 'div' : 'keyword3',
+ 'else' : 'keyword3',
+ 'email' : 'keyword3',
+ 'end' : 'keyword3',
+ 'equals' : 'keyword3',
+ 'external' : 'keyword3',
+ 'false' : 'keyword3',
+ 'FE' : 'keyword3',
+ 'fe_groups' : 'keyword3',
+ 'fe_users' : 'keyword3',
+ 'feadmin' : 'keyword3',
+ 'header' : 'keyword3',
+ 'html' : 'keyword3',
+ 'id' : 'keyword3',
+ 'if' : 'keyword3',
+ 'ifEmpty' : 'keyword3',
+ 'IFSUB' : 'keyword3',
+ 'IFSUBRO' : 'keyword3',
+ 'image' : 'keyword3',
+ 'inBranch' : 'keyword3',
+ 'isFalse' : 'keyword3',
+ 'isGreaterThan' : 'keyword3',
+ 'isInList' : 'keyword3',
+ 'isLessThan' : 'keyword3',
+ 'isPositive' : 'keyword3',
+ 'isTrue' : 'keyword3',
+ 'keyword3' : 'keyword3',
+ 'language' : 'keyword3',
+ 'leveltitle' : 'keyword3',
+ 'list' : 'keyword3',
+ 'login' : 'keyword3',
+ 'mailform' : 'keyword3',
+ 'media' : 'keyword3',
+ 'menu' : 'keyword3',
+ 'mod' : 'keyword3',
+ 'multimedia' : 'keyword3',
+ 'negate' : 'keyword3',
+ 'NEW' : 'keyword3',
+ 'NO' : 'keyword3',
+ 'none' : 'keyword3',
+ 'pages' : 'keyword3',
+ 'pages_language_overlay' : 'keyword3',
+ 'parseFunc_RTE' : 'keyword3',
+ 'pid' : 'keyword3',
+ 'required' : 'keyword3',
+ 'RO' : 'keyword3',
+ 'rootline' : 'keyword3',
+ 'script' : 'keyword3',
+ 'search' : 'keyword3',
+ 'shortcut' : 'keyword3',
+ 'sitemap' : 'keyword3',
+ 'SPC' : 'keyword3',
+ 'splash' : 'keyword3',
+ 'sys_dmail' : 'keyword3',
+ 'sys_domain' : 'keyword3',
+ 'sys_filemounts' : 'keyword3',
+ 'sys_note' : 'keyword3',
+ 'sys_template' : 'keyword3',
+ 'tabel' : 'keyword3',
+ 'text' : 'keyword3',
+ 'textpic' : 'keyword3',
+ 'this' : 'keyword3',
+ 'top' : 'keyword3',
+ 'true' : 'keyword3',
+ 'tt_address' : 'keyword3',
+ 'tt_board' : 'keyword3',
+ 'tt_board_list' : 'keyword3',
+ 'tt_board_tree' : 'keyword3',
+ 'tt_calender' : 'keyword3',
+ 'tt_content' : 'keyword3',
+ 'tt_guest' : 'keyword3',
+ 'tt_news' : 'keyword3',
+ 'tt_poll' : 'keyword3',
+ 'tt_products' : 'keyword3',
+ 'tt_rating' : 'keyword3',
+ 'twice' : 'keyword3',
+ 'tx_automaketemplate_pi1' : 'keyword3',
+ 'tx_belog_webinfo' : 'keyword3',
+ 'tx_browserpagetitle' : 'keyword3',
+ 'tx_browserpagetitle_browser_title' : 'keyword3',
+ 'tx_chcforum_pi1' : 'keyword3',
+ 'tx_cms_layout' : 'keyword3',
+ 'tx_cms_webinfo_hits' : 'keyword3',
+ 'tx_cms_webinfo_lang' : 'keyword3',
+ 'tx_cms_webinfo_page' : 'keyword3',
+ 'tx_cssstyledcontent_pi1' : 'keyword3',
+ 'tx_dephpot_pi1' : 'keyword3',
+ 'tx_extkey' : 'keyword3',
+ 'tx_extkey_controllers' : 'keyword3',
+ 'tx_extkey_login' : 'keyword3',
+ 'tx_extrapagecmoptions' : 'keyword3',
+ 'tx_funcwizards_webfunc' : 'keyword3',
+ 'tx_gooffotoboek_pi1' : 'keyword3',
+ 'tx_impexp' : 'keyword3',
+ 'tx_impexp_clickmenu' : 'keyword3',
+ 'tx_impexp_modfunc1' : 'keyword3',
+ 'tx_indexed_search_extparse' : 'keyword3',
+ 'tx_indexedsearch' : 'keyword3',
+ 'tx_indexedsearch_indexer' : 'keyword3',
+ 'tx_indexedsearch_lexer' : 'keyword3',
+ 'tx_indexedsearch_modfunc1' : 'keyword3',
+ 'tx_indexedsearch_modfunc2' : 'keyword3',
+ 'tx_indexedsearch_pihook' : 'keyword3',
+ 'tx_infopagetsconfig_webinfo' : 'keyword3',
+ 'tx_install' : 'keyword3',
+ 'tx_lzgallery_pi1' : 'keyword3',
+ 'tx_mhajaxsearch_pi1' : 'keyword3',
+ 'tx_mhajaxsearch_q' : 'keyword3',
+ 'tx_mhajaxsearch_result' : 'keyword3',
+ 'tx_mhajaxsearch_search' : 'keyword3',
+ 'tx_newloginbox_pi1' : 'keyword3',
+ 'tx_newloginbox_pi3' : 'keyword3',
+ 'tx_open_printlink' : 'keyword3',
+ 'tx_pdfgenerator' : 'keyword3',
+ 'tx_realurl_advanced' : 'keyword3',
+ 'tx_realurl_enable' : 'keyword3',
+ 'tx_realurl_pathsegment' : 'keyword3',
+ 'tx_realurl_pi1' : 'keyword3',
+ 'tx_rlmptmplselector' : 'keyword3',
+ 'tx_rlmptmplselector_pi1' : 'keyword3',
+ 'tx_sochat_pi1' : 'keyword3',
+ 'tx_srfeuserregister_pi1' : 'keyword3',
+ 'tx_sv_auth' : 'keyword3',
+ 'tx_sv_authbase' : 'keyword3',
+ 'tx_sysaction' : 'keyword3',
+ 'tx_templavoila_pi1' : 'keyword3',
+ 'tx_terdoc_pi1' : 'keyword3',
+ 'tx_ttnews' : 'keyword3',
+ 'tx_ttnews_catmenu' : 'keyword3',
+ 'tx_ttnews_itemsProcFunc' : 'keyword3',
+ 'tx_ttnews_tcemain' : 'keyword3',
+ 'tx_ttnews_treeview=' : 'keyword3',
+ 'tx_ttproducts_pi1' : 'keyword3',
+ 'tx_veguestbook_pi1' : 'keyword3',
+ 'tx_version_cm1' : 'keyword3',
+ 'tx_vjchat_chat' : 'keyword3',
+ 'tx_vjchat_pi1' : 'keyword3',
+ 'tx_wizardcrpages_webfunc_2' : 'keyword3',
+ 'tx_wizardsortpages_webfunc_2' : 'keyword3',
+ 'tx_wwwebstats4u_pi1' : 'keyword3',
+ 'uid' : 'keyword3',
+ 'uniqueGlobal' : 'keyword3',
+ 'uniqueLocal' : 'keyword3',
+ 'unsetEmpty' : 'keyword3',
+ 'updated' : 'keyword3',
+ 'uploads' : 'keyword3',
+ 'us' : 'keyword3',
+ 'user_task' : 'keyword3',
+ 'USERDEF1' : 'keyword3',
+ 'USERDEF1RO' : 'keyword3',
+ 'USERDEF2' : 'keyword3',
+ 'USERDEF2RO' : 'keyword3',
+ 'usergroup' : 'keyword3',
+ 'USR' : 'keyword3',
+ 'USRRO' : 'keyword3',
+ 'web_func' : 'keyword3',
+ 'web_info' : 'keyword3',
+ 'web_layout' : 'keyword3',
+ 'web_list' : 'keyword3',
+ 'web_ts' : 'keyword',
+ 'xhtml_strict' : 'keyword3',
+ 'xhtml_trans' : 'keyword3',
+ 'XY' : 'keyword3',
+ 'ypMenu' : 'keyword3'
+}
+
+var tokenizeTypoScript = function(){
+
+ // Some helper regexp matchers.
+ var isOperatorChar = matcher(/[\+\-\*\&\%\/=<>!\?]/);
+ var isDigit = matcher(/[0-9]/);
+ var isHexDigit = matcher(/[0-9A-Fa-f]/);
+ var isWordChar = matcher(/[\w\$_]/);
+ function isWhiteSpace(ch){
+ // Unfortunately, IE's regexp matcher thinks non-breaking spaces
+ // aren't whitespace. Also, in our scheme newlines are no
+ // whitespace (they are another special case).
+ return ch != "\n" && (ch == nbsp || /\s/.test(ch));
+ }
+
+ // This function produces a MochiKit-style iterator that tokenizes
+ // the output of the given stringstream (see stringstream.js).
+ // Tokens are objects with a type, style, and value property. The
+ // value contains the textual content of the token. Because this may
+ // include trailing whitespace (for efficiency reasons), some
+ // tokens, such a variable names, also have a name property
+ // containing their actual textual value.
+ return function(source){
+ // Produce a value to return. Automatically skips and includes any
+ // whitespace. The base argument is prepended to the value
+ // property and assigned to the name property -- this is used when
+ // the caller has already extracted the text from the stream
+ // himself.
+ function result(type, style, base){
+ // nextWhile(isWhiteSpace); - comment thats line because needed for autocomplete
+ var value = {type: type, style: style, value: (base ? base + source.get() : source.get())};
+ if (base) value.name = base;
+ return value;
+ }
+
+ // Advance the text stream over characters for which test returns
+ // true. (The characters that are 'consumed' like this can later
+ // be retrieved by calling source.get()).
+ function nextWhile(test){
+ var next;
+ while((next = source.peek()) && test(next))
+ source.next();
+ }
+ // Advance the stream until the given character (not preceded by a
+ // backslash) is encountered (or a newline is found).
+ function nextUntilUnescaped(end){
+ var escaped = false;
+ var next;
+ while((next = source.peek()) && next != "\n"){
+ source.next();
+ if (next == end && !escaped)
+ break;
+ escaped = next == "\\";
+ }
+ }
+
+ function readHexNumber(){
+ source.next(); // skip the 'x'
+ nextWhile(isHexDigit);
+ return result("number", "atom");
+ }
+ function readNumber(){
+ nextWhile(isDigit);
+ if (source.peek() == "."){
+ source.next();
+ nextWhile(isDigit);
+ }
+ if (source.peek() == "e" || source.peek() == "E"){
+ source.next();
+ if (source.peek() == "-")
+ source.next();
+ nextWhile(isDigit);
+ }
+ return result("number", "atom");
+ }
+ // Read a word, look it up in keywords. If not found, it is a
+ // variable, otherwise it is a keyword of the type found.
+ function readWord(){
+ nextWhile(isWordChar);
+ var word = source.get();
+ var known = typoscriptWords.hasOwnProperty(word) && {type: 'keyword', style: typoscriptWords[word]};
+ return known ? result(known.type, known.style, word) : result("variable", "other", word);
+ }
+ function readRegexp(){
+ nextUntilUnescaped("/");
+ nextWhile(matcher(/[gi]/));
+ return result("regexp", "string");
+ }
+ // Mutli-line comments are tricky. We want to return the newlines
+ // embedded in them as regular newline tokens, and then continue
+ // returning a comment token for every line of the comment. So
+ // some state has to be saved (inComment) to indicate whether we
+ // are inside a /* */ sequence.
+ function readMultilineComment(start){
+ this.inComment = true;
+ var maybeEnd = (start == "*");
+ while(true){
+ var next = source.peek();
+ if (next == "\n")
+ break;
+ source.next();
+ if (next == "/" && maybeEnd){
+ this.inComment = false;
+ break;
+ }
+ maybeEnd = (next == "*");
+ }
+ return result("comment", "comment");
+ }
+
+ // Fetch the next token. Dispatches on first character in the
+ // stream, or first two characters when the first is a slash. The
+ // || things are a silly trick to keep simple cases on a single
+ // line.
+ function next(){
+ var token = null;
+ var ch = source.next();
+ if (ch == "\n")
+ token = {type: "newline", style: "whitespace", value: source.get()};
+ else if (this.inComment)
+ token = readMultilineComment.call(this, ch);
+ else if (isWhiteSpace(ch))
+ token = nextWhile(isWhiteSpace) || result("whitespace", "whitespace");
+ else if (ch == "\"" || ch == "'")
+ token = nextUntilUnescaped(ch) || result("string", "string");
+ // with punctuation, the type of the token is the symbol itself
+ else if (/[\[\]{}\(\),;\:\.]/.test(ch))
+ token = result(ch, "punctuation");
+ else if (ch == "0" && (source.peek() == "x" || source.peek() == "X"))
+ token = readHexNumber();
+ else if (isDigit(ch))
+ token = readNumber();
+ else if (ch == "/"){
+ next = source.peek();
+ if (next == "*")
+ token = readMultilineComment.call(this, ch);
+ else if (next == "/")
+ token = nextUntilUnescaped(null) || result("comment", "comment");
+ else if (this.regexp)
+ token = readRegexp();
+ else
+ token = nextWhile(isOperatorChar) || result("operator", "operator");
+ } else if (ch == "#")
+ token = nextUntilUnescaped(null) || result("comment", "comment");
+ else if (isOperatorChar(ch))
+ token = nextWhile(isOperatorChar) || result("operator", "operator");
+ else
+ token = readWord();
+
+ // JavaScript's syntax rules for when a slash might be the start
+ // of a regexp and when it is just a division operator are kind
+ // of non-obvious. This decides, based on the current token,
+ // whether the next token could be a regular expression.
+ if (token.style != "whitespace" && token != "comment")
+ this.regexp = token.type == "operator" || token.type == "keyword c" || token.type.match(/[\[{}\(,;:]/);
+ return token;
+ }
+
+ // Wrap it in an iterator. The state (regexp and inComment) is
+ // exposed because a parser will need to save it when making a
+ // copy of its state.
+ return {next: next, regexp: true, inComment: false};
+ }
+}();
--- /dev/null
+/* A few useful utility functions. */
+
+// Retrieve the next value from an iterator, or return an alternative
+// value if the iterator is at its end.
+function nextOr(iter, alternative){
+ try {
+ return iter.next();
+ }
+ catch (e) {
+ if (e != StopIteration)
+ throw e;
+ else return alternative;
+ }
+}
+
+// Create an ojbect to represent a set. Takes any number of strings as
+// arguments, and returns an object in which the properties named by
+// these strings are set to true.
+function setObject(){
+ var obj = {};
+ forEach(arguments, function(value){
+ obj[value] = true;
+ });
+ return obj;
+}
+
+// Create a predicate function that tests a string againsts a given
+// regular expression.
+function matcher(regexp){
+ return function(value){return regexp.test(value);};
+}
+
+// Test whether a DOM node has a certain CSS class. Much faster than
+// the MochiKit equivalent, for some reason.
+function hasClass(element, className){
+ var classes = element.className;
+ return classes && new RegExp("(^| )" + className + "($| )").test(classes);
+}
+
+function repeatString(str, times) {
+ var result = [];
+ while(times--) result.push(str);
+ return result.join("");
+}
+
+// Insert a DOM node after another node.
+function insertAfter(newNode, oldNode) {
+ var parent = oldNode.parentNode;
+ var next = oldNode.nextSibling;
+ if (next)
+ parent.insertBefore(newNode, next);
+ else
+ parent.appendChild(newNode);
+ return newNode;
+}
+
+// Insert a dom node at the start of a container.
+function insertAtStart(node, container) {
+ if (container.firstChild)
+ container.insertBefore(node, container.firstChild);
+ else
+ container.appendChild(node);
+ return node;
+}
+
+// Check whether a node is contained in another one.
+function isAncestor(node, child) {
+ while (child = child.parentNode) {
+ if (node == child)
+ return true;
+ }
+ return false;
+}
+
+// The non-breaking space character.
+var nbsp = String.fromCharCode(160);