PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i5h-3LL

HOME


5h-3LL 1.0
DIR: /srv/http/vyvoj.adent.cz/vyvoj/lib/ckeditor/ckeditor-3.6.3
/srv/http/vyvoj.adent.cz/vyvoj/lib/ckeditor/ckeditor-3.6.3/
Upload File:
Current File : /srv/http/vyvoj.adent.cz/vyvoj/lib/ckeditor/ckeditor-3.6.3/ckeditor.asp
<%
 '
 ' Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
 ' For licensing, see LICENSE.html or http://ckeditor.com/license

' Shared variable for all instances ("static")
dim CKEDITOR_initComplete
dim CKEDITOR_returnedEvents

 ''
 ' \brief CKEditor class that can be used to create editor
 ' instances in ASP pages on server side.
 ' @see http://ckeditor.com
 '
 ' Sample usage:
 ' @code
 ' editor = new CKEditor
 ' editor.editor "editor1", "<p>Initial value.</p>", empty, empty
 ' @endcode

Class CKEditor

	''
	' The version of %CKEditor.
	private version

	''
	' A constant string unique for each release of %CKEditor.
	private mTimeStamp

	''
	' URL to the %CKEditor installation directory (absolute or relative to document root).
	' If not set, CKEditor will try to guess it's path.
	'
	' Example usage:
	' @code
	' editor.basePath = "/ckeditor/"
	' @endcode
	Public basePath

	''
	' A boolean variable indicating whether CKEditor has been initialized.
	' Set it to true only if you have already included
	' &lt;script&gt; tag loading ckeditor.js in your website.
	Public initialized

	''
	' Boolean variable indicating whether created code should be printed out or returned by a function.
	'
	' Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function.
	' @code
	' editor = new CKEditor
	' editor.returnOutput = true
	' code = editor.editor("editor1", "<p>Initial value.</p>", empty, empty)
	' response.write "<p>Editor 1:</p>"
	' response.write code
	' @endcode
	Public returnOutput

	''
	' A Dictionary with textarea attributes.
	'
	' When %CKEditor is created with the editor() method, a HTML &lt;textarea&gt; element is created,
	' it will be displayed to anyone with JavaScript disabled or with incompatible browser.
	public textareaAttributes

	''
	' A string indicating the creation date of %CKEditor.
	' Do not change it unless you want to force browsers to not use previously cached version of %CKEditor.
	public timestamp

	''
	' A dictionary that holds the instance configuration.
	private oInstanceConfig

	''
	' A dictionary that holds the configuration for all the instances.
	private oAllInstancesConfig

	''
	' A dictionary that holds event listeners for the instance.
	private oInstanceEvents

	''
	' A dictionary that holds event listeners for all the instances.
	private oAllInstancesEvents

	''
	' A Dictionary that holds global event listeners (CKEDITOR object)
	private oGlobalEvents


	Private Sub Class_Initialize()
		version = "3.6.3"
		timeStamp = "C3HA5RM"
		mTimeStamp = "C3HA5RM"

		Set oInstanceConfig = CreateObject("Scripting.Dictionary")
		Set oAllInstancesConfig = CreateObject("Scripting.Dictionary")

		Set oInstanceEvents = CreateObject("Scripting.Dictionary")
		Set oAllInstancesEvents = CreateObject("Scripting.Dictionary")
		Set oGlobalEvents = CreateObject("Scripting.Dictionary")

		Set textareaAttributes = CreateObject("Scripting.Dictionary")
		textareaAttributes.Add "rows", 8
		textareaAttributes.Add "cols", 60
	End Sub

	''
	 ' Creates a %CKEditor instance.
	 ' In incompatible browsers %CKEditor will downgrade to plain HTML &lt;textarea&gt; element.
	 '
	 ' @param name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element).
	 ' @param value (string) Initial value.
	 '
	 ' Example usage:
	 ' @code
	 ' set editor = New CKEditor
	 ' editor.editor "field1", "<p>Initial value.</p>"
	 ' @endcode
	 '
	 ' Advanced example:
	 ' @code
	 ' set editor = new CKEditor
	 ' set config = CreateObject("Scripting.Dictionary")
	 ' config.Add "toolbar", Array( _
	 '	Array( "Source", "-", "Bold", "Italic", "Underline", "Strike" ), _
	 '	Array( "Image", "Link", "Unlink", "Anchor" ) _
	 ' )
	 ' set events = CreateObject("Scripting.Dictionary")
	 ' events.Add "instanceReady", "function (evt) { alert('Loaded second editor: ' + evt.editor.name );}"

	 ' editor.editor "field1", "<p>Initial value.</p>", config, events
	 ' @endcode
	 '
	public function editor(name, value)
		dim attr, out, js, customConfig, extraConfig
		dim attribute

		attr = ""

		for each attribute in textareaAttributes
			attr = attr & " " &  attribute & "=""" & replace( textareaAttributes( attribute ), """", "&quot" ) & """"
		next

		out = "<textarea name=""" & name & """" & attr & ">" & Server.HtmlEncode(value) & "</textarea>" & vbcrlf

		if not(initialized) then
			out = out & init()
		end if

		set customConfig = configSettings()
		js = returnGlobalEvents()

		extraConfig = (new JSON)( empty, customConfig, false )
		if extraConfig<>"" then extraConfig = ", " & extraConfig
		js = js & "CKEDITOR.replace('" & name & "'" & extraConfig & ");"

		out = out & script(js)

		if not(returnOutput) then
			response.write out
			out = ""
		end if

		editor = out

		oInstanceConfig.RemoveAll
		oInstanceEvents.RemoveAll
	end function

	''
	 ' Replaces a &lt;textarea&gt; with a %CKEditor instance.
	 '
	 ' @param id (string) The id or name of textarea element.
	 '
	 ' Example 1: adding %CKEditor to &lt;textarea name="article"&gt;&lt;/textarea&gt; element:
	 ' @code
	 ' set editor = New CKEditor
	 ' editor.replace "article"
	 ' @endcode
	 '
	public function replaceInstance(id)
		dim out, js, customConfig, extraConfig

		out = ""
		if not(initialized) then
			out = out & init()
		end if

		set customConfig = configSettings()
		js = returnGlobalEvents()

		extraConfig = (new JSON)( empty, customConfig, false )
		if extraConfig<>"" then extraConfig = ", " & extraConfig
		js = js & "CKEDITOR.replace('" & id & "'" & extraConfig & ");"

		out = out & script(js)

		if not(returnOutput) then
			response.write out
			out = ""
		end if

		replaceInstance = out

		oInstanceConfig.RemoveAll
		oInstanceEvents.RemoveAll
	end function

	''
	 ' Replace all &lt;textarea&gt; elements available in the document with editor instances.
	 '
	 ' @param className (string) If set, replace all textareas with class className in the page.
	 '
	 ' Example 1: replace all &lt;textarea&gt; elements in the page.
	 ' @code
	 ' editor = new CKEditor
	 ' editor.replaceAll empty
	 ' @endcode
	 '
	 ' Example 2: replace all &lt;textarea class="myClassName"&gt; elements in the page.
	 ' @code
	 ' editor = new CKEditor
	 ' editor.replaceAll 'myClassName'
	 ' @endcode
	 '
	function replaceAll(className)
		dim out, js, customConfig

		out = ""
		if not(initialized) then
			out = out & init()
		end if

		set customConfig = configSettings()
		js = returnGlobalEvents()

		if (customConfig.Count=0) then
			if (isEmpty(className)) then
				js = js & "CKEDITOR.replaceAll();"
			else
				js = js & "CKEDITOR.replaceAll('" & className & "');"
			end if
		else
			js = js & "CKEDITOR.replaceAll( function(textarea, config) {\n"
			if not(isEmpty(className)) then
				js = js & "	var classRegex = new RegExp('(?:^| )' + '" & className & "' + '(?:$| )');\n"
				js = js & "	if (!classRegex.test(textarea.className))\n"
				js = js & "		return false;\n"
			end if
			js = js & "	CKEDITOR.tools.extend(config, " & (new JSON)( empty, customConfig, false ) & ", true);"
			js = js & "} );"
		end if

		out = out & script(js)

		if not(returnOutput) then
			response.write out
			out = ""
		end if

		replaceAll = out

		oInstanceConfig.RemoveAll
		oInstanceEvents.RemoveAll
	end function


	''
	' A Dictionary that holds the %CKEditor configuration for all instances
	' For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
	'
	' Example usage:
	' @code
	' editor.config("height") = 400
	' // Use @@ at the beggining of a string to ouput it without surrounding quotes.
	' editor.config("width") = "@@screen.width * 0.8"
	' @endcode
	Public Property Let Config( configKey, configValue )
		oAllInstancesConfig.Add configKey, configValue
	End Property

	''
	' Configuration options for the next instance
	'
	Public Property Let instanceConfig( configKey, configValue )
		oInstanceConfig.Add configKey, configValue
	End Property

	''
	 ' Adds event listener.
	 ' Events are fired by %CKEditor in various situations.
	 '
	 ' @param eventName (string) Event name.
	 ' @param javascriptCode (string) Javascript anonymous function or function name.
	 '
	 ' Example usage:
	 ' @code
	 ' editor.addEventHandler  "instanceReady", "function (ev) { " & _
	 '    " alert('Loaded: ' + ev.editor.name); " & _
	 ' "}"
	 ' @endcode
	 '
	public sub addEventHandler(eventName, javascriptCode)
		if not(oAllInstancesEvents.Exists( eventName ) ) then
			oAllInstancesEvents.Add eventName, Array()
		end if

		dim listeners, size
		listeners = oAllInstancesEvents( eventName )
		size = ubound(listeners) + 1
		redim preserve listeners(size)
		listeners(size) = javascriptCode

		oAllInstancesEvents( eventName ) = listeners
'		'' Avoid duplicates. fixme...
'		if (!in_array($javascriptCode, $this->_events[$event])) {
'			$this->_events[$event][] = $javascriptCode;
'		}
	end sub

	''
	 ' Clear registered event handlers.
	 ' Note: this function will have no effect on already created editor instances.
	 '
	 ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed.
	 '
	public sub clearEventHandlers( eventName )
		if not(isEmpty( eventName )) then
			oAllInstancesEvents.Remove eventName
		else
			oAllInstancesEvents.RemoveAll
		end if
	end sub


	''
	 ' Adds event listener only for the next instance.
	 ' Events are fired by %CKEditor in various situations.
	 '
	 ' @param eventName (string) Event name.
	 ' @param javascriptCode (string) Javascript anonymous function or function name.
	 '
	 ' Example usage:
	 ' @code
	 ' editor.addInstanceEventHandler  "instanceReady", "function (ev) { " & _
	 '    " alert('Loaded: ' + ev.editor.name); " & _
	 ' "}"
	 ' @endcode
	 '
	public sub addInstanceEventHandler(eventName, javascriptCode)
		if not(oInstanceEvents.Exists( eventName ) ) then
			oInstanceEvents.Add eventName, Array()
		end if

		dim listeners, size
		listeners = oInstanceEvents( eventName )
		size = ubound(listeners) + 1
		redim preserve listeners(size)
		listeners(size) = javascriptCode

		oInstanceEvents( eventName ) = listeners
'		'' Avoid duplicates. fixme...
'		if (!in_array($javascriptCode, $this->_events[$event])) {
'			$this->_events[$event][] = $javascriptCode;
'		}
	end sub

	''
	 ' Clear registered event handlers.
	 ' Note: this function will have no effect on already created editor instances.
	 '
	 ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed.
	 '
	public sub clearInstanceEventHandlers( eventName )
		if not(isEmpty( eventName )) then
			oInstanceEvents.Remove eventName
		else
			oInstanceEvents.RemoveAll
		end if
	end sub

	''
	 ' Adds global event listener.
	 '
	 ' @param event (string) Event name.
	 ' @param javascriptCode (string) Javascript anonymous function or function name.
	 '
	 ' Example usage:
	 ' @code
	 ' editor.addGlobalEventHandler "dialogDefinition", "function (ev) { " & _
	 '   "  alert('Loading dialog: ' + ev.data.name); " & _
	 ' "}"
	 ' @endcode
	 '
	public sub addGlobalEventHandler( eventName, javascriptCode)
		if not(oGlobalEvents.Exists( eventName ) ) then
			oGlobalEvents.Add eventName, Array()
		end if

		dim listeners, size
		listeners = oGlobalEvents( eventName )
		size = ubound(listeners) + 1
		redim preserve listeners(size)
		listeners(size) = javascriptCode

		oGlobalEvents( eventName ) = listeners

'		// Avoid duplicates.
'		if (!in_array($javascriptCode, $this->_globalEvents[$event])) {
'			$this->_globalEvents[$event][] = $javascriptCode;
'		}
	end sub

	''
	 ' Clear registered global event handlers.
	 ' Note: this function will have no effect if the event handler has been already printed/returned.
	 '
	 ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed .
	 '
	public sub clearGlobalEventHandlers( eventName )
		if not(isEmpty( eventName )) then
			oGlobalEvents.Remove eventName
		else
			oGlobalEvents.RemoveAll
		end if
	end sub

	''
	 ' Prints javascript code.
	 '
	 ' @param string js
	 '
	private function script(js)
		script = "<script type=""text/javascript"">" & _
			"//<![CDATA[" & vbcrlf & _
			js & vbcrlf & _
			"//]]>" & _
			"</script>" & vbcrlf
	end function

	''
	 ' Returns the configuration array (global and instance specific settings are merged into one array).
	 '
	 ' @param instanceConfig (Dictionary) The specific configurations to apply to editor instance.
	 ' @param instanceEvents (Dictionary) Event listeners for editor instance.
	 '
	private function configSettings()
		dim mergedConfig, mergedEvents
		set mergedConfig = cloneDictionary(oAllInstancesConfig)
		set mergedEvents = cloneDictionary(oAllInstancesEvents)

		if not(isEmpty(oInstanceConfig)) then
			set mergedConfig = mergeDictionary(mergedConfig, oInstanceConfig)
		end if

		if not(isEmpty(oInstanceEvents)) then
			for each eventName in oInstanceEvents
				code = oInstanceEvents( eventName )

				if not(mergedEvents.Exists( eventName)) then
					mergedEvents.Add eventName, code
				else

					dim listeners, size
					listeners = mergedEvents( eventName )
					size = ubound(listeners)
					if isArray( code ) then
						addedCount = ubound(code)
						redim preserve listeners( size + addedCount + 1 )
						for i = 0 to addedCount
							listeners(size + i + 1) = code (i)
						next
					else
						size = size + 1
						redim preserve listeners(size)
						listeners(size) = code
					end if

					mergedEvents( eventName ) = listeners
				end if
			next

		end if

		dim i, eventName, handlers, configON, ub, code

		if mergedEvents.Count>0 then
			if mergedConfig.Exists( "on" ) then
				set configON = mergedConfig.items( "on" )
			else
				set configON = CreateObject("Scripting.Dictionary")
				mergedConfig.Add "on", configOn
			end if

			for each eventName in mergedEvents
				handlers = mergedEvents( eventName )
				code = ""

				if isArray(handlers) then
					uB = ubound(handlers)
					if (uB = 0) then
						code = handlers(0)
					else
						code = "function (ev) {"
						for i=0 to uB
							code = code & "(" & handlers(i) & ")(ev);"
						next
						code = code & "}"
					end if
				else
					code = handlers
				end if
				' Using @@ at the beggining to signal JSON that we don't want this quoted.
				configON.Add eventName, "@@" & code
			next

'			set mergedConfig.Item("on") = configOn
		end if

		set configSettings = mergedConfig
	end function

	 ''
		' Returns a copy of a scripting.dictionary object
		'
	private function cloneDictionary( base )
		dim newOne, tmpKey

		Set newOne = CreateObject("Scripting.Dictionary")
		for each tmpKey in base
			newOne.Add tmpKey , base( tmpKey )
		next

		set cloneDictionary = newOne
	end function

	 ''
		' Combines two scripting.dictionary objects
		' The base object isn't modified, and extra gets all the properties in base
		'
	private function mergeDictionary(base, extra)
		dim newOne, tmpKey

		for each tmpKey in base
			if not(extra.Exists( tmpKey )) then
				extra.Add tmpKey, base( tmpKey )
			end if
		next

		set mergeDictionary = extra
	end function

	''
	 ' Return global event handlers.
	 '
	private function returnGlobalEvents()
		dim out, eventName, handlers
		dim handlersForEvent, handler, code, i
		out = ""

		if (isempty(CKEDITOR_returnedEvents)) then
			set CKEDITOR_returnedEvents = CreateObject("Scripting.Dictionary")
		end if

		for each eventName in oGlobalEvents
			handlers = oGlobalEvents( eventName )

			if not(CKEDITOR_returnedEvents.Exists(eventName)) then
				CKEDITOR_returnedEvents.Add eventName, CreateObject("Scripting.Dictionary")
			end if

				set handlersForEvent = CKEDITOR_returnedEvents.Item( eventName )

				' handlersForEvent is another dictionary
				' and handlers is an array

				for i = 0 to ubound(handlers)
					code = handlers( i )

					' Return only new events
					if not(handlersForEvent.Exists( code )) then
						if (out <> "") then out = out & vbcrlf
						out = out & "CKEDITOR.on('" &  eventName & "', " & code & ");"
						handlersForEvent.Add code, code
					end if
				next
		next

		returnGlobalEvents = out
	end function

	''
	 ' Initializes CKEditor (executed only once).
	 '
	private function init()
		dim out, args, path, extraCode, file
		out = ""

		if (CKEDITOR_initComplete) then
			init = ""
			exit function
		end if

		if (initialized) then
			CKEDITOR_initComplete = true
			init = ""
			exit function
		end if

		args = ""
		path = ckeditorPath()

		if (timestamp <> "") and (timestamp <> "%" & "TIMESTAMP%") then
			args = "?t=" & timestamp
		end if

		' Skip relative paths...
		if (instr(path, "..") <> 0) then
			out = out & script("window.CKEDITOR_BASEPATH='" &  path  & "';")
		end if

		out = out & "<scr" & "ipt type=""text/javascript"" src=""" & path & ckeditorFileName() & args & """></scr" & "ipt>" & vbcrlf

		extraCode = ""
		if (timestamp <> mTimeStamp) then
			extraCode = extraCode & "CKEDITOR.timestamp = '" & timestamp & "';"
		end if
		if (extraCode <> "") then
			out = out & script(extraCode)
		end if

		CKEDITOR_initComplete = true
		initialized = true

		init = out
	end function

	private function ckeditorFileName()
		ckeditorFileName = "ckeditor.js"
	end function

	''
	 ' Return path to ckeditor.js.
	 '
	private function ckeditorPath()
		if (basePath <> "") then
			ckeditorPath = basePath
		else
			' In classic ASP we can't get the location of this included script
			ckeditorPath = "/ckeditor/"
		end if

		' Try to check if that folder contains the CKEditor files:
		' If it's a full URL avoid checking it as it might point to an external server.
		if (instr(ckeditorPath, "://") <> 0) then exit function

		dim filename, oFSO, exists
		filename = server.mapPath(basePath & ckeditorFileName())
		set oFSO = Server.CreateObject("Scripting.FileSystemObject")
		exists = oFSO.FileExists(filename)
		set oFSO = nothing

		if not(exists) then
			response.clear
			response.write "<h1>CKEditor path validation failed</h1>"
			response.write "<p>The path &quot;" & ckeditorPath & "&quot; doesn't include the CKEditor main file (" & ckeditorFileName() & ")</p>"
			response.write "<p>Please, verify that you have set it correctly and/or adjust the 'basePath' property</p>"
			response.write "<p>Checked for physical file: &quot;" & filename & "&quot;</p>"
			response.end
		end if
	end function

End Class



' URL: http://www.webdevbros.net/2007/04/26/generate-json-from-asp-datatypes/
'**************************************************************************************************************
'' @CLASSTITLE:		JSON
'' @CREATOR:		Michal Gabrukiewicz (gabru at grafix.at), Michael Rebec
'' @CONTRIBUTORS:	- Cliff Pruitt (opensource at crayoncowboy.com)
''					- Sylvain Lafontaine
''					- Jef Housein
''					- Jeremy Brown
'' @CREATEDON:		2007-04-26 12:46
'' @CDESCRIPTION:	Comes up with functionality for JSON (http://json.org) to use within ASP.
''					Correct escaping of characters, generating JSON Grammer out of ASP datatypes and structures
''					Some examples (all use the <em>toJSON()</em> method but as it is the class' default method it can be left out):
''					<code>
''					<%
''					'simple number
''					output = (new JSON)("myNum", 2, false)
''					'generates {"myNum": 2}
''
''					'array with different datatypes
''					output = (new JSON)("anArray", array(2, "x", null), true)
''					'generates "anArray": [2, "x", null]
''					'(note: the last parameter was true, thus no surrounding brackets in the result)
''					% >
''					</code>
'' @REQUIRES:		-
'' @OPTIONEXPLICIT:	yes
'' @VERSION:		1.5.1

'**************************************************************************************************************
class JSON

	'private members
	private output, innerCall

	'**********************************************************************************************************
	'* constructor
	'**********************************************************************************************************
	public sub class_initialize()
		newGeneration()
	end sub

	'******************************************************************************************
	'' @SDESCRIPTION:	STATIC! takes a given string and makes it JSON valid
	'' @DESCRIPTION:	all characters which needs to be escaped are beeing replaced by their
	''					unicode representation according to the
	''					RFC4627#2.5 - http://www.ietf.org/rfc/rfc4627.txt?number=4627
	'' @PARAM:			val [string]: value which should be escaped
	'' @RETURN:			[string] JSON valid string
	'******************************************************************************************
	public function escape(val)
		dim cDoubleQuote, cRevSolidus, cSolidus
		cDoubleQuote = &h22
		cRevSolidus = &h5C
		cSolidus = &h2F
		dim i, currentDigit
		for i = 1 to (len(val))
			currentDigit = mid(val, i, 1)
			if ascw(currentDigit) > &h00 and ascw(currentDigit) < &h1F then
				currentDigit = escapequence(currentDigit)
			elseif ascw(currentDigit) >= &hC280 and ascw(currentDigit) <= &hC2BF then
				currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC200), 2, 0), 2)
			elseif ascw(currentDigit) >= &hC380 and ascw(currentDigit) <= &hC3BF then
				currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC2C0), 2, 0), 2)
			else
				select case ascw(currentDigit)
					case cDoubleQuote: currentDigit = escapequence(currentDigit)
					case cRevSolidus: currentDigit = escapequence(currentDigit)
					case cSolidus: currentDigit = escapequence(currentDigit)
				end select
			end if
			escape = escape & currentDigit
		next
	end function

	'******************************************************************************************************************
	'' @SDESCRIPTION:	generates a representation of a name value pair in JSON grammer
	'' @DESCRIPTION:	It generates a name value pair which is represented as <em>{"name": value}</em> in JSON.
	''					the generation is fully recursive. Thus the value can also be a complex datatype (array in dictionary, etc.) e.g.
	''					<code>
	''					<%
	''					set j = new JSON
	''					j.toJSON "n", array(RS, dict, false), false
	''					j.toJSON "n", array(array(), 2, true), false
	''					% >
	''					</code>
	'' @PARAM:			name [string]: name of the value (accessible with javascript afterwards). leave empty to get just the value
	'' @PARAM:			val [variant], [int], [float], [array], [object], [dictionary]: value which needs
	''					to be generated. Conversation of the data types is as follows:<br>
	''					- <strong>ASP datatype -> JavaScript datatype</strong>
	''					- NOTHING, NULL -> null
	''					- INT, DOUBLE -> number
	''					- STRING -> string
	''					- BOOLEAN -> bool
	''					- ARRAY -> array
	''					- DICTIONARY -> Represents it as name value pairs. Each key is accessible as property afterwards. json will look like <code>"name": {"key1": "some value", "key2": "other value"}</code>
	''					- <em>multidimensional array</em> -> Generates a 1-dimensional array (flat) with all values of the multidimensional array
	''					- <em>request</em> object -> every property and collection (cookies, form, querystring, etc) of the asp request object is exposed as an item of a dictionary. Property names are <strong>lowercase</strong>. e.g. <em>servervariables</em>.
	''					- OBJECT -> name of the type (if unknown type) or all its properties (if class implements <em>reflect()</em> method)
	''					Implement a <strong>reflect()</strong> function if you want your custom classes to be recognized. The function must return
	''					a dictionary where the key holds the property name and the value its value. Example of a reflect function within a User class which has firstname and lastname properties
	''					<code>
	''					<%
	''					function reflect()
	''					.	set reflect = server.createObject("scripting.dictionary")
	''					.	reflect.add "firstname", firstname
	''					.	reflect.add "lastname", lastname
	''					end function
	''					% >
	''					</code>
	''					Example of how to generate a JSON representation of the asp request object and access the <em>HTTP_HOST</em> server variable in JavaScript:
	''					<code>
	''					<script>alert(<%= (new JSON)(empty, request, false) % >.servervariables.HTTP_HOST);</script>
	''					</code>
	'' @PARAM:			nested [bool]: indicates if the name value pair is already nested within another? if yes then the <em>{}</em> are left out.
	'' @RETURN:			[string] returns a JSON representation of the given name value pair
	'******************************************************************************************************************
	public default function toJSON(name, val, nested)
		if not nested and not isEmpty(name) then write("{")
		if not isEmpty(name) then write("""" & escape(name) & """: ")
		generateValue(val)
		if not nested and not isEmpty(name) then write("}")
		toJSON = output

		if innerCall = 0 then newGeneration()
	end function

	'******************************************************************************************************************
	'* generate
	'******************************************************************************************************************
	private function generateValue(val)
		if isNull(val) then
			write("null")
		elseif isArray(val) then
			generateArray(val)
		elseif isObject(val) then
			dim tName : tName = typename(val)
			if val is nothing then
				write("null")
			elseif tName = "Dictionary" or tName = "IRequestDictionary" then
				generateDictionary(val)
			elseif tName = "IRequest" then
				set req = server.createObject("scripting.dictionary")
				req.add "clientcertificate", val.ClientCertificate
				req.add "cookies", val.cookies
				req.add "form", val.form
				req.add "querystring", val.queryString
				req.add "servervariables", val.serverVariables
				req.add "totalbytes", val.totalBytes
				generateDictionary(req)
			elseif tName = "IStringList" then
				if val.count = 1 then
					toJSON empty, val(1), true
				else
					generateArray(val)
				end if
			else
				generateObject(val)
			end if
		else
			'bool
			dim varTyp
			varTyp = varType(val)
			if varTyp = 11 then
				if val then write("true") else write("false")
			'int, long, byte
			elseif varTyp = 2 or varTyp = 3 or varTyp = 17 or varTyp = 19 then
				write(cLng(val))
			'single, double, currency
			elseif varTyp = 4 or varTyp = 5 or varTyp = 6 or varTyp = 14 then
				write(replace(cDbl(val), ",", "."))
			else
				' Using @@ at the beggining to signal JSON that we don't want this quoted.
				if left(val, 2) = "@@" then
					write( mid( val, 3 ) )
				else
					write("""" & escape(val & "") & """")
				end if
			end if
		end if
		generateValue = output
	end function

	'******************************************************************************************************************
	'* generateArray
	'******************************************************************************************************************
	private sub generateArray(val)
		dim item, i
		write("[")
		i = 0
		'the for each allows us to support also multi dimensional arrays
		for each item in val
			if i > 0 then write(",")
			generateValue(item)
			i = i + 1
		next
		write("]")
	end sub

	'******************************************************************************************************************
	'* generateDictionary
	'******************************************************************************************************************
	private sub generateDictionary(val)
		innerCall = innerCall + 1
		if val.count = 0 then
			toJSON empty, null, true
			exit sub
		end if
		dim key, i
		write("{")
		i = 0
		for each key in val
			if i > 0 then write(",")
			toJSON key, val(key), true
			i = i + 1
		next
		write("}")
		innerCall = innerCall - 1
	end sub

	'******************************************************************************************************************
	'* generateObject
	'******************************************************************************************************************
	private sub generateObject(val)
		dim props
		on error resume next
		set props = val.reflect()
		if err = 0 then
			on error goto 0
			innerCall = innerCall + 1
			toJSON empty, props, true
			innerCall = innerCall - 1
		else
			on error goto 0
			write("""" & escape(typename(val)) & """")
		end if
	end sub

	'******************************************************************************************************************
	'* newGeneration
	'******************************************************************************************************************
	private sub newGeneration()
		output = empty
		innerCall = 0
	end sub

	'******************************************************************************************
	'* JsonEscapeSquence
	'******************************************************************************************
	private function escapequence(digit)
		escapequence = "\u00" + right(padLeft(hex(ascw(digit)), 2, 0), 2)
	end function

	'******************************************************************************************
	'* padLeft
	'******************************************************************************************
	private function padLeft(value, totalLength, paddingChar)
		padLeft = right(clone(paddingChar, totalLength) & value, totalLength)
	end function

	'******************************************************************************************
	'* clone
	'******************************************************************************************
	private function clone(byVal str, n)
		dim i
		for i = 1 to n : clone = clone & str : next
	end function

	'******************************************************************************************
	'* write
	'******************************************************************************************
	private sub write(val)
		output = output & val
	end sub

end class
%>