....................................../////.===Shadow-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 195.3.193.33  /  Your IP : 216.73.216.125
Web Server : Apache
System : Linux server3 5.10.0-35-amd64 #1 SMP Debian 5.10.237-1 (2025-05-19) x86_64
User : web032 ( 1035)
PHP Version : 7.3.33
Disable Function : show_source, highlight_file, apache_child_terminate, apache_get_modules, apache_note, apache_setenv, virtual, dl, disk_total_space, posix_getpwnam, posix_getpwuid, posix_mkfifo, posix_mknod, posix_setpgid, posix_setsid, posix_setuid, posix_uname, proc_nice, openlog, syslog, pfsockopen
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/web032/htdocs/cms/plugins/system/jcemediabox/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/web032/htdocs/cms/plugins/system/jcemediabox/js/jcemediabox-src.js
/**
 * JCEMediaBox 		1.2.1
 * @package 		JCEMediaBox
 * @url				http://www.joomlacontenteditor.net
 * @copyright 		Copyright (C) 2006 - 2015 Ryan Demmer. All rights reserved
 * @copyright		Copyright 2009, Moxiecode Systems AB
 * @license 		GNU/GPL Version 2 - http://www.gnu.org/licenses/gpl-2.0.html
 * @date			15 March 2016
 * This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 *
 */
