Repository: Beau-zihan/WebIM Branch: master Commit: 751d61cebf00 Files: 66 Total size: 428.7 KB Directory structure: gitextract_eevj4kjm/ ├── .gitattributes ├── .gitignore ├── README.md ├── ajax/ │ ├── card.html │ ├── chats.php │ ├── companyinfo.html │ ├── friends.html │ ├── friends.php │ ├── im_contact.html │ ├── im_face.html │ ├── im_window.html │ ├── login.html │ ├── msgbox.html │ ├── product.html │ ├── report.html │ ├── set.html │ ├── share.html │ └── userinfo.php ├── demo.html ├── docs/ │ ├── css/ │ │ └── docs.css │ ├── index.html │ └── prettify/ │ ├── lang-apollo.js │ ├── lang-clj.js │ ├── lang-css.js │ ├── lang-go.js │ ├── lang-hs.js │ ├── lang-lisp.js │ ├── lang-lua.js │ ├── lang-ml.js │ ├── lang-n.js │ ├── lang-proto.js │ ├── lang-scala.js │ ├── lang-sql.js │ ├── lang-tex.js │ ├── lang-vb.js │ ├── lang-vhdl.js │ ├── lang-wiki.js │ ├── lang-xq.js │ ├── lang-yaml.js │ ├── prettify.css │ └── prettify.js ├── img/ │ └── set.psd ├── index.html ├── js/ │ ├── im.css │ ├── im.plus.js │ └── jQuery.im.js ├── set/ │ ├── Jcrop/ │ │ ├── css/ │ │ │ └── jquery.Jcrop.css │ │ ├── demos/ │ │ │ ├── crop.php │ │ │ ├── demo_files/ │ │ │ │ └── demos.css │ │ │ ├── jquery-ui.html │ │ │ ├── non-image.html │ │ │ ├── styling.html │ │ │ ├── tutorial1.html │ │ │ ├── tutorial2.html │ │ │ ├── tutorial3.html │ │ │ ├── tutorial4.html │ │ │ └── tutorial5.html │ │ ├── index.html │ │ └── js/ │ │ ├── jquery.Jcrop.js │ │ └── jquery.color.js │ ├── avatar.html │ ├── css/ │ │ └── avatar.css │ ├── js/ │ │ └── jquery.Jcrop.js │ └── uploadify/ │ ├── jquery.uploadify-3.1.js │ └── uploadify.swf └── sound/ └── msg.swf ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp *.sln merge=union *.csproj merge=union *.vbproj merge=union *.fsproj merge=union *.dbproj merge=union # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ ################# ## Eclipse ################# *.pydevproject .project .metadata bin/ tmp/ *.tmp *.bak *.swp *~.nib local.properties .classpath .settings/ .loadpath # External tool builders .externalToolBuilders/ # Locally stored "Eclipse launch configurations" *.launch # CDT-specific .cproject # PDT-specific .buildpath ################# ## Visual Studio ################# ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.sln.docstates # Build results [Dd]ebug/ [Rr]elease/ x64/ build/ [Bb]in/ [Oo]bj/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* *_i.c *_p.c *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.log *.scc # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf *.cachefile # Visual Studio profiler *.psess *.vsp *.vspx # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch *.ncrunch* .*crunch*.local.xml # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.Publish.xml *.pubxml # NuGet Packages Directory ## TODO: If you have NuGet Package Restore enabled, uncomment the next line #packages/ # Windows Azure Build Output csx *.build.csdef # Windows Store app package directory AppPackages/ # Others sql/ *.Cache ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.[Pp]ublish.xml *.pfx *.publishsettings # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file to a newer # Visual Studio version. Backup files are not needed, because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files App_Data/*.mdf App_Data/*.ldf ############# ## Windows detritus ############# # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Mac crap .DS_Store ############# ## Python ############# *.py[co] # Packages *.egg *.egg-info dist/ build/ eggs/ parts/ var/ sdist/ develop-eggs/ .installed.cfg # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox #Translations *.mo #Mr Developer .mr.developer.cfg ================================================ FILE: README.md ================================================ # WebIM说明 WebIM是一款基于jQuery的一款web即时通讯插件,姑且这么称呼吧。插件最大程度实现了IM的常用功能,除即时通讯的常用功能外,还加入了:消息盒子、窗口抖动、添加删除好友、最近联系人、超时登录界面、网站小秘书、聊天记录、发送频率限制、发送产品、发送名片、发送表情、产品分享、黑名单、举报、收藏、公告、智能网址过滤、消息提醒、修改资料、名片二维码、禁止粘贴、收起联系人列表、推荐好友等30余项改进。全浏览器兼容。 插件调用简单方便,只需在现有的web系统中加入几行代码,理论上可嵌入任何web系统。 2012年项目,已不再维护。 ## 截图 ![webim](https://github.com/Beau-zihan/WebIM/blob/master/webim-preview.png) ## 配置
$(function() {
         $(document).FnWebIM({
             autoLogin          :true,       //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true
             msgRefreshTime     :1000,       //number型,消息刷新时间,单位为ms
             friendRefreshTime :10000,      //number型,好友刷新时间,单位为ms
             showSecretary     :true,       //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true
             noticeContent     :"唐僧师徒历经千辛万苦,终于见到了佛祖……",        //string型,公告内容 为空时不显示公告
             sendPicture       :true,       //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true
             msgMaxSize        :300,        //number型,单条消息最大允许字符
             msgSound          :false,      //boolean型,是否开启声音提醒,true:开启,false:关闭,默认为true
             defaultWindow     :""          //string型,登录后打开新聊天窗口,此处接收的参数为联系人的uid,否则会出错
         });
    });
## 详细说明文档 http://www.zi-han.net/case/im/help.html ## 示例 http://www.zi-han.net/developer/721.html ##注意 请在服务器(如localhost)环境下打开 ================================================ FILE: ajax/card.html ================================================
郑子涵 先生 技术部 | 前端开发
手机:18693179452
电话:09318976086
传真:09318976086
地址:甘肃兰州市城关区庆阳路世纪广场A座1708
邮编:730030
网址:http://www.zi-han.net/
================================================ FILE: ajax/chats.php ================================================ [ {"T": "1","D": "6-11 12:12:23","M": "你们带U盘了么?"}, {"T": "0","D": "6-11 12:12:23","M": ""}, {"T": "1","D": "6-11 12:12:23","M": "那你们就原路回去吧,我用QQ传给你们!"}, {"T": "0","D": "6-11 12:12:23","M": "早知道加你QQ就完了,老子还走这么远干嘛啊"}, {"T": "1","D": "6-11 12:12:23","M": "你们以为要加就加啊,我经常隐身滴!最后,如来还来句:你们有没psp啊?"}, {"T": "0","D": "6-11 12:12:23","M": "……"}, {"T": "1","D": "6-11 12:12:23","M": "那这么远的路,你们是怎么娱乐的?"}, {"T": "0","D": "6-11 12:12:23","M": "打怪升级……"}, {"T": "0","D": "6-11 12:12:23","M": "唐僧师徒按原路返回……"}, {"T": "1","D": "6-11 12:12:23","M": "经书传输中……"}, {"T": "1","D": "6-11 12:12:23","M": "怎么这么慢呢,你什么网啊?"}, {"T": "0","D": "6-11 12:12:23","M": "单位的网……"}, {"T": "1","D": "6-11 12:12:23","M": "……你再来一趟吧,带上U盘"}, {"T": "1","D": "6-11 12:12:23","M": "来张图片试试!"} ] ================================================ FILE: ajax/companyinfo.html ================================================
生财通指数:
120
工商注册:
个人身份:
联 系  人:
郑子涵
经营模式:
生产厂家
所在地区:
甘肃 兰州市
特殊荣誉:
注册时间:
2008年12月12日
最后登录:
最近一周内登录过

收藏公司共被收藏 4 次

================================================ FILE: ajax/friends.html ================================================

淄博林华商贸有限公司

小米

加为好友

东阳市东彩服饰辅料有限公司

小米

加为好友

苍南县君越工艺品有限公司

小米

加为好友
================================================ FILE: ajax/friends.php ================================================ [ {"RencentContacts": [ {"a": "../img/noavatar_s.png","n": "阳光般闪耀","o": "online","uid": "001","h":"", "m":0}, {"a": "../temp/1.jpg","n": "小米","o": "online","uid": "002","h": "", "m":0}, {"a": "../temp/2.jpg","n": "安卓-关龙飞","o": "online","uid": "003","h": "", "m":1}, {"a": "../temp/3.jpg","n": "诚信办证","o": "online","uid": "004","h": "", "m":0}, {"a": "../temp/4.jpg","n": "业务--小张","o": "offline","uid": "005","h": "", "m":3}, {"a": "../temp/5.jpg","n": "诚信办证","o": "offline","uid": "006","h": "", "m":0}, {"a": "../temp/6.jpg","n": "业务--小张","o": "offline","uid": "007","h": "", "m":0}, {"a": "../temp/7.jpg","n": "诚信办证","o": "offline","uid": "008","h": "", "m":0}, {"a": "../temp/8.jpg","n": "业务--小张","o": "offline","uid": "009","h": "", "m":0} ], "Friends": [ {"a": "../temp/9.jpg","n": "诚信办证","o": "online","uid": "010","h": "", "m":1}, {"a": "../img/noavatar_s.png","n": "业务--小张","o": "online","uid": "011","h": "", "m":0}, {"a": "../temp/10.jpg","n": "关龙飞","o": "offline","uid": "012","h": "", "m":0}, {"a": "../temp/11.jpg","n": "小米","o": "offline","uid": "013","h": "", "m":0} ], "RencentContactsOnline":5, "FriendsOnline":2 } ] ================================================ FILE: ajax/im_contact.html ================================================

在线聊天工具

 

最近联系人

我的好友

================================================ FILE: ajax/im_face.html ================================================
================================================ FILE: ajax/im_window.html ================================================
按Ctrl+回车键快速发送消息
用户公司信息
================================================ FILE: ajax/login.html ================================================
用户名:
密码:
验证码:
注册新账户 忘记密码?
================================================ FILE: ajax/msgbox.html ================================================

淄博林华商贸有限公司 - 小麦

对方发送了一张名片给您……

377-18

系统小秘书

您的账户存在异常,请及时修改密码!

377-18
================================================ FILE: ajax/product.html ================================================
产品

固定一体功能型超声波流量计 去看看 加入收藏 分享 + 更多同类产品

================================================ FILE: ajax/report.html ================================================

举报类型:

举报说明:

================================================ FILE: ajax/set.html ================================================ ================================================ FILE: ajax/share.html ================================================
新浪微博 腾讯微博 我的淘宝 QQ空间 人人网 美丽说 蘑菇街 开心网 搜狐微博 网易微博 点点网 百度贴吧 Twitter Facebook
================================================ FILE: ajax/userinfo.php ================================================ [ {"UserConfig": [0,0,0,0],"UserAvatar": "../img/avatar_b-sys.png","UserName": "zihan","isOnline": "online","UID": "795238409283faseafaeeDSIKHJ","cid": "0982304","cname": "淄博林华商贸有限公司" } ] ================================================ FILE: demo.html ================================================ 即时通讯示例 ================================================ FILE: docs/css/docs.css ================================================ * { margin: 0; padding: 0; } a { outline: none; } body { line-height: 1; } table { border-collapse: collapse; border-spacing: 0; } html, body { background: url(../img/faq_foot_bg.png) repeat scroll 0 0 #575C63; color: #F0F0F0; font: 14px/1.5 Helvetica, "Microsoft YaHei", Arial, Tahoma; height: 100%; width: 100%; text-align: center; text-shadow: 0 1px 1px #333; } pre, code { font: 14px/1.5 Helvetica, "Microsoft YaHei", Arial, Tahoma; margin: 10px 0; -moz-border-radius: 3px; -khtml-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .fnFaq .faq { width: 100%; background: url(../img/bg_faq_bottom.png) repeat 0 0 transparent; text-shadow: none; text-align: left; padding: 0 0 50px; } .fnFaq .container { width: 1000px; margin: 0 auto; } .fnFaq .faq .logo { position: fixed; top: 40px; display: block; width: 195px; height: 110px; background: url(../img/faq_ico.png) no-repeat transparent -3px 0; } .fnFaq .main { position: relative; width: 790px; margin-left: 212px; background: url(../img/bg_faq.png) repeat 0 0 #fff; box-shadow: 0 1px 1px #999; padding: 45px 0 50px; } .fnFaq .main .faqLine { position: absolute; top: 0; left: 30px; width: 1px; height: 100%; background: #f1f3f3; border-left: 1px solid #edefef; border-right: 1px solid #edefef; } .fnFaq .main .content { text-align: left; width: 770px; } .fnFaq .main .content dl { margin: 0 0 20px; } .fnFaq .main .content dt { background: url(../img/faq_line_point.png) no-repeat 20px 0 transparent; color: #1b1d20; font-size: 16px; font-weight: 700; padding-left: 50px; margin: 0 0 14px; } .fnFaq .main .content dd { color: #565b62; font-size: 14px; line-height: 1.6em; padding-left: 50px; } .fnFaq .main .descripte { color: #6ba5be; padding-left: 50px; } .fnFaq .footer { height: 90px; width: 1000px; line-height: 90px; font-size: 36px; text-align: left; margin: 0 auto; } .fnFaq .footer .img { width: 60px; height: 60px; margin-top: 14px; float: right; background: url(../img/faq_foot_img.png) no-repeat transparent; } table { max-width: 100%; border-collapse: collapse; border-spacing: 0; background-color: #fff; } .table { width: 100%; margin-bottom: 18px; border: 1px solid #dddddd; } .table th, .table td { padding: 8px; line-height: 18px; text-align: left; vertical-align: top; border: 1px solid #dddddd; } .table th { font-weight: bold; } .table thead th { vertical-align: bottom; } .table colgroup + thead tr:first-child th, .table colgroup + thead tr:first-child td, .table thead:first-child tr:first-child th, .table thead:first-child tr:first-child td { border-top: 0; } .table tbody + tbody { border-top: 2px solid #dddddd; } .table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th { background-color: #f9f9f9; } .table tbody tr:hover td, .table tbody tr:hover th { background-color: #f5f5f5; } .btn { display: inline-block; *display: inline; /* IE7 inline-block hack */ *zoom: 1; padding: 4px 10px 4px; margin-bottom: 0; text-decoration: none; font-size: 13px; line-height: 18px; color: #333333; text-align: center; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); vertical-align: middle; background-color: #f5f5f5; background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); background-image: linear-gradient(top, #ffffff, #e6e6e6); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#e6e6e6', GradientType = 0); border-color: #e6e6e6 #e6e6e6 #bfbfbf; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); border: 1px solid #cccccc; border-bottom-color: #b3b3b3; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); cursor: pointer; *margin-left: .3em; } .btn:hover, .btn:active, .btn.active, .btn.disabled, .btn[disabled] { background-color: #e6e6e6; } .btn:active, .btn.active { background-color: #cccccc \9; } .btn:first-child { *margin-left: 0; } .btn:hover { color: #333333; text-decoration: none; background-color: #e6e6e6; background-position: 0 -15px; -webkit-transition: background-position 0.1s linear; -moz-transition: background-position 0.1s linear; -ms-transition: background-position 0.1s linear; -o-transition: background-position 0.1s linear; transition: background-position 0.1s linear; } .btn:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .btn.active, .btn:active { background-image: none; -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); background-color: #e6e6e6; background-color: #d9d9d9 \9; outline: 0; } .btn.disabled, .btn[disabled] { cursor: default; background-image: none; background-color: #e6e6e6; opacity: 0.65; filter: alpha(opacity = 65); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .btn-large { padding: 9px 14px; font-size: 15px; line-height: normal; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .btn-large [class^="icon-"] { margin-top: 1px; } .btn-small { padding: 5px 9px; font-size: 11px; line-height: 16px; } .btn-small [class^="icon-"] { margin-top: -1px; } .btn-mini { padding: 2px 6px; font-size: 11px; line-height: 14px; } .btn-primary, .btn-primary:hover, .btn-warning, .btn-warning:hover, .btn-danger, .btn-danger:hover, .btn-success, .btn-success:hover, .btn-info, .btn-info:hover, .btn-inverse, .btn-inverse:hover { text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); color: #ffffff; } .btn-primary.active, .btn-warning.active, .btn-danger.active, .btn-success.active, .btn-info.active, .btn-inverse.active { color: rgba(255, 255, 255, 0.75); } .btn-primary { background-color: #0074cc; background-image: -moz-linear-gradient(top, #0088cc, #0055cc); background-image: -ms-linear-gradient(top, #0088cc, #0055cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0055cc); background-image: -o-linear-gradient(top, #0088cc, #0055cc); background-image: linear-gradient(top, #0088cc, #0055cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#0088cc', endColorstr = '#0055cc', GradientType = 0); border-color: #0055cc #0055cc #003580; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); } .btn-primary:hover, .btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] { background-color: #0055cc; } .btn-primary:active, .btn-primary.active { background-color: #004099 \9; } .btn-warning { background-color: #faa732; background-image: -moz-linear-gradient(top, #fbb450, #f89406); background-image: -ms-linear-gradient(top, #fbb450, #f89406); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); background-image: -webkit-linear-gradient(top, #fbb450, #f89406); background-image: -o-linear-gradient(top, #fbb450, #f89406); background-image: linear-gradient(top, #fbb450, #f89406); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#fbb450', endColorstr = '#f89406', GradientType = 0); border-color: #f89406 #f89406 #ad6704; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); } .btn-warning:hover, .btn-warning:active, .btn-warning.active, .btn-warning.disabled, .btn-warning[disabled] { background-color: #f89406; } .btn-warning:active, .btn-warning.active { background-color: #c67605 \9; } .btn-danger { background-color: #da4f49; background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); background-image: -ms-linear-gradient(top, #ee5f5b, #bd362f); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); background-image: linear-gradient(top, #ee5f5b, #bd362f); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ee5f5b', endColorstr = '#bd362f', GradientType = 0); border-color: #bd362f #bd362f #802420; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); } .btn-danger:hover, .btn-danger:active, .btn-danger.active, .btn-danger.disabled, .btn-danger[disabled] { background-color: #bd362f; } .btn-danger:active, .btn-danger.active { background-color: #942a25 \9; } .btn-success { background-color: #5bb75b; background-image: -moz-linear-gradient(top, #62c462, #51a351); background-image: -ms-linear-gradient(top, #62c462, #51a351); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); background-image: -webkit-linear-gradient(top, #62c462, #51a351); background-image: -o-linear-gradient(top, #62c462, #51a351); background-image: linear-gradient(top, #62c462, #51a351); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#62c462', endColorstr = '#51a351', GradientType = 0); border-color: #51a351 #51a351 #387038; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); } .btn-success:hover, .btn-success:active, .btn-success.active, .btn-success.disabled, .btn-success[disabled] { background-color: #51a351; } .btn-success:active, .btn-success.active { background-color: #408140 \9; } .btn-info { background-color: #49afcd; background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); background-image: -ms-linear-gradient(top, #5bc0de, #2f96b4); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); background-image: linear-gradient(top, #5bc0de, #2f96b4); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#5bc0de', endColorstr = '#2f96b4', GradientType = 0); border-color: #2f96b4 #2f96b4 #1f6377; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); } .btn-info:hover, .btn-info:active, .btn-info.active, .btn-info.disabled, .btn-info[disabled] { background-color: #2f96b4; } .btn-info:active, .btn-info.active { background-color: #24748c \9; } .btn-inverse { background-color: #414141; background-image: -moz-linear-gradient(top, #555555, #222222); background-image: -ms-linear-gradient(top, #555555, #222222); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222)); background-image: -webkit-linear-gradient(top, #555555, #222222); background-image: -o-linear-gradient(top, #555555, #222222); background-image: linear-gradient(top, #555555, #222222); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#555555', endColorstr = '#222222', GradientType = 0); border-color: #222222 #222222 #000000; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:dximagetransform.microsoft.gradient(enabled = false); } .btn-inverse:hover, .btn-inverse:active, .btn-inverse.active, .btn-inverse.disabled, .btn-inverse[disabled] { background-color: #222222; } .btn-inverse:active, .btn-inverse.active { background-color: #080808 \9; } button.btn, input[type="submit"].btn { *padding-top: 2px; *padding-bottom: 2px; } button.btn::-moz-focus-inner, input[type="submit"].btn::-moz-focus-inner { padding: 0; border: 0; } button.btn.btn-large, input[type="submit"].btn.btn-large { *padding-top: 7px; *padding-bottom: 7px; } button.btn.btn-small, input[type="submit"].btn.btn-small { *padding-top: 3px; *padding-bottom: 3px; } button.btn.btn-mini, input[type="submit"].btn.btn-mini { *padding-top: 1px; *padding-bottom: 1px; } .alert { padding: 8px 35px 8px 14px; margin-bottom: 18px; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); background-color: #fcf8e3; border: 1px solid #fbeed5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; color: #c09853; } .alert-heading { color: inherit; } .alert .close { position: relative; top: -2px; right: -21px; line-height: 18px; } .alert-success { background-color: #dff0d8; border-color: #d6e9c6; color: #468847; } .alert-danger, .alert-error { background-color: #f2dede; border-color: #eed3d7; color: #b94a48; } .alert-info { background-color: #d9edf7; border-color: #bce8f1; color: #3a87ad; } .alert-block { padding-top: 14px; padding-bottom: 14px; } .alert-block > p, .alert-block > ul { margin-bottom: 0; } .alert-block p + p { margin-top: 5px; } ================================================ FILE: docs/index.html ================================================ 凡纳网 -- 技术说明文档
1.这是个什么插件?
此插件是凡纳网开发的基于jQuery的一款web即时通讯插件。
2.如何调用
STEP1:在需要调用的页面最后引入以下js
<script type="text/javascript" src="js/jQuery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/fanna_im.plus.js?skin=fanna_im"></script>
<script type="text/javascript" src="js/jQuery.fnIM.js"></script>
注意:<script type="text/javascript" src="js/fanna_im.plus.js?skin=fanna_im"></script>中所带的skin参数为插件所用到的css文件,如无特殊需要,请勿更改,否则会出错!!!。
STEP2:调用插件
$(function() {
         $(document).FnWebIM();   //简单调用
});
3.参数设置
$(function() {
         $(document).FnWebIM({
             autoLogin          :true,
             msgRefreshTime    :1000,
             friendRefreshTime :10000,
             showSecretary     :true,
             noticeContent     :"公告内容",
             sendPicture       :true,
             msgMaxSize        :300,
             msgSound           :false,
             defaultWindow     :""
         });
});
4.【Demo】点击联系人后打开新聊天窗口
html:
<a class="oWindow" href="#" uid="8759328409230">联系我</a>
jQuery:
$(function() {
        $("a.oWindow").click(function(){
            var uid=$(this).attr("uid");
             $(document).FnWebIM({
                 defaultWindow     :uid    //注意uid的正确性,当获取不到用户信息时,会出错!!
             });
        });
});
5.相关参数说明
参数 类型 说明 默认值
autoLogin boolean型 是否自动登录,true:自动登录,false:手动登录 true
msgRefreshTime number型 消息刷新时间,单位为ms 1000
friendRefreshTime number型 好友列表刷新时间,单位为ms 10000
showSecretary boolean型 默认是否显示小秘书,true:显示,false:不显示 true
noticeContent string型 公告内容,为空时不显示公告  
sendPicture boolean型 是否允许发送图片,true:允许,false:不允许 true
msgMaxSize number型 单条消息最大允许字符数 300
msgSound boolean型 boolean型,是否开启声音提醒,true:开启,false:关闭 true
defaultWindow string型 登录后打开新聊天窗口,此处接收的参数为联系人的uid,
否则会出错。为空时不打开新窗口
 
5.相关页面说明
页面 参数说明
userinfo.jsp · 从session中获取请求的用户标识(UID);
· update:更新用户设置
chats.jsp · 从session中获取请求的用户标识(UID);
· del:清空聊天记录;
· add:查看更多记录;
· time:聊天记录刷新时间
friends.jsp · 从session中获取请求的用户标识(UID);
· time:联系人列表刷新时间
company.html · uid:所请求的用户uid;
friends.html · 从session中获取请求的用户标识(UID);
· type:好友类型:推荐好友|黑名单
msgbox.html · uid:所请求的用户uid;
product.html · pid:所请求的产品ID;
set.html 暂空
其他页面 说明
im_contact.html 联系人列表模板
im_window.html 聊天窗口模板
reprot.html 举报好友页面
share.html 产品分享页面
login.html 会话超时页面
6.实例演示
普通示例[自动登录] 点击联系人登录并弹出联系人窗口
7.示例图
查看大图
================================================ FILE: docs/prettify/lang-apollo.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\n\r]*/,null,"#"],["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/, null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[ES]?BANK=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[!-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["apollo","agc","aea"]); ================================================ FILE: docs/prettify/lang-clj.js ================================================ /* Copyright (C) 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ var a=null; PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a], ["typ",/^:[\dA-Za-z-]+/]]),["clj"]); ================================================ FILE: docs/prettify/lang-css.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); ================================================ FILE: docs/prettify/lang-go.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["pln",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])+(?:'|$)|`[^`]*(?:`|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\/\*[\S\s]*?\*\/)/],["pln",/^(?:[^"'/`]|\/(?![*/]))+/]]),["go"]); ================================================ FILE: docs/prettify/lang-hs.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n \r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/, null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]); ================================================ FILE: docs/prettify/lang-lisp.js ================================================ var a=null; PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a], ["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","scm"]); ================================================ FILE: docs/prettify/lang-lua.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\S\s]*?(?:]\1]|$)|[^\n\r]*)/],["str",/^\[(=*)\[[\S\s]*?(?:]\1]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i], ["pln",/^[_a-z]\w*/i],["pun",/^[^\w\t\n\r \xa0][^\w\t\n\r "'+=\xa0-]*/]]),["lua"]); ================================================ FILE: docs/prettify/lang-ml.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["com",/^#(?:if[\t\n\r \xa0]+(?:[$_a-z][\w']*|``[^\t\n\r`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])(?:'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\(\*[\S\s]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/], ["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^(?:[_a-z][\w']*[!#?]?|``[^\t\n\r`]*(?:``|$))/i],["pun",/^[^\w\t\n\r "'\xa0]+/]]),["fs","ml"]); ================================================ FILE: docs/prettify/lang-n.js ================================================ var a=null; PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\xa0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/, a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/, a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]); ================================================ FILE: docs/prettify/lang-proto.js ================================================ PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]); ================================================ FILE: docs/prettify/lang-scala.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["str",/^"(?:""(?:""?(?!")|[^"\\]|\\.)*"{0,3}|(?:[^\n\r"\\]|\\.)*"?)/,null,'"'],["lit",/^`(?:[^\n\r\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&(--:-@[-^{-~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\n\r'\\]|\\(?:'|[^\n\r']+))'/],["lit",/^'[$A-Z_a-z][\w$]*(?![\w$'])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/], ["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:0(?:[0-7]+|x[\da-f]+)l?|(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:e[+-]?\d+)?f?|l?)|\\.\d+(?:e[+-]?\d+)?f?)/i],["typ",/^[$_]*[A-Z][\d$A-Z_]*[a-z][\w$]*/],["pln",/^[$A-Z_a-z][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"]); ================================================ FILE: docs/prettify/lang-sql.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["str",/^(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\n\r]*|\/\*[\S\s]*?(?:\*\/|$))/],["kwd",/^(?:add|all|alter|and|any|as|asc|authorization|backup|begin|between|break|browse|bulk|by|cascade|case|check|checkpoint|close|clustered|coalesce|collate|column|commit|compute|constraint|contains|containstable|continue|convert|create|cross|current|current_date|current_time|current_timestamp|current_user|cursor|database|dbcc|deallocate|declare|default|delete|deny|desc|disk|distinct|distributed|double|drop|dummy|dump|else|end|errlvl|escape|except|exec|execute|exists|exit|fetch|file|fillfactor|for|foreign|freetext|freetexttable|from|full|function|goto|grant|group|having|holdlock|identity|identitycol|identity_insert|if|in|index|inner|insert|intersect|into|is|join|key|kill|left|like|lineno|load|match|merge|national|nocheck|nonclustered|not|null|nullif|of|off|offsets|on|open|opendatasource|openquery|openrowset|openxml|option|or|order|outer|over|percent|plan|precision|primary|print|proc|procedure|public|raiserror|read|readtext|reconfigure|references|replication|restore|restrict|return|revoke|right|rollback|rowcount|rowguidcol|rule|save|schema|select|session_user|set|setuser|shutdown|some|statistics|system_user|table|textsize|then|to|top|tran|transaction|trigger|truncate|tsequal|union|unique|update|updatetext|use|user|using|values|varying|view|waitfor|when|where|while|with|writetext)(?=[^\w-]|$)/i, null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^[_a-z][\w-]*/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'+\xa0-]*/]]),["sql"]); ================================================ FILE: docs/prettify/lang-tex.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"],["com",/^%[^\n\r]*/,null,"%"]],[["kwd",/^\\[@-Za-z]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[()=[\]{}]+/]]),["latex","tex"]); ================================================ FILE: docs/prettify/lang-vb.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0\u2028\u2029]+/,null,"\t\n\r \xa0

"],["str",/^(?:["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})(?:["\u201c\u201d]c|$)|["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})*(?:["\u201c\u201d]|$))/i,null,'"“”'],["com",/^['\u2018\u2019].*/,null,"'‘’"]],[["kwd",/^(?:addhandler|addressof|alias|and|andalso|ansi|as|assembly|auto|boolean|byref|byte|byval|call|case|catch|cbool|cbyte|cchar|cdate|cdbl|cdec|char|cint|class|clng|cobj|const|cshort|csng|cstr|ctype|date|decimal|declare|default|delegate|dim|directcast|do|double|each|else|elseif|end|endif|enum|erase|error|event|exit|finally|for|friend|function|get|gettype|gosub|goto|handles|if|implements|imports|in|inherits|integer|interface|is|let|lib|like|long|loop|me|mod|module|mustinherit|mustoverride|mybase|myclass|namespace|new|next|not|notinheritable|notoverridable|object|on|option|optional|or|orelse|overloads|overridable|overrides|paramarray|preserve|private|property|protected|public|raiseevent|readonly|redim|removehandler|resume|return|select|set|shadows|shared|short|single|static|step|stop|string|structure|sub|synclock|then|throw|to|try|typeof|unicode|until|variant|wend|when|while|with|withevents|writeonly|xor|endif|gosub|let|variant|wend)\b/i, null],["com",/^rem.*/i],["lit",/^(?:true\b|false\b|nothing\b|\d+(?:e[+-]?\d+[dfr]?|[dfilrs])?|(?:&h[\da-f]+|&o[0-7]+)[ils]?|\d*\.\d+(?:e[+-]?\d+)?[dfr]?|#\s+(?:\d+[/-]\d+[/-]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:am|pm))?)?|\d+:\d+(?::\d+)?(\s*(?:am|pm))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*])/i],["pun",/^[^\w\t\n\r "'[\]\xa0\u2018\u2019\u201c\u201d\u2028\u2029]+/],["pun",/^(?:\[|])/]]),["vb","vbs"]); ================================================ FILE: docs/prettify/lang-vhdl.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \xa0"]],[["str",/^(?:[box]?"(?:[^"]|"")*"|'.')/i],["com",/^--[^\n\r]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i, null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^'(?:active|ascending|base|delayed|driving|driving_value|event|high|image|instance_name|last_active|last_event|last_value|left|leftof|length|low|path_name|pos|pred|quiet|range|reverse_range|right|rightof|simple_name|stable|succ|transaction|val|value)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w.\\]+#(?:[+-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:e[+-]?\d+(?:_\d+)*)?)/i], ["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'\xa0-]*/]]),["vhdl","vhd"]); ================================================ FILE: docs/prettify/lang-wiki.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\d\t a-gi-z\xa0]+/,null,"\t \xa0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[*=[\]^~]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^[A-Z][a-z][\da-z]+[A-Z][a-z][^\W_]+\b/],["lang-",/^{{{([\S\s]+?)}}}/],["lang-",/^`([^\n\r`]+)`/],["str",/^https?:\/\/[^\s#/?]*(?:\/[^\s#?]*)?(?:\?[^\s#]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\S\s])[^\n\r#*=A-[^`h{~]*/]]),["wiki"]); PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"]); ================================================ FILE: docs/prettify/lang-xq.js ================================================ PR.registerLangHandler(PR.createSimpleLexer([["var pln",/^\$[\w-]+/,null,"$"]],[["pln",/^[\s=][<>][\s=]/],["lit",/^@[\w-]+/],["tag",/^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["com",/^\(:[\S\s]*?:\)/],["pln",/^[(),/;[\]{}]$/],["str",/^(?:"(?:[^"\\{]|\\[\S\s])*(?:"|$)|'(?:[^'\\{]|\\[\S\s])*(?:'|$))/,null,"\"'"],["kwd",/^(?:xquery|where|version|variable|union|typeswitch|treat|to|then|text|stable|sortby|some|self|schema|satisfies|returns|return|ref|processing-instruction|preceding-sibling|preceding|precedes|parent|only|of|node|namespace|module|let|item|intersect|instance|in|import|if|function|for|follows|following-sibling|following|external|except|every|else|element|descending|descendant-or-self|descendant|define|default|declare|comment|child|cast|case|before|attribute|assert|ascending|as|ancestor-or-self|ancestor|after|eq|order|by|or|and|schema-element|document-node|node|at)\b/], ["typ",/^(?:xs:yearMonthDuration|xs:unsignedLong|xs:time|xs:string|xs:short|xs:QName|xs:Name|xs:long|xs:integer|xs:int|xs:gYearMonth|xs:gYear|xs:gMonthDay|xs:gDay|xs:float|xs:duration|xs:double|xs:decimal|xs:dayTimeDuration|xs:dateTime|xs:date|xs:byte|xs:boolean|xs:anyURI|xf:yearMonthDuration)\b/,null],["fun pln",/^(?:xp:dereference|xinc:node-expand|xinc:link-references|xinc:link-expand|xhtml:restructure|xhtml:clean|xhtml:add-lists|xdmp:zip-manifest|xdmp:zip-get|xdmp:zip-create|xdmp:xquery-version|xdmp:word-convert|xdmp:with-namespaces|xdmp:version|xdmp:value|xdmp:user-roles|xdmp:user-last-login|xdmp:user|xdmp:url-encode|xdmp:url-decode|xdmp:uri-is-file|xdmp:uri-format|xdmp:uri-content-type|xdmp:unquote|xdmp:unpath|xdmp:triggers-database|xdmp:trace|xdmp:to-json|xdmp:tidy|xdmp:subbinary|xdmp:strftime|xdmp:spawn-in|xdmp:spawn|xdmp:sleep|xdmp:shutdown|xdmp:set-session-field|xdmp:set-response-encoding|xdmp:set-response-content-type|xdmp:set-response-code|xdmp:set-request-time-limit|xdmp:set|xdmp:servers|xdmp:server-status|xdmp:server-name|xdmp:server|xdmp:security-database|xdmp:security-assert|xdmp:schema-database|xdmp:save|xdmp:role-roles|xdmp:role|xdmp:rethrow|xdmp:restart|xdmp:request-timestamp|xdmp:request-status|xdmp:request-cancel|xdmp:request|xdmp:redirect-response|xdmp:random|xdmp:quote|xdmp:query-trace|xdmp:query-meters|xdmp:product-edition|xdmp:privilege-roles|xdmp:privilege|xdmp:pretty-print|xdmp:powerpoint-convert|xdmp:platform|xdmp:permission|xdmp:pdf-convert|xdmp:path|xdmp:octal-to-integer|xdmp:node-uri|xdmp:node-replace|xdmp:node-kind|xdmp:node-insert-child|xdmp:node-insert-before|xdmp:node-insert-after|xdmp:node-delete|xdmp:node-database|xdmp:mul64|xdmp:modules-root|xdmp:modules-database|xdmp:merging|xdmp:merge-cancel|xdmp:merge|xdmp:md5|xdmp:logout|xdmp:login|xdmp:log-level|xdmp:log|xdmp:lock-release|xdmp:lock-acquire|xdmp:load|xdmp:invoke-in|xdmp:invoke|xdmp:integer-to-octal|xdmp:integer-to-hex|xdmp:http-put|xdmp:http-post|xdmp:http-options|xdmp:http-head|xdmp:http-get|xdmp:http-delete|xdmp:hosts|xdmp:host-status|xdmp:host-name|xdmp:host|xdmp:hex-to-integer|xdmp:hash64|xdmp:hash32|xdmp:has-privilege|xdmp:groups|xdmp:group-serves|xdmp:group-servers|xdmp:group-name|xdmp:group-hosts|xdmp:group|xdmp:get-session-field-names|xdmp:get-session-field|xdmp:get-response-encoding|xdmp:get-response-code|xdmp:get-request-username|xdmp:get-request-user|xdmp:get-request-url|xdmp:get-request-protocol|xdmp:get-request-path|xdmp:get-request-method|xdmp:get-request-header-names|xdmp:get-request-header|xdmp:get-request-field-names|xdmp:get-request-field-filename|xdmp:get-request-field-content-type|xdmp:get-request-field|xdmp:get-request-client-certificate|xdmp:get-request-client-address|xdmp:get-request-body|xdmp:get-current-user|xdmp:get-current-roles|xdmp:get|xdmp:function-name|xdmp:function-module|xdmp:function|xdmp:from-json|xdmp:forests|xdmp:forest-status|xdmp:forest-restore|xdmp:forest-restart|xdmp:forest-name|xdmp:forest-delete|xdmp:forest-databases|xdmp:forest-counts|xdmp:forest-clear|xdmp:forest-backup|xdmp:forest|xdmp:filesystem-file|xdmp:filesystem-directory|xdmp:exists|xdmp:excel-convert|xdmp:eval-in|xdmp:eval|xdmp:estimate|xdmp:email|xdmp:element-content-type|xdmp:elapsed-time|xdmp:document-set-quality|xdmp:document-set-property|xdmp:document-set-properties|xdmp:document-set-permissions|xdmp:document-set-collections|xdmp:document-remove-properties|xdmp:document-remove-permissions|xdmp:document-remove-collections|xdmp:document-properties|xdmp:document-locks|xdmp:document-load|xdmp:document-insert|xdmp:document-get-quality|xdmp:document-get-properties|xdmp:document-get-permissions|xdmp:document-get-collections|xdmp:document-get|xdmp:document-forest|xdmp:document-delete|xdmp:document-add-properties|xdmp:document-add-permissions|xdmp:document-add-collections|xdmp:directory-properties|xdmp:directory-locks|xdmp:directory-delete|xdmp:directory-create|xdmp:directory|xdmp:diacritic-less|xdmp:describe|xdmp:default-permissions|xdmp:default-collections|xdmp:databases|xdmp:database-restore-validate|xdmp:database-restore-status|xdmp:database-restore-cancel|xdmp:database-restore|xdmp:database-name|xdmp:database-forests|xdmp:database-backup-validate|xdmp:database-backup-status|xdmp:database-backup-purge|xdmp:database-backup-cancel|xdmp:database-backup|xdmp:database|xdmp:collection-properties|xdmp:collection-locks|xdmp:collection-delete|xdmp:collation-canonical-uri|xdmp:castable-as|xdmp:can-grant-roles|xdmp:base64-encode|xdmp:base64-decode|xdmp:architecture|xdmp:apply|xdmp:amp-roles|xdmp:amp|xdmp:add64|xdmp:add-response-header|xdmp:access|trgr:trigger-set-recursive|trgr:trigger-set-permissions|trgr:trigger-set-name|trgr:trigger-set-module|trgr:trigger-set-event|trgr:trigger-set-description|trgr:trigger-remove-permissions|trgr:trigger-module|trgr:trigger-get-permissions|trgr:trigger-enable|trgr:trigger-disable|trgr:trigger-database-online-event|trgr:trigger-data-event|trgr:trigger-add-permissions|trgr:remove-trigger|trgr:property-content|trgr:pre-commit|trgr:post-commit|trgr:get-trigger-by-id|trgr:get-trigger|trgr:document-scope|trgr:document-content|trgr:directory-scope|trgr:create-trigger|trgr:collection-scope|trgr:any-property-content|thsr:set-entry|thsr:remove-term|thsr:remove-synonym|thsr:remove-entry|thsr:query-lookup|thsr:lookup|thsr:load|thsr:insert|thsr:expand|thsr:add-synonym|spell:suggest-detailed|spell:suggest|spell:remove-word|spell:make-dictionary|spell:load|spell:levenshtein-distance|spell:is-correct|spell:insert|spell:double-metaphone|spell:add-word|sec:users-collection|sec:user-set-roles|sec:user-set-password|sec:user-set-name|sec:user-set-description|sec:user-set-default-permissions|sec:user-set-default-collections|sec:user-remove-roles|sec:user-privileges|sec:user-get-roles|sec:user-get-description|sec:user-get-default-permissions|sec:user-get-default-collections|sec:user-doc-permissions|sec:user-doc-collections|sec:user-add-roles|sec:unprotect-collection|sec:uid-for-name|sec:set-realm|sec:security-version|sec:security-namespace|sec:security-installed|sec:security-collection|sec:roles-collection|sec:role-set-roles|sec:role-set-name|sec:role-set-description|sec:role-set-default-permissions|sec:role-set-default-collections|sec:role-remove-roles|sec:role-privileges|sec:role-get-roles|sec:role-get-description|sec:role-get-default-permissions|sec:role-get-default-collections|sec:role-doc-permissions|sec:role-doc-collections|sec:role-add-roles|sec:remove-user|sec:remove-role-from-users|sec:remove-role-from-role|sec:remove-role-from-privileges|sec:remove-role-from-amps|sec:remove-role|sec:remove-privilege|sec:remove-amp|sec:protect-collection|sec:privileges-collection|sec:privilege-set-roles|sec:privilege-set-name|sec:privilege-remove-roles|sec:privilege-get-roles|sec:privilege-add-roles|sec:priv-doc-permissions|sec:priv-doc-collections|sec:get-user-names|sec:get-unique-elem-id|sec:get-role-names|sec:get-role-ids|sec:get-privilege|sec:get-distinct-permissions|sec:get-collection|sec:get-amp|sec:create-user-with-role|sec:create-user|sec:create-role|sec:create-privilege|sec:create-amp|sec:collections-collection|sec:collection-set-permissions|sec:collection-remove-permissions|sec:collection-get-permissions|sec:collection-add-permissions|sec:check-admin|sec:amps-collection|sec:amp-set-roles|sec:amp-remove-roles|sec:amp-get-roles|sec:amp-doc-permissions|sec:amp-doc-collections|sec:amp-add-roles|search:unparse|search:suggest|search:snippet|search:search|search:resolve-nodes|search:resolve|search:remove-constraint|search:parse|search:get-default-options|search:estimate|search:check-options|prof:value|prof:reset|prof:report|prof:invoke|prof:eval|prof:enable|prof:disable|prof:allowed|ppt:clean|pki:template-set-request|pki:template-set-name|pki:template-set-key-type|pki:template-set-key-options|pki:template-set-description|pki:template-in-use|pki:template-get-version|pki:template-get-request|pki:template-get-name|pki:template-get-key-type|pki:template-get-key-options|pki:template-get-id|pki:template-get-description|pki:need-certificate|pki:is-temporary|pki:insert-trusted-certificates|pki:insert-template|pki:insert-signed-certificates|pki:insert-certificate-revocation-list|pki:get-trusted-certificate-ids|pki:get-template-ids|pki:get-template-certificate-authority|pki:get-template-by-name|pki:get-template|pki:get-pending-certificate-requests-xml|pki:get-pending-certificate-requests-pem|pki:get-pending-certificate-request|pki:get-certificates-for-template-xml|pki:get-certificates-for-template|pki:get-certificates|pki:get-certificate-xml|pki:get-certificate-pem|pki:get-certificate|pki:generate-temporary-certificate-if-necessary|pki:generate-temporary-certificate|pki:generate-template-certificate-authority|pki:generate-certificate-request|pki:delete-template|pki:delete-certificate|pki:create-template|pdf:make-toc|pdf:insert-toc-headers|pdf:get-toc|pdf:clean|p:status-transition|p:state-transition|p:remove|p:pipelines|p:insert|p:get-by-id|p:get|p:execute|p:create|p:condition|p:collection|p:action|ooxml:runs-merge|ooxml:package-uris|ooxml:package-parts-insert|ooxml:package-parts|msword:clean|mcgm:polygon|mcgm:point|mcgm:geospatial-query-from-elements|mcgm:geospatial-query|mcgm:circle|math:tanh|math:tan|math:sqrt|math:sinh|math:sin|math:pow|math:modf|math:log10|math:log|math:ldexp|math:frexp|math:fmod|math:floor|math:fabs|math:exp|math:cosh|math:cos|math:ceil|math:atan2|math:atan|math:asin|math:acos|map:put|map:map|map:keys|map:get|map:delete|map:count|map:clear|lnk:to|lnk:remove|lnk:insert|lnk:get|lnk:from|lnk:create|kml:polygon|kml:point|kml:interior-polygon|kml:geospatial-query-from-elements|kml:geospatial-query|kml:circle|kml:box|gml:polygon|gml:point|gml:interior-polygon|gml:geospatial-query-from-elements|gml:geospatial-query|gml:circle|gml:box|georss:point|georss:geospatial-query|georss:circle|geo:polygon|geo:point|geo:interior-polygon|geo:geospatial-query-from-elements|geo:geospatial-query|geo:circle|geo:box|fn:zero-or-one|fn:years-from-duration|fn:year-from-dateTime|fn:year-from-date|fn:upper-case|fn:unordered|fn:true|fn:translate|fn:trace|fn:tokenize|fn:timezone-from-time|fn:timezone-from-dateTime|fn:timezone-from-date|fn:sum|fn:subtract-dateTimes-yielding-yearMonthDuration|fn:subtract-dateTimes-yielding-dayTimeDuration|fn:substring-before|fn:substring-after|fn:substring|fn:subsequence|fn:string-to-codepoints|fn:string-pad|fn:string-length|fn:string-join|fn:string|fn:static-base-uri|fn:starts-with|fn:seconds-from-time|fn:seconds-from-duration|fn:seconds-from-dateTime|fn:round-half-to-even|fn:round|fn:root|fn:reverse|fn:resolve-uri|fn:resolve-QName|fn:replace|fn:remove|fn:QName|fn:prefix-from-QName|fn:position|fn:one-or-more|fn:number|fn:not|fn:normalize-unicode|fn:normalize-space|fn:node-name|fn:node-kind|fn:nilled|fn:namespace-uri-from-QName|fn:namespace-uri-for-prefix|fn:namespace-uri|fn:name|fn:months-from-duration|fn:month-from-dateTime|fn:month-from-date|fn:minutes-from-time|fn:minutes-from-duration|fn:minutes-from-dateTime|fn:min|fn:max|fn:matches|fn:lower-case|fn:local-name-from-QName|fn:local-name|fn:last|fn:lang|fn:iri-to-uri|fn:insert-before|fn:index-of|fn:in-scope-prefixes|fn:implicit-timezone|fn:idref|fn:id|fn:hours-from-time|fn:hours-from-duration|fn:hours-from-dateTime|fn:floor|fn:false|fn:expanded-QName|fn:exists|fn:exactly-one|fn:escape-uri|fn:escape-html-uri|fn:error|fn:ends-with|fn:encode-for-uri|fn:empty|fn:document-uri|fn:doc-available|fn:doc|fn:distinct-values|fn:distinct-nodes|fn:default-collation|fn:deep-equal|fn:days-from-duration|fn:day-from-dateTime|fn:day-from-date|fn:data|fn:current-time|fn:current-dateTime|fn:current-date|fn:count|fn:contains|fn:concat|fn:compare|fn:collection|fn:codepoints-to-string|fn:codepoint-equal|fn:ceiling|fn:boolean|fn:base-uri|fn:avg|fn:adjust-time-to-timezone|fn:adjust-dateTime-to-timezone|fn:adjust-date-to-timezone|fn:abs|feed:unsubscribe|feed:subscription|feed:subscribe|feed:request|feed:item|feed:description|excel:clean|entity:enrich|dom:set-pipelines|dom:set-permissions|dom:set-name|dom:set-evaluation-context|dom:set-domain-scope|dom:set-description|dom:remove-pipeline|dom:remove-permissions|dom:remove|dom:get|dom:evaluation-context|dom:domains|dom:domain-scope|dom:create|dom:configuration-set-restart-user|dom:configuration-set-permissions|dom:configuration-set-evaluation-context|dom:configuration-set-default-domain|dom:configuration-get|dom:configuration-create|dom:collection|dom:add-pipeline|dom:add-permissions|dls:retention-rules|dls:retention-rule-remove|dls:retention-rule-insert|dls:retention-rule|dls:purge|dls:node-expand|dls:link-references|dls:link-expand|dls:documents-query|dls:document-versions-query|dls:document-version-uri|dls:document-version-query|dls:document-version-delete|dls:document-version-as-of|dls:document-version|dls:document-update|dls:document-unmanage|dls:document-set-quality|dls:document-set-property|dls:document-set-properties|dls:document-set-permissions|dls:document-set-collections|dls:document-retention-rules|dls:document-remove-properties|dls:document-remove-permissions|dls:document-remove-collections|dls:document-purge|dls:document-manage|dls:document-is-managed|dls:document-insert-and-manage|dls:document-include-query|dls:document-history|dls:document-get-permissions|dls:document-extract-part|dls:document-delete|dls:document-checkout-status|dls:document-checkout|dls:document-checkin|dls:document-add-properties|dls:document-add-permissions|dls:document-add-collections|dls:break-checkout|dls:author-query|dls:as-of-query|dbk:convert|dbg:wait|dbg:value|dbg:stopped|dbg:stop|dbg:step|dbg:status|dbg:stack|dbg:out|dbg:next|dbg:line|dbg:invoke|dbg:function|dbg:finish|dbg:expr|dbg:eval|dbg:disconnect|dbg:detach|dbg:continue|dbg:connect|dbg:clear|dbg:breakpoints|dbg:break|dbg:attached|dbg:attach|cvt:save-converted-documents|cvt:part-uri|cvt:destination-uri|cvt:basepath|cvt:basename|cts:words|cts:word-query-weight|cts:word-query-text|cts:word-query-options|cts:word-query|cts:word-match|cts:walk|cts:uris|cts:uri-match|cts:train|cts:tokenize|cts:thresholds|cts:stem|cts:similar-query-weight|cts:similar-query-nodes|cts:similar-query|cts:shortest-distance|cts:search|cts:score|cts:reverse-query-weight|cts:reverse-query-nodes|cts:reverse-query|cts:remainder|cts:registered-query-weight|cts:registered-query-options|cts:registered-query-ids|cts:registered-query|cts:register|cts:query|cts:quality|cts:properties-query-query|cts:properties-query|cts:polygon-vertices|cts:polygon|cts:point-longitude|cts:point-latitude|cts:point|cts:or-query-queries|cts:or-query|cts:not-query-weight|cts:not-query-query|cts:not-query|cts:near-query-weight|cts:near-query-queries|cts:near-query-options|cts:near-query-distance|cts:near-query|cts:highlight|cts:geospatial-co-occurrences|cts:frequency|cts:fitness|cts:field-words|cts:field-word-query-weight|cts:field-word-query-text|cts:field-word-query-options|cts:field-word-query-field-name|cts:field-word-query|cts:field-word-match|cts:entity-highlight|cts:element-words|cts:element-word-query-weight|cts:element-word-query-text|cts:element-word-query-options|cts:element-word-query-element-name|cts:element-word-query|cts:element-word-match|cts:element-values|cts:element-value-ranges|cts:element-value-query-weight|cts:element-value-query-text|cts:element-value-query-options|cts:element-value-query-element-name|cts:element-value-query|cts:element-value-match|cts:element-value-geospatial-co-occurrences|cts:element-value-co-occurrences|cts:element-range-query-weight|cts:element-range-query-value|cts:element-range-query-options|cts:element-range-query-operator|cts:element-range-query-element-name|cts:element-range-query|cts:element-query-query|cts:element-query-element-name|cts:element-query|cts:element-pair-geospatial-values|cts:element-pair-geospatial-value-match|cts:element-pair-geospatial-query-weight|cts:element-pair-geospatial-query-region|cts:element-pair-geospatial-query-options|cts:element-pair-geospatial-query-longitude-name|cts:element-pair-geospatial-query-latitude-name|cts:element-pair-geospatial-query-element-name|cts:element-pair-geospatial-query|cts:element-pair-geospatial-boxes|cts:element-geospatial-values|cts:element-geospatial-value-match|cts:element-geospatial-query-weight|cts:element-geospatial-query-region|cts:element-geospatial-query-options|cts:element-geospatial-query-element-name|cts:element-geospatial-query|cts:element-geospatial-boxes|cts:element-child-geospatial-values|cts:element-child-geospatial-value-match|cts:element-child-geospatial-query-weight|cts:element-child-geospatial-query-region|cts:element-child-geospatial-query-options|cts:element-child-geospatial-query-element-name|cts:element-child-geospatial-query-child-name|cts:element-child-geospatial-query|cts:element-child-geospatial-boxes|cts:element-attribute-words|cts:element-attribute-word-query-weight|cts:element-attribute-word-query-text|cts:element-attribute-word-query-options|cts:element-attribute-word-query-element-name|cts:element-attribute-word-query-attribute-name|cts:element-attribute-word-query|cts:element-attribute-word-match|cts:element-attribute-values|cts:element-attribute-value-ranges|cts:element-attribute-value-query-weight|cts:element-attribute-value-query-text|cts:element-attribute-value-query-options|cts:element-attribute-value-query-element-name|cts:element-attribute-value-query-attribute-name|cts:element-attribute-value-query|cts:element-attribute-value-match|cts:element-attribute-value-geospatial-co-occurrences|cts:element-attribute-value-co-occurrences|cts:element-attribute-range-query-weight|cts:element-attribute-range-query-value|cts:element-attribute-range-query-options|cts:element-attribute-range-query-operator|cts:element-attribute-range-query-element-name|cts:element-attribute-range-query-attribute-name|cts:element-attribute-range-query|cts:element-attribute-pair-geospatial-values|cts:element-attribute-pair-geospatial-value-match|cts:element-attribute-pair-geospatial-query-weight|cts:element-attribute-pair-geospatial-query-region|cts:element-attribute-pair-geospatial-query-options|cts:element-attribute-pair-geospatial-query-longitude-name|cts:element-attribute-pair-geospatial-query-latitude-name|cts:element-attribute-pair-geospatial-query-element-name|cts:element-attribute-pair-geospatial-query|cts:element-attribute-pair-geospatial-boxes|cts:document-query-uris|cts:document-query|cts:distance|cts:directory-query-uris|cts:directory-query-depth|cts:directory-query|cts:destination|cts:deregister|cts:contains|cts:confidence|cts:collections|cts:collection-query-uris|cts:collection-query|cts:collection-match|cts:classify|cts:circle-radius|cts:circle-center|cts:circle|cts:box-west|cts:box-south|cts:box-north|cts:box-east|cts:box|cts:bearing|cts:arc-intersection|cts:and-query-queries|cts:and-query-options|cts:and-query|cts:and-not-query-positive-query|cts:and-not-query-negative-query|cts:and-not-query|css:get|css:convert|cpf:success|cpf:failure|cpf:document-set-state|cpf:document-set-processing-status|cpf:document-set-last-updated|cpf:document-set-error|cpf:document-get-state|cpf:document-get-processing-status|cpf:document-get-last-updated|cpf:document-get-error|cpf:check-transition|alert:spawn-matching-actions|alert:rule-user-id-query|alert:rule-set-user-id|alert:rule-set-query|alert:rule-set-options|alert:rule-set-name|alert:rule-set-description|alert:rule-set-action|alert:rule-remove|alert:rule-name-query|alert:rule-insert|alert:rule-id-query|alert:rule-get-user-id|alert:rule-get-query|alert:rule-get-options|alert:rule-get-name|alert:rule-get-id|alert:rule-get-description|alert:rule-get-action|alert:rule-action-query|alert:remove-triggers|alert:make-rule|alert:make-log-action|alert:make-config|alert:make-action|alert:invoke-matching-actions|alert:get-my-rules|alert:get-all-rules|alert:get-actions|alert:find-matching-rules|alert:create-triggers|alert:config-set-uri|alert:config-set-trigger-ids|alert:config-set-options|alert:config-set-name|alert:config-set-description|alert:config-set-cpf-domain-names|alert:config-set-cpf-domain-ids|alert:config-insert|alert:config-get-uri|alert:config-get-trigger-ids|alert:config-get-options|alert:config-get-name|alert:config-get-id|alert:config-get-description|alert:config-get-cpf-domain-names|alert:config-get-cpf-domain-ids|alert:config-get|alert:config-delete|alert:action-set-options|alert:action-set-name|alert:action-set-module-root|alert:action-set-module-db|alert:action-set-module|alert:action-set-description|alert:action-remove|alert:action-insert|alert:action-get-options|alert:action-get-name|alert:action-get-module-root|alert:action-get-module-db|alert:action-get-module|alert:action-get-description|zero-or-one|years-from-duration|year-from-dateTime|year-from-date|upper-case|unordered|true|translate|trace|tokenize|timezone-from-time|timezone-from-dateTime|timezone-from-date|sum|subtract-dateTimes-yielding-yearMonthDuration|subtract-dateTimes-yielding-dayTimeDuration|substring-before|substring-after|substring|subsequence|string-to-codepoints|string-pad|string-length|string-join|string|static-base-uri|starts-with|seconds-from-time|seconds-from-duration|seconds-from-dateTime|round-half-to-even|round|root|reverse|resolve-uri|resolve-QName|replace|remove|QName|prefix-from-QName|position|one-or-more|number|not|normalize-unicode|normalize-space|node-name|node-kind|nilled|namespace-uri-from-QName|namespace-uri-for-prefix|namespace-uri|name|months-from-duration|month-from-dateTime|month-from-date|minutes-from-time|minutes-from-duration|minutes-from-dateTime|min|max|matches|lower-case|local-name-from-QName|local-name|last|lang|iri-to-uri|insert-before|index-of|in-scope-prefixes|implicit-timezone|idref|id|hours-from-time|hours-from-duration|hours-from-dateTime|floor|false|expanded-QName|exists|exactly-one|escape-uri|escape-html-uri|error|ends-with|encode-for-uri|empty|document-uri|doc-available|doc|distinct-values|distinct-nodes|default-collation|deep-equal|days-from-duration|day-from-dateTime|day-from-date|data|current-time|current-dateTime|current-date|count|contains|concat|compare|collection|codepoints-to-string|codepoint-equal|ceiling|boolean|base-uri|avg|adjust-time-to-timezone|adjust-dateTime-to-timezone|adjust-date-to-timezone|abs)\b/], ["pln",/^[\w:-]+/],["pln",/^[\t\n\r \xa0]+/]]),["xq","xquery"]); ================================================ FILE: docs/prettify/lang-yaml.js ================================================ var a=null; PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]); ================================================ FILE: docs/prettify/prettify.css ================================================ .com { color: #93a1a1; } .lit { color: #195f91; } .pun, .opn, .clo { color: #93a1a1; } .fun { color: #dc322f; } .str, .atv { color: #D14; } .kwd, .linenums .tag { color: #1e347b; } .typ, .atn, .dec, .var { color: teal; } .pln { color: #48484c; } .prettyprint { padding: 8px; background-color: #f7f7f9; border: 1px solid #e1e1e8; } .prettyprint.linenums { -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; } /* Specify class=linenums on a pre to get line numbering */ ol.linenums { margin: 0 0 0 33px; /* IE indents via margin-left */ } ol.linenums li { padding-left: 12px; color: #bebec5; line-height: 18px; text-shadow: 0 1px 0 #fff; } ================================================ FILE: docs/prettify/prettify.js ================================================ // Copyright (C) 2006 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview * some functions for browser-side pretty printing of code contained in html. * *

* For a fairly comprehensive set of languages see the * README * file that came with this source. At a minimum, the lexer should work on a * number of languages including C and friends, Java, Python, Bash, SQL, HTML, * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk * and a subset of Perl, but, because of commenting conventions, doesn't work on * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. *

* Usage:

    *
  1. include this source file in an html page via * {@code } *
  2. define style rules. See the example page for examples. *
  3. mark the {@code
    } and {@code } tags in your source with
     *    {@code class=prettyprint.}
     *    You can also use the (html deprecated) {@code } tag, but the pretty
     *    printer needs to do more substantial DOM manipulations to support that, so
     *    some css styles may not be preserved.
     * </ol>
     * That's it.  I wanted to keep the API as simple as possible, so there's no
     * need to specify which language the code is in, but if you wish, you can add
     * another class to the {@code <pre>} or {@code <code>} element to specify the
     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
     * starts with "lang-" followed by a file extension, specifies the file type.
     * See the "lang-*.js" files in this directory for code that implements
     * per-language file handlers.
     * <p>
     * Change log:<br>
     * cbeust, 2006/08/22
     * <blockquote>
     *   Java annotations (start with "@") are now captured as literals ("lit")
     * </blockquote>
     * @requires console
     */
    
    // JSLint declarations
    /*global console, document, navigator, setTimeout, window */
    
    /**
     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
     * UI events.
     * If set to {@code false}, {@code prettyPrint()} is synchronous.
     */
    window['PR_SHOULD_USE_CONTINUATION'] = true;
    
    (function () {
        // Keyword lists for various languages.
        // We use things that coerce to strings to make them compact when minified
        // and to defeat aggressive optimizers that fold large string constants.
        var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
        var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
            "double,enum,extern,float,goto,int,long,register,short,signed,sizeof," +
            "static,struct,switch,typedef,union,unsigned,void,volatile"];
        var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
            "new,operator,private,protected,public,this,throw,true,try,typeof"];
        var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
            "concept,concept_map,const_cast,constexpr,decltype," +
            "dynamic_cast,explicit,export,friend,inline,late_check," +
            "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
            "template,typeid,typename,using,virtual,where"];
        var JAVA_KEYWORDS = [COMMON_KEYWORDS,
            "abstract,boolean,byte,extends,final,finally,implements,import," +
                "instanceof,null,native,package,strictfp,super,synchronized,throws," +
                "transient"];
        var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
            "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
                "fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock," +
                "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed," +
                "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];
        var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
            "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
            "true,try,unless,until,when,while,yes";
        var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
            "debugger,eval,export,function,get,null,set,undefined,var,with," +
                "Infinity,NaN"];
        var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
            "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
            "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
        var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
            "elif,except,exec,finally,from,global,import,in,is,lambda," +
            "nonlocal,not,or,pass,print,raise,try,with,yield," +
            "False,True,None"];
        var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
            "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
            "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
            "BEGIN,END"];
        var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
            "function,in,local,set,then,until"];
        var ALL_KEYWORDS = [
            CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS +
                PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
        var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;
    
        // token style names.  correspond to css classes
        /**
         * token style for a string literal
         * @const
         */
        var PR_STRING = 'str';
        /**
         * token style for a keyword
         * @const
         */
        var PR_KEYWORD = 'kwd';
        /**
         * token style for a comment
         * @const
         */
        var PR_COMMENT = 'com';
        /**
         * token style for a type
         * @const
         */
        var PR_TYPE = 'typ';
        /**
         * token style for a literal value.  e.g. 1, null, true.
         * @const
         */
        var PR_LITERAL = 'lit';
        /**
         * token style for a punctuation string.
         * @const
         */
        var PR_PUNCTUATION = 'pun';
        /**
         * token style for a punctuation string.
         * @const
         */
        var PR_PLAIN = 'pln';
    
        /**
         * token style for an sgml tag.
         * @const
         */
        var PR_TAG = 'tag';
        /**
         * token style for a markup declaration such as a DOCTYPE.
         * @const
         */
        var PR_DECLARATION = 'dec';
        /**
         * token style for embedded source.
         * @const
         */
        var PR_SOURCE = 'src';
        /**
         * token style for an sgml attribute name.
         * @const
         */
        var PR_ATTRIB_NAME = 'atn';
        /**
         * token style for an sgml attribute value.
         * @const
         */
        var PR_ATTRIB_VALUE = 'atv';
    
        /**
         * A class that indicates a section of markup that is not code, e.g. to allow
         * embedding of line numbers within code listings.
         * @const
         */
        var PR_NOCODE = 'nocode';
    
    
    
        /**
         * A set of tokens that can precede a regular expression literal in
         * javascript
         * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
         * has the full list, but I've removed ones that might be problematic when
         * seen in languages that don't support regular expression literals.
         *
         * <p>Specifically, I've removed any keywords that can't precede a regexp
         * literal in a syntactically legal javascript program, and I've removed the
         * "in" keyword since it's not a keyword in many languages, and might be used
         * as a count of inches.
         *
         * <p>The link a above does not accurately describe EcmaScript rules since
         * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
         * very well in practice.
         *
         * @private
         * @const
         */
        var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    
    // CAVEAT: this does not properly handle the case where a regular
    // expression immediately follows another since a regular expression may
    // have flags for case-sensitivity and the like.  Having regexp tokens
    // adjacent is not valid in any language I'm aware of, so I'm punting.
    // TODO: maybe style special characters inside a regexp as punctuation.
    
    
        /**
         * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
         * matches the union of the sets of strings matched by the input RegExp.
         * Since it matches globally, if the input strings have a start-of-input
         * anchor (/^.../), it is ignored for the purposes of unioning.
         * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
         * @return {RegExp} a global regex.
         */
        function combinePrefixPatterns(regexs) {
            var capturedGroupIndex = 0;
    
            var needToFoldCase = false;
            var ignoreCase = false;
            for (var i = 0, n = regexs.length; i < n; ++i) {
                var regex = regexs[i];
                if (regex.ignoreCase) {
                    ignoreCase = true;
                } else if (/[a-z]/i.test(regex.source.replace(
                    /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
                    needToFoldCase = true;
                    ignoreCase = false;
                    break;
                }
            }
    
            var escapeCharToCodeUnit = {
                'b': 8,
                't': 9,
                'n': 0xa,
                'v': 0xb,
                'f': 0xc,
                'r': 0xd
            };
    
            function decodeEscape(charsetPart) {
                var cc0 = charsetPart.charCodeAt(0);
                if (cc0 !== 92 /* \\ */) {
                    return cc0;
                }
                var c1 = charsetPart.charAt(1);
                cc0 = escapeCharToCodeUnit[c1];
                if (cc0) {
                    return cc0;
                } else if ('0' <= c1 && c1 <= '7') {
                    return parseInt(charsetPart.substring(1), 8);
                } else if (c1 === 'u' || c1 === 'x') {
                    return parseInt(charsetPart.substring(2), 16);
                } else {
                    return charsetPart.charCodeAt(1);
                }
            }
    
            function encodeEscape(charCode) {
                if (charCode < 0x20) {
                    return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
                }
                var ch = String.fromCharCode(charCode);
                if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
                    ch = '\\' + ch;
                }
                return ch;
            }
    
            function caseFoldCharset(charSet) {
                var charsetParts = charSet.substring(1, charSet.length - 1).match(
                    new RegExp(
                        '\\\\u[0-9A-Fa-f]{4}'
                            + '|\\\\x[0-9A-Fa-f]{2}'
                            + '|\\\\[0-3][0-7]{0,2}'
                            + '|\\\\[0-7]{1,2}'
                            + '|\\\\[\\s\\S]'
                            + '|-'
                            + '|[^-\\\\]',
                        'g'));
                var groups = [];
                var ranges = [];
                var inverse = charsetParts[0] === '^';
                for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
                    var p = charsetParts[i];
                    if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
                        groups.push(p);
                    } else {
                        var start = decodeEscape(p);
                        var end;
                        if (i + 2 < n && '-' === charsetParts[i + 1]) {
                            end = decodeEscape(charsetParts[i + 2]);
                            i += 2;
                        } else {
                            end = start;
                        }
                        ranges.push([start, end]);
                        // If the range might intersect letters, then expand it.
                        // This case handling is too simplistic.
                        // It does not deal with non-latin case folding.
                        // It works for latin source code identifiers though.
                        if (!(end < 65 || start > 122)) {
                            if (!(end < 65 || start > 90)) {
                                ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
                            }
                            if (!(end < 97 || start > 122)) {
                                ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
                            }
                        }
                    }
                }
    
                // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
                // -> [[1, 12], [14, 14], [16, 17]]
                ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
                var consolidatedRanges = [];
                var lastRange = [NaN, NaN];
                for (var i = 0; i < ranges.length; ++i) {
                    var range = ranges[i];
                    if (range[0] <= lastRange[1] + 1) {
                        lastRange[1] = Math.max(lastRange[1], range[1]);
                    } else {
                        consolidatedRanges.push(lastRange = range);
                    }
                }
    
                var out = ['['];
                if (inverse) { out.push('^'); }
                out.push.apply(out, groups);
                for (var i = 0; i < consolidatedRanges.length; ++i) {
                    var range = consolidatedRanges[i];
                    out.push(encodeEscape(range[0]));
                    if (range[1] > range[0]) {
                        if (range[1] + 1 > range[0]) { out.push('-'); }
                        out.push(encodeEscape(range[1]));
                    }
                }
                out.push(']');
                return out.join('');
            }
    
            function allowAnywhereFoldCaseAndRenumberGroups(regex) {
                // Split into character sets, escape sequences, punctuation strings
                // like ('(', '(?:', ')', '^'), and runs of characters that do not
                // include any of the above.
                var parts = regex.source.match(
                    new RegExp(
                        '(?:'
                            + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
                            + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
                            + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
                            + '|\\\\[0-9]+'  // a back-reference or octal escape
                            + '|\\\\[^ux0-9]'  // other escape sequence
                            + '|\\(\\?[:!=]'  // start of a non-capturing group
                            + '|[\\(\\)\\^]'  // start/emd of a group, or line start
                            + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
                            + ')',
                        'g'));
                var n = parts.length;
    
                // Maps captured group numbers to the number they will occupy in
                // the output or to -1 if that has not been determined, or to
                // undefined if they need not be capturing in the output.
                var capturedGroups = [];
    
                // Walk over and identify back references to build the capturedGroups
                // mapping.
                for (var i = 0, groupIndex = 0; i < n; ++i) {
                    var p = parts[i];
                    if (p === '(') {
                        // groups are 1-indexed, so max group index is count of '('
                        ++groupIndex;
                    } else if ('\\' === p.charAt(0)) {
                        var decimalValue = +p.substring(1);
                        if (decimalValue && decimalValue <= groupIndex) {
                            capturedGroups[decimalValue] = -1;
                        }
                    }
                }
    
                // Renumber groups and reduce capturing groups to non-capturing groups
                // where possible.
                for (var i = 1; i < capturedGroups.length; ++i) {
                    if (-1 === capturedGroups[i]) {
                        capturedGroups[i] = ++capturedGroupIndex;
                    }
                }
                for (var i = 0, groupIndex = 0; i < n; ++i) {
                    var p = parts[i];
                    if (p === '(') {
                        ++groupIndex;
                        if (capturedGroups[groupIndex] === undefined) {
                            parts[i] = '(?:';
                        }
                    } else if ('\\' === p.charAt(0)) {
                        var decimalValue = +p.substring(1);
                        if (decimalValue && decimalValue <= groupIndex) {
                            parts[i] = '\\' + capturedGroups[groupIndex];
                        }
                    }
                }
    
                // Remove any prefix anchors so that the output will match anywhere.
                // ^^ really does mean an anchored match though.
                for (var i = 0, groupIndex = 0; i < n; ++i) {
                    if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
                }
    
                // Expand letters to groups to handle mixing of case-sensitive and
                // case-insensitive patterns if necessary.
                if (regex.ignoreCase && needToFoldCase) {
                    for (var i = 0; i < n; ++i) {
                        var p = parts[i];
                        var ch0 = p.charAt(0);
                        if (p.length >= 2 && ch0 === '[') {
                            parts[i] = caseFoldCharset(p);
                        } else if (ch0 !== '\\') {
                            // TODO: handle letters in numeric escapes.
                            parts[i] = p.replace(
                                /[a-zA-Z]/g,
                                function (ch) {
                                    var cc = ch.charCodeAt(0);
                                    return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
                                });
                        }
                    }
                }
    
                return parts.join('');
            }
    
            var rewritten = [];
            for (var i = 0, n = regexs.length; i < n; ++i) {
                var regex = regexs[i];
                if (regex.global || regex.multiline) { throw new Error('' + regex); }
                rewritten.push(
                    '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
            }
    
            return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
        }
    
    
        /**
         * Split markup into a string of source code and an array mapping ranges in
         * that string to the text nodes in which they appear.
         *
         * <p>
         * The HTML DOM structure:</p>
         * <pre>
         * (Element   "p"
         *   (Element "b"
         *     (Text  "print "))       ; #1
         *   (Text    "'Hello '")      ; #2
         *   (Element "br")            ; #3
         *   (Text    "  + 'World';")) ; #4
         * </pre>
         * <p>
         * corresponds to the HTML
         * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
         *
         * <p>
         * It will produce the output:</p>
         * <pre>
         * {
         *   sourceCode: "print 'Hello '\n  + 'World';",
         *   //                 1         2
         *   //       012345678901234 5678901234567
         *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
         * }
         * </pre>
         * <p>
         * where #1 is a reference to the {@code "print "} text node above, and so
         * on for the other text nodes.
         * </p>
         *
         * <p>
         * The {@code} spans array is an array of pairs.  Even elements are the start
         * indices of substrings, and odd elements are the text nodes (or BR elements)
         * that contain the text for those substrings.
         * Substrings continue until the next index or the end of the source.
         * </p>
         *
         * @param {Node} node an HTML DOM subtree containing source-code.
         * @return {Object} source code and the text nodes in which they occur.
         */
        function extractSourceSpans(node) {
            var nocode = /(?:^|\s)nocode(?:\s|$)/;
    
            var chunks = [];
            var length = 0;
            var spans = [];
            var k = 0;
    
            var whitespace;
            if (node.currentStyle) {
                whitespace = node.currentStyle.whiteSpace;
            } else if (window.getComputedStyle) {
                whitespace = document.defaultView.getComputedStyle(node, null)
                    .getPropertyValue('white-space');
            }
            var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
    
            function walk(node) {
                switch (node.nodeType) {
                    case 1:  // Element
                        if (nocode.test(node.className)) { return; }
                        for (var child = node.firstChild; child; child = child.nextSibling) {
                            walk(child);
                        }
                        var nodeName = node.nodeName;
                        if ('BR' === nodeName || 'LI' === nodeName) {
                            chunks[k] = '\n';
                            spans[k << 1] = length++;
                            spans[(k++ << 1) | 1] = node;
                        }
                        break;
                    case 3: case 4:  // Text
                    var text = node.nodeValue;
                    if (text.length) {
                        if (!isPreformatted) {
                            text = text.replace(/[ \t\r\n]+/g, ' ');
                        } else {
                            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
                        }
                        // TODO: handle tabs here?
                        chunks[k] = text;
                        spans[k << 1] = length;
                        length += text.length;
                        spans[(k++ << 1) | 1] = node;
                    }
                    break;
                }
            }
    
            walk(node);
    
            return {
                sourceCode: chunks.join('').replace(/\n$/, ''),
                spans: spans
            };
        }
    
    
        /**
         * Apply the given language handler to sourceCode and add the resulting
         * decorations to out.
         * @param {number} basePos the index of sourceCode within the chunk of source
         *    whose decorations are already present on out.
         */
        function appendDecorations(basePos, sourceCode, langHandler, out) {
            if (!sourceCode) { return; }
            var job = {
                sourceCode: sourceCode,
                basePos: basePos
            };
            langHandler(job);
            out.push.apply(out, job.decorations);
        }
    
        var notWs = /\S/;
    
        /**
         * Given an element, if it contains only one child element and any text nodes
         * it contains contain only space characters, return the sole child element.
         * Otherwise returns undefined.
         * <p>
         * This is meant to return the CODE element in {@code <pre><code ...>} when
         * there is a single child element that contains all the non-space textual
         * content, but not to return anything where there are multiple child elements
         * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
         * is textual content.
         */
        function childContentWrapper(element) {
            var wrapper = undefined;
            for (var c = element.firstChild; c; c = c.nextSibling) {
                var type = c.nodeType;
                wrapper = (type === 1)  // Element Node
                    ? (wrapper ? element : c)
                    : (type === 3)  // Text Node
                    ? (notWs.test(c.nodeValue) ? element : wrapper)
                    : wrapper;
            }
            return wrapper === element ? undefined : wrapper;
        }
    
        /** Given triples of [style, pattern, context] returns a lexing function,
         * The lexing function interprets the patterns to find token boundaries and
         * returns a decoration list of the form
         * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
         * where index_n is an index into the sourceCode, and style_n is a style
         * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
         * all characters in sourceCode[index_n-1:index_n].
         *
         * The stylePatterns is a list whose elements have the form
         * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
         *
         * Style is a style constant like PR_PLAIN, or can be a string of the
         * form 'lang-FOO', where FOO is a language extension describing the
         * language of the portion of the token in $1 after pattern executes.
         * E.g., if style is 'lang-lisp', and group 1 contains the text
         * '(hello (world))', then that portion of the token will be passed to the
         * registered lisp handler for formatting.
         * The text before and after group 1 will be restyled using this decorator
         * so decorators should take care that this doesn't result in infinite
         * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
         * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
         * '<script>foo()<\/script>', which would cause the current decorator to
         * be called with '<script>' which would not match the same rule since
         * group 1 must not be empty, so it would be instead styled as PR_TAG by
         * the generic tag rule.  The handler registered for the 'js' extension would
         * then be called with 'foo()', and finally, the current decorator would
         * be called with '<\/script>' which would not match the original rule and
         * so the generic tag rule would identify it as a tag.
         *
         * Pattern must only match prefixes, and if it matches a prefix, then that
         * match is considered a token with the same style.
         *
         * Context is applied to the last non-whitespace, non-comment token
         * recognized.
         *
         * Shortcut is an optional string of characters, any of which, if the first
         * character, gurantee that this pattern and only this pattern matches.
         *
         * @param {Array} shortcutStylePatterns patterns that always start with
         *   a known character.  Must have a shortcut string.
         * @param {Array} fallthroughStylePatterns patterns that will be tried in
         *   order if the shortcut ones fail.  May have shortcuts.
         *
         * @return {function (Object)} a
         *   function that takes source code and returns a list of decorations.
         */
        function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
            var shortcuts = {};
            var tokenizer;
            (function () {
                var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
                var allRegexs = [];
                var regexKeys = {};
                for (var i = 0, n = allPatterns.length; i < n; ++i) {
                    var patternParts = allPatterns[i];
                    var shortcutChars = patternParts[3];
                    if (shortcutChars) {
                        for (var c = shortcutChars.length; --c >= 0;) {
                            shortcuts[shortcutChars.charAt(c)] = patternParts;
                        }
                    }
                    var regex = patternParts[1];
                    var k = '' + regex;
                    if (!regexKeys.hasOwnProperty(k)) {
                        allRegexs.push(regex);
                        regexKeys[k] = null;
                    }
                }
                allRegexs.push(/[\0-\uffff]/);
                tokenizer = combinePrefixPatterns(allRegexs);
            })();
    
            var nPatterns = fallthroughStylePatterns.length;
    
            /**
             * Lexes job.sourceCode and produces an output array job.decorations of
             * style classes preceded by the position at which they start in
             * job.sourceCode in order.
             *
             * @param {Object} job an object like <pre>{
             *    sourceCode: {string} sourceText plain text,
             *    basePos: {int} position of job.sourceCode in the larger chunk of
             *        sourceCode.
             * }</pre>
             */
            var decorate = function (job) {
                var sourceCode = job.sourceCode, basePos = job.basePos;
                /** Even entries are positions in source in ascending order.  Odd enties
                 * are style markers (e.g., PR_COMMENT) that run from that position until
                 * the end.
                 * @type {Array.<number|string>}
                 */
                var decorations = [basePos, PR_PLAIN];
                var pos = 0;  // index into sourceCode
                var tokens = sourceCode.match(tokenizer) || [];
                var styleCache = {};
    
                for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
                    var token = tokens[ti];
                    var style = styleCache[token];
                    var match = void 0;
    
                    var isEmbedded;
                    if (typeof style === 'string') {
                        isEmbedded = false;
                    } else {
                        var patternParts = shortcuts[token.charAt(0)];
                        if (patternParts) {
                            match = token.match(patternParts[1]);
                            style = patternParts[0];
                        } else {
                            for (var i = 0; i < nPatterns; ++i) {
                                patternParts = fallthroughStylePatterns[i];
                                match = token.match(patternParts[1]);
                                if (match) {
                                    style = patternParts[0];
                                    break;
                                }
                            }
    
                            if (!match) {  // make sure that we make progress
                                style = PR_PLAIN;
                            }
                        }
    
                        isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
                        if (isEmbedded && !(match && typeof match[1] === 'string')) {
                            isEmbedded = false;
                            style = PR_SOURCE;
                        }
    
                        if (!isEmbedded) { styleCache[token] = style; }
                    }
    
                    var tokenStart = pos;
                    pos += token.length;
    
                    if (!isEmbedded) {
                        decorations.push(basePos + tokenStart, style);
                    } else {  // Treat group 1 as an embedded block of source code.
                        var embeddedSource = match[1];
                        var embeddedSourceStart = token.indexOf(embeddedSource);
                        var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
                        if (match[2]) {
                            // If embeddedSource can be blank, then it would match at the
                            // beginning which would cause us to infinitely recurse on the
                            // entire token, so we catch the right context in match[2].
                            embeddedSourceEnd = token.length - match[2].length;
                            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
                        }
                        var lang = style.substring(5);
                        // Decorate the left of the embedded source
                        appendDecorations(
                            basePos + tokenStart,
                            token.substring(0, embeddedSourceStart),
                            decorate, decorations);
                        // Decorate the embedded source
                        appendDecorations(
                            basePos + tokenStart + embeddedSourceStart,
                            embeddedSource,
                            langHandlerForExtension(lang, embeddedSource),
                            decorations);
                        // Decorate the right of the embedded section
                        appendDecorations(
                            basePos + tokenStart + embeddedSourceEnd,
                            token.substring(embeddedSourceEnd),
                            decorate, decorations);
                    }
                }
                job.decorations = decorations;
            };
            return decorate;
        }
    
        /** returns a function that produces a list of decorations from source text.
         *
         * This code treats ", ', and ` as string delimiters, and \ as a string
         * escape.  It does not recognize perl's qq() style strings.
         * It has no special handling for double delimiter escapes as in basic, or
         * the tripled delimiters used in python, but should work on those regardless
         * although in those cases a single string literal may be broken up into
         * multiple adjacent string literals.
         *
         * It recognizes C, C++, and shell style comments.
         *
         * @param {Object} options a set of optional parameters.
         * @return {function (Object)} a function that examines the source code
         *     in the input job and builds the decoration list.
         */
        function sourceDecorator(options) {
            var shortcutStylePatterns = [], fallthroughStylePatterns = [];
            if (options['tripleQuotedStrings']) {
                // '''multi-line-string''', 'single-line-string', and double-quoted
                shortcutStylePatterns.push(
                    [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
                        null, '\'"']);
            } else if (options['multiLineStrings']) {
                // 'multi-line-string', "multi-line-string"
                shortcutStylePatterns.push(
                    [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
                        null, '\'"`']);
            } else {
                // 'single-line-string', "single-line-string"
                shortcutStylePatterns.push(
                    [PR_STRING,
                        /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
                        null, '"\'']);
            }
            if (options['verbatimStrings']) {
                // verbatim-string-literal production from the C# grammar.  See issue 93.
                fallthroughStylePatterns.push(
                    [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
            }
            var hc = options['hashComments'];
            if (hc) {
                if (options['cStyleComments']) {
                    if (hc > 1) {  // multiline hash comments
                        shortcutStylePatterns.push(
                            [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
                    } else {
                        // Stop C preprocessor declarations at an unclosed open comment
                        shortcutStylePatterns.push(
                            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
                                null, '#']);
                    }
                    fallthroughStylePatterns.push(
                        [PR_STRING,
                            /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
                            null]);
                } else {
                    shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
                }
            }
            if (options['cStyleComments']) {
                fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
                fallthroughStylePatterns.push(
                    [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
            }
            if (options['regexLiterals']) {
                /**
                 * @const
                 */
                var REGEX_LITERAL = (
                    // A regular expression literal starts with a slash that is
                    // not followed by * or / so that it is not confused with
                    // comments.
                    '/(?=[^/*])'
                        // and then contains any number of raw characters,
                        + '(?:[^/\\x5B\\x5C]'
                        // escape sequences (\x5C),
                        +    '|\\x5C[\\s\\S]'
                        // or non-nesting character sets (\x5B\x5D);
                        +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
                        // finally closed by a /.
                        + '/');
                fallthroughStylePatterns.push(
                    ['lang-regex',
                        new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
                    ]);
            }
    
            var types = options['types'];
            if (types) {
                fallthroughStylePatterns.push([PR_TYPE, types]);
            }
    
            var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
            if (keywords.length) {
                fallthroughStylePatterns.push(
                    [PR_KEYWORD,
                        new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
                        null]);
            }
    
            shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
            fallthroughStylePatterns.push(
                // TODO(mikesamuel): recognize non-latin letters and numerals in idents
                [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
                [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
                [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
                [PR_LITERAL,
                    new RegExp(
                        '^(?:'
                            // A hex number
                            + '0x[a-f0-9]+'
                            // or an octal or decimal number,
                            + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
                            // possibly in scientific notation
                            + '(?:e[+\\-]?\\d+)?'
                            + ')'
                            // with an optional modifier like UL for unsigned long
                            + '[a-z]*', 'i'),
                    null, '0123456789'],
                // Don't treat escaped quotes in bash as starting strings.  See issue 144.
                [PR_PLAIN,       /^\\[\s\S]?/, null],
                [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]);
    
            return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
        }
    
        var decorateSource = sourceDecorator({
            'keywords': ALL_KEYWORDS,
            'hashComments': true,
            'cStyleComments': true,
            'multiLineStrings': true,
            'regexLiterals': true
        });
    
        /**
         * Given a DOM subtree, wraps it in a list, and puts each line into its own
         * list item.
         *
         * @param {Node} node modified in place.  Its content is pulled into an
         *     HTMLOListElement, and each line is moved into a separate list item.
         *     This requires cloning elements, so the input might not have unique
         *     IDs after numbering.
         */
        function numberLines(node, opt_startLineNum) {
            var nocode = /(?:^|\s)nocode(?:\s|$)/;
            var lineBreak = /\r\n?|\n/;
    
            var document = node.ownerDocument;
    
            var whitespace;
            if (node.currentStyle) {
                whitespace = node.currentStyle.whiteSpace;
            } else if (window.getComputedStyle) {
                whitespace = document.defaultView.getComputedStyle(node, null)
                    .getPropertyValue('white-space');
            }
            // If it's preformatted, then we need to split lines on line breaks
            // in addition to <BR>s.
            var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
    
            var li = document.createElement('LI');
            while (node.firstChild) {
                li.appendChild(node.firstChild);
            }
            // An array of lines.  We split below, so this is initialized to one
            // un-split line.
            var listItems = [li];
    
            function walk(node) {
                switch (node.nodeType) {
                    case 1:  // Element
                        if (nocode.test(node.className)) { break; }
                        if ('BR' === node.nodeName) {
                            breakAfter(node);
                            // Discard the <BR> since it is now flush against a </LI>.
                            if (node.parentNode) {
                                node.parentNode.removeChild(node);
                            }
                        } else {
                            for (var child = node.firstChild; child; child = child.nextSibling) {
                                walk(child);
                            }
                        }
                        break;
                    case 3: case 4:  // Text
                    if (isPreformatted) {
                        var text = node.nodeValue;
                        var match = text.match(lineBreak);
                        if (match) {
                            var firstLine = text.substring(0, match.index);
                            node.nodeValue = firstLine;
                            var tail = text.substring(match.index + match[0].length);
                            if (tail) {
                                var parent = node.parentNode;
                                parent.insertBefore(
                                    document.createTextNode(tail), node.nextSibling);
                            }
                            breakAfter(node);
                            if (!firstLine) {
                                // Don't leave blank text nodes in the DOM.
                                node.parentNode.removeChild(node);
                            }
                        }
                    }
                    break;
                }
            }
    
            // Split a line after the given node.
            function breakAfter(lineEndNode) {
                // If there's nothing to the right, then we can skip ending the line
                // here, and move root-wards since splitting just before an end-tag
                // would require us to create a bunch of empty copies.
                while (!lineEndNode.nextSibling) {
                    lineEndNode = lineEndNode.parentNode;
                    if (!lineEndNode) { return; }
                }
    
                function breakLeftOf(limit, copy) {
                    // Clone shallowly if this node needs to be on both sides of the break.
                    var rightSide = copy ? limit.cloneNode(false) : limit;
                    var parent = limit.parentNode;
                    if (parent) {
                        // We clone the parent chain.
                        // This helps us resurrect important styling elements that cross lines.
                        // E.g. in <i>Foo<br>Bar</i>
                        // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
                        var parentClone = breakLeftOf(parent, 1);
                        // Move the clone and everything to the right of the original
                        // onto the cloned parent.
                        var next = limit.nextSibling;
                        parentClone.appendChild(rightSide);
                        for (var sibling = next; sibling; sibling = next) {
                            next = sibling.nextSibling;
                            parentClone.appendChild(sibling);
                        }
                    }
                    return rightSide;
                }
    
                var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    
                // Walk the parent chain until we reach an unattached LI.
                for (var parent;
                    // Check nodeType since IE invents document fragments.
                     (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
                    copiedListItem = parent;
                }
                // Put it on the list of lines for later processing.
                listItems.push(copiedListItem);
            }
    
            // Split lines while there are lines left to split.
            for (var i = 0;  // Number of lines that have been split so far.
                 i < listItems.length;  // length updated by breakAfter calls.
                 ++i) {
                walk(listItems[i]);
            }
    
            // Make sure numeric indices show correctly.
            if (opt_startLineNum === (opt_startLineNum|0)) {
                listItems[0].setAttribute('value', opt_startLineNum);
            }
    
            var ol = document.createElement('OL');
            ol.className = 'linenums';
            var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
            for (var i = 0, n = listItems.length; i < n; ++i) {
                li = listItems[i];
                // Stick a class on the LIs so that stylesheets can
                // color odd/even rows, or any other row pattern that
                // is co-prime with 10.
                li.className = 'L' + ((i + offset) % 10);
                if (!li.firstChild) {
                    li.appendChild(document.createTextNode('\xA0'));
                }
                ol.appendChild(li);
            }
    
            node.appendChild(ol);
        }
    
        /**
         * Breaks {@code job.sourceCode} around style boundaries in
         * {@code job.decorations} and modifies {@code job.sourceNode} in place.
         * @param {Object} job like <pre>{
         *    sourceCode: {string} source as plain text,
         *    spans: {Array.<number|Node>} alternating span start indices into source
         *       and the text node or element (e.g. {@code <BR>}) corresponding to that
         *       span.
         *    decorations: {Array.<number|string} an array of style classes preceded
         *       by the position at which they start in job.sourceCode in order
         * }</pre>
         * @private
         */
        function recombineTagsAndDecorations(job) {
            var isIE = /\bMSIE\b/.test(navigator.userAgent);
            var newlineRe = /\n/g;
    
            var source = job.sourceCode;
            var sourceLength = source.length;
            // Index into source after the last code-unit recombined.
            var sourceIndex = 0;
    
            var spans = job.spans;
            var nSpans = spans.length;
            // Index into spans after the last span which ends at or before sourceIndex.
            var spanIndex = 0;
    
            var decorations = job.decorations;
            var nDecorations = decorations.length;
            // Index into decorations after the last decoration which ends at or before
            // sourceIndex.
            var decorationIndex = 0;
    
            // Remove all zero-length decorations.
            decorations[nDecorations] = sourceLength;
            var decPos, i;
            for (i = decPos = 0; i < nDecorations;) {
                if (decorations[i] !== decorations[i + 2]) {
                    decorations[decPos++] = decorations[i++];
                    decorations[decPos++] = decorations[i++];
                } else {
                    i += 2;
                }
            }
            nDecorations = decPos;
    
            // Simplify decorations.
            for (i = decPos = 0; i < nDecorations;) {
                var startPos = decorations[i];
                // Conflate all adjacent decorations that use the same style.
                var startDec = decorations[i + 1];
                var end = i + 2;
                while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
                    end += 2;
                }
                decorations[decPos++] = startPos;
                decorations[decPos++] = startDec;
                i = end;
            }
    
            nDecorations = decorations.length = decPos;
    
            var decoration = null;
            while (spanIndex < nSpans) {
                var spanStart = spans[spanIndex];
                var spanEnd = spans[spanIndex + 2] || sourceLength;
    
                var decStart = decorations[decorationIndex];
                var decEnd = decorations[decorationIndex + 2] || sourceLength;
    
                var end = Math.min(spanEnd, decEnd);
    
                var textNode = spans[spanIndex + 1];
                var styledText;
                if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
                    // Don't introduce spans around empty text nodes.
                    && (styledText = source.substring(sourceIndex, end))) {
                    // This may seem bizarre, and it is.  Emitting LF on IE causes the
                    // code to display with spaces instead of line breaks.
                    // Emitting Windows standard issue linebreaks (CRLF) causes a blank
                    // space to appear at the beginning of every line but the first.
                    // Emitting an old Mac OS 9 line separator makes everything spiffy.
                    if (isIE) { styledText = styledText.replace(newlineRe, '\r'); }
                    textNode.nodeValue = styledText;
                    var document = textNode.ownerDocument;
                    var span = document.createElement('SPAN');
                    span.className = decorations[decorationIndex + 1];
                    var parentNode = textNode.parentNode;
                    parentNode.replaceChild(span, textNode);
                    span.appendChild(textNode);
                    if (sourceIndex < spanEnd) {  // Split off a text node.
                        spans[spanIndex + 1] = textNode
                            // TODO: Possibly optimize by using '' if there's no flicker.
                            = document.createTextNode(source.substring(end, spanEnd));
                        parentNode.insertBefore(textNode, span.nextSibling);
                    }
                }
    
                sourceIndex = end;
    
                if (sourceIndex >= spanEnd) {
                    spanIndex += 2;
                }
                if (sourceIndex >= decEnd) {
                    decorationIndex += 2;
                }
            }
        }
    
    
        /** Maps language-specific file extensions to handlers. */
        var langHandlerRegistry = {};
        /** Register a language handler for the given file extensions.
         * @param {function (Object)} handler a function from source code to a list
         *      of decorations.  Takes a single argument job which describes the
         *      state of the computation.   The single parameter has the form
         *      {@code {
         *        sourceCode: {string} as plain text.
         *        decorations: {Array.<number|string>} an array of style classes
         *                     preceded by the position at which they start in
         *                     job.sourceCode in order.
         *                     The language handler should assigned this field.
         *        basePos: {int} the position of source in the larger source chunk.
         *                 All positions in the output decorations array are relative
         *                 to the larger source chunk.
         *      } }
         * @param {Array.<string>} fileExtensions
         */
        function registerLangHandler(handler, fileExtensions) {
            for (var i = fileExtensions.length; --i >= 0;) {
                var ext = fileExtensions[i];
                if (!langHandlerRegistry.hasOwnProperty(ext)) {
                    langHandlerRegistry[ext] = handler;
                } else if (window['console']) {
                    console['warn']('cannot override language handler %s', ext);
                }
            }
        }
        function langHandlerForExtension(extension, source) {
            if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
                // Treat it as markup if the first non whitespace character is a < and
                // the last non-whitespace character is a >.
                extension = /^\s*</.test(source)
                    ? 'default-markup'
                    : 'default-code';
            }
            return langHandlerRegistry[extension];
        }
        registerLangHandler(decorateSource, ['default-code']);
        registerLangHandler(
            createSimpleLexer(
                [],
                [
                    [PR_PLAIN,       /^[^<?]+/],
                    [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
                    [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
                    // Unescaped content in an unknown language
                    ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
                    ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
                    [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
                    ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
                    // Unescaped content in javascript.  (Or possibly vbscript).
                    ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
                    // Contains unescaped stylesheet content
                    ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
                    ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
                ]),
            ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
        registerLangHandler(
            createSimpleLexer(
                [
                    [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
                    [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
                ],
                [
                    [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
                    [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
                    ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
                    [PR_PUNCTUATION,  /^[=<>\/]+/],
                    ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
                    ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
                    ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
                    ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
                    ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
                    ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
                ]),
            ['in.tag']);
        registerLangHandler(
            createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
        registerLangHandler(sourceDecorator({
            'keywords': CPP_KEYWORDS,
            'hashComments': true,
            'cStyleComments': true,
            'types': C_TYPES
        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
        registerLangHandler(sourceDecorator({
            'keywords': 'null,true,false'
        }), ['json']);
        registerLangHandler(sourceDecorator({
            'keywords': CSHARP_KEYWORDS,
            'hashComments': true,
            'cStyleComments': true,
            'verbatimStrings': true,
            'types': C_TYPES
        }), ['cs']);
        registerLangHandler(sourceDecorator({
            'keywords': JAVA_KEYWORDS,
            'cStyleComments': true
        }), ['java']);
        registerLangHandler(sourceDecorator({
            'keywords': SH_KEYWORDS,
            'hashComments': true,
            'multiLineStrings': true
        }), ['bsh', 'csh', 'sh']);
        registerLangHandler(sourceDecorator({
            'keywords': PYTHON_KEYWORDS,
            'hashComments': true,
            'multiLineStrings': true,
            'tripleQuotedStrings': true
        }), ['cv', 'py']);
        registerLangHandler(sourceDecorator({
            'keywords': PERL_KEYWORDS,
            'hashComments': true,
            'multiLineStrings': true,
            'regexLiterals': true
        }), ['perl', 'pl', 'pm']);
        registerLangHandler(sourceDecorator({
            'keywords': RUBY_KEYWORDS,
            'hashComments': true,
            'multiLineStrings': true,
            'regexLiterals': true
        }), ['rb']);
        registerLangHandler(sourceDecorator({
            'keywords': JSCRIPT_KEYWORDS,
            'cStyleComments': true,
            'regexLiterals': true
        }), ['js']);
        registerLangHandler(sourceDecorator({
            'keywords': COFFEE_KEYWORDS,
            'hashComments': 3,  // ### style block comments
            'cStyleComments': true,
            'multilineStrings': true,
            'tripleQuotedStrings': true,
            'regexLiterals': true
        }), ['coffee']);
        registerLangHandler(createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    
        function applyDecorator(job) {
            var opt_langExtension = job.langExtension;
    
            try {
                // Extract tags, and convert the source code to plain text.
                var sourceAndSpans = extractSourceSpans(job.sourceNode);
                /** Plain text. @type {string} */
                var source = sourceAndSpans.sourceCode;
                job.sourceCode = source;
                job.spans = sourceAndSpans.spans;
                job.basePos = 0;
    
                // Apply the appropriate language handler
                langHandlerForExtension(opt_langExtension, source)(job);
    
                // Integrate the decorations and tags back into the source code,
                // modifying the sourceNode in place.
                recombineTagsAndDecorations(job);
            } catch (e) {
                if ('console' in window) {
                    console['log'](e && e['stack'] ? e['stack'] : e);
                }
            }
        }
    
        /**
         * @param sourceCodeHtml {string} The HTML to pretty print.
         * @param opt_langExtension {string} The language name to use.
         *     Typically, a filename extension like 'cpp' or 'java'.
         * @param opt_numberLines {number|boolean} True to number lines,
         *     or the 1-indexed number of the first line in sourceCodeHtml.
         */
        function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
            var container = document.createElement('PRE');
            // This could cause images to load and onload listeners to fire.
            // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
            // We assume that the inner HTML is from a trusted source.
            container.innerHTML = sourceCodeHtml;
            if (opt_numberLines) {
                numberLines(container, opt_numberLines);
            }
    
            var job = {
                langExtension: opt_langExtension,
                numberLines: opt_numberLines,
                sourceNode: container
            };
            applyDecorator(job);
            return container.innerHTML;
        }
    
        function prettyPrint(opt_whenDone) {
            function byTagName(tn) { return document.getElementsByTagName(tn); }
            // fetch a list of nodes to rewrite
            var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
            var elements = [];
            for (var i = 0; i < codeSegments.length; ++i) {
                for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
                    elements.push(codeSegments[i][j]);
                }
            }
            codeSegments = null;
    
            var clock = Date;
            if (!clock['now']) {
                clock = { 'now': function () { return +(new Date); } };
            }
    
            // The loop is broken into a series of continuations to make sure that we
            // don't make the browser unresponsive when rewriting a large page.
            var k = 0;
            var prettyPrintingJob;
    
            var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
            var prettyPrintRe = /\bprettyprint\b/;
    
            function doWork() {
                var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
                    clock['now']() + 250 /* ms */ :
                    Infinity);
                for (; k < elements.length && clock['now']() < endTime; k++) {
                    var cs = elements[k];
                    var className = cs.className;
                    if (className.indexOf('prettyprint') >= 0) {
                        // If the classes includes a language extensions, use it.
                        // Language extensions can be specified like
                        //     <pre class="prettyprint lang-cpp">
                        // the language extension "cpp" is used to find a language handler as
                        // passed to PR.registerLangHandler.
                        // HTML5 recommends that a language be specified using "language-"
                        // as the prefix instead.  Google Code Prettify supports both.
                        // http://dev.w3.org/html5/spec-author-view/the-code-element.html
                        var langExtension = className.match(langExtensionRe);
                        // Support <pre class="prettyprint"><code class="language-c">
                        var wrapper;
                        if (!langExtension && (wrapper = childContentWrapper(cs))
                            && "CODE" === wrapper.tagName) {
                            langExtension = wrapper.className.match(langExtensionRe);
                        }
    
                        if (langExtension) {
                            langExtension = langExtension[1];
                        }
    
                        // make sure this is not nested in an already prettified element
                        var nested = false;
                        for (var p = cs.parentNode; p; p = p.parentNode) {
                            if ((p.tagName === 'pre' || p.tagName === 'code' ||
                                p.tagName === 'xmp') &&
                                p.className && p.className.indexOf('prettyprint') >= 0) {
                                nested = true;
                                break;
                            }
                        }
                        if (!nested) {
                            // Look for a class like linenums or linenums:<n> where <n> is the
                            // 1-indexed number of the first line.
                            var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
                            lineNums = lineNums
                                ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
                                : false;
                            if (lineNums) { numberLines(cs, lineNums); }
    
                            // do the pretty printing
                            prettyPrintingJob = {
                                langExtension: langExtension,
                                sourceNode: cs,
                                numberLines: lineNums
                            };
                            applyDecorator(prettyPrintingJob);
                        }
                    }
                }
                if (k < elements.length) {
                    // finish up in a continuation
                    setTimeout(doWork, 250);
                } else if (opt_whenDone) {
                    opt_whenDone();
                }
            }
    
            doWork();
        }
    
        /**
         * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
         * {@code class=prettyprint} and prettify them.
         *
         * @param {Function?} opt_whenDone if specified, called when the last entry
         *     has been finished.
         */
        window['prettyPrintOne'] = prettyPrintOne;
        /**
         * Pretty print a chunk of code.
         *
         * @param {string} sourceCodeHtml code as html
         * @return {string} code as html, but prettier
         */
        window['prettyPrint'] = prettyPrint;
        /**
         * Contains functions for creating and registering new language handlers.
         * @type {Object}
         */
        window['PR'] = {
            'createSimpleLexer': createSimpleLexer,
            'registerLangHandler': registerLangHandler,
            'sourceDecorator': sourceDecorator,
            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
            'PR_COMMENT': PR_COMMENT,
            'PR_DECLARATION': PR_DECLARATION,
            'PR_KEYWORD': PR_KEYWORD,
            'PR_LITERAL': PR_LITERAL,
            'PR_NOCODE': PR_NOCODE,
            'PR_PLAIN': PR_PLAIN,
            'PR_PUNCTUATION': PR_PUNCTUATION,
            'PR_SOURCE': PR_SOURCE,
            'PR_STRING': PR_STRING,
            'PR_TAG': PR_TAG,
            'PR_TYPE': PR_TYPE
        };
    })();
    
    
    ================================================
    FILE: index.html
    ================================================
    <!DOCTYPE html>
    <html>
    <head>
        <title>即时通讯示例--自动登录</title>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    </head>
    <body>
    <script type="text/javascript" src="js/jQuery-1.7.1.min.js"></script>
    <script type="text/javascript" src="js/im.plus.js?skin=im"></script>
    <script type="text/javascript" src="js/jQuery.im.js"></script>
    <script type="text/javascript">
        $(function() {
             $(document).FnWebIM({
                 autoLogin          :true,      //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true
                 msgRefreshTime    :1000,       //number型,消息刷新时间,单位为ms
                 friendRefreshTime :10000,     //number型,好友刷新时间,单位为ms
                 showSecretary     :true,      //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true
                 noticeContent     :"唐僧师徒历经千辛万苦,终于见到了佛祖……",        //string型,公告内容 为空时不显示公告
                 sendPicture       :true,      //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true
                 msgMaxSize        :300,        //number型,单条消息最大允许字符
                 msgSound           :false,     //boolean型,是否开启声音提醒,true:开启,false:关闭,默认为true
                 defaultWindow     :""   //string型,登录后打开新聊天窗口,此处接收的参数为联系人的uid,否则会出错
             });
        });
    </script>
    </body>
    </html>
    
    ================================================
    FILE: js/im.css
    ================================================
    @charset "utf-8";
    *{margin:0;padding:0}
    img{border: none;}
    a,input.d-button{outline: none;outline: 0;hide-focus: expression( this.hideFocus=true );}
    *html{_background: url(about:blank) fixed;}
    body { _margin:0; _height:100%; background: #fcfcfc}
    #fn_imbar{position: fixed;right:3px;bottom:0;padding:0 5px;_float:right;height:24px;line-height: 26px;overflow:hidden;border: solid 1px #ddd;border-bottom:none;background: url("../img/im_bg.png") repeat-x 0 -798px;font-size: 12px;color:#666;cursor: pointer;}
    *html #fn_imbar{position:absolute;bottom:auto;top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)));}
    #fn_imbar span{display: block;padding-left:20px;}
    #fn_imbar.im_loading span{background: url("../img/loading.gif") no-repeat 0 6px;}
    #fn_imbar.im_login span{background: url("../img/newmsg.gif") no-repeat 2px 6px;}
    #fn_imbar b{padding:0 5px;background: #c00;color:#fff;margin-left:3px;-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;font-weight: normal;line-height: 12px;overflow: hidden; }
    .d-outer { text-align:left; }
    .d-border, .d-dialog { border:0 none; margin:0; border-collapse:collapse; width:auto;}
    .d-nw, .d-n, .d-ne, .d-w, .d-c, .d-e, .d-sw, .d-s, .d-se, .d-header, .d-main, .d-footer { padding:0; }
    .d-title { overflow:hidden; text-overflow: ellipsis; cursor:default; font-family:tahoma,arial,\5b8b\4f53;}
    .d-state-noTitle .d-title { display:none; }
    .d-close { display:block; position:absolute; text-decoration:none; outline:none; _cursor:pointer; }
    .d-close:hover { text-decoration:none; }
    .d-main { text-align:center; vertical-align:middle; min-width:9em;font-family:tahoma,arial,\5b8b\4f53; }
    .d-content {font-size:12px; display:block\0/*IE8 BUG*/; display:inline-block\9\0; *zoom:1; *display:inline; text-align:left; border:0 none;  }
    .d-content.d-state-full { display:block; width:100%; margin:0; padding:0!important; height:100%; }
    .d-loading { width:100%; height:32px; text-align:left; text-indent:-999em; overflow:hidden; background:url(../img/loading.gif) no-repeat center center; }
    .d-buttons { padding:5px 8px; text-align:right; white-space:nowrap; }
    .d-button { margin-left:8px; height:24px;line-height: 22px; padding:0 15px;+padding:0 5px;border:solid 1px #c1c8d1;background: url("../img/dialog.png") repeat-x 0 -61px;border-radius: 2px;color: #333;cursor: pointer;}
    .d-button:focus { outline:none 0 !important;  }
    .d-button:hover { color:#000; border-color:#e8cca0; background-position: 0 -92px;}
    .d-button:active {border-color:#7494c4;outline:none 0 !important; }
    .d-button[disabled],.d-button[disabled]:hover { cursor:default; color:#999;}
    .d-state-highlight { color: #000; border: 1px solid #a1badf;}
    .d-state-highlight:hover { border-color:#7494c4; }
    .d-state-highlight:active { border-color:#999; }
    .d-input-text{width:338px;padding:3px 5px;border:solid 1px #b7b7b7;outline: none;color:#666;font-family:tahoma,arial,\5b8b\4f53;margin-top:3px;}
    .d-input-text:focus{border:solid 1px #999;}
    .d-mask { background:#fff; filter:alpha(opacity=20);-moz-opacity:0.2;  opacity:0.2; }
    .d-inner { background:#FFF;}
    .d-outer{ border:1px solid #b7b7b7;border-top:solid 2px #000;}
    .d-state-lock .d-nw, .d-state-lock .d-n, .d-state-lock .d-ne, .d-state-lock .d-w, .d-state-lock .d-e, .d-state-lock .d-sw, .d-state-lock .d-s, .d-state-lock .d-se { background:rgba(0, 0, 0, .5); background:#999\9!important; filter:alpha(opacity=50);}
    .d-title { height:29px; line-height:28px; padding:0 28px 0 15px; background: url("../img/dialog.png") repeat-x 0 -28px; border-bottom:1px solid #b7b7b7;color:#333!important;font-size:12px;font-weight: bold;}
    .d-state-drag .d-title,.d-state-drag .d-titleBar { box-shadow:none; }
    .d-close { padding:0; top:8px; right:8px; width:17px; height:17px;background: url("../img/dialog.png") no-repeat 2px 2px;overflow: hidden; }
    .d-close:hover {color:#C00;margin:-1px;background-color:#fff;border: solid 1px #ced5e0; }
    .d-content { color:#666; }
    .d-state-focus{background: #fff;}
    .d-state-focus .d-content { color:#333; }
    .d-buttons { background-color:#fcfcfc;  }
    .d-nw, .d-n, .d-ne, .d-w, .d-e, .d-sw, .d-s, .d-se { display:none; }
    #fn_imbox{display:none;border-left:solid 1px #313131;border-top:solid 2px #000;font-size:12px;position:fixed;bottom:0;right:0;width:180px;height:360px;background: #fff; font-family:tahoma,arial,\5b8b\4f53;z-index: 1;}
    *html #fn_imbox{position:absolute;bottom:auto;right:-1px;top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)));}
    #fn_imbox .im_top{height:31px;background: url("../img/im_bg.png") repeat-x 0 -867px;position: relative;z-index: 1;}
    #fn_imbox .im_top a.cc{display: block;height:8px;background: url("../img/im_bg.png") no-repeat center -678px;overflow: hidden; }
    #fn_imbox .im_top a:hover{background-position:  center -717px; }
    #fn_imbox .im_top h4{font-size:12px;font-weight:normal;color:#fff;padding-left:30px; background: url("../img/im_bg.png") no-repeat 11px -761px;float: left;width:126px;height:22px;cursor: pointer;}
    #fn_imbox .im_top a.modify{text-decoration: none;color:#fff;display:inline-block;width:14px;margin-right:5px;background: url("../img/m_ico.png") no-repeat 0 -148px;float: right;}
    #fn_imbox .im_top a.modify:hover{background-position:  0 -167px;}
    #fn_imbox .im_contents{height:303px;_height:326px;}
    #fn_imbox .im_contents .hide{display: none;}
    #fn_imbox .im_contents h4{border-bottom:solid 1px #b7b7b7;padding-left:20px;color:#717171;height:24px;line-height: 22px;cursor: pointer;font-weight: normal;margin-top:1px;font-size:12px;}
    #fn_imbox .im_contents h4 i{color:#999;font-style: normal;margin-left:5px;}
    #fn_imbox .im_group_expansion{background:url("../img/im_bg.png") no-repeat 6px -346px #f3f3f3; }
    #fn_imbox .im_group_expansion:hover{background-position: 6px -365px; color:#333;}
    #fn_imbox .im_group_away{background:url("../img/im_bg.png") no-repeat 6px -386px #f3f3f3; }
    #fn_imbox .im_group_away:hover{background-position: 6px -408px; color:#333;}
    #fn_imbox .im_group_contacts{height:253px;overflow: hidden;margin-bottom:1px;border-bottom:solid 1px #b7b7b7;_width:180px;_height:251px;}
    #fn_imbox .im_contact{padding:8px;height: 30px;overflow: hidden;width: 175px;-moz-user-select:   none;cursor: default;}
    #fn_imbox .im_contact:hover{background: #fafafa;}
    #fn_imbox .current{background: #f7f7f7;}
    #fn_imbox .im_contact i{float: left;display: block;width:30px;height: 30px;overflow: hidden;-moz-border-radius:2px;-khtml-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;}
    #fn_imbox .im_contact.offline i img{width:30px;height: 30px;FILTER: gray;-webkit-filter: grayscale(100%); }
    #fn_imbox .im_contact.offline:hover i img{FILTER:;-webkit-filter: grayscale(0);}
    #fn_imbox .im_contact sup{display:block;width:5px;height:5px;position: absolute;margin:-8px 0 0 24px;border:solid 1px #fff; +margin:24px 0 0 -6px;overflow: hidden;}
    #fn_imbox .im_contact.online sup{background: green;}
    #fn_imbox .im_contact.offline sup{background: #ddd;}
    #fn_imbox .im_contact span{float:left;display:block;width:100px;height:30px;line-height:30px;overflow:hidden;padding:0 10px;color:#555;}
    #fn_imbox .im_contact b{display: inline-block;width:21px;height:12px;background: url("../img/new.gif") no-repeat;margin-left:5px;}
    #fn_imbox .im_group_contacts a{float: left;display: block;width: 10px;height:10px;background: url("../img/im_bg.png") no-repeat 0 -450px;margin-top:11px;}
    #fn_imbox .im_group_contacts a:hover{background-position: 0 -480px;}
    #fn_imbox .im_bottombar{background:url("../img/im_bg.png") repeat-x 0 -799px;height:25px;line-height: 25px;position: absolute;z-index: 1;width: 180px;border-top:solid 1px #b7b7b7;_margin-top:-23px;}
    #fn_imbox .im_bottombar input{float: left;background:transparent url("../img/im_bg.png") no-repeat 7px -581px;border: none 0;height:25px;line-height:26px;padding:0 0 0 20px;color:#666;width: 134px;outline: none;}
    #fn_imbox .im_bottombar span{float: left;display: block;width:25px;height:25px;background:url("../img/im_bg.png") no-repeat 6px -611px;border-left:solid 1px #b7b7b7;cursor: pointer; }
    #fn_imbox .im_bottombar span:hover, #fn_imbox .im_bottombar span.current{background-position:6px -641px; }
    #fn_imbox .im_bottombar ul{position: fixed;padding:10px 0;border-top:2px solid #000;right:0;bottom:25px;background: #fff;display: none;z-index: 2;_position: absolute;+bottom:26px; }
    #fn_imbox .im_bottombar li{list-style: none;padding:0 15px 0 28px;line-height: 22px;color:#666;height:24px;cursor: pointer;width: 84px;width: 137px;+line-height:26px;_line-height: 22px;overflow: hidden;}
    #fn_imbox .im_bottombar li.selected{background: url("../img/im_bg.png") no-repeat 10px -508px;}
    #fn_imbox .im_bottombar li.selected.current{background: url("../img/im_bg.png") no-repeat 10px -552px;}
    #fn_imbox .im_bottombar li:hover{background-color: #f0f2f5 !important;}
    #fn_imbox .im_bottombar li.setting{background:url("../img/im_bg.png") no-repeat 10px -612px;}
    #fn_imbox .im_bottombar li.backlist{background:url("../img/m_ico.png") no-repeat 10px 7px;}
    #fn_imbox .im_bottombar li.friends{background:url("../img/m_ico.png") no-repeat 10px -67px;}
    #fn_imbox .im_bottombar li.help{background:url("../img/m_ico.png") no-repeat 10px -94px;}
    #fn_imbox .im_bottombar li.loginout{background:url("../img/im_bg.png") no-repeat 10px -1307px;}
    #fn_imbox .im_bottombar li.loginout:hover{background-position:10px -1332px;}
    #fn_imbox .im_top h4.im_newmsg{background:url("../img/msg.gif") no-repeat 10px 1px;}
    .im_contactinfobar{margin-left:-8px;font-family:tahoma,arial,\5b8b\4f53;}
    .im_contactinfobar a.im_avatar{display: block;position: absolute;+position:relative;float:left;width:50px;height:50px;padding:3px;border: #b7b7b7 solid 1px;background: #fff;margin-top:-25px;z-index: 2;}
    .im_contactinfobar a.im_avatar:hover{border-color:#999; }
    .im_contactinfobar a.im_avatar.offline img{width:50px;height: 50px;FILTER: gray;-webkit-filter: grayscale(100%); }
    .im_contactinfobar a.im_avatar.offline:hover img{FILTER:;-webkit-filter: grayscale(0);}
    .im_contactinfobar .im_contactinfo{float: left;margin-left:66px;+margin-left:10px;}
    .im_contactinfobar .im_contactinfo a{color:#555;text-decoration: none;font-weight: normal;}
    .im_contactinfobar .im_contactinfo a:hover{color:#333;text-decoration: underline;}
    .im_contactinfobar .im_contactinfo a#imcontact{padding:6px;display:inline;}
    .im_contactinfobar .im_contactinfo a.im_addcontact{background: url("../img/im_bg.png") no-repeat 0 -907px;}
    .im_contactinfobar .im_contactinfo a.im_addcontact:hover{background-position: 0 -934px;text-decoration: none;}
    .im_contactinfobar .im_contactinfo a.im_removecontact{background: url("../img/im_bg.png") no-repeat 0 -1103px;}
    .im_contactinfobar .im_contactinfo a.im_removecontact:hover{background-position: 0 -1130px;text-decoration: none;}
    .im_contactinfobar .im_contactinfo a.im_contact{padding-right:20px;background: url("../img/im_bg.png") no-repeat right -150px;}
    .im_contactinfobar .im_contactinfo a.im_contact:hover{background-position: right -167px;}
    #im_window{width:400px;+height:328px;background: #fff;font-size:12px;font-family:tahoma,arial,\5b8b\4f53;overflow: hidden;}
    #im_window #im_body{float: left;width: 400px;}
    #im_window .im_chats{height:240px;overflow:hidden;border-bottom: solid 1px #b7b7b7;width:100%;}
    #im_window .im_notice{width:100%;float:left;line-height: 16px;background: #fffbe2;color:#777;}
    #im_window .im_notice span{display: block;width: 89%;padding:4px 0 4px 24px;background:url("../img/im_bg.png") no-repeat 7px -191px;float: left;}
    #im_window a.im_notice_close{display: block;width: 12px;height: 12px;background: url("../img/im_bg.png") no-repeat 0 -103px;float: right;margin:7px 6px 0 0;}
    #im_window a.im_notice_close:hover{background-position: 0 -124px;}
    #im_window a.im_morechats{display: block;text-align: center;line-height: 24px;color:#999;text-decoration: none;}
    #im_window a.im_morechats:hover{color:#666;background: #fcfcfc;}
    #im_window .im_chat_content{padding:3px 10px;background: #fcfcfc;border-top:solid 1px #f1f1f1;clear: both;}
    #im_window .im_chat_content i{font-style:normal;color:#999; }
    #im_window .im_chat_content a.fn_url{padding-right:20px;background: url("../img/im_bg.png") no-repeat right -1035px;line-height: 16px; }
    #im_window .im_chat_content .im_chat_txt{color:#555;line-height: 16px;padding:3px 0 5px 0;word-break: break-all;}
    #im_window .im_chat_content .im_chat_txt em{color:#666;font-style: normal;display: block;background:url("../img/im_bg.png") no-repeat 0 -196px;padding-left:18px;}
    #im_window .im_chat_content .im_chat_txt img{max-width: 380px;_width: expression(this.width> 380 ? 380 : true);}
    #im_window .im_chat_content.myself{background: #fff;border-top:none;}
    #im_window .im_send_msg{height:49px;padding:5px;line-height: 16px;overflow: hidden;outline:none; cursor: text;}
    #im_window .im_operatebar{background: #f5f6f7;height:30px;+position: absolute;width: 400px;}
    #im_window .im_operatebars{background: #f5f6f7;height:30px;}
    #im_window a.im_operates{display: block;width:16px;height:16px;float: left;margin:7px 0 0 7px;}
    #im_window a.im_face{background: url("../img/im_bg.png") no-repeat 0 -257px;}
    #im_window a.im_face:hover{background-position:0 -278px;}
    #im_window a.im_upload_pic{background: url("../img/im_bg.png") no-repeat 0 -301px;overflow: hidden;}
    #im_window a.im_upload_pic:hover{background-position:0 -321px;}
    #im_window a.im_shake{background: url("../img/im_bg.png") no-repeat 0 -40px;}
    #im_window a.im_shake:hover{background-position:0 -61px;}
    #im_window a.im_product{background: url("../img/im_bg.png") no-repeat 0 -1174px;}
    #im_window a.im_product:hover{background-position:0 -1200px;}
    #im_window a.im_card{background: url("../img/im_bg.png") no-repeat 0 -1224px;}
    #im_window a.im_card:hover{background-position:0 -1250px;}
    #im_window a.im_moreoperates{background: url("../img/im_bg.png") no-repeat 2px -1361px;}
    #im_window a.im_moreoperates:hover{background-position:2px -1385px;}
    #im_window .im_moreoperate{position: absolute;background:#fbfbfb;line-height: 26px;width: 400px; height:0;overflow: hidden;}
    #im_window .im_moreoperate a{color:#888;text-decoration: none; float: left;padding-left:15px;margin-left:8px;}
    #im_window .im_moreoperate a:hover{color:#666;}
    #im_window .im_moreoperate a.im_abacklist{background: url("../img/m_ico.png") no-repeat 0 9px;}
    #im_window .im_moreoperate a.im_areport{background: url("../img/m_ico.png") no-repeat 0 -15px;}
    #im_window .im_moreoperate a.im_aemptyrecords{background: url("../img/m_ico.png") no-repeat 1px -40px;}
    #im_window .im_moreoperate a.im_aclose{float: right;margin-right:6px;font-size:16px;}
    #im_window .im_operatebar i{float: right;line-height: 30px;white-space:nowrap;color:#999;font-style: normal;_margin-top:-25px;}
    #im_window .im_operatebar a.im_sendmsg_btn{display:block;width:64px;height:22px;margin:4px 5px 0 7px;float: right;background: url("../img/sendmsg.png") no-repeat;}
    #im_window .im_operatebar a.im_sendmsg_btn:hover{background-position: 0 bottom;}
    #im_face{display:none;position: absolute;margin:-193px 0 0 -1px;z-index:3;border:solid 1px #b7b7b7;width:400px;height:190px;font-size: 12px;overflow: hidden;background:#fff url("../img/loading.gif") no-repeat center center;}
    #im_window #im_contactinfo{position:absolute;width: 199px;height:360px;+height:361px;display: none;border:solid 1px #b7b7b7;border-top:2px #000 solid;margin:-32px 0 0 400px;+margin:-33px 0 0 0;}
    #im_window .im_contactinfobar{height:29px;line-height: 29px;background: url("../img/im_bg.png") repeat-x;border-bottom: solid 1px #b7b7b7;padding:0 7px;margin:0;+margin-top:1px;}
    #im_window .im_contactinfobar a.d-close{margin-top:-2px;}
    #im_window .im_contactinfobar a.d-close:hover{margin-top:-3px;}
    #im_window .im_contactinfos{height: 300px;overflow:hidden;background:#fff url("../img/loading.gif") no-repeat center center;}
    #im_window .im_contactgohome{line-height: 30px;float: right;padding-left:13px;color:#999;margin-right:7px;text-decoration: none;background: url("../img/im_bg.png") no-repeat 0 -962px;+line-height: 34px;_line-height:30px;}
    #im_window .im_contactgohome:hover{color:#666;background-position: 0 -992px;}
    .im_infos{margin:-2px;background: url("../img/i.png") repeat-x center center;border:solid 2px #000;-moz-border-radius:2px;-khtml-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;}
    .im_infos p{padding:20px 25px 20px 60px;background: url("../img/i_ico.png") no-repeat 20px 12px;color:#555; }
    
    
    #im_msgbox .d-content{height:240px;}
    
    ================================================
    FILE: js/im.plus.js
    ================================================
    (function(g,h){function i(a){var c=f.expando,d=a===g?0:a[c];d===h&&(a[c]=d=++f.uuid);return d}var f=g.art=function(a,c){return new f.fn.constructor(a,c)},p=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,o=/[\n\t]/g;if(g.$===h)g.$=f;f.fn=f.prototype={constructor:function(a,c){var d,c=c||document;if(!a)return this;if(a.nodeType)return this[0]=a,this;if("string"===typeof a&&(d=p.exec(a))&&d[2])return(d=c.getElementById(d[2]))&&d.parentNode&&(this[0]=d),this;this[0]=a;return this},hasClass:function(a){return-1<
        (" "+this[0].className+" ").replace(o," ").indexOf(" "+a+" ")?!0:!1},addClass:function(a){this.hasClass(a)||(this[0].className+=" "+a);return this},removeClass:function(a){var c=this[0];if(a){if(this.hasClass(a))c.className=c.className.replace(a," ")}else c.className="";return this},css:function(a,c){var d,e=this[0];if("string"===typeof a){if(c===h)return f.css(e,a);e.style[a]=c}else for(d in a)e.style[d]=a[d];return this},show:function(){return this.css("display","block")},hide:function(){return this.css("display",
        "none")},offset:function(){var a=this[0],c=a.getBoundingClientRect(),d=a.ownerDocument,a=d.body,d=d.documentElement;return{left:c.left+(self.pageXOffset||d.scrollLeft)-(d.clientLeft||a.clientLeft||0),top:c.top+(self.pageYOffset||d.scrollTop)-(d.clientTop||a.clientTop||0)}},html:function(a){var c=this[0];if(a===h)return c.innerHTML;f.cleanData(c.getElementsByTagName("*"));c.innerHTML=a;return this},remove:function(){var a=this[0];f.cleanData(a.getElementsByTagName("*"));f.cleanData([a]);a.parentNode.removeChild(a);
        return this},bind:function(a,c){f.event.add(this[0],a,c);return this},unbind:function(a,c){f.event.remove(this[0],a,c);return this}};f.fn.constructor.prototype=f.fn;f.isWindow=function(a){return a&&"object"===typeof a&&"setInterval"in a};f.fn.find=function(a){var c=this[0],d=a.split(".")[1];if(d)if(document.getElementsByClassName)d=c.getElementsByClassName(d);else{for(var e=a=0,b=[],c=(c||document).getElementsByTagName("*"),m=c.length,d=RegExp("(^|\\s)"+d+"(\\s|$)");a<m;a++)d.test(c[a].className)&&
    (b[e]=c[a],e++);d=b}else d=c.getElementsByTagName(a);return f(d[0])};f.each=function(a,c){var d,e=0,b=a.length;if(b===h)for(d in a){if(!1===c.call(a[d],d,a[d]))break}else for(d=a[0];e<b&&!1!==c.call(d,e,d);d=a[++e]);return a};f.data=function(a,c,d){var e=f.cache,a=i(a);if(c===h)return e[a];e[a]||(e[a]={});d!==h&&(e[a][c]=d);return e[a][c]};f.removeData=function(a,c){var d=!0,e=f.expando,b=f.cache,m=i(a),n=m&&b[m];if(n)if(c){delete n[c];for(var k in n)d=!1;d&&delete f.cache[m]}else delete b[m],a.removeAttribute?
        a.removeAttribute(e):a[e]=null};f.uuid=0;f.cache={};f.expando="@cache"+ +new Date;f.event={add:function(a,c,d){var j;var e,b=f.event;e=f.data(a,"@events")||f.data(a,"@events",{});j=e[c]=e[c]||{},e=j;(e.listeners=e.listeners||[]).push(d);if(!e.handler)e.elem=a,e.handler=b.handler(e),a.addEventListener?a.addEventListener(c,e.handler,!1):a.attachEvent("on"+c,e.handler)},remove:function(a,c,d){var e,b,m;b=f.event;var n=!0,k=f.data(a,"@events");if(k)if(c){if(b=k[c]){m=b.listeners;if(d)for(e=0;e<m.length;e++)m[e]===
        d&&m.splice(e--,1);else b.listeners=[];if(0===b.listeners.length){a.removeEventListener?a.removeEventListener(c,b.handler,!1):a.detachEvent("on"+c,b.handler);delete k[c];b=f.data(a,"@events");for(var r in b)n=!1;n&&f.removeData(a,"@events")}}}else for(e in k)b.remove(a,e)},handler:function(a){return function(c){for(var c=f.event.fix(c||g.event),d=0,e=a.listeners,b;b=e[d++];)!1===b.call(a.elem,c)&&(c.preventDefault(),c.stopPropagation())}},fix:function(a){if(a.target)return a;var c={target:a.srcElement||
        document,preventDefault:function(){a.returnValue=!1},stopPropagation:function(){a.cancelBubble=!0}},d;for(d in a)c[d]=a[d];return c}};f.cleanData=function(a){for(var c=0,d,e=a.length,b=f.event.remove,m=f.removeData;c<e;c++)d=a[c],b(d),m(d)};f.css="defaultView"in document&&"getComputedStyle"in document.defaultView?function(a,c){return document.defaultView.getComputedStyle(a,!1)[c]}:function(a,c){return a.currentStyle[c]||""};f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(){var c=
        this[0],b;return(b=f.isWindow(c)?c:9===c.nodeType?c.defaultView||c.parentWindow:!1)?"pageXOffset"in b?b[a?"pageYOffset":"pageXOffset"]:b.document.documentElement[d]||b.document.body[d]:c[d]}});f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn[d]=function(a){var b=this[0];return!b?null==a?null:this:f.isWindow(b)?b.document.documentElement["client"+c]||b.document.body["client"+c]:9===b.nodeType?Math.max(b.documentElement["client"+c],b.body["scroll"+c],b.documentElement["scroll"+c],
        b.body["offset"+c],b.documentElement["offset"+c]):null}});return f})(window);
    (function(g,h,i){if("BackCompat"===document.compatMode)throw Error("artDialog: Document types require more than xhtml1.0");var f,p=0,o="artDialog"+ +new Date,a=h.VBArray&&!h.XMLHttpRequest,c="createTouch"in document&&!("onmousemove"in document)||/(iPhone|iPad|iPod)/i.test(navigator.userAgent),d=!a&&!c,e=function(b,a,n){b=b||{};if("string"===typeof b||1===b.nodeType)b={content:b,fixed:!c};var k;k=e.defaults;var r=b.follow=1===this.nodeType&&this||b.follow,t;for(t in k)b[t]===i&&(b[t]=k[t]);b.id=r&&
        r[o+"follow"]||b.id||o+p;if(k=e.list[b.id])return r&&k.follow(r),k.zIndex().focus(),k;if(!d)b.fixed=!1;if(!b.button||!b.button.push)b.button=[];if(a!==i)b.ok=a;b.ok&&b.button.push({id:"ok",value:b.okValue,callback:b.ok,focus:!0});if(n!==i)b.cancel=n;b.cancel&&b.button.push({id:"cancel",value:b.cancelValue,callback:b.cancel});e.defaults.zIndex=b.zIndex;p++;return e.list[b.id]=f?f.constructor(b):new e.fn.constructor(b)};e.version="5.0";e.fn=e.prototype={constructor:function(b){var a;this.closed=!1;
        this.config=b;this.dom=a=this.dom||this._getDom();b.skin&&a.wrap.addClass(b.skin);a.wrap.css("position",b.fixed?"fixed":"absolute");a.close[!1===b.cancel?"hide":"show"]();a.content.css("padding",b.padding);this.button.apply(this,b.button);this.title(b.title).content(b.content).size(b.width,b.height).time(b.time);b.follow?this.follow(b.follow):this.position();this.zIndex();b.lock&&this.lock();this._addEvent();this[b.visible?"visible":"hidden"]().focus();f=null;b.initialize&&b.initialize.call(this);
        return this},content:function(b){var a,c,e,d,f=this,v=this.dom.content,l=v[0];this._elemBack&&(this._elemBack(),delete this._elemBack);if("string"===typeof b)v.html(b);else if(b&&1===b.nodeType)d=b.style.display,a=b.previousSibling,c=b.nextSibling,e=b.parentNode,this._elemBack=function(){a&&a.parentNode?a.parentNode.insertBefore(b,a.nextSibling):c&&c.parentNode?c.parentNode.insertBefore(b,c):e&&e.appendChild(b);b.style.display=d;f._elemBack=null},v.html(""),l.appendChild(b),g(b).show();return this.position()},
        title:function(b){var a=this.dom,c=a.outer,a=a.title;!1===b?(a.hide().html(""),c.addClass("d-state-noTitle")):(a.show().html(b),c.removeClass("d-state-noTitle"));return this},position:function(){var b=this.dom,a=b.wrap[0],c=b.window,e=b.document,d=this.config.fixed,b=d?0:e.scrollLeft(),e=d?0:e.scrollTop(),d=c.width(),f=c.height(),g=a.offsetHeight,c=(d-a.offsetWidth)/2+b,d=d=(g<4*f/7?0.382*f-g/2:(f-g)/2)+e,a=a.style;a.left=Math.max(c,b)+"px";a.top=Math.max(d,e)+"px";return this},size:function(b,a){var c=
            this.dom.main[0].style;"number"===typeof b&&(b+="px");"number"===typeof a&&(a+="px");c.width=b;c.height=a;return this},follow:function(b){var a=g(b),c=this.config;if(!b||!b.offsetWidth&&!b.offsetHeight)return this.position(this._left,this._top);var d=c.fixed,e=o+"follow",f=this.dom,h=f.window,l=f.document,f=h.width(),h=h.height(),s=l.scrollLeft(),l=l.scrollTop(),j=a.offset(),a=b.offsetWidth,i=d?j.left-s:j.left,j=d?j.top-l:j.top,q=this.dom.wrap[0],p=q.style,u=q.offsetWidth,q=q.offsetHeight,w=i-(u-
            a)/2,x=j+b.offsetHeight,s=d?0:s,d=d?0:l;p.left=(w<s?i:w+u>f&&i-u>s?i-u+a:w)+"px";p.top=(x+q>h+d&&j-q>d?j-q:x)+"px";this._follow&&this._follow.removeAttribute(e);this._follow=b;b[e]=c.id;return this},button:function(){for(var b=this.dom.buttons,a=b[0],c=this._listeners=this._listeners||{},d=[].slice.call(arguments),e=0,f,h,l,i,j;e<d.length;e++){f=d[e];h=f.value;l=f.id||h;i=!c[l];j=!i?c[l].elem:document.createElement("input");j.type="button";j.className="d-button";c[l]||(c[l]={});if(h)j.value=h;if(f.width)j.style.width=
            f.width;if(f.callback)c[l].callback=f.callback;if(f.focus)this._focus&&this._focus.removeClass("d-state-highlight"),this._focus=g(j).addClass("d-state-highlight"),this.focus();j[o+"callback"]=l;j.disabled=!!f.disabled;if(i)c[l].elem=j,a.appendChild(j)}b[0].style.display=d.length?"":"none";return this},visible:function(){this.dom.wrap.css("visibility","visible");this.dom.outer.addClass("d-state-visible");this._isLock&&this._lockMask.show();return this},hidden:function(){this.dom.wrap.css("visibility",
            "hidden");this.dom.outer.removeClass("d-state-visible");this._isLock&&this._lockMask.hide();return this},close:function(){if(this.closed)return this;var b=this.dom,a=b.wrap,c=e.list,k=this.config.beforeunload,g=this.config.follow;if(k&&!1===k.call(this))return this;if(e.focus===this)e.focus=null;g&&g.removeAttribute(o+"follow");this._elemBack&&this._elemBack();this.time();this.unlock();this._removeEvent();delete c[this.config.id];if(f)a.remove();else{f=this;b.title.html("");b.content.html("");b.buttons.html("");
            a[0].className=a[0].style.cssText="";b.outer[0].className="d-outer";a.css({left:0,top:0,position:d?"fixed":"absolute"});for(var h in this)this.hasOwnProperty(h)&&"dom"!==h&&delete this[h];this.hidden()}this.closed=!0;return this},time:function(b){var a=this,c=this._timer;c&&clearTimeout(c);if(b)this._timer=setTimeout(function(){a._click("cancel")},b);return this},focus:function(){if(this.config.focus)try{var b=this._focus&&this._focus[0]||this.dom.close[0];b&&b.focus()}catch(a){}return this},zIndex:function(){var b=
            this.dom,a=e.focus,c=e.defaults.zIndex++;b.wrap.css("zIndex",c);this._lockMask&&this._lockMask.css("zIndex",c-1);a&&a.dom.outer.removeClass("d-state-focus");e.focus=this;b.outer.addClass("d-state-focus");return this},lock:function(){if(this._isLock)return this;var b=this,a=this.dom,c=document.createElement("div"),f=g(c),i=e.defaults.zIndex-1;this.zIndex();a.outer.addClass("d-state-lock");f.css({zIndex:i,position:"fixed",left:0,top:0,width:"100%",height:"100%",overflow:"hidden"}).addClass("d-mask");
            d||f.css({position:"absolute",width:g(h).width()+"px",height:g(document).height()+"px"});f.bind("click",function(){b._reset()});document.body.appendChild(c);this._lockMask=f;this._isLock=!0;return this},unlock:function(){if(!this._isLock)return this;this._lockMask.unbind();this._lockMask.hide();this._lockMask.remove();this.dom.outer.removeClass("d-state-lock");this._isLock=!1;return this},_getDom:function(){var b=document.body;if(!b)throw Error('artDialog: "documents.body" not ready');
            var a=document.createElement("div");a.style.cssText="position:absolute;left:0;top:0";a.innerHTML=e._templates;b.insertBefore(a,b.firstChild);for(var c=0,d={},f=a.getElementsByTagName("*"),i=f.length;c<i;c++)(b=f[c].className.split("d-")[1])&&(d[b]=g(f[c]));d.window=g(h);d.document=g(document);d.wrap=g(a);return d},_click:function(b){b=this._listeners[b]&&this._listeners[b].callback;return"function"!==typeof b||!1!==b.call(this)?this.close():this},_reset:function(){var b=this.config.follow;b?this.follow(b):
            this.position()},_addEvent:function(){var b=this,a=this.dom;a.wrap.bind("click",function(c){c=c.target;if(c.disabled)return!1;if(c===a.close[0])return b._click("cancel"),!1;(c=c[o+"callback"])&&b._click(c)}).bind("mousedown",function(){b.zIndex()})},_removeEvent:function(){this.dom.wrap.unbind()}};e.fn.constructor.prototype=e.fn;g.fn.dialog=g.fn.artDialog=function(){var b=arguments;this[this.live?"live":"bind"]("click",function(){e.apply(this,b);return!1});return this};e.focus=null;e.get=function(b){return b===
        i?e.list:e.list[b]};e.list={};g(document).bind("keydown",function(b){var a=b.target,c=a.nodeName,d=/^input|textarea$/i,f=e.focus,b=b.keyCode;f&&f.config.esc&&!(d.test(c)&&"button"!==a.type)&&27===b&&f._click("cancel")});g(h).bind("resize",function(){var b=e.list,a;for(a in b)b[a]._reset()});e._templates='<div class="d-outer"><table class="d-border"><tbody><tr><td class="d-nw"></td><td class="d-n"></td><td class="d-ne"></td></tr><tr><td class="d-w"></td><td class="d-c"><div class="d-inner"><table class="d-dialog"><tbody><tr><td class="d-header"><div class="d-titleBar"><div class="d-title"></div><a class="d-close" href="javascript:/*artDialog*/;"></a></div></td></tr><tr><td class="d-main"><div class="d-content"></div></td></tr><tr><td class="d-footer"><div class="d-buttons"></div></td></tr></tbody></table></div></td><td class="d-e"></td></tr><tr><td class="d-sw"></td><td class="d-s"></td><td class="d-se"></td></tr></tbody></table></div>';
        e.defaults={content:'<div class="d-loading"><span>数据加载中...</span></div>',title:"消息提示:",button:null,ok:null,cancel:null,initialize:null,beforeunload:null,okValue:"确定",cancelValue:"取消",width:"auto",height:"auto",padding:"20px 25px",skin:null,time:null,esc:!0,focus:false,visible:!0,follow:null,lock:true,fixed:true,zIndex:1987};this.artDialog=g.dialog=g.artDialog=e})(this.art||this.jQuery,this);
    (function(c){c.alert=c.dialog.alert=function(b,a){return c.dialog({id:"Alert",fixed:!0,lock:!0,content:b,ok:!0,beforeunload:a})};c.confirm=c.dialog.confirm=function(b,a,m){return c.dialog({id:"Confirm",fixed:!0,lock:!0,content:b,ok:a,cancel:m})};c.prompt=c.dialog.prompt=function(b,a,m){var d;return c.dialog({id:"Prompt",fixed:!0,lock:!0,content:['<div style="margin-bottom:5px;font-size:12px">',b,'</div><div><input type="text" class="d-input-text" value="',m||"",'"  /></div>'].join(""),
        initialize:function(){d=this.dom.content.find(".d-input-text")[0];d.select();d.focus()},ok:function(){return a&&a.call(this,d.value)},cancel:function(){}})};c.dialog.prototype.shake=function(){var b=function(a,b,c){var h=+new Date,e=setInterval(function(){var f=(+new Date-h)/c;1<=f?(clearInterval(e),b(f)):a(f)},13)},a=function(c,d,g,h){var e=h;void 0===e&&(e=6,g/=e);var f=parseInt(c.style.marginLeft)||0;b(function(a){c.style.marginLeft=f+(d-f)*a+"px"},function(){0!==e&&a(c,1===e?0:1.5*(d/e-d),g,--e)},
        g)};return function(){a(this.dom.wrap[0],10,300);return this}}();var o=function(){var b=this,a=function(a){var c=b[a];b[a]=function(){return c.apply(b,arguments)}};a("start");a("over");a("end")};o.prototype={start:function(b){c(document).bind("mousemove",this.over).bind("mouseup",this.end);this._sClientX=b.clientX;this._sClientY=b.clientY;this.onstart(b.clientX,b.clientY);return!1},over:function(b){this._mClientX=b.clientX;this._mClientY=b.clientY;this.onover(b.clientX-this._sClientX,b.clientY-this._sClientY);
        return!1},end:function(b){c(document).unbind("mousemove",this.over).unbind("mouseup",this.end);this.onend(b.clientX,b.clientY);return!1}};var j=c(window),k=c(document),i=document.documentElement,p=!!("minWidth"in i.style)&&"onlosecapture"in i,q="setCapture"in i,r=function(){return!1},n=function(b){var a=new o,c=artDialog.focus,d=c.dom,g=d.wrap,h=d.title,e=g[0],f=h[0],i=d.main[0],l=e.style,s=i.style,t=b.target===d.se[0]?!0:!1,u=(d="fixed"===e.style.position)?0:k.scrollLeft(),v=d?0:k.scrollTop(),n=
        j.width()-e.offsetWidth+u,A=j.height()-e.offsetHeight+v,w,x,y,z;a.onstart=function(){t?(w=i.offsetWidth,x=i.offsetHeight):(y=e.offsetLeft,z=e.offsetTop);k.bind("dblclick",a.end).bind("dragstart",r);p?h.bind("losecapture",a.end):j.bind("blur",a.end);q&&f.setCapture();g.addClass("d-state-drag");c.focus()};a.onover=function(a,b){if(t){var c=a+w,d=b+x;l.width="auto";s.width=Math.max(0,c)+"px";l.width=e.offsetWidth+"px";s.height=Math.max(0,d)+"px"}else c=Math.max(u,Math.min(n,a+y)),d=Math.max(v,Math.min(A,
        b+z)),l.left=c+"px",l.top=d+"px"};a.onend=function(){k.unbind("dblclick",a.end).unbind("dragstart",r);p?h.unbind("losecapture",a.end):j.unbind("blur",a.end);q&&f.releaseCapture();g.removeClass("d-state-drag")};a.start(b)};c(document).bind("mousedown",function(b){var a=artDialog.focus;if(a){var c=b.target,d=a.config,a=a.dom;if(!1!==d.drag&&c===a.title[0]||!1!==d.resize&&c===a.se[0])return n(b),!1}})})(this.art||this.jQuery);
    _path=window['_artDialog_path']||(function(script,i,me){_thisScript=me||script[script.length-1];me=_thisScript.src.replace(/\\/g,'/');return me.lastIndexOf('/')<0?'.':me.substring(0,me.lastIndexOf('/'));}(document.getElementsByTagName('script')));_skin=_thisScript.src.split('skin=')[1];if(_skin){var link=document.createElement('link');link.rel='stylesheet';link.href=_path+'/'+_skin+'.css';_thisScript.parentNode.insertBefore(link,_thisScript);};
    $.fn.extend({mousewheel:function(a){return this.each(function(){var b=this;b.D=0;if($.browser.msie||$.browser.safari){b.onmousewheel=function(){b.D=event.wheelDelta;event.returnValue=false;a&&a.call(b)}}else{b.addEventListener("DOMMouseScroll",function(c){b.D=c.detail>0?-1:1;c.preventDefault();a&&a.call(b)},false)}})}});$.fn.extend({jscroll:function(a){return this.each(function(){a=a||{};a.Bar=a.Bar||{};a.Btn=a.Btn||{};a.Bar.Bg=a.Bar.Bg||{};a.Bar.Bd=a.Bar.Bd||{};a.Btn.uBg=a.Btn.uBg||{};a.Btn.dBg=a.Btn.dBg||{};var d={W:"5px",BgUrl:"",Bg:"#fff",Bar:{Pos:"up",Bd:{Out:"#b5b5b5",Hover:"#ccc"},Bg:{Out:"#fff",Hover:"#fff",Focus:"orange"}},Btn:{btn:true,uBg:{Out:"#ccc",Hover:"#fff",Focus:"orange"},dBg:{Out:"#ccc",Hover:"#fff",Focus:"orange"}},Fn:function(){}};a.W=a.W||d.W;a.BgUrl=a.BgUrl||d.BgUrl;a.Bg=a.Bg||d.Bg;a.Bar.Pos=a.Bar.Pos||d.Bar.Pos;a.Bar.Bd.Out=a.Bar.Bd.Out||d.Bar.Bd.Out;a.Bar.Bd.Hover=a.Bar.Bd.Hover||d.Bar.Bd.Hover;a.Bar.Bg.Out=a.Bar.Bg.Out||d.Bar.Bg.Out;a.Bar.Bg.Hover=a.Bar.Bg.Hover||d.Bar.Bg.Hover;a.Bar.Bg.Focus=a.Bar.Bg.Focus||d.Bar.Bg.Focus;a.Btn.btn=a.Btn.btn!=undefined?a.Btn.btn:d.Btn.btn;a.Btn.uBg.Out=a.Btn.uBg.Out||d.Btn.uBg.Out;a.Btn.uBg.Hover=a.Btn.uBg.Hover||d.Btn.uBg.Hover;a.Btn.uBg.Focus=a.Btn.uBg.Focus||d.Btn.uBg.Focus;a.Btn.dBg.Out=a.Btn.dBg.Out||d.Btn.dBg.Out;a.Btn.dBg.Hover=a.Btn.dBg.Hover||d.Btn.dBg.Hover;a.Btn.dBg.Focus=a.Btn.dBg.Focus||d.Btn.dBg.Focus;a.Fn=a.Fn||d.Fn;var e=this;var m,u=0,w=0;$(e).css({overflow:"hidden",position:"relative",padding:"0px"});var l=$(e).width(),s=$(e).height()-1;var o=a.W?parseInt(a.W):21;var t=l-o;var r=a.Btn.btn==true?o:0;if($(e).children(".jscroll-c").height()==null){$(e).wrapInner("<div class='jscroll-c' style='top:0px;z-index:9999;zoom:1;position:relative'></div>");$(e).children(".jscroll-c").prepend("<div style='height:0px;overflow:hidden'></div>");$(e).append("<div class='jscroll-e' unselectable='on' style=' height:100%;top:0px;right:0;-moz-user-select:none;position:absolute;overflow:hidden;z-index:10000;'><div class='jscroll-u' style='position:absolute;top:0px;width:100%;left:0;background:blue;overflow:hidden'></div><div class='jscroll-h'  unselectable='on' style='background:green;position:absolute;left:0;-moz-user-select:none;border:1px solid'></div><div class='jscroll-d' style='position:absolute;bottom:0px;width:100%;left:0;background:blue;overflow:hidden'></div></div>")}var j=$(e).children(".jscroll-c");var h=$(e).children(".jscroll-e");var g=h.children(".jscroll-h");var b=h.children(".jscroll-u");var i=h.children(".jscroll-d");if($.browser.msie){document.execCommand("BackgroundImageCache",false,true)}j.css({"padding-right":o});h.css({width:o,background:a.Bg,"background-image":a.BgUrl});g.css({top:r,background:a.Bar.Bg.Out,"background-image":a.BgUrl,"border-color":a.Bar.Bd.Out,width:o-2});b.css({height:r,background:a.Btn.uBg.Out,"background-image":a.BgUrl});i.css({height:r,background:a.Btn.dBg.Out,"background-image":a.BgUrl});g.hover(function(){if(w==0){$(this).css({background:a.Bar.Bg.Hover,"background-image":a.BgUrl,"border-color":a.Bar.Bd.Hover})}},function(){if(w==0){$(this).css({background:a.Bar.Bg.Out,"background-image":a.BgUrl,"border-color":a.Bar.Bd.Out})}});b.hover(function(){if(w==0){$(this).css({background:a.Btn.uBg.Hover,"background-image":a.BgUrl})}},function(){if(w==0){$(this).css({background:a.Btn.uBg.Out,"background-image":a.BgUrl})}});i.hover(function(){if(w==0){$(this).css({background:a.Btn.dBg.Hover,"background-image":a.BgUrl})}},function(){if(w==0){$(this).css({background:a.Btn.dBg.Out,"background-image":a.BgUrl})}});var c=j.height();var v=(s-2*r)*s/c;if(v<10){v=10}var f=v/6;var k=0,q=false;g.height(v);if(c<=s){j.css({padding:0});h.css({display:"none"})}else{q=true}if(a.Bar.Pos!="up"){k=s-v-r;p()}g.bind("mousedown",function(z){a.Fn&&a.Fn.call(e);w=1;g.css({background:a.Bar.Bg.Focus,"background-image":a.BgUrl});var y=z.pageY,x=parseInt($(this).css("top"));$(document).mousemove(function(A){k=x+A.pageY-y;p()});$(document).mouseup(function(){w=0;g.css({background:a.Bar.Bg.Out,"background-image":a.BgUrl,"border-color":a.Bar.Bd.Out});$(document).unbind()});return false});b.bind("mousedown",function(x){a.Fn&&a.Fn.call(e);w=1;b.css({background:a.Btn.uBg.Focus,"background-image":a.BgUrl});e.timeSetT("u");$(document).mouseup(function(){w=0;b.css({background:a.Btn.uBg.Out,"background-image":a.BgUrl});$(document).unbind();clearTimeout(m);u=0});return false});i.bind("mousedown",function(x){a.Fn&&a.Fn.call(e);w=1;i.css({background:a.Btn.dBg.Focus,"background-image":a.BgUrl});e.timeSetT("d");$(document).mouseup(function(){w=0;i.css({background:a.Btn.dBg.Out,"background-image":a.BgUrl});$(document).unbind();clearTimeout(m);u=0});return false});e.timeSetT=function(z){var x=this;if(z=="u"){k-=f}else{k+=f}p();u+=2;var y=500-u*50;if(y<=0){y=0}m=setTimeout(function(){x.timeSetT(z)},y)};h.bind("mousedown",function(x){a.Fn&&a.Fn.call(e);k=k+x.pageY-g.offset().top-v/2;n();return false});function n(){if(k<r){k=r}if(k>s-v-r){k=s-v-r}g.stop().animate({top:k},100);var x=-((k-r)*c/(s-2*r));j.stop().animate({top:x},1000)}function p(){if(k<r){k=r}if(k>s-v-r){k=s-v-r}g.css({top:k});var x=-((k-r)*c/(s-2*r));j.css({top:x})}$(e).mousewheel(function(){if(q!=true){return}a.Fn&&a.Fn.call(e);if(this.D>0){k-=f}else{k+=f}p()})})}});
    
    
    
    ================================================
    FILE: js/jQuery.im.js
    ================================================
    ;(function($){
        $.fn.extend({
            //将可选择的变量传递给方法
            FnWebIM: function(options) {
                //设置默认值并用逗号隔开
                var defaults = {
                    autoLogin          :true,      //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true
                    msgRefreshTime    :1000,       //number型,消息刷新时间,单位为ms
                    friendRefreshTime :10000,     //number型,好友刷新时间,单位为ms
                    showSecretary     :true,      //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true
                    noticeContent     :"",        //string型,公告内容 为空时不显示公告
                    sendPicture       :true,      //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true
                    msgMaxSize        :300,        //number型,单条消息最大允许字符
                    msgSound           :true,      //是否开启声音提醒
                    defaultWindow     :""         //string型,登录后打开新聊天窗口,从用户点击的链接接收参数
                }
                var options =  $.extend(defaults, options);
                return this.each(function() {
                    //显示fn_imbar
                    $("body").append('<div id="fn_imbar" class="im_login"><span>在线交流工具<b title="3条未读消息">3</b></span></div><div id="fn_imbox"></div>');
    
                    $("#fn_imbar.im_login").click(function(){
                        $(this).attr("class","im_loading").find("span").html("登录中,请稍后…");
                        /************************联系人面板****************************/
                        $.ajax({url:"ajax/im_contact.html",dataType:"html",success:loginIM,error:loginError});
                        function loginIM(data){
                            //显示联系人面板
                            $("#fn_imbox").html(data).show();
                            //装配联系人数据
                            Friends();
                            $("#fn_imbar").hide();
                            $("#fn_imbox .im_top h4").toggle(function(){//收起联系人面板
                                $("#fn_imbox").animate({height: 30}, 800);
                                $("#fn_imbox .im_bottombar ul").hide();
                            },function(){//展开联系人面板
                                $("#fn_imbox").animate({height: 360}, 800);
                            });
    
                            //修改资料
                            $("#fn_imbox .im_top a.modify").click(function(){
                                $.ajax({url:"ajax/msgbox.html",dataType:"html",success:function(data){
                                    art.dialog({title:"消息盒子",padding:0,content:data,ok:function(){}});
                                    $("#im_msgboxs").jscroll();
                                    $("dl.im_msgbox dd.im_msginfo").click(function(){
                                        var uid=$(this).attr("uid");
                                        $.ajax({url:"ajax/im_window.html",dataType:"html",success:function(data){
                                            var uid=$(this).attr("uid");
                                            $.getJSON("ajax/userinfo.php?uid="+uid,function(json){
                                                //打开新窗口
                                                openWindow(json[0].cid,json[0].UID,json[0].isOnline,json[0].UserAvatar,json[0].cname,json[0].UserName,data);
                                            });
                                        },error:function(XMLHttpRequest, textStatus, errorThrown){
                                            message("对不起,聊天窗口加载失败! CODE:"+XMLHttpRequest.status);
                                        }});
                                    });
                                    $("dl.im_msgbox dt, dl.im_msgbox .msg_contact").click(function(){
                                        card($(this).attr("uid"));
                                    });
                                },error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("消息窗口加载失败,请重试!CODE:"+XMLHttpRequest.status);
                                }});
                            });
    
    
                            //好友分组
                            $("#fn_imbox .im_contents h4").click(function(){
                                $(this).attr("class","im_group_expansion").siblings("h4").attr("class","im_group_away").siblings(".im_group_contacts").hide();
                                $(this).next(".im_group_contacts").show().jscroll();//显示滚动条
                            });
                            //好友搜索
                            $("#fn_imbox .im_bottombar input").focus(function(){
                                if($(this).val()=="查找联系人"){
                                    $(this).val("");
                                }
                                //$(this).die().live('keyup',function(){
                                //    var contactNum=$(this).parents("#fn_imbox").find(".im_contact span").size(),
                                //         searchTxt=$(this).val();
                                //    if(contactNum!=0 && $.trim(searchTxt).length!=0){
                                //        for(var i=0;i<contactNum;i++){
                                //            var contactName=$(this).parents("#fn_imbox").find(".im_contact span").eq(i).text();
                                //            if(contactName.indexOf(searchTxt)!=-1){
                                //               $(this).parents("#fn_imbox").find(".im_contact span").eq(i).parents(".im_contact").hide();
                                //           }
                                //        }
                                //    }
                                //});
                            }).blur(function(){
                                    if($(this).val()==""){
                                        $(this).val("查找联系人");
                                    }
                                });
                            //设置选项
                            $("#fn_imbox .im_bottombar span").toggle(function(){
                                $(this).addClass("current").parent().find("ul").fadeIn();
                            },function(){
                                $(this).removeClass("current").parent().find("ul").hide();
                            });
    //                            $("#fn_imbox .im_bottombar li.selected:not('.smssub')").click(function(){
    //                                if($(this).hasClass("current")){
    //                                    $(this).removeClass("current");
    //                                }
    //                                else{
    //                                    $(this).addClass("current");
    //                                }
    //                                //提交用户设置数据
    //                            });
    //                        $("#fn_imbox .im_bottombar li.smssub").click(function(){
    //                            art.alert("您还没有开通短信小秘书功能,请先开通。 <a href='#' target='_blank'>开通&gt;</a> ");
    //                        });
                            $("#fn_imbox .im_bottombar li.setting").click(function(){
                                modify();
                            });
                            $("#fn_imbox .im_bottombar li.backlist").click(function(){
                                $.ajax({url:"ajax/friends.html",dataType:"html",success:function(data){
                                    art.dialog({title:"查看黑名单",padding:0,content:data,ok:function(){
    
                                    }});
                                    $(".im_friendsbox").jscroll();
                                    $(".im_friendsbox dt, .im_friendname").click(function(){
                                        card($(this).attr("uid"));
                                    });
                                    $("a.im_addcontact").click(function(){
                                        $(this).parents("dl").fadeOut();
                                        message("好友添加成功!");
                                    });
                                },error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("黑名单面板加载失败,请重试!CODE:"+XMLHttpRequest.status);
                                }});
                            });
                            $("#fn_imbox .im_bottombar li.friends").click(function(){
                                $.ajax({url:"ajax/friends.html",dataType:"html",success:function(data){
                                    art.dialog({title:"推荐好友",padding:0,content:data,ok:function(){
    
                                    }});
                                    $(".im_friendsbox").jscroll();
                                    $(".im_friendsbox dt, .im_friendname").click(function(){
                                        card($(this).attr("uid"));
                                    });
                                    $("a.im_addcontact").click(function(){
                                        Friends();
                                        $(this).parents("dl").fadeOut();
                                        message("好友添加成功!");
                                    });
                                },error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("推荐好友面板加载失败,请重试!CODE:"+XMLHttpRequest.status);
                                }});
                            });
                            $("#fn_imbox .im_bottombar li.loginout").click(function(){
                                art.confirm("您确定要退出本次登录吗?",function(){
                                    loginTimeOut();
                                    message("注销成功!");
    
                                },function(){
    
                                });
                            });
                            //会话超时
                            function loginTimeOut(){
                                $.ajax({url:"ajax/login.html",dataType:"html",success:function(data){
                                    art.dialog({title:"会话超时,请重新登录!",content:data,okValue:"登录",ok:function(){
                                        message("登录成功!");
                                    },cancel:function(){
                                        message("登录已取消!");
                                    }});
                                },error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("登录面板获取失败!CODE:"+XMLHttpRequest.status);
                                }});
                            }
                            //加载聊天窗口
                            $.ajax({url:"ajax/im_window.html",dataType:"html",success:function(data){
                                if(options.defaultWindow!=""){
                                    $.getJSON("ajax/userinfo.php?uid="+options.defaultWindow,function(json){
                                        //打开新窗口
                                        openWindow(json[0].cid,json[0].UID,json[0].isOnline,json[0].UserAvatar,json[0].cname,json[0].UserName,data);
                                    });
                                }
                                $(".im_contact").click(function(){
                                    //选中联系人
                                    $(".im_contact").removeClass("current");
                                    $(this).addClass("current");
                                    //清除消息提示
                                    $(this).find("b").remove();
                                    //阻止全选
                                    this.onselectstart=function(){return false};
                                    var uid=$(this).attr("uid");
                                    $.getJSON("ajax/userinfo.php?uid="+uid,function(json){
                                        //打开新窗口
                                        openWindow(json[0].cid,json[0].UID,json[0].isOnline,json[0].UserAvatar,json[0].cname,json[0].UserName,data);
                                    });
                                    //清除消息提示
                                    if($(".im_contents").has("b").length==0){
                                        noMsg();
                                    }
                                });
                            },error:function(XMLHttpRequest, textStatus, errorThrown){
                                message("对不起,聊天窗口加载失败! CODE:"+XMLHttpRequest.status);
                            }});
                        }
                        function loginError(XMLHttpRequest, textStatus, errorThrown){
                            art.alert("登录超时,请重新登录! CODE:"+XMLHttpRequest.status,function(){loginTimeOut();});
                        }
                        /****装配联系人数据****/
                        function Friends(){
                            $("#imRencentContacts,#imFriends").html("");
                            //凡纳小秘书
                            if(options.showSecretary){
                                $("#imFriends").append('<div class="im_contact online"  uid=""><i><img src="../img/avatar_s-sys.png" width="30" height="30" /><sup></sup></i><span>凡纳小秘书</span><a href="#" target="_blank"></a></div>');
                            }
                            $.getJSON("ajax/friends.php",function(json){
                                for(var i=0;i<json[0].RencentContacts.length;i++){
                                    $("#imRencentContacts").append('<div class="im_contact '+json[0].RencentContacts[i].o+'" uid="'+json[0].RencentContacts[i].uid+'"><i><img src="'+json[0].RencentContacts[i].a+'" width="30" height="30" /><sup></sup></i><span>'+json[0].RencentContacts[i].n+'</span><a href="'+json[0].RencentContacts[i].h+'" target="_blank"></a></div>');
                                    if(json[0].RencentContacts[i].m!=0){
                                        $("#imRencentContacts .im_contact:eq("+i+")").find("span").append("<b></b>");
                                    }
                                }
    
                                for(var i=0;i<json[0].Friends.length;i++){
                                    $("#imFriends").append('<div class="im_contact '+json[0].Friends[i].o+'" uid="'+json[0].Friends[i].uid+'"><i><img src="'+json[0].Friends[i].a+'" width="30" height="30" /><sup></sup></i><span>'+json[0].Friends[i].n+'</span><a href="'+json[0].Friends[i].h+'" target="_blank"></a></div>');
                                    if(json[0].RencentContacts[i].m!=0){
                                        $("#imFriends .im_contact:eq("+i+")").find("span").append("<b></b>");
                                    }
                                }
                                var Scroll=function(){$(".im_contacts").jscroll();}//显示滚动条
                                Scroll();
                                $("#imRencentContacts").prev("h4").find("i").html("("+json[0].RencentContactsOnline+"/"+json[0].RencentContacts.length+")");
                                $("#imFriends").prev("h4").find("i").html("("+json[0].FriendsOnline+"/"+json[0].Friends.length+")");
                                if(json[0].RencentContactsOnline!=0&&json[0].FriendsOnline!=0){
                                   newMsg();//新消息提醒
                                }
                            });
    
                        }
                        /****打开新聊天窗口****/
                        function openWindow(cid,uid,o,a,n,c,m){
                            var t='<div class="im_contactinfobar"><a class="im_avatar" '+o+' href="javascript:;" uid="'+uid+'"><img src="'+a+'"  width="50" height="50" /></a><span class="im_contactinfo"><a class="im_contactcompany" href="javascript:;" cid="'+cid+'">'+n+'</a> - <a class="im_contact"  id="contactcard" href="javascript:;" uid="'+uid+'">'+c+'</a><a class="im_addcontact" id="imcontact"  href="javascript:;" title="添加好友">&nbsp;</a></span></div>';
                            //关闭上一个聊天窗口
                            art.dialog({id:"msgWindow"}).close();
                            //创建新聊天窗口
                            art.dialog({id:"msgWindow",padding:"0",lock:false,title:t,content:m});
                            //显示公告内容
                            if(options.noticeContent!=""){
                                $(".im_chats .im_morechats").before('<div class="im_notice"><span>'+options.noticeContent+'</span><a href="javascript:;" class="im_notice_close"></a></div>');
                            }
                            //操作当前聊天窗口
                            operatewindow();
                            //加载聊天记录
                            msgList();
                        }
                        /****加载聊天记录****/
                        function msgList(){
                            $.getJSON("ajax/chats.php",function(json){
                                $.each(json,function(i){
                                    if(json[i].T=="0"){
                                        $(".im_chats .im_chat_content:last").after('<div class="im_chat_content"><i>'+json[i].D+'</i><div class="im_chat_txt">'+json[i].M+'</div></div>');
                                    }
                                    else if(json[i].T=="1"){
                                        $(".im_chats .im_chat_content:last").after('<div class="im_chat_content myself"><i>'+json[i].D+'</i><div class="im_chat_txt">'+json[i].M+'</div></div>');
                                    }
    
                                });
                                //滚动条显示
                                $(".im_chats").jscroll();
                                //滚动条显示->聊天记录中有图片的情况
                                var imgSize=$(".im_chats img").size();
                                $(".im_chats img").load(function(){
                                    if(!--imgSize){
                                        $(".im_chats").jscroll();
                                    }
                                })
                            });
                        }
                        /****聊天窗口选项****/
                        function operatewindow(){
                            //表情面板
                            $(".im_face").click(function(){
                                var _this=$(this).parent().find("#im_face");
                                _this.show();
                                $.ajax({url:"ajax/im_face.html",success:function(data){
                                    _this.html(data).find(".im_faceclose,.im_faceico a").click(function(){
                                        $("#im_face").hide();
                                    });
                                    _this.find(".im_faceico a").click(function(){
                                        //取到表情代码  $(this).attr("code")
                                        $("#im_window .im_send_msg").html($("#im_window .im_send_msg").html()+$(this).html()).click();
                                    });
                                },dataType:"html",error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("表情面板获取失败,请重试!CODE:"+XMLHttpRequest.status)
                                }});
                            });
                            //发送图片
                            if(options.sendPicture=false){
                                $(".im_upload_pic").remove();
                            }
                            $(".im_upload_pic").click(function(){
                                art.alert("需要用jQuery Ajax上传插件。");
                            });
                            //发送抖动
                            var lastshakeTime;
                            $(".im_shake").click(function(){
                                var shakeTime=new Date().getTime();
                                if(typeof lastshakeTime=="undefined"){
                                    sendShake();
                                    lastshakeTime=shakeTime;
                                }
                                else{
                                    if((shakeTime-lastshakeTime)>=10000){
                                        sendShake();
                                    }
                                    else{
                                        message("喝杯茶休息下吧,您的操作太频繁了!");
                                    }
                                    lastshakeTime=shakeTime;
                                }
    
                            });
                            //发送产品
                            $(".im_product").click(function(){
                                art.prompt('请输入您的在凡纳网的产品网址 (<a href="javascript:;" title="① 打开您想要发送的的产品页面,\n② 复制地址栏里的地址粘贴到下面文本框即可。\n注意:必须为凡纳网的产品地址">?</a>):', function (value) {
                                    var fnURL=new RegExp(/^http:\/\/[A-Za-z0-9|_|-]*.?fanna.com.cn\/(productdetails|p)_[0-9]*[.htmls]/);
                                    if(fnURL.test(value)==true){
                                        var pid=value.substring((value.lastIndexOf('_')+1),value.lastIndexOf("."));
                                        /*************************加载产品信息************************/
                                        $.ajax({url:"ajax/product.html?pid="+pid,dataType:"html",success:function(data){
                                            $(".im_chats .im_chat_content:last").after('<div class="im_chat_content myself"><i>'+msgTime+'</i><div class="im_chat_txt" style="min-height:90px"><em>您发送了一件产品给对方……</em>'+data+'</div></div>');
                                            $(".im_chats").jscroll({Bar:{Pos:"bottom"}});
                                            //此处提价用户消息至服务器 msgTime+data
    
                                            $("a.im_product_favorites").click(function(){
                                                message("收藏成功!");
                                                $(this).remove();
                                            });
                                            $("a.im_product_share").click(function(){
                                                $.ajax({url:"ajax/share.html",dataType:"html",success:function(data){
                                                    art.dialog({title:"分享到:",content:data,ok:function(){}});
                                                },error:function(XMLHttpRequest, textStatus, errorThrown){
                                                    message("分享内容面板加载失败,请重试!CODE"+XMLHttpRequest.status);
                                                }});
                                            });
                                        },error:function(XMLHttpRequest, textStatus, errorThrown){
                                            message("产品信息获取失败,请重试!CODE:"+XMLHttpRequest.status);
                                        }});
                                    }
                                    else{
                                        this.shake().title("您输入的网址有误,请重新输入!");
                                        return false;
                                    }
                                }, '如:http://www.fanna.com.cn/productdetails_00000000.htmls');
                            });
                            //发送名片
                            $(".im_card").click(function(){
                                $.ajax({url:"ajax/card.html",success:function(data){
                                    art.dialog({content:data,title:"名片预览",okValue:"发送名片",ok:function(){
                                        $(".im_chats .im_chat_content:last").after('<div class="im_chat_content myself"><i>'+msgTime+'</i><div class="im_chat_txt" style="min-height:90px"><em>您发送了自己的名片给对方……</em><div class="im_mycard">'+data+'<p><a href="javascript:;" class="cc atocard">收藏到名片夹</a><a href="javascript:;" class="cc aqrcode">添加到手机通讯录</a></p></div></div></div>');
                                        $(".im_chats").jscroll({Bar:{Pos:"bottom"}});
                                        //提交数据
                                        message("名片发送成功!");
                                        $("a.atocard").click(function(){
                                            message("收藏成功!");
                                            $(this).remove();
                                        });
                                        $("a.aqrcode").click(function(){
                                            cardQRcode($(".im_contactcard"));
                                        });
                                    },button:[{value:"修改名片",callback:function(){
                                        modify();
                                        return false;
                                    }}]});
                                },dataType:"html",error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("名片信息获取失败,请重试!CODE:"+XMLHttpRequest.status);
                                }});
    
                            });
                            //更多设置
                            $("a.im_moreoperates").click(function(){
                                $(".im_moreoperate").animate({height:"28px",marginTop:"-28px"},400);
                                $("a.im_abacklist").click(function(){
                                    art.confirm("您确定要将该好友加入黑名单吗?",function(){
                                        message("您已经将该好友加入了黑名单!");
                                    },function(){})
                                });
                                $("a.im_areport").click(function(){
                                    art.confirm("您确定要举报该好友吗?",function(){
                                        art.dialog({title:"请填写举报原因:",padding:"0",content:"<iframe width='400' scrolling='no' height='215' src='ajax/report.html' frameborder='0'></iframe> ",ok:function(){
                                            //提交数据
                                            message("举报成功,我们会尽快核实");
                                        },cancel:function(){
    
                                        }});
                                    },function(){})
                                });
                                $("a.im_aemptyrecords").click(function(){
                                    art.confirm("您确定清空与该好友的聊天记录吗?",function(){
                                        //清空聊天记录
                                        $.post('ajax/chats.php', function(data) {
                                            //重新加载聊天内容
                                            $(".im_chats .im_chat_content:gt(0)").remove();
                                            msgList();
                                        });
                                    },function(){})
                                });
                            });
                            $(".im_moreoperate .im_aclose,.im_send_msg").click(function(){
                                $(".im_moreoperate").animate({height:0,marginTop:"0"},200);
                            });
                            //发送留言
                            $("#im_window .im_send_msg").die().live("focus",function(){
                                $(document).die().live("keypress",function(e){
                                    if(e.ctrlKey && e.which == 13 || e.which == 10) {
                                        sendMsg();
                                    }
                                });
                            });
                            $("#im_window .im_sendmsg_btn").click(function(){
                                sendMsg();
                            });
    
                            //公司信息面板
                            $(".im_contactcompany").click(function(){
                                $.ajax({url:"ajax/companyinfo.html?"+$(this).attr("cid"),dataType:"html",success:function(data){
                                    $(".im_contactinfos").html(data).jscroll();
                                    $(".im_companyFav").click(function(){
                                        message("收藏成功!");
                                        $(this).parent().html("已收藏");
                                    });
                                },error:function(XMLHttpRequest, textStatus, errorThrown){
                                    message("公司信息获取失败,请重试!CODE"+XMLHttpRequest.status);
                                }});
                                $("#im_contactinfo").show();
                                $("#im_contactinfo .d-close").click(function(){
                                    $("#im_contactinfo").hide();
                                });
                            });
                            //联系人名片
                            $("#contactcard,.im_avatar").click(function(){
                                card($(this).attr("uid"));
                            });
                            //关闭主窗体
                            $("#im_body .im_close,#im_body .im_minimize").click(function(){
                                $("#im_window").hide();
                            });
                            //关闭公告
                            $("a.im_notice_close").click(function(){
                                $(this).parent().hide();
                                $(".im_chats").jscroll();
                            });
                            //查看聊天记录
                            $(".im_morechats").click(function(){
                                //加载聊天记录
                                msgList();
                                $(".im_chats").jscroll();
                            });
                            //添加好友
                            $("#imcontact").click(function(){
                                if($(this).hasClass("im_addcontact")){
                                    art.confirm('您确定要将对方添加为好友吗?', function () {
                                        //提交数据并刷新联系人列表
                                        Friends();
                                        $("#imcontact").attr({"class":"im_removecontact","title":"删除好友"});
                                        message("添加好友成功!");
                                    },function(){});
                                }
                                else{
                                    art.confirm('您确定要将对方从好友列表中删除吗?', function () {
                                        //提交数据并刷新联系人列表
                                        Friends();
                                        $("#imcontact").attr({"class":"im_addcontact","title":"加为好友"});
                                        message("删除好友成功!");
                                    },function(){});
                                }
    
                            });
                        }
                        /****发送窗口抖动****/
                        function sendShake(){
                            art.dialog.get("msgWindow").shake();
                            $(".im_chats .im_chat_content:last").after('<div class="im_chat_content myself"><i>'+msgTime+'</i><div class="im_chat_txt"><em>您发送了一个抖动窗口…</em></div></div>');
                            $(".im_chats").jscroll({Bar:{Pos:"bottom"}});
                        }
                        /****发送消息****/
                        function sendMsg(){
                            //消息发送
                            var msgContent=$("#im_window .im_send_msg");
                            if(msgContent.html().length!=0&&msgContent.html().length<options.msgMaxSize){
                                $(".im_chats .im_chat_content:last").after('<div class="im_chat_content myself"><i>'+msgTime+'</i><div class="im_chat_txt">'+msgContent.html()+'</div></div>');
                                $(".im_chats").jscroll({Bar:{Pos:"bottom"}});
                                urlFilter();
                                msgContent.html("").click();
                                //此处提价用户消息至服务器
                            }
                            else if(msgContent.html().length==0){
                                message("对不起,消息不能为空!");
                                msgContent.click();
                            }
                            else{
                                message("对不起,您输入的字数超过限制!");
                            }
                        }
                        /****网址过滤****/
                        function urlFilter(){
                            var msgRecord = $(".im_chats .im_chat_content:last"),urls;
                            try{
                                urls=msgRecord.html().match(/http:\/\/[A-Za-z0-9|_|-]*.?fanna.com.cn\/[0-9a-z_!~*'().;?:@&=+$,%#-]*/gi);
                                for(var i=0;i<urls.length;i++){
                                    msgRecord.html(msgRecord.html().replace(urls[i], '<a class="fn_url" href="'+urls[i]+'" target="_blank" title="凡纳网官方网站,没有安全风险">'+urls[i]+'</a>'));
                                }
                            }catch(ex){}
                        }
                        /****消息发送时间,可能需要改为服务器时间****/
                        var msgTime=msgDate();
                        function msgDate(){
                            //系统时间,需改为服务器时间
                            var msgDate= new Date();
                            return (parseInt(msgDate.getMonth())+1)+"-"+msgDate.getDate()+" "+msgDate.getHours()+":"+msgDate.getMinutes()+":"+msgDate.getSeconds();
                        }
                        /****新消息提示****/
                        function newMsg(){
                            $("#fn_imbox .im_top h4").addClass("im_newmsg");
                            if(options.msgSound){
                                $("body").append('<object type="application/x-shockwave-flash" data="sound/msg.swf" width="10" height="10" id="newMessage" style="overflow: hidden;"><param name="movie" value="sound/msg.swf" /></object>');
                                setTimeout(function(){$("#newMessage").remove()},3000);
                            }
                        }
                        /****清除新消息提示****/
                        function noMsg(){
                            $("#fn_imbox .im_top h4").removeClass("im_newmsg");
                        }
                        /****修改资料****/
                        function modify(){
                            $.ajax({url:"ajax/set.html",dataType:"html",success:function(data){
                                art.dialog({title:"修改我的资料:",content:data,okValue:"提交修改",cancelValue:"取消",
                                    ok:function(){
                                        message("资料修改成功!");
                                    },cancel:function(){
    
                                    }});
                            },error:function(XMLHttpRequest, textStatus, errorThrown){
                                message("设置面板加载失败!CODE:"+XMLHttpRequest.status);
                            }});
    
                        }
                        /****用户名片****/
                        function card(uid){
                            $.ajax({url:"ajax/card.html?uid="+uid,dataType:"html",success:function(data){
                                art.dialog({content:data,title:false,okValue:"收藏该名片",ok:function(){
                                    message("收藏成功!您可以从“我的名片夹”查看该名片。</a>");
                                },button:[{value:"添加到手机通讯录",callback:function(){
                                    cardQRcode($(".im_contactcard"));
                                    return false;
                                }}]});
                            },error:function(XMLHttpRequest, textStatus, errorThrown){
                                message("名片信息获取失败,请重试!CODE:"+XMLHttpRequest.status);
                            }});
                        }
                        /****名片二维码****/
                        function cardQRcode(pNode){
                            var QRcode={
                                Name:pNode.find("dt b").text(),
                                Title:pNode.find("dt i").text(),
                                Department:pNode.find("dt span").text(),
                                Company:$("").text(),//公司名称
                                Zipcode:pNode.find(".zipcode i").text(),
                                Phone:pNode.find(".phone i").text(),
                                Fax:pNode.find(".fax i").text(),
                                Mobile:pNode.find(".mobile i").text(),
                                WebSite:pNode.find(".website i").text()
                            }
                            var QRcodeURL="http://www.mayacode.com/api.php?uid=1&from=maya&v=1&f=1&t=1&sid=01&Name="+QRcode.Name+"&Title="+QRcode.Title+"&Department="+QRcode.Department+"&Company="+QRcode.Company+"&Zipcode="+QRcode.Zipcode+"&Phone="+QRcode.Phone+"&Fax="+QRcode.Fax+"&Mobile="+QRcode.Mobile+"&WebSite="+QRcode.WebSite;
                            var Qrcode="<img src="+window.encodeURI(QRcodeURL)+" style='margin:-20px -25px' height='306' width='306' />";
                            art.dialog({title:false,content:Qrcode});
                        }
                        /****全局信息提示****/
                        function message(c){
                            art.dialog({time: 2000,padding:0,title:false,lock:false,content:"<div class='im_infos'><p>"+c+"</p></div>",cancel:false});
                        }
                    });
                    if(options.autoLogin||options.defaultWindow!=""){ $("#fn_imbar.im_login").click();}
                });
            }
        });
    
    })(jQuery);
    /****禁止粘贴****/
    function msgPaste(){
        art.dialog({time: 2000,padding:0,title:false,lock:false,content:"<div class='im_infos'><p>为营造一个良好的网络环境,暂不允许粘贴!</p></div>",cancel:false});
    }
    
    
    
    
    
    ================================================
    FILE: set/Jcrop/css/jquery.Jcrop.css
    ================================================
    /* jquery.Jcrop.css v0.9.10 - MIT License */
    
    /*
      The outer-most container in a typical Jcrop instance
      If you are having difficulty with formatting related to styles
      on a parent element, place any fixes here or in a like selector
    
      You can also style this element if you want to add a border, etc
      A better method for styling can be seen below with .jcrop-light
      (Add a class to the holder and style elements for that extended class)
    */
    .jcrop-holder {
      direction: ltr;
      text-align: left;
    }
    
    /* These styles define the border lines */
    .jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif) top left repeat;font-size:0;position:absolute;}
    .jcrop-vline{height:100%;width:1px!important;}
    .jcrop-hline{height:1px!important;width:100%;}
    .jcrop-vline.right{right:0;}
    .jcrop-hline.bottom{bottom:0;}
    
    /* Handle style - size is set by Jcrop handleSize option (currently) */
    .jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}
    
    /* This style is used for invisible click targets */
    .jcrop-tracker
    {
      height: 100%; 
      width: 100%;
      -webkit-tap-highlight-color: transparent; /* "turn off" link highlight */
      -webkit-touch-callout: none;              /* disable callout, image save panel */
      -webkit-user-select: none;                /* disable cut copy paste */
    }
    
    /* Positioning of handles and drag bars */
    .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
    .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
    .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
    .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
    .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
    .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
    .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
    .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
    .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
    .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
    .jcrop-dragbar.ord-n{margin-top:-4px;}
    .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
    .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
    .jcrop-dragbar.ord-w{margin-left:-4px;}
    
    /* The "jcrop-light" class/extension */
    .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline
    {
    	background:#FFF;
    	filter:Alpha(opacity=70)!important;
    	opacity:.70!important;
    }
    .jcrop-light .jcrop-handle
    {
    	-moz-border-radius:3px;
    	-webkit-border-radius:3px;
    	background-color:#000;
    	border-color:#FFF;
    	border-radius:3px;
    }
    
    /* The "jcrop-dark" class/extension */
    .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline
    {
    	background:#000;
    	filter:Alpha(opacity=70)!important;
    	opacity:.7!important;
    }
    .jcrop-dark .jcrop-handle
    {
    	-moz-border-radius:3px;
    	-webkit-border-radius:3px;
    	background-color:#FFF;
    	border-color:#000;
    	border-radius:3px;
    }
    
    /* Fix for twitter bootstrap et al. */
    .jcrop-holder img,img.jcrop-preview{ max-width: none; }
    
    
    ================================================
    FILE: set/Jcrop/demos/crop.php
    ================================================
    <?php
    
    /**
     * Jcrop image cropping plugin for jQuery
     * Example cropping script
     * @copyright 2008-2009 Kelly Hallman
     * More info: http://deepliquid.com/content/Jcrop_Implementation_Theory.html
     */
    
    if ($_SERVER['REQUEST_METHOD'] == 'POST')
    {
    	$targ_w = $targ_h = 150;
    	$jpeg_quality = 90;
    
    	$src = 'demo_files/pool.jpg';
    	$img_r = imagecreatefromjpeg($src);
    	$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
    
    	imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
    	$targ_w,$targ_h,$_POST['w'],$_POST['h']);
    
    	header('Content-type: image/jpeg');
    	imagejpeg($dst_r,null,$jpeg_quality);
    
    	exit;
    }
    
    // If not a POST request, display page below:
    
    ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    
    		<script src="../js/jquery.min.js"></script>
    		<script src="../js/jquery.Jcrop.js"></script>
    		<link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
    		<link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
    
    		<script language="Javascript">
    
    			$(function(){
    
    				$('#cropbox').Jcrop({
    					aspectRatio: 1,
    					onSelect: updateCoords
    				});
    
    			});
    
    			function updateCoords(c)
    			{
    				$('#x').val(c.x);
    				$('#y').val(c.y);
    				$('#w').val(c.w);
    				$('#h').val(c.h);
    			};
    
    			function checkCoords()
    			{
    				if (parseInt($('#w').val())) return true;
    				alert('Please select a crop region then press submit.');
    				return false;
    			};
    
    		</script>
    
    	</head>
    
    	<body>
    
    	<div id="outer">
    	<div class="jcExample">
    	<div class="article">
    
    		<h1>Jcrop - Crop Behavior</h1>
    
    		<!-- This is the image we're attaching Jcrop to -->
    		<img src="demo_files/pool.jpg" id="cropbox" />
    
    		<!-- This is the form that our event handler fills -->
    		<form action="crop.php" method="post" onsubmit="return checkCoords();">
    			<input type="hidden" id="x" name="x" />
    			<input type="hidden" id="y" name="y" />
    			<input type="hidden" id="w" name="w" />
    			<input type="hidden" id="h" name="h" />
    			<input type="submit" value="Crop Image" />
    		</form>
    
    		<p>
    			<b>An example server-side crop script.</b> Hidden form values
    			are set when a selection is made. If you press the <i>Crop Image</i>
    			button, the form will be submitted and a 150x150 thumbnail will be
    			dumped to the browser. Try it!
    		</p>
    
    		<div id="dl_links">
    			<a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
    			<a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
    		</div>
    
    
    	</div>
    	</div>
    	</div>
    	</body>
    
    </html>
    
    
    ================================================
    FILE: set/Jcrop/demos/demo_files/demos.css
    ================================================
    /* Jcrop Demo CSS
     * Not required to run Jcrop
     * Just makes the demo pages look less ugly
     */
    
    body
    {
      margin: 0;
      padding: 0;
      background: #eee;
      font-family: Calibri, sans-serif;
    }
    
    .article h1
    {
      color: #333;
      font-size: 2.2em;
      margin-top: .2em;
    }
    
    .jcropper-holder { border: 1px black solid; }
    
    #outer { text-align: center; }
    
    .jcExample
    {
      text-align: left;
      background: white;
      width: 700px;
      font-size: 80%;
      margin: 1.5em auto 2em auto;
      border: 1px #999 solid;
      padding: 1em 2em 2em;
    }
    
    .jcExample .article { width: 565px; }
    
    form { margin: 1.5em 0; }
    form.coords label { margin-right: 1em; font-weight: bold; color: #900; }
    form.coords input { width: 3em; }
    
    .ui-button { font-size: 10pt; }
    .ui-dialog { font-size: 9pt; }
    .ui-state-default { font-size: 9pt; }
    .ui-widget-overlay { opacity: 0.80; filter: Alpha(opacity=70); }
    .jc-dialog { padding-top: 1em; }
    .ui-dialog p tt { color: yellow; }
    
    li small { font-style: normal; color: #CF4429; font-size: 11px; }
    
    .jcrop-light .jcrop-selection {
      -moz-box-shadow: 0px 0px 15px #999; /* Firefox */
      -webkit-box-shadow: 0px 0px 15px #999; /* Safari, Chrome */
      box-shadow: 0px 0px 15px #999; /* CSS3 */
    }
     .jcrop-dark .jcrop-selection {
      -moz-box-shadow: 0px 0px 15px #000; /* Firefox */
      -webkit-box-shadow: 0px 0px 15px #000; /* Safari, Chrome */
      box-shadow: 0px 0px 15px #000; /* CSS3 */
    }
    
    .jcrop-fancy .jcrop-handle.ord-e {
      -webkit-border-top-left-radius: 0px;
      -webkit-border-bottom-left-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-w {
      -webkit-border-top-right-radius: 0px;
      -webkit-border-bottom-right-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-nw {
      -webkit-border-bottom-right-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-ne {
      -webkit-border-bottom-left-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-sw {
      -webkit-border-top-right-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-se {
      -webkit-border-top-left-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-s {
      -webkit-border-top-left-radius: 0px;
      -webkit-border-top-right-radius: 0px;
    }
    .jcrop-fancy .jcrop-handle.ord-n {
      -webkit-border-bottom-left-radius: 0px;
      -webkit-border-bottom-right-radius: 0px;
    }
    
    
    ================================================
    FILE: set/Jcrop/demos/jquery-ui.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; Hello World</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/vader/jquery-ui.css" type="text/css" />
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
        <script type="text/javascript">
    
        jQuery(function($){
    
          // How easy is this??
          $('#jc-hidden-image').Jcrop();
          $('button.ui-button').button();
    
          // Attach hidden dialog button click event
          $('#jc-hidden-btn').click(function(){
            $('#jc-hidden-dialog').dialog({
              modal: true,
              width: (parseInt($('#jc-hidden-image').width())+34)+'px',
              title: 'Jcrop in jQuery-ui Dialog (Hidden)',
              resizable: false
            });
            return false;
          });
    
          $('#jc-dyn-btn').click(function(){
            var jcrop_api;
            var $dialog = $('<div><div class="jc-dialog"><img src="demo_files/sago.jpg" /></div></div>');
            $dialog.find('img').Jcrop({},function(){
              jcrop_api = this;
              $dialog.dialog({
                modal: true,
                title: 'Jcrop in jQuery-ui Dialog (Dynamic)',
                close: function(){ $dialog.remove(); },
                width: jcrop_api.getBounds()[0]+34,
                resizable: false
              })
            });
            $dialog.append('<p><b>This dialog was dynamically created in Javascript.</b><br />'+
              'Jcrop was attached to the image, and the dialog opened when Jcrop finished.</p>');
            return false;
          });
    
          $('#tabs-2 img').Jcrop({
            setSelect: [10,10,200,200]
          });
          $('#tabs').tabs();
    
        });
    
        </script>
      </head>
    
      <body>
        <div id="outer">
        <div class="jcExample">
        <div class="article">
    
          <h1>Jcrop - jQuery UI Example</h1>
    
    
          <!-- Hidden dialog -->
          <div style="display:none;" id="jc-hidden-dialog">
          <div class="jc-dialog">
            <img src="demo_files/sago.jpg" id="jc-hidden-image" />
          </div>
            <p><b>This dialog is embedded on the page in a hidden container.</b><br />
            The container is rendered with <tt>style="display:none;"</tt> set.</p>
          </div>
          <!-- /Hidden dialog -->
    
          <p>
            <b>This example demonstrates more complex invocations of Jcrop.</b>
            These techniques can be integrated with other libraries or more
            complex user interfaces.
          </p>
    
          <div style="margin: 1em 0;">
          <div id="tabs">
            <ul>
              <li><a href="#tabs-1">About jQuery-ui Demos</a></li>
              <li><a href="#tabs-2">Jcrop in Tab</a></li>
            </ul>
            <div id="tabs-1">
              <p>
                Prior to v0.9.10 release, it was difficult to instantiate Jcrop
                on an image unless it was visible on the page. This meant that
                opening Jcrop in a dialog or a hidden tab was problematic, and
                involved specific timing (e.g. attaching the Jcrop method
                call to an "open" handler for the UI element).
              </p>
              <p>
                This demo shows simple invocations of Jcrop using jQuery UI. If
                you are using a different library to produce dialog boxes or tabs,
                the theory of operation should be similar.
              </p>
              <button class="ui-button" id="jc-hidden-btn">Hidden Dialog</button>
              <button class="ui-button" id="jc-dyn-btn">Dynamic Dialog</button>
            </div>
            <div id="tabs-2">
              <img src="demo_files/pool.jpg" />
            </div>
          </div>
          </div>
    
          <div id="dl_links">
            <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
            <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
          </div>
    
        </div>
        </div>
        </div>
      </body>
    </html>
    
    
    
    ================================================
    FILE: set/Jcrop/demos/non-image.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; Non-Image</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
        <script type="text/javascript">
    
        jQuery(function($){
    
          // I did JSON.stringify(jcrop_api.tellSelect()) on a crop I liked:
          var c = {"x":13,"y":7,"x2":487,"y2":107,"w":474,"h":100};
    
          $('#target').Jcrop({
            bgFade: true,
            setSelect: [c.x,c.y,c.x2,c.y2]
          });
    
        });
    
        </script>
        <style type="text/css">
          #target {
            background-color: #ccc;
            width: 500px;
            height: 330px;
            font-size: 24px;
            display: block;
          }
        </style>
      </head>
    
      <body>
        <div id="outer">
        <div class="jcExample">
        <div class="article">
    
          <h1>Jcrop - Non-Image</h1>
          <p id="target">
            <b style="display:block; padding: .5em 1em;">
              This is an example of attaching Jcrop to a target that is not an image. You are now cropping a paragraph tag.
            </b>
          </p>
    
          <p>
            <b>Attaching Jcrop to a non-image element.</b>
            This is mostly useful to implement other interfaces, such as <tt>canvas</tt> or over an arbitrary <tt>div</tt>.
          </p>
    
          <div id="dl_links">
            <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
            <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
          </div>
    
        </div>
        </div>
        </div>
      </body>
    </html>
    
    
    
    ================================================
    FILE: set/Jcrop/demos/styling.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; Styling Example</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
        <script src="../js/jquery.color.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/vader/jquery-ui.css" type="text/css" />
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
        <script type="text/javascript">
    
        jQuery(function($){
    
          var api;
    
          $('#target').Jcrop({
            // start off with jcrop-light class
            bgOpacity: 0.5,
            bgColor: 'white',
            addClass: 'jcrop-light'
          },function(){
            api = this;
            api.setSelect([130,65,130+350,65+285]);
            api.setOptions({ bgFade: true });
            api.ui.selection.addClass('jcrop-selection');
          });
    
          // Attach some button handlers
          $('#radio2').click(function(){
            api.ui.holder.removeClass('jcrop-light');
            api.ui.holder.addClass('jcrop-dark');
            api.setOptions({ bgColor: 'black', bgOpacity: 0.4 });
            return false;
          });
          $('#radio1').click(function(){
            api.ui.holder.removeClass('jcrop-dark');
            api.ui.holder.addClass('jcrop-light');
            api.setOptions({ bgColor: 'white', bgOpacity: 0.5 });
            return false;
          });
          $('#radio3').click(function(){
            api.ui.holder.removeClass('jcrop-dark');
            api.ui.holder.removeClass('jcrop-light');
            api.setOptions({ bgColor: 'black', bgOpacity: 0.6 });
            return false;
          });
    
          $('#radioset').buttonset();
    
        });
    
        </script>
      </head>
    
      <body>
        <div id="outer">
        <div class="jcExample">
        <div class="article">
    
          <h1>Jcrop - Styling Example</h1>
          <img src="demo_files/pool.jpg" id="target" alt="Flowers" />
    
          <div style="margin-top:1em; width:500px;">
          <fieldset>
          <legend>Manipulate classes</legend>
            <div id="radioset">
              <input type="radio" id="radio1" name="radio" checked="checked" /><label for="radio1">jcrop-light</label>
              <input type="radio" id="radio2" name="radio" /><label for="radio2">jcrop-dark</label>
              <input type="radio" id="radio3" name="radio" /><label for="radio3">normal</label>
            </div>
          </fieldset>
          </div>
    
          <p>
            <b>Example styling tricks.</b> Click the buttons above to change the appearance of Jcrop in real-time.
          </p>
    
          <div id="dl_links">
            <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
            <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
          </div>
    
        </div>
        </div>
        </div>
      </body>
    </html>
    
    
    
    ================================================
    FILE: set/Jcrop/demos/tutorial1.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; Hello World</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
        <script type="text/javascript">
    
        jQuery(function($){
    
          // How easy is this??
          $('#target').Jcrop();
    
        });
    
        </script>
      </head>
    
      <body>
        <div id="outer">
        <div class="jcExample">
        <div class="article">
    
          <h1>Jcrop - Hello World</h1>
          <img src="demo_files/pool.jpg" id="target" alt="Flowers" />
    
          <p>
            <b>This example demonstrates the default behavior of Jcrop.</b>
            Since no event handlers have been attached it only performs
            the cropping behavior.
          </p>
    
          <div id="dl_links">
            <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
            <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
          </div>
    
        </div>
        </div>
        </div>
      </body>
    </html>
    
    
    
    ================================================
    FILE: set/Jcrop/demos/tutorial2.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; Event Handler</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
        <script type="text/javascript">
    
        jQuery(function($){
    
          $('#target').Jcrop({
            onChange:   showCoords,
            onSelect:   showCoords,
            onRelease:  clearCoords
          });
    
        });
    
        // Simple event handler, called from onChange and onSelect
        // event handlers, as per the Jcrop invocation above
        function showCoords(c)
        {
          $('#x1').val(c.x);
          $('#y1').val(c.y);
          $('#x2').val(c.x2);
          $('#y2').val(c.y2);
          $('#w').val(c.w);
          $('#h').val(c.h);
        };
    
        function clearCoords()
        {
          $('#coords input').val('');
        };
    
        </script>
      </head>
      <body>
      <div id="outer">
      <div class="jcExample">
      <div class="article">
    
        <h1>Jcrop - Event Handlers</h1>
    
        <!-- This is the image we're attaching Jcrop to -->
        <img src="demo_files/pool.jpg" id="target" alt="Flowers" />
    
        <!-- This is the form that our event handler fills -->
        <form id="coords"
          class="coords"
          onsubmit="return false;"
          action="http://example.com/post.php">
    
          <div>
          <label>X1 <input type="text" size="4" id="x1" name="x1" /></label>
          <label>Y1 <input type="text" size="4" id="y1" name="y1" /></label>
          <label>X2 <input type="text" size="4" id="x2" name="x2" /></label>
          <label>Y2 <input type="text" size="4" id="y2" name="y2" /></label>
          <label>W <input type="text" size="4" id="w" name="w" /></label>
          <label>H <input type="text" size="4" id="h" name="h" /></label>
          </div>
        </form>
    
        <p>
          <b>An example with a basic event handler.</b> Here we've tied
          several form values together with a simple event handler invocation.
          The result is that the form values are updated in real-time as
          the selection is changed using Jcrop's <em>onChange</em> handler.
        </p>
    
        <p>
          That's how easily Jcrop can be integrated into a traditional web form!
        </p>
    
        <div id="dl_links">
          <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
          <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
        </div>
    
    
      </div>
      </div>
      </div>
      </body>
    
    </html>
    
    
    ================================================
    FILE: set/Jcrop/demos/tutorial3.html
    ================================================
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <link rel="stylesheet" type="text/css" href="css/jquery.Jcrop.css" media="all">
    </head>
    <body>
    <img src="temp/pool.jpg" id="target" alt="Flowers" />
    <div style="width:50px;height:50px;overflow:hidden;">
        <img src="temp/pool.jpg" id="preview_b" alt="Preview" class="jcrop-preview" />
    </div>
    <div style="width:30px;height:30px;overflow:hidden;">
        <img src="temp/pool.jpg" id="preview_s" alt="Preview" class="jcrop-preview" />
    </div>
    <script type="text/javascript" src="../js/jQuery-1.7.1.min.js"></script>
    <script type="text/javascript" src="js/jquery.Jcrop.js"></script>
    
    <script type="text/javascript">
        jQuery(function($){
            var jcrop_api, boundx, boundy;
            $('#target').Jcrop({
                onChange: updatePreview,
                onSelect: updatePreview,
                aspectRatio: 1
            },function(){
                var bounds = this.getBounds();
                boundx = bounds[0];
                boundy = bounds[1];
                jcrop_api = this;
            });
            function updatePreview(c)
            {
                if (parseInt(c.w) > 0)
                {
                    var rxb = 50 / c.w;
                    var ryb = 50 / c.h;
                    var rxs = 30 / c.w;
                    var rys = 30 / c.h;
                    $('#preview_b').css({
                        width: Math.round(rxb * boundx) + 'px',
                        height: Math.round(ryb * boundy) + 'px',
                        marginLeft: '-' + Math.round(rxb * c.x) + 'px',
                        marginTop: '-' + Math.round(ryb * c.y) + 'px'
                    });
                    $('#preview_s').css({
                        width: Math.round(rxs * boundx) + 'px',
                        height: Math.round(rys * boundy) + 'px',
                        marginLeft: '-' + Math.round(rxs * c.x) + 'px',
                        marginTop: '-' + Math.round(rys * c.y) + 'px'
                    });
                }
            };
        });
    </script>
    </body>
    </html>
    
    ================================================
    FILE: set/Jcrop/demos/tutorial4.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; Animations / Transitions</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <script src="../js/jquery.color.js" type="text/javascript"></script>
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="../css/jquery.Jcrop.extras.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
    
        <script type="text/javascript">
    
          jQuery(function($){
    
            var jcrop_api;
    
            $('#target').Jcrop({
              bgFade:     true,
              bgOpacity: .3,
              setSelect: [ 60, 70, 540, 330 ]
            },function(){
              jcrop_api = this;
            });
    
            $('#fadetog').change(function(){
              jcrop_api.setOptions({
                bgFade: this.checked
              });
            }).attr('checked','checked');
    
            $('#shadetog').change(function(){
              if (this.checked) $('#shadetxt').slideDown();
                else $('#shadetxt').slideUp();
              jcrop_api.setOptions({
                shade: this.checked
              });
            }).attr('checked',false);
    
            // Define page sections
            var sections = {
              anim_buttons: 'Animate Selection',
              bgo_buttons: 'Change bgOpacity',
              bgc_buttons: 'Change bgColor'
            };
            // Define animation buttons
            var ac = {
              anim1: [217,122,382,284],
              anim2: [20,20,580,380],
              anim3: [24,24,176,376],
              anim4: [347,165,550,355],
              anim5: [136,55,472,183]
            };
            // Define bgOpacity buttons
            var bgo = {
              Low: .2,
              Mid: .5,
              High: .8,
              Full: 1
            };
            // Define bgColor buttons
            var bgc = {
              Red: '#900',
              Blue: '#4BB6F0',
              Yellow: '#F0B207',
              Green: '#46B81C',
              White: 'white',
              Black: 'black'
            };
            // Create fieldset targets for buttons
            for(i in sections)
              insertSection(i,sections[i]);
    
            // Create animation buttons
            for(i in ac) {
              $('#anim_buttons').append(
                $('<button />').append(i).click(animHandler(ac[i])), ' '
              );
            }
            // Create bgOpacity buttons
            for(i in bgo) {
              $('#bgo_buttons').append(
                $('<button />').append(i).click(setoptHandler('bgOpacity',bgo[i])), ' '
              );
            }
            // Create bgColor buttons
            for(i in bgc) {
              $('#bgc_buttons').append(
                $('<button />').append(i).css({
                  backgroundColor: bgc[i],
                  color: ((i == 'Black') || (i == 'Red'))?'white':'black'
                }).click(setoptHandler('bgColor',bgc[i])), ' '
              );
            }
            // Function to insert named sections into interface
            function insertSection(k,v) {
              $('#interface').append(
                $('<fieldset></fieldset>').attr('id',k).append(
                  $('<legend></legend>').append(v)
                )
              );
            };
            // Handler for option-setting buttons
            function setoptHandler(k,v) {
              return function() {
                var opt = { };
                opt[k] = v;
                jcrop_api.setOptions(opt);
                return false;
              };
            };
            // Handler for animation buttons
            function animHandler(v) {
              return function() {
                jcrop_api.animateTo(v);
                return false;
              };
            };
    
            $('#anim_buttons').append(
              $('<button></button>').append('Bye!').click(function(){
                jcrop_api.animateTo(
                  [300,200,300,200],
                  function(){ this.release(); }
                );
                return false;
              })
            );
    
            $('#interface').show();
    
          });
    
        </script>
    
      </head>
    
      <body>
        <div id="outer">
        <div class="jcExample">
        <div class="article">
    
          <h1>Jcrop - Animations/Transitions</h1>
          <img src="demo_files/sago.jpg" id="target" alt="Flowers" />
    
          <div id="interface" style="margin: 1em 0;"></div>
          <div><label><input type="checkbox" id="fadetog" /> Enable fading (bgFade: true)</label></div>
          <div><label><input type="checkbox" id="shadetog" /> Use experimental shader (shade: true)</label></div>
    
          <p id="shadetxt" style="display:none; color:#900;">
            <b>Experimental shader active.</b>
            Jcrop now includes a shading mode that facilitates building
            better transparent Jcrop instances. The experimental shader is less
            robust than Jcrop's default shading method and should only be
            used if you require this functionality. 
          </p>
    
          <p>
            <b>Animation/Transitions.</b>
            Demonstration of animateTo API method and transitions for bgColor
            and bgOpacity options. Color fading requires inclusion of John Resig's
            jQuery <a href="http://plugins.jquery.com/project/color">Color 
            Animations</a> plugin. If it is not included, colors will not fade.
          </p>
    
        <div id="dl_links">
          <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
          <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
        </div>
    
        </div>
        </div>
        </div>
      </body>
    </html>
    
    
    
    ================================================
    FILE: set/Jcrop/demos/tutorial5.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
        <title>Jcrop &raquo; Tutorials &raquo; API Demo</title>
        <script src="../js/jquery.min.js" type="text/javascript"></script>
        <script src="../js/jquery.Jcrop.js" type="text/javascript"></script>
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
        <style type="text/css">
          .optdual { position: relative; }
          .optdual .offset { position: absolute; left: 18em; }
          .optlist label { width: 16em; display: block; }
          #dl_links { margin-top: .5em; }
        </style>
        <script type="text/javascript">
    
          jQuery(function($){
    
            // The variable jcrop_api will hold a reference to the
            // Jcrop API once Jcrop is instantiated.
            var jcrop_api;
    
            // In this example, since Jcrop may be attached or detached
            // at the whim of the user, I've wrapped the call into a function
            initJcrop();
            
            // The function is pretty simple
            function initJcrop()//{{{
            {
              // Hide any interface elements that require Jcrop
              // (This is for the local user interface portion.)
              $('.requiresjcrop').hide();
    
              // Invoke Jcrop in typical fashion
              $('#target').Jcrop({
                onRelease: releaseCheck
              },function(){
    
                jcrop_api = this;
                jcrop_api.animateTo([100,100,400,300]);
    
                // Setup and dipslay the interface for "enabled"
                $('#can_click,#can_move,#can_size').attr('checked','checked');
                $('#ar_lock,#size_lock,#bg_swap').attr('checked',false);
                $('.requiresjcrop').show();
    
              });
    
            };
            //}}}
    
            // Use the API to find cropping dimensions
            // Then generate a random selection
            // This function is used by setSelect and animateTo buttons
            // Mainly for demonstration purposes
            function getRandom() {
              var dim = jcrop_api.getBounds();
              return [
                Math.round(Math.random() * dim[0]),
                Math.round(Math.random() * dim[1]),
                Math.round(Math.random() * dim[0]),
                Math.round(Math.random() * dim[1])
              ];
            };
    
            // This function is bound to the onRelease handler...
            // In certain circumstances (such as if you set minSize
            // and aspectRatio together), you can inadvertently lose
            // the selection. This callback re-enables creating selections
            // in such a case. Although the need to do this is based on a
            // buggy behavior, it's recommended that you in some way trap
            // the onRelease callback if you use allowSelect: false
            function releaseCheck()
            {
              jcrop_api.setOptions({ allowSelect: true });
              $('#can_click').attr('checked',false);
            };
    
            // Attach interface buttons
            // This may appear to be a lot of code but it's simple stuff
            $('#setSelect').click(function(e) {
              // Sets a random selection
              jcrop_api.setSelect(getRandom());
            });
            $('#animateTo').click(function(e) {
              // Animates to a random selection
              jcrop_api.animateTo(getRandom());
            });
            $('#release').click(function(e) {
              // Release method clears the selection
              jcrop_api.release();
            });
            $('#disable').click(function(e) {
              // Disable Jcrop instance
              jcrop_api.disable();
              // Update the interface to reflect disabled state
              $('#enable').show();
              $('.requiresjcrop').hide();
            });
            $('#enable').click(function(e) {
              // Re-enable Jcrop instance
              jcrop_api.enable();
              // Update the interface to reflect enabled state
              $('#enable').hide();
              $('.requiresjcrop').show();
            });
            $('#rehook').click(function(e) {
              // This button is visible when Jcrop has been destroyed
              // It performs the re-attachment and updates the UI
              $('#rehook,#enable').hide();
              initJcrop();
              $('#unhook,.requiresjcrop').show();
              return false;
            });
            $('#unhook').click(function(e) {
              // Destroy Jcrop widget, restore original state
              jcrop_api.destroy();
              // Update the interface to reflect un-attached state
              $('#unhook,#enable,.requiresjcrop').hide();
              $('#rehook').show();
              return false;
            });
    
            // Hook up the three image-swapping buttons
            $('#img1').click(function(e) {
              jcrop_api.setImage('demo_files/sago.jpg');
              jcrop_api.setOptions({ bgOpacity: .6 });
              return false;
            });
            $('#img2').click(function(e) {
              jcrop_api.setImage('demo_files/pool.jpg');
              jcrop_api.setOptions({ bgOpacity: .6 });
              return false;
            });
            $('#img3').click(function(e) {
              jcrop_api.setImage('demo_files/sago.jpg',function(){
                this.setOptions({
                  bgOpacity: 1,
                  outerImage: 'demo_files/sagomod.jpg'
                });
                this.animateTo(getRandom());
              });
              return false;
            });
    
            // The checkboxes simply set options based on it's checked value
            // Options are changed by passing a new options object
    
            // Also, to prevent strange behavior, they are initially checked
            // This matches the default initial state of Jcrop
    
            $('#can_click').change(function(e) {
              jcrop_api.setOptions({ allowSelect: !!this.checked });
              jcrop_api.focus();
            });
            $('#can_move').change(function(e) {
              jcrop_api.setOptions({ allowMove: !!this.checked });
              jcrop_api.focus();
            });
            $('#can_size').change(function(e) {
              jcrop_api.setOptions({ allowResize: !!this.checked });
              jcrop_api.focus();
            });
            $('#ar_lock').change(function(e) {
              jcrop_api.setOptions(this.checked?
                { aspectRatio: 4/3 }: { aspectRatio: 0 });
              jcrop_api.focus();
            });
            $('#size_lock').change(function(e) {
              jcrop_api.setOptions(this.checked? {
                minSize: [ 80, 80 ],
                maxSize: [ 350, 350 ]
              }: {
                minSize: [ 0, 0 ],
                maxSize: [ 0, 0 ]
              });
              jcrop_api.focus();
            });
    
          });
    
        </script>
    
      </head>
    
      <body>
        <div id="outer">
        <div class="jcExample">
        <div class="article">
    
          <h1>Jcrop - API Demo</h1>
          <img src="demo_files/sago.jpg" id="target" alt="Jcrop Image" />
    
          <div style="margin: .8em 0 .5em;">
            <span class="requiresjcrop">
              <button id="setSelect">setSelect</button>
              <button id="animateTo">animateTo</button>
              <button id="release">Release</button>
              <button id="disable">Disable</button>
            </span>
            <button id="enable" style="display:none;">Re-Enable</button>
            <button id="unhook">Destroy!</button>
            <button id="rehook" style="display:none;">Attach Jcrop</button>
          </div>
    
          <fieldset class="optdual requiresjcrop">
            <legend>Option Toggles</legend>
            <div class="optlist offset">
              <label><input type="checkbox" id="ar_lock" />Aspect ratio</label>
              <label><input type="checkbox" id="size_lock" />minSize/maxSize setting</label>
            </div>
            <div class="optlist">
              <label><input type="checkbox" id="can_click" />Allow new selections</label>
              <label><input type="checkbox" id="can_move" />Selection can be moved</label>
              <label><input type="checkbox" id="can_size" />Resizable selection</label>
            </div>
          </fieldset>
    
          <fieldset class="requiresjcrop" style="margin: .5em 0;">
            <legend>Change Image</legend>
            <span>
              <button id="img2">Pool</button>
              <button id="img1">Sago</button>
              <button id="img3">Sago w/ outerImage</button>
            </span>
          </fieldset>
    
        <div id="dl_links">
          <a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a> |
          <a href="http://deepliquid.com/content/Jcrop_Manual.html">Manual (Docs)</a>
        </div>
    
        </div>
        </div>
        </div>
      </body>
    </html>
    
    
    
    ================================================
    FILE: set/Jcrop/index.html
    ================================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <title>Jcrop: the jQuery Image Cropping Plugin</title>
      <link rel="stylesheet" href="demos/demo_files/demos.css" type="text/css" />
      <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
    </head>
    <body>
    
    	<div id="outer">
    	<div class="jcExample">
    	<div class="article">
    <h1>Jcrop Image Cropping Plugin</h1>
    
    <big>
    	<a href="http://deepliquid.com/content/Jcrop.html"><b>Jcrop</b></a>
    	is the image cropping plugin for
    	<a href="http://jquery.com/">jQuery</a>.<br />
    	You've successfully unpacked Jcrop.
    </big>
    
    <h3>Static Demos</h3>
    
    <ul>
    	<li><a href="demos/tutorial1.html">Hello World</a>
    		&mdash; default behavior</li>
    	<li><a href="demos/tutorial2.html">Basic Handler</a>
    		&mdash; basic form integration</li>
    	<li><a href="demos/tutorial3.html">Aspect Ratio w/ Preview Pane</a>
    		&mdash; nice visual example</li>
    	<li><a href="demos/tutorial4.html">Animation/Transitions</a>
    		&mdash; animation/fading demo</li>
    	<li><a href="demos/tutorial5.html">API Interface</a>
    		&mdash; real-time API example</li>
    	<li><a href="demos/jquery-ui.html">jQuery UI Demo</a>
    		&mdash; invoking Jcrop in dialogs and hidden tabs
        <small>New in 0.9.10</small>
        </li>
    	<li><a href="demos/styling.html">Styling Example</a>
    		&mdash; style Jcrop dynamically with CSS
        <small>New in 0.9.10</small>
        </li>
      <li><a href="demos/non-image.html">Non-Image Elements</a>
        &mdash; attach to other DOM block elements
        <small>New in 0.9.10</small>
        </li>
    </ul>
    
    <h3>Live Demo</h3>
    
    <ul>
    	<li><a href="demos/crop.php">PHP Cropping Demo</a>
    		&mdash; requires PHP/gd support</li>
    </ul>
    
    <h3>Jcrop Links</h3>
    
    <ul>
    	<li><a href="http://deepliquid.com/content/Jcrop.html">Jcrop Home</a></li>
    	<li><a href="http://deepliquid.com/content/Jcrop_Manual.html">Jcrop Manual</a></li>
    </ul>
    
    <hr style="margin-top:2em;" />
    <small>
    	<b>&copy; 2008-2012 Tapmodo Interactive LLC</b><br />
    	Free software released under <a href="MIT-LICENSE.txt">MIT License</a>
    </small>
    </div>
    </div>
    </div>
    
    </body>
    </html>
    
    
    ================================================
    FILE: set/Jcrop/js/jquery.Jcrop.js
    ================================================
    /**
     * jquery.Jcrop.js v0.9.10
     * jQuery Image Cropping Plugin - released under MIT License 
     * Author: Kelly Hallman <khallman@gmail.com>
     * http://github.com/tapmodo/Jcrop
     * Copyright (c) 2008-2012 Tapmodo Interactive LLC {{{
     *
     * Permission is hereby granted, free of charge, to any person
     * obtaining a copy of this software and associated documentation
     * files (the "Software"), to deal in the Software without
     * restriction, including without limitation the rights to use,
     * copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the
     * Software is furnished to do so, subject to the following
     * conditions:
     *
     * The above copyright notice and this permission notice shall be
     * included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     * OTHER DEALINGS IN THE SOFTWARE.
     *
     * }}}
     */
    
    (function ($) {
    
      $.Jcrop = function (obj, opt) {
        var options = $.extend({}, $.Jcrop.defaults),
            docOffset, lastcurs, ie6mode = false;
    
        // Internal Methods {{{
        function px(n) {
          return n + 'px';
        }
        function cssClass(cl) {
          return options.baseClass + '-' + cl;
        }
        function supportsColorFade() {
          return $.fx.step.hasOwnProperty('backgroundColor');
        }
        function getPos(obj) //{{{
        {
          var pos = $(obj).offset();
          return [pos.left, pos.top];
        }
        //}}}
        function mouseAbs(e) //{{{
        {
          return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];
        }
        //}}}
        function setOptions(opt) //{{{
        {
          if (typeof(opt) !== 'object') opt = {};
          options = $.extend(options, opt);
    
          $.each(['onChange','onSelect','onRelease','onDblClick'],function(i,e) {
            if (typeof(options[e]) !== 'function') options[e] = function () {};
          });
        }
        //}}}
        function startDragMode(mode, pos) //{{{
        {
          docOffset = getPos($img);
          Tracker.setCursor(mode === 'move' ? mode : mode + '-resize');
    
          if (mode === 'move') {
            return Tracker.activateHandlers(createMover(pos), doneSelect);
          }
    
          var fc = Coords.getFixed();
          var opp = oppLockCorner(mode);
          var opc = Coords.getCorner(oppLockCorner(opp));
    
          Coords.setPressed(Coords.getCorner(opp));
          Coords.setCurrent(opc);
    
          Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect);
        }
        //}}}
        function dragmodeHandler(mode, f) //{{{
        {
          return function (pos) {
            if (!options.aspectRatio) {
              switch (mode) {
              case 'e':
                pos[1] = f.y2;
                break;
              case 'w':
                pos[1] = f.y2;
                break;
              case 'n':
                pos[0] = f.x2;
                break;
              case 's':
                pos[0] = f.x2;
                break;
              }
            } else {
              switch (mode) {
              case 'e':
                pos[1] = f.y + 1;
                break;
              case 'w':
                pos[1] = f.y + 1;
                break;
              case 'n':
                pos[0] = f.x + 1;
                break;
              case 's':
                pos[0] = f.x + 1;
                break;
              }
            }
            Coords.setCurrent(pos);
            Selection.update();
          };
        }
        //}}}
        function createMover(pos) //{{{
        {
          var lloc = pos;
          KeyManager.watchKeys();
    
          return function (pos) {
            Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);
            lloc = pos;
    
            Selection.update();
          };
        }
        //}}}
        function oppLockCorner(ord) //{{{
        {
          switch (ord) {
          case 'n':
            return 'sw';
          case 's':
            return 'nw';
          case 'e':
            return 'nw';
          case 'w':
            return 'ne';
          case 'ne':
            return 'sw';
          case 'nw':
            return 'se';
          case 'se':
            return 'nw';
          case 'sw':
            return 'ne';
          }
        }
        //}}}
        function createDragger(ord) //{{{
        {
          return function (e) {
            if (options.disabled) {
              return false;
            }
            if ((ord === 'move') && !options.allowMove) {
              return false;
            }
            
            // Fix position of crop area when dragged the very first time.
            // Necessary when crop image is in a hidden element when page is loaded.
            docOffset = getPos($img);
    
            btndown = true;
            startDragMode(ord, mouseAbs(e));
            e.stopPropagation();
            e.preventDefault();
            return false;
          };
        }
        //}}}
        function presize($obj, w, h) //{{{
        {
          var nw = $obj.width(),
              nh = $obj.height();
          if ((nw > w) && w > 0) {
            nw = w;
            nh = (w / $obj.width()) * $obj.height();
          }
          if ((nh > h) && h > 0) {
            nh = h;
            nw = (h / $obj.height()) * $obj.width();
          }
          xscale = $obj.width() / nw;
          yscale = $obj.height() / nh;
          $obj.width(nw).height(nh);
        }
        //}}}
        function unscale(c) //{{{
        {
          return {
            x: c.x * xscale,
            y: c.y * yscale,
            x2: c.x2 * xscale,
            y2: c.y2 * yscale,
            w: c.w * xscale,
            h: c.h * yscale
          };
        }
        //}}}
        function doneSelect(pos) //{{{
        {
          var c = Coords.getFixed();
          if ((c.w > options.minSelect[0]) && (c.h > options.minSelect[1])) {
            Selection.enableHandles();
            Selection.done();
          } else {
            Selection.release();
          }
          Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');
        }
        //}}}
        function newSelection(e) //{{{
        {
          if (options.disabled) {
            return false;
          }
          if (!options.allowSelect) {
            return false;
          }
          btndown = true;
          docOffset = getPos($img);
          Selection.disableHandles();
          Tracker.setCursor('crosshair');
          var pos = mouseAbs(e);
          Coords.setPressed(pos);
          Selection.update();
          Tracker.activateHandlers(selectDrag, doneSelect);
          KeyManager.watchKeys();
    
          e.stopPropagation();
          e.preventDefault();
          return false;
        }
        //}}}
        function selectDrag(pos) //{{{
        {
          Coords.setCurrent(pos);
          Selection.update();
        }
        //}}}
        function newTracker() //{{{
        {
          var trk = $('<div></div>').addClass(cssClass('tracker'));
          if ($.browser.msie) {
            trk.css({
              opacity: 0,
              backgroundColor: 'white'
            });
          }
          return trk;
        }
        //}}}
    
        // }}}
        // Initialization {{{
        // Sanitize some options {{{
        if ($.browser.msie && ($.browser.version.split('.')[0] === '6')) {
          ie6mode = true;
        }
        if (typeof(obj) !== 'object') {
          obj = $(obj)[0];
        }
        if (typeof(opt) !== 'object') {
          opt = {};
        }
        // }}}
        setOptions(opt);
        // Initialize some jQuery objects {{{
        // The values are SET on the image(s) for the interface
        // If the original image has any of these set, they will be reset
        // However, if you destroy() the Jcrop instance the original image's
        // character in the DOM will be as you left it.
        var img_css = {
          border: 'none',
          visibility: 'visible',
          margin: 0,
          padding: 0,
          position: 'absolute',
          top: 0,
          left: 0
        };
    
        var $origimg = $(obj),
          img_mode = true;
    
        if (obj.tagName == 'IMG') {
          // Fix size of crop image.
          // Necessary when crop image is within a hidden element when page is loaded.
          if ($origimg[0].width != 0 && $origimg[0].height != 0) {
            // Obtain dimensions from contained img element.
            $origimg.width($origimg[0].width);
            $origimg.height($origimg[0].height);
          } else {
            // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0). 
            var tempImage = new Image();
            tempImage.src = $origimg[0].src;
            $origimg.width(tempImage.width);
            $origimg.height(tempImage.height);
          } 
    
          var $img = $origimg.clone().removeAttr('id').css(img_css).show();
    
          $img.width($origimg.width());
          $img.height($origimg.height());
          $origimg.after($img).hide();
    
        } else {
          $img = $origimg.css(img_css).show();
          img_mode = false;
          if (options.shade === null) { options.shade = true; }
        }
    
        presize($img, options.boxWidth, options.boxHeight);
    
        var boundx = $img.width(),
            boundy = $img.height(),
            
            
            $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({
            position: 'relative',
            backgroundColor: options.bgColor
          }).insertAfter($origimg).append($img);
    
        if (options.addClass) {
          $div.addClass(options.addClass);
        }
    
        var $img2 = $('<div />'),
    
            $img_holder = $('<div />') 
            .width('100%').height('100%').css({
              zIndex: 310,
              position: 'absolute',
              overflow: 'hidden'
            }),
    
            $hdl_holder = $('<div />') 
            .width('100%').height('100%').css('zIndex', 320), 
    
            $sel = $('<div />') 
            .css({
              position: 'absolute',
              zIndex: 600
            }).dblclick(function(){
              var c = Coords.getFixed();
              options.onDblClick.call(api,c);
            }).insertBefore($img).append($img_holder, $hdl_holder); 
    
        if (img_mode) {
    
          $img2 = $('<img />')
              .attr('src', $img.attr('src')).css(img_css).width(boundx).height(boundy),
    
          $img_holder.append($img2);
    
        }
    
        if (ie6mode) {
          $sel.css({
            overflowY: 'hidden'
          });
        }
    
        var bound = options.boundary;
        var $trk = newTracker().width(boundx + (bound * 2)).height(boundy + (bound * 2)).css({
          position: 'absolute',
          top: px(-bound),
          left: px(-bound),
          zIndex: 290
        }).mousedown(newSelection);
    
        /* }}} */
        // Set more variables {{{
        var bgcolor = options.bgColor,
            bgopacity = options.bgOpacity,
            xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true,
            btndown, animating, shift_down;
    
        docOffset = getPos($img);
        // }}}
        // }}}
        // Internal Modules {{{
        // Touch Module {{{ 
        var Touch = (function () {
          // Touch support detection function adapted (under MIT License)
          // from code by Jeffrey Sambells - http://github.com/iamamused/
          function hasTouchSupport() {
            var support = {},
                events = ['touchstart', 'touchmove', 'touchend'],
                el = document.createElement('div'), i;
    
            try {
              for(i=0; i<events.length; i++) {
                var eventName = events[i];
                eventName = 'on' + eventName;
                var isSupported = (eventName in el);
                if (!isSupported) {
                  el.setAttribute(eventName, 'return;');
                  isSupported = typeof el[eventName] == 'function';
                }
                support[events[i]] = isSupported;
              }
              return support.touchstart && support.touchend && support.touchmove;
            }
            catch(err) {
              return false;
            }
          }
    
          function detectSupport() {
            if ((options.touchSupport === true) || (options.touchSupport === false)) return options.touchSupport;
              else return hasTouchSupport();
          }
          return {
            createDragger: function (ord) {
              return function (e) {
                e.pageX = e.originalEvent.changedTouches[0].pageX;
                e.pageY = e.originalEvent.changedTouches[0].pageY;
                if (options.disabled) {
                  return false;
                }
                if ((ord === 'move') && !options.allowMove) {
                  return false;
                }
                btndown = true;
                startDragMode(ord, mouseAbs(e));
                e.stopPropagation();
                e.preventDefault();
                return false;
              };
            },
            newSelection: function (e) {
              e.pageX = e.originalEvent.changedTouches[0].pageX;
              e.pageY = e.originalEvent.changedTouches[0].pageY;
              return newSelection(e);
            },
            isSupported: hasTouchSupport,
            support: detectSupport()
          };
        }());
        // }}}
        // Coords Module {{{
        var Coords = (function () {
          var x1 = 0,
              y1 = 0,
              x2 = 0,
              y2 = 0,
              ox, oy;
    
          function setPressed(pos) //{{{
          {
            pos = rebound(pos);
            x2 = x1 = pos[0];
            y2 = y1 = pos[1];
          }
          //}}}
          function setCurrent(pos) //{{{
          {
            pos = rebound(pos);
            ox = pos[0] - x2;
            oy = pos[1] - y2;
            x2 = pos[0];
            y2 = pos[1];
          }
          //}}}
          function getOffset() //{{{
          {
            return [ox, oy];
          }
          //}}}
          function moveOffset(offset) //{{{
          {
            var ox = offset[0],
                oy = offset[1];
    
            if (0 > x1 + ox) {
              ox -= ox + x1;
            }
            if (0 > y1 + oy) {
              oy -= oy + y1;
            }
    
            if (boundy < y2 + oy) {
              oy += boundy - (y2 + oy);
            }
            if (boundx < x2 + ox) {
              ox += boundx - (x2 + ox);
            }
    
            x1 += ox;
            x2 += ox;
            y1 += oy;
            y2 += oy;
          }
          //}}}
          function getCorner(ord) //{{{
          {
            var c = getFixed();
            switch (ord) {
            case 'ne':
              return [c.x2, c.y];
            case 'nw':
              return [c.x, c.y];
            case 'se':
              return [c.x2, c.y2];
            case 'sw':
              return [c.x, c.y2];
            }
          }
          //}}}
          function getFixed() //{{{
          {
            if (!options.aspectRatio) {
              return getRect();
            }
            // This function could use some optimization I think...
            var aspect = options.aspectRatio,
                min_x = options.minSize[0] / xscale,
                
                
                //min_y = options.minSize[1]/yscale,
                max_x = options.maxSize[0] / xscale,
                max_y = options.maxSize[1] / yscale,
                rw = x2 - x1,
                rh = y2 - y1,
                rwa = Math.abs(rw),
                rha = Math.abs(rh),
                real_ratio = rwa / rha,
                xx, yy, w, h;
    
            if (max_x === 0) {
              max_x = boundx * 10;
            }
            if (max_y === 0) {
              max_y = boundy * 10;
            }
            if (real_ratio < aspect) {
              yy = y2;
              w = rha * aspect;
              xx = rw < 0 ? x1 - w : w + x1;
    
              if (xx < 0) {
                xx = 0;
                h = Math.abs((xx - x1) / aspect);
                yy = rh < 0 ? y1 - h : h + y1;
              } else if (xx > boundx) {
                xx = boundx;
                h = Math.abs((xx - x1) / aspect);
                yy = rh < 0 ? y1 - h : h + y1;
              }
            } else {
              xx = x2;
              h = rwa / aspect;
              yy = rh < 0 ? y1 - h : y1 + h;
              if (yy < 0) {
                yy = 0;
                w = Math.abs((yy - y1) * aspect);
                xx = rw < 0 ? x1 - w : w + x1;
              } else if (yy > boundy) {
                yy = boundy;
                w = Math.abs(yy - y1) * aspect;
                xx = rw < 0 ? x1 - w : w + x1;
              }
            }
    
            // Magic %-)
            if (xx > x1) { // right side
              if (xx - x1 < min_x) {
                xx = x1 + min_x;
              } else if (xx - x1 > max_x) {
                xx = x1 + max_x;
              }
              if (yy > y1) {
                yy = y1 + (xx - x1) / aspect;
              } else {
                yy = y1 - (xx - x1) / aspect;
              }
            } else if (xx < x1) { // left side
              if (x1 - xx < min_x) {
                xx = x1 - min_x;
              } else if (x1 - xx > max_x) {
                xx = x1 - max_x;
              }
              if (yy > y1) {
                yy = y1 + (x1 - xx) / aspect;
              } else {
                yy = y1 - (x1 - xx) / aspect;
              }
            }
    
            if (xx < 0) {
              x1 -= xx;
              xx = 0;
            } else if (xx > boundx) {
              x1 -= xx - boundx;
              xx = boundx;
            }
    
            if (yy < 0) {
              y1 -= yy;
              yy = 0;
            } else if (yy > boundy) {
              y1 -= yy - boundy;
              yy = boundy;
            }
    
            return makeObj(flipCoords(x1, y1, xx, yy));
          }
          //}}}
          function rebound(p) //{{{
          {
            if (p[0] < 0) {
              p[0] = 0;
            }
            if (p[1] < 0) {
              p[1] = 0;
            }
    
            if (p[0] > boundx) {
              p[0] = boundx;
            }
            if (p[1] > boundy) {
              p[1] = boundy;
            }
    
            return [p[0], p[1]];
          }
          //}}}
          function flipCoords(x1, y1, x2, y2) //{{{
          {
            var xa = x1,
                xb = x2,
                ya = y1,
                yb = y2;
            if (x2 < x1) {
              xa = x2;
              xb = x1;
            }
            if (y2 < y1) {
              ya = y2;
              yb = y1;
            }
            return [xa, ya, xb, yb];
          }
          //}}}
          function getRect() //{{{
          {
            var xsize = x2 - x1,
                ysize = y2 - y1,
                delta;
    
            if (xlimit && (Math.abs(xsize) > xlimit)) {
              x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);
            }
            if (ylimit && (Math.abs(ysize) > ylimit)) {
              y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);
            }
    
            if (ymin / yscale && (Math.abs(ysize) < ymin / yscale)) {
              y2 = (ysize > 0) ? (y1 + ymin / yscale) : (y1 - ymin / yscale);
            }
            if (xmin / xscale && (Math.abs(xsize) < xmin / xscale)) {
              x2 = (xsize > 0) ? (x1 + xmin / xscale) : (x1 - xmin / xscale);
            }
    
            if (x1 < 0) {
              x2 -= x1;
              x1 -= x1;
            }
            if (y1 < 0) {
              y2 -= y1;
              y1 -= y1;
            }
            if (x2 < 0) {
              x1 -= x2;
              x2 -= x2;
            }
            if (y2 < 0) {
              y1 -= y2;
              y2 -= y2;
            }
            if (x2 > boundx) {
              delta = x2 - boundx;
              x1 -= delta;
              x2 -= delta;
            }
            if (y2 > boundy) {
              delta = y2 - boundy;
              y1 -= delta;
              y2 -= delta;
            }
            if (x1 > boundx) {
              delta = x1 - boundy;
              y2 -= delta;
              y1 -= delta;
            }
            if (y1 > boundy) {
              delta = y1 - boundy;
              y2 -= delta;
              y1 -= delta;
            }
    
            return makeObj(flipCoords(x1, y1, x2, y2));
          }
          //}}}
          function makeObj(a) //{{{
          {
            return {
              x: a[0],
              y: a[1],
              x2: a[2],
              y2: a[3],
              w: a[2] - a[0],
              h: a[3] - a[1]
            };
          }
          //}}}
    
          return {
            flipCoords: flipCoords,
            setPressed: setPressed,
            setCurrent: setCurrent,
            getOffset: getOffset,
            moveOffset: moveOffset,
            getCorner: getCorner,
            getFixed: getFixed
          };
        }());
    
        //}}}
        // Shade Module {{{
        var Shade = (function() {
          var enabled = false,
              holder = $('<div />').css({
                position: 'absolute',
                zIndex: 240,
                opacity: 0
              }),
              shades = {
                top: createShade(),
                left: createShade().height(boundy),
                right: createShade().height(boundy),
                bottom: createShade()
              };
    
          function resizeShades(w,h) {
            shades.left.css({ height: px(h) });
            shades.right.css({ height: px(h) });
          }
          function updateAuto()
          {
            return updateShade(Coords.getFixed());
          }
          function updateShade(c)
          {
            shades.top.css({
              left: px(c.x),
              width: px(c.w),
              height: px(c.y)
            });
            shades.bottom.css({
              top: px(c.y2),
              left: px(c.x),
              width: px(c.w),
              height: px(boundy-c.y2)
            });
            shades.right.css({
              left: px(c.x2),
              width: px(boundx-c.x2)
            });
            shades.left.css({
              width: px(c.x)
            });
          }
          function createShade() {
            return $('<div />').css({
              position: 'absolute',
              backgroundColor: options.shadeColor||options.bgColor
            }).appendTo(holder);
          }
          function enableShade() {
            if (!enabled) {
              enabled = true;
              holder.insertBefore($img);
              updateAuto();
              Selection.setBgOpacity(1,0,1);
              $img2.hide();
    
              setBgColor(options.shadeColor||options.bgColor,1);
              if (Selection.isAwake())
              {
                setOpacity(options.bgOpacity,1);
              }
                else setOpacity(1,1);
            }
          }
          function setBgColor(color,now) {
            colorChangeMacro(getShades(),color,now);
          }
          function disableShade() {
            if (enabled) {
              holder.remove();
              $img2.show();
              enabled = false;
              if (Selection.isAwake()) {
                Selection.setBgOpacity(options.bgOpacity,1,1);
              } else {
                Selection.setBgOpacity(1,1,1);
                Selection.disableHandles();
              }
              colorChangeMacro($div,0,1);
            }
          }
          function setOpacity(opacity,now) {
            if (enabled) {
              if (options.bgFade && !now) {
                holder.animate({
                  opacity: 1-opacity
                },{
                  queue: false,
                  duration: options.fadeTime
                });
              }
              else holder.css({opacity:1-opacity});
            }
          }
          function refreshAll() {
            options.shade ? enableShade() : disableShade();
            if (Selection.isAwake()) setOpacity(options.bgOpacity);
          }
          function getShades() {
            return holder.children();
          }
    
          return {
            update: updateAuto,
            updateRaw: updateShade,
            getShades: getShades,
            setBgColor: setBgColor,
            enable: enableShade,
            disable: disableShade,
            resize: resizeShades,
            refresh: refreshAll,
            opacity: setOpacity
          };
        }());
        // }}}
        // Selection Module {{{
        var Selection = (function () {
          var awake,
              hdep = 370,
              borders = {},
              handle = {},
              dragbar = {},
              seehandles = false;
    
          // Private Methods
          function insertBorder(type) //{{{
          {
            var jq = $('<div />').css({
              position: 'absolute',
              opacity: options.borderOpacity
            }).addClass(cssClass(type));
            $img_holder.append(jq);
            return jq;
          }
          //}}}
          function dragDiv(ord, zi) //{{{
          {
            var jq = $('<div />').mousedown(createDragger(ord)).css({
              cursor: ord + '-resize',
              position: 'absolute',
              zIndex: zi
            }).addClass('ord-'+ord);
    
            if (Touch.support) {
              jq.bind('touchstart.jcrop', Touch.createDragger(ord));
            }
    
            $hdl_holder.append(jq);
            return jq;
          }
          //}}}
          function insertHandle(ord) //{{{
          {
            var hs = options.handleSize;
            return dragDiv(ord, hdep++).css({
              opacity: options.handleOpacity
            }).width(hs).height(hs).addClass(cssClass('handle'));
          }
          //}}}
          function insertDragbar(ord) //{{{
          {
            return dragDiv(ord, hdep++).addClass('jcrop-dragbar');
          }
          //}}}
          function createDragbars(li) //{{{
          {
            var i;
            for (i = 0; i < li.length; i++) {
              dragbar[li[i]] = insertDragbar(li[i]);
            }
          }
          //}}}
          function createBorders(li) //{{{
          {
            var cl,i;
            for (i = 0; i < li.length; i++) {
              switch(li[i]){
                case'n': cl='hline'; break;
                case's': cl='hline bottom'; break;
                case'e': cl='vline right'; break;
                case'w': cl='vline'; break;
              }
              borders[li[i]] = insertBorder(cl);
            }
          }
          //}}}
          function createHandles(li) //{{{
          {
            var i;
            for (i = 0; i < li.length; i++) {
              handle[li[i]] = insertHandle(li[i]);
            }
          }
          //}}}
          function moveto(x, y) //{{{
          {
            if (!options.shade) {
              $img2.css({
                top: px(-y),
                left: px(-x)
              });
            }
            $sel.css({
              top: px(y),
              left: px(x)
            });
          }
          //}}}
          function resize(w, h) //{{{
          {
            $sel.width(w).height(h);
          }
          //}}}
          function refresh() //{{{
          {
            var c = Coords.getFixed();
    
            Coords.setPressed([c.x, c.y]);
            Coords.setCurrent([c.x2, c.y2]);
    
            updateVisible();
          }
          //}}}
    
          // Internal Methods
          function updateVisible(select) //{{{
          {
            if (awake) {
              return update(select);
            }
          }
          //}}}
          function update(select) //{{{
          {
            var c = Coords.getFixed();
    
            resize(c.w, c.h);
            moveto(c.x, c.y);
            if (options.shade) Shade.updateRaw(c);
    
            awake || show();
    
            if (select) {
              options.onSelect.call(api, unscale(c));
            } else {
              options.onChange.call(api, unscale(c));
            }
          }
          //}}}
          function setBgOpacity(opacity,force,now) //{{{
          {
            if (!awake && !force) return;
            if (options.bgFade && !now) {
              $img.animate({
                opacity: opacity
              },{
                queue: false,
                duration: options.fadeTime
              });
            } else {
              $img.css('opacity', opacity);
            }
          }
          //}}}
          function show() //{{{
          {
            $sel.show();
    
            if (options.shade) Shade.opacity(bgopacity);
              else setBgOpacity(bgopacity,true);
    
            awake = true;
          }
          //}}}
          function release() //{{{
          {
            disableHandles();
            $sel.hide();
    
            if (options.shade) Shade.opacity(1);
              else setBgOpacity(1);
    
            awake = false;
            options.onRelease.call(api);
          }
          //}}}
          function showHandles() //{{{
          {
            if (seehandles) {
              $hdl_holder.show();
            }
          }
          //}}}
          function enableHandles() //{{{
          {
            seehandles = true;
            if (options.allowResize) {
              $hdl_holder.show();
              return true;
            }
          }
          //}}}
          function disableHandles() //{{{
          {
            seehandles = false;
            $hdl_holder.hide();
          } 
          //}}}
          function animMode(v) //{{{
          {
            if (animating === v) {
              disableHandles();
            } else {
              enableHandles();
            }
          } 
          //}}}
          function done() //{{{
          {
            animMode(false);
            refresh();
          } 
          //}}}
          // Insert draggable elements {{{
          // Insert border divs for outline
    
          if (options.dragEdges && $.isArray(options.createDragbars))
            createDragbars(options.createDragbars);
    
          if ($.isArray(options.createHandles))
            createHandles(options.createHandles);
    
          if (options.drawBorders && $.isArray(options.createBorders))
            createBorders(options.createBorders);
    
          //}}}
    
          // This is a hack for iOS5 to support drag/move touch functionality
          $(document).bind('touchstart.jcrop-ios',function(e) {
            if ($(e.currentTarget).hasClass('jcrop-tracker')) e.stopPropagation();
          });
    
          var $track = newTracker().mousedown(createDragger('move')).css({
            cursor: 'move',
            position: 'absolute',
            zIndex: 360
          });
    
          if (Touch.support) {
            $track.bind('touchstart.jcrop', Touch.createDragger('move'));
          }
    
          $img_holder.append($track);
          disableHandles();
    
          return {
            updateVisible: updateVisible,
            update: update,
            release: release,
            refresh: refresh,
            isAwake: function () {
              return awake;
            },
            setCursor: function (cursor) {
              $track.css('cursor', cursor);
            },
            enableHandles: enableHandles,
            enableOnly: function () {
              seehandles = true;
            },
            showHandles: showHandles,
            disableHandles: disableHandles,
            animMode: animMode,
            setBgOpacity: setBgOpacity,
            done: done
          };
        }());
        
        //}}}
        // Tracker Module {{{
        var Tracker = (function () {
          var onMove = function () {},
              onDone = function () {},
              trackDoc = options.trackDocument;
    
          function toFront() //{{{
          {
            $trk.css({
              zIndex: 450
            });
            if (Touch.support) {
              $(document)
                .bind('touchmove.jcrop', trackTouchMove)
                .bind('touchend.jcrop', trackTouchEnd);
            }
            if (trackDoc) {
              $(document)
                .bind('mousemove.jcrop',trackMove)
                .bind('mouseup.jcrop',trackUp);
            }
          } 
          //}}}
          function toBack() //{{{
          {
            $trk.css({
              zIndex: 290
            });
            $(document).unbind('.jcrop');
          } 
          //}}}
          function trackMove(e) //{{{
          {
            onMove(mouseAbs(e));
            return false;
          } 
          //}}}
          function trackUp(e) //{{{
          {
            e.preventDefault();
            e.stopPropagation();
    
            if (btndown) {
              btndown = false;
    
              onDone(mouseAbs(e));
    
              if (Selection.isAwake()) {
                options.onSelect.call(api, unscale(Coords.getFixed()));
              }
    
              toBack();
              onMove = function () {};
              onDone = function () {};
            }
    
            return false;
          }
          //}}}
          function activateHandlers(move, done) //{{{
          {
            btndown = true;
            onMove = move;
            onDone = done;
            toFront();
            return false;
          }
          //}}}
          function trackTouchMove(e) //{{{
          {
            e.pageX = e.originalEvent.changedTouches[0].pageX;
            e.pageY = e.originalEvent.changedTouches[0].pageY;
            return trackMove(e);
          }
          //}}}
          function trackTouchEnd(e) //{{{
          {
            e.pageX = e.originalEvent.changedTouches[0].pageX;
            e.pageY = e.originalEvent.changedTouches[0].pageY;
            return trackUp(e);
          }
          //}}}
          function setCursor(t) //{{{
          {
            $trk.css('cursor', t);
          }
          //}}}
    
          if (!trackDoc) {
            $trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);
          }
    
          $img.before($trk);
          return {
            activateHandlers: activateHandlers,
            setCursor: setCursor
          };
        }());
        //}}}
        // KeyManager Module {{{
        var KeyManager = (function () {
          var $keymgr = $('<input type="radio" />').css({
            position: 'fixed',
            left: '-120px',
            width: '12px'
          }),
              $keywrap = $('<div />').css({
              position: 'absolute',
              overflow: 'hidden'
            }).append($keymgr);
    
          function watchKeys() //{{{
          {
            if (options.keySupport) {
              $keymgr.show();
              $keymgr.focus();
            }
          }
          //}}}
          function onBlur(e) //{{{
          {
            $keymgr.hide();
          }
          //}}}
          function doNudge(e, x, y) //{{{
          {
            if (options.allowMove) {
              Coords.moveOffset([x, y]);
              Selection.updateVisible(true);
            }
            e.preventDefault();
            e.stopPropagation();
          }
          //}}}
          function parseKey(e) //{{{
          {
            if (e.ctrlKey || e.metaKey) {
              return true;
            }
            shift_down = e.shiftKey ? true : false;
            var nudge = shift_down ? 10 : 1;
    
            switch (e.keyCode) {
            case 37:
              doNudge(e, -nudge, 0);
              break;
            case 39:
              doNudge(e, nudge, 0);
              break;
            case 38:
              doNudge(e, 0, -nudge);
              break;
            case 40:
              doNudge(e, 0, nudge);
              break;
            case 27:
              if (options.allowSelect) Selection.release();
              break;
            case 9:
              return true;
            }
    
            return false;
          }
          //}}}
    
          if (options.keySupport) {
            $keymgr.keydown(parseKey).blur(onBlur);
            if (ie6mode || !options.fixedSupport) {
              $keymgr.css({
                position: 'absolute',
                left: '-20px'
              });
              $keywrap.append($keymgr).insertBefore($img);
            } else {
              $keymgr.insertBefore($img);
            }
          }
    
    
          return {
            watchKeys: watchKeys
          };
        }());
        //}}}
        // }}}
        // API methods {{{
        function setClass(cname) //{{{
        {
          $div.removeClass().addClass(cssClass('holder')).addClass(cname);
        }
        //}}}
        function animateTo(a, callback) //{{{
        {
          var x1 = a[0] / xscale,
              y1 = a[1] / yscale,
              x2 = a[2] / xscale,
              y2 = a[3] / yscale;
    
          if (animating) {
            return;
          }
    
          var animto = Coords.flipCoords(x1, y1, x2, y2),
              c = Coords.getFixed(),
              initcr = [c.x, c.y, c.x2, c.y2],
              animat = initcr,
              interv = options.animationDelay,
              ix1 = animto[0] - initcr[0],
              iy1 = animto[1] - initcr[1],
              ix2 = animto[2] - initcr[2],
              iy2 = animto[3] - initcr[3],
              pcent = 0,
              velocity = options.swingSpeed;
    
          x = animat[0];
          y = animat[1];
          x2 = animat[2];
          y2 = animat[3];
    
          Selection.animMode(true);
          var anim_timer;
    
          function queueAnimator() {
            window.setTimeout(animator, interv);
          }
          var animator = (function () {
            return function () {
              pcent += (100 - pcent) / velocity;
    
              animat[0] = x + ((pcent / 100) * ix1);
              animat[1] = y + ((pcent / 100) * iy1);
              animat[2] = x2 + ((pcent / 100) * ix2);
              animat[3] = y2 + ((pcent / 100) * iy2);
    
              if (pcent >= 99.8) {
                pcent = 100;
              }
              if (pcent < 100) {
                setSelectRaw(animat);
                queueAnimator();
              } else {
                Selection.done();
                if (typeof(callback) === 'function') {
                  callback.call(api);
                }
              }
            };
          }());
          queueAnimator();
        }
        //}}}
        function setSelect(rect) //{{{
        {
          setSelectRaw([rect[0] / xscale, rect[1] / yscale, rect[2] / xscale, rect[3] / yscale]);
          options.onSelect.call(api, unscale(Coords.getFixed()));
          Selection.enableHandles();
        }
        //}}}
        function setSelectRaw(l) //{{{
        {
          Coords.setPressed([l[0], l[1]]);
          Coords.setCurrent([l[2], l[3]]);
          Selection.update();
        }
        //}}}
        function tellSelect() //{{{
        {
          return unscale(Coords.getFixed());
        }
        //}}}
        function tellScaled() //{{{
        {
          return Coords.getFixed();
        }
        //}}}
        function setOptionsNew(opt) //{{{
        {
          setOptions(opt);
          interfaceUpdate();
        }
        //}}}
        function disableCrop() //{{{
        {
          options.disabled = true;
          Selection.disableHandles();
          Selection.setCursor('default');
          Tracker.setCursor('default');
        }
        //}}}
        function enableCrop() //{{{
        {
          options.disabled = false;
          interfaceUpdate();
        }
        //}}}
        function cancelCrop() //{{{
        {
          Selection.done();
          Tracker.activateHandlers(null, null);
        }
        //}}}
        function destroy() //{{{
        {
          $div.remove();
          $origimg.show();
          $(obj).removeData('Jcrop');
        }
        //}}}
        function setImage(src, callback) //{{{
        {
          Selection.release();
          disableCrop();
          var img = new Image();
          img.onload = function () {
            var iw = img.width;
            var ih = img.height;
            var bw = options.boxWidth;
            var bh = options.boxHeight;
            $img.width(iw).height(ih);
            $img.attr('src', src);
            $img2.attr('src', src);
            presize($img, bw, bh);
            boundx = $img.width();
            boundy = $img.height();
            $img2.width(boundx).height(boundy);
            $trk.width(boundx + (bound * 2)).height(boundy + (bound * 2));
            $div.width(boundx).height(boundy);
            Shade.resize(boundx,boundy);
            enableCrop();
    
            if (typeof(callback) === 'function') {
              callback.call(api);
            }
          };
          img.src = src;
        }
        //}}}
        function colorChangeMacro($obj,color,now) {
          var mycolor = color || options.bgColor;
          if (options.bgFade && supportsColorFade() && options.fadeTime && !now) {
            $obj.animate({
              backgroundColor: mycolor
            }, {
              queue: false,
              duration: options.fadeTime
            });
          } else {
            $obj.css('backgroundColor', mycolor);
          }
        }
        function interfaceUpdate(alt) //{{{
        // This method tweaks the interface based on options object.
        // Called when options are changed and at end of initialization.
        {
          if (options.allowResize) {
            if (alt) {
              Selection.enableOnly();
            } else {
              Selection.enableHandles();
            }
          } else {
            Selection.disableHandles();
          }
    
          Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');
          Selection.setCursor(options.allowMove ? 'move' : 'default');
    
          if (options.hasOwnProperty('trueSize')) {
            xscale = options.trueSize[0] / boundx;
            yscale = options.trueSize[1] / boundy;
          }
    
          if (options.hasOwnProperty('setSelect')) {
            setSelect(options.setSelect);
            Selection.done();
            delete(options.setSelect);
          }
    
          Shade.refresh();
    
          if (options.bgColor != bgcolor) {
            colorChangeMacro(
              options.shade? Shade.getShades(): $div,
              options.shade?
                (options.shadeColor || options.bgColor):
                options.bgColor
            );
            bgcolor = options.bgColor;
          }
    
          if (bgopacity != options.bgOpacity) {
            bgopacity = options.bgOpacity;
            if (options.shade) Shade.refresh();
              else Selection.setBgOpacity(bgopacity);
          }
    
          xlimit = options.maxSize[0] || 0;
          ylimit = options.maxSize[1] || 0;
          xmin = options.minSize[0] || 0;
          ymin = options.minSize[1] || 0;
    
          if (options.hasOwnProperty('outerImage')) {
            $img.attr('src', options.outerImage);
            delete(options.outerImage);
          }
    
          Selection.refresh();
        }
        //}}}
        //}}}
    
        if (Touch.support) $trk.bind('touchstart.jcrop', Touch.newSelection);
    
        $hdl_holder.hide();
        interfaceUpdate(true);
    
        var api = {
          setImage: setImage,
          animateTo: animateTo,
          setSelect: setSelect,
          setOptions: setOptionsNew,
          tellSelect: tellSelect,
          tellScaled: tellScaled,
          setClass: setClass,
    
          disable: disableCrop,
          enable: enableCrop,
          cancel: cancelCrop,
          release: Selection.release,
          destroy: destroy,
    
          focus: KeyManager.watchKeys,
    
          getBounds: function () {
            return [boundx * xscale, boundy * yscale];
          },
          getWidgetSize: function () {
            return [boundx, boundy];
          },
          getScaleFactor: function () {
            return [xscale, yscale];
          },
          getOptions: function() {
            // careful: internal values are returned
            return options;
          },
    
          ui: {
            holder: $div,
            selection: $sel
          }
        };
    
        if ($.browser.msie)
          $div.bind('selectstart', function () { return false; });
    
        $origimg.data('Jcrop', api);
        return api;
      };
      $.fn.Jcrop = function (options, callback) //{{{
      {
        var api;
        // Iterate over each object, attach Jcrop
        this.each(function () {
          // If we've already attached to this object
          if ($(this).data('Jcrop')) {
            // The API can be requested this way (undocumented)
            if (options === 'api') return $(this).data('Jcrop');
            // Otherwise, we just reset the options...
            else $(this).data('Jcrop').setOptions(options);
          }
          // If we haven't been attached, preload and attach
          else {
            if (this.tagName == 'IMG')
              $.Jcrop.Loader(this,function(){
                $(this).css({display:'block',visibility:'hidden'});
                api = $.Jcrop(this, options);
                if ($.isFunction(callback)) callback.call(api);
              });
            else {
              $(this).css({display:'block',visibility:'hidden'});
              api = $.Jcrop(this, options);
              if ($.isFunction(callback)) callback.call(api);
            }
          }
        });
    
        // Return "this" so the object is chainable (jQuery-style)
        return this;
      };
      //}}}
      // $.Jcrop.Loader - basic image loader {{{
    
      $.Jcrop.Loader = function(imgobj,success,error){
        var $img = $(imgobj), img = $img[0];
    
        function completeCheck(){
          if (img.complete) {
            $img.unbind('.jcloader');
            if ($.isFunction(success)) success.call(img);
          }
          else window.setTimeout(completeCheck,50);
        }
    
        $img
          .bind('load.jcloader',completeCheck)
          .bind('error.jcloader',function(e){
            $img.unbind('.jcloader');
            if ($.isFunction(error)) error.call(img);
          });
    
        if (img.complete && $.isFunction(success)){
          $img.unbind('.jcloader');
          success.call(img);
        }
      };
    
      //}}}
      // Global Defaults {{{
      $.Jcrop.defaults = {
    
        // Basic Settings
        allowSelect: true,
        allowMove: true,
        allowResize: true,
    
        trackDocument: true,
    
        // Styling Options
        baseClass: 'jcrop',
        addClass: null,
        bgColor: 'black',
        bgOpacity: 0.6,
        bgFade: false,
        borderOpacity: 0.4,
        handleOpacity: 0.5,
        handleSize: 7,
    
        aspectRatio: 0,
        keySupport: true,
        createHandles: ['n','s','e','w','nw','ne','se','sw'],
        createDragbars: ['n','s','e','w'],
        createBorders: ['n','s','e','w'],
        drawBorders: true,
        dragEdges: true,
        fixedSupport: true,
        touchSupport: null,
    
        shade: null,
    
        boxWidth: 0,
        boxHeight: 0,
        boundary: 2,
        fadeTime: 400,
        animationDelay: 20,
        swingSpeed: 3,
    
        minSelect: [0, 0],
        maxSize: [0, 0],
        minSize: [0, 0],
    
        // Callbacks / Event Handlers
        onChange: function () {},
        onSelect: function () {},
        onDblClick: function () {},
        onRelease: function () {}
      };
    
      // }}}
    }(jQuery));
    
    
    ================================================
    FILE: set/Jcrop/js/jquery.color.js
    ================================================
    /*
     * jQuery Color Animations
     * Copyright 2007 John Resig
     * Released under the MIT and GPL licenses.
     */
    
    (function(jQuery){
    
    	// We override the animation for all of these color styles
    	jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
    		jQuery.fx.step[attr] = function(fx){
    			if ( fx.state == 0 ) {
    				fx.start = getColor( fx.elem, attr );
    				fx.end = getRGB( fx.end );
    			}
    
    			fx.elem.style[attr] = "rgb(" + [
    				Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
    				Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
    				Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
    			].join(",") + ")";
    		}
    	});
    
    	// Color Conversion functions from highlightFade
    	// By Blair Mitchelmore
    	// http://jquery.offput.ca/highlightFade/
    
    	// Parse strings looking for color tuples [255,255,255]
    	function getRGB(color) {
    		var result;
    
    		// Check if we're already dealing with an array of colors
    		if ( color && color.constructor == Array && color.length == 3 )
    			return color;
    
    		// Look for rgb(num,num,num)
    		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
    			return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
    
    		// Look for rgb(num%,num%,num%)
    		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
    			return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
    
    		// Look for #a0b1c2
    		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
    			return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
    
    		// Look for #fff
    		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
    			return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
    
    		// Otherwise, we're most likely dealing with a named color
    		return colors[jQuery.trim(color).toLowerCase()];
    	}
    	
    	function getColor(elem, attr) {
    		var color;
    
    		do {
    			color = jQuery.curCSS(elem, attr);
    
    			// Keep going until we find an element that has color, or we hit the body
    			if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") )
    				break; 
    
    			attr = "backgroundColor";
    		} while ( elem = elem.parentNode );
    
    		return getRGB(color);
    	};
    	
    	// Some named colors to work with
    	// From Interface by Stefan Petre
    	// http://interface.eyecon.ro/
    
    	var colors = {
    		aqua:[0,255,255],
    		azure:[240,255,255],
    		beige:[245,245,220],
    		black:[0,0,0],
    		blue:[0,0,255],
    		brown:[165,42,42],
    		cyan:[0,255,255],
    		darkblue:[0,0,139],
    		darkcyan:[0,139,139],
    		darkgrey:[169,169,169],
    		darkgreen:[0,100,0],
    		darkkhaki:[189,183,107],
    		darkmagenta:[139,0,139],
    		darkolivegreen:[85,107,47],
    		darkorange:[255,140,0],
    		darkorchid:[153,50,204],
    		darkred:[139,0,0],
    		darksalmon:[233,150,122],
    		darkviolet:[148,0,211],
    		fuchsia:[255,0,255],
    		gold:[255,215,0],
    		green:[0,128,0],
    		indigo:[75,0,130],
    		khaki:[240,230,140],
    		lightblue:[173,216,230],
    		lightcyan:[224,255,255],
    		lightgreen:[144,238,144],
    		lightgrey:[211,211,211],
    		lightpink:[255,182,193],
    		lightyellow:[255,255,224],
    		lime:[0,255,0],
    		magenta:[255,0,255],
    		maroon:[128,0,0],
    		navy:[0,0,128],
    		olive:[128,128,0],
    		orange:[255,165,0],
    		pink:[255,192,203],
    		purple:[128,0,128],
    		violet:[128,0,128],
    		red:[255,0,0],
    		silver:[192,192,192],
    		white:[255,255,255],
    		yellow:[255,255,0]
    	};
    	
    })(jQuery);
    
    
    ================================================
    FILE: set/avatar.html
    ================================================
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <link rel="stylesheet" type="text/css" href="css/avatar.css" media="all">
        <style type="text/css">
    
            body{background: #fafafa;}
            button{clear: both;display: block;padding:5px 15px;}
        </style>
    </head>
    <body>
    <div class="avatarbox">
        <div class="imgproview_b">
            <div class="imgcenter">
                <input style="display: none" type="file" name="" id="uploadpic">
            </div>
        </div>
        <div class="imgproview">
            <div class="imgbox_b"><div></div><span>中尺寸头像50×50像素</span></div>
            <div class="imgbox_s"><div></div><span>小尺寸头像30×30像素</span></div>
        </div>
        <button>保存头像</button>
    </div>
    <script type="text/javascript" src="js/jQuery-1.7.1.min.js"></script>
    <script type="text/javascript" src="uploadify/jquery.uploadify-3.1.min.js"></script>
    <script type="text/javascript" src="js/jquery.Jcrop.js"></script>
    <script type="text/javascript">
        $(function($){
            $("#uploadpic").uploadify({
                auto:true,
                height: 36,
                swf: 'uploadify/uploadify.swf',
                uploader: 'avatar.html',
                width: 101,
                buttonText:"",
                onUploadStart:function(file){
                    $(".imgcenter").html("").addClass("uploading");
                },
                onUploadSuccess:function(file, data, response){
                    userAvatar(data);//返回的data值为图片的地址
                },
                onUploadError:function(data){
    
                }
            });
            function userAvatar(picUrl){
                $(".imgcenter").html("<img src="+picUrl+" id='target' alt='Flowers' />").addClass("uploadcomplete");
                $(".imgbox_b div").append("<img src="+picUrl+" id='preview_b' alt='Preview' class='jcrop-preview' />");
                $(".imgbox_s div").append("<img src="+picUrl+" id='preview_s' alt='Preview' class='jcrop-preview' />");
                $(".imgproview").append('<div class="imgbox_s"><a href="javacript:;">重新上传</a></div>');
                var jcrop_api, boundx, boundy;
                $('#target').Jcrop({onChange: updatePreview,onSelect: updatePreview,bgOpacity:   .8,aspectRatio: 1},function(){
                    var bounds = this.getBounds();boundx = bounds[0];boundy = bounds[1];jcrop_api = this;});
                function updatePreview(c){
                    if (parseInt(c.w) > 0){
                        var rxb = 50 / c.w,ryb = 50 / c.h,rxs = 30 / c.w,rys = 30 / c.h;
                        $('#preview_b').css({width: Math.round(rxb * boundx) + 'px',height: Math.round(ryb * boundy) + 'px',marginLeft: '-' + Math.round(rxb * c.x) + 'px', marginTop: '-' + Math.round(ryb * c.y) + 'px'});
                        $('#preview_s').css({width: Math.round(rxs * boundx) + 'px',height: Math.round(rys * boundy) + 'px',marginLeft: '-' + Math.round(rxs * c.x) + 'px',marginTop: '-' + Math.round(rys * c.y) + 'px'});
                    }
                };
            }
        });
    </script>
    </body>
    </html>
    
    ================================================
    FILE: set/css/avatar.css
    ================================================
    *{padding:0;margin:0;}
    img{border:none;}
    .jcrop-holder {direction: ltr;text-align: left;}
    .jcrop-vline,.jcrop-hline{background:#FFF url(../img/Jcrop.gif) top left repeat;font-size:0;position:absolute;}
    .jcrop-vline{height:100%;width:1px!important;}
    .jcrop-hline{height:1px!important;width:100%;}
    .jcrop-vline.right{right:0;}
    .jcrop-hline.bottom{bottom:0;}
    .jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}
    .jcrop-tracker{height: 100%; width: 100%;-webkit-tap-highlight-color: transparent;-webkit-touch-callout: none; -webkit-user-select: none;}
    .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
    .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
    .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
    .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
    .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
    .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
    .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
    .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
    .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
    .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
    .jcrop-dragbar.ord-n{margin-top:-4px;}
    .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
    .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
    .jcrop-dragbar.ord-w{margin-left:-4px;}
    .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:Alpha(opacity=70)!important;opacity:.70!important;}
    .jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
    .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:Alpha(opacity=70)!important;opacity:.7!important;}
    .jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;	border-radius:3px;}
    .jcrop-holder img,img.jcrop-preview{ max-width: none; }
    
    .avatarbox{background: #fff;width: 352px; height:280px;}
    .avatarbox .imgcenter{background: url(../img/avatar_bg.png) no-repeat;border:solid 1px #eee;width:280px;height:280px;overflow: hidden;display:table-cell;text-align:center;vertical-align:middle;*display:block;font-size:280px;+font-size:270px; }
    .avatarbox .uploading{background:#fafafa url(../img/loading.gif) no-repeat center center;}
    .avatarbox .uploadcomplete{background: #fff;}
    .avatarbox .imgcenter img{display:block;max-height: 280px;max-width: 280px;vertical-align: middle;}
    .avatarbox .imgproview_b{float: left;}
    .avatarbox .imgproview{float: left;margin-left:10px;width: 60px;}
    .avatarbox .imgproview a{font-size: 12px;display: block;color:#666;display: block;width:60px;height: 21px;background: url("../img/favc_btn.png") no-repeat; text-align: center;line-height: 21px; text-decoration: none;}
    .avatarbox .imgproview a:hover{background-position: 0 bottom;color:#333;}
    .avatarbox .imgbox_b{height:100px; text-align: center}
    .avatarbox .imgbox_b div{width:50px;height:50px;overflow:hidden;margin:0 auto;background: #fafafa;}
    .avatarbox .imgbox_s{height:86px; text-align: center}
    .avatarbox .imgbox_s div{width:30px;height:30px;overflow:hidden;margin:0 auto;background: #fafafa;}
    .avatarbox .imgproview span{color:#999;font-size: 12px;line-height:1.2;display:block;margin:5px 0;}
    
    #uploadpic{margin:120px auto 0 auto;+margin-top:-26px;_margin-top:180px;}
    .avatarbox .imgcenter .uploadify-error {background-color: #FDE5DD !important;font-size:12px;}
    .avatarbox .imgcenter .uploadify-error a{display: none;}
    .uploadify {position: relative;margin-bottom: 1em;}
    .swfupload{background:transparent;_margin:0 0 0 -50px;}
    .uploadify-button {background: url(../img/upload_btn.png) no-repeat;width: 100%;}
    .uploadify:hover .uploadify-button {background-position:0 -36px;}
    .uploadify-error {background-color: #FDE5DD !important;font-size:12px !important;}
    .uploadify-error a{display: none;}
    .uploadify-progress {background-color: #E5E5E5;margin-top: 10px;width: 100%;}
    .uploadify-progress-bar {background-color: #0099FF;height: 3px;	width: 1px;}
    
    ================================================
    FILE: set/js/jquery.Jcrop.js
    ================================================
    /**
     * jquery.Jcrop.js v0.9.10
     * jQuery Image Cropping Plugin - released under MIT License 
     * Author: Kelly Hallman <khallman@gmail.com>
     * http://github.com/tapmodo/Jcrop
     * Copyright (c) 2008-2012 Tapmodo Interactive LLC {{{
     *
     * Permission is hereby granted, free of charge, to any person
     * obtaining a copy of this software and associated documentation
     * files (the "Software"), to deal in the Software without
     * restriction, including without limitation the rights to use,
     * copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the
     * Software is furnished to do so, subject to the following
     * conditions:
     *
     * The above copyright notice and this permission notice shall be
     * included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     * OTHER DEALINGS IN THE SOFTWARE.
     *
     * }}}
     */
    
    (function ($) {
    
      $.Jcrop = function (obj, opt) {
        var options = $.extend({}, $.Jcrop.defaults),
            docOffset, lastcurs, ie6mode = false;
    
        // Internal Methods {{{
        function px(n) {
          return n + 'px';
        }
        function cssClass(cl) {
          return options.baseClass + '-' + cl;
        }
        function supportsColorFade() {
          return $.fx.step.hasOwnProperty('backgroundColor');
        }
        function getPos(obj) //{{{
        {
          var pos = $(obj).offset();
          return [pos.left, pos.top];
        }
        //}}}
        function mouseAbs(e) //{{{
        {
          return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];
        }
        //}}}
        function setOptions(opt) //{{{
        {
          if (typeof(opt) !== 'object') opt = {};
          options = $.extend(options, opt);
    
          $.each(['onChange','onSelect','onRelease','onDblClick'],function(i,e) {
            if (typeof(options[e]) !== 'function') options[e] = function () {};
          });
        }
        //}}}
        function startDragMode(mode, pos) //{{{
        {
          docOffset = getPos($img);
          Tracker.setCursor(mode === 'move' ? mode : mode + '-resize');
    
          if (mode === 'move') {
            return Tracker.activateHandlers(createMover(pos), doneSelect);
          }
    
          var fc = Coords.getFixed();
          var opp = oppLockCorner(mode);
          var opc = Coords.getCorner(oppLockCorner(opp));
    
          Coords.setPressed(Coords.getCorner(opp));
          Coords.setCurrent(opc);
    
          Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect);
        }
        //}}}
        function dragmodeHandler(mode, f) //{{{
        {
          return function (pos) {
            if (!options.aspectRatio) {
              switch (mode) {
              case 'e':
                pos[1] = f.y2;
                break;
              case 'w':
                pos[1] = f.y2;
                break;
              case 'n':
                pos[0] = f.x2;
                break;
              case 's':
                pos[0] = f.x2;
                break;
              }
            } else {
              switch (mode) {
              case 'e':
                pos[1] = f.y + 1;
                break;
              case 'w':
                pos[1] = f.y + 1;
                break;
              case 'n':
                pos[0] = f.x + 1;
                break;
              case 's':
                pos[0] = f.x + 1;
                break;
              }
            }
            Coords.setCurrent(pos);
            Selection.update();
          };
        }
        //}}}
        function createMover(pos) //{{{
        {
          var lloc = pos;
          KeyManager.watchKeys();
    
          return function (pos) {
            Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);
            lloc = pos;
    
            Selection.update();
          };
        }
        //}}}
        function oppLockCorner(ord) //{{{
        {
          switch (ord) {
          case 'n':
            return 'sw';
          case 's':
            return 'nw';
          case 'e':
            return 'nw';
          case 'w':
            return 'ne';
          case 'ne':
            return 'sw';
          case 'nw':
            return 'se';
          case 'se':
            return 'nw';
          case 'sw':
            return 'ne';
          }
        }
        //}}}
        function createDragger(ord) //{{{
        {
          return function (e) {
            if (options.disabled) {
              return false;
            }
            if ((ord === 'move') && !options.allowMove) {
              return false;
            }
            
            // Fix position of crop area when dragged the very first time.
            // Necessary when crop image is in a hidden element when page is loaded.
            docOffset = getPos($img);
    
            btndown = true;
            startDragMode(ord, mouseAbs(e));
            e.stopPropagation();
            e.preventDefault();
            return false;
          };
        }
        //}}}
        function presize($obj, w, h) //{{{
        {
          var nw = $obj.width(),
              nh = $obj.height();
          if ((nw > w) && w > 0) {
            nw = w;
            nh = (w / $obj.width()) * $obj.height();
          }
          if ((nh > h) && h > 0) {
            nh = h;
            nw = (h / $obj.height()) * $obj.width();
          }
          xscale = $obj.width() / nw;
          yscale = $obj.height() / nh;
          $obj.width(nw).height(nh);
        }
        //}}}
        function unscale(c) //{{{
        {
          return {
            x: c.x * xscale,
            y: c.y * yscale,
            x2: c.x2 * xscale,
            y2: c.y2 * yscale,
            w: c.w * xscale,
            h: c.h * yscale
          };
        }
        //}}}
        function doneSelect(pos) //{{{
        {
          var c = Coords.getFixed();
          if ((c.w > options.minSelect[0]) && (c.h > options.minSelect[1])) {
            Selection.enableHandles();
            Selection.done();
          } else {
            Selection.release();
          }
          Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');
        }
        //}}}
        function newSelection(e) //{{{
        {
          if (options.disabled) {
            return false;
          }
          if (!options.allowSelect) {
            return false;
          }
          btndown = true;
          docOffset = getPos($img);
          Selection.disableHandles();
          Tracker.setCursor('crosshair');
          var pos = mouseAbs(e);
          Coords.setPressed(pos);
          Selection.update();
          Tracker.activateHandlers(selectDrag, doneSelect);
          KeyManager.watchKeys();
    
          e.stopPropagation();
          e.preventDefault();
          return false;
        }
        //}}}
        function selectDrag(pos) //{{{
        {
          Coords.setCurrent(pos);
          Selection.update();
        }
        //}}}
        function newTracker() //{{{
        {
          var trk = $('<div></div>').addClass(cssClass('tracker'));
          if ($.browser.msie) {
            trk.css({
              opacity: 0,
              backgroundColor: 'white'
            });
          }
          return trk;
        }
        //}}}
    
        // }}}
        // Initialization {{{
        // Sanitize some options {{{
        if ($.browser.msie && ($.browser.version.split('.')[0] === '6')) {
          ie6mode = true;
        }
        if (typeof(obj) !== 'object') {
          obj = $(obj)[0];
        }
        if (typeof(opt) !== 'object') {
          opt = {};
        }
        // }}}
        setOptions(opt);
        // Initialize some jQuery objects {{{
        // The values are SET on the image(s) for the interface
        // If the original image has any of these set, they will be reset
        // However, if you destroy() the Jcrop instance the original image's
        // character in the DOM will be as you left it.
        var img_css = {
          border: 'none',
          visibility: 'visible',
          margin: 0,
          padding: 0,
          position: 'absolute',
          top: 0,
          left: 0
        };
    
        var $origimg = $(obj),
          img_mode = true;
    
        if (obj.tagName == 'IMG') {
          // Fix size of crop image.
          // Necessary when crop image is within a hidden element when page is loaded.
          if ($origimg[0].width != 0 && $origimg[0].height != 0) {
            // Obtain dimensions from contained img element.
            $origimg.width($origimg[0].width);
            $origimg.height($origimg[0].height);
          } else {
            // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0). 
            var tempImage = new Image();
            tempImage.src = $origimg[0].src;
            $origimg.width(tempImage.width);
            $origimg.height(tempImage.height);
          } 
    
          var $img = $origimg.clone().removeAttr('id').css(img_css).show();
    
          $img.width($origimg.width());
          $img.height($origimg.height());
          $origimg.after($img).hide();
    
        } else {
          $img = $origimg.css(img_css).show();
          img_mode = false;
          if (options.shade === null) { options.shade = true; }
        }
    
        presize($img, options.boxWidth, options.boxHeight);
    
        var boundx = $img.width(),
            boundy = $img.height(),
            
            
            $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({
            position: 'relative',
            backgroundColor: options.bgColor
          }).insertAfter($origimg).append($img);
    
        if (options.addClass) {
          $div.addClass(options.addClass);
        }
    
        var $img2 = $('<div />'),
    
            $img_holder = $('<div />') 
            .width('100%').height('100%').css({
              zIndex: 310,
              position: 'absolute',
              overflow: 'hidden'
            }),
    
            $hdl_holder = $('<div />') 
            .width('100%').height('100%').css('zIndex', 320), 
    
            $sel = $('<div />') 
            .css({
              position: 'absolute',
              zIndex: 600
            }).dblclick(function(){
              var c = Coords.getFixed();
              options.onDblClick.call(api,c);
            }).insertBefore($img).append($img_holder, $hdl_holder); 
    
        if (img_mode) {
    
          $img2 = $('<img />')
              .attr('src', $img.attr('src')).css(img_css).width(boundx).height(boundy),
    
          $img_holder.append($img2);
    
        }
    
        if (ie6mode) {
          $sel.css({
            overflowY: 'hidden'
          });
        }
    
        var bound = options.boundary;
        var $trk = newTracker().width(boundx + (bound * 2)).height(boundy + (bound * 2)).css({
          position: 'absolute',
          top: px(-bound),
          left: px(-bound),
          zIndex: 290
        }).mousedown(newSelection);
    
        /* }}} */
        // Set more variables {{{
        var bgcolor = options.bgColor,
            bgopacity = options.bgOpacity,
            xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true,
            btndown, animating, shift_down;
    
        docOffset = getPos($img);
        // }}}
        // }}}
        // Internal Modules {{{
        // Touch Module {{{ 
        var Touch = (function () {
          // Touch support detection function adapted (under MIT License)
          // from code by Jeffrey Sambells - http://github.com/iamamused/
          function hasTouchSupport() {
            var support = {},
                events = ['touchstart', 'touchmove', 'touchend'],
                el = document.createElement('div'), i;
    
            try {
              for(i=0; i<events.length; i++) {
                var eventName = events[i];
                eventName = 'on' + eventName;
                var isSupported = (eventName in el);
                if (!isSupported) {
                  el.setAttribute(eventName, 'return;');
                  isSupported = typeof el[eventName] == 'function';
                }
                support[events[i]] = isSupported;
              }
              return support.touchstart && support.touchend && support.touchmove;
            }
            catch(err) {
              return false;
            }
          }
    
          function detectSupport() {
            if ((options.touchSupport === true) || (options.touchSupport === false)) return options.touchSupport;
              else return hasTouchSupport();
          }
          return {
            createDragger: function (ord) {
              return function (e) {
                e.pageX = e.originalEvent.changedTouches[0].pageX;
                e.pageY = e.originalEvent.changedTouches[0].pageY;
                if (options.disabled) {
                  return false;
                }
                if ((ord === 'move') && !options.allowMove) {
                  return false;
                }
                btndown = true;
                startDragMode(ord, mouseAbs(e));
                e.stopPropagation();
                e.preventDefault();
                return false;
              };
            },
            newSelection: function (e) {
              e.pageX = e.originalEvent.changedTouches[0].pageX;
              e.pageY = e.originalEvent.changedTouches[0].pageY;
              return newSelection(e);
            },
            isSupported: hasTouchSupport,
            support: detectSupport()
          };
        }());
        // }}}
        // Coords Module {{{
        var Coords = (function () {
          var x1 = 0,
              y1 = 0,
              x2 = 0,
              y2 = 0,
              ox, oy;
    
          function setPressed(pos) //{{{
          {
            pos = rebound(pos);
            x2 = x1 = pos[0];
            y2 = y1 = pos[1];
          }
          //}}}
          function setCurrent(pos) //{{{
          {
            pos = rebound(pos);
            ox = pos[0] - x2;
            oy = pos[1] - y2;
            x2 = pos[0];
            y2 = pos[1];
          }
          //}}}
          function getOffset() //{{{
          {
            return [ox, oy];
          }
          //}}}
          function moveOffset(offset) //{{{
          {
            var ox = offset[0],
                oy = offset[1];
    
            if (0 > x1 + ox) {
              ox -= ox + x1;
            }
            if (0 > y1 + oy) {
              oy -= oy + y1;
            }
    
            if (boundy < y2 + oy) {
              oy += boundy - (y2 + oy);
            }
            if (boundx < x2 + ox) {
              ox += boundx - (x2 + ox);
            }
    
            x1 += ox;
            x2 += ox;
            y1 += oy;
            y2 += oy;
          }
          //}}}
          function getCorner(ord) //{{{
          {
            var c = getFixed();
            switch (ord) {
            case 'ne':
              return [c.x2, c.y];
            case 'nw':
              return [c.x, c.y];
            case 'se':
              return [c.x2, c.y2];
            case 'sw':
              return [c.x, c.y2];
            }
          }
          //}}}
          function getFixed() //{{{
          {
            if (!options.aspectRatio) {
              return getRect();
            }
            // This function could use some optimization I think...
            var aspect = options.aspectRatio,
                min_x = options.minSize[0] / xscale,
                
                
                //min_y = options.minSize[1]/yscale,
                max_x = options.maxSize[0] / xscale,
                max_y = options.maxSize[1] / yscale,
                rw = x2 - x1,
                rh = y2 - y1,
                rwa = Math.abs(rw),
                rha = Math.abs(rh),
                real_ratio = rwa / rha,
                xx, yy, w, h;
    
            if (max_x === 0) {
              max_x = boundx * 10;
            }
            if (max_y === 0) {
              max_y = boundy * 10;
            }
            if (real_ratio < aspect) {
              yy = y2;
              w = rha * aspect;
              xx = rw < 0 ? x1 - w : w + x1;
    
              if (xx < 0) {
                xx = 0;
                h = Math.abs((xx - x1) / aspect);
                yy = rh < 0 ? y1 - h : h + y1;
              } else if (xx > boundx) {
                xx = boundx;
                h = Math.abs((xx - x1) / aspect);
                yy = rh < 0 ? y1 - h : h + y1;
              }
            } else {
              xx = x2;
              h = rwa / aspect;
              yy = rh < 0 ? y1 - h : y1 + h;
              if (yy < 0) {
                yy = 0;
                w = Math.abs((yy - y1) * aspect);
                xx = rw < 0 ? x1 - w : w + x1;
              } else if (yy > boundy) {
                yy = boundy;
                w = Math.abs(yy - y1) * aspect;
                xx = rw < 0 ? x1 - w : w + x1;
              }
            }
    
            // Magic %-)
            if (xx > x1) { // right side
              if (xx - x1 < min_x) {
                xx = x1 + min_x;
              } else if (xx - x1 > max_x) {
                xx = x1 + max_x;
              }
              if (yy > y1) {
                yy = y1 + (xx - x1) / aspect;
              } else {
                yy = y1 - (xx - x1) / aspect;
              }
            } else if (xx < x1) { // left side
              if (x1 - xx < min_x) {
                xx = x1 - min_x;
              } else if (x1 - xx > max_x) {
                xx = x1 - max_x;
              }
              if (yy > y1) {
                yy = y1 + (x1 - xx) / aspect;
              } else {
                yy = y1 - (x1 - xx) / aspect;
              }
            }
    
            if (xx < 0) {
              x1 -= xx;
              xx = 0;
            } else if (xx > boundx) {
              x1 -= xx - boundx;
              xx = boundx;
            }
    
            if (yy < 0) {
              y1 -= yy;
              yy = 0;
            } else if (yy > boundy) {
              y1 -= yy - boundy;
              yy = boundy;
            }
    
            return makeObj(flipCoords(x1, y1, xx, yy));
          }
          //}}}
          function rebound(p) //{{{
          {
            if (p[0] < 0) {
              p[0] = 0;
            }
            if (p[1] < 0) {
              p[1] = 0;
            }
    
            if (p[0] > boundx) {
              p[0] = boundx;
            }
            if (p[1] > boundy) {
              p[1] = boundy;
            }
    
            return [p[0], p[1]];
          }
          //}}}
          function flipCoords(x1, y1, x2, y2) //{{{
          {
            var xa = x1,
                xb = x2,
                ya = y1,
                yb = y2;
            if (x2 < x1) {
              xa = x2;
              xb = x1;
            }
            if (y2 < y1) {
              ya = y2;
              yb = y1;
            }
            return [xa, ya, xb, yb];
          }
          //}}}
          function getRect() //{{{
          {
            var xsize = x2 - x1,
                ysize = y2 - y1,
                delta;
    
            if (xlimit && (Math.abs(xsize) > xlimit)) {
              x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);
            }
            if (ylimit && (Math.abs(ysize) > ylimit)) {
              y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);
            }
    
            if (ymin / yscale && (Math.abs(ysize) < ymin / yscale)) {
              y2 = (ysize > 0) ? (y1 + ymin / yscale) : (y1 - ymin / yscale);
            }
            if (xmin / xscale && (Math.abs(xsize) < xmin / xscale)) {
              x2 = (xsize > 0) ? (x1 + xmin / xscale) : (x1 - xmin / xscale);
            }
    
            if (x1 < 0) {
              x2 -= x1;
              x1 -= x1;
            }
            if (y1 < 0) {
              y2 -= y1;
              y1 -= y1;
            }
            if (x2 < 0) {
              x1 -= x2;
              x2 -= x2;
            }
            if (y2 < 0) {
              y1 -= y2;
              y2 -= y2;
            }
            if (x2 > boundx) {
              delta = x2 - boundx;
              x1 -= delta;
              x2 -= delta;
            }
            if (y2 > boundy) {
              delta = y2 - boundy;
              y1 -= delta;
              y2 -= delta;
            }
            if (x1 > boundx) {
              delta = x1 - boundy;
              y2 -= delta;
              y1 -= delta;
            }
            if (y1 > boundy) {
              delta = y1 - boundy;
              y2 -= delta;
              y1 -= delta;
            }
    
            return makeObj(flipCoords(x1, y1, x2, y2));
          }
          //}}}
          function makeObj(a) //{{{
          {
            return {
              x: a[0],
              y: a[1],
              x2: a[2],
              y2: a[3],
              w: a[2] - a[0],
              h: a[3] - a[1]
            };
          }
          //}}}
    
          return {
            flipCoords: flipCoords,
            setPressed: setPressed,
            setCurrent: setCurrent,
            getOffset: getOffset,
            moveOffset: moveOffset,
            getCorner: getCorner,
            getFixed: getFixed
          };
        }());
    
        //}}}
        // Shade Module {{{
        var Shade = (function() {
          var enabled = false,
              holder = $('<div />').css({
                position: 'absolute',
                zIndex: 240,
                opacity: 0
              }),
              shades = {
                top: createShade(),
                left: createShade().height(boundy),
                right: createShade().height(boundy),
                bottom: createShade()
              };
    
          function resizeShades(w,h) {
            shades.left.css({ height: px(h) });
            shades.right.css({ height: px(h) });
          }
          function updateAuto()
          {
            return updateShade(Coords.getFixed());
          }
          function updateShade(c)
          {
            shades.top.css({
              left: px(c.x),
              width: px(c.w),
              height: px(c.y)
            });
            shades.bottom.css({
              top: px(c.y2),
              left: px(c.x),
              width: px(c.w),
              height: px(boundy-c.y2)
            });
            shades.right.css({
              left: px(c.x2),
              width: px(boundx-c.x2)
            });
            shades.left.css({
              width: px(c.x)
            });
          }
          function createShade() {
            return $('<div />').css({
              position: 'absolute',
              backgroundColor: options.shadeColor||options.bgColor
            }).appendTo(holder);
          }
          function enableShade() {
            if (!enabled) {
              enabled = true;
              holder.insertBefore($img);
              updateAuto();
              Selection.setBgOpacity(1,0,1);
              $img2.hide();
    
              setBgColor(options.shadeColor||options.bgColor,1);
              if (Selection.isAwake())
              {
                setOpacity(options.bgOpacity,1);
              }
                else setOpacity(1,1);
            }
          }
          function setBgColor(color,now) {
            colorChangeMacro(getShades(),color,now);
          }
          function disableShade() {
            if (enabled) {
              holder.remove();
              $img2.show();
              enabled = false;
              if (Selection.isAwake()) {
                Selection.setBgOpacity(options.bgOpacity,1,1);
              } else {
                Selection.setBgOpacity(1,1,1);
                Selection.disableHandles();
              }
              colorChangeMacro($div,0,1);
            }
          }
          function setOpacity(opacity,now) {
            if (enabled) {
              if (options.bgFade && !now) {
                holder.animate({
                  opacity: 1-opacity
                },{
                  queue: false,
                  duration: options.fadeTime
                });
              }
              else holder.css({opacity:1-opacity});
            }
          }
          function refreshAll() {
            options.shade ? enableShade() : disableShade();
            if (Selection.isAwake()) setOpacity(options.bgOpacity);
          }
          function getShades() {
            return holder.children();
          }
    
          return {
            update: updateAuto,
            updateRaw: updateShade,
            getShades: getShades,
            setBgColor: setBgColor,
            enable: enableShade,
            disable: disableShade,
            resize: resizeShades,
            refresh: refreshAll,
            opacity: setOpacity
          };
        }());
        // }}}
        // Selection Module {{{
        var Selection = (function () {
          var awake,
              hdep = 370,
              borders = {},
              handle = {},
              dragbar = {},
              seehandles = false;
    
          // Private Methods
          function insertBorder(type) //{{{
          {
            var jq = $('<div />').css({
              position: 'absolute',
              opacity: options.borderOpacity
            }).addClass(cssClass(type));
            $img_holder.append(jq);
            return jq;
          }
          //}}}
          function dragDiv(ord, zi) //{{{
          {
            var jq = $('<div />').mousedown(createDragger(ord)).css({
              cursor: ord + '-resize',
              position: 'absolute',
              zIndex: zi
            }).addClass('ord-'+ord);
    
            if (Touch.support) {
              jq.bind('touchstart.jcrop', Touch.createDragger(ord));
            }
    
            $hdl_holder.append(jq);
            return jq;
          }
          //}}}
          function insertHandle(ord) //{{{
          {
            var hs = options.handleSize;
            return dragDiv(ord, hdep++).css({
              opacity: options.handleOpacity
            }).width(hs).height(hs).addClass(cssClass('handle'));
          }
          //}}}
          function insertDragbar(ord) //{{{
          {
            return dragDiv(ord, hdep++).addClass('jcrop-dragbar');
          }
          //}}}
          function createDragbars(li) //{{{
          {
            var i;
            for (i = 0; i < li.length; i++) {
              dragbar[li[i]] = insertDragbar(li[i]);
            }
          }
          //}}}
          function createBorders(li) //{{{
          {
            var cl,i;
            for (i = 0; i < li.length; i++) {
              switch(li[i]){
                case'n': cl='hline'; break;
                case's': cl='hline bottom'; break;
                case'e': cl='vline right'; break;
                case'w': cl='vline'; break;
              }
              borders[li[i]] = insertBorder(cl);
            }
          }
          //}}}
          function createHandles(li) //{{{
          {
            var i;
            for (i = 0; i < li.length; i++) {
              handle[li[i]] = insertHandle(li[i]);
            }
          }
          //}}}
          function moveto(x, y) //{{{
          {
            if (!options.shade) {
              $img2.css({
                top: px(-y),
                left: px(-x)
              });
            }
            $sel.css({
              top: px(y),
              left: px(x)
            });
          }
          //}}}
          function resize(w, h) //{{{
          {
            $sel.width(w).height(h);
          }
          //}}}
          function refresh() //{{{
          {
            var c = Coords.getFixed();
    
            Coords.setPressed([c.x, c.y]);
            Coords.setCurrent([c.x2, c.y2]);
    
            updateVisible();
          }
          //}}}
    
          // Internal Methods
          function updateVisible(select) //{{{
          {
            if (awake) {
              return update(select);
            }
          }
          //}}}
          function update(select) //{{{
          {
            var c = Coords.getFixed();
    
            resize(c.w, c.h);
            moveto(c.x, c.y);
            if (options.shade) Shade.updateRaw(c);
    
            awake || show();
    
            if (select) {
              options.onSelect.call(api, unscale(c));
            } else {
              options.onChange.call(api, unscale(c));
            }
          }
          //}}}
          function setBgOpacity(opacity,force,now) //{{{
          {
            if (!awake && !force) return;
            if (options.bgFade && !now) {
              $img.animate({
                opacity: opacity
              },{
                queue: false,
                duration: options.fadeTime
              });
            } else {
              $img.css('opacity', opacity);
            }
          }
          //}}}
          function show() //{{{
          {
            $sel.show();
    
            if (options.shade) Shade.opacity(bgopacity);
              else setBgOpacity(bgopacity,true);
    
            awake = true;
          }
          //}}}
          function release() //{{{
          {
            disableHandles();
            $sel.hide();
    
            if (options.shade) Shade.opacity(1);
              else setBgOpacity(1);
    
            awake = false;
            options.onRelease.call(api);
          }
          //}}}
          function showHandles() //{{{
          {
            if (seehandles) {
              $hdl_holder.show();
            }
          }
          //}}}
          function enableHandles() //{{{
          {
            seehandles = true;
            if (options.allowResize) {
              $hdl_holder.show();
              return true;
            }
          }
          //}}}
          function disableHandles() //{{{
          {
            seehandles = false;
            $hdl_holder.hide();
          } 
          //}}}
          function animMode(v) //{{{
          {
            if (animating === v) {
              disableHandles();
            } else {
              enableHandles();
            }
          } 
          //}}}
          function done() //{{{
          {
            animMode(false);
            refresh();
          } 
          //}}}
          // Insert draggable elements {{{
          // Insert border divs for outline
    
          if (options.dragEdges && $.isArray(options.createDragbars))
            createDragbars(options.createDragbars);
    
          if ($.isArray(options.createHandles))
            createHandles(options.createHandles);
    
          if (options.drawBorders && $.isArray(options.createBorders))
            createBorders(options.createBorders);
    
          //}}}
    
          // This is a hack for iOS5 to support drag/move touch functionality
          $(document).bind('touchstart.jcrop-ios',function(e) {
            if ($(e.currentTarget).hasClass('jcrop-tracker')) e.stopPropagation();
          });
    
          var $track = newTracker().mousedown(createDragger('move')).css({
            cursor: 'move',
            position: 'absolute',
            zIndex: 360
          });
    
          if (Touch.support) {
            $track.bind('touchstart.jcrop', Touch.createDragger('move'));
          }
    
          $img_holder.append($track);
          disableHandles();
    
          return {
            updateVisible: updateVisible,
            update: update,
            release: release,
            refresh: refresh,
            isAwake: function () {
              return awake;
            },
            setCursor: function (cursor) {
              $track.css('cursor', cursor);
            },
            enableHandles: enableHandles,
            enableOnly: function () {
              seehandles = true;
            },
            showHandles: showHandles,
            disableHandles: disableHandles,
            animMode: animMode,
            setBgOpacity: setBgOpacity,
            done: done
          };
        }());
        
        //}}}
        // Tracker Module {{{
        var Tracker = (function () {
          var onMove = function () {},
              onDone = function () {},
              trackDoc = options.trackDocument;
    
          function toFront() //{{{
          {
            $trk.css({
              zIndex: 450
            });
            if (Touch.support) {
              $(document)
                .bind('touchmove.jcrop', trackTouchMove)
                .bind('touchend.jcrop', trackTouchEnd);
            }
            if (trackDoc) {
              $(document)
                .bind('mousemove.jcrop',trackMove)
                .bind('mouseup.jcrop',trackUp);
            }
          } 
          //}}}
          function toBack() //{{{
          {
            $trk.css({
              zIndex: 290
            });
            $(document).unbind('.jcrop');
          } 
          //}}}
          function trackMove(e) //{{{
          {
            onMove(mouseAbs(e));
            return false;
          } 
          //}}}
          function trackUp(e) //{{{
          {
            e.preventDefault();
            e.stopPropagation();
    
            if (btndown) {
              btndown = false;
    
              onDone(mouseAbs(e));
    
              if (Selection.isAwake()) {
                options.onSelect.call(api, unscale(Coords.getFixed()));
              }
    
              toBack();
              onMove = function () {};
              onDone = function () {};
            }
    
            return false;
          }
          //}}}
          function activateHandlers(move, done) //{{{
          {
            btndown = true;
            onMove = move;
            onDone = done;
            toFront();
            return false;
          }
          //}}}
          function trackTouchMove(e) //{{{
          {
            e.pageX = e.originalEvent.changedTouches[0].pageX;
            e.pageY = e.originalEvent.changedTouches[0].pageY;
            return trackMove(e);
          }
          //}}}
          function trackTouchEnd(e) //{{{
          {
            e.pageX = e.originalEvent.changedTouches[0].pageX;
            e.pageY = e.originalEvent.changedTouches[0].pageY;
            return trackUp(e);
          }
          //}}}
          function setCursor(t) //{{{
          {
            $trk.css('cursor', t);
          }
          //}}}
    
          if (!trackDoc) {
            $trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);
          }
    
          $img.before($trk);
          return {
            activateHandlers: activateHandlers,
            setCursor: setCursor
          };
        }());
        //}}}
        // KeyManager Module {{{
        var KeyManager = (function () {
          var $keymgr = $('<input type="radio" />').css({
            position: 'fixed',
            left: '-120px',
            width: '12px'
          }),
              $keywrap = $('<div />').css({
              position: 'absolute',
              overflow: 'hidden'
            }).append($keymgr);
    
          function watchKeys() //{{{
          {
            if (options.keySupport) {
              $keymgr.show();
              $keymgr.focus();
            }
          }
          //}}}
          function onBlur(e) //{{{
          {
            $keymgr.hide();
          }
          //}}}
          function doNudge(e, x, y) //{{{
          {
            if (options.allowMove) {
              Coords.moveOffset([x, y]);
              Selection.updateVisible(true);
            }
            e.preventDefault();
            e.stopPropagation();
          }
          //}}}
          function parseKey(e) //{{{
          {
            if (e.ctrlKey || e.metaKey) {
              return true;
            }
            shift_down = e.shiftKey ? true : false;
            var nudge = shift_down ? 10 : 1;
    
            switch (e.keyCode) {
            case 37:
              doNudge(e, -nudge, 0);
              break;
            case 39:
              doNudge(e, nudge, 0);
              break;
            case 38:
              doNudge(e, 0, -nudge);
              break;
            case 40:
              doNudge(e, 0, nudge);
              break;
            case 27:
              if (options.allowSelect) Selection.release();
              break;
            case 9:
              return true;
            }
    
            return false;
          }
          //}}}
    
          if (options.keySupport) {
            $keymgr.keydown(parseKey).blur(onBlur);
            if (ie6mode || !options.fixedSupport) {
              $keymgr.css({
                position: 'absolute',
                left: '-20px'
              });
              $keywrap.append($keymgr).insertBefore($img);
            } else {
              $keymgr.insertBefore($img);
            }
          }
    
    
          return {
            watchKeys: watchKeys
          };
        }());
        //}}}
        // }}}
        // API methods {{{
        function setClass(cname) //{{{
        {
          $div.removeClass().addClass(cssClass('holder')).addClass(cname);
        }
        //}}}
        function animateTo(a, callback) //{{{
        {
          var x1 = a[0] / xscale,
              y1 = a[1] / yscale,
              x2 = a[2] / xscale,
              y2 = a[3] / yscale;
    
          if (animating) {
            return;
          }
    
          var animto = Coords.flipCoords(x1, y1, x2, y2),
              c = Coords.getFixed(),
              initcr = [c.x, c.y, c.x2, c.y2],
              animat = initcr,
              interv = options.animationDelay,
              ix1 = animto[0] - initcr[0],
              iy1 = animto[1] - initcr[1],
              ix2 = animto[2] - initcr[2],
              iy2 = animto[3] - initcr[3],
              pcent = 0,
              velocity = options.swingSpeed;
    
          x = animat[0];
          y = animat[1];
          x2 = animat[2];
          y2 = animat[3];
    
          Selection.animMode(true);
          var anim_timer;
    
          function queueAnimator() {
            window.setTimeout(animator, interv);
          }
          var animator = (function () {
            return function () {
              pcent += (100 - pcent) / velocity;
    
              animat[0] = x + ((pcent / 100) * ix1);
              animat[1] = y + ((pcent / 100) * iy1);
              animat[2] = x2 + ((pcent / 100) * ix2);
              animat[3] = y2 + ((pcent / 100) * iy2);
    
              if (pcent >= 99.8) {
                pcent = 100;
              }
              if (pcent < 100) {
                setSelectRaw(animat);
                queueAnimator();
              } else {
                Selection.done();
                if (typeof(callback) === 'function') {
                  callback.call(api);
                }
              }
            };
          }());
          queueAnimator();
        }
        //}}}
        function setSelect(rect) //{{{
        {
          setSelectRaw([rect[0] / xscale, rect[1] / yscale, rect[2] / xscale, rect[3] / yscale]);
          options.onSelect.call(api, unscale(Coords.getFixed()));
          Selection.enableHandles();
        }
        //}}}
        function setSelectRaw(l) //{{{
        {
          Coords.setPressed([l[0], l[1]]);
          Coords.setCurrent([l[2], l[3]]);
          Selection.update();
        }
        //}}}
        function tellSelect() //{{{
        {
          return unscale(Coords.getFixed());
        }
        //}}}
        function tellScaled() //{{{
        {
          return Coords.getFixed();
        }
        //}}}
        function setOptionsNew(opt) //{{{
        {
          setOptions(opt);
          interfaceUpdate();
        }
        //}}}
        function disableCrop() //{{{
        {
          options.disabled = true;
          Selection.disableHandles();
          Selection.setCursor('default');
          Tracker.setCursor('default');
        }
        //}}}
        function enableCrop() //{{{
        {
          options.disabled = false;
          interfaceUpdate();
        }
        //}}}
        function cancelCrop() //{{{
        {
          Selection.done();
          Tracker.activateHandlers(null, null);
        }
        //}}}
        function destroy() //{{{
        {
          $div.remove();
          $origimg.show();
          $(obj).removeData('Jcrop');
        }
        //}}}
        function setImage(src, callback) //{{{
        {
          Selection.release();
          disableCrop();
          var img = new Image();
          img.onload = function () {
            var iw = img.width;
            var ih = img.height;
            var bw = options.boxWidth;
            var bh = options.boxHeight;
            $img.width(iw).height(ih);
            $img.attr('src', src);
            $img2.attr('src', src);
            presize($img, bw, bh);
            boundx = $img.width();
            boundy = $img.height();
            $img2.width(boundx).height(boundy);
            $trk.width(boundx + (bound * 2)).height(boundy + (bound * 2));
            $div.width(boundx).height(boundy);
            Shade.resize(boundx,boundy);
            enableCrop();
    
            if (typeof(callback) === 'function') {
              callback.call(api);
            }
          };
          img.src = src;
        }
        //}}}
        function colorChangeMacro($obj,color,now) {
          var mycolor = color || options.bgColor;
          if (options.bgFade && supportsColorFade() && options.fadeTime && !now) {
            $obj.animate({
              backgroundColor: mycolor
            }, {
              queue: false,
              duration: options.fadeTime
            });
          } else {
            $obj.css('backgroundColor', mycolor);
          }
        }
        function interfaceUpdate(alt) //{{{
        // This method tweaks the interface based on options object.
        // Called when options are changed and at end of initialization.
        {
          if (options.allowResize) {
            if (alt) {
              Selection.enableOnly();
            } else {
              Selection.enableHandles();
            }
          } else {
            Selection.disableHandles();
          }
    
          Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');
          Selection.setCursor(options.allowMove ? 'move' : 'default');
    
          if (options.hasOwnProperty('trueSize')) {
            xscale = options.trueSize[0] / boundx;
            yscale = options.trueSize[1] / boundy;
          }
    
          if (options.hasOwnProperty('setSelect')) {
            setSelect(options.setSelect);
            Selection.done();
            delete(options.setSelect);
          }
    
          Shade.refresh();
    
          if (options.bgColor != bgcolor) {
            colorChangeMacro(
              options.shade? Shade.getShades(): $div,
              options.shade?
                (options.shadeColor || options.bgColor):
                options.bgColor
            );
            bgcolor = options.bgColor;
          }
    
          if (bgopacity != options.bgOpacity) {
            bgopacity = options.bgOpacity;
            if (options.shade) Shade.refresh();
              else Selection.setBgOpacity(bgopacity);
          }
    
          xlimit = options.maxSize[0] || 0;
          ylimit = options.maxSize[1] || 0;
          xmin = options.minSize[0] || 0;
          ymin = options.minSize[1] || 0;
    
          if (options.hasOwnProperty('outerImage')) {
            $img.attr('src', options.outerImage);
            delete(options.outerImage);
          }
    
          Selection.refresh();
        }
        //}}}
        //}}}
    
        if (Touch.support) $trk.bind('touchstart.jcrop', Touch.newSelection);
    
        $hdl_holder.hide();
        interfaceUpdate(true);
    
        var api = {
          setImage: setImage,
          animateTo: animateTo,
          setSelect: setSelect,
          setOptions: setOptionsNew,
          tellSelect: tellSelect,
          tellScaled: tellScaled,
          setClass: setClass,
    
          disable: disableCrop,
          enable: enableCrop,
          cancel: cancelCrop,
          release: Selection.release,
          destroy: destroy,
    
          focus: KeyManager.watchKeys,
    
          getBounds: function () {
            return [boundx * xscale, boundy * yscale];
          },
          getWidgetSize: function () {
            return [boundx, boundy];
          },
          getScaleFactor: function () {
            return [xscale, yscale];
          },
          getOptions: function() {
            // careful: internal values are returned
            return options;
          },
    
          ui: {
            holder: $div,
            selection: $sel
          }
        };
    
        if ($.browser.msie)
          $div.bind('selectstart', function () { return false; });
    
        $origimg.data('Jcrop', api);
        return api;
      };
      $.fn.Jcrop = function (options, callback) //{{{
      {
        var api;
        // Iterate over each object, attach Jcrop
        this.each(function () {
          // If we've already attached to this object
          if ($(this).data('Jcrop')) {
            // The API can be requested this way (undocumented)
            if (options === 'api') return $(this).data('Jcrop');
            // Otherwise, we just reset the options...
            else $(this).data('Jcrop').setOptions(options);
          }
          // If we haven't been attached, preload and attach
          else {
            if (this.tagName == 'IMG')
              $.Jcrop.Loader(this,function(){
                $(this).css({display:'block',visibility:'hidden'});
                api = $.Jcrop(this, options);
                if ($.isFunction(callback)) callback.call(api);
              });
            else {
              $(this).css({display:'block',visibility:'hidden'});
              api = $.Jcrop(this, options);
              if ($.isFunction(callback)) callback.call(api);
            }
          }
        });
    
        // Return "this" so the object is chainable (jQuery-style)
        return this;
      };
      //}}}
      // $.Jcrop.Loader - basic image loader {{{
    
      $.Jcrop.Loader = function(imgobj,success,error){
        var $img = $(imgobj), img = $img[0];
    
        function completeCheck(){
          if (img.complete) {
            $img.unbind('.jcloader');
            if ($.isFunction(success)) success.call(img);
          }
          else window.setTimeout(completeCheck,50);
        }
    
        $img
          .bind('load.jcloader',completeCheck)
          .bind('error.jcloader',function(e){
            $img.unbind('.jcloader');
            if ($.isFunction(error)) error.call(img);
          });
    
        if (img.complete && $.isFunction(success)){
          $img.unbind('.jcloader');
          success.call(img);
        }
      };
    
      //}}}
      // Global Defaults {{{
      $.Jcrop.defaults = {
    
        // Basic Settings
        allowSelect: true,
        allowMove: true,
        allowResize: true,
    
        trackDocument: true,
    
        // Styling Options
        baseClass: 'jcrop',
        addClass: null,
        bgColor: 'black',
        bgOpacity: 0.6,
        bgFade: false,
        borderOpacity: 0.4,
        handleOpacity: 0.5,
        handleSize: 7,
    
        aspectRatio: 0,
        keySupport: true,
        createHandles: ['n','s','e','w','nw','ne','se','sw'],
        createDragbars: ['n','s','e','w'],
        createBorders: ['n','s','e','w'],
        drawBorders: true,
        dragEdges: true,
        fixedSupport: true,
        touchSupport: null,
    
        shade: null,
    
        boxWidth: 0,
        boxHeight: 0,
        boundary: 2,
        fadeTime: 400,
        animationDelay: 20,
        swingSpeed: 3,
    
        minSelect: [0, 0],
        maxSize: [0, 0],
        minSize: [0, 0],
    
        // Callbacks / Event Handlers
        onChange: function () {},
        onSelect: function () {},
        onDblClick: function () {},
        onRelease: function () {}
      };
    
      // }}}
    }(jQuery));
    
    
    ================================================
    FILE: set/uploadify/jquery.uploadify-3.1.js
    ================================================
    /*
    SWFObject v2.2 <http://code.google.com/p/swfobject/> 
    is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
    */
    ;var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;
    if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;
    X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);
    ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0;}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");
    if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)];}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac};
    }(),k=function(){if(!M.w3){return;}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f();
    }if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false);}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);
    f();}});if(O==top){(function(){if(J){return;}try{j.documentElement.doScroll("left");}catch(X){setTimeout(arguments.callee,0);return;}f();})();}}if(M.wk){(function(){if(J){return;
    }if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return;}f();})();}s(f);}}();function f(){if(J){return;}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));
    Z.parentNode.removeChild(Z);}catch(aa){return;}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]();}}function K(X){if(J){X();}else{U[U.length]=X;}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false);
    }else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false);}else{if(typeof O.attachEvent!=D){i(O,"onload",Y);}else{if(typeof O.onload=="function"){var X=O.onload;
    O.onload=function(){X();Y();};}else{O.onload=Y;}}}}}function h(){if(T){V();}else{H();}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);
    aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");
    M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)];}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return;}}X.removeChild(aa);Z=null;H();
    })();}else{H();}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);
    if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa);}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;
    ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class");}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align");
    }var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value");
    }}P(ai,ah,Y,ab);}else{p(ae);if(ab){ab(aa);}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z;}ab(aa);}}}}}function z(aa){var X=null;
    var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y;}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z;}}}return X;}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312);
    }function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null;}else{l=ae;Q=X;}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310";
    }if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137";}j.title=j.title.slice(0,47)+" - Flash Player Installation";
    var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac;
    }else{ab.flashvars=ac;}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";
    (function(){if(ae.readyState==4){ae.parentNode.removeChild(ae);}else{setTimeout(arguments.callee,10);}})();}u(aa,ab,X);}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");
    Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y);}else{setTimeout(arguments.callee,10);
    }})();}else{Y.parentNode.replaceChild(g(Y),Y);}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML;}else{var Y=ab.getElementsByTagName(r)[0];
    if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true));
    }}}}}return aa;}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X;}if(aa){if(typeof ai.id==D){ai.id=Y;}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae];
    }else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"';}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"';}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />';
    }}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id);}else{var Z=C(r);Z.setAttribute("type",q);
    for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac]);}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac]);
    }}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab]);}}aa.parentNode.replaceChild(Z,aa);X=Z;}}return X;}function e(Z,X,Y){var aa=C("param");
    aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa);}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";
    (function(){if(X.readyState==4){b(Y);}else{setTimeout(arguments.callee,10);}})();}else{X.parentNode.removeChild(X);}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null;
    }}Y.parentNode.removeChild(Y);}}function c(Z){var X=null;try{X=j.getElementById(Z);}catch(Y){}return X;}function C(X){return j.createElement(X);}function i(Z,X,Y){Z.attachEvent(X,Y);
    I[I.length]=[Z,X,Y];}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false;
    }function v(ac,Y,ad,ab){if(M.ie&&M.mac){return;}var aa=j.getElementsByTagName("head")[0];if(!aa){return;}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;
    G=null;}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1];
    }G=X;}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y);}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"));
    }}}function w(Z,X){if(!m){return;}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y;}else{v("#"+Z,"visibility:"+Y);}}function L(Y){var Z=/[\\\"<>\.;]/;
    var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y;}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;
    for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2]);}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa]);}for(var Y in M){M[Y]=null;}M=null;for(var X in swfobject){swfobject[X]=null;
    }swfobject=null;});}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;
    w(ab,false);}else{if(Z){Z({success:false,id:ab});}}},getObjectById:function(X){if(M.w3){return z(X);}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};
    if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al];}}aj.data=ab;
    aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak];}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai];
    }else{am.flashvars=ai+"="+Z[ai];}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true);}X.success=true;X.ref=an;}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);
    return;}else{w(ah,true);}}if(ac){ac(X);}});}else{if(ac){ac(X);}}},switchOffAutoHideShow:function(){m=false;},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]};
    },hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X);}else{return undefined;}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y);
    }},removeSWF:function(X){if(M.w3){y(X);}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X);}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;
    if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1];}if(aa==null){return L(Z);}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)));
    }}}return"";},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block";
    }}if(E){E(B);}}a=false;}}};}();
    
    /*
    SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
    
    mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
    
    SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
    http://www.opensource.org/licenses/mit-license.php
     
    SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
    http://www.opensource.org/licenses/mit-license.php
    */
    
    var SWFUpload;if(SWFUpload==undefined){SWFUpload=function(a){this.initSWFUpload(a)}}SWFUpload.prototype.initSWFUpload=function(b){try{this.customSettings={};this.settings=b;this.eventQueue=[];this.movieName="SWFUpload_"+SWFUpload.movieCount++;this.movieElement=null;SWFUpload.instances[this.movieName]=this;this.initSettings();this.loadFlash();this.displayDebugInfo()}catch(a){delete SWFUpload.instances[this.movieName];throw a}};SWFUpload.instances={};SWFUpload.movieCount=0;SWFUpload.version="2.2.0 2009-03-25";SWFUpload.QUEUE_ERROR={QUEUE_LIMIT_EXCEEDED:-100,FILE_EXCEEDS_SIZE_LIMIT:-110,ZERO_BYTE_FILE:-120,INVALID_FILETYPE:-130};SWFUpload.UPLOAD_ERROR={HTTP_ERROR:-200,MISSING_UPLOAD_URL:-210,IO_ERROR:-220,SECURITY_ERROR:-230,UPLOAD_LIMIT_EXCEEDED:-240,UPLOAD_FAILED:-250,SPECIFIED_FILE_ID_NOT_FOUND:-260,FILE_VALIDATION_FAILED:-270,FILE_CANCELLED:-280,UPLOAD_STOPPED:-290};SWFUpload.FILE_STATUS={QUEUED:-1,IN_PROGRESS:-2,ERROR:-3,COMPLETE:-4,CANCELLED:-5};SWFUpload.BUTTON_ACTION={SELECT_FILE:-100,SELECT_FILES:-110,START_UPLOAD:-120};SWFUpload.CURSOR={ARROW:-1,HAND:-2};SWFUpload.WINDOW_MODE={WINDOW:"window",TRANSPARENT:"transparent",OPAQUE:"opaque"};SWFUpload.completeURL=function(a){if(typeof(a)!=="string"||a.match(/^https?:\/\//i)||a.match(/^\//)){return a}var c=window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:"");var b=window.location.pathname.lastIndexOf("/");if(b<=0){path="/"}else{path=window.location.pathname.substr(0,b)+"/"}return path+a};SWFUpload.prototype.initSettings=function(){this.ensureDefault=function(b,a){this.settings[b]=(this.settings[b]==undefined)?a:this.settings[b]};this.ensureDefault("upload_url","");this.ensureDefault("preserve_relative_urls",false);this.ensureDefault("file_post_name","Filedata");this.ensureDefault("post_params",{});this.ensureDefault("use_query_string",false);this.ensureDefault("requeue_on_error",false);this.ensureDefault("http_success",[]);this.ensureDefault("assume_success_timeout",0);this.ensureDefault("file_types","*.*");this.ensureDefault("file_types_description","All Files");this.ensureDefault("file_size_limit",0);this.ensureDefault("file_upload_limit",0);this.ensureDefault("file_queue_limit",0);this.ensureDefault("flash_url","swfupload.swf");this.ensureDefault("prevent_swf_caching",true);this.ensureDefault("button_image_url","");this.ensureDefault("button_width",1);this.ensureDefault("button_height",1);this.ensureDefault("button_text","");this.ensureDefault("button_text_style","color: #000000; font-size: 16pt;");this.ensureDefault("button_text_top_padding",0);this.ensureDefault("button_text_left_padding",0);this.ensureDefault("button_action",SWFUpload.BUTTON_ACTION.SELECT_FILES);this.ensureDefault("button_disabled",false);this.ensureDefault("button_placeholder_id","");this.ensureDefault("button_placeholder",null);this.ensureDefault("button_cursor",SWFUpload.CURSOR.ARROW);this.ensureDefault("button_window_mode",SWFUpload.WINDOW_MODE.WINDOW);this.ensureDefault("debug",false);this.settings.debug_enabled=this.settings.debug;this.settings.return_upload_start_handler=this.returnUploadStart;this.ensureDefault("swfupload_loaded_handler",null);this.ensureDefault("file_dialog_start_handler",null);this.ensureDefault("file_queued_handler",null);this.ensureDefault("file_queue_error_handler",null);this.ensureDefault("file_dialog_complete_handler",null);this.ensureDefault("upload_start_handler",null);this.ensureDefault("upload_progress_handler",null);this.ensureDefault("upload_error_handler",null);this.ensureDefault("upload_success_handler",null);this.ensureDefault("upload_complete_handler",null);this.ensureDefault("debug_handler",this.debugMessage);this.ensureDefault("custom_settings",{});this.customSettings=this.settings.custom_settings;if(!!this.settings.prevent_swf_caching){this.settings.flash_url=this.settings.flash_url+(this.settings.flash_url.indexOf("?")<0?"?":"&")+"preventswfcaching="+new Date().getTime()}if(!this.settings.preserve_relative_urls){this.settings.upload_url=SWFUpload.completeURL(this.settings.upload_url);this.settings.button_image_url=SWFUpload.completeURL(this.settings.button_image_url)}delete this.ensureDefault};SWFUpload.prototype.loadFlash=function(){var a,b;if(document.getElementById(this.movieName)!==null){throw"ID "+this.movieName+" is already in use. The Flash Object could not be added"}a=document.getElementById(this.settings.button_placeholder_id)||this.settings.button_placeholder;if(a==undefined){throw"Could not find the placeholder element: "+this.settings.button_placeholder_id}b=document.createElement("div");b.innerHTML=this.getFlashHTML();a.parentNode.replaceChild(b.firstChild,a);if(window[this.movieName]==undefined){window[this.movieName]=this.getMovieElement()}};SWFUpload.prototype.getFlashHTML=function(){return['<object id="',this.movieName,'" type="application/x-shockwave-flash" data="',this.settings.flash_url,'" width="',this.settings.button_width,'" height="',this.settings.button_height,'" class="swfupload">','<param name="wmode" value="',this.settings.button_window_mode,'" />','<param name="movie" value="',this.settings.flash_url,'" />','<param name="quality" value="high" />','<param name="menu" value="false" />','<param name="allowScriptAccess" value="always" />','<param name="flashvars" value="'+this.getFlashVars()+'" />',"</object>"].join("")};SWFUpload.prototype.getFlashVars=function(){var b=this.buildParamString();var a=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&amp;uploadURL=",encodeURIComponent(this.settings.upload_url),"&amp;useQueryString=",encodeURIComponent(this.settings.use_query_string),"&amp;requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&amp;httpSuccess=",encodeURIComponent(a),"&amp;assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&amp;params=",encodeURIComponent(b),"&amp;filePostName=",encodeURIComponent(this.settings.file_post_name),"&amp;fileTypes=",encodeURIComponent(this.settings.file_types),"&amp;fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&amp;fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&amp;fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&amp;fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&amp;debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&amp;buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&amp;buttonWidth=",encodeURIComponent(this.settings.button_width),"&amp;buttonHeight=",encodeURIComponent(this.settings.button_height),"&amp;buttonText=",encodeURIComponent(this.settings.button_text),"&amp;buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&amp;buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&amp;buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&amp;buttonAction=",encodeURIComponent(this.settings.button_action),"&amp;buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&amp;buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")};SWFUpload.prototype.getMovieElement=function(){if(this.movieElement==undefined){this.movieElement=document.getElementById(this.movieName)}if(this.movieElement===null){throw"Could not find Flash element"}return this.movieElement};SWFUpload.prototype.buildParamString=function(){var c=this.settings.post_params;var b=[];if(typeof(c)==="object"){for(var a in c){if(c.hasOwnProperty(a)){b.push(encodeURIComponent(a.toString())+"="+encodeURIComponent(c[a].toString()))}}}return b.join("&amp;")};SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,false);var a=null;a=this.getMovieElement();if(a&&typeof(a.CallFunction)==="unknown"){for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(e){}}try{a.parentNode.removeChild(a)}catch(b){}}window[this.movieName]=null;SWFUpload.instances[this.movieName]=null;delete SWFUpload.instances[this.movieName];this.movieElement=null;this.settings=null;this.customSettings=null;this.eventQueue=null;this.movieName=null;return true}catch(d){return false}};SWFUpload.prototype.displayDebugInfo=function(){this.debug(["---SWFUpload Instance Info---\n","Version: ",SWFUpload.version,"\n","Movie Name: ",this.movieName,"\n","Settings:\n","\t","upload_url:               ",this.settings.upload_url,"\n","\t","flash_url:                ",this.settings.flash_url,"\n","\t","use_query_string:         ",this.settings.use_query_string.toString(),"\n","\t","requeue_on_error:         ",this.settings.requeue_on_error.toString(),"\n","\t","http_success:             ",this.settings.http_success.join(", "),"\n","\t","assume_success_timeout:   ",this.settings.assume_success_timeout,"\n","\t","file_post_name:           ",this.settings.file_post_name,"\n","\t","post_params:              ",this.settings.post_params.toString(),"\n","\t","file_types:               ",this.settings.file_types,"\n","\t","file_types_description:   ",this.settings.file_types_description,"\n","\t","file_size_limit:          ",this.settings.file_size_limit,"\n","\t","file_upload_limit:        ",this.settings.file_upload_limit,"\n","\t","file_queue_limit:         ",this.settings.file_queue_limit,"\n","\t","debug:                    ",this.settings.debug.toString(),"\n","\t","prevent_swf_caching:      ",this.settings.prevent_swf_caching.toString(),"\n","\t","button_placeholder_id:    ",this.settings.button_placeholder_id.toString(),"\n","\t","button_placeholder:       ",(this.settings.button_placeholder?"Set":"Not Set"),"\n","\t","button_image_url:         ",this.settings.button_image_url.toString(),"\n","\t","button_width:             ",this.settings.button_width.toString(),"\n","\t","button_height:            ",this.settings.button_height.toString(),"\n","\t","button_text:              ",this.settings.button_text.toString(),"\n","\t","button_text_style:        ",this.settings.button_text_style.toString(),"\n","\t","button_text_top_padding:  ",this.settings.button_text_top_padding.toString(),"\n","\t","button_text_left_padding: ",this.settings.button_text_left_padding.toString(),"\n","\t","button_action:            ",this.settings.button_action.toString(),"\n","\t","button_disabled:          ",this.settings.button_disabled.toString(),"\n","\t","custom_settings:          ",this.settings.custom_settings.toString(),"\n","Event Handlers:\n","\t","swfupload_loaded_handler assigned:  ",(typeof this.settings.swfupload_loaded_handler==="function").toString(),"\n","\t","file_dialog_start_handler assigned: ",(typeof this.settings.file_dialog_start_handler==="function").toString(),"\n","\t","file_queued_handler assigned:       ",(typeof this.settings.file_queued_handler==="function").toString(),"\n","\t","file_queue_error_handler assigned:  ",(typeof this.settings.file_queue_error_handler==="function").toString(),"\n","\t","upload_start_handler assigned:      ",(typeof this.settings.upload_start_handler==="function").toString(),"\n","\t","upload_progress_handler assigned:   ",(typeof this.settings.upload_progress_handler==="function").toString(),"\n","\t","upload_error_handler assigned:      ",(typeof this.settings.upload_error_handler==="function").toString(),"\n","\t","upload_success_handler assigned:    ",(typeof this.settings.upload_success_handler==="function").toString(),"\n","\t","upload_complete_handler assigned:   ",(typeof this.settings.upload_complete_handler==="function").toString(),"\n","\t","debug_handler assigned:             ",(typeof this.settings.debug_handler==="function").toString(),"\n"].join(""))};SWFUpload.prototype.addSetting=function(b,c,a){if(c==undefined){return(this.settings[b]=a)}else{return(this.settings[b]=c)}};SWFUpload.prototype.getSetting=function(a){if(this.settings[a]!=undefined){return this.settings[a]}return""};SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement();var returnValue,returnString;try{returnString=movieElement.CallFunction('<invoke name="'+functionName+'" returntype="javascript">'+__flash__argumentsToXML(argumentArray,0)+"</invoke>");returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}if(returnValue!=undefined&&typeof returnValue.post==="object"){returnValue=this.unescapeFilePostParams(returnValue)}return returnValue};SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")};SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")};SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])};SWFUpload.prototype.cancelUpload=function(a,b){if(b!==false){b=true}this.callFlash("CancelUpload",[a,b])};SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")};SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")};SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])};SWFUpload.prototype.getFile=function(a){if(typeof(a)==="number"){return this.callFlash("GetFileByIndex",[a])}else{return this.callFlash("GetFile",[a])}};SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])};SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])};SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString();this.callFlash("SetUploadURL",[a])};SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a;this.callFlash("SetPostParams",[a])};SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b;this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a];this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a;this.settings.file_types_description=b;this.callFlash("SetFileTypes",[a,b])};SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a;this.callFlash("SetFileSizeLimit",[a])};SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a;this.callFlash("SetFileUploadLimit",[a])};SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a;this.callFlash("SetFileQueueLimit",[a])};SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a;this.callFlash("SetFilePostName",[a])};SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a;this.callFlash("SetUseQueryString",[a])};SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a;this.callFlash("SetRequeueOnError",[a])};SWFUpload.prototype.setHTTPSuccess=function(a){if(typeof a==="string"){a=a.replace(" ","").split(",")}this.settings.http_success=a;this.callFlash("SetHTTPSuccess",[a])};SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a;this.callFlash("SetAssumeSuccessTimeout",[a])};SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a;this.callFlash("SetDebugEnabled",[a])};SWFUpload.prototype.setButtonImageURL=function(a){if(a==undefined){a=""}this.settings.button_image_url=a;this.callFlash("SetButtonImageURL",[a])};SWFUpload.prototype.setButtonDimensions=function(c,a){this.settings.button_width=c;this.settings.button_height=a;var b=this.getMovieElement();if(b!=undefined){b.style.width=c+"px";b.style.height=a+"px"}this.callFlash("SetButtonDimensions",[c,a])};SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a;this.callFlash("SetButtonText",[a])};SWFUpload.prototype.setButtonTextPadding=function(b,a){this.settings.button_text_top_padding=a;this.settings.button_text_left_padding=b;this.callFlash("SetButtonTextPadding",[b,a])};SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a;this.callFlash("SetButtonTextStyle",[a])};SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a;this.callFlash("SetButtonDisabled",[a])};SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a;this.callFlash("SetButtonAction",[a])};SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a;this.callFlash("SetButtonCursor",[a])};SWFUpload.prototype.queueEvent=function(b,c){if(c==undefined){c=[]}else{if(!(c instanceof Array)){c=[c]}}var a=this;if(typeof this.settings[b]==="function"){this.eventQueue.push(function(){this.settings[b].apply(this,c)});setTimeout(function(){a.executeNextEvent()},0)}else{if(this.settings[b]!==null){throw"Event handler "+b+" is unknown or is not a function"}}};SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;if(typeof(a)==="function"){a.apply(this)}};SWFUpload.prototype.unescapeFilePostParams=function(c){var e=/[$]([0-9a-f]{4})/i;var f={};var d;if(c!=undefined){for(var a in c.post){if(c.post.hasOwnProperty(a)){d=a;var b;while((b=e.exec(d))!==null){d=d.replace(b[0],String.fromCharCode(parseInt("0x"+b[1],16)))}f[d]=c.post[a]}}c.post=f}return c};SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return false}};SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();if(!a){this.debug("Flash called back ready but the flash movie can't be found.");return}this.cleanUp(a);this.queueEvent("swfupload_loaded_handler")};SWFUpload.prototype.cleanUp=function(a){try{if(this.movieElement&&typeof(a.CallFunction)==="unknown"){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(b){}}}}catch(d){}window.__flash__removeCallback=function(e,f){try{if(e){e[f]=null}}catch(g){}}};SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")};SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("file_queued_handler",a)};SWFUpload.prototype.fileQueueError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("file_queue_error_handler",[a,c,b])};SWFUpload.prototype.fileDialogComplete=function(b,c,a){this.queueEvent("file_dialog_complete_handler",[b,c,a])};SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("return_upload_start_handler",a)};SWFUpload.prototype.returnUploadStart=function(a){var b;if(typeof this.settings.upload_start_handler==="function"){a=this.unescapeFilePostParams(a);b=this.settings.upload_start_handler.call(this,a)}else{if(this.settings.upload_start_handler!=undefined){throw"upload_start_handler must be a function"}}if(b===undefined){b=true}b=!!b;this.callFlash("ReturnUploadStart",[b])};SWFUpload.prototype.uploadProgress=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_progress_handler",[a,c,b])};SWFUpload.prototype.uploadError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_error_handler",[a,c,b])};SWFUpload.prototype.uploadSuccess=function(b,a,c){b=this.unescapeFilePostParams(b);this.queueEvent("upload_success_handler",[b,a,c])};SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("upload_complete_handler",a)};SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)};SWFUpload.prototype.debugMessage=function(c){if(this.settings.debug){var a,d=[];if(typeof c==="object"&&typeof c.name==="string"&&typeof c.message==="string"){for(var b in c){if(c.hasOwnProperty(b)){d.push(b+": "+c[b])}}a=d.join("\n")||"";d=a.split("\n");a="EXCEPTION: "+d.join("\nEXCEPTION: ");SWFUpload.Console.writeLine(a)}else{SWFUpload.Console.writeLine(c)}}};SWFUpload.Console={};SWFUpload.Console.writeLine=function(d){var b,a;try{b=document.getElementById("SWFUpload_Console");if(!b){a=document.createElement("form");document.getElementsByTagName("body")[0].appendChild(a);b=document.createElement("textarea");b.id="SWFUpload_Console";b.style.fontFamily="monospace";b.setAttribute("wrap","off");b.wrap="off";b.style.overflow="auto";b.style.width="700px";b.style.height="350px";b.style.margin="5px";a.appendChild(b)}b.value+=d+"\n";b.scrollTop=b.scrollHeight-b.clientHeight}catch(c){alert("Exception: "+c.name+" Message: "+c.message)}};
    
    /*
    Uploadify v3.1.1
    Copyright (c) 2012 Reactive Apps, Ronnie Garcia
    Released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
    */
    
    (function($) {
    
    	// These methods can be called by adding them as the first argument in the uploadify plugin call
    	var methods = {
    
    		init : function(options, swfUploadOptions) {
    			
    			return this.each(function() {
    
    				// Create a reference to the jQuery DOM object
    				var $this = $(this);
    
    				// Clone the original DOM object
    				var $clone = $this.clone();
    
    				// Setup the default options
    				var settings = $.extend({
    					// Required Settings
    					id       : $this.attr('id'), // The ID of the DOM object
    					swf      : 'uploadify.swf',  // The path to the uploadify SWF file
    					uploader : 'uploadify.php',  // The path to the server-side upload script
    					
    					// Options
    					auto            : true,               // Automatically upload files when added to the queue
    					buttonClass     : '',                 // A class name to add to the browse button DOM object
    					buttonCursor    : 'hand',             // The cursor to use with the browse button
    					buttonImage     : null,               // (String or null) The path to an image to use for the Flash browse button if not using CSS to style the button
    					buttonText      : 'SELECT FILES',     // The text to use for the browse button
    					checkExisting   : false,              // The path to a server-side script that checks for existing files on the server
    					debug           : false,              // Turn on swfUpload debugging mode
    					fileObjName     : 'Filedata',         // The name of the file object to use in your server-side script
    					fileSizeLimit   : 0,                  // The maximum size of an uploadable file in KB (Accepts units B KB MB GB if string, 0 for no limit)
    					fileTypeDesc    : 'All Files',        // The description for file types in the browse dialog
    					fileTypeExts    : '*.*',              // Allowed extensions in the browse dialog (server-side validation should also be used)
    					height          : 30,                 // The height of the browse button
    					method          : 'post',             // The method to use when sending files to the server-side upload script
    					multi           : true,               // Allow multiple file selection in the browse dialog
    					formData        : {},                 // An object with additional data to send to the server-side upload script with every file upload
    					preventCaching  : true,               // Adds a random value to the Flash URL to prevent caching of it (conflicts with existing parameters)
    					progressData    : 'percentage',       // ('percentage' or 'speed') Data to show in the queue item during a file upload
    					queueID         : false,              // The ID of the DOM object to use as a file queue (without the #)
    					queueSizeLimit  : 999,                // The maximum number of files that can be in the queue at one time
    					removeCompleted : true,               // Remove queue items from the queue when they are done uploading
    					removeTimeout   : 3,                  // The delay in seconds before removing a queue item if removeCompleted is set to true
    					requeueErrors   : false,              // Keep errored files in the queue and keep trying to upload them
    					successTimeout  : 30,                 // The number of seconds to wait for Flash to detect the server's response after the file has finished uploading
    					uploadLimit     : 0,                  // The maximum number of files you can upload
    					width           : 120,                // The width of the browse button
    					
    					// Events
    					overrideEvents   : []             // (Array) A list of default event handlers to skip
    					/*
    					onCancel         // Triggered when a file is cancelled from the queue
    					onClearQueue     // Triggered during the 'clear queue' method
    					onDestroy        // Triggered when the uploadify object is destroyed
    					onDialogClose    // Triggered when the browse dialog is closed
    					onDialogOpen     // Triggered when the browse dialog is opened
    					onDisable        // Triggered when the browse button gets disabled
    					onEnable         // Triggered when the browse button gets enabled
    					onFallback       // Triggered is Flash is not detected    
    					onInit           // Triggered when Uploadify is initialized
    					onQueueComplete  // Triggered when all files in the queue have been uploaded
    					onSelectError    // Triggered when an error occurs while selecting a file (file size, queue size limit, etc.)
    					onSelect         // Triggered for each file that is selected
    					onSWFReady       // Triggered when the SWF button is loaded
    					onUploadComplete // Triggered when a file upload completes (success or error)
    					onUploadError    // Triggered when a file upload returns an error
    					onUploadSuccess  // Triggered when a file is uploaded successfully
    					onUploadProgress // Triggered every time a file progress is updated
    					onUploadStart    // Triggered immediately before a file upload starts
    					*/
    				}, options);
    
    				// Prepare settings for SWFUpload
    				var swfUploadSettings = {
    					assume_success_timeout   : settings.successTimeout,
    					button_placeholder_id    : settings.id,
    					button_width             : settings.width,
    					button_height            : settings.height,
    					button_text              : null,
    					button_text_style        : null,
    					button_text_top_padding  : 0,
    					button_text_left_padding : 0,
    					button_action            : (settings.multi ? SWFUpload.BUTTON_ACTION.SELECT_FILES : SWFUpload.BUTTON_ACTION.SELECT_FILE),
    					button_disabled          : false,
    					button_cursor            : (settings.buttonCursor == 'arrow' ? SWFUpload.CURSOR.ARROW : SWFUpload.CURSOR.HAND),
    					button_window_mode       : SWFUpload.WINDOW_MODE.TRANSPARENT,
    					debug                    : settings.debug,						
    					requeue_on_error         : settings.requeueErrors,
    					file_post_name           : settings.fileObjName,
    					file_size_limit          : settings.fileSizeLimit,
    					file_types               : settings.fileTypeExts,
    					file_types_description   : settings.fileTypeDesc,
    					file_queue_limit         : settings.queueSizeLimit,
    					file_upload_limit        : settings.uploadLimit,
    					flash_url                : settings.swf,					
    					prevent_swf_caching      : settings.preventCaching,
    					post_params              : settings.formData,
    					upload_url               : settings.uploader,
    					use_query_string         : (settings.method == 'get'),
    					
    					// Event Handlers 
    					file_dialog_complete_handler : handlers.onDialogClose,
    					file_dialog_start_handler    : handlers.onDialogOpen,
    					file_queued_handler          : handlers.onSelect,
    					file_queue_error_handler     : handlers.onSelectError,
    					swfupload_loaded_handler     : settings.onSWFReady,
    					upload_complete_handler      : handlers.onUploadComplete,
    					upload_error_handler         : handlers.onUploadError,
    					upload_progress_handler      : handlers.onUploadProgress,
    					upload_start_handler         : handlers.onUploadStart,
    					upload_success_handler       : handlers.onUploadSuccess
    				}
    
    				// Merge the user-defined options with the defaults
    				if (swfUploadOptions) {
    					swfUploadSettings = $.extend(swfUploadSettings, swfUploadOptions);
    				}
    				// Add the user-defined settings to the swfupload object
    				swfUploadSettings = $.extend(swfUploadSettings, settings);
    				
    				// Detect if Flash is available
    				var playerVersion  = swfobject.getFlashPlayerVersion();
    				var flashInstalled = (playerVersion.major >= 9);
    
    				if (flashInstalled) {
    					// Create the swfUpload instance
    					window['uploadify_' + settings.id] = new SWFUpload(swfUploadSettings);
    					var swfuploadify = window['uploadify_' + settings.id];
    
    					// Add the SWFUpload object to the elements data object
    					$this.data('uploadify', swfuploadify);
    					
    					// Wrap the instance
    					var $wrapper = $('<div />', {
    						'id'    : settings.id,
    						'class' : 'uploadify',
    						'css'   : {
    									'height'   : settings.height + 'px',
    									'width'    : settings.width + 'px'
    								  }
    					});
    					$('#' + swfuploadify.movieName).wrap($wrapper);
    					// Recreate the reference to wrapper
    					$wrapper = $('#' + settings.id);
    					// Add the data object to the wrapper 
    					$wrapper.data('uploadify', swfuploadify);
    
    					// Create the button
    					var $button = $('<div />', {
    						'id'    : settings.id + '-button',
    						'class' : 'uploadify-button ' + settings.buttonClass
    					});
    					if (settings.buttonImage) {
    						$button.css({
    							'background-image' : "url('" + settings.buttonImage + "')",
    							'text-indent'      : '-9999px'
    						});
    					}
    					$button.html('<span class="uploadify-button-text">' + settings.buttonText + '</span>')
    					.css({
    						'height'      : settings.height + 'px',
    						'line-height' : settings.height + 'px',
    						'width'       : settings.width + 'px'
    					});
    					// Append the button to the wrapper
    					$wrapper.append($button);
    
    					// Adjust the styles of the movie
    					$('#' + swfuploadify.movieName).css({
    						'position' : 'absolute',
    						'z-index'  : 1
    					});
    					
    					// Create the file queue
    					if (!settings.queueID) {
    						var $queue = $('<div />', {
    							'id'    : settings.id + '-queue',
    							'class' : 'uploadify-queue'
    						});
    						$wrapper.after($queue);
    						swfuploadify.settings.queueID      = settings.id + '-queue';
    						swfuploadify.settings.defaultQueue = true;
    					}
    					
    					// Create some queue related objects and variables
    					swfuploadify.queueData = {
    						files              : {}, // The files in the queue
    						filesSelected      : 0, // The number of files selected in the last select operation
    						filesQueued        : 0, // The number of files added to the queue in the last select operation
    						filesReplaced      : 0, // The number of files replaced in the last select operation
    						filesCancelled     : 0, // The number of files that were cancelled instead of replaced
    						filesErrored       : 0, // The number of files that caused error in the last select operation
    						uploadsSuccessful  : 0, // The number of files that were successfully uploaded
    						uploadsErrored     : 0, // The number of files that returned errors during upload
    						averageSpeed       : 0, // The average speed of the uploads in KB
    						queueLength        : 0, // The number of files in the queue
    						queueSize          : 0, // The size in bytes of the entire queue
    						uploadSize         : 0, // The size in bytes of the upload queue
    						queueBytesUploaded : 0, // The size in bytes that have been uploaded for the current upload queue
    						uploadQueue        : [], // The files currently to be uploaded
    						errorMsg           : 'Some files were not added to the queue:'
    					};
    
    					// Save references to all the objects
    					swfuploadify.original = $clone;
    					swfuploadify.wrapper  = $wrapper;
    					swfuploadify.button   = $button;
    					swfuploadify.queue    = $queue;
    
    					// Call the user-defined init event handler
    					if (settings.onInit) settings.onInit.call($this, swfuploadify);
    
    				} else {
    
    					// Call the fallback function
    					if (settings.onFallback) settings.onFallback.call($this);
    
    				}
    			});
    
    		},
    
    		// Stop a file upload and remove it from the queue 
    		cancel : function(fileID, supressEvent) {
    
    			var args = arguments;
    
    			this.each(function() {
    				// Create a reference to the jQuery DOM object
    				var $this        = $(this),
    					swfuploadify = $this.data('uploadify'),
    					settings     = swfuploadify.settings,
    					delay        = -1;
    
    				if (args[0]) {
    					// Clear the queue
    					if (args[0] == '*') {
    						var queueItemCount = swfuploadify.queueData.queueLength;
    						$('#' + settings.queueID).find('.uploadify-queue-item').each(function() {
    							delay++;
    							if (args[1] === true) {
    								swfuploadify.cancelUpload($(this).attr('id'), false);
    							} else {
    								swfuploadify.cancelUpload($(this).attr('id'));
    							}
    							$(this).find('.data').removeClass('data').html(' - Cancelled');
    							$(this).find('.uploadify-progress-bar').remove();
    							$(this).delay(1000 + 100 * delay).fadeOut(500, function() {
    								$(this).remove();
    							});
    						});
    						swfuploadify.queueData.queueSize   = 0;
    						swfuploadify.queueData.queueLength = 0;
    						// Trigger the onClearQueue event
    						if (settings.onClearQueue) settings.onClearQueue.call($this, queueItemCount);
    					} else {
    						for (var n = 0; n < args.length; n++) {
    							swfuploadify.cancelUpload(args[n]);
    							$('#' + args[n]).find('.data').removeClass('data').html(' - Cancelled');
    							$('#' + args[n]).find('.uploadify-progress-bar').remove();
    							$('#' + args[n]).delay(1000 + 100 * n).fadeOut(500, function() {
    								$(this).remove();
    							});
    						}
    					}
    				} else {
    					var item = $('#' + settings.queueID).find('.uploadify-queue-item').get(0);
    					$item = $(item);
    					swfuploadify.cancelUpload($item.attr('id'));
    					$item.find('.data').removeClass('data').html(' - Cancelled');
    					$item.find('.uploadify-progress-bar').remove();
    					$item.delay(1000).fadeOut(500, function() {
    						$(this).remove();
    					});
    				}
    			});
    
    		},
    
    		// Revert the DOM object back to its original state
    		destroy : function() {
    
    			this.each(function() {
    				// Create a reference to the jQuery DOM object
    				var $this        = $(this),
    					swfuploadify = $this.data('uploadify'),
    					settings     = swfuploadify.settings;
    
    				// Destroy the SWF object and 
    				swfuploadify.destroy();
    				
    				// Destroy the queue
    				if (settings.defaultQueue) {
    					$('#' + settings.queueID).remove();
    				}
    				
    				// Reload the original DOM element
    				$('#' + settings.id).replaceWith(swfuploadify.original);
    
    				// Call the user-defined event handler
    				if (settings.onDestroy) settings.onDestroy.call(this);
    
    				delete swfuploadify;
    			});
    
    		},
    
    		// Disable the select button
    		disable : function(isDisabled) {
    			
    			this.each(function() {
    				// Create a reference to the jQuery DOM object
    				var $this        = $(this),
    					swfuploadify = $this.data('uploadify'),
    					settings     = swfuploadify.settings;
    
    				// Call the user-defined event handlers
    				if (isDisabled) {
    					swfuploadify.button.addClass('disabled');
    					if (settings.onDisable) settings.onDisable.call(this);
    				} else {
    					swfuploadify.button.removeClass('disabled');
    					if (settings.onEnable) settings.onEnable.call(this);
    				}
    
    				// Enable/disable the browse button
    				swfuploadify.setButtonDisabled(isDisabled);
    			});
    
    		},
    
    		// Get or set the settings data
    		settings : function(name, value, resetObjects) {
    
    			var args        = arguments;
    			var returnValue = value;
    
    			this.each(function() {
    				// Create a reference to the jQuery DOM object
    				var $this        = $(this),
    					swfuploadify = $this.data('uploadify'),
    					settings     = swfuploadify.settings;
    
    				if (typeof(args[0]) == 'object') {
    					for (var n in value) {
    						setData(n,value[n]);
    					}
    				}
    				if (args.length === 1) {
    					returnValue =  settings[name];
    				} else {
    					switch (name) {
    						case 'uploader':
    							swfuploadify.setUploadURL(value);
    							break;
    						case 'formData':
    							if (!resetObjects) {
    								value = $.extend(settings.formData, value);
    							}
    							swfuploadify.setPostParams(settings.formData);
    							break;
    						case 'method':
    							if (value == 'get') {
    								swfuploadify.setUseQueryString(true);
    							} else {
    								swfuploadify.setUseQueryString(false);
    							}
    							break;
    						case 'fileObjName':
    							swfuploadify.setFilePostName(value);
    							break;
    						case 'fileTypeExts':
    							swfuploadify.setFileTypes(value, settings.fileTypeDesc);
    							break;
    						case 'fileTypeDesc':
    							swfuploadify.setFileTypes(settings.fileTypeExts, value);
    							break;
    						case 'fileSizeLimit':
    							swfuploadify.setFileSizeLimit(value);
    							break;
    						case 'uploadLimit':
    							swfuploadify.setFileUploadLimit(value);
    							break;
    						case 'queueSizeLimit':
    							swfuploadify.setFileQueueLimit(value);
    							break;
    						case 'buttonImage':
    							swfuploadify.button.css('background-image', settingValue);
    							break;
    						case 'buttonCursor':
    							if (value == 'arrow') {
    								swfuploadify.setButtonCursor(SWFUpload.CURSOR.ARROW);
    							} else {
    								swfuploadify.setButtonCursor(SWFUpload.CURSOR.HAND);
    							}
    							break;
    						case 'buttonText':
    							$('#' + settings.id + '-button').find('.uploadify-button-text').html(value);
    							break;
    						case 'width':
    							swfuploadify.setButtonDimensions(value, settings.height);
    							break;
    						case 'height':
    							swfuploadify.setButtonDimensions(settings.width, value);
    							break;
    						case 'multi':
    							if (value) {
    								swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILES);
    							} else {
    								swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILE);
    							}
    							break;
    					}
    					settings[name] = value;
    				}
    			});
    			
    			if (args.length === 1) {
    				return returnValue;
    			}
    
    		},
    
    		// Stop the current uploads and requeue what is in progress
    		stop : function() {
    
    			this.each(function() {
    				// Create a reference to the jQuery DOM object
    				var $this        = $(this),
    					swfuploadify = $this.data('uploadify');
    
    				// Reset the queue information
    				swfuploadify.queueData.averageSpeed  = 0;
    				swfuploadify.queueData.uploadSize    = 0;
    				swfuploadify.queueData.bytesUploaded = 0;
    				swfuploadify.queueData.uploadQueue   = [];
    
    				swfuploadify.stopUpload();
    			});
    
    		},
    
    		// Start uploading files in the queue
    		upload : function() {
    
    			var args = arguments;
    
    			this.each(function() {
    				// Create a reference to the jQuery DOM object
    				var $this        = $(this),
    					swfuploadify = $this.data('uploadify');
    
    				// Reset the queue information
    				swfuploadify.queueData.averageSpeed  = 0;
    				swfuploadify.queueData.uploadSize    = 0;
    				swfuploadify.queueData.bytesUploaded = 0;
    				swfuploadify.queueData.uploadQueue   = [];
    				
    				// Upload the files
    				if (args[0]) {
    					if (args[0] == '*') {
    						swfuploadify.queueData.uploadSize = swfuploadify.queueData.queueSize;
    						swfuploadify.queueData.uploadQueue.push('*');
    						swfuploadify.startUpload();
    					} else {
    						for (var n = 0; n < args.length; n++) {
    							swfuploadify.queueData.uploadSize += swfuploadify.queueData.files[args[n]].size;
    							swfuploadify.queueData.uploadQueue.push(args[n]);
    						}
    						swfuploadify.startUpload(swfuploadify.queueData.uploadQueue.shift());
    					}
    				} else {
    					swfuploadify.startUpload();
    				}
    
    			});
    
    		}
    
    	}
    
    	// These functions handle all the events that occur with the file uploader
    	var handlers = {
    
    		// Triggered when the file dialog is opened
    		onDialogOpen : function() {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			// Reset some queue info
    			this.queueData.errorMsg       = 'Some files were not added to the queue:';
    			this.queueData.filesReplaced  = 0;
    			this.queueData.filesCancelled = 0;
    
    			// Call the user-defined event handler
    			if (settings.onDialogOpen) settings.onDialogOpen.call(this);
    		},
    
    		// Triggered when the browse dialog is closed
    		onDialogClose :  function(filesSelected, filesQueued, queueLength) {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			// Update the queue information
    			this.queueData.filesErrored  = filesSelected - filesQueued;
    			this.queueData.filesSelected = filesSelected;
    			this.queueData.filesQueued   = filesQueued - this.queueData.filesCancelled;
    			this.queueData.queueLength   = queueLength;
    
    			// Run the default event handler
    			if ($.inArray('onDialogClose', settings.overrideEvents) < 0) {
    				if (this.queueData.filesErrored > 0) {
    					alert(this.queueData.errorMsg);
    				}
    			}
    
    			// Call the user-defined event handler
    			if (settings.onDialogClose) settings.onDialogClose.call(this, this.queueData);
    
    			// Upload the files if auto is true
    			if (settings.auto) $('#' + settings.id).uploadify('upload', '*');
    		},
    
    		// Triggered once for each file added to the queue
    		onSelect : function(file) {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			// Check if a file with the same name exists in the queue
    			var queuedFile = {};
    			for (var n in this.queueData.files) {
    				queuedFile = this.queueData.files[n];
    				if (queuedFile.uploaded != true && queuedFile.name == file.name) {
    					var replaceQueueItem = confirm('The file named "' + file.name + '" is already in the queue.\nDo you want to replace the existing item in the queue?');
    					if (!replaceQueueItem) {
    						this.cancelUpload(file.id);
    						this.queueData.filesCancelled++;
    						return false;
    					} else {
    						$('#' + queuedFile.id).remove();
    						this.cancelUpload(queuedFile.id);
    						this.queueData.filesReplaced++;
    					}
    				}
    			}
    
    			// Get the size of the file
    			var fileSize = Math.round(file.size / 1024);
    			var suffix   = 'KB';
    			if (fileSize > 1000) {
    				fileSize = Math.round(fileSize / 1000);
    				suffix   = 'MB';
    			}
    			var fileSizeParts = fileSize.toString().split('.');
    			fileSize = fileSizeParts[0];
    			if (fileSizeParts.length > 1) {
    				fileSize += '.' + fileSizeParts[1].substr(0,2);
    			}
    			fileSize += suffix;
    			
    			// Truncate the filename if it's too long
    			var fileName = file.name;
    			if (fileName.length > 25) {
    				fileName = fileName.substr(0,25) + '...';
    			}
    
    			// Run the default event handler
    			if ($.inArray('onSelect', settings.overrideEvents) < 0) {
    				
    				// Add the file item to the queue
    				$('#' + settings.queueID).append('<div id="' + file.id + '" class="uploadify-queue-item">\
    					<div class="cancel">\
    						<a href="javascript:$(\'#' + settings.id + '\').uploadify(\'cancel\', \'' + file.id + '\')">X</a>\
    					</div>\
    					<span class="fileName">' + fileName + ' (' + fileSize + ')</span><span class="data"></span>\
    					<div class="uploadify-progress">\
    						<div class="uploadify-progress-bar"><!--Progress Bar--></div>\
    					</div>\
    				</div>');
    				
    			}
    
    			this.queueData.queueSize += file.size;
    			this.queueData.files[file.id] = file;
    
    			// Call the user-defined event handler
    			if (settings.onSelect) settings.onSelect.apply(this, arguments);
    		},
    
    		// Triggered when a file is not added to the queue
    		onSelectError : function(file, errorCode, errorMsg) {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			// Run the default event handler
    			if ($.inArray('onSelectError', settings.overrideEvents) < 0) {
    				switch(errorCode) {
    					case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
    						if (settings.queueSizeLimit > errorMsg) {
    							this.queueData.errorMsg += '\nThe number of files selected exceeds the remaining upload limit (' + errorMsg + ').';
    						} else {
    							this.queueData.errorMsg += '\nThe number of files selected exceeds the queue size limit (' + settings.queueSizeLimit + ').';
    						}
    						break;
    					case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
    						this.queueData.errorMsg += '\nThe file "' + file.name + '" exceeds the size limit (' + settings.fileSizeLimit + ').';
    						break;
    					case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
    						this.queueData.errorMsg += '\nThe file "' + file.name + '" is empty.';
    						break;
    					case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
    						this.queueData.errorMsg += '\nThe file "' + file.name + '" is not an accepted file type (' + settings.fileTypeDesc + ').';
    						break;
    				}
    			}
    			if (errorCode != SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
    				delete this.queueData.files[file.id];
    			}
    
    			// Call the user-defined event handler
    			if (settings.onSelectError) settings.onSelectError.apply(this, arguments);
    		},
    
    		// Triggered when all the files in the queue have been processed
    		onQueueComplete : function() {
    			if (this.settings.onQueueComplete) this.settings.onQueueComplete.call(this, this.settings.queueData);
    		},
    
    		// Triggered when a file upload successfully completes
    		onUploadComplete : function(file) {
    			// Load the swfupload settings
    			var settings     = this.settings,
    				swfuploadify = this;
    
    			// Check if all the files have completed uploading
    			var stats = this.getStats();
    			this.queueData.queueLength = stats.files_queued;
    			if (this.queueData.uploadQueue[0] == '*') {
    				if (this.queueData.queueLength > 0) {
    					this.startUpload();
    				} else {
    					this.queueData.uploadQueue = [];
    
    					// Call the user-defined event handler for queue complete
    					if (settings.onQueueComplete) settings.onQueueComplete.call(this, this.queueData);
    				}
    			} else {
    				if (this.queueData.uploadQueue.length > 0) {
    					this.startUpload(this.queueData.uploadQueue.shift());
    				} else {
    					this.queueData.uploadQueue = [];
    
    					// Call the user-defined event handler for queue complete
    					if (settings.onQueueComplete) settings.onQueueComplete.call(this, this.queueData);
    				}
    			}
    
    			// Call the default event handler
    			if ($.inArray('onUploadComplete', settings.overrideEvents) < 0) {
    				if (settings.removeCompleted) {
    					switch (file.filestatus) {
    						case SWFUpload.FILE_STATUS.COMPLETE:
    							setTimeout(function() { 
    								if ($('#' + file.id)) {
    									swfuploadify.queueData.queueSize   -= file.size;
    									swfuploadify.queueData.queueLength -= 1;
    									delete swfuploadify.queueData.files[file.id]
    									$('#' + file.id).fadeOut(500, function() {
    										$(this).remove();
    									});
    								}
    							}, settings.removeTimeout * 1000);
    							break;
    						case SWFUpload.FILE_STATUS.ERROR:
    							if (!settings.requeueErrors) {
    								setTimeout(function() {
    									if ($('#' + file.id)) {
    										swfuploadify.queueData.queueSize   -= file.size;
    										swfuploadify.queueData.queueLength -= 1;
    										delete swfuploadify.queueData.files[file.id];
    										$('#' + file.id).fadeOut(500, function() {
    											$(this).remove();
    										});
    									}
    								}, settings.removeTimeout * 1000);
    							}
    							break;
    					}
    				} else {
    					file.uploaded = true;
    				}
    			}
    
    			// Call the user-defined event handler
    			if (settings.onUploadComplete) settings.onUploadComplete.call(this, file);
    		},
    
    		// Triggered when a file upload returns an error
    		onUploadError : function(file, errorCode, errorMsg) {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			// Set the error string
    			var errorString = 'Error';
    			switch(errorCode) {
    				case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
    					errorString = 'HTTP Error (' + errorMsg + ')';
    					break;
    				case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
    					errorString = 'Missing Upload URL';
    					break;
    				case SWFUpload.UPLOAD_ERROR.IO_ERROR:
    					errorString = 'IO Error';
    					break;
    				case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
    					errorString = 'Security Error';
    					break;
    				case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
    					alert('The upload limit has been reached (' + errorMsg + ').');
    					errorString = 'Exceeds Upload Limit';
    					break;
    				case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
    					errorString = 'Failed';
    					break;
    				case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:
    					break;
    				case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
    					errorString = 'Validation Error';
    					break;
    				case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
    					errorString = 'Cancelled';
    					this.queueData.queueSize   -= file.size;
    					this.queueData.queueLength -= 1;
    					if (file.status == SWFUpload.FILE_STATUS.IN_PROGRESS || $.inArray(file.id, this.queueData.uploadQueue) >= 0) {
    						this.queueData.uploadSize -= file.size;
    					}
    					// Trigger the onCancel event
    					if (settings.onCancel) settings.onCancel.call(this, file);
    					delete this.queueData.files[file.id];
    					break;
    				case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
    					errorString = 'Stopped';
    					break;
    			}
    
    			// Call the default event handler
    			if ($.inArray('onUploadError', settings.overrideEvents) < 0) {
    
    				if (errorCode != SWFUpload.UPLOAD_ERROR.FILE_CANCELLED && errorCode != SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED) {
    					$('#' + file.id).addClass('uploadify-error');
    				}
    
    				// Reset the progress bar
    				$('#' + file.id).find('.uploadify-progress-bar').css('width','1px');
    
    				// Add the error message to the queue item
    				if (errorCode != SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND && file.status != SWFUpload.FILE_STATUS.COMPLETE) {
    					$('#' + file.id).find('.data').html(' - ' + errorString);
    				}
    			}
    
    			var stats = this.getStats();
    			this.queueData.uploadsErrored = stats.upload_errors;
    
    			// Call the user-defined event handler
    			if (settings.onUploadError) settings.onUploadError.call(this, file, errorCode, errorMsg, errorString);
    		},
    
    		// Triggered periodically during a file upload
    		onUploadProgress : function(file, fileBytesLoaded, fileTotalBytes) {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			// Setup all the variables
    			var timer            = new Date();
    			var newTime          = timer.getTime();
    			var lapsedTime       = newTime - this.timer;
    			if (lapsedTime > 500) {
    				this.timer = newTime;
    			}
    			var lapsedBytes      = fileBytesLoaded - this.bytesLoaded;
    			this.bytesLoaded     = fileBytesLoaded;
    			var queueBytesLoaded = this.queueData.queueBytesUploaded + fileBytesLoaded;
    			var percentage       = Math.round(fileBytesLoaded / fileTotalBytes * 100);
    			
    			// Calculate the average speed
    			var suffix = 'KB/s';
    			var mbs = 0;
    			var kbs = (lapsedBytes / 1024) / (lapsedTime / 1000);
    			    kbs = Math.floor(kbs * 10) / 10;
    			if (this.queueData.averageSpeed > 0) {
    				this.queueData.averageSpeed = Math.floor((this.queueData.averageSpeed + kbs) / 2);
    			} else {
    				this.queueData.averageSpeed = Math.floor(kbs);
    			}
    			if (kbs > 1000) {
    				mbs = (kbs * .001);
    				this.queueData.averageSpeed = Math.floor(mbs);
    				suffix = 'MB/s';
    			}
    			
    			// Call the default event handler
    			if ($.inArray('onUploadProgress', settings.overrideEvents) < 0) {
    				if (settings.progressData == 'percentage') {
    					$('#' + file.id).find('.data').html(' - ' + percentage + '%');
    				} else if (settings.progressData == 'speed' && lapsedTime > 500) {
    					$('#' + file.id).find('.data').html(' - ' + this.queueData.averageSpeed + suffix);
    				}
    				$('#' + file.id).find('.uploadify-progress-bar').css('width', percentage + '%');
    			}
    
    			// Call the user-defined event handler
    			if (settings.onUploadProgress) settings.onUploadProgress.call(this, file, fileBytesLoaded, fileTotalBytes, queueBytesLoaded, this.queueData.uploadSize);
    		},
    
    		// Triggered right before a file is uploaded
    		onUploadStart : function(file) {
    			// Load the swfupload settings
    			var settings = this.settings;
    
    			var timer        = new Date();
    			this.timer       = timer.getTime();
    			this.bytesLoaded = 0;
    			if (this.queueData.uploadQueue.length == 0) {
    				this.queueData.uploadSize = file.size;
    			}
    			if (settings.checkExisting) {
    				$.ajax({
    					type    : 'POST',
    					async   : false,
    					url     : settings.checkExisting,
    					data    : {filename: file.name},
    					success : function(data) {
    						if (data == 1) {
    							var overwrite = confirm('A file with the name "' + file.name + '" already exists on the server.\nWould you like to replace the existing file?');
    							if (!overwrite) {
    								this.cancelUpload(file.id);
    								$('#' + file.id).remove();
    								if (this.queueData.uploadQueue.length > 0 && this.queueData.queueLength > 0) {
    									if (this.queueData.uploadQueue[0] == '*') {
    										this.startUpload();
    									} else {
    										this.startUpload(this.queueData.uploadQueue.shift());
    									}
    								}
    							}
    						}
    					}
    				});
    			}
    
    			// Call the user-defined event handler
    			if (settings.onUploadStart) settings.onUploadStart.call(this, file); 
    		},
    
    		// Triggered when a file upload returns a successful code
    		onUploadSuccess : function(file, data, response) {
    			// Load the swfupload settings
    			var settings = this.settings;
    			var stats    = this.getStats();
    			this.queueData.uploadsSuccessful = stats.successful_uploads;
    			this.queueData.queueBytesUploaded += file.size;
    
    			// Call the default event handler
    			if ($.inArray('onUploadSuccess', settings.overrideEvents) < 0) {
    				$('#' + file.id).find('.data').html(' - Complete');
    			}
    
    			// Call the user-defined event handler
    			if (settings.onUploadSuccess) settings.onUploadSuccess.call(this, file, data, response); 
    		}
    
    	}
    
    	$.fn.uploadify = function(method) {
    
    		if (methods[method]) {
    			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    		} else if (typeof method === 'object' || !method) {
    			return methods.init.apply(this, arguments);
    		} else {
    			$.error('The method ' + method + ' does not exist in $.uploadify');
    		}
    
    	}
    
    })($);