(function (window) {
    /**
     *
     *  Base64 encode / decode
     *  http://www.webtoolkit.info/
     *
     **/
    var Base64 = {
        // private property
        _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
        // public method for encoding
        encode: function (input) {
            var output = "";
            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
            var i = 0;

            input = Base64._utf8_encode(input);

            while (i < input.length) {

                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);

                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;

                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }

                output = output +
                        Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
                        Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);

            }

            return output;
        },
        // public method for decoding
        decode: function (input) {
            var output = "";
            var chr1, chr2, chr3;
            var enc1, enc2, enc3, enc4;
            var i = 0;

            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

            while (i < input.length) {

                enc1 = Base64._keyStr.indexOf(input.charAt(i++));
                enc2 = Base64._keyStr.indexOf(input.charAt(i++));
                enc3 = Base64._keyStr.indexOf(input.charAt(i++));
                enc4 = Base64._keyStr.indexOf(input.charAt(i++));

                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;

                output = output + String.fromCharCode(chr1);

                if (enc3 != 64) {
                    output = output + String.fromCharCode(chr2);
                }
                if (enc4 != 64) {
                    output = output + String.fromCharCode(chr3);
                }

            }

            output = Base64._utf8_decode(output);

            return output;

        },
        // private method for UTF-8 encoding
        _utf8_encode: function (string) {
            string = string.replace(/\r\n/g, "\n");
            var utftext = "";

            for (var n = 0; n < string.length; n++) {

                var c = string.charCodeAt(n);

                if (c < 128) {
                    utftext += String.fromCharCode(c);
                }
                else if ((c > 127) && (c < 2048)) {
                    utftext += String.fromCharCode((c >> 6) | 192);
                    utftext += String.fromCharCode((c & 63) | 128);
                }
                else {
                    utftext += String.fromCharCode((c >> 12) | 224);
                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                    utftext += String.fromCharCode((c & 63) | 128);
                }

            }

            return utftext;
        },
        // private method for UTF-8 decoding
        _utf8_decode: function (utftext) {
            var string = "";
            var i = 0;
            var c = 0, c1 = 0, c2 = 0;

            while (i < utftext.length) {

                c = utftext.charCodeAt(i);

                if (c < 128) {
                    string += String.fromCharCode(c);
                    i++;
                }
                else if ((c > 191) && (c < 224)) {
                    c1 = utftext.charCodeAt(i + 1);
                    string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                    i += 2;
                }
                else {
                    c1 = utftext.charCodeAt(i + 1);
                    c2 = utftext.charCodeAt(i + 2);
                    string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                    i += 3;
                }

            }
            return string;
        }
    };

    // patch in btoa
    if (!window.btoa) {
        window.btoa = Base64.encode;
    }
    // patch in atob
    if (!window.atob) {
        window.atob = Base64.decode;
    }

    // html5 element support
    var support = {};

    /*
     * From Modernizr v2.0.6
     * http://www.modernizr.com
     * Copyright (c) 2009-2011 Faruk Ates, Paul Irish, Alex Sexton
     */
    support.video = (function () {
        var elem = document.createElement('video'), bool = false;

        // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
        try {
            if (bool = !!elem.canPlayType) {
                bool = new Boolean(bool);
                bool.ogg = elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '');

                // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
                bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '');

                bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '');
            }

        } catch (e) {
        }

        return bool;
    })();

    var entities = {
        '\"': '&quot;',
        "'": '&#39;',
        '<': '&lt;',
        '>': '&gt;',
        '&': '&amp;'
    };

    /*
     * From Modernizr v2.0.6
     * http://www.modernizr.com
     * Copyright (c) 2009-2011 Faruk Ates, Paul Irish, Alex Sexton
     */
    support.audio = (function () {
        var elem = document.createElement('audio'), bool = false;

        try {
            if (bool = !!elem.canPlayType) {
                bool = new Boolean(bool);
                bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '');
                bool.mp3 = elem.canPlayType('audio/mpeg;').replace(/^no$/, '');

                // Mimetypes accepted:
                //   developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
                //   bit.ly/iphoneoscodecs
                bool.wav = elem.canPlayType('audio/wav; codecs="1"').replace(/^no$/, '');
                bool.m4a = (elem.canPlayType('audio/x-m4a;') ||
                        elem.canPlayType('audio/aac;')).replace(/^no$/, '');
            }
        } catch (e) {
        }

        return bool;
    })();

    window.JCEMediaBox = {
        domLoaded: false,
        /**
         * Global Options Object
         */
        options: {
            popup: {
                width: '',
                height: '',
                legacy: 0,
                lightbox: 0,
                shadowbox: 0,
                overlay: 1,
                overlayopacity: 0.8,
                overlaycolor: '#000000',
                resize: 0,
                icons: 1,
                fadespeed: 500,
                scalespeed: 500,
                hideobjects: 1,
                scrolling: 'fixed',
                //protect				: 1,
                close: 2,
                labels: {
                    'close': 'Close',
                    'next': 'Next',
                    'previous': 'Previous',
                    'numbers': '{$current} of {$total}',
                    'cancel': 'Cancel'
                },
                cookie_expiry: 7,
                google_viewer: 0,
                pdfjs: 0
            },
            tooltip: {
                speed: 150,
                offsets: {
                    x: 16,
                    y: 16
                },
                position: 'br',
                opacity: 0.8,
                background: '#000000',
                color: '#ffffff'
            },
            base: '/',
            pngfix: false,
            pngfixclass: '',
            theme: 'standard',
            imgpath: 'plugins/system/jcemediabox/img',
            mediafallback: false,
            mediaplayer: "",
            mediaselector: "audio,video"
        },
        init: function (options) {
            this.extend(this.options, options);
            // Clear IE6 background cache
            if (this.isIE6) {
                try {
                    document.execCommand("BackgroundImageCache", false, true);
                } catch (e) {
                }
            }
            // add DOM support for IE < 9
            if (!support.video || !support.audio) {
                document.createElement('source');
            }

            this.ready();
        },
        /**
         * Function to determine if DOM is ready.
         * Based on JQuery ready.js - https://github.com/jquery/jquery/blob/1.11-stable/src/core/ready.js
         * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
         * Released under the MIT license
         * http://jquery.org/license
         */
        ready: function () {
            var win = window, doc = win.document, self = JCEMediaBox;

            if (self.domLoaded) {
                return self._init();
            }

            /**
             * Clean-up method for dom ready events
             */
            function detach() {
                if (doc.addEventListener) {
                    doc.removeEventListener("DOMContentLoaded", completed, false);
                    win.removeEventListener("load", completed, false);

                } else {
                    doc.detachEvent("onreadystatechange", completed);
                    win.detachEvent("onload", completed);
                }
            }

            /**
             * The ready event handler and self cleanup method
             */
            function completed(event) {
                // readyState === "complete" is good enough for us to call the dom ready in oldIE
                //if (doc.addEventListener || event && event.type === "load" || doc.readyState === "complete") {
                    detach();

                    self.domLoaded = true;

                    self._init();
                //}
            }

            if (doc.readyState === "complete") {
                // Handle it asynchronously to allow scripts the opportunity to delay ready
                setTimeout(completed);

                // Standards-based browsers support DOMContentLoaded
            } else if (doc.addEventListener) {
                // Use the handy event callback
                doc.addEventListener("DOMContentLoaded", completed, false);

                // A fallback to window.onload, that will always work
                win.addEventListener("load", completed, false);

                // If IE event model is used
            } else {
                // Ensure firing before onload, maybe late but safe also for iframes
                doc.attachEvent("onreadystatechange", completed);

                // A fallback to window.onload, that will always work
                win.attachEvent("onload", completed);

                // If IE and not a frame
                // continually check to see if the document is ready
                var top = false;

                try {
                    top = win.frameElement == null && doc.documentElement;
                } catch (e) {
                }

                if (top && top.doScroll) {
                    (function doScrollCheck() {
                        if (!self.domLoaded) {

                            try {
                                // Use the trick by Diego Perini
                                // http://javascript.nwbox.com/IEContentLoaded/
                                top.doScroll("left");
                            } catch (e) {
                                return setTimeout(doScrollCheck, 50);
                            }

                            // and execute any waiting functions
                            completed();
                        }
                    })();
                }
            }
        },
        /**
         * Get the Site Base URL
         * @method getSite
         * @return {String} Site Base URL
         */
        getSite: function () {
            var base = this.options.base;

            if (base) {
                // Get document location
                var site = document.location.href;
                // Split into port (http) and location
                var parts = site.split(':\/\/');

                var port = parts[0];
                var url = parts[1];

                // Get url part before base
                if (url.indexOf(base) != -1) {
                    url = url.substr(0, url.indexOf(base));
                    // Get url part before first slash
                } else {
                    url = url.substr(0, url.indexOf('/')) || url;
                }
                // Return full url
                return port + '://' + url + base;
            }
            // Can't get site URL!
            return null;
        },
        /**
         * Private internal function
         * Initialize JCEMediaBox
         */
        _init: function () {
            var self = this, na = navigator, ua = na.userAgent;

            /**
             * Constant that is true if the browser is Opera.
             *
             * @property isOpera
             * @type Boolean
             * @final
             */
            self.isOpera = window.opera && opera.buildNumber;

            /**
             * Constant that is true if the browser is WebKit (Safari/Chrome).
             *
             * @property isWebKit
             * @type Boolean
             * @final
             */
            self.isWebKit = /WebKit/.test(ua);

            self.isChrome = /Chrome\//.test(ua);

            self.isSafari = /Safari\//.test(ua);

            /**
             * Constant that is true if the browser is IE.
             *
             * @property isIE
             * @type Boolean
             * @final
             */
            self.isIE = !self.isWebKit && !self.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName) && !!window.ActiveXObject;

            /**
             * Constant that is true if the browser is IE 6 or older.
             *
             * @property isIE6
             * @type Boolean
             * @final
             */
            self.isIE6 = self.isIE && /MSIE [56]/.test(ua) && !window.XMLHttpRequest;

            /**
             * Constant that is true if the browser is IE 7.
             *
             * @property isIE7
             * @type Boolean
             * @final
             */
            self.isIE7 = self.isIE && /MSIE [7]/.test(ua) && !!window.XMLHttpRequest && !document.querySelector;

            /**
             * Constant that tells if the current browser is an iPhone or iPad.
             *
             * @property isiOS
             * @type Boolean
             * @final
             */
            self.isiOS = /(iPad|iPhone)/.test(ua);

            self.isAndroid = /Android/.test(ua);

            self.isMobile = self.isiOS || self.isAndroid;

            /**
             * Get the Site URL
             * @property site
             * @type String
             */
            this.site = this.getSite();

            // Can't get reliable site URL
            if (!this.site) {
                return false;
            }

            // Initialize Popup / Tooltip creation
            this.Popup.init();
            this.ToolTip.init();

            if (this.options.mediafallback) {
                this.mediaFallback();
            }
        },

        mediaFallback: function() {
            var self = this, DOM = this.DOM, each = this.each;

            function toAbsolute(url) {
                var div = document.createElement('div');
                div.innerHTML = '<a href="' + url + '">x</a>';

                return div.firstChild.href;
            }

            function resolveMediaPath(s, absolute) {
                if (s && s.indexOf('://') === -1 && s.charAt(0) !== '/') {
                    s = self.options.base + s;
                }

                if (absolute) {
                    return toAbsolute(s);
                }

                return s;
            }

            // process video
            var selector    = this.options.mediaselector;
            var elms        = DOM.select(selector);
            var swf         = this.options.mediaplayer || 'plugins/system/jcemediabox/mediaplayer/mediaplayer.swf';

            var supportMap = {
                'video': {
                    'h264' : ['video/mp4', 'video/mpeg'],
                    'webm' : ['video/webm'],
                    'ogg'  : ['video/ogg']
                },
                'audio': {
                    'mp3'   : ['audio/mp3'],
                    'ogg'   : ['audio/ogg'],
                    'webm'  : ['audio/webm']
                }
            };

            function checkSupport(name, type) {
                var hasSupport = false;

                for (var n in supportMap[name]) {
                    if (supportMap[name][n].indexOf(type) !== -1) {
                        hasSupport = support[name] && !!support[name][n];
                    }
                }

                return hasSupport;
            }

            if (elms.length) {
                each(elms, function(el) {
                    var type = el.getAttribute('type'), src = el.getAttribute('src'), name = el.nodeName.toLowerCase(), hasSupport = false;

                    // no src attribute set, try finding in <source>
                    if (!src || !type) {
                        var source = DOM.select('source[type]', el);

                        each(source, function(n) {
                            src = n.getAttribute('src'), type = n.getAttribute('type');

                            // video/x-flv not supported by any browser
                            if (type !== "video/x-flv") {
                                hasSupport = checkSupport(name, type);
                            }

                            if (!hasSupport) {
                                return false;
                            }
                        });

                        // check for flv fallback
                        if (!hasSupport && name === "video") {
                            source = DOM.select('source[type="video/x-flv"]', el);

                            if (source.length) {
                                src = source[0].getAttribute('src'), type = "video/x-flv";
                            }
                        }
                    } else {
                        hasSupport = checkSupport(name, type);
                    }

                    // can't do anything without these!
                    if (!src || !type) {
                        return;
                    }

                    // native audio/video support (exclude flv)
                    if (hasSupport) {
                        return;
                    }

                    var w = el.getAttribute('width'), h = el.getAttribute('height');
                    var html = '', flashvars = [];

                    // not custom player
                    if (!self.options.mediaplayer) {
                        flashvars.push('file=' + resolveMediaPath(src, true));
                    }

                    self.each(['autoplay', 'loop', 'preload', 'controls'], function(at) {
                        var v = el.getAttribute(at);

                        if (typeof v !== "undefined" && v !== null) {
                            if (v === at) {
                                v = true;
                            }

                            flashvars.push(at + '=' + v);
                        }

                    });

                    var i, attrs = el.attributes;

                    for (i = attrs.length - 1; i >= 0; i--) {
                        var attrName = attrs[i].name;
                        if (attrName && (attrName.indexOf('data-video-') !== -1 || attrName.indexOf('data-audio-') !== -1)) {
                            var name = attrName.replace(/data-(video|audio)-/i, '');
                            var value = attrs[i].value;

                            if (typeof value !== "undefined" || value !== null) {
                                flashvars.push(name + '=' + value);
                            }
                        }
                    }

                    html += '<object class="wf-mediaplayer-object" data="' + resolveMediaPath(swf) + '" type="application/x-shockwave-flash"';

                    if (w) {
                        html += ' width="' + w + '"';
                    }

                    if (h) {
                        html += ' height="' + h + '"';
                    }

                    html += '>';

                    html += '<param name="movie" value="' + resolveMediaPath(swf) + '" />';
                    html += '<param name="flashvars" value="' + flashvars.join('&') + '" />';
                    html += '<param name="allowfullscreen" value="true" />';
                    html += '<param name="wmode" value="transparent" />';

                    var poster = el.getAttribute('poster');

                    if (poster) {
                        html += '<img src="' + resolveMediaPath(poster) + '" alt="" />';
                    }

                    html += '<i>Flash is required to play this video. <a href="https://get.adobe.com/flashplayer" target="_blank">Get Adobe® Flash Player</a></i>';
                    html += '</object>';

                    var div = document.createElement('span');
                    div.innerHTML = html;

                    var o = div.firstChild;

                    if (o && o.nodeName === "OBJECT") {
                        el.parentNode.replaceChild(o, el);

                        if (poster) {
                            o.style.backgroundImage = "url('" + resolveMediaPath(poster) + "')";
                        }
                    }
                });
            }
        },

        /**
         * Performs an iteration of all items in a collection such as an object or array. This method will execure the
         * callback function for each item in the collection, if the callback returns false the iteration will terminate.
         * The callback has the following format: cb(value, key_or_index).
         *
         * @method each
         * @param {Object} o Collection to iterate.
         * @param {function} cb Callback function to execute for each item.
         * @param {Object} s Optional scope to execute the callback in.
         * @copyright	Copyright 2009, Moxiecode Systems AB
         */
        each: function (o, cb, s) {
            var n, l;

            if (!o) {
                return 0;
            }

            s = s || o;

            if (o.length !== undefined) {
                // Indexed arrays, needed for Safari
                for (n = 0, l = o.length; n < l; n++) {
                    if (cb.call(s, o[n], n, o) === false) {
                        break;
                    }
                }
            } else {
                // Hashtables
                for (n in o) {
                    if (o.hasOwnProperty(n)) {
                        if (cb.call(s, o[n], n, o) === false) {
                            break;
                        }
                    }
                }
            }

            return o;
        },
        /**
         * Extends an object with the specified other object(s).
         *
         * @method extend
         * @param {Object} o Object to extend with new items.
         * @param {Object} e..n Object(s) to extend the specified object with.
         * @return {Object} o New extended object, same reference as the input object.
         * @copyright	Copyright 2009, Moxiecode Systems AB
         */
        extend: function (obj, ext) {
            var i, l, name, args = arguments, value;

            for (i = 1, l = args.length; i < l; i++) {
                ext = args[i];
                for (name in ext) {
                    if (ext.hasOwnProperty(name)) {
                        value = ext[name];

                        if (value !== undefined) {
                            obj[name] = value;
                        }
                    }
                }
            }

            return obj;
        },
        /**
         * Removes whitespace from the beginning and end of a string.
         *
         * @method trim
         * @param {String} s String to remove whitespace from.
         * @return {String} New string with removed whitespace.
         * @copyright	Copyright 2009, Moxiecode Systems AB
         */
        trim: function (s) {
            return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');
        },
        /**
         * Find index of item in array
         * @param {array} a Array to look in
         * @param {mixed} s Item to find
         * @return {Number, i} Index
         */
        inArray: function (a, s) {
            var i, l;

            if (a) {
                for (i = 0, l = a.length; i < l; i++) {
                    if (a[i] === s) {
                        return i;
                    }
                }
            }

            return -1;
        },
        /**
         * DOM functions
         */
        DOM: {
            /**
             * Get an Element by ID
             * @param {Object} s ID
             */
            get: function (s) {
                if (typeof (s) == 'string')
                    return document.getElementById(s);

                return s;
            },
            /**
             * Return elements matching a simple selector, eg: a, a[id], a.classname
             * @param {Object} o Selector
             * @param {Object} p Parent Element
             */
            select: function (o, p) {
                var t = this, r = [], s, parts, at, tag, cl, each = JCEMediaBox.each;
                p = p || document;
                // Return all elements
                if (o == '*') {
                    return p.getElementsByTagName(o);
                }

                // Use native support if available
                if (p.querySelectorAll) {
                    return p.querySelectorAll(o);
                }

                /**
                 * Internal inArray function
                 * @param {Object} a Array to check
                 * @param {Object} s Key to check for
                 */
                function inArray(a, v) {
                    var i, l;

                    if (a) {
                        for (i = 0, l = a.length; i < l; i++) {
                            if (a[i] === v)
                                return true;
                        }
                    }

                    return false;
                }

                // Split selector
                s = o.split(',');
                each(s, function (selectors) {
                    parts = JCEMediaBox.trim(selectors).split('.');
                    // Element
                    tag = parts[0] || '*';
                    // Class
                    cl = parts[1] || '';
                    // Handle attributes
                    if (/\[(.*?)\]/.test(tag)) {
                        tag = tag.replace(/(.*?)\[(.*?)\]/, function (a, b, c) {
                            at = c;
                            return b;
                        });

                    }
                    // Get all elements for the given parent and tag
                    var elements = p.getElementsByTagName(tag);

                    // If class or attribute
                    if (cl || at) {
                        each(elements, function (el) {
                            // If class
                            if (cl) {
                                if (t.hasClass(el, cl)) {
                                    if (!inArray(r, el)) {
                                        r.push(el);
                                    }
                                }
                            }
                            // If attribute
                            if (at) {
                                if (el.getAttribute(at)) {
                                    if (!inArray(r, el)) {
                                        r.push(el);
                                    }
                                }
                            }
                        });

                    } else {
                        r = elements;
                    }
                });

                return r;
            },
            /**
             * Check if an element has a specific class
             * @param {Object} el Element
             * @param {Object} c Class
             */
            hasClass: function (el, c) {
                return new RegExp(c).test(el.className);
            },
            /**
             * Add a class to an element
             * @param {Object} el Element
             * @param {Object} c Class
             */
            addClass: function (el, c) {
                if (!this.hasClass(el, c)) {
                    el.className = JCEMediaBox.trim(el.className + ' ' + c);
                }
            },
            /**
             * Remove a class from an element
             * @param {Object} el Element
             * @param {Object} c Class to remove
             */
            removeClass: function (el, c) {
                if (this.hasClass(el, c)) {
                    var s = el.className;
                    var re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");
                    var v = s.replace(re, ' ');
                    v = v.replace(/^\s|\s$/g, '');
                    el.className = v;
                }
            },
            /**
             * Show an element
             * @param {Object} el Element to show
             */
            show: function (el) {
                el.style.display = 'block';
            },
            /**
             * Hide and element
             * @param {Object} el Element to hide
             */
            hide: function (el) {
                el.style.display = 'none';
            },
            /**
             * Remove an element or attribute
             * @param {Object} el Element
             * @param {String} attrib Attribute
             */
            remove: function (el, attrib) {
                if (attrib) {
                    el.removeAttribute(attrib);
                } else {
                    var p = el.parentNode || document.body;
                    p.removeChild(el);
                }
            },
            /**
             * Set or retrieve a style
             * @param {Object} el Target Element
             * @param {Object} s Style to set / get
             * @param {Object} v Value to set
             */
            style: function (n, na, v) {
                var isIE = JCEMediaBox.isIE, r, s;

                if (!n) {
                    return;
                }

                // Camelcase it, if needed
                na = na.replace(/-(\D)/g, function (a, b) {
                    return b.toUpperCase();
                });

                s = n.style;

                // Get value
                if (typeof v == 'undefined') {

                    if (na == 'float')
                        na = isIE ? 'styleFloat' : 'cssFloat';

                    r = s[na];

                    if (document.defaultView && !r) {
                        if (/float/i.test(na))
                            na = 'float';

                        // Remove camelcase
                        na = na.replace(/[A-Z]/g, function (a) {
                            return '-' + a;
                        }).toLowerCase();

                        try {
                            r = document.defaultView.getComputedStyle(n, null).getPropertyValue(na);
                        } catch (e) {
                        }
                    }

                    if (n.currentStyle && !r)
                        r = n.currentStyle[na];

                    return r;

                } else {

                    switch (na) {
                        case 'opacity':
                            v = parseFloat(v);
                            // IE specific opacity
                            if (isIE) {
                                s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";

                                if (!n.currentStyle || !n.currentStyle.hasLayout)
                                    s.display = 'inline-block';
                            }
                            s[na] = v;
                            break;
                        case 'float':
                            na = isIE ? 'styleFloat' : 'cssFloat';
                            break;
                        default:
                            if (v && /(margin|padding|width|height|top|bottom|left|right)/i.test(na)) {
                                // Add pixel value if number
                                v = /^[\-0-9\.]+$/.test(v) ? v + 'px' : v;
                            }
                            break;
                    }
                    s[na] = v;
                }
            },
            /**
             * Set styles
             * @param {Object} el Target Element
             * @param {Object} props Object of style key/values
             */
            styles: function (el, props) {
                var t = this;
                JCEMediaBox.each(props, function (v, s) {
                    return t.style(el, s, v);
                });

            },
            /**
             * Set an Element attribute
             * @param {Object} el
             * @param {Object} s
             * @param {Object} v
             */
            attribute: function (el, s, v) {
                if (typeof v == 'undefined') {
                    if (s == 'class') {
                        return el.className;
                    }
                    v = el.getAttribute(s);
                    // Remove anonymous function from events
                    if (v && /^on/.test(s)) {
                        v = v.toString();
                        v = v.replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
                    }
                    // Fix Hspace
                    if (s == 'hspace' && v == -1) {
                        v = '';
                    }
                    return v;
                }
                // Remove attribute if no value
                if (v === '') {
                    el.removeAttribute(s);
                }

                switch (s) {
                    case 'style':
                        if (typeof v == 'object') {
                            this.styles(el, v);
                        } else {
                            el.style.cssText = v;
                        }
                        break;
                    case 'class':
                        el.className = v || '';
                        break;
                    default:
                        el.setAttribute(s, v);
                        break;
                }
            },
            /**
             * Set Attributes on an Element
             * @param {Object} el Target Element
             * @param {Object} attribs Attributes Object
             */
            attributes: function (el, attribs) {
                var t = this;
                JCEMediaBox.each(attribs, function (v, s) {
                    t.attribute(el, s, v);
                });

            },
            /**
             * Create an Element
             * @param {Object} el Element to create
             * @param {Object} attribs Attributes
             * @param {Object} styles Styles
             * @param {Object} html HTML
             */
            create: function (el, attribs, html) {
                var o = document.createElement(el);
                this.attributes(o, attribs);
                if (typeof html != 'undefined') {
                    o.innerHTML = html;
                }

                return o;
            },
            /**
             * Add an element to another
             * @param {Object} n Element to add to
             * @param {Object} o Element to add. Will be created if string
             * @param {Object} a Optional attributes
             * @param {Object} h Optional HTML
             */
            add: function (n, o, a, h) {
                if (typeof o == 'string') {
                    a = a || {};
                    o = this.create(o, a, h);
                }
                n.appendChild(o);

                return o;
            },
            /**
             * Add an element before the passed in element
             * @param {Object} n Element to insert into
             * @param {Object} o Element to insert
             * @param {Object} c Element to insert before
             */
            addBefore: function (n, o, c) {
                if (typeof c == 'undefined') {
                    c = n.firstChild;
                }
                n.insertBefore(o, c);
            },
            /**
             * IE6 PNG Fix
             * @param {Object} el Element to fix
             */
            png: function (el) {
                var s;
                // Image Elements
                if (el.nodeName == 'IMG') {
                    s = el.src;
                    if (/\.png$/i.test(s)) {
                        this.attribute(el, 'src', JCEMediaBox.site + 'plugins/system/jcemediabox/img/blank.gif');
                        this.style(el, 'filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + s + "')");
                    }
                    // Background-image styles
                } else {
                    s = this.style(el, 'background-image');
                    if (/\.png/i.test(s)) {
                        var bg = /url\("(.*)"\)/.exec(s)[1];
                        this.styles(el, {
                            'background-image': 'none',
                            'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + bg + "', sizingMethod='image')"
                        });
                    }
                }
            },
            encode: function (s) {
                return ('' + s).replace(/[<>&\"\']/g, function (c) {
                    return entities[c] || c;
                });
            },
            decode: function (s) {
                var el;

                s = s.replace(/&lt;/g, '<').replace(/&gt;/g, '>');

                el = document.createElement("div");
                el.innerHTML = s;

                return el.innerHTML || s;
            }

        },
        /**
         * Event Functions
         */
        Event: {
            events: [],
            /**
             * Add an Event handler
             * @param {Object} o Target Element
             * @param {Object} n Event name
             * @param {Object} f Callback function
             * @param {Object} s Scope
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            add: function (o, n, f, s) {
                var t = this;

                // Setup event callback
                cb = function (e) {
                    // Is all events disabled
                    if (t.disabled)
                        return;

                    e = e || window.event;

                    // Patch in target, preventDefault and stopPropagation in IE it's W3C valid
                    if (e && JCEMediaBox.isIE) {
                        if (!e.target) {
                            e.target = e.srcElement || document;
                        }

                        if (!e.relatedTarget && e.fromElement) {
                            e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement;
                        }

                        // Patch in preventDefault, stopPropagation methods for W3C compatibility
                        JCEMediaBox.extend(e, {
                            preventDefault: function () {
                                this.returnValue = false;
                            },
                            stopPropagation: function () {
                                this.cancelBubble = true;
                            }

                        });
                    }
                    if (e && JCEMediaBox.isWebKit) {
                        if (e.target.nodeType == 3) {
                            e.target = e.target.parentNode;
                        }
                    }

                    if (!s)
                        return f(e);

                    return f.call(s, e);
                };

                // Internal function to add an event to an object
                function _add(o, n, f) {
                    if (o.attachEvent) {
                        o.attachEvent('on' + n, f);
                    } else if (o.addEventListener) {
                        o.addEventListener(n, f, false);
                    } else {
                        o['on' + n] = f;
                    }
                }

                t.events.push({
                    obj: o,
                    name: n,
                    func: f,
                    cfunc: cb,
                    scope: s
                });

                // Add event
                _add(o, n, cb);
            },
            /**
             * Removes the specified event handler by name and function from a element or collection of elements.
             *
             * @method remove
             * @param {String/Element/Array} o Element ID string or HTML element or an array of elements or ids to remove handler from.
             * @param {String} n Event handler name like for example: "click"
             * @param {function} f Function to remove.
             * @return {bool/Array} Bool state if true if the handler was removed or an array with states if multiple elements where passed in.
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            remove: function (o, n, f) {
                var t = this, a = t.events, s = false;

                JCEMediaBox.each(a, function (e, i) {
                    if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {
                        a.splice(i, 1);
                        t._remove(o, n, e.cfunc);
                        s = true;
                        return false;
                    }
                });

                return s;
            },
            /**
             * Internal function to remove an Event
             * @param {Object} o
             * @param {Object} n
             * @param {Object} f
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            _remove: function (o, n, f) {
                if (o) {
                    try {
                        if (o.detachEvent)
                            o.detachEvent('on' + n, f);
                        else if (o.removeEventListener)
                            o.removeEventListener(n, f, false);
                        else
                            o['on' + n] = null;
                    } catch (ex) {
                        // Might fail with permission denined on IE so we just ignore that
                    }
                }
            },
            /**
             * Cancels an event for both bubbeling and the default browser behavior.
             *
             * @method cancel
             * @param {Event} e Event object to cancel.
             * @return {Boolean} Always false.
             * @copyright Copyright 2009, Moxiecode Systems AB
             */
            cancel: function (e) {
                if (!e)
                    return false;

                this.stop(e);

                return this.prevent(e);
            },
            /**
             * Stops propogation/bubbeling of an event.
             *
             * @method stop
             * @param {Event} e Event to cancel bubbeling on.
             * @return {Boolean} Always false.
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            stop: function (e) {
                if (e.stopPropagation)
                    e.stopPropagation();
                else
                    e.cancelBubble = true;

                return false;
            },
            /**
             * Prevent default browser behvaior of an event.
             *
             * @method prevent
             * @param {Event} e Event to prevent default browser behvaior of an event.
             * @return {Boolean} Always false.
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            prevent: function (e) {
                if (e.preventDefault)
                    e.preventDefault();
                else
                    e.returnValue = false;

                return false;
            },
            /**
             * Destroys the instance.
             *
             * @method destroy
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            destroy: function () {
                var t = this;

                JCEMediaBox.each(t.events, function (e, i) {
                    t._remove(e.obj, e.name, e.cfunc);
                    e.obj = e.cfunc = null;
                });

                t.events = [];
                t = null;
            },
            /**
             * Adds an unload handler to the document. This handler will be executed when the document gets unloaded.
             * This method is useful for dealing with browser memory leaks where it might be vital to remove DOM references etc.
             *
             * @method addUnload
             * @param {function} f Function to execute before the document gets unloaded.
             * @param {Object} s Optional scope to execute the function in.
             * @return {function} Returns the specified unload handler function.
             * @copyright	Copyright 2009, Moxiecode Systems AB
             */
            addUnload: function (f, s) {
                var t = this;

                f = {
                    func: f,
                    scope: s || this
                };

                if (!t.unloads) {
                    function unload() {
                        var li = t.unloads, o, n;

                        if (li) {
                            // Call unload handlers
                            for (n in li) {
                                o = li[n];

                                if (o && o.func)
                                    o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy
                            }

                            // Detach unload function
                            if (window.detachEvent) {
                                window.detachEvent('onbeforeunload', fakeUnload);
                                window.detachEvent('onunload', unload);
                            } else if (window.removeEventListener)
                                window.removeEventListener('unload', unload, false);

                            // Destroy references
                            t.unloads = o = li = w = unload = 0;

                            // Run garbarge collector on IE
                            if (window.CollectGarbage)
                                CollectGarbage();
                        }
                    }

                    function fakeUnload() {
                        var d = document;

                        // Is there things still loading, then do some magic
                        if (d.readyState == 'interactive') {
                            function stop() {
                                // Prevent memory leak
                                d.detachEvent('onstop', stop);

                                // Call unload handler
                                if (unload)
                                    unload();

                                d = 0;
                            }

                            // Fire unload when the currently loading page is stopped
                            if (d)
                                d.attachEvent('onstop', stop);

                            // Remove onstop listener after a while to prevent the unload function
                            // to execute if the user presses cancel in an onbeforeunload
                            // confirm dialog and then presses the browser stop button
                            window.setTimeout(function () {
                                if (d)
                                    d.detachEvent('onstop', stop);
                            }, 0);

                        }
                    }

                    // Attach unload handler
                    if (window.attachEvent) {
                        window.attachEvent('onunload', unload);
                        window.attachEvent('onbeforeunload', fakeUnload);
                    } else if (window.addEventListener)
                        window.addEventListener('unload', unload, false);

                    // Setup initial unload handler array
                    t.unloads = [f];
                } else
                    t.unloads.push(f);

                return f;
            },
            /**
             * Removes the specified function form the unload handler list.
             *
             * @method removeUnload
             * @param {function} f Function to remove from unload handler list.
             * @return {function} Removed function name or null if it wasn't found.
             */
            removeUnload: function (f) {
                var u = this.unloads, r = null;

                JCEMediaBox.each(u, function (o, i) {
                    if (o && o.func == f) {
                        u.splice(i, 1);
                        r = f;
                        return false;
                    }
                });

                return r;
            }

        },
        Dimensions: {
            /**
             * Get client window width
             */
            getWidth: function () {
                return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0;
            },
            /**
             * Get client window height
             */
            getHeight: function () {
                if (JCEMediaBox.isiOS || JCEMediaBox.isAndroid) {
                    var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
                    return window.innerHeight * zoomLevel;
                }

                return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0;
            },
            /**
             * Get client window scroll height
             */
            getScrollHeight: function () {
                return document.documentElement.scrollHeight || document.body.scrollHeight || 0;
            },
            /**
             * Get client window scroll width
             */
            getScrollWidth: function () {
                return document.documentElement.scrollWidth || document.body.scrollWidth || 0;
            },
            /**
             * Get client window scroll top
             */
            getScrollTop: function () {
                return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
            },
            /**
             * Get the page scrollbar width
             */
            getScrollbarWidth: function () {
                var DOM = JCEMediaBox.DOM;

                if (this.scrollbarWidth) {
                    return this.scrollbarWidth;
                }

                var outer = DOM.add(document.body, 'div', {
                    'style': {
                        position: 'absolute',
                        visibility: 'hidden',
                        width: 200,
                        height: 200,
                        border: 0,
                        margin: 0,
                        padding: 0,
                        overflow: 'hidden'
                    }
                });

                var inner = DOM.add(outer, 'div', {
                    'style': {
                        width: '100%',
                        height: 200,
                        border: 0,
                        margin: 0,
                        padding: 0
                    }
                });

                var w1 = parseInt(inner.offsetWidth);
                outer.style.overflow = 'scroll';
                var w2 = parseInt(inner.offsetWidth);
                if (w1 == w2) {
                    w2 = parseInt(outer.clientWidth);
                }
                document.body.removeChild(outer);
                this.scrollbarWidth = (w1 - w2);

                return this.scrollbarWidth;
            },
            /**
             * Get the outerwidth of an element
             * @param {Object} n Element
             */
            outerWidth: function (n) {
                var v = 0, x = 0;

                x = n.offsetWidth;

                if (!x) {
                    JCEMediaBox.each(['padding-left', 'padding-right', 'border-left', 'border-right', 'width'], function (s) {
                        v = parseFloat(JCEMediaBox.DOM.style(n, s));
                        v = /[0-9]/.test(v) ? v : 0;

                        x = x + v;
                    });

                }
                return x;
            },
            /**
             * Get the outerheight of an Element
             * @param {Object} n Element
             */
            outerHeight: function (n) {
                var v = 0, x = 0;

                x = n.offsetHeight;

                if (!x) {
                    JCEMediaBox.each(['padding-top', 'padding-bottom', 'border-top', 'border-bottom', 'height'], function (s) {
                        v = parseFloat(JCEMediaBox.DOM.style(n, s));
                        v = /[0-9]/.test(v) ? v : 0;
                        x = x + v;
                    });

                }
                return x;
            }

        },
        /**
         * FX Functions
         * @param {Object} t
         * @param {Object} b
         * @param {Object} c
         * @param {Object} d
         */
        FX: {
            animate: function (el, props, speed, cb) {
                var DOM = JCEMediaBox.DOM;
                var options = {
                    speed: speed || 100,
                    callback: cb ||
                            function () {
                            }

                };

                var styles = {}, sv;

                JCEMediaBox.each(props, function (v, s) {
                    // Find start value
                    sv = parseFloat(DOM.style(el, s));
                    styles[s] = [sv, v];
                });

                new JCEMediaBox.fx(el, options).custom(styles);
                return true;
            }

        }
    };

    /**
     * XHR Functions
     * Based on XHR.js (Mootools) and XHR.js (TinyMCE)
     * Copyright 2009, Moxiecode Systems AB, <http://tinymce.moxiecode.com>
     * copyright (c) 2007 Valerio Proietti, <http://mad4milk.net>
     */
    JCEMediaBox.XHR = function (options, scope) {
        this.options = {
            //method: 'GET',
            async: true,
            headers: {
                //'User-Agent' 		: 'XMLHTTP/1.0',
                'X-Requested-With': 'XMLHttpRequest',
                'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
            },
            data: null,
            encoding: 'UTF-8',
            success: function () {
            },
            error: function () {
            }

        };
        // Set options
        JCEMediaBox.extend(this.options, options);
        // optional scope for callback functions
        this.scope = scope || this;
    };

    JCEMediaBox.XHR.prototype = {
        /**
         * Set transport method
         */
        setTransport: function () {
            function get(s) {
                var x = 0;

                try {
                    x = new ActiveXObject(s);
                } catch (ex) {
                }

                return x;
            }

            this.transport = window.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');
        },
        /**
         * Process return
         */
        onStateChange: function () {
            if (this.transport.readyState != 4 || !this.running) {
                return;
            }

            this.running = false;

            if ((this.transport.status >= 200) && (this.transport.status < 300)) {
                var s = this.transport.responseText;
                var x = this.transport.responseXML;

                this.options.success.call(this.scope, s, x);
            } else {
                this.options.error.call(this.scope, this.transport, this.options);
            }
            // Clean up
            this.transport.onreadystatechange = function () {
            };

            this.transport = null;
        },
        /**
         * Send request
         * @param {Object} url URL
         * @param {Object} options Request options
         * @param {Object} s Scope
         */
        send: function (url) {
            var t = this, extend = JCEMediaBox.extend;
            if (this.running) {
                return this;
            }
            this.running = true;
            // Set request transport method
            this.setTransport();
            // store request method as uppercase (GET|POST)
            var method = this.options.data ? 'POST' : 'GET';

            // set encoding
            var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding.toUpperCase() : '';

            // Set standard GET header
            var contentType = {
                'Content-type': 'text/html' + encoding
            };

            // Set URL Encoded / POST header options
            if (this.options.data) {
                contentType = {
                    'Content-type': 'application/x-www-form-urlencoded' + encoding
                };
            }

            extend(this.options.headers, contentType);

            // Open transport
            this.transport.open(method, url, this.options.async);
            // Set readystatechange function
            this.transport.onreadystatechange = function () {
                return t.onStateChange();
            };

            /*if (method == 'POST' && this.transport.overrideMimeType) {
             extend(this.options.headers, {
             'Connection': 'close'
             });
             }*/
            // set headers
            for (var type in this.options.headers) {
                try {
                    this.transport.setRequestHeader(type, this.options.headers[type]);
                } catch (e) {
                }
            }
            // send request
            this.transport.send(this.options.data);
        }

    }, /**
     * Core Fx Functions
     * @param {Object} el Element to animate
     * @param {Object} props A set of styles to animate
     * @param {String} speed Speed of animation in milliseconds
     * @param {Object} cb Optional Callback when the animation finishes
     */
    JCEMediaBox.fx = function (el, options) {
        this.element = el;
        this.callback = options.callback;
        this.speed = options.speed;
        this.wait = true;
        this.fps = 50;
        this.now = {};
    };

    /**
     * Based on Moo.Fx.Base and Moo.Fx.Styles
     * @copyright (c) 2006 Valerio Proietti (http://mad4milk.net). MIT-style license.
     */
    JCEMediaBox.fx.prototype = {
        step: function () {
            var time = new Date().getTime();
            if (time < this.time + this.speed) {
                this.cTime = time - this.time;
                this.setNow();

            } else {
                var t = this;
                this.clearTimer();
                this.now = this.to;

                setTimeout(function () {
                    t.callback.call(t.element, t);
                }, 10);

            }
            this.increase();
        },
        setNow: function () {
            var p;

            for (p in this.from) {
                this.now[p] = this.compute(this.from[p], this.to[p]);
            }
        },
        compute: function (from, to) {
            var change = to - from;
            return this.transition(this.cTime, from, change, this.speed);
        },
        clearTimer: function () {
            clearInterval(this.timer);
            this.timer = null;
            return this;
        },
        start: function (from, to) {
            var t = this;
            if (!this.wait)
                this.clearTimer();

            if (this.timer)
                return;

            this.from = from;
            this.to = to;
            this.time = new Date().getTime();
            this.timer = setInterval(function () {
                return t.step();
            }, Math.round(1000 / this.fps));

            return this;
        },
        custom: function (o) {
            if (this.timer && this.wait)
                return;
            var from = {}, to = {}, property;

            for (property in o) {
                from[property] = o[property][0];
                to[property] = o[property][1];
            }
            return this.start(from, to);
        },
        increase: function () {
            for (var p in this.now) {
                this.setStyle(this.element, p, this.now[p]);
            }
        },
        transition: function (t, b, c, d) {
            return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
        },
        setStyle: function (e, p, v) {
            JCEMediaBox.DOM.style(e, p, v);
        }

    },
    /**
     * Core Tooltip Object
     * Create and display tooltips
     * Based on Mootools Tips Class
     * copyright (c) 2007 Valerio Proietti, <http://mad4milk.net>
     */
    JCEMediaBox.ToolTip = {
        /**
         * Initialise the tooltip
         * @param {Object} elements
         * @param {Object} options
         */
        init: function () {
            var t = this;

            // Load tooltip theme
            var theme = JCEMediaBox.options.theme == 'custom' ? JCEMediaBox.options.themecustom : JCEMediaBox.options.theme;

            this.tooltiptheme = '';

            new JCEMediaBox.XHR({
                success: function (text, xml) {
                    var re = /<!-- THEME START -->([\s\S]*?)<!-- THEME END -->/;
                    if (re.test(text)) {
                        text = re.exec(text)[1];
                    }
                    t.tooltiptheme = text;

                    t.create();
                }

            }).send(JCEMediaBox.site + JCEMediaBox.options.themepath + '/' + theme + '/tooltip.html');
        },
        /**
         * Create tooltips in the cuurent document or node
         * @param o Option parent node, defaults to document
         */
        create: function (o) {
            var t = this, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, Event = JCEMediaBox.Event;

            /**
             * Private internal function to exclude children of element in event
             * @param {Object} el 	Element with event
             * @param {Object} e 	Event object
             * @param {Object} fn 	Callback function
             */
            function _withinElement(el, e, fn) {
                // Get target
                var p = e.relatedTarget;
                // If element is not target and target not within element...
                while (p && p != el) {
                    try {
                        p = p.parentNode;
                    } catch (e) {
                        p = el;
                    }
                }

                if (p != el) {
                    return fn.call(this);
                }
                return false;
            }

            // Add events to each found tooltip element
            each(DOM.select('.jcetooltip, .jce_tooltip', o), function (el) {
                // store away title
                DOM.attribute(el, 'data-title', el.title);
                DOM.remove(el, 'title');

                var n = el;

                // set event element as parent if popup icon
                if (el.nodeName == 'IMG' && el.parentNode.className == 'jcemediabox-zoom-span') {
                    n = el.parentNode;
                }

                Event.add(n, 'mouseover', function (e) {
                    _withinElement(el, e, function () {
                        return t.start(el);
                    });

                });

                Event.add(n, 'mouseout', function (e) {
                    _withinElement(el, e, function () {
                        return t.end(el);
                    });

                });

                Event.add(n, 'mousemove', function (e) {
                    return t.locate(e);
                });

            });

        },
        /**
         * Create the tooltip div
         */
        build: function () {
            if (!this.toolTip) {
                var DOM = JCEMediaBox.DOM;
                this.toolTip = DOM.add(document.body, 'div', {
                    'style': {
                        'opacity': 0
                    },
                    'class': 'jcemediabox-tooltip'
                }, this.tooltiptheme);
                if (JCEMediaBox.isIE6) {
                    DOM.addClass(this.toolTip, 'ie6');
                }
            }
        },
        /**
         * Show the tooltip and build the tooltip text
         * @param {Object} e  Event
         * @param {Object} el Target Element
         */
        start: function (el) {
            var t = this, DOM = JCEMediaBox.DOM;
            if (!this.tooltiptheme)
                return false;
            // Create tooltip if it doesn't exist
            this.build();

            // Get tooltip text from title
            var text = DOM.attribute(el, 'data-title') || '', title = '';

            // Split tooltip text ie: title::text
            if (/::/.test(text)) {
                var parts = text.split('::');
                title = JCEMediaBox.trim(parts[0]);
                text = JCEMediaBox.trim(parts[1]);
            }

            var h = '';
            // Set tooltip title html
            if (title) {
                h += '<h4>' + title + '</h4>';
            }
            // Set tooltip text html
            if (text) {
                h += '<p>' + text + '</p>';
            }

            // Set tooltip html
            var tn = DOM.get('jcemediabox-tooltip-text');
            // Use simple tooltip
            if (typeof tn == 'undefined') {
                this.toolTip.className = 'jcemediabox-tooltip-simple';
                this.toolTip.innerHTML = h;
            } else {
                tn.innerHTML = h;
            }
            // Set visible
            DOM.style(t.toolTip, 'visibility', 'visible');
            // Fade in tooltip
            JCEMediaBox.FX.animate(t.toolTip, {
                'opacity': JCEMediaBox.options.tooltip.opacity
            }, JCEMediaBox.options.tooltip.speed);
        },
        /**
         * Fade Out and hide the tooltip
         * Restore the original element title
         * @param {Object} el Element
         */
        end: function (el) {
            if (!this.tooltiptheme)
                return false;

            // Fade out tooltip and hide

            JCEMediaBox.DOM.styles(this.toolTip, {
                'visibility': 'hidden',
                'opacity': 0
            });
        },
        /**
         * Position the tooltip
         * @param {Object} e Event trigger
         */
        locate: function (e) {
            if (!this.tooltiptheme)
                return false;

            this.build();

            var o = JCEMediaBox.options.tooltip.offsets;
            var page = {
                'x': e.pageX || e.clientX + document.documentElement.scrollLeft,
                'y': e.pageY || e.clientY + document.documentElement.scrollTop
            };
            var tip = {
                'x': this.toolTip.offsetWidth,
                'y': this.toolTip.offsetHeight
            };
            var pos = {
                'x': page.x + o.x,
                'y': page.y + o.y
            };

            var ah = 0;

            switch (JCEMediaBox.options.tooltip.position) {
                case 'tl':
                    pos.x = (page.x - tip.x) - o.x;
                    pos.y = (page.y - tip.y) - (ah + o.y);
                    break;
                case 'tr':
                    pos.x = page.x + o.x;
                    pos.y = (page.y - tip.y) - (ah + o.y);
                    break;
                case 'tc':
                    pos.x = (page.x - Math.round((tip.x / 2))) + o.x;
                    pos.y = (page.y - tip.y) - (ah + o.y);
                    break;
                case 'bl':
                    pos.x = (page.x - tip.x) - o.x;
                    pos.y = (page.y + Math.round((tip.y / 2))) - (ah + o.y);
                    break;
                case 'br':
                    pos.x = page.x + o.x;
                    pos.y = page.y + o.y;
                    break;
                case 'bc':
                    pos.x = (page.x - (tip.x / 2)) + o.x;
                    pos.y = page.y + ah + o.y;
                    break;
            }
            JCEMediaBox.DOM.styles(this.toolTip, {
                top: pos.y,
                left: pos.x
            });
        },
        /**
         * Position the tooltip
         * @param {Object} element
         */
        position: function (element) {
        }

    },
    /**
     * Core Popup Object
     * Creates and displays a media popup
     */
    JCEMediaBox.Popup = {
        /**
         * List of default addon media types
         */
        addons: {
            'flash': {},
            'image': {},
            'iframe': {},
            'html': {},
            'pdf': {}
        },
        /**
         * Extend the addons object with a new addon
         * @param {String} n Addon name
         * @param {Object} o Addon object
         */
        setAddons: function (n, o) {
            JCEMediaBox.extend(this.addons[n], o);
        },
        /**
         * Return an addon object by name or all addons
         * @param {String} n Addon name
         */
        getAddons: function (n) {
            if (n) {
                return this.addons[n];
            }
            return this.addons;
        },
        /**
         * Get / Test an addon object
         * @param {Object} v
         * @param {Object} n
         */
        getAddon: function (v, n) {
            var cp = false, r, each = JCEMediaBox.each;

            addons = this.getAddons(n);

            each(this.addons, function (o, s) {
                each(o, function (fn) {
                    r = fn.call(this, v);
                    if (typeof r != 'undefined') {
                        cp = r;
                    }
                });

            });

            return cp;
        },
        /**
         * Clean an event removing anonymous function etc.
         * @param {String} s Event content
         * Copyright 2009, Moxiecode Systems AB
         */
        cleanEvent: function (s) {
            return s.replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
        },
        /**
         * Create an object from a well formed JSON string
         * @param {String} data JSON String
         * @return {Object}
         * Logic borrowed from JQuery
         * http://jquery.com/
         * Copyright 2010, John Resig
         */
        parseJSON: function (data) {
            if (typeof data !== "string" || !data) {
                return null;
            }

            if (/^[\],:{}\s]*$/
                    .test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
                            .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
                            .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
                // Try to use the native JSON parser first
                return window.JSON && window.JSON.parse ?
                        window.JSON.parse(data) :
                        (new Function("return " + data))();
            }
        },
        /**
         * Get a popup parameter object
         * @param {String} s Parameter string
         */
        params: function (s) {
            var a = [], x = [], self = this, DOM = JCEMediaBox.DOM;

            function trim(s) {
                return s = s.replace(/^\s+/, '').replace(/\s+$/, '');
            }

            if (typeof s == 'string') {
                // if a JSON string return the object
                if (/^\{[\w\W]+\}$/.test(s)) {
                    return this.parseJSON(s);
                }

                // JCE MediaBox parameter format eg: title[title]
                if (/\w+\[[^\]]+\]/.test(s)) {
                    s = s.replace(/([\w]+)\[([^\]]+)\](;)?/g, function (a, b, c, d) {

                        return '"' + b + '":"' + DOM.encode(trim(c)) + '"' + (d ? ',' : '');
                    });

                    return this.parseJSON('{' + s + '}');
                }

                // if url
                if (s.indexOf('&') != -1) {
                    x = s.split(/&(amp;)?/g);
                } else {
                    x.push(s);
                }
            }

            // if array
            if (typeof s == 'object' && s instanceof Array) {
                x = s;
            }

            JCEMediaBox.each(x, function (n, i) {
                if (n) {
                    n = n.replace(/^([^\[]+)(\[|=|:)([^\]]*)(\]?)$/, function (a, b, c, d) {
                        if (d) {
                            if (!/[^0-9]/.test(d)) {
                                return '"' + b + '":' + parseInt(d);
                            }

                            return '"' + b + '":"' + DOM.encode(trim(d)) + '"';
                        }
                        return '';
                    });

                    if (n) {
                        a.push(n);
                    }
                }
            });

            return this.parseJSON('{' + a.join(',') + '}');
        },
        /**
         * Gets the raw data of a cookie by name.
         * Copyright 2009, Moxiecode Systems AB
         *
         * @method get
         * @param {String} n Name of cookie to retrive.
         * @return {String} Cookie data string.
         */
        getCookie: function (n) {
            var c = document.cookie, e, p = n + "=", b;

            // Strict mode
            if (!c)
                return;

            b = c.indexOf("; " + p);

            if (b == -1) {
                b = c.indexOf(p);

                if (b != 0)
                    return null;
            } else {
                b += 2;
            }

            e = c.indexOf(";", b);

            if (e == -1)
                e = c.length;

            return unescape(c.substring(b + p.length, e));
        },
        /**
         * Sets a raw cookie string.
         * Copyright 2009, Moxiecode Systems AB
         *
         * @method set
         * @param {String} n Name of the cookie.
         * @param {String} v Raw cookie data.
         * @param {Date} e Optional date object for the expiration of the cookie.
         * @param {String} p Optional path to restrict the cookie to.
         * @param {String} d Optional domain to restrict the cookie to.
         * @param {String} s Is the cookie secure or not.
         */
        setCookie: function (n, v, e, p, d, s) {
            document.cookie = n + "=" + escape(v) +
                    ((e) ? "; expires=" + e.toGMTString() : "") +
                    ((p) ? "; path=" + escape(p) : "") +
                    ((d) ? "; domain=" + d : "") +
                    ((s) ? "; secure" : "");
        },
        /**
         * Convert legacy popups to new format
         */
        convertLegacy: function () {
            var self = this, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM;
            each(DOM.select('a[href]'), function (el) {

                // Only JCE Popup links
                if (/com_jce/.test(el.href)) {
                    var p, s, img;
                    var oc = DOM.attribute(el, 'onclick');
                    if (oc) {
                        s = oc.replace(/&#39;/g, "'").split("'");
                        p = self.params(s[1]);

                        var img = p.img || '';
                        var title = p.title || '';
                    }

                    if (img) {
                        if (!/http:\/\//.test(img)) {
                            if (img.charAt(0) == '/') {
                                img = img.substr(1);
                            }
                            img = JCEMediaBox.site.replace(/http:\/\/([^\/]+)/, '') + img;
                        }

                        DOM.attributes(el, {
                            'href': img,
                            'title': title.replace(/_/, ' '),
                            'onclick': ''
                        });

                        DOM.addClass(el, 'jcepopup');
                    }
                }
            });

        },
        /**
         * Convert lightbox popups to MediaBox
         */
        convertLightbox: function () {
            var each = JCEMediaBox.each, DOM = JCEMediaBox.DOM;
            each(DOM.select('a[rel*=lightbox]'), function (el) {
                DOM.addClass(el, 'jcepopup');
                r = el.rel.replace(/lightbox\[?([^\]]*)\]?/, function (a, b) {
                    if (b) {
                        return 'group[' + b + ']';
                    }
                    return '';
                });

                DOM.attribute(el, 'rel', r);
            });

        },
        /**
         * Convert shadowbox popups to MediaBox
         */
        convertShadowbox: function () {
            var each = JCEMediaBox.each, DOM = JCEMediaBox.DOM;
            each(DOM.select('a[rel*=shadowbox]'), function (el) {
                DOM.addClass(el, 'jcepopup');
                r = el.rel.replace(/shadowbox\[?([^\]]*)\]?/, function (a, b) {
                    var attribs = '', group = '';
                    // group
                    if (b) {
                        group = 'group[' + b + ']';
                    }
                    // attributes
                    if (/;=/.test(a)) {
                        attribs = a.replace(/=([^;"]+)/g, function (x, z) {
                            return '[' + z + ']';
                        });

                    }
                    if (group && attribs) {
                        return group + ';' + attribs;
                    }
                    return group || attribs || '';
                });

                DOM.attribute(el, 'rel', r);
            });

        },
        /**
         * Translate popup labels
         * @param {String} s Theme HTML
         */
        translate: function (s) {
            if (!s) {
                s = this.popup.theme;
            }
            s = s.replace(/\{#(\w+?)\}/g, function (a, b) {
                return JCEMediaBox.options.popup.labels[b];
            });

            return s;
        },
        /**
         * Returns a styles object from a parameter
         * @param {Object} o
         */
        styles: function (o) {
            var x = [];
            if (!o)
                return {};

            JCEMediaBox.each(o.split(';'), function (s, i) {
                s = s.replace(/(.*):(.*)/, function (a, b, c) {
                    return '"' + b + '":"' + c + '"';
                });

                x.push(s);
            });

            return this.parseJSON('{' + x.join(',') + '}');
        },
        /**
         * Get the file type from the url, type attribute or className
         * @param {Object} el
         */
        getType: function (el) {
            var o = {}, type = '';

            // Media types
            if (el.type && /(director|windowsmedia|mplayer|quicktime|real|divx|flash|pdf)/.test(el.type)) {
                type = /(director|windowsmedia|mplayer|quicktime|real|divx|flash|pdf)/.exec(el.type)[1];
            }

            o = this.getAddon(el.src);

            if (o && o.type) {
                type = o.type;
            }

            return type || el.type || 'iframe';
        },
        /**
         * Determine media type and properties
         * @param {Object} c
         */
        mediatype: function (c) {
            var ci, cb, mt;

            c = /(director|windowsmedia|mplayer|quicktime|real|divx|flash|pdf)/.exec(c);

            switch (c[1]) {
                case 'director':
                case 'application/x-director':
                    ci = '166b1bca-3f9c-11cf-8075-444553540000';
                    cb = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0';
                    mt = 'application/x-director';
                    break;
                case 'windowsmedia':
                case 'mplayer':
                case 'application/x-mplayer2':
                    ci = '6bf52a52-394a-11d3-b153-00c04f79faa6';
                    cb = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';
                    mt = 'application/x-mplayer2';
                    break;
                case 'quicktime':
                case 'video/quicktime':
                    ci = '02bf25d5-8c17-4b23-bc80-d3488abddc6b';
                    cb = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0';
                    mt = 'video/quicktime';
                    break;
                case 'real':
                case 'realaudio':
                case 'audio/x-pn-realaudio-plugin':
                    ci = 'cfcdaa03-8be4-11cf-b84b-0020afbbccfa';
                    cb = '';
                    mt = 'audio/x-pn-realaudio-plugin';
                    break;
                case 'divx':
                case 'video/divx':
                    ci = '67dabfbf-d0ab-41fa-9c46-cc0f21721616';
                    cb = 'http://go.divx.com/plugin/DivXBrowserPlugin.cab';
                    mt = 'video/divx';
                    break;
                case 'pdf':
                case 'application/pdf':
                    ci = 'ca8a9780-280d-11cf-a24d-444553540000';
                    cb = '';
                    mt = 'application/pdf';
                    break;
                default:
                case 'flash':
                case 'application/x-shockwave-flash':
                    ci = 'd27cdb6e-ae6d-11cf-96b8-444553540000';
                    cb = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,124,0';
                    mt = 'application/x-shockwave-flash';
                    break;
            }
            return {
                'classid': ci,
                'codebase': cb,
                'mediatype': mt
            };
        },
        /**
         * Determine whether the url is local
         * @param {Object} s
         */
        islocal: function (s) {
            if (/^(\w+:)?\/\//.test(s)) {
                return new RegExp('^(' + JCEMediaBox.site + ')').test(s);
            } else {
                return true;
            }
        },
        protocolRelative: function (url) {
            if (JCEMediaBox.isIE6) {
                return url;
            }

            var local = document.location.href;

            // external ssl
            if (url.indexOf('https://') !== -1) {
                return url;
            }

            // local ssl, use protocol relative for non-ssl external
            if (local.indexOf('https://') !== -1) {
                return url.replace(/http(s)?:\/\//i, '//');
            }

            return url;
        },
        /**
         * Get the width of the container frame
         */
        frameWidth: function () {
            var w = 0, el = this.frame;

            JCEMediaBox.each(['left', 'right'], function (s) {
                w = w + parseFloat(JCEMediaBox.DOM.style(el, 'padding-' + s));
            });

            return parseFloat(this.frame.clientWidth - w);
        },
        /**
         * Get the height of the container frame
         */
        frameHeight: function () {
            var h = 0, el = this.frame, DIM = JCEMediaBox.Dimensions;

            JCEMediaBox.each(['top', 'bottom'], function (s) {
                h = h + parseFloat(JCEMediaBox.DOM.style(el, 'padding-' + s));
            });

            h = h + ((JCEMediaBox.isIE6 || JCEMediaBox.isIE7) ? DIM.getScrollbarWidth() : 0);

            return parseInt(DIM.getHeight()) - h;
        },
        /**
         * Get the width of the usable window
         */
        width: function () {
            return this.frameWidth() - JCEMediaBox.Dimensions.getScrollbarWidth();
        },
        /**
         * Get the height of the usable window less info divs
         */
        height: function () {
            var h = 0, t = this, each = JCEMediaBox.each, DIM = JCEMediaBox.Dimensions;
            each(['top', 'bottom'], function (s) {
                var el = t['info-' + s];
                if (el) {
                    h = h + parseInt(DIM.outerHeight(el));
                }
            });

            return this.frameHeight() - h;
        },
        /**
         * Print the page contents (TODO)
         */
        printPage: function () {
            return false;
        },
        /**
         * Create a popup zoom icon
         * @param {Object} el Popup link element
         */
        zoom: function (el) {
            var self = this;
            var DOM = JCEMediaBox.DOM, extend = JCEMediaBox.extend, each = JCEMediaBox.each;
            var children = el.childNodes;

            // Create basic zoom element
            var zoom = DOM.create('span');

            // add IE6 identifier class
            if (JCEMediaBox.isIE6) {
                DOM.addClass(el, 'ie6');
            }

            var cls = DOM.attribute(el, 'class');
            // replace icon- with zoom- to avoid bootstrap etc. conflicts
            cls = cls.replace('icon-', 'zoom-', 'g');
            DOM.attribute(el, 'class', cls);

            var img = DOM.select('img', el);

            // If child is an image (thumbnail)
            if (img && img.length) {
                // get first img tag
                var child = img[0];

                var align = child.getAttribute('align');
                var vspace = child.getAttribute('vspace');
                var hspace = child.getAttribute('hspace');

                var styles = {};

                // Transfer margin, padding and border
                each(['top', 'right', 'bottom', 'left'], function (pos) {
                    // Set margin
                    styles['margin-' + pos] = DOM.style(child, 'margin-' + pos);
                    // Set padding
                    styles['padding-' + pos] = DOM.style(child, 'padding-' + pos);
                    // Set border
                    each(['width', 'style', 'color'], function (prop) {
                        styles['border-' + pos + '-' + prop] = DOM.style(child, 'border-' + pos + '-' + prop);
                    });
                });

                // Correct from deprecated align attribute
                if (/\w+/.test(align)) {
                    extend(styles, {
                        'float': /left|right/.test(align) ? align : '',
                        'text-align': /top|middle|bottom/.test(align) ? align : ''
                    });
                }
                // Correct from deprecated vspace attribute
                if (vspace > 0) {
                    extend(styles, {
                        'margin-top': parseInt(vspace),
                        'margin-bottom': parseInt(vspace)
                    });
                }
                // Correct from deprecated hspace attribute
                if (hspace > 0) {
                    extend(styles, {
                        'margin-left': parseInt(hspace),
                        'margin-right': parseInt(hspace)
                    });
                }

                var w = child.getAttribute('width');
                var h = child.getAttribute('height');
                var ws = child.style.width;

                // get 'real' width and height
                var rh = child.height, rw = child.width;

                // we can only render the zoom icon if we have a valid dimensions for the image
                if (!w && !ws && !rw) {
                    // prevent loop
                    if (child.loaded) {
                        return false;
                    }

                    child.onload = function() {
                        child.loaded = true;

                        return self.zoom(el);
                    };

                    child.onerror = function() {
                        return false;
                    };

                    return false;
                }

                // height is set but not width, calculate width
                if (!w && h) {
                    w = h / rh * rw;
                }

                if (!w) {
                    // pixel value
                    if (/([0-9]+)(px)?$/.test(ws)) {
                        w = parseFloat(ws);
                        // other value
                    } else {
                        w = rw;
                    }
                }

                // add width values if set
                if (w) {
                    child.setAttribute('width', w);
                    styles.width = w;
                }

                // Add style alignment
                extend(styles, {
                    'text-align': child.style.textAlign
                });

                var float = DOM.style(child, 'float');

                if (float === "left" || float === "right") {
                    styles.float = float;
                }

                /**
                 * Private Internal function
                 * Build and place the icon
                 * @param {Object} el The Parent Link Element
                 * @param {Object} zoom The Zoom Element
                 * @param {Object} zoom The Child Element (Image)
                 * @param {Object} styles Computed Styles object
                 */
                function _buildIcon(el, zoom, child, styles) {
                    // Clone image as span element
                    var span = DOM.add(el, 'span', {
                        'class': 'jcemediabox-zoom-span',
                        'style': child.style.cssText
                    });

                    // Set styles
                    DOM.styles(span, styles);

                    if (DOM.hasClass(el.parentNode, 'wf_caption')) {
                        span.style.width = null;
                        DOM.style(span, 'max-width', DOM.style(el.parentNode, 'max-width'));
                    }

                    if (span.style.width) {
                        DOM.style(span, 'max-width', span.style.width);
                        span.style.width = null;
                    }

                    // Move the image into the parent SPAN
                    DOM.add(span, child);
                    // Move the zoom icon into the parent SPAN
                    DOM.add(span, zoom);

                    // Remove attributes that may affect layout
                    each(['style', 'align', 'border', 'hspace', 'vspace'], function (v, i) {
                        child.removeAttribute(v);
                    });

                    // Add zoom-image class
                    DOM.addClass(zoom, 'jcemediabox-zoom-image');

                    // Set explicit positions for IE6 when zoom icon is png
                    if (JCEMediaBox.isIE6 && /\.png/i.test(DOM.style(zoom, 'background-image'))) {
                        DOM.png(zoom);
                    }

                    // Remove styles from image
                    DOM.styles(child, {
                        'margin': 0,
                        'padding': 0,
                        'float': 'none',
                        'border': 'none'
                    });
                }
                // build zoom icon
                _buildIcon(el, zoom, child, styles);
            } else {
                DOM.addClass(zoom, 'jcemediabox-zoom-link');
                if (DOM.hasClass(el, 'zoom-left')) {
                    DOM.addBefore(el, zoom);
                } else {
                    DOM.add(el, zoom);
                }
                // IE7 won't accept display:inherit
                if (JCEMediaBox.isIE7) {
                    DOM.style(zoom, 'display', 'inline-block');
                }
            }
            // Return zoom icon element
            return zoom;
        },
        /**
         * Process autopopups
         */
        auto: function () {
            var t = this, expires = JCEMediaBox.options.popup.cookie_expiry, dts, key;

            function makeID(src) {
                // use the current page URL for unique key
                var url = document.location.href;
                // base64 encode key and popup src
                var key = window.btoa(url + src);
                // remove non-word characters
                key = key.replace(/[^\w]/g, '');
                // keep it short
                key = key.substr(0, 24);

                return key;
            }

            JCEMediaBox.each(this.popups, function (el, i) {
                if (el.auto) {
                    if (el.auto == 'single') {
                        // use element ID or base64 key
                        key = el.id || makeID(el.src);

                        // get cookie
                        var cookie = t.getCookie('jcemediabox_' + key + '_' + i);

                        // create cookie with base64 key and expiry
                        if (!cookie) {
                            // create data if expiry set
                            if (expires) {
                                dts = new Date();
                                dts.setHours(expires * 24);
                            }

                            t.setCookie('jcemediabox_' + key + '_' + i, 1, dts);
                            t.start(el);
                        }
                    } else if (el.auto == 'multiple') {
                        t.start(el);
                    }
                }
            });

        },
        /**
         * Initilise popup and create global jcepopup variable
         * @param {Object} elements Optional array of popup elements
         */
        init: function () {
            window.jcepopup = this;
            this.create();
        },
        /**
         * Get popup objects
         * @param {String} s Optional selector
         * @param {Object} p Optional parent element popups contained within
         */
        getPopups: function (s, p) {
            var selector = 'a.jcebox, a.jcelightbox, a.jcepopup, area.jcebox, area.jcelightbox, area.jcepopup';
            return JCEMediaBox.DOM.select(s || selector, p);
        },
        getData: function (n) {
            var DOM = JCEMediaBox.DOM, each = JCEMediaBox.each, o = {}, data;
            var re = /\w+\[[^\]]+\]/;

            data = n.getAttribute('data-mediabox') || n.getAttribute('data-json');

            if (!data) {
                // try data-mediabox-* attributes (since 1.1.23, JCE 2.5.3)
                var i, attrs = n.attributes, x = 0;

                for (i = attrs.length - 1; i >= 0; i--) {
                    var attrName = attrs[i].name;
                    if (attrName && attrName.indexOf('data-mediabox-') !== -1) {
                        var attr = attrName.replace('data-mediabox-', '');
                        o[attr] = attrs[i].value;
                        x++;
                    }
                }

                if (x) {
                    return o;
                }

                var title = DOM.attribute(n, 'title');
                var rel = DOM.attribute(n, 'rel');

                if (title && re.test(title)) {
                    // convert to object
                    o = this.params(title);

                    // restore rel attribute
                    DOM.attribute(n, 'title', o.title || '');

                    return o;
                }

                if (rel && re.test(rel)) {
                    var args = [];

                    rel = rel.replace(/\b((\w+)\[(.*?)\])(;?)/g, function (a, b, c) {
                        args.push(b);
                        return '';
                    });

                    o = this.params(args) || {};

                    // restore rel attribute
                    DOM.attribute(n, 'rel', rel || o.rel || '');

                    return o;
                }
            } else {
                // remove data attributes
                n.removeAttribute('data-json');
                n.removeAttribute('data-mediabox');

                return this.params(data);
            }

            return o;
        },
        /**
         * Process a popup link and return properties object
         * @param {Object} el Popup link element
         */
        process: function (el) {
            var DOM = JCEMediaBox.DOM, data, o = {}, group = '', auto = false;

            // Fix title and rel and move parameters
            var title = el.title || '';
            var rel = el.rel || '';

            var src = el.href;

            // Legacy width/height values
            src = src.replace(/b(w|h)=([0-9]+)/g, function (s, k, v) {
                k = (k == 'w') ? 'width' : 'height';

                return k + '=' + v;
            });

            data = this.getData(el) || {};

            // Process rel attribute
            if (!/\w+\[[^\]]+\]/.test(rel)) {
                var rx = 'alternate|stylesheet|start|next|prev|contents|index|glossary|copyright|chapter|section|subsection|appendix|help|bookmark|nofollow|licence|tag|friend';
                var lb = '(lightbox(\[(.*?)\])?)';
                var lt = '(lyte(box|frame|show)(\[(.*?)\])?)';

                group = JCEMediaBox.trim(rel.replace(new RegExp('\s*(' + rx + '|' + lb + '|' + lt + ')\s*'), '', 'gi'));
            }

            // Get AREA parameters from URL if not set
            if (el.nodeName == 'AREA') {
                if (!data) {
                    data = this.params(src);
                }
                // Set AREA group
                group = group || 'AREA_ELEMENT';
                // set type
                if (!data.type) {
                    if (match = /\b(ajax|iframe|image|flash|director|shockwave|mplayer|windowsmedia|quicktime|realaudio|real|divx|pdf)\b/.exec(el.className)) {
                        data.type = match[0];
                    }
                }
            }

            // check for auto popup
            //if (el.id) {
            if (/autopopup-(single|multiple)/.test(el.className)) {
                auto = /(multiple)/.test(el.className) ? 'multiple' : 'single';
            }
            //}

            // get group from data object
            group = group || data.group || '';

            // Popup object
            JCEMediaBox.extend(o, {
                'src': src,
                'title': data.title || title,
                'group': DOM.hasClass(el, 'nogroup') ? '' : group,
                'type': data.type || el.type || '',
                'params': data,
                //'id'	: el.id || '',
                'auto': auto
            });

            // Remove type
            el.href = el.href.replace(/&type=(ajax|text\/html|text\/xml)/, '');

            return o;
        },
        /**
         * Create a popup from identifiable link or area elements
         * Load the popup theme
         * @param {Object} elements Optional array of popup elements
         */
        create: function (elements) {
            var t = this, each = JCEMediaBox.each, Event = JCEMediaBox.Event, DOM = JCEMediaBox.DOM, pageload = false, auto = false;

            // set pageload marker
            if (!elements) {
                pageload = true;
                this.popups = [];

                // Converts a legacy (window) popup into an inline popup
                if (JCEMediaBox.options.popup.legacy == 1) {
                    t.convertLegacy();
                }

                // Converts a lightbox popup into mediabox popup
                if (JCEMediaBox.options.popup.lightbox == 1) {
                    t.convertLightbox();
                }

                // Converts a shadowbox popup into mediabox popup
                if (JCEMediaBox.options.popup.shadowbox == 1) {
                    t.convertShadowbox();
                }
            }

            // get supplied elements or from jcepopup class
            this.elements = elements || this.getPopups();

            // Iterate through all found or specified popup links
            each(this.elements, function (el, i) {

                if (el.childNodes.length === 1 && el.firstChild.nodeName === "IMG") {
                    DOM.addClass(el, 'jcemediabox-image');
                }

                // Create zoom icon
                if (JCEMediaBox.options.popup.icons == 1 && el.nodeName == 'A' && !/(noicon|icon-none|noshow)/.test(el.className) && el.style.display != 'none') {
                    t.zoom(el);
                }

                // Simplify class identifier for css
                if (/(jcelightbox|jcebox)/.test(el.className)) {
                    DOM.removeClass(el, 'jcelightbox');
                    DOM.removeClass(el, 'jcebox');
                    DOM.addClass(el, 'jcepopup');
                }

                var o = t.process(el);

                t.popups.push(o);

                // new index if not a pageload
                if (!pageload) {
                    i = t.popups.length - 1;
                }

                // Add click event to link
                Event.add(el, 'click', function (e) {
                    Event.cancel(e);
                    return t.start(o, i);
                });

            });

            // if no elements are specified, must be a pageload
            if (pageload) {
                // set theme
                this.popuptheme = '';

                // Load the popup theme
                var theme = JCEMediaBox.options.theme;

                new JCEMediaBox.XHR({
                    success: function (text, xml) {
                        var re = /<!-- THEME START -->([\s\S]*?)<!-- THEME END -->/;
                        if (re.test(text)) {
                            text = re.exec(text)[1];
                        }
                        t.popuptheme = text;
                        // Process auto popups
                        if (!auto) {
                            t.auto();
                            auto = true;
                        }
                    }

                }).send(JCEMediaBox.site + 'plugins/system/jcemediabox/themes/' + theme + '/popup.html');
            }
        },
        /**
         * Public popup method
         * @param {String / Object} data Popup URL string or data object or element
         * @param {String} title Popup Title
         * @param {String} group Popup Group
         * @param {String} type Popup Type, eg: image, flash, ajax
         * @param {Object} params Popup Parameters Object
         */
        open: function (data, title, group, type, params) {
            var i, o = {};

            if (typeof data == 'string') {
                data = {
                    'src': data,
                    'title': title,
                    'group': group,
                    'type': type,
                    'params': params
                };
            }

            // process as an element
            if (typeof (data == 'object') && data.nodeName && (data.nodeName == 'A' || data.nodeName == 'AREA')) {
                i = JCEMediaBox.inArray(this.elements, data);

                if (i >= 0) {
                    return this.start(this.popups[i], i);
                }

                // process element
                var o = this.process(data);

                // add to array
                var x = this.popups.push(o);

                // start
                return this.start(o, x - 1);
            }

            return this.start(data);
        },
        /**
         * Start a popup
         * @param {Object} o The popup link object
         * @param {Object} i The popup index
         */
        start: function (p, i) {
            var n = 0, items = [], each = JCEMediaBox.each, len;

            // build popup window
            if (this.build()) {
                if (p.group) {
                    each(this.popups, function (o, x) {
                        if (o.group == p.group) {
                            len = items.push(o);
                            if (i && x == i) {
                                n = len - 1;
                            }
                        }
                    });

                    // Triggered popup
                    if (!p.auto && typeof i == 'undefined') {
                        items.push(p);
                        n = items.length - 1;
                    }
                } else {
                    items.push(p);
                }
                return this.show(items, n);
            }
        },
        /**
         * Build Popup structure
         */
        build: function () {
            var t = this, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, Event = JCEMediaBox.Event;

            if (!this.page) {
                // Create main page object
                this.page = DOM.add(document.body, 'div', {
                    id: 'jcemediabox-popup-page'
                });

                if (JCEMediaBox.isIE6) {
                    DOM.addClass(this.page, 'ie6');
                }

                if (JCEMediaBox.isIE7) {
                    DOM.addClass(this.page, 'ie7');
                }

                if (JCEMediaBox.isiOS) {
                    DOM.addClass(this.page, 'ios');
                }

                if (JCEMediaBox.isAndroid) {
                    DOM.addClass(this.page, 'android');
                }

                if (JCEMediaBox.options.popup.overlay == 1) {
                    // Create overlay
                    this.overlay = DOM.add(this.page, 'div', {
                        id: 'jcemediabox-popup-overlay',
                        style: {
                            'opacity': 0,
                            'background-color': JCEMediaBox.options.popup.overlaycolor
                        }
                    });
                }

                // Cancel if no theme
                if (!this.popuptheme) {
                    return false;
                }
                // Remove comments
                this.popuptheme = this.popuptheme.replace(/<!--(.*?)-->/g, '');
                // Translate
                this.popuptheme = this.translate(this.popuptheme);
                // Create Frame
                this.frame = DOM.add(this.page, 'div', {
                    id: 'jcemediabox-popup-frame'
                }, '<div id="jcemediabox-popup-body">' + this.popuptheme + '</div>');

                // Create all Popup structure objects
                each(DOM.select('*[id]', this.frame), function (el) {
                    var s = el.id.replace('jcemediabox-popup-', '');
                    t[s] = el;
                    DOM.hide(el);
                });

                if ((JCEMediaBox.isiOS || JCEMediaBox.isAndroid) && JCEMediaBox.isWebKit) {
                    // add iPad scroll fix
                    DOM.style(this.content, 'webkitOverflowScrolling', 'touch');
                }

                // Add close function to frame on click
                if (JCEMediaBox.options.popup.close == 2) {
                    Event.add(this.frame, 'click', function (e) {
                        if (e.target && e.target == t.frame) {
                            t.close();
                        }
                    });
                }

                // Setup Close link event
                if (this.closelink) {
                    Event.add(this.closelink, 'click', function () {
                        return t.close();
                    });

                }
                // Setup Cancel link event
                if (this.cancellink) {
                    Event.add(this.cancellink, 'click', function () {
                        return t.close();
                    });

                }
                // Setup Next link event
                if (this.next) {
                    Event.add(this.next, 'click', function () {
                        return t.nextItem();
                    });

                }
                // Setup Previous link event
                if (this.prev) {
                    Event.add(this.prev, 'click', function () {
                        return t.previousItem();
                    });

                }
                if (this.numbers) {
                    this.numbers.tmpHTML = this.numbers.innerHTML;
                }

                if (this.print) {
                    Event.add(this.print, 'click', function () {
                        return t.printPage();
                    });

                }
                // PNG Fix
                if (JCEMediaBox.isIE6) {
                    DOM.png(this.body);
                    each(DOM.select('*', this.body), function (el) {
                        // Exclude loaded content
                        if (DOM.attribute(el, 'id') == 'jcemediabox-popup-content') {
                            return;
                        }
                        DOM.png(el);
                    });

                }
            }
            return true;
        },
        /**
         * Show the popup window
         * @param {Array} items Array of popup objects
         * @param {Int} n Index of current popup
         */
        show: function (items, n) {
            var DOM = JCEMediaBox.DOM, DIM = JCEMediaBox.Dimensions, top = 0;
            this.items = items;
            this.bind(true);

            // Show popup
            DOM.show(this.body);

            // Get top position
            if (!/\d/.test(this.body.style.top)) {
                top = (DIM.getHeight() - DIM.outerHeight(this.body)) / 2;
            }

            // Set top position
            DOM.style(this.body, 'top', top);
            // Changes if IE6 or scrollpopup
            if (JCEMediaBox.isIE6 || JCEMediaBox.options.popup.scrolling == 'scroll') {
                DOM.addClass(this.page, 'scrolling');
                DOM.style(this.overlay, 'height', DIM.getScrollHeight());
                DOM.style(this.body, 'top', DIM.getScrollTop() + top);
            }
            // Fade in overlay
            if (JCEMediaBox.options.popup.overlay == 1 && this.overlay) {
                DOM.show(this.overlay);
                JCEMediaBox.FX.animate(this.overlay, {
                    'opacity': JCEMediaBox.options.popup.overlayopacity
                }, JCEMediaBox.options.popup.fadespeed);
            }

            return this.change(n);
        },
        /**
         * Create event / key bindings
         * @param {Boolean} open Whether popup is opened or closed
         */

        // TODO - Resize popup when browser window resizes
        bind: function (open) {
            var t = this, isIE6 = JCEMediaBox.isIE6, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, Event = JCEMediaBox.Event, DIM = JCEMediaBox.Dimensions;

            if (isIE6) {
                each(DOM.select('select'), function (el) {
                    if (open) {
                        el.tmpStyle = el.style.visibility || '';
                    }
                    el.style.visibility = open ? 'hidden' : el.tmpStyle;
                });

            }
            if (JCEMediaBox.options.popup.hideobjects) {
                each(DOM.select('object, embed'), function (el) {
                    if (el.id == 'jcemediabox-popup-object')
                        return;
                    if (open) {
                        el.tmpStyle = el.style.visibility || '';
                    }
                    el.style.visibility = open ? 'hidden' : el.tmpStyle;
                });

            }
            var scroll = JCEMediaBox.options.popup.scrollpopup;
            if (open) {
                Event.add(document, 'keydown', function (e) {
                    t.listener(e);
                });

                if (isIE6) {
                    Event.add(window, 'scroll', function (e) {
                        DOM.style(t.overlay, 'height', JCEMediaBox.Dimensions.getScrollHeight());
                    });

                    Event.add(window, 'scroll', function (e) {
                        DOM.style(t.overlay, 'width', JCEMediaBox.Dimensions.getScrollWidth());
                    });

                }
            } else {
                if (isIE6 || !scroll) {
                    Event.remove(window, 'scroll');
                    Event.remove(window, 'resize');
                }
                Event.remove(document, 'keydown');
            }
        },
        /**
         * Keyboard listener
         * @param {Object} e Event
         */
        listener: function (e) {
            switch (e.keyCode) {
                case 27:
                    this.close();
                    break;
                case 37:
                    this.previousItem();
                    break;
                case 39:
                    this.nextItem();
                    break;
            }
        },
        /**
         * Process a popup in the group queue
         * @param {Object} n Queue position
         */
        queue: function (n) {
            var t = this;
            // Optional element
            var changed = false;

            JCEMediaBox.each(['top', 'bottom'], function (s) {
                var el = t['info-' + s];
                if (el) {
                    var v = JCEMediaBox.Dimensions.outerHeight(el);
                    var style = {};
                    style['top'] = (s == 'top') ? v : -v;
                    JCEMediaBox.FX.animate(el, style, JCEMediaBox.options.popup.scalespeed, function () {
                        if (!changed) {
                            changed = true;
                            JCEMediaBox.FX.animate(t.content, {
                                'opacity': 0
                            }, JCEMediaBox.options.popup.fadespeed, function () {
                                return t.change(n);
                            });

                        }
                    });

                }
            });

        },
        /**
         * Process the next popup in the group
         */
        nextItem: function () {
            if (this.items.length == 1)
                return false;
            var n = this.index + 1;

            if (n < 0 || n >= this.items.length) {
                return false;
            }
            return this.queue(n);
        },
        /**
         * Process the previous popup in the group
         */
        previousItem: function () {
            if (this.items.length == 1)
                return false;
            var n = this.index - 1;

            if (n < 0 || n >= this.items.length) {
                return false;
            }
            return this.queue(n);
        },
        /**
         * Set the popup information (caption, title, numbers)
         */
        info: function () {
            var each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, Event = JCEMediaBox.Event;
            // Optional Element Caption/Title

            if (this.caption) {
                var title = this.active.title || '', text = this.active.caption || '', h = '';

                var ex = '([-!#$%&\'\*\+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'\*\+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+)';
                var ux = '((news|telnet|nttp|file|http|ftp|https)://[-!#$%&\'\*\+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'\*\+\\./0-9=?A-Z^_`a-z{|}~]+)';

                function processRe(h) {
                    h = h.replace(new RegExp(ex, 'g'), '<a href="mailto:$1" target="_blank" title="$1">$1</a>');
                    h = h.replace(new RegExp(ux, 'g'), '<a href="$1" target="_blank" title="$1">$1</a>');

                    return h;
                }

                if (title) {
                    h += '<h4>' + DOM.decode(title) + '</h4>';
                }

                if (text) {
                    h += '<p>' + DOM.decode(text) + '</p>';
                }

                // set caption html (may be empty)
                this.caption.innerHTML = h;

                // hide caption container if empty
                if (h != '') {
                    // Process e-mail and urls
                    each(DOM.select('*', this.caption), function (el) {
                        if (el.nodeName != 'A') {
                            each(el.childNodes, function (n, i) {
                                if (n.nodeType == 3) {
                                    var s = n.innerText || n.textContent || n.data || null;
                                    if (s && /(@|:\/\/)/.test(s)) {
                                        if (s = processRe(s)) {
                                            n.parentNode.innerHTML = s;
                                        }
                                    }
                                }
                            });

                        }
                    });
                }
            }
            // Optional Element
            var t = this, len = this.items.length;

            if (this.numbers && len > 1) {
                var html = this.numbers.tmpHTML || '{$numbers}';

                if (/\{\$numbers\}/.test(html)) {
                    this.numbers.innerHTML = '';
                    for (var i = 0; i < len; i++) {
                        var n = i + 1;

                        var title = decodeURIComponent(this.items[i].title || n);

                        // Craete Numbers link
                        var link = DOM.add(this.numbers, 'a', {
                            'href': 'javascript:;',
                            'title': title,
                            'class': (this.index == i) ? 'active' : ''
                        }, n);
                        // add click event
                        Event.add(link, 'click', function (e) {
                            var x = parseInt(e.target.innerHTML) - 1;
                            if (t.index == x) {
                                return false;
                            }
                            return t.queue(x);
                        });

                    }
                }

                if (/\{\$(current|total)\}/.test(html)) {
                    this.numbers.innerHTML = html.replace('{$current}', this.index + 1).replace('{$total}', len);
                }
            } else {
                if (this.numbers) {
                    this.numbers.innerHTML = '';
                }
            }

            each(['top', 'bottom'], function (v, i) {
                var el = t['info-' + v];
                if (el) {
                    DOM.show(el);
                    each(DOM.select('*[id]', el), function (s) {
                        DOM.show(s);
                    });
                    DOM.style(el, 'visibility', 'hidden');
                }
            });

            // Show / Hide Previous and Next buttons
            DOM.hide(this.next);
            DOM.hide(this.prev);

            if (len > 1) {
                if (this.prev) {
                    if (this.index > 0) {
                        DOM.show(this.prev);
                    } else {
                        DOM.hide(this.prev);
                    }
                }
                if (this.next) {
                    if (this.index < len - 1) {
                        DOM.show(this.next);
                    } else {
                        DOM.hide(this.next);
                    }
                }
            }
        },
        /**
         * Change the popup
         * @param {Integer} n Popup number
         */
        change: function (n) {
            var t = this, extend = JCEMediaBox.extend, each = JCEMediaBox.each, inArray = JCEMediaBox.inArray, DOM = JCEMediaBox.DOM, Event = JCEMediaBox.Event, isIE = JCEMediaBox.isIE, DIM = JCEMediaBox.Dimensions;

            var p = {}, o, w, h;
            if (n < 0 || n >= this.items.length) {
                return false;
            }
            this.index = n;
            this.active = {};

            // Show Container
            DOM.show(this.container);
            // Show Loader
            if (this.loader) {
                DOM.show(this.loader);
            }
            // Show Cancel
            if (this.cancellink) {
                DOM.show(this.cancellink);
            }
            // Remove object
            if (this.object) {
                this.object = null;
            }

            this.content.innerHTML = '';

            o = this.items[n];

            // Get parameters from addon
            extend(p, this.getAddon(o.src, o.type));

            // delete alternate src
            delete o.params.src;

            // Get set parameters
            extend(p, o.params);

            var width = p.width || JCEMediaBox.options.popup.width || 0;
            var height = p.height || JCEMediaBox.options.popup.height || 0;

            if (width && /%/.test(width)) {
                width = DIM.getWidth() * parseInt(width) / 100;
            }

            if (height && /%/.test(height)) {
                height = DIM.getHeight() * parseInt(height) / 100;
            }

            var title = o.title || p.title || '';
            var caption = p.caption || '';

            if (/::/.test(title)) {
                var parts = title.split('::');
                title = JCEMediaBox.trim(parts[0]);
                caption = JCEMediaBox.trim(parts[1]);
            }

            // decode title
            title = decodeURIComponent(DOM.decode(title));
            // decode caption
            caption = decodeURIComponent(DOM.decode(caption));

            extend(this.active, {
                'src': p.src || o.src,
                'title': title,
                'caption': caption,
                'type': p.type || this.getType(o),
                'params': p || {},
                'width': width,
                'height': height
            });

            function toAbsolute(url) {
                var div = document.createElement('div');
                div.innerHTML = '<a href="' + url + '">x</a>';

                return div.firstChild.href;
            }

            function resolveMediaPath(s, absolute) {
                if (s && s.indexOf('://') === -1 && s.charAt(0) !== '/') {
                    s = JCEMediaBox.options.base + s;
                }

                if (absolute) {
                    return toAbsolute(s);
                }

                return s;
            }

            switch (this.active.type) {
                case 'image':
                case 'image/jpeg':
                case 'image/png':
                case 'image/gif':
                case 'image/bmp':
                    if (this.print && this.options.print) {
                        this.print.style.visibility = 'visible';
                    }

                    this.img = new Image();
                    this.img.onload = function () {
                        return t.setup();
                    };

                    this.img.onerror = function () {
                        t.img.error = true;
                        return t.setup();
                    };

                    this.img.src = this.active.src;

                    // fix for resize / transparency issues in IE
                    if (isIE) {
                        DOM.style(this.content, 'background-color', DOM.style(this.content, 'background-color'));
                    }

                    // allow image to be resized
                    if (p.width && !p.height) {
                        this.active.height = 0;
                    } else if (p.height && !p.width) {
                        this.active.width = 0;
                    }

                    break;
                case 'flash':
                case 'director':
                case 'shockwave':
                case 'mplayer':
                case 'windowsmedia':
                case 'quicktime':
                case 'realaudio':
                case 'real':
                case 'divx':
                    if (this.print) {
                        this.print.style.visibility = 'hidden';
                    }

                    p.src = this.active.src;

                    var base = /:\/\//.test(p.src) ? '' : this.site;
                    this.object = '';

                    w = this.width();
                    h = this.height();

                    var mt = this.mediatype(this.active.type);

                    if (this.active.type == 'flash') {
                        p.wmode = 'transparent';
                        p.base = base;
                    }
                    if (/(mplayer|windowsmedia)/i.test(this.active.type)) {
                        p.baseurl = base;
                        if (isIE) {
                            p.url = p.src;
                            delete p.src;
                        }
                    }
                    // delete some parameters
                    delete p.title;
                    delete p.group;

                    // Set width/height
                    p.width = this.active.width || this.width();
                    p.height = this.active.height || this.height();

                    var flash = /flash/i.test(this.active.type);
                    var pdf = /pdf/i.test(this.active.type);
                    // Create single object for IE / Flash / PDF

                    // set global media type
                    this.active.type = 'media';
                    this.active.width = p.width;
                    this.active.height = p.height;

                    if (flash || isIE) {
                        this.object = '<object id="jcemediabox-popup-object"';
                        // Add type and data attribute
                        if (flash && !isIE) {
                            this.object += ' type="' + mt.mediatype + '" data="' + p.src + '"';
                        } else {
                            this.object += ' classid="clsid:' + mt.classid + '"';
                            if (mt.codebase) {
                                this.object += ' codebase="' + mt.codebase + '"';
                            }
                        }

                        for (n in p) {
                            if (p[n] !== '') {
                                if (/^(id|name|style|width|height)$/.test(n)) {
                                    t.object += ' ' + n + '="' + decodeURIComponent(DOM.decode(p[n])) + '"';
                                    delete p[n];
                                }
                            }
                        }

                        delete p.type;

                        // Close object
                        this.object += '>';
                        // Create param elements
                        for (n in p) {
                            t.object += '<param name="' + n + '" value="' + decodeURIComponent(DOM.decode(p[n])) + '" />';
                        }
                        // Add closing object element
                        this.object += '</object>';
                        // Use embed for non-IE browsers
                    } else {
                        this.object = '<embed id="jcemediabox-popup-object" type="' + mt.mediatype + '"';
                        for (n in p) {
                            if (v !== '') {
                                t.object += ' ' + n + '="' + v + '"';
                            }
                        }
                        this.object += '></embed>';
                    }

                    this.setup();
                    break;
                case 'video/x-flv':
                case 'video/mp4':
                case 'video/mpeg':
                case 'video/ogg':
                case 'audio/ogg':
                case 'audio/mp3':
                case 'video/webm':
                case 'audio/webm':
                    var type = this.active.type, tag = /video/.test(type) ? 'video' : 'audio';

                    var supportMap = {
                        'video': {
                            'h264' : ['video/mp4', 'video/mpeg'],
                            'webm' : ['video/webm'],
                            'ogg'  : ['video/ogg']
                        },
                        'audio': {
                            'mp3'   : ['audio/mp3'],
                            'ogg'   : ['audio/ogg'],
                            'webm'  : ['audio/webm']
                        }
                    };

                    var hasSupport = false;

                    // video/x-flv not supported by any browser
                    if (type !== "video/x-flv") {
                        for (var n in supportMap[tag]) {
                            if (supportMap[tag][n].indexOf(type) !== -1) {
                                hasSupport = support[tag] && !!support[tag][n];
                            }
                        }
                    }

                    this.object = '';

                    var src = resolveMediaPath(this.active.src);

                    if (p.poster) {
                        p.poster = resolveMediaPath(p.poster);
                    }

                    // create <audio> / <video> tag if suported
                    if (hasSupport) {
                        p.width = p.width || this.active.width;
                        p.height = p.height || this.active.height;

                        this.object += '<' + tag + ' type="' + type + '" src="' + this.active.src + '"' ;

                        for (n in p) {
                            if (p[n] !== '') {
                                if (/(loop|autoplay|controls|preload)$/.test(n)) {
                                    t.object += ' ' + n + '="' + n + '"';
                                }

                                if (/(id|style|poster|audio)$/.test(n)) {
                                    t.object += ' ' + n + '="' + decodeURIComponent(DOM.decode(p[n])) + '"';
                                }
                            }
                        }

                        this.object += '></' + tag + '>';

                    } else if (/(video|audio)\/(mp4|mpeg|x-flv|mp3)/.test(type)) {
                        var swf = JCEMediaBox.options.base + 'plugins/system/jcemediabox/mediaplayer/mediaplayer.swf';

                        this.object += '<object type="application/x-shockwave-flash" class="wf-mediaplayer-object" data="' + swf +'"';
                        // create empty style
                        p.style = p.style || "";

                        var flashvars = ['file=' + toAbsolute(src)];

                        // if supported
                        if (p.poster) {
                            //flashvars.push('poster=' + toAbsolute(p.poster));
                            p.style += " background-image:url('" + p.poster + "')";
                        }

                        each(p, function(v, n) {
                            if (v !== "") {
                                n = n.toLowerCase();

                                if (n === "loop" || n === "autoplay" || n === "controls") {
                                    flashvars.push(n + '=' + !!v);
                                }

                                if (n === "preload") {
                                    flashvars.push(n + '=' + v);
                                }

                                if (n === "id" || n === "style") {
                                    v = decodeURIComponent(DOM.decode(v));

                                    v = JCEMediaBox.trim(v);

                                    if (v !== "") {
                                        t.object += ' ' + n + '="' + v + '"';
                                    }
                                }

                                if (n === "width" | n === "height") {
                                    t.object += ' ' + n + '="' + v + '"';
                                }
                            }
                        });

                        this.object += '>';

                        this.object += '<param name="movie" value="' + swf +'" />';
                        this.object += '<param name="flashvars" value="' + flashvars.join('&') + '" />';
                        this.object += '<param name="allowfullscreen" value="true" />';
                        this.object += '<param name="wmode" value="transparent" />';
                        this.object += '<i>Flash is required to play this video. <a href="http://get.adobe.com/flashplayer/" target="_blank">Get Adobe® Flash Player</a></i>';
                        this.object += '</object>';
                    } else {
                        DOM.addClass(this.content, 'broken-media');
                    }

                    // set global media type
                    this.active.type = 'media';

                    this.setup();
                    break;
                case 'ajax':
                case 'text/html':
                case 'text/xml':
                    if (this.print && this.options.print) {
                        this.print.style.visibility = 'visible';
                    }

                    this.active.width = this.active.width || this.width();
                    this.active.height = this.active.height || this.height();

                    if (this.islocal(this.active.src)) {
                        if (!/tmpl=component/i.test(this.active.src)) {
                            this.active.src += /\?/.test(this.active.src) ? '&tmpl=component' : '?tmpl=component';
                        }
                        this.active.type = 'ajax';
                    } else {
                        this.active.type = 'iframe';
                        this.setup();
                    }

                    styles = extend(this.styles(p.styles), {
                        display: 'none'
                    });

                    this.active.src = this.active.src.replace(/\&type=(ajax|text\/html|text\/xml)/, '');

                    // show loader
                    if (this.loader) {
                        DOM.show(this.loader);
                    }

                    // create an iframe to load internal content in rather than using ajax so that javascript in the article is processed
                    var iframe = DOM.add(document.body, 'iframe', {
                        src: this.active.src,
                        style: 'display:none;'
                    });

                    // transfer data and delete iframe when loaded
                    Event.add(iframe, 'load', function () {

                        // Create ajax container
                        t.ajax = DOM.add(t.content, 'div', {
                            id: 'jcemediabox-popup-ajax',
                            'style': styles
                        });

                        // transfer data
                        t.ajax.innerHTML = iframe.contentWindow.document.body.innerHTML;

                        // Corrective stuff for IE6 and IE7
                        if (JCEMediaBox.isIE6) {
                            DOM.style(t.ajax, 'margin-right', JCEMediaBox.Dimensions.getScrollbarWidth());
                        }

                        if (JCEMediaBox.isIE7) {
                            DOM.style(t.ajax, 'padding-right', JCEMediaBox.Dimensions.getScrollbarWidth());
                        }

                        window.setTimeout(function () {
                            // remove iframe
                            DOM.remove(iframe);
                        }, 10);

                        // process any popups in loaded content
                        t.create(t.getPopups('', t.content));

                        // process any tooltips in loaded content
                        JCEMediaBox.ToolTip.create(t.content);

                        // setup
                        return t.setup();
                    });

                    iframe.onerror = function () {
                        DOM.addClass(this.content, 'broken-page');
                        return t.setup();
                    };

                    break;
                case 'iframe':
                case 'pdf':
                case 'video/youtube':
                case 'video/vimeo':
                default:
                    // iOS Safari cannot open PDF files properly
                    if (JCEMediaBox.isMobile && this.active.type === "pdf") {
                        this.close();
                        return window.open(this.active.src);
                    }

                    if (this.print) {
                        this.print.style.visibility = 'hidden';
                    }

                    if (this.islocal(this.active.src)) {
                        // add tmpl=component to internal links, skip pdf
                        if (!/tmpl=component/i.test(this.active.src) && !/\.pdf\b/i.test(this.active.src)) {
                            this.active.src += /\?/.test(this.active.src) ? '&tmpl=component' : '?tmpl=component';
                        }
                    }

                    // make URL protocol relative
                    this.active.src = this.protocolRelative(this.active.src);

                    this.active.width = this.active.width || this.width();
                    this.active.height = this.active.height || this.height();

                    this.active.type = 'iframe';
                    this.setup();

                    break;
            }
            return false;
        },
        /**
         * Proportional resizing method
         * @param {Object} w
         * @param {Object} h
         * @param {Object} x
         * @param {Object} y
         */
        resize: function (w, h, x, y) {
            if (w > x) {
                h = h * (x / w);
                w = x;
                if (h > y) {
                    w = w * (y / h);
                    h = y;
                }
            } else if (h > y) {
                w = w * (y / h);
                h = y;
                if (w > x) {
                    h = h * (x / w);
                    w = x;
                }
            }
            w = Math.round(w);
            h = Math.round(h);

            return {
                width: Math.round(w),
                height: Math.round(h)
            };
        },
        /**
         * Pre-animation setup. Resize images, set width / height
         */
        setup: function () {
            var t = this, DOM = JCEMediaBox.DOM, w, h, o = JCEMediaBox.options.popup;

            w = this.active.width;
            h = this.active.height;

            // Setup info
            this.info();

            // Get image dimensions and resize if necessary
            if (this.active.type == 'image') {
                if (t.img.error) {
                    w = 300;
                    h = 300;
                }

                var x = this.img.width;
                var y = this.img.height;

                if (w && !h) {
                    h = y * (w / x);
                } else if (!w && h) {
                    w = x * (h / y);
                }

                w = w || x;
                h = h || y;
            }

            // Resize to fit screen
            if (parseInt(o.resize) === 1 || (parseInt(o.resize) === 0 && o.scrolling == 'fixed')) {
                var x = this.width();
                var y = this.height();

                var dim = this.resize(w, h, x, y);

                w = dim.width;
                h = dim.height;
            }

            // set content dimensions
            DOM.styles(this.content, {
                width: w,
                height: h
            });

            DOM.hide(this.content);

            if (this.active.type == 'image') {
                if (this.img.error) {
                    DOM.addClass(this.content, 'broken-image');
                } else {
                    this.content.innerHTML = '<img id="jcemediabox-popup-img" src="' + this.active.src + '" title="' + this.active.title + '" />';
                }

                // fix resized images in IE
                if (JCEMediaBox.isIE) {
                    var img = DOM.get('jcemediabox-popup-img');
                    if (img) {
                        DOM.style(img, '-ms-interpolation-mode', 'bicubic');
                    }
                }
            }

            // Animate box
            return this.animate();
        },
        showInfo: function () {
            var t = this, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, FX = JCEMediaBox.FX, DIM = JCEMediaBox.Dimensions, Event = JCEMediaBox.Event;
            var ss = JCEMediaBox.options.popup.scalespeed, fs = JCEMediaBox.options.popup.fadespeed;

            // Set Information
            var itop = t['info-top'];
            if (itop) {
                each(DOM.select('*[id]', itop), function (el) {
                    if (/jcemediabox-popup-(next|prev)/.test(DOM.attribute(el, 'id'))) {
                        return;
                    }
                    DOM.show(el);
                });

                var h = DIM.outerHeight(itop);
                DOM.styles(itop, {
                    'z-index': -1,
                    'top': h,
                    'visibility': 'visible'
                });

                FX.animate(itop, {
                    'top': 0
                }, ss);
            }

            if (t.closelink) {
                DOM.show(t.closelink);
            }

            var ibottom = t['info-bottom'];
            if (ibottom) {
                each(DOM.select('*[id]', ibottom), function (el) {
                    if (/jcemediabox-popup-(next|prev)/.test(DOM.attribute(el, 'id'))) {
                        return;
                    }
                    DOM.show(el);
                });

                var h = DIM.outerHeight(ibottom);

                DOM.styles(ibottom, {
                    'z-index': -1,
                    'top': -h,
                    'visibility': 'visible'
                });

                FX.animate(ibottom, {
                    'top': 0
                }, ss);
            }
        },
        /**
         * Animate the Popup
         */
        animate: function () {
            var t = this, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, FX = JCEMediaBox.FX, DIM = JCEMediaBox.Dimensions, Event = JCEMediaBox.Event;
            var ss = JCEMediaBox.options.popup.scalespeed, fs = JCEMediaBox.options.popup.fadespeed;

            var cw = DIM.outerWidth(this.content);
            var ch = DIM.outerHeight(this.content);

            var ih = 0;
            each(['top', 'bottom'], function (v, i) {
                var el = t['info-' + v];
                if (el) {
                    ih = ih + DIM.outerHeight(el);
                }
            });

            var st = DOM.style(this.page, 'position') == 'fixed' ? 0 : DIM.getScrollTop();
            var top = st + (this.frameHeight() / 2) - ((ch + ih) / 2);

            if (top < 0) {
                top = 0;
            }

            DOM.style(this.content, 'opacity', 0);

            // Animate width
            FX.animate(this.body, {
                'height': ch,
                'top': top,
                'width': cw
            }, ss, function () {
                // Iframe
                if (t.active.type == 'iframe') {
                    // Create IFrame
                    var iframe = DOM.add(t.content, 'iframe', {
                        id: 'jcemediabox-popup-iframe',
                        frameborder: 0,
                        allowTransparency: true,
                        allowfullscreen: true,
                        scrolling: t.active.params.scrolling || 'auto',
                        width: '100%',
                        height: '100%'
                    });

                    // use pdf loader
                    if (/\.pdf\b/.test(t.active.src)) {
                        // Hide loader
                        if (t.loader) {
                            DOM.hide(t.loader);
                        }
                    } else {
                        var win = iframe.contentWindow, doc = win.document, _timer;

                        // fallback iframe load for iOS WebKit
                        if (JCEMediaBox.isiOS && JCEMediaBox.isWebKit) {
                            _timer = setInterval(function () {
                                if (doc.readyState === 'complete') {
                                    clearInterval(_timer);

                                    if (t.loader) {
                                        DOM.hide(t.loader);
                                    }
                                }
                            }, 1000);
                        }

                        iframe.onload = function () {
                            if (_timer) {
                                clearInterval(_timer);
                            }

                            // Hide loader
                            if (t.loader) {
                                DOM.hide(t.loader);
                            }
                        };
                    }

                    iframe.setAttribute('src', t.active.src);

                    t.iframe = iframe;

                } else {
                    // Hide loader
                    if (t.loader) {
                        DOM.hide(t.loader);
                    }

                    // If media
                    if (t.active.type == 'media' && t.object) {
                        t.content.innerHTML = t.object;

                        if (/\.pdf\b/.test(t.active.src) && JCEMediaBox.isiOS) {
                            DOM.styles(DOM.get('jcemediabox-popup-object'), {'height': '1000%', 'width': '150%'});
                        }
                    }

                    if (t.active.type == 'ajax') {
                        DOM.show(t.ajax);
                    }
                }

                DOM.show(t.content);
                t.content.focus();

                // Animate fade in for images only and not on IE6!
                if (t.active.type == 'image' && !JCEMediaBox.isIE6) {
                    FX.animate(t.content, {
                        'opacity': 1
                    }, fs, function () {
                        t.showInfo();
                    });

                } else {
                    DOM.style(t.content, 'opacity', 1);
                    t.showInfo();
                }
            });

        },
        /**
         * Close the popup window. Destroy all objects
         */
        close: function (keepopen) {
            var t = this, each = JCEMediaBox.each, DOM = JCEMediaBox.DOM, DIM = JCEMediaBox.Dimensions, FX = JCEMediaBox.FX;

            var ss = JCEMediaBox.options.popup.scalespeed;

            if (this.iframe) {
                DOM.attribute(this.iframe, 'src', '');
            }

            // Destroy objects
            each(['img', 'object', 'iframe', 'ajax'], function (i, v) {
                //t[v] = null;

                if (t[v]) {
                    DOM.remove(t[v]);
                }

                t[v] = null;
            });

            // Hide closelink
            if (this.closelink) {
                DOM.hide(this.closelink);
            }

            // Empty content div
            this.content.innerHTML = '';

            if (!keepopen) {
                // Hide info div
                each(['top', 'bottom'], function (v, i) {
                    var el = t['info-' + v];
                    if (el) {
                        DOM.hide(el);
                    }
                });

                // reset popups
                var popups = this.getPopups();
                while (this.popups.length > popups.length) {
                    this.popups.pop();
                }

                // remove frame
                DOM.remove(this.frame);
                // Fade out overlay
                if (this.overlay) {
                    if (JCEMediaBox.isIE6) {
                        // Remove event bindings
                        this.bind();
                        // Remove body, ie: popup
                        DOM.remove(this.page);
                        this.page = null;
                    } else {
                        JCEMediaBox.FX.animate(this.overlay, {
                            'opacity': 0
                        }, JCEMediaBox.options.popup.fadespeed, function () {
                            t.bind();
                            // destroy page
                            DOM.remove(t.page);
                            t.page = null;
                        });

                    }
                } else {
                    // destroy page
                    DOM.remove(this.page);
                    this.page = null;
                }
            }
            return false;
        }

    };
})(window);
// Cleanup events
JCEMediaBox.Event.addUnload(function () {
    JCEMediaBox.Event.destroy();
});

Youez - 2016 - github.com/yon3zu
LinuXploit