xuhy
2024-05-13 ad99af1cd94bc1564efcc606f3d91f95bd1ac9b3
driver-js
185个文件已添加
130167 ■■■■■ 已修改文件
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/ASPJson.class.asp 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/MultiformProcessor.class.asp 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/PathFormatter.class.asp 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/README.md 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/Uploader.Class.asp 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_config.asp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_crawler.asp 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_list.asp 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_upload.asp 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/config.json 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/config_loader.asp 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/controller.asp 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/index.html 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/config.json 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/controller.jsp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/ActionEnter.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/ConfigManager.java 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/Encoder.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/PathFormat.java 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/ActionMap.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/ActionState.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/AppInfo.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/BaseState.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/FileType.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/MIMEType.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/MultiState.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/State.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/hunter/FileManager.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/hunter/ImageHunter.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/Base64Uploader.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/BinaryUploader.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/StorageManager.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/Uploader.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/en.js 684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/addimage.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/alldeletebtnhoverskin.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/alldeletebtnupskin.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/background.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/button.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/copy.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/deletedisable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/deleteenable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/listbackground.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/localimage.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/music.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotateleftdisable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotateleftenable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotaterightdisable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotaterightenable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/copy.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/localimage.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/music.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/zh-cn.js 669 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/Config.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/ConfigHandler.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/CrawlerHandler.cs 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/Handler.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/ListFileHandler.cs 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/NotSupportedHandler.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/PathFormater.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/UploadHandler.cs 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Bin/Newtonsoft.Json.dll 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Bin/Newtonsoft.Json.pdb 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Bin/Newtonsoft.Json.xml 8472 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/README.md 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Web.config 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/config.json 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/controller.ashx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/net.sln 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/Uploader.class.php 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/action_crawler.php 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/action_list.php 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/action_upload.php 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/config.json 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/controller.php 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/css/ueditor.css 1903 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/css/ueditor.min.css 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/dialogbase.css 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/anchor.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/arrow.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/arrow_down.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/arrow_up.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/button-bg.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cancelbutton.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/charts.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_h.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_h.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_v.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_v.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/dialog-title-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/filescan.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/highlighted.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/icons-all.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/loaderror.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/loading.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/lock.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/neweditor-tab-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/pagebreak.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/scale.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/sortable.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/spacer.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/sparator_v.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/table-cell-align.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/tangram-colorpicker.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/toolbar_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/unhighlighted.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/videologo.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/word.gif 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/wordpaste.png 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/iframe.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/SyntaxHighlighter/shCore.js 3655 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/SyntaxHighlighter/shCoreDefault.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/codemirror/codemirror.css 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/codemirror/codemirror.js 3581 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/mootools-adapter.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/mootools-adapter.src.js 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/prototype-adapter.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/prototype-adapter.src.js 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/standalone-framework.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/standalone-framework.src.js 583 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts-more.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts-more.src.js 2430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts.js 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts.src.js 16974 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/annotations.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/annotations.src.js 401 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/canvas-tools.js 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/canvas-tools.src.js 3113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/data.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/data.src.js 582 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/drilldown.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/drilldown.src.js 447 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/exporting.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/exporting.src.js 709 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/funnel.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/funnel.src.js 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/heatmap.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/heatmap.src.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/map.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/map.src.js 1002 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/no-data-to-display.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/no-data-to-display.src.js 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/dark-blue.js 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/dark-green.js 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/gray.js 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/grid.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/skies.js 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/jquery-1.10.2.js 9789 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/jquery-1.10.2.min.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/jquery-1.10.2.min.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/snapscreen/UEditorSnapscreen.exe 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.eot 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.svg 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.ttf 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.woff 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video-js.css 766 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video-js.min.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video-js.swf 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video.dev.js 7108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video.js 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/Uploader.swf 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.custom.js 5670 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.custom.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.flashonly.js 4176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.flashonly.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.html5only.js 5559 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.html5only.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.js 6733 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.withoutimage.js 4593 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.withoutimage.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/zeroclipboard/ZeroClipboard.js 1256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/zeroclipboard/ZeroClipboard.min.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/zeroclipboard/ZeroClipboard.swf 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.all.js 29429 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.all.min.js 709 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.config.js 413 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.parse.js 1022 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.parse.min.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/ASPJson.class.asp
New file
@@ -0,0 +1,271 @@
<%
'Februari 2014 - Version 1.17 by Gerrit van Kuipers
Class AspJSON
    Public data
    Private p_JSONstring
    private aj_in_string, aj_in_escape, aj_i_tmp, aj_char_tmp, aj_s_tmp, aj_line_tmp, aj_line, aj_lines, aj_currentlevel, aj_currentkey, aj_currentvalue, aj_newlabel, aj_XmlHttp, aj_RegExp, aj_colonfound
    Private Sub Class_Initialize()
        Set data = Collection()
        Set aj_RegExp = new regexp
        aj_RegExp.Pattern = "\s{0,}(\S{1}[\s,\S]*\S{1})\s{0,}"
        aj_RegExp.Global = False
        aj_RegExp.IgnoreCase = True
        aj_RegExp.Multiline = True
    End Sub
    Private Sub Class_Terminate()
        Set data = Nothing
        Set aj_RegExp = Nothing
    End Sub
    Public Sub loadJSON(inputsource)
        inputsource = aj_MultilineTrim(inputsource)
        If Len(inputsource) = 0 Then Err.Raise 1, "loadJSON Error", "No data to load."
        select case Left(inputsource, 1)
            case "{", "["
            case else
                Set aj_XmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
                aj_XmlHttp.open "GET", inputsource, False
                aj_XmlHttp.setRequestHeader "Content-Type", "text/json"
                aj_XmlHttp.setRequestHeader "CharSet", "UTF-8"
                aj_XmlHttp.Send
                inputsource = aj_XmlHttp.responseText
                set aj_XmlHttp = Nothing
        end select
        p_JSONstring = CleanUpJSONstring(inputsource)
        aj_lines = Split(p_JSONstring, Chr(13) & Chr(10))
        Dim level(99)
        aj_currentlevel = 1
        Set level(aj_currentlevel) = data
        For Each aj_line In aj_lines
            aj_currentkey = ""
            aj_currentvalue = ""
            If Instr(aj_line, ":") > 0 Then
                aj_in_string = False
                aj_in_escape = False
                aj_colonfound = False
                For aj_i_tmp = 1 To Len(aj_line)
                    If aj_in_escape Then
                        aj_in_escape = False
                    Else
                        Select Case Mid(aj_line, aj_i_tmp, 1)
                            Case """"
                                aj_in_string = Not aj_in_string
                            Case ":"
                                If Not aj_in_escape And Not aj_in_string Then
                                    aj_currentkey = Left(aj_line, aj_i_tmp - 1)
                                    aj_currentvalue = Mid(aj_line, aj_i_tmp + 1)
                                    aj_colonfound = True
                                    Exit For
                                End If
                            Case "\"
                                aj_in_escape = True
                        End Select
                    End If
                Next
                if aj_colonfound then
                    aj_currentkey = aj_Strip(aj_JSONDecode(aj_currentkey), """")
                    If Not level(aj_currentlevel).exists(aj_currentkey) Then level(aj_currentlevel).Add aj_currentkey, ""
                end if
            End If
            If right(aj_line,1) = "{" Or right(aj_line,1) = "[" Then
                If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
                Set level(aj_currentlevel).Item(aj_currentkey) = Collection()
                Set level(aj_currentlevel + 1) = level(aj_currentlevel).Item(aj_currentkey)
                aj_currentlevel = aj_currentlevel + 1
                aj_currentkey = ""
            ElseIf right(aj_line,1) = "}" Or right(aj_line,1) = "]" or right(aj_line,2) = "}," Or right(aj_line,2) = "]," Then
                aj_currentlevel = aj_currentlevel - 1
            ElseIf Len(Trim(aj_line)) > 0 Then
                if Len(aj_currentvalue) = 0 Then aj_currentvalue = aj_line
                aj_currentvalue = getJSONValue(aj_currentvalue)
                If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
                level(aj_currentlevel).Item(aj_currentkey) = aj_currentvalue
            End If
        Next
    End Sub
    Public Function Collection()
        set Collection = Server.CreateObject("Scripting.Dictionary")
    End Function
    Public Function AddToCollection(dictobj)
        if TypeName(dictobj) <> "Dictionary" then Err.Raise 1, "AddToCollection Error", "Not a collection."
        aj_newlabel = dictobj.Count
        dictobj.Add aj_newlabel, Collection()
        set AddToCollection = dictobj.item(aj_newlabel)
    end function
    Private Function CleanUpJSONstring(aj_originalstring)
        aj_originalstring = Replace(aj_originalstring, Chr(13) & Chr(10), "")
        aj_originalstring = Mid(aj_originalstring, 2, Len(aj_originalstring) - 2)
        aj_in_string = False : aj_in_escape = False : aj_s_tmp = ""
        For aj_i_tmp = 1 To Len(aj_originalstring)
            aj_char_tmp = Mid(aj_originalstring, aj_i_tmp, 1)
            If aj_in_escape Then
                aj_in_escape = False
                aj_s_tmp = aj_s_tmp & aj_char_tmp
            Else
                Select Case aj_char_tmp
                    Case "\" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_escape = True
                    Case """" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_string = Not aj_in_string
                    Case "{", "["
                        aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
                    Case "}", "]"
                        aj_s_tmp = aj_s_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10)) & aj_char_tmp
                    Case "," : aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
                    Case Else : aj_s_tmp = aj_s_tmp & aj_char_tmp
                End Select
            End If
        Next
        CleanUpJSONstring = ""
        aj_s_tmp = split(aj_s_tmp, Chr(13) & Chr(10))
        For Each aj_line_tmp In aj_s_tmp
            aj_line_tmp = replace(replace(aj_line_tmp, chr(10), ""), chr(13), "")
            CleanUpJSONstring = CleanUpJSONstring & aj_Trim(aj_line_tmp) & Chr(13) & Chr(10)
        Next
    End Function
    Private Function getJSONValue(ByVal val)
        val = Trim(val)
        If Left(val,1) = ":"  Then val = Mid(val, 2)
        If Right(val,1) = "," Then val = Left(val, Len(val) - 1)
        val = Trim(val)
        Select Case val
            Case "true"  : getJSONValue = True
            Case "false" : getJSONValue = False
            Case "null" : getJSONValue = Null
            Case Else
                If (Instr(val, """") = 0) Then
                    If IsNumeric(val) Then
                        getJSONValue = CDbl(val)
                    Else
                        getJSONValue = val
                    End If
                Else
                    If Left(val,1) = """" Then val = Mid(val, 2)
                    If Right(val,1) = """" Then val = Left(val, Len(val) - 1)
                    getJSONValue = aj_JSONDecode(Trim(val))
                End If
        End Select
    End Function
    Private JSONoutput_level
    Public Function JSONoutput()
        dim wrap_dicttype, aj_label
        JSONoutput_level = 1
        wrap_dicttype = "[]"
        For Each aj_label In data
             If Not aj_IsInt(aj_label) Then wrap_dicttype = "{}"
        Next
        JSONoutput = Left(wrap_dicttype, 1) & Chr(13) & Chr(10) & GetDict(data) & Right(wrap_dicttype, 1)
    End Function
    Public Function PrintJson
        Response.AddHeader "Content-Type", "text/plain"
        If IsEmpty(Request.QueryString("callback")) Then
            Response.Write JSONoutput()
        Else
            Response.Write Request.QueryString("callback") & "(" & JSONoutput() & ")"
        End If
    End Function
    Private Function GetDict(objDict)
        dim aj_item, aj_keyvals, aj_label, aj_dicttype
        For Each aj_item In objDict
            Select Case TypeName(objDict.Item(aj_item))
                Case "Dictionary"
                    GetDict = GetDict & Space(JSONoutput_level * 4)
                    aj_dicttype = "[]"
                    For Each aj_label In objDict.Item(aj_item).Keys
                         If Not aj_IsInt(aj_label) Then aj_dicttype = "{}"
                    Next
                    If aj_IsInt(aj_item) Then
                        GetDict = GetDict & (Left(aj_dicttype,1) & Chr(13) & Chr(10))
                    Else
                        GetDict = GetDict & ("""" & aj_JSONEncode(aj_item) & """" & ": " & Left(aj_dicttype,1) & Chr(13) & Chr(10))
                    End If
                    JSONoutput_level = JSONoutput_level + 1
                    aj_keyvals = objDict.Keys
                    GetDict = GetDict & (GetSubDict(objDict.Item(aj_item)) & Space(JSONoutput_level * 4) & Right(aj_dicttype,1) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10))
                Case Else
                    aj_keyvals =  objDict.Keys
                    GetDict = GetDict & (Space(JSONoutput_level * 4) & aj_InlineIf(aj_IsInt(aj_item), "", """" & aj_JSONEncode(aj_item) & """: ") & WriteValue(objDict.Item(aj_item)) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10))
            End Select
        Next
    End Function
    Private Function aj_IsInt(val)
        aj_IsInt = (TypeName(val) = "Integer" Or TypeName(val) = "Long")
    End Function
    Private Function GetSubDict(objSubDict)
        GetSubDict = GetDict(objSubDict)
        JSONoutput_level= JSONoutput_level -1
    End Function
    Private Function WriteValue(ByVal val)
        Select Case TypeName(val)
            Case "Double", "Integer", "Long": WriteValue = val
            Case "Null"                        : WriteValue = "null"
            Case "Boolean"                    : WriteValue = aj_InlineIf(val, "true", "false")
            Case Else                        : WriteValue = """" & aj_JSONEncode(val) & """"
        End Select
    End Function
    Private Function aj_JSONEncode(ByVal val)
        val = Replace(val, "\", "\\")
        val = Replace(val, """", "\""")
        'val = Replace(val, "/", "\/")
        val = Replace(val, Chr(8), "\b")
        val = Replace(val, Chr(12), "\f")
        val = Replace(val, Chr(10), "\n")
        val = Replace(val, Chr(13), "\r")
        val = Replace(val, Chr(9), "\t")
        aj_JSONEncode = Trim(val)
    End Function
    Private Function aj_JSONDecode(ByVal val)
        val = Replace(val, "\""", """")
        val = Replace(val, "\\", "\")
        val = Replace(val, "\/", "/")
        val = Replace(val, "\b", Chr(8))
        val = Replace(val, "\f", Chr(12))
        val = Replace(val, "\n", Chr(10))
        val = Replace(val, "\r", Chr(13))
        val = Replace(val, "\t", Chr(9))
        aj_JSONDecode = Trim(val)
    End Function
    Private Function aj_InlineIf(condition, returntrue, returnfalse)
        If condition Then aj_InlineIf = returntrue Else aj_InlineIf = returnfalse
    End Function
    Private Function aj_Strip(ByVal val, stripper)
        If Left(val, 1) = stripper Then val = Mid(val, 2)
        If Right(val, 1) = stripper Then val = Left(val, Len(val) - 1)
        aj_Strip = val
    End Function
    Private Function aj_MultilineTrim(TextData)
        aj_MultilineTrim = aj_RegExp.Replace(TextData, "$1")
    End Function
    private function aj_Trim(val)
        aj_Trim = Trim(val)
        Do While Left(aj_Trim, 1) = Chr(9) : aj_Trim = Mid(aj_Trim, 2) : Loop
        Do While Right(aj_Trim, 1) = Chr(9) : aj_Trim = Left(aj_Trim, Len(aj_Trim) - 1) : Loop
        aj_Trim = Trim(aj_Trim)
    end function
End Class
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/MultiformProcessor.class.asp
New file
@@ -0,0 +1,138 @@
<%
' Power by Techird
' Processor Usage:
'   Set p = new MultiformProcessor
'   Set formValues = p.Process()
'   filename = formValues.Item("filename")
'   Set stream = formValues.Item("file1") // the name of the file input
'   stream.SaveToFile "upload/" & filename
'   stream.Close
Class MultiformProcessor
    Private adTypeBinary
    Private adTypeText
    Private adModeReadWrite
    Private binCtLf
    Private binCtLf2
    private Sub Class_Initialize()
        adTypeBinary = 1
        adTypeText = 2
        adModeReadWrite = 3
        binCtLf = ChrB(13) & ChrB(10)
        binCtLf2 = binCtLf & binCtLf
    End Sub
    Private Function OpenStream( optype )
        Set stream = Server.CreateObject("ADODB.Stream")
        stream.Type = optype
        stream.Mode = adModeReadWrite
        stream.Open
        Set OpenStream = stream
    End Function
    Private Function CopyStreamPart( stream, pBgn, pEnd )
        Dim iStream, oStream
        Set iStream = stream
        Set oStream = OpenStream( adTypeBinary )
        iStream.Position = pBgn
        iStream.CopyTo oStream, pEnd - pBgn
        Set CopyStreamPart = oStream
    End Function
    Private Function GetString( stream, pBgn, pEnd )
        Dim iStream, oStream
        Set iStream = stream
        Set oStream = OpenStream( adTypeBinary )
        iStream.Position = pBgn
        iStream.CopyTo oStream, pEnd - pBgn
        oStream.Position = 0
        oStream.Type = adTypeText
        oStream.Charset = GetCharset
        GetString = oStream.ReadText
        oStream.Close
    End Function
    Private Function GetCharset()
        If Charset = "" Then
            GetCharset = "utf-8"
        Else
            GetCharset = Charset
        End If
    End Function
    'See RFC 2388
    'http://www.ietf.org/rfc/rfc2388.txt
    public Function Process()
        Dim formBytes, bLen, pBgn, pEnd, header, stream
        Dim varPtn, filePtn, formValues, key, field
        formBytes = Request.BinaryRead( Request.TotalBytes )
        Set stream = OpenStream( adTypeBinary )
            stream.Write formBytes
        Set varPtn = new RegExp
            varPtn.Pattern = "(\w+?)=""(.+?)"""
            varPtn.Global = True
        Set filePtn = new RegExp
            filePtn.Pattern = "filename="
        Set formValues = Server.CreateObject("Scripting.Dictionary")
        'Find boundary
        bLen = InStrB( 1, formBytes, binCtLf ) - 1
        boundary = LeftB( formBytes, bLen )
        'Init begin pointer to byte start
        pBgn = 1
        Do
            'Find begin pointer and end pointer for block header
            pBgn = pBgn + bLen + LenB( binCtLf ) - 1
            pEnd = InStrB( pBgn, formBytes, binCtLf2 )
            'If next block not found, means all blocks processed
            If pEnd = 0 Then
                Exit Do 'Load Finished
            End If
            'Decode the headerf
            header = GetString( stream, pBgn, pEnd )
            'Test if the block is a file block
            isFileBlock = filePtn.Test( header )
            'Find begin pointer and end pointer for block content
            pBgn = pEnd + LenB(binCtLf2) - 1
            pEnd = InStrB(pBgn, formBytes, boundary) - LenB( binCtLf ) - 1
            'Extract field values from header, which like key = "filed"
            Set matches = varPtn.Execute( header )
            For Each match In matches
                key = match.SubMatches(0)
                field = match.SubMatches(1)
                'filename as a field
                If key = "filename" Then
                    formValues.Add key, field
                'name specified fields
                ElseIf key = "name" Then
                    If isFileBlock Then
                        'Resolve content as stream for fileblock
                        formValues.Add field, CopyStreamPart(stream, pBgn, pEnd)
                    Else
                        'Resolve content as string for non-fileblock
                        formValues.Add field, GetString(stream, pBgn, pEnd)
                    End If
                End If
            Next
            'Move over the begin pointer to next block
            pBgn = pEnd + LenB( binCtLf ) + 1
        Loop
        stream.Close
        Set Process = formValues
    End Function
End Class
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/PathFormatter.class.asp
New file
@@ -0,0 +1,81 @@
<%
Class PathFormatter
    Public Function Format( ByVal pathFormat, ByVal filename )
        Dim ext, name
        If IsEmpty( format ) Then
            format = "{yyyy}{mm}{dd}{hh}{ii}{ss}{rand:6}"
        End If
        Set invalidPattern = new RegExp
        invalidPattern.Pattern = "[\\\/\:\*\?\<\>\|""]"
        invalidPattern.Global = true
        filename = invalidPattern.Replace( filename, "" )
        ext = GetExt( filename )
        name = GetNameWithoutExt( filename )
        pathFormat = Replace( pathFormat, "{filename}", name )
        pathFormat = Replace( pathFormat, "{time}", TimeStamp() )
        pathFormat = Replace( pathFormat, "{yyyy}", Year(Now) )
        pathFormat = Replace( pathFormat, "{yy}", Year(Now) Mod 100 )
        pathFormat = Replace( pathFormat, "{mm}", LeadZero( Month(Now) ) )
        pathFormat = Replace( pathFormat, "{dd}", LeadZero( Day(Now) ) )
        pathFormat = Replace( pathFormat, "{hh}", LeadZero( Hour(Now) ) )
        pathFormat = Replace( pathFormat, "{ii}", LeadZero( Minute(Now) ) )
        pathFormat = Replace( pathFormat, "{ss}", LeadZero( Second(Now) ) )
        Set randPattern = new RegExp
        randPattern.Pattern = "{rand(\:?)(\d+)}"
        Set matches = randPattern.Execute(pathFormat)
        If matches.Count Then
            Set match = matches(0)
            digit = 6
            If match.SubMatches.Count > 1 Then
                digit = 0 + match.SubMatches(1)
            End If
            min = 1
            Do While digit > 0
                min = min * 10
                digit = digit - 1
            Loop
            max = min * 10
            pathFormat = randPattern.Replace( pathFormat, Rand( min, max ) )
        End If
        Format = pathFormat + ext
    End Function
    Private Function GetExt( file )
        GetExt = Right( file, Len(file) - InStrRev(file, ".") + 1 )
    End Function
    Private Function GetNameWithoutExt( file )
        GetNameWithoutExt = Left( file, InStrRev(file, ".") - 1 )
    End Function
    Private Function TimeStamp()
        TimeStamp = DateDiff("s", "1970-1-1 8:00:00", Now())
    End Function
    Private Function Rand( min, max )
        Randomize
        Rand = Int( (max - min + 1) * Rnd + min )
    End Function
    Private Function GetFormatedDate()
        Dim yyyy, mm, dd
        yyyy = Year(Date)
        mm = LeadZero(Month(Date))
        dd = LeadZero(Day(Date))
        GetFormatedDate = yyyy & mm & dd
    End Function
    Private Function LeadZero( number )
        If number < 10 Then
            LeadZero = "0" & number
        Else
            LeadZero = number
        End If
    End Function
End Class
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/README.md
New file
@@ -0,0 +1,115 @@
# UEditor ASP 支持说明
应广大用户要求,UEditor 团队在原本支持的 PHP、Java 和 .Net 的后台的基础上,推出了 ASP 后台的支持。
## 支持版本 ##
支持 UEditor 1.2.6+ 的版本
## 支持功能 ##
支持所有其他后台已支持的功能,包括:
1. 图片上传
2. 远程图片转存
3. 图片管理
4. 涂鸦上传(包括背景)
5. Word 图片转存
6. 截图上传
7. 文件上传
## 部署指南 ##
Classic ASP 一般在 IIS 上运行。其它 ASP 服务器不介绍部署方式,请自行研究。
### 配置 ###
对于 v1.4.0 之前的版本,需要修改 `ueditor.config.js`。最简单的方法,就是把文件中的 php 都替换成 asp。要修改的配置包括:
```javascript
{
     imageUrl:URL+"asp/imageUp.asp"
    ,imagePath:URL + "asp/"
    ,scrawlUrl:URL+"asp/scrawlUp.asp"
    ,scrawlPath:URL+"asp/"
    ,fileUrl:URL+"asp/fileUp.asp"
    ,filePath:URL + "asp/"
    ,catcherUrl:URL +"asp/getRemoteImage.asp"
    ,catcherPath:URL + "asp/"
    ,imageManagerUrl:URL + "asp/imageManager.asp"
    ,imageManagerPath:URL + "asp/"
    ,snapscreenServerUrl: URL +"asp/imageUp.asp"
    ,snapscreenPath: URL + "asp/"
    ,wordImageUrl:URL + "asp/imageUp.asp"
    ,wordImagePath:URL + "asp/"
    ,getMovieUrl:URL+"asp/getMovie.asp"
}
```
UEditor v1.4.0 后进行了后端的统一配置,后端相关的配置文件是 `config.json`,在具体的后台目录下。需要注意以下两个类型的配置:
```javascript
{
    "{tpl}UrlPrefix": "/ueditor/asp/",
    "{tpl}PathFormat": "upload/{tpl}/{yyyy}{mm}{dd}/{time}{rand:6}"
}
```
`{tpl}PathFormat` 是资源(图片、涂鸦、文件等)保存的位置以及文件名格式,这个路径在 ASP 中是相对运行目录的。
`{tpl}UrlPrefix` 是资源定位的基本路径,在 ASP 后台中一般设置成 ASP 的目录。
比如,IIS 中运行的 UEditor ASP 的目录为 C:\iis_pub\wwwroot\mysite\ueditor\asp,而网站的访问地址为 http://localhost/mysite/,那么你可以这样修改这两类配置项:
```javascript
{
    "{tpl}UrlPrefix": "/mysite/ueditor/asp/",
    "{tpl}PathFormat": "upload/{tpl}/{yyyy}{mm}{dd}/{time}{rand:6}"
}
```
### 在 IIS 6.X 中部署
IIS 的安装在这里不介绍,请自行查阅相关资料。
1. 启用 ASP 拓展
    * 打开 IIS 管理器
    * 展开本地计算机
    * 选中 Web 服务拓展
    * 允许 Active Server Pages 拓展
2. 配置网站脚本执行权限(如果使用虚拟路径,请跳过本步骤)
    * 在网站上右击,点属性
    * 切换到主目录选项卡,勾选*读取*、*写入*两个权限,并且*执行权限*选择*纯脚本*
    * 点确定
3. 使用虚拟路径
    * 在网站上右击,点*新建* - *虚拟路径*
    * 按照向导填写名称和路径
    * 勾选*读取*、*执行脚本*和*写入*三个权限
    * 完成虚拟目录的创建
4. 配置脚本执行身份
    * 在网站或虚拟路径上右击,点属性
    * 选择*目录安全性*选项卡
    * 在*身份验证和访问控制*中点击*编辑*
    * 勾选*启用匿名访问*,点击用户名后面的*浏览*
    * 输入*administrator*点确定
    * 输入*administrator*账号的密码
    * 点击确定,再确认一次密码
5. 设置最大 HTTP 请求大小限制
    * 找到位于 C:\Windows\System32\Inetsrv 中的 metabase.XML,打开,查找ASPMaxRequestEntityAllowed,修改为需要的值(如10240000 即 10M)
    > ASP 文件中也有上传文件大小的限制,不过先验证的限制是 IIS 中设置的,所以如果 IIS 中设置最大 256K,那么就算 ASP 中设置了最大 10M,那么超过 256K 的文件也无法上传,而且 ASP 没法给出错误信息。
### 在 IIS 7.X 中部署
IIS7 默认不安装 ASP,需要手动添加进去。添加方法请读者自行查阅。
1. 配置脚本执行身份
    * 选中网站或者应用程序
    * 双击 IIS 中的*身份验证*
    * 双击匿名身份验证
    * 填写*administrator*的用户名和密码,确定
2. 设置最大 HTTP 请求大小限制
    * 打开 IIS 控制台
    * 双击 ASP,展开*限制属性*,修改*醉倒请求实体主体限制*为需要的值(如10240000 即 10M)
    > ASP 文件中也有上传文件大小的限制,不过先验证的限制是 IIS 中设置的,所以如果 IIS 中设置最大 256K,那么就算 ASP 中设置了最大 10M,那么超过 256K 的文件也无法上传,而且 ASP 没法给出错误信息。
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/Uploader.Class.asp
New file
@@ -0,0 +1,219 @@
<!--#include file="PathFormatter.class.asp"-->
<!--#include file="MultiformProcessor.class.asp"-->
<%
' ASP 文件上传类
' Author: techird
' Email: techird@qq.com
'配置
'MAX_SIZE 在这里设定了之后如果出现大上传失败,请执行以下步骤
'IIS 6
    '找到位于 C:\Windows\System32\Inetsrv 中的 metabase.XML 打开,找到ASPMaxRequestEntityAllowed 把他修改为需要的值(如10240000即10M)
'IIS 7
    '打开IIS控制台,选择 ASP,在限制属性里有一个“最大请求实体主题限制”,设置需要的值
CURRENT_ENCODING = "gb2312"
Class Uploader
    '上传配置
    Private cfgMaxSize
    Private cfgAllowType
    Private cfgPathFormat
    Private cfgFileField
    '上传返回信息
    Private stateString
    Private rsOriginalFileName
    Private rsFilePath
    Private rsFileName
    Private rsFileSize
    Private rsState
    Private rsFormValues
    Private Sub Class_Initialize
        Set stateString = Server.CreateObject("Scripting.Dictionary")
        stateString.Add "SIZE_LIMIT_EXCCEED", "File size exceeded!"
        stateString.Add "TYPE_NOW_ALLOW", "File type not allowed!"
    End Sub
    Public Property Let MaxSize(ByVal size)
        cfgMaxSize = size
    End Property
    Public Property Let AllowType(ByVal types)
        Set cfgAllowType = types
    End Property
    Public Property Let PathFormat(ByVal format)
        cfgPathFormat = format
    End Property
    Public Property Let FileField(ByVal field)
        cfgFileField = field
    End Property
    Public Property Get OriginalFileName
        OriginalFileName = rsOriginalFileName
    End Property
    Public Property Get FileName
        FileName = rsFileName
    End Property
    Public Property Get FilePath
        FilePath = rsFilePath
    End Property
    Public Property Get FileSize
        FileSize = rsFileSize
    End Property
    Public Property Get State
        State = rsState
    End Property
    Public Property Get FormValues
        Set FormValues = rsFormValues
    End Property
    Public Function UploadForm()
        ProcessForm()
        SaveFile()
    End Function
    Public Function ProcessForm()
        Set processor = new MultiformProcessor
        Set rsFormValues = processor.Process()
    End Function
    Public Function SaveFile()
        Dim stream, filename
        Set stream = rsFormValues.Item( cfgFileField )
        filename = rsFormValues.Item( "filename" )
        DoUpload stream, filename
    End Function
    Public Function UploadBase64( filename )
        Dim stream, content
        content = Request.Item ( cfgFileField )
        Set stream = Base64Decode( content )
        DoUpload stream, filename
    End Function
    Public Function UploadRemote( url )
        Dim stream, filename
        filename = Right( url, Len(url) - InStrRev(url, "/") )
        Set stream = CrawlImage( url )
        If Not IsNull(stream) Then
            DoUpload stream, filename
        Else
            rsState = "Failed"
        End If
        Set stream = Nothing
    End Function
    Private Function DoUpload( stream, filename )
        rsFileSize = stream.Size
        If rsFileSize > cfgMaxSize Then
            rsState = stateString.Item( "SIZE_LIMIT_EXCCEED" )
            Exit Function
        End If
        rsOriginalFileName = filename
        fileType = GetExt(filename)
        If CheckExt(fileType) = False Then
            rsState = stateString.Item( "TYPE_NOW_ALLOW" )
            Exit Function
        End If
        Set formatter = new PathFormatter
        rsFilePath = formatter.format( cfgPathFormat, filename )
        savePath = Server.MapPath(rsFilePath)
        CheckOrCreatePath(  GetDirectoryName(savePath) )
        stream.SaveToFile savePath
        stream.Close
        rsState = "SUCCESS"
    End Function
    Private Function GetDirectoryName(path)
        GetDirectoryName = Left( path, InStrRev(path, "\") )
    End Function
    Private Function Base64Decode( content )
        dim xml, stream, node
        Set xml = Server.CreateObject("MSXML2.DOMDocument")
        Set stream = Server.CreateObject("ADODB.Stream")
        Set node = xml.CreateElement("tmpNode")
        node.dataType = "bin.base64"
        node.Text = content
        stream.Charset = CURRENT_ENCODING
        stream.Type = 1
        stream.Open()
        stream.Write( node.nodeTypedValue )
        Set Base64Decode = stream
        Set node = Nothing
        Set stream = Nothing
        Set xml = Nothing
    End Function
    Private Function CrawlImage( url )
        Dim http, stream
        Set http = Server.CreateObject("Microsoft.XMLHTTP")
        http.Open "GET", url, false
        http.Send
        If http.Status = 200 Then
            Set stream = Server.CreateObject("ADODB.Stream")
            stream.Type = 1
            stream.Open()
            stream.Write http.ResponseBody
            Set CrawlImage = stream
        Else
            Set CrawlImage = null
        End If
        Set http = Nothing
    End Function
    Private Function CheckExt( fileType )
        If IsEmpty (cfgAllowType) Then
            CheckExt = true
             Exit Function
        End If
        For Each ext In cfgAllowType
            If UCase(fileType) = UCase(cfgAllowType.Item(ext)) Then
                CheckExt = true
                Exit Function
            End If
        Next
        CheckExt = false
    End Function
    Private Function GetExt( file )
        GetExt = Right( file, Len(file) - InStrRev(file, ".") + 1 )
    End Function
    Private Function CheckOrCreatePath( ByVal path )
        Set fs = Server.CreateObject("Scripting.FileSystemObject")
        Dim parts
        parts = Split( path, "\" )
        path = ""
        For Each part in parts
            path = path + part + "\"
            If fs.FolderExists( path ) = False Then
                fs.CreateFolder( path )
            End If
        Next
    End Function
End Class
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_config.asp
New file
@@ -0,0 +1,9 @@
<!--#include file="ASPJson.class.asp"-->
<!--#include file="config_loader.asp"-->
<%
    Set json = new ASPJson
    Set json.data = config
    json.PrintJson()
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_crawler.asp
New file
@@ -0,0 +1,32 @@
<!--#include file="ASPJson.class.asp"-->
<!--#include file="config_loader.asp"-->
<!--#include file="Uploader.class.asp"-->
<%
    Set up = new Uploader
    up.MaxSize = config.Item("catcherMaxSize")
    up.AllowType = config.Item("catcherAllowFiles")
    up.PathFormat = config.Item("catcherPathFormat")
    urls = Split(Request.Item("source[]"), ", ")
    Set list = new ASPJson.Collection
    For i = 0 To UBound(urls)
        up.UploadRemote( urls(i) )
        Dim instance
        Set instance = new ASPJson.Collection
        instance.Add "state", up.State
        instance.Add "url", up.FilePath
        instance.Add "source", urls(i)
        list.Add i, instance
    Next
    Set json = new ASPJson
    With json.data
        .Add "state", "SUCCESS"
        .Add "list", list
    End With
    json.PrintJson()
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_list.asp
New file
@@ -0,0 +1,81 @@
<!--#include file="ASPJson.class.asp"-->
<!--#include file="config_loader.asp"-->
<%
    listTemplateName = Session.Value("ueditor_asp_listTemplateName")
    start = CInt(Request.Item("start"))
    size = CInt(Request.Item("size"))
    total = 0
    If size < 0 Then
        size = CInt(config.Item( listTemplateName + "ManagerListSize" ))
    End If
    path = config.Item( listTemplateName + "ManagerListPath" )
    Set extensions = config.Item( listTemplateName + "ManagerAllowFiles")
    Set list = new ASPJson.Collection
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    If fso.FolderExists(Server.MapPath(path)) = False Then
        state = "找不到目录:" + path
    Else
        Set all = ListAllFilesInFolder( fso, path )
        total = all.Count
        index = 0
        For Each file in all
            If index >= start And index < start + size Then
                Dim fileObject
                Set fileObject = new ASPJson.Collection
                fileObject.Add "url", file
                list.Add index - start, fileObject
            End If
            index = index + 1
        Next
        state = "SUCCESS"
    End If
    Set json = new ASPJson
    With json.data
        .Add "state", state
        .Add "list", list
        .Add "start", start
        .Add "size", size
        .Add "total", total
    End With
    json.PrintJson()
    Function ListAllFilesInFolder( fso, path )
        Dim list
        Set list = Server.CreateObject("Scripting.Dictionary")
        Set folder = fso.GetFolder(Server.MapPath(path))
        For Each file In folder.Files
            If CheckExt(file.Name) Then
                list.Add path & "/" & file.Name, true
            End If
        Next
        For Each subFolder In folder.SubFolders
            Set subList = ListAllFilesInFolder( fso, path & "/" & subFolder.Name )
            For Each subListFile In subList
                list.Add subListFile, true
            Next
        Next
        Set ListAllFilesInFolder = list
    End Function
    Function CheckExt( filename )
        For Each ext In extensions
            If UCase(GetExt(filename)) = UCase(extensions.Item(ext)) Then
                CheckExt = true
                Exit Function
            End If
        Next
        CheckExt = false
    End Function
    Function GetExt( file )
        GetExt = Right( file, Len(file) - InStrRev(file, ".") + 1 )
    End Function
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/action_upload.asp
New file
@@ -0,0 +1,29 @@
<!--#include file="ASPJson.class.asp"-->
<!--#include file="config_loader.asp"-->
<!--#include file="Uploader.class.asp"-->
<%
    uploadTemplateName = Session.Value("ueditor_asp_uploadTemplateName")
    Set up = new Uploader
    up.MaxSize = config.Item( uploadTemplateName & "MaxSize" )
    up.FileField = config.Item( uploadTemplateName & "FieldName" )
    up.PathFormat = config.Item( uploadTemplateName & "PathFormat" )
    If Not IsEmpty( Session.Value("base64Upload") ) Then
        up.UploadBase64( Session.Value("base64Upload") )
    Else
        up.AllowType = config.Item( uploadTemplateName & "AllowFiles" )
        up.UploadForm()
    End If
    Set json = new ASPJson
    With json.data
        .Add "url", up.FilePath
        .Add "original", up.OriginalFileName
        .Add "state", up.State
        .Add "title", up.OriginalFileName
    End With
    json.PrintJson()
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/config.json
New file
@@ -0,0 +1,94 @@
/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
    /* 上传图片配置项 */
    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
    "imageFieldName": "upfile", /* 提交的图片表单名称 */
    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageUrlPrefix": "/ueditor/asp/", /* 图片访问路径前缀 */
    "imagePathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                /* {time} 会替换成时间戳 */
                                /* {yyyy} 会替换成四位年份 */
                                /* {yy} 会替换成两位年份 */
                                /* {mm} 会替换成两位月份 */
                                /* {dd} 会替换成两位日期 */
                                /* {hh} 会替换成两位小时 */
                                /* {ii} 会替换成两位分钟 */
                                /* {ss} 会替换成两位秒 */
                                /* 非法字符 \ : * ? " < > | */
                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
    /* 涂鸦图片上传配置项 */
    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
    "scrawlPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
    "scrawlUrlPrefix": "/ueditor/asp/", /* 图片访问路径前缀 */
    "scrawlInsertAlign": "none",
    /* 截图工具上传 */
    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
    "snapscreenPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "snapscreenUrlPrefix": "/ueditor/asp/", /* 图片访问路径前缀 */
    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
    /* 抓取远程图片配置 */
    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
    "catcherPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "catcherUrlPrefix": "/ueditor/asp/", /* 图片访问路径前缀 */
    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
    /* 上传视频配置 */
    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
    "videoFieldName": "upfile", /* 提交的视频表单名称 */
    "videoPathFormat": "upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "videoUrlPrefix": "/ueditor/asp/", /* 视频访问路径前缀 */
    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
    /* 上传文件配置 */
    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
    "fileFieldName": "upfile", /* 提交的文件表单名称 */
    "filePathFormat": "upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "fileUrlPrefix": "/ueditor/asp/", /* 文件访问路径前缀 */
    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ], /* 上传文件格式显示 */
    /* 列出指定目录下的图片 */
    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
    "imageManagerListPath": "upload/image", /* 指定要列出图片的目录 */
    "imageManagerListSize": 20, /* 每次列出文件数量 */
    "imageManagerUrlPrefix": "/ueditor/asp/", /* 图片访问路径前缀 */
    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
    /* 列出指定目录下的文件 */
    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
    "fileManagerListPath": "upload/file", /* 指定要列出文件的目录 */
    "fileManagerUrlPrefix": "/ueditor/asp/", /* 文件访问路径前缀 */
    "fileManagerListSize": 20, /* 每次列出文件数量 */
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ] /* 列出的文件类型 */
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/config_loader.asp
New file
@@ -0,0 +1,21 @@
<%
    Set json = new ASPJson
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    Set stream = Server.CreateObject("ADODB.Stream")
    stream.Open()
    stream.Charset = "UTF-8"
    stream.LoadFromFile Server.MapPath( "config.json" )
    content = stream.ReadText()
    Set commentPattern = new RegExp
    commentPattern.Multiline = true
    commentPattern.Pattern = "/\*[\s\S]+?\*/"
    commentPattern.Global = true
    content = commentPattern.Replace(content, "")
    json.loadJSON( content )
    Set config = json.data
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/asp/controller.asp
New file
@@ -0,0 +1,44 @@
<%@ LANGUAGE="VBSCRIPT" CODEPAGE="65001" %>
<%
    action = Request.Item("action")
    Session.Contents.Remove("ueditor_asp_uploadTemplateName")
    Session.Contents.Remove("ueditor_asp_base64Upload")
    Session.Contents.Remove("ueditor_asp_listTemplateName")
    Select Case action
        Case "config"
            Server.Execute("action_config.asp")
        Case "uploadimage"
            Session.Value("ueditor_asp_uploadTemplateName") = "image"
            Server.Execute("action_upload.asp")
        Case "uploadscrawl"
            Session.Value("ueditor_asp_uploadTemplateName") = "scrawl"
            Session.Value("base64Upload") = "scrawl.png"
            Server.Execute("action_upload.asp")
        Case "uploadvideo"
            Session.Value("ueditor_asp_uploadTemplateName") = "video"
            Server.Execute("action_upload.asp")
        Case "uploadfile"
            Session.Value("ueditor_asp_uploadTemplateName") = "file"
            Server.Execute("action_upload.asp")
        Case "listimage"
            Session.Value("ueditor_asp_listTemplateName") = "image"
            Server.Execute("action_list.asp")
        Case "listfile"
            Session.Value("ueditor_asp_listTemplateName") = "file"
            Server.Execute("action_list.asp")
        Case "catchimage"
            Server.Execute("action_crawler.asp")
    End Select
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/index.html
New file
@@ -0,0 +1,175 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>完整demo</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <script type="text/javascript" charset="utf-8" src="ueditor.config.js"></script>
    <script type="text/javascript" charset="utf-8" src="ueditor.all.min.js"> </script>
    <!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败-->
    <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文-->
    <script type="text/javascript" charset="utf-8" src="lang/zh-cn/zh-cn.js"></script>
    <style type="text/css">
        div{
            width:100%;
        }
    </style>
</head>
<body>
<div>
    <h1>完整demo</h1>
    <script id="editor" type="text/plain" style="width:1024px;height:500px;"></script>
</div>
<div id="btns">
    <div>
        <button onclick="getAllHtml()">获得整个html的内容</button>
        <button onclick="getContent()">获得内容</button>
        <button onclick="setContent()">写入内容</button>
        <button onclick="setContent(true)">追加内容</button>
        <button onclick="getContentTxt()">获得纯文本</button>
        <button onclick="getPlainTxt()">获得带格式的纯文本</button>
        <button onclick="hasContent()">判断是否有内容</button>
        <button onclick="setFocus()">使编辑器获得焦点</button>
        <button onmousedown="isFocus(event)">编辑器是否获得焦点</button>
        <button onmousedown="setblur(event)" >编辑器失去焦点</button>
    </div>
    <div>
        <button onclick="getText()">获得当前选中的文本</button>
        <button onclick="insertHtml()">插入给定的内容</button>
        <button id="enable" onclick="setEnabled()">可以编辑</button>
        <button onclick="setDisabled()">不可编辑</button>
        <button onclick=" UE.getEditor('editor').setHide()">隐藏编辑器</button>
        <button onclick=" UE.getEditor('editor').setShow()">显示编辑器</button>
        <button onclick=" UE.getEditor('editor').setHeight(300)">设置高度为300默认关闭了自动长高</button>
    </div>
    <div>
        <button onclick="getLocalData()" >获取草稿箱内容</button>
        <button onclick="clearLocalData()" >清空草稿箱</button>
    </div>
</div>
<div>
    <button onclick="createEditor()">
    创建编辑器</button>
    <button onclick="deleteEditor()">
    删除编辑器</button>
</div>
<script type="text/javascript">
    //实例化编辑器
    //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
    var ue = UE.getEditor('editor');
    function isFocus(e){
        alert(UE.getEditor('editor').isFocus());
        UE.dom.domUtils.preventDefault(e)
    }
    function setblur(e){
        UE.getEditor('editor').blur();
        UE.dom.domUtils.preventDefault(e)
    }
    function insertHtml() {
        var value = prompt('插入html代码', '');
        UE.getEditor('editor').execCommand('insertHtml', value)
    }
    function createEditor() {
        enableBtn();
        UE.getEditor('editor');
    }
    function getAllHtml() {
        alert(UE.getEditor('editor').getAllHtml())
    }
    function getContent() {
        var arr = [];
        arr.push("使用editor.getContent()方法可以获得编辑器的内容");
        arr.push("内容为:");
        arr.push(UE.getEditor('editor').getContent());
        alert(arr.join("\n"));
    }
    function getPlainTxt() {
        var arr = [];
        arr.push("使用editor.getPlainTxt()方法可以获得编辑器的带格式的纯文本内容");
        arr.push("内容为:");
        arr.push(UE.getEditor('editor').getPlainTxt());
        alert(arr.join('\n'))
    }
    function setContent(isAppendTo) {
        var arr = [];
        arr.push("使用editor.setContent('欢迎使用ueditor')方法可以设置编辑器的内容");
        UE.getEditor('editor').setContent('欢迎使用ueditor', isAppendTo);
        alert(arr.join("\n"));
    }
    function setDisabled() {
        UE.getEditor('editor').setDisabled('fullscreen');
        disableBtn("enable");
    }
    function setEnabled() {
        UE.getEditor('editor').setEnabled();
        enableBtn();
    }
    function getText() {
        //当你点击按钮时编辑区域已经失去了焦点,如果直接用getText将不会得到内容,所以要在选回来,然后取得内容
        var range = UE.getEditor('editor').selection.getRange();
        range.select();
        var txt = UE.getEditor('editor').selection.getText();
        alert(txt)
    }
    function getContentTxt() {
        var arr = [];
        arr.push("使用editor.getContentTxt()方法可以获得编辑器的纯文本内容");
        arr.push("编辑器的纯文本内容为:");
        arr.push(UE.getEditor('editor').getContentTxt());
        alert(arr.join("\n"));
    }
    function hasContent() {
        var arr = [];
        arr.push("使用editor.hasContents()方法判断编辑器里是否有内容");
        arr.push("判断结果为:");
        arr.push(UE.getEditor('editor').hasContents());
        alert(arr.join("\n"));
    }
    function setFocus() {
        UE.getEditor('editor').focus();
    }
    function deleteEditor() {
        disableBtn();
        UE.getEditor('editor').destroy();
    }
    function disableBtn(str) {
        var div = document.getElementById('btns');
        var btns = UE.dom.domUtils.getElementsByTagName(div, "button");
        for (var i = 0, btn; btn = btns[i++];) {
            if (btn.id == str) {
                UE.dom.domUtils.removeAttributes(btn, ["disabled"]);
            } else {
                btn.setAttribute("disabled", "true");
            }
        }
    }
    function enableBtn() {
        var div = document.getElementById('btns');
        var btns = UE.dom.domUtils.getElementsByTagName(div, "button");
        for (var i = 0, btn; btn = btns[i++];) {
            UE.dom.domUtils.removeAttributes(btn, ["disabled"]);
        }
    }
    function getLocalData () {
        alert(UE.getEditor('editor').execCommand( "getlocaldata" ));
    }
    function clearLocalData () {
        UE.getEditor('editor').execCommand( "clearlocaldata" );
        alert("已清空草稿箱")
    }
</script>
</body>
</html>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/config.json
New file
@@ -0,0 +1,94 @@
/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
    /* 上传图片配置项 */
    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
    "imageFieldName": "upfile", /* 提交的图片表单名称 */
    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageUrlPrefix": "", /* 图片访问路径前缀 */
    "imagePathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                /* {time} 会替换成时间戳 */
                                /* {yyyy} 会替换成四位年份 */
                                /* {yy} 会替换成两位年份 */
                                /* {mm} 会替换成两位月份 */
                                /* {dd} 会替换成两位日期 */
                                /* {hh} 会替换成两位小时 */
                                /* {ii} 会替换成两位分钟 */
                                /* {ss} 会替换成两位秒 */
                                /* 非法字符 \ : * ? " < > | */
                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
    /* 涂鸦图片上传配置项 */
    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
    "scrawlPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
    "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
    "scrawlInsertAlign": "none",
    /* 截图工具上传 */
    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
    "snapscreenPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
    /* 抓取远程图片配置 */
    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
    "catcherPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "catcherUrlPrefix": "", /* 图片访问路径前缀 */
    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
    /* 上传视频配置 */
    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
    "videoFieldName": "upfile", /* 提交的视频表单名称 */
    "videoPathFormat": "/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "videoUrlPrefix": "", /* 视频访问路径前缀 */
    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
    /* 上传文件配置 */
    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
    "fileFieldName": "upfile", /* 提交的文件表单名称 */
    "filePathFormat": "/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "fileUrlPrefix": "", /* 文件访问路径前缀 */
    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ], /* 上传文件格式显示 */
    /* 列出指定目录下的图片 */
    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
    "imageManagerListPath": "/ueditor/jsp/upload/image/", /* 指定要列出图片的目录 */
    "imageManagerListSize": 20, /* 每次列出文件数量 */
    "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
    /* 列出指定目录下的文件 */
    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
    "fileManagerListPath": "/ueditor/jsp/upload/file/", /* 指定要列出文件的目录 */
    "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
    "fileManagerListSize": 20, /* 每次列出文件数量 */
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ] /* 列出的文件类型 */
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/controller.jsp
New file
@@ -0,0 +1,14 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
    import="com.baidu.ueditor.ActionEnter"
    pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%
    request.setCharacterEncoding( "utf-8" );
    response.setHeader("Content-Type" , "text/html");
    String rootPath = application.getRealPath( "/" );
    out.write( new ActionEnter( request, rootPath ).exec() );
%>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/ActionEnter.java
New file
@@ -0,0 +1,127 @@
package com.baidu.ueditor;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.baidu.ueditor.define.ActionMap;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.hunter.FileManager;
import com.baidu.ueditor.hunter.ImageHunter;
import com.baidu.ueditor.upload.Uploader;
public class ActionEnter {
    private HttpServletRequest request = null;
    private String rootPath = null;
    private String contextPath = null;
    private String actionType = null;
    private ConfigManager configManager = null;
    public ActionEnter ( HttpServletRequest request, String rootPath ) {
        this.request = request;
        this.rootPath = rootPath;
        this.actionType = request.getParameter( "action" );
        this.contextPath = request.getContextPath();
        this.configManager = ConfigManager.getInstance( this.rootPath, this.contextPath, request.getRequestURI() );
    }
    public String exec () {
        String callbackName = this.request.getParameter("callback");
        if ( callbackName != null ) {
            if ( !validCallbackName( callbackName ) ) {
                return new BaseState( false, AppInfo.ILLEGAL ).toJSONString();
            }
            return callbackName+"("+this.invoke()+");";
        } else {
            return this.invoke();
        }
    }
    public String invoke() {
        if ( actionType == null || !ActionMap.mapping.containsKey( actionType ) ) {
            return new BaseState( false, AppInfo.INVALID_ACTION ).toJSONString();
        }
        if ( this.configManager == null || !this.configManager.valid() ) {
            return new BaseState( false, AppInfo.CONFIG_ERROR ).toJSONString();
        }
        State state = null;
        int actionCode = ActionMap.getType( this.actionType );
        Map<String, Object> conf = null;
        switch ( actionCode ) {
            case ActionMap.CONFIG:
                return this.configManager.getAllConfig().toString();
            case ActionMap.UPLOAD_IMAGE:
            case ActionMap.UPLOAD_SCRAWL:
            case ActionMap.UPLOAD_VIDEO:
            case ActionMap.UPLOAD_FILE:
                conf = this.configManager.getConfig( actionCode );
                state = new Uploader( request, conf ).doExec();
                break;
            case ActionMap.CATCH_IMAGE:
                conf = configManager.getConfig( actionCode );
                String[] list = this.request.getParameterValues( (String)conf.get( "fieldName" ) );
                state = new ImageHunter( conf ).capture( list );
                break;
            case ActionMap.LIST_IMAGE:
            case ActionMap.LIST_FILE:
                conf = configManager.getConfig( actionCode );
                int start = this.getStartIndex();
                state = new FileManager( conf ).listFile( start );
                break;
        }
        return state.toJSONString();
    }
    public int getStartIndex () {
        String start = this.request.getParameter( "start" );
        try {
            return Integer.parseInt( start );
        } catch ( Exception e ) {
            return 0;
        }
    }
    /**
     * callback参数验证
     */
    public boolean validCallbackName ( String name ) {
        if ( name.matches( "^[a-zA-Z_]+[\\w0-9_]*$" ) ) {
            return true;
        }
        return false;
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/ConfigManager.java
New file
@@ -0,0 +1,222 @@
package com.baidu.ueditor;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import com.baidu.ueditor.define.ActionMap;
/**
 * 配置管理器
 * @author hancong03@baidu.com
 *
 */
public final class ConfigManager {
    private final String rootPath;
    private final String originalPath;
    private final String contextPath;
    private static final String configFileName = "config.json";
    private String parentPath = null;
    private JSONObject jsonConfig = null;
    // 涂鸦上传filename定义
    private final static String SCRAWL_FILE_NAME = "scrawl";
    // 远程图片抓取filename定义
    private final static String REMOTE_FILE_NAME = "remote";
    /*
     * 通过一个给定的路径构建一个配置管理器, 该管理器要求地址路径所在目录下必须存在config.properties文件
     */
    private ConfigManager ( String rootPath, String contextPath, String uri ) throws FileNotFoundException, IOException {
        rootPath = rootPath.replace( "\\", "/" );
        this.rootPath = rootPath;
        this.contextPath = contextPath;
        if ( contextPath.length() > 0 ) {
            this.originalPath = this.rootPath + uri.substring( contextPath.length() );
        } else {
            this.originalPath = this.rootPath + uri;
        }
        this.initEnv();
    }
    /**
     * 配置管理器构造工厂
     * @param rootPath 服务器根路径
     * @param contextPath 服务器所在项目路径
     * @param uri 当前访问的uri
     * @return 配置管理器实例或者null
     */
    public static ConfigManager getInstance ( String rootPath, String contextPath, String uri ) {
        try {
            return new ConfigManager(rootPath, contextPath, uri);
        } catch ( Exception e ) {
            return null;
        }
    }
    // 验证配置文件加载是否正确
    public boolean valid () {
        return this.jsonConfig != null;
    }
    public JSONObject getAllConfig () {
        return this.jsonConfig;
    }
    public Map<String, Object> getConfig ( int type ) {
        Map<String, Object> conf = new HashMap<String, Object>();
        String savePath = null;
        switch ( type ) {
            case ActionMap.UPLOAD_FILE:
                conf.put( "isBase64", "false" );
                conf.put( "maxSize", this.jsonConfig.getLong( "fileMaxSize" ) );
                conf.put( "allowFiles", this.getArray( "fileAllowFiles" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "fileFieldName" ) );
                savePath = this.jsonConfig.getString( "filePathFormat" );
                break;
            case ActionMap.UPLOAD_IMAGE:
                conf.put( "isBase64", "false" );
                conf.put( "maxSize", this.jsonConfig.getLong( "imageMaxSize" ) );
                conf.put( "allowFiles", this.getArray( "imageAllowFiles" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "imageFieldName" ) );
                savePath = this.jsonConfig.getString( "imagePathFormat" );
                break;
            case ActionMap.UPLOAD_VIDEO:
                conf.put( "maxSize", this.jsonConfig.getLong( "videoMaxSize" ) );
                conf.put( "allowFiles", this.getArray( "videoAllowFiles" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "videoFieldName" ) );
                savePath = this.jsonConfig.getString( "videoPathFormat" );
                break;
            case ActionMap.UPLOAD_SCRAWL:
                conf.put( "filename", ConfigManager.SCRAWL_FILE_NAME );
                conf.put( "maxSize", this.jsonConfig.getLong( "scrawlMaxSize" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "scrawlFieldName" ) );
                conf.put( "isBase64", "true" );
                savePath = this.jsonConfig.getString( "scrawlPathFormat" );
                break;
            case ActionMap.CATCH_IMAGE:
                conf.put( "filename", ConfigManager.REMOTE_FILE_NAME );
                conf.put( "filter", this.getArray( "catcherLocalDomain" ) );
                conf.put( "maxSize", this.jsonConfig.getLong( "catcherMaxSize" ) );
                conf.put( "allowFiles", this.getArray( "catcherAllowFiles" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "catcherFieldName" ) + "[]" );
                savePath = this.jsonConfig.getString( "catcherPathFormat" );
                break;
            case ActionMap.LIST_IMAGE:
                conf.put( "allowFiles", this.getArray( "imageManagerAllowFiles" ) );
                conf.put( "dir", this.jsonConfig.getString( "imageManagerListPath" ) );
                conf.put( "count", this.jsonConfig.getInt( "imageManagerListSize" ) );
                break;
            case ActionMap.LIST_FILE:
                conf.put( "allowFiles", this.getArray( "fileManagerAllowFiles" ) );
                conf.put( "dir", this.jsonConfig.getString( "fileManagerListPath" ) );
                conf.put( "count", this.jsonConfig.getInt( "fileManagerListSize" ) );
                break;
        }
        conf.put( "savePath", savePath );
        conf.put( "rootPath", this.rootPath );
        return conf;
    }
    private void initEnv () throws FileNotFoundException, IOException {
        File file = new File( this.originalPath );
        if ( !file.isAbsolute() ) {
            file = new File( file.getAbsolutePath() );
        }
        this.parentPath = file.getParent();
        String configContent = this.readFile( this.getConfigPath() );
        try{
            JSONObject jsonConfig = new JSONObject( configContent );
            this.jsonConfig = jsonConfig;
        } catch ( Exception e ) {
            this.jsonConfig = null;
        }
    }
    private String getConfigPath () {
        return this.parentPath + File.separator + ConfigManager.configFileName;
    }
    private String[] getArray ( String key ) {
        JSONArray jsonArray = this.jsonConfig.getJSONArray( key );
        String[] result = new String[ jsonArray.length() ];
        for ( int i = 0, len = jsonArray.length(); i < len; i++ ) {
            result[i] = jsonArray.getString( i );
        }
        return result;
    }
    private String readFile ( String path ) throws IOException {
        StringBuilder builder = new StringBuilder();
        try {
            InputStreamReader reader = new InputStreamReader( new FileInputStream( path ), "UTF-8" );
            BufferedReader bfReader = new BufferedReader( reader );
            String tmpContent = null;
            while ( ( tmpContent = bfReader.readLine() ) != null ) {
                builder.append( tmpContent );
            }
            bfReader.close();
        } catch ( UnsupportedEncodingException e ) {
            // 忽略
        }
        return this.filter( builder.toString() );
    }
    // 过滤输入字符串, 剔除多行注释以及替换掉反斜杠
    private String filter ( String input ) {
        return input.replaceAll( "/\\*[\\s\\S]*?\\*/", "" );
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/Encoder.java
New file
@@ -0,0 +1,24 @@
package com.baidu.ueditor;
public class Encoder {
    public static String toUnicode ( String input ) {
        StringBuilder builder = new StringBuilder();
        char[] chars = input.toCharArray();
        for ( char ch : chars ) {
            if ( ch < 256 ) {
                builder.append( ch );
            } else {
                builder.append( "\\u" +  Integer.toHexString( ch& 0xffff ) );
            }
        }
        return builder.toString();
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/PathFormat.java
New file
@@ -0,0 +1,157 @@
package com.baidu.ueditor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PathFormat {
    private static final String TIME = "time";
    private static final String FULL_YEAR = "yyyy";
    private static final String YEAR = "yy";
    private static final String MONTH = "mm";
    private static final String DAY = "dd";
    private static final String HOUR = "hh";
    private static final String MINUTE = "ii";
    private static final String SECOND = "ss";
    private static final String RAND = "rand";
    private static Date currentDate = null;
    public static String parse ( String input ) {
        Pattern pattern = Pattern.compile( "\\{([^\\}]+)\\}", Pattern.CASE_INSENSITIVE  );
        Matcher matcher = pattern.matcher(input);
        PathFormat.currentDate = new Date();
        StringBuffer sb = new StringBuffer();
        while ( matcher.find() ) {
            matcher.appendReplacement(sb, PathFormat.getString( matcher.group( 1 ) ) );
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    /**
     * 格式化路径, 把windows路径替换成标准路径
     * @param input 待格式化的路径
     * @return 格式化后的路径
     */
    public static String format ( String input ) {
        return input.replace( "\\", "/" );
    }
    public static String parse ( String input, String filename ) {
        Pattern pattern = Pattern.compile( "\\{([^\\}]+)\\}", Pattern.CASE_INSENSITIVE  );
        Matcher matcher = pattern.matcher(input);
        String matchStr = null;
        PathFormat.currentDate = new Date();
        StringBuffer sb = new StringBuffer();
        while ( matcher.find() ) {
            matchStr = matcher.group( 1 );
            if ( matchStr.indexOf( "filename" ) != -1 ) {
                filename = filename.replace( "$", "\\$" ).replaceAll( "[\\/:*?\"<>|]", "" );
                matcher.appendReplacement(sb, filename );
            } else {
                matcher.appendReplacement(sb, PathFormat.getString( matchStr ) );
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    private static String getString ( String pattern ) {
        pattern = pattern.toLowerCase();
        // time 处理
        if ( pattern.indexOf( PathFormat.TIME ) != -1 ) {
            return PathFormat.getTimestamp();
        } else if ( pattern.indexOf( PathFormat.FULL_YEAR ) != -1 ) {
            return PathFormat.getFullYear();
        } else if ( pattern.indexOf( PathFormat.YEAR ) != -1 ) {
            return PathFormat.getYear();
        } else if ( pattern.indexOf( PathFormat.MONTH ) != -1 ) {
            return PathFormat.getMonth();
        } else if ( pattern.indexOf( PathFormat.DAY ) != -1 ) {
            return PathFormat.getDay();
        } else if ( pattern.indexOf( PathFormat.HOUR ) != -1 ) {
            return PathFormat.getHour();
        } else if ( pattern.indexOf( PathFormat.MINUTE ) != -1 ) {
            return PathFormat.getMinute();
        } else if ( pattern.indexOf( PathFormat.SECOND ) != -1 ) {
            return PathFormat.getSecond();
        } else if ( pattern.indexOf( PathFormat.RAND ) != -1 ) {
            return PathFormat.getRandom( pattern );
        }
        return pattern;
    }
    private static String getTimestamp () {
        return System.currentTimeMillis() + "";
    }
    private static String getFullYear () {
        return new SimpleDateFormat( "yyyy" ).format( PathFormat.currentDate );
    }
    private static String getYear () {
        return new SimpleDateFormat( "yy" ).format( PathFormat.currentDate );
    }
    private static String getMonth () {
        return new SimpleDateFormat( "MM" ).format( PathFormat.currentDate );
    }
    private static String getDay () {
        return new SimpleDateFormat( "dd" ).format( PathFormat.currentDate );
    }
    private static String getHour () {
        return new SimpleDateFormat( "HH" ).format( PathFormat.currentDate );
    }
    private static String getMinute () {
        return new SimpleDateFormat( "mm" ).format( PathFormat.currentDate );
    }
    private static String getSecond () {
        return new SimpleDateFormat( "ss" ).format( PathFormat.currentDate );
    }
    private static String getRandom ( String pattern ) {
        int length = 0;
        pattern = pattern.split( ":" )[ 1 ].trim();
        length = Integer.parseInt( pattern );
        return ( Math.random() + "" ).replace( ".", "" ).substring( 0, length );
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/ActionMap.java
New file
@@ -0,0 +1,42 @@
package com.baidu.ueditor.define;
import java.util.Map;
import java.util.HashMap;
/**
 * 定义请求action类型
 * @author hancong03@baidu.com
 *
 */
@SuppressWarnings("serial")
public final class ActionMap {
    public static final Map<String, Integer> mapping;
    // 获取配置请求
    public static final int CONFIG = 0;
    public static final int UPLOAD_IMAGE = 1;
    public static final int UPLOAD_SCRAWL = 2;
    public static final int UPLOAD_VIDEO = 3;
    public static final int UPLOAD_FILE = 4;
    public static final int CATCH_IMAGE = 5;
    public static final int LIST_FILE = 6;
    public static final int LIST_IMAGE = 7;
    static {
        mapping = new HashMap<String, Integer>(){{
            put( "config", ActionMap.CONFIG );
            put( "uploadimage", ActionMap.UPLOAD_IMAGE );
            put( "uploadscrawl", ActionMap.UPLOAD_SCRAWL );
            put( "uploadvideo", ActionMap.UPLOAD_VIDEO );
            put( "uploadfile", ActionMap.UPLOAD_FILE );
            put( "catchimage", ActionMap.CATCH_IMAGE );
            put( "listfile", ActionMap.LIST_FILE );
            put( "listimage", ActionMap.LIST_IMAGE );
        }};
    }
    public static int getType ( String key ) {
        return ActionMap.mapping.get( key );
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/ActionState.java
New file
@@ -0,0 +1,5 @@
package com.baidu.ueditor.define;
public enum ActionState {
    UNKNOW_ERROR
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/AppInfo.java
New file
@@ -0,0 +1,77 @@
package com.baidu.ueditor.define;
import java.util.HashMap;
import java.util.Map;
public final class AppInfo {
    public static final int SUCCESS = 0;
    public static final int MAX_SIZE = 1;
    public static final int PERMISSION_DENIED = 2;
    public static final int FAILED_CREATE_FILE = 3;
    public static final int IO_ERROR = 4;
    public static final int NOT_MULTIPART_CONTENT = 5;
    public static final int PARSE_REQUEST_ERROR = 6;
    public static final int NOTFOUND_UPLOAD_DATA = 7;
    public static final int NOT_ALLOW_FILE_TYPE = 8;
    public static final int INVALID_ACTION = 101;
    public static final int CONFIG_ERROR = 102;
    public static final int PREVENT_HOST = 201;
    public static final int CONNECTION_ERROR = 202;
    public static final int REMOTE_FAIL = 203;
    public static final int NOT_DIRECTORY = 301;
    public static final int NOT_EXIST = 302;
    public static final int ILLEGAL = 401;
    public static Map<Integer, String> info = new HashMap<Integer, String>(){{
        put( AppInfo.SUCCESS, "SUCCESS" );
        // 无效的Action
        put( AppInfo.INVALID_ACTION, "\u65E0\u6548\u7684Action" );
        // 配置文件初始化失败
        put( AppInfo.CONFIG_ERROR, "\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u5931\u8D25" );
        // 抓取远程图片失败
        put( AppInfo.REMOTE_FAIL, "\u6293\u53D6\u8FDC\u7A0B\u56FE\u7247\u5931\u8D25" );
        // 被阻止的远程主机
        put( AppInfo.PREVENT_HOST, "\u88AB\u963B\u6B62\u7684\u8FDC\u7A0B\u4E3B\u673A" );
        // 远程连接出错
        put( AppInfo.CONNECTION_ERROR, "\u8FDC\u7A0B\u8FDE\u63A5\u51FA\u9519" );
        // "文件大小超出限制"
        put( AppInfo.MAX_SIZE, "\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236" );
        // 权限不足, 多指写权限
        put( AppInfo.PERMISSION_DENIED, "\u6743\u9650\u4E0D\u8DB3" );
        // 创建文件失败
        put( AppInfo.FAILED_CREATE_FILE, "\u521B\u5EFA\u6587\u4EF6\u5931\u8D25" );
        // IO错误
        put( AppInfo.IO_ERROR, "IO\u9519\u8BEF" );
        // 上传表单不是multipart/form-data类型
        put( AppInfo.NOT_MULTIPART_CONTENT, "\u4E0A\u4F20\u8868\u5355\u4E0D\u662Fmultipart/form-data\u7C7B\u578B" );
        // 解析上传表单错误
        put( AppInfo.PARSE_REQUEST_ERROR, "\u89E3\u6790\u4E0A\u4F20\u8868\u5355\u9519\u8BEF" );
        // 未找到上传数据
        put( AppInfo.NOTFOUND_UPLOAD_DATA, "\u672A\u627E\u5230\u4E0A\u4F20\u6570\u636E" );
        // 不允许的文件类型
        put( AppInfo.NOT_ALLOW_FILE_TYPE, "\u4E0D\u5141\u8BB8\u7684\u6587\u4EF6\u7C7B\u578B" );
        // 指定路径不是目录
        put( AppInfo.NOT_DIRECTORY, "\u6307\u5B9A\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55" );
        // 指定路径并不存在
        put( AppInfo.NOT_EXIST, "\u6307\u5B9A\u8DEF\u5F84\u5E76\u4E0D\u5B58\u5728" );
        // callback参数名不合法
        put( AppInfo.ILLEGAL, "Callback\u53C2\u6570\u540D\u4E0D\u5408\u6CD5" );
    }};
    public static String getStateInfo ( int key ) {
        return AppInfo.info.get( key );
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/BaseState.java
New file
@@ -0,0 +1,90 @@
package com.baidu.ueditor.define;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.baidu.ueditor.Encoder;
public class BaseState implements State {
    private boolean state = false;
    private String info = null;
    private Map<String, String> infoMap = new HashMap<String, String>();
    public BaseState () {
        this.state = true;
    }
    public BaseState ( boolean state ) {
        this.setState( state );
    }
    public BaseState ( boolean state, String info ) {
        this.setState( state );
        this.info = info;
    }
    public BaseState ( boolean state, int infoCode ) {
        this.setState( state );
        this.info = AppInfo.getStateInfo( infoCode );
    }
    public boolean isSuccess () {
        return this.state;
    }
    public void setState ( boolean state ) {
        this.state = state;
    }
    public void setInfo ( String info ) {
        this.info = info;
    }
    public void setInfo ( int infoCode ) {
        this.info = AppInfo.getStateInfo( infoCode );
    }
    @Override
    public String toJSONString() {
        return this.toString();
    }
    public String toString () {
        String key = null;
        String stateVal = this.isSuccess() ? AppInfo.getStateInfo( AppInfo.SUCCESS ) : this.info;
        StringBuilder builder = new StringBuilder();
        builder.append( "{\"state\": \"" + stateVal + "\"" );
        Iterator<String> iterator = this.infoMap.keySet().iterator();
        while ( iterator.hasNext() ) {
            key = iterator.next();
            builder.append( ",\"" + key + "\": \"" + this.infoMap.get(key) + "\"" );
        }
        builder.append( "}" );
        return Encoder.toUnicode( builder.toString() );
    }
    @Override
    public void putInfo(String name, String val) {
        this.infoMap.put(name, val);
    }
    @Override
    public void putInfo(String name, long val) {
        this.putInfo(name, val+"");
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/FileType.java
New file
@@ -0,0 +1,31 @@
package com.baidu.ueditor.define;
import java.util.HashMap;
import java.util.Map;
public class FileType {
    public static final String JPG = "JPG";
    private static final Map<String, String> types = new HashMap<String, String>(){{
        put( FileType.JPG, ".jpg" );
    }};
    public static String getSuffix ( String key ) {
        return FileType.types.get( key );
    }
    /**
     * 根据给定的文件名,获取其后缀信息
     * @param filename
     * @return
     */
    public static String getSuffixByFilename ( String filename ) {
        return filename.substring( filename.lastIndexOf( "." ) ).toLowerCase();
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/MIMEType.java
New file
@@ -0,0 +1,20 @@
package com.baidu.ueditor.define;
import java.util.HashMap;
import java.util.Map;
public class MIMEType {
    public static final Map<String, String> types = new HashMap<String, String>(){{
        put( "image/gif", ".gif" );
        put( "image/jpeg", ".jpg" );
        put( "image/jpg", ".jpg" );
        put( "image/png", ".png" );
        put( "image/bmp", ".bmp" );
    }};
    public static String getSuffix ( String mime ) {
        return MIMEType.types.get( mime );
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/MultiState.java
New file
@@ -0,0 +1,112 @@
package com.baidu.ueditor.define;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.baidu.ueditor.Encoder;
/**
 * 多状态集合状态
 * 其包含了多个状态的集合, 其本身自己也是一个状态
 * @author hancong03@baidu.com
 *
 */
public class MultiState implements State {
    private boolean state = false;
    private String info = null;
    private Map<String, Long> intMap = new HashMap<String, Long>();
    private Map<String, String> infoMap = new HashMap<String, String>();
    private List<String> stateList = new ArrayList<String>();
    public MultiState ( boolean state ) {
        this.state = state;
    }
    public MultiState ( boolean state, String info ) {
        this.state = state;
        this.info = info;
    }
    public MultiState ( boolean state, int infoKey ) {
        this.state = state;
        this.info = AppInfo.getStateInfo( infoKey );
    }
    @Override
    public boolean isSuccess() {
        return this.state;
    }
    public void addState ( State state ) {
        stateList.add( state.toJSONString() );
    }
    /**
     * 该方法调用无效果
     */
    @Override
    public void putInfo(String name, String val) {
        this.infoMap.put(name, val);
    }
    @Override
    public String toJSONString() {
        String stateVal = this.isSuccess() ? AppInfo.getStateInfo( AppInfo.SUCCESS ) : this.info;
        StringBuilder builder = new StringBuilder();
        builder.append( "{\"state\": \"" + stateVal + "\"" );
        // 数字转换
        Iterator<String> iterator = this.intMap.keySet().iterator();
        while ( iterator.hasNext() ) {
            stateVal = iterator.next();
            builder.append( ",\""+ stateVal +"\": " + this.intMap.get( stateVal ) );
        }
        iterator = this.infoMap.keySet().iterator();
        while ( iterator.hasNext() ) {
            stateVal = iterator.next();
            builder.append( ",\""+ stateVal +"\": \"" + this.infoMap.get( stateVal ) + "\"" );
        }
        builder.append( ", list: [" );
        iterator = this.stateList.iterator();
        while ( iterator.hasNext() ) {
            builder.append( iterator.next() + "," );
        }
        if ( this.stateList.size() > 0 ) {
            builder.deleteCharAt( builder.length() - 1 );
        }
        builder.append( " ]}" );
        return Encoder.toUnicode( builder.toString() );
    }
    @Override
    public void putInfo(String name, long val) {
        this.intMap.put( name, val );
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/define/State.java
New file
@@ -0,0 +1,18 @@
package com.baidu.ueditor.define;
/**
 * 处理状态接口
 * @author hancong03@baidu.com
 *
 */
public interface State {
    public boolean isSuccess ();
    public void putInfo( String name, String val );
    public void putInfo ( String name, long val );
    public String toJSONString ();
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/hunter/FileManager.java
New file
@@ -0,0 +1,112 @@
package com.baidu.ueditor.hunter;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.MultiState;
import com.baidu.ueditor.define.State;
public class FileManager {
    private String dir = null;
    private String rootPath = null;
    private String[] allowFiles = null;
    private int count = 0;
    public FileManager ( Map<String, Object> conf ) {
        this.rootPath = (String)conf.get( "rootPath" );
        this.dir = this.rootPath + (String)conf.get( "dir" );
        this.allowFiles = this.getAllowFiles( conf.get("allowFiles") );
        this.count = (Integer)conf.get( "count" );
    }
    public State listFile ( int index ) {
        File dir = new File( this.dir );
        State state = null;
        if ( !dir.exists() ) {
            return new BaseState( false, AppInfo.NOT_EXIST );
        }
        if ( !dir.isDirectory() ) {
            return new BaseState( false, AppInfo.NOT_DIRECTORY );
        }
        Collection<File> list = FileUtils.listFiles( dir, this.allowFiles, true );
        if ( index < 0 || index > list.size() ) {
            state = new MultiState( true );
        } else {
            Object[] fileList = Arrays.copyOfRange( list.toArray(), index, index + this.count );
            state = this.getState( fileList );
        }
        state.putInfo( "start", index );
        state.putInfo( "total", list.size() );
        return state;
    }
    private State getState ( Object[] files ) {
        MultiState state = new MultiState( true );
        BaseState fileState = null;
        File file = null;
        for ( Object obj : files ) {
            if ( obj == null ) {
                break;
            }
            file = (File)obj;
            fileState = new BaseState( true );
            fileState.putInfo( "url", PathFormat.format( this.getPath( file ) ) );
            state.addState( fileState );
        }
        return state;
    }
    private String getPath ( File file ) {
        String path = file.getAbsolutePath();
        return path.replace( this.rootPath, "/" );
    }
    private String[] getAllowFiles ( Object fileExt ) {
        String[] exts = null;
        String ext = null;
        if ( fileExt == null ) {
            return new String[ 0 ];
        }
        exts = (String[])fileExt;
        for ( int i = 0, len = exts.length; i < len; i++ ) {
            ext = exts[ i ];
            exts[ i ] = ext.replace( ".", "" );
        }
        return exts;
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/hunter/ImageHunter.java
New file
@@ -0,0 +1,133 @@
package com.baidu.ueditor.hunter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.MIMEType;
import com.baidu.ueditor.define.MultiState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.upload.StorageManager;
/**
 * 图片抓取器
 * @author hancong03@baidu.com
 *
 */
public class ImageHunter {
    private String filename = null;
    private String savePath = null;
    private String rootPath = null;
    private List<String> allowTypes = null;
    private long maxSize = -1;
    private List<String> filters = null;
    public ImageHunter ( Map<String, Object> conf ) {
        this.filename = (String)conf.get( "filename" );
        this.savePath = (String)conf.get( "savePath" );
        this.rootPath = (String)conf.get( "rootPath" );
        this.maxSize = (Long)conf.get( "maxSize" );
        this.allowTypes = Arrays.asList( (String[])conf.get( "allowFiles" ) );
        this.filters = Arrays.asList( (String[])conf.get( "filter" ) );
    }
    public State capture ( String[] list ) {
        MultiState state = new MultiState( true );
        for ( String source : list ) {
            state.addState( captureRemoteData( source ) );
        }
        return state;
    }
    public State captureRemoteData ( String urlStr ) {
        HttpURLConnection connection = null;
        URL url = null;
        String suffix = null;
        try {
            url = new URL( urlStr );
            if ( !validHost( url.getHost() ) ) {
                return new BaseState( false, AppInfo.PREVENT_HOST );
            }
            connection = (HttpURLConnection) url.openConnection();
            connection.setInstanceFollowRedirects( true );
            connection.setUseCaches( true );
            if ( !validContentState( connection.getResponseCode() ) ) {
                return new BaseState( false, AppInfo.CONNECTION_ERROR );
            }
            suffix = MIMEType.getSuffix( connection.getContentType() );
            if ( !validFileType( suffix ) ) {
                return new BaseState( false, AppInfo.NOT_ALLOW_FILE_TYPE );
            }
            if ( !validFileSize( connection.getContentLength() ) ) {
                return new BaseState( false, AppInfo.MAX_SIZE );
            }
            String savePath = this.getPath( this.savePath, this.filename, suffix );
            String physicalPath = this.rootPath + savePath;
            State state = StorageManager.saveFileByInputStream( connection.getInputStream(), physicalPath );
            if ( state.isSuccess() ) {
                state.putInfo( "url", PathFormat.format( savePath ) );
                state.putInfo( "source", urlStr );
            }
            return state;
        } catch ( Exception e ) {
            return new BaseState( false, AppInfo.REMOTE_FAIL );
        }
    }
    private String getPath ( String savePath, String filename, String suffix  ) {
        return PathFormat.parse( savePath + suffix, filename );
    }
    private boolean validHost ( String hostname ) {
        return !filters.contains( hostname );
    }
    private boolean validContentState ( int code ) {
        return HttpURLConnection.HTTP_OK == code;
    }
    private boolean validFileType ( String type ) {
        return this.allowTypes.contains( type );
    }
    private boolean validFileSize ( int size ) {
        return size < this.maxSize;
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/Base64Uploader.java
New file
@@ -0,0 +1,52 @@
package com.baidu.ueditor.upload;
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
public final class Base64Uploader {
    public static State save(String content, Map<String, Object> conf) {
        byte[] data = decode(content);
        long maxSize = ((Long) conf.get("maxSize")).longValue();
        if (!validSize(data, maxSize)) {
            return new BaseState(false, AppInfo.MAX_SIZE);
        }
        String suffix = FileType.getSuffix("JPG");
        String savePath = PathFormat.parse((String) conf.get("savePath"),
                (String) conf.get("filename"));
        savePath = savePath + suffix;
        String physicalPath = (String) conf.get("rootPath") + savePath;
        State storageState = StorageManager.saveBinaryFile(data, physicalPath);
        if (storageState.isSuccess()) {
            storageState.putInfo("url", PathFormat.format(savePath));
            storageState.putInfo("type", suffix);
            storageState.putInfo("original", "");
        }
        return storageState;
    }
    private static byte[] decode(String content) {
        return Base64.decodeBase64(content);
    }
    private static boolean validSize(byte[] data, long length) {
        return data.length <= length;
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/BinaryUploader.java
New file
@@ -0,0 +1,98 @@
package com.baidu.ueditor.upload;
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class BinaryUploader {
    public static final State save(HttpServletRequest request,
            Map<String, Object> conf) {
        FileItemStream fileStream = null;
        boolean isAjaxUpload = request.getHeader( "X_Requested_With" ) != null;
        if (!ServletFileUpload.isMultipartContent(request)) {
            return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
        }
        ServletFileUpload upload = new ServletFileUpload(
                new DiskFileItemFactory());
        if ( isAjaxUpload ) {
            upload.setHeaderEncoding( "UTF-8" );
        }
        try {
            FileItemIterator iterator = upload.getItemIterator(request);
            while (iterator.hasNext()) {
                fileStream = iterator.next();
                if (!fileStream.isFormField())
                    break;
                fileStream = null;
            }
            if (fileStream == null) {
                return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
            }
            String savePath = (String) conf.get("savePath");
            String originFileName = fileStream.getName();
            String suffix = FileType.getSuffixByFilename(originFileName);
            originFileName = originFileName.substring(0,
                    originFileName.length() - suffix.length());
            savePath = savePath + suffix;
            long maxSize = ((Long) conf.get("maxSize")).longValue();
            if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
                return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
            }
            savePath = PathFormat.parse(savePath, originFileName);
            String physicalPath = (String) conf.get("rootPath") + savePath;
            InputStream is = fileStream.openStream();
            State storageState = StorageManager.saveFileByInputStream(is,
                    physicalPath, maxSize);
            is.close();
            if (storageState.isSuccess()) {
                storageState.putInfo("url", PathFormat.format(savePath));
                storageState.putInfo("type", suffix);
                storageState.putInfo("original", originFileName + suffix);
            }
            return storageState;
        } catch (FileUploadException e) {
            return new BaseState(false, AppInfo.PARSE_REQUEST_ERROR);
        } catch (IOException e) {
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }
    private static boolean validType(String type, String[] allowTypes) {
        List<String> list = Arrays.asList(allowTypes);
        return list.contains(type);
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/StorageManager.java
New file
@@ -0,0 +1,155 @@
package com.baidu.ueditor.upload;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.State;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.FileUtils;
public class StorageManager {
    public static final int BUFFER_SIZE = 8192;
    public StorageManager() {
    }
    public static State saveBinaryFile(byte[] data, String path) {
        File file = new File(path);
        State state = valid(file);
        if (!state.isSuccess()) {
            return state;
        }
        try {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(file));
            bos.write(data);
            bos.flush();
            bos.close();
        } catch (IOException ioe) {
            return new BaseState(false, AppInfo.IO_ERROR);
        }
        state = new BaseState(true, file.getAbsolutePath());
        state.putInfo( "size", data.length );
        state.putInfo( "title", file.getName() );
        return state;
    }
    public static State saveFileByInputStream(InputStream is, String path,
            long maxSize) {
        State state = null;
        File tmpFile = getTmpFile();
        byte[] dataBuf = new byte[ 2048 ];
        BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);
            int count = 0;
            while ((count = bis.read(dataBuf)) != -1) {
                bos.write(dataBuf, 0, count);
            }
            bos.flush();
            bos.close();
            if (tmpFile.length() > maxSize) {
                tmpFile.delete();
                return new BaseState(false, AppInfo.MAX_SIZE);
            }
            state = saveTmpFile(tmpFile, path);
            if (!state.isSuccess()) {
                tmpFile.delete();
            }
            return state;
        } catch (IOException e) {
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }
    public static State saveFileByInputStream(InputStream is, String path) {
        State state = null;
        File tmpFile = getTmpFile();
        byte[] dataBuf = new byte[ 2048 ];
        BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);
            int count = 0;
            while ((count = bis.read(dataBuf)) != -1) {
                bos.write(dataBuf, 0, count);
            }
            bos.flush();
            bos.close();
            state = saveTmpFile(tmpFile, path);
            if (!state.isSuccess()) {
                tmpFile.delete();
            }
            return state;
        } catch (IOException e) {
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }
    private static File getTmpFile() {
        File tmpDir = FileUtils.getTempDirectory();
        String tmpFileName = (Math.random() * 10000 + "").replace(".", "");
        return new File(tmpDir, tmpFileName);
    }
    private static State saveTmpFile(File tmpFile, String path) {
        State state = null;
        File targetFile = new File(path);
        if (targetFile.canWrite()) {
            return new BaseState(false, AppInfo.PERMISSION_DENIED);
        }
        try {
            FileUtils.moveFile(tmpFile, targetFile);
        } catch (IOException e) {
            return new BaseState(false, AppInfo.IO_ERROR);
        }
        state = new BaseState(true);
        state.putInfo( "size", targetFile.length() );
        state.putInfo( "title", targetFile.getName() );
        return state;
    }
    private static State valid(File file) {
        File parentPath = file.getParentFile();
        if ((!parentPath.exists()) && (!parentPath.mkdirs())) {
            return new BaseState(false, AppInfo.FAILED_CREATE_FILE);
        }
        if (!parentPath.canWrite()) {
            return new BaseState(false, AppInfo.PERMISSION_DENIED);
        }
        return new BaseState(true);
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/jsp/src/com/baidu/ueditor/upload/Uploader.java
New file
@@ -0,0 +1,29 @@
package com.baidu.ueditor.upload;
import com.baidu.ueditor.define.State;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class Uploader {
    private HttpServletRequest request = null;
    private Map<String, Object> conf = null;
    public Uploader(HttpServletRequest request, Map<String, Object> conf) {
        this.request = request;
        this.conf = conf;
    }
    public final State doExec() {
        String filedName = (String) this.conf.get("fieldName");
        State state = null;
        if ("true".equals(this.conf.get("isBase64"))) {
            state = Base64Uploader.save(this.request.getParameter(filedName),
                    this.conf);
        } else {
            state = BinaryUploader.save(this.request, this.conf);
        }
        return state;
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/en.js
New file
@@ -0,0 +1,684 @@
/**
 * Created with JetBrains PhpStorm.
 * User: taoqili
 * Date: 12-6-12
 * Time: 下午6:57
 * To change this template use File | Settings | File Templates.
 */
UE.I18N['en'] = {
    'labelMap':{
        'anchor':'Anchor', 'undo':'Undo', 'redo':'Redo', 'bold':'Bold', 'indent':'Indent', 'snapscreen':'SnapScreen',
        'italic':'Italic', 'underline':'Underline', 'strikethrough':'Strikethrough', 'subscript':'SubScript','fontborder':'text border',
        'superscript':'SuperScript', 'formatmatch':'Format Match', 'source':'Source', 'blockquote':'BlockQuote',
        'pasteplain':'PastePlain', 'selectall':'SelectAll', 'print':'Print', 'preview':'Preview',
        'horizontal':'Horizontal', 'removeformat':'RemoveFormat', 'time':'Time', 'date':'Date',
        'unlink':'Unlink', 'insertrow':'InsertRow', 'insertcol':'InsertCol', 'mergeright':'MergeRight', 'mergedown':'MergeDown',
        'deleterow':'DeleteRow', 'deletecol':'DeleteCol', 'splittorows':'SplitToRows','insertcode':'insert code',
        'splittocols':'SplitToCols', 'splittocells':'SplitToCells','deletecaption':'DeleteCaption','inserttitle':'InsertTitle',
        'mergecells':'MergeCells', 'deletetable':'DeleteTable', 'cleardoc':'Clear', 'insertparagraphbeforetable':"InsertParagraphBeforeTable",
        'fontfamily':'FontFamily', 'fontsize':'FontSize', 'paragraph':'Paragraph','simpleupload':'Single Image','insertimage':'Multi Image','edittable':'Edit Table', 'edittd':'Edit Td','link':'Link',
        'emotion':'Emotion', 'spechars':'Spechars', 'searchreplace':'SearchReplace', 'map':'BaiduMap', 'gmap':'GoogleMap',
        'insertvideo':'Video', 'help':'Help', 'justifyleft':'JustifyLeft', 'justifyright':'JustifyRight', 'justifycenter':'JustifyCenter',
        'justifyjustify':'Justify', 'forecolor':'FontColor', 'backcolor':'BackColor', 'insertorderedlist':'OL',
        'insertunorderedlist':'UL', 'fullscreen':'FullScreen', 'directionalityltr':'EnterFromLeft', 'directionalityrtl':'EnterFromRight',
        'rowspacingtop':'RowSpacingTop', 'rowspacingbottom':'RowSpacingBottom', 'pagebreak':'PageBreak', 'insertframe':'Iframe', 'imagenone':'Default',
        'imageleft':'ImageLeft', 'imageright':'ImageRight', 'attachment':'Attachment', 'imagecenter':'ImageCenter', 'wordimage':'WordImage',
        'lineheight':'LineHeight','edittip':'EditTip','customstyle':'CustomStyle', 'scrawl':'Scrawl', 'autotypeset':'AutoTypeset',
        'webapp':'WebAPP', 'touppercase':'UpperCase', 'tolowercase':'LowerCase','template':'Template','background':'Background','inserttable':'InsertTable',
        'music':'Music', 'charts': 'charts','drafts': 'Load from Drafts'
    },
    'insertorderedlist':{
        'num':'1,2,3...',
        'num1':'1),2),3)...',
        'num2':'(1),(2),(3)...',
        'cn':'一,二,三....',
        'cn1':'一),二),三)....',
        'cn2':'(一),(二),(三)....',
        'decimal':'1,2,3...',
        'lower-alpha':'a,b,c...',
        'lower-roman':'i,ii,iii...',
        'upper-alpha':'A,B,C...',
        'upper-roman':'I,II,III...'
    },
    'insertunorderedlist':{
        'circle':'○ Circle',
        'disc':'● Circle dot',
        'square':'■ Rectangle ',
        'dash' :'- Dash',
        'dot' : '。dot'
    },
    'paragraph':{'p':'Paragraph', 'h1':'Title 1', 'h2':'Title 2', 'h3':'Title 3', 'h4':'Title 4', 'h5':'Title 5', 'h6':'Title 6'},
    'fontfamily':{
        'songti':'Sim Sun',
        'kaiti':'Sim Kai',
        'heiti':'Sim Hei',
        'lishu':'Sim Li',
        'yahei': 'Microsoft YaHei',
        'andaleMono':'Andale Mono',
        'arial': 'Arial',
        'arialBlack':'Arial Black',
        'comicSansMs':'Comic Sans MS',
        'impact':'Impact',
        'timesNewRoman':'Times New Roman'
    },
    'customstyle':{
        'tc':'Title center',
        'tl':'Title left',
        'im':'Important',
        'hi':'Highlight'
    },
    'autoupload': {
        'exceedSizeError': 'File Size Exceed',
        'exceedTypeError': 'File Type Not Allow',
        'jsonEncodeError': 'Server Return Format Error',
        'loading':"loading...",
        'loadError':"load error",
        'errorLoadConfig': 'Server config not loaded, upload can not work.',
    },
    'simpleupload':{
        'exceedSizeError': 'File Size Exceed',
        'exceedTypeError': 'File Type Not Allow',
        'jsonEncodeError': 'Server Return Format Error',
        'loading':"loading...",
        'loadError':"load error",
        'errorLoadConfig': 'Server config not loaded, upload can not work.',
    },
    'elementPathTip':"Path",
    'wordCountTip':"Word Count",
    'wordCountMsg':'{#count} characters entered,{#leave} left. ',
    'wordOverFlowMsg':'<span style="color:red;">The number of characters has exceeded allowable maximum values, the server may refuse to save!</span>',
    'ok':"OK",
    'cancel':"Cancel",
    'closeDialog':"closeDialog",
    'tableDrag':"You must import the file uiUtils.js before drag! ",
    'autofloatMsg':"The plugin AutoFloat depends on EditorUI!",
    'loadconfigError': 'Get server config error.',
    'loadconfigFormatError': 'Server config format error.',
    'loadconfigHttpError': 'Get server config http error.',
    'snapScreen_plugin':{
        'browserMsg':"Only IE supported!",
        'callBackErrorMsg':"The callback data is wrong,please check the config!",
        'uploadErrorMsg':"Upload error,please check your server environment! "
    },
    'insertcode':{
        'as3':'ActionScript 3',
        'bash':'Bash/Shell',
        'cpp':'C/C++',
        'css':'CSS',
        'cf':'ColdFusion',
        'c#':'C#',
        'delphi':'Delphi',
        'diff':'Diff',
        'erlang':'Erlang',
        'groovy':'Groovy',
        'html':'HTML',
        'java':'Java',
        'jfx':'JavaFX',
        'js':'JavaScript',
        'pl':'Perl',
        'php':'PHP',
        'plain':'Plain Text',
        'ps':'PowerShell',
        'python':'Python',
        'ruby':'Ruby',
        'scala':'Scala',
        'sql':'SQL',
        'vb':'Visual Basic',
        'xml':'XML'
    },
    'confirmClear':"Do you confirm to clear the Document?",
    'contextMenu':{
        'delete':"Delete",
        'selectall':"Select all",
        'deletecode':"Delete Code",
        'cleardoc':"Clear Document",
        'confirmclear':"Do you confirm to clear the Document?",
        'unlink':"Unlink",
        'paragraph':"Paragraph",
        'edittable':"Table property",
        'aligncell':'Align cell',
        'aligntable':'Table alignment',
        'tableleft':'Left float',
        'tablecenter':'Center',
        'tableright':'Right float',
        'aligntd':'Cell alignment',
        'edittd':"Cell property",
        'setbordervisible':'set table edge visible',
        'table':"Table",
        'justifyleft':'Justify Left',
        'justifyright':'Justify Right',
        'justifycenter':'Justify Center',
        'justifyjustify':'Default',
        'deletetable':"Delete table",
        'insertparagraphbefore':"InsertedBeforeLine",
        'insertparagraphafter':'InsertedAfterLine',
        'inserttable':'Insert table',
        'insertcaption':'Insert caption',
        'deletecaption':'Delete Caption',
        'inserttitle':'Insert Title',
        'deletetitle':'Delete Title',
        'inserttitlecol':'Insert Title Col',
        'deletetitlecol':'Delete Title Col',
        'averageDiseRow':'AverageDise Row',
        'averageDisCol':'AverageDis Col',
        'deleterow':"Delete row",
        'deletecol':"Delete col",
        'insertrow':"Insert row",
        'insertcol':"Insert col",
        'insertrownext':'Insert Row Next',
        'insertcolnext':'Insert Col Next',
        'mergeright':"Merge right",
        'mergeleft':"Merge left",
        'mergedown':"Merge down",
        'mergecells':"Merge cells",
        'splittocells':"Split to cells",
        'splittocols':"Split to Cols",
        'splittorows':"Split to Rows",
        'tablesort':'Table sorting',
        'enablesort':'Sorting Enable',
        'disablesort':'Sorting Disable',
        'reversecurrent':'Reverse current',
        'orderbyasc':'Order By ASCII',
        'reversebyasc':'Reverse By ASCII',
        'orderbynum':'Order By Num',
        'reversebynum':'Reverse By Num',
        'borderbk':'Border shading',
        'setcolor':'interlaced color',
        'unsetcolor':'Cancel interlacedcolor',
        'setbackground':'Background interlaced',
        'unsetbackground':'Cancel Bk interlaced',
        'redandblue':'Blue and red',
        'threecolorgradient':'Three-color gradient',
        'copy':"Copy(Ctrl + c)",
        'copymsg':"Browser does not support. Please use 'Ctrl + c' instead!",
        'paste':"Paste(Ctrl + v)",
        'pastemsg':"Browser does not support. Please use 'Ctrl + v' instead!"
    },
    'copymsg': "Browser does not support. Please use 'Ctrl + c' instead!",
    'pastemsg': "Browser does not support. Please use 'Ctrl + v' instead!",
    'anthorMsg':"Link",
    'clearColor':'Clear',
    'standardColor':'Standard color',
    'themeColor':'Theme color',
    'property':'Property',
    'default':'Default',
    'modify':'Modify',
    'justifyleft':'Justify Left',
    'justifyright':'Justify Right',
    'justifycenter':'Justify Center',
    'justify':'Default',
    'clear':'Clear',
    'anchorMsg':'Anchor',
    'delete':'Delete',
    'clickToUpload':"Click to upload",
    'unset':'Language hasn\'t been set!',
    't_row':'row',
    't_col':'col',
    'pasteOpt':'Paste Option',
    'pasteSourceFormat':"Keep Source Formatting",
    'tagFormat':'Keep tag',
    'pasteTextFormat':'Keep Text only',
    'more':'More',
    'autoTypeSet':{
        'mergeLine':"Merge empty line",
        'delLine':"Del empty line",
        'removeFormat':"Remove format",
        'indent':"Indent",
        'alignment':"Alignment",
        'imageFloat':"Image float",
        'removeFontsize':"Remove font size",
        'removeFontFamily':"Remove fontFamily",
        'removeHtml':"Remove redundant HTML code",
        'pasteFilter':"Paste filter",
        'run':"Done",
        'symbol':'Symbol Conversion',
        'bdc2sb':'Full-width to Half-width',
        'tobdc':'Half-width to Full-width'
    },
    'background':{
        'static':{
            'lang_background_normal':'Normal',
            'lang_background_local':'Online',
            'lang_background_set':'Background Set',
            'lang_background_none':'No Background',
            'lang_background_colored':'Colored Background',
            'lang_background_color':'Color Set',
            'lang_background_netimg':'Net-Image',
            'lang_background_align':'Align Type',
            'lang_background_position':'Position',
            'repeatType':{'options':["Center", "Repeat-x", "Repeat-y", "Tile","Custom"]}
        },
        'noUploadImage':"No pictures has been uploaded!",
        'toggleSelect':'Change the active state by click!\n Image Size: '
    },
    //===============dialog i18N=======================
    'insertimage':{
        'static':{
            'lang_tab_remote':"Insert",
            'lang_tab_upload':"Local",
            'lang_tab_online':"Manager",
            'lang_tab_search':"Search",
            'lang_input_url':"Address:",
            'lang_input_size':"Size:",
            'lang_input_width':"Width",
            'lang_input_height':"Height",
            'lang_input_border':"Border:",
            'lang_input_vhspace':"Margins:",
            'lang_input_title':"Title:",
            'lang_input_align':'Image Float Style:',
            'lang_imgLoading':"Loading...",
            'lang_start_upload':"Start Upload",
            'lock':{'title':"Lock rate"},
            'searchType':{'title':"ImageType", 'options':["News", "Wallpaper", "emotions", "photo"]},
            'searchTxt':{'value':"Enter the search keyword!"},
            'searchBtn':{'value':"Search"},
            'searchReset':{'value':"Clear"},
            'noneAlign':{'title':'None Float'},
            'leftAlign':{'title':'Left Float'},
            'rightAlign':{'title':'Right Float'},
            'centerAlign':{'title':'Center In A Line'}
        },
        'uploadSelectFile':'Select File',
        'uploadAddFile':'Add File',
        'uploadStart':'Start Upload',
        'uploadPause':'Pause Upload',
        'uploadContinue':'Continue Upload',
        'uploadRetry':'Retry Upload',
        'uploadDelete':'Delete',
        'uploadTurnLeft':'Turn Left',
        'uploadTurnRight':'Turn Right',
        'uploadPreview':'Doing Preview',
        'uploadNoPreview':'Can Not Preview',
        'updateStatusReady': 'Selected _ pictures, total _KB.',
        'updateStatusConfirm': '_ uploaded successfully and _ upload failed',
        'updateStatusFinish': 'Total _ pictures (_KB), _  uploaded successfully',
        'updateStatusError': ' and _ upload failed',
        'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player',
        'errorLoadConfig': 'Server config not loaded, upload can not work.',
        'errorExceedSize':'File Size Exceed',
        'errorFileType':'File Type Not Allow',
        'errorInterrupt':'File Upload Interrupted',
        'errorUploadRetry':'Upload Error, Please Retry.',
        'errorHttp':'Http Error',
        'errorServerUpload':'Server Result Error.',
        'remoteLockError':"Cannot Lock the Proportion between width and height",
        'numError':"Please enter the correct Num. e.g 123,400",
        'imageUrlError':"The image format may be wrong!",
        'imageLoadError':"Error,please check the network or URL!",
        'searchRemind':"Enter the search keyword!",
        'searchLoading':"Image is loading,please wait...",
        'searchRetry':" Sorry,can't find the image,please try again!"
    },
    'attachment':{
        'static':{
            'lang_tab_upload': 'Upload',
            'lang_tab_online': 'Online',
            'lang_start_upload':"Start upload",
            'lang_drop_remind':"You can drop files here, a single maximum of 300 files"
        },
        'uploadSelectFile':'Select File',
        'uploadAddFile':'Add File',
        'uploadStart':'Start Upload',
        'uploadPause':'Pause Upload',
        'uploadContinue':'Continue Upload',
        'uploadRetry':'Retry Upload',
        'uploadDelete':'Delete',
        'uploadTurnLeft':'Turn Left',
        'uploadTurnRight':'Turn Right',
        'uploadPreview':'Doing Preview',
        'updateStatusReady': 'Selected _ files, total _KB.',
        'updateStatusConfirm': '_ uploaded successfully and _ upload failed',
        'updateStatusFinish': 'Total _ files (_KB), _  uploaded successfully',
        'updateStatusError': ' and _ upload failed',
        'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player',
        'errorLoadConfig': 'Server config not loaded, upload can not work.',
        'errorExceedSize':'File Size Exceed',
        'errorFileType':'File Type Not Allow',
        'errorInterrupt':'File Upload Interrupted',
        'errorUploadRetry':'Upload Error, Please Retry.',
        'errorHttp':'Http Error',
        'errorServerUpload':'Server Result Error.'
    },
    'insertvideo':{
        'static':{
            'lang_tab_insertV':"Video",
            'lang_tab_searchV':"Search",
            'lang_tab_uploadV':"Upload",
            'lang_video_url':" URL ",
            'lang_video_size':"Video Size",
            'lang_videoW':"Width",
            'lang_videoH':"Height",
            'lang_alignment':"Alignment",
            'videoSearchTxt':{'value':"Enter the search keyword!"},
            'videoType':{'options':["All", "Hot", "Entertainment", "Funny", "Sports", "Science", "variety"]},
            'videoSearchBtn':{'value':"Search in Baidu"},
            'videoSearchReset':{'value':"Clear result"},
            'lang_input_fileStatus':' No file uploaded!',
            'startUpload':{'style':"background:url(upload.png) no-repeat;"},
            'lang_upload_size':"Video Size",
            'lang_upload_width':"Width",
            'lang_upload_height':"Height",
            'lang_upload_alignment':"Alignment",
            'lang_format_advice':"Recommends mp4 format."
        },
        'numError':"Please enter the correct Num. e.g 123,400",
        'floatLeft':"Float left",
        'floatRight':"Float right",
        'default':"Default",
        'block':"Display in block",
        'urlError':"The video url format may be wrong!",
        'loading':" &nbsp;The video is loading, please wait…",
        'clickToSelect':"Click to select",
        'goToSource':'Visit source video ',
        'noVideo':" &nbsp; &nbsp;Sorry,can't find the video,please try again!",
        'browseFiles':'Open files',
        'uploadSuccess':'Upload Successful!',
        'delSuccessFile':'Remove from the success of the queue',
        'delFailSaveFile':'Remove the save failed file',
        'statusPrompt':' file(s) uploaded! ',
        'flashVersionError':'The current Flash version is too low, please update FlashPlayer,then try again!',
        'flashLoadingError':'The Flash failed loading! Please check the path or network state',
        'fileUploadReady':'Wait for uploading...',
        'delUploadQueue':'Remove from the uploading queue ',
        'limitPrompt1':'Can not choose more than single',
        'limitPrompt2':'file(s)!Please choose again!',
        'delFailFile':'Remove failure file',
        'fileSizeLimit':'File size exceeds the limit!',
        'emptyFile':'Can not upload an empty file!',
        'fileTypeError':'File type error!',
        'unknownError':'Unknown error!',
        'fileUploading':'Uploading,please wait...',
        'cancelUpload':'Cancel upload',
        'netError':'Network error',
        'failUpload':'Upload failed',
        'serverIOError':'Server IO error!',
        'noAuthority':'No Permission!',
        'fileNumLimit':'Upload limit to the number',
        'failCheck':'Authentication fails, the upload is skipped!',
        'fileCanceling':'Cancel, please wait...',
        'stopUploading':'Upload has stopped...',
        'uploadSelectFile':'Select File',
        'uploadAddFile':'Add File',
        'uploadStart':'Start Upload',
        'uploadPause':'Pause Upload',
        'uploadContinue':'Continue Upload',
        'uploadRetry':'Retry Upload',
        'uploadDelete':'Delete',
        'uploadTurnLeft':'Turn Left',
        'uploadTurnRight':'Turn Right',
        'uploadPreview':'Doing Preview',
        'updateStatusReady': 'Selected _ files, total _KB.',
        'updateStatusConfirm': '_ uploaded successfully and _ upload failed',
        'updateStatusFinish': 'Total _ files (_KB), _  uploaded successfully',
        'updateStatusError': ' and _ upload failed',
        'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player',
        'errorLoadConfig': 'Server config not loaded, upload can not work.',
        'errorExceedSize':'File Size Exceed',
        'errorFileType':'File Type Not Allow',
        'errorInterrupt':'File Upload Interrupted',
        'errorUploadRetry':'Upload Error, Please Retry.',
        'errorHttp':'Http Error',
        'errorServerUpload':'Server Result Error.'
    },
    'webapp':{
        'tip1':"This function provided by Baidu APP,please apply for baidu APPKey webmaster first!",
        'tip2':"And then open the file ueditor.config.js to set it! ",
        'applyFor':"APPLY FOR",
        'anthorApi':"Baidu API"
    },
    'template':{
        'static':{
            'lang_template_bkcolor':'Background Color',
            'lang_template_clear' : 'Keep Content',
            'lang_template_select':'Select Template'
        },
        'blank':"Blank",
        'blog':"Blog",
        'resume':"Resume",
        'richText':"Rich Text",
        'scrPapers':"Scientific Papers"
    },
    scrawl:{
        'static':{
            'lang_input_previousStep':"Previous",
            'lang_input_nextsStep':"Next",
            'lang_input_clear':'Clear',
            'lang_input_addPic':'AddImage',
            'lang_input_ScalePic':'ScaleImage',
            'lang_input_removePic':'RemoveImage',
            'J_imgTxt':{title:'Add background image'}
        },
        'noScarwl':"No paint, a white paper...",
        'scrawlUpLoading':"Image is uploading, please wait...",
        'continueBtn':"Try again",
        'imageError':"Image failed to load!",
        'backgroundUploading':'Image is uploading,please wait...'
    },
    'music':{
        'static':{
            'lang_input_tips':"Input singer/song/album, search you interested in music!",
            'J_searchBtn':{value:'Search songs'}
        },
        'emptyTxt':'Not search to the relevant music results, please change a keyword try.',
        'chapter':'Songs',
        'singer':'Singer',
        'special':'Album',
        'listenTest':'Audition'
    },
    anchor:{
        'static':{
            'lang_input_anchorName':'Anchor Name:'
        }
    },
    'charts':{
        'static':{
            'lang_data_source':'Data source:',
            'lang_chart_format': 'Chart format:',
            'lang_data_align': 'Align',
            'lang_chart_align_same': 'Consistent with the X-axis Y-axis',
            'lang_chart_align_reverse': 'X-axis Y-axis opposite',
            'lang_chart_title': 'Title',
            'lang_chart_main_title': 'main title:',
            'lang_chart_sub_title': 'sub title:',
            'lang_chart_x_title': 'X-axis title:',
            'lang_chart_y_title': 'Y-axis title:',
            'lang_chart_tip': 'Prompt',
            'lang_cahrt_tip_prefix': 'prefix:',
            'lang_cahrt_tip_description': '仅饼图有效, 当鼠标移动到饼图中相应的块上时,提示框内的文字的前缀',
            'lang_chart_data_unit': 'Unit',
            'lang_chart_data_unit_title': 'unit:',
            'lang_chart_data_unit_description': '显示在每个数据点上的数据的单位, 比如: 温度的单位 ℃',
            'lang_chart_type': 'Chart type:',
            'lang_prev_btn': 'Previous',
            'lang_next_btn': 'Next'
        }
    },
    emotion:{
        'static':{
            'lang_input_choice':'Choice',
            'lang_input_Tuzki':'Tuzki',
            'lang_input_lvdouwa':'LvDouWa',
            'lang_input_BOBO':'BOBO',
            'lang_input_babyCat':'BabyCat',
            'lang_input_bubble':'Bubble',
            'lang_input_youa':'YouA'
        }
    },
    gmap:{
        'static':{
            'lang_input_address':'Address:',
            'lang_input_search':'Search',
            'address':{value:"Beijing"}
        },
        searchError:'Unable to locate the address!'
    },
    help:{
        'static':{
            'lang_input_about':'About',
            'lang_input_shortcuts':'Shortcuts',
            'lang_input_introduction':"UEditor is developed by Baidu Co.ltd.  It is lightweight, customizable , focusing on user experience and etc. , UEditor is based on open source BSD license , allowing free use and redistribution.",
            'lang_Txt_shortcuts':'Shortcuts',
            'lang_Txt_func':'Function',
            'lang_Txt_bold':'Bold',
            'lang_Txt_copy':'Copy',
            'lang_Txt_cut':'Cut',
            'lang_Txt_Paste':'Paste',
            'lang_Txt_undo':'Undo',
            'lang_Txt_redo':'Redo',
            'lang_Txt_italic':'Italic',
            'lang_Txt_underline':'Underline',
            'lang_Txt_selectAll':'Select All',
            'lang_Txt_visualEnter':'Submit',
            'lang_Txt_fullscreen':'Fullscreen'
        }
    },
    insertframe:{
        'static':{
            'lang_input_address':'Address:',
            'lang_input_width':'Width:',
            'lang_input_height':'height:',
            'lang_input_isScroll':'Enable scrollbars:',
            'lang_input_frameborder':'Show frame border:',
            'lang_input_alignMode':'Alignment:',
            'align':{title:"Alignment", options:["Default", "Left", "Right", "Center"]}
        },
        'enterAddress':'Please enter an address!'
    },
    link:{
        'static':{
            'lang_input_text':'Text:',
            'lang_input_url':'URL:',
            'lang_input_title':'Title:',
            'lang_input_target':'open in new window:'
        },
        'validLink':'Supports only effective when a link is selected',
        'httpPrompt':'The hyperlink you enter should start with "http|https|ftp://"!'
    },
    map:{
        'static':{
            lang_city:"City",
            lang_address:"Address",
            city:{value:"Beijing"},
            lang_search:"Search",
            lang_dynamicmap:"Dynamic map"
        },
        cityMsg:"Please enter the city name!",
        errorMsg:"Can't find the place!"
    },
    searchreplace:{
        'static':{
            lang_tab_search:"Search",
            lang_tab_replace:"Replace",
            lang_search1:"Search",
            lang_search2:"Search",
            lang_replace:"Replace",
            lang_searchReg:'Support regular expression ,which starts and ends with a slash ,for example "/expression/"',
            lang_searchReg1:'Support regular expression ,which starts and ends with a slash ,for example "/expression/"',
            lang_case_sensitive1:"Case sense",
            lang_case_sensitive2:"Case sense",
            nextFindBtn:{value:"Next"},
            preFindBtn:{value:"Preview"},
            nextReplaceBtn:{value:"Next"},
            preReplaceBtn:{value:"Preview"},
            repalceBtn:{value:"Replace"},
            repalceAllBtn:{value:"Replace all"}
        },
        getEnd:"Has the search to the bottom!",
        getStart:"Has the search to the top!",
        countMsg:"Altogether replaced {#count} character(s)!"
    },
    snapscreen:{
        'static':{
            lang_showMsg:"You should install the UEditor screenshots program first!",
            lang_download:"Download!",
            lang_step1:"Step1:Download the program and then run it",
            lang_step2:"Step2:After complete install,try to click the button again"
        }
    },
    spechars:{
        'static':{},
        tsfh:"Special",
        lmsz:"Roman",
        szfh:"Numeral",
        rwfh:"Japanese",
        xlzm:"The Greek",
        ewzm:"Russian",
        pyzm:"Phonetic",
        yyyb:"English",
        zyzf:"Others"
    },
    'edittable':{
        'static':{
            'lang_tableStyle':'Table style',
            'lang_insertCaption':'Add table header row',
            'lang_insertTitle':'Add table title row',
            'lang_insertTitleCol':'Add table title col',
            'lang_tableSize':'Automatically adjust table size',
            'lang_autoSizeContent':'Adaptive by form text',
            'lang_orderbycontent':"Table of contents sortable",
            'lang_autoSizePage':'Page width adaptive',
            'lang_example':'Example',
            'lang_borderStyle':'Table Border',
            'lang_color':'Color:'
        },
        captionName:'Caption',
        titleName:'Title',
        cellsName:'text',
        errorMsg:'There are merged cells, can not sort.'
    },
    'edittip':{
        'static':{
            lang_delRow:'Delete entire row',
            lang_delCol:'Delete entire col'
        }
    },
    'edittd':{
        'static':{
            lang_tdBkColor:'Background Color:'
        }
    },
    'formula':{
        'static':{
        }
    },
    wordimage:{
        'static':{
            lang_resave:"The re-save step",
            uploadBtn:{src:"upload.png", alt:"Upload"},
            clipboard:{style:"background: url(copy.png) -153px -1px no-repeat;"},
            lang_step:" 1. Click top button to copy the url and then open the dialog to paste it. 2. Open after choose photos uploaded process."
        },
        fileType:"Image",
        flashError:"Flash initialization failed!",
        netError:"Network error! Please try again!",
        copySuccess:"URL has been copied!",
        'flashI18n':{
            lang:encodeURI( '{"UploadingState":"totalNum: ${a},uploadComplete: ${b}", "BeforeUpload":"waitingNum: ${a}", "ExceedSize":"Size exceed${a}", "ErrorInPreview":"Preview failed", "DefaultDescription":"Description", "LoadingImage":"Loading..."}' ),
            uploadingTF:encodeURI( '{"font":"Arial", "size":12, "color":"0x000", "bold":"true", "italic":"false", "underline":"false"}' ),
            imageTF:encodeURI( '{"font":"Arial", "size":11, "color":"red", "bold":"false", "italic":"false", "underline":"false"}' ),
            textEncoding:"utf-8",
            addImageSkinURL:"addImage.png",
            allDeleteBtnUpSkinURL:"allDeleteBtnUpSkin.png",
            allDeleteBtnHoverSkinURL:"allDeleteBtnHoverSkin.png",
            rotateLeftBtnEnableSkinURL:"rotateLeftEnable.png",
            rotateLeftBtnDisableSkinURL:"rotateLeftDisable.png",
            rotateRightBtnEnableSkinURL:"rotateRightEnable.png",
            rotateRightBtnDisableSkinURL:"rotateRightDisable.png",
            deleteBtnEnableSkinURL:"deleteEnable.png",
            deleteBtnDisableSkinURL:"deleteDisable.png",
            backgroundURL:'',
            listBackgroundURL:'',
            buttonURL:'button.png'
        }
    },
    'autosave': {
        'success':'Local conservation success'
    }
};
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/addimage.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/alldeletebtnhoverskin.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/alldeletebtnupskin.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/background.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/button.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/copy.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/deletedisable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/deleteenable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/listbackground.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/localimage.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/music.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotateleftdisable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotateleftenable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotaterightdisable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/rotaterightenable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/en/images/upload.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/copy.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/localimage.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/music.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/images/upload.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/lang/zh-cn/zh-cn.js
New file
@@ -0,0 +1,669 @@
/**
 * Created with JetBrains PhpStorm.
 * User: taoqili
 * Date: 12-6-12
 * Time: 下午5:02
 * To change this template use File | Settings | File Templates.
 */
UE.I18N['zh-cn'] = {
    'labelMap':{
        'anchor':'锚点', 'undo':'撤销', 'redo':'重做', 'bold':'加粗', 'indent':'首行缩进', 'snapscreen':'截图',
        'italic':'斜体', 'underline':'下划线', 'strikethrough':'删除线', 'subscript':'下标','fontborder':'字符边框',
        'superscript':'上标', 'formatmatch':'格式刷', 'source':'源代码', 'blockquote':'引用',
        'pasteplain':'纯文本粘贴模式', 'selectall':'全选', 'print':'打印', 'preview':'预览',
        'horizontal':'分隔线', 'removeformat':'清除格式', 'time':'时间', 'date':'日期',
        'unlink':'取消链接', 'insertrow':'前插入行', 'insertcol':'前插入列', 'mergeright':'右合并单元格', 'mergedown':'下合并单元格',
        'deleterow':'删除行', 'deletecol':'删除列', 'splittorows':'拆分成行',
        'splittocols':'拆分成列', 'splittocells':'完全拆分单元格','deletecaption':'删除表格标题','inserttitle':'插入标题',
        'mergecells':'合并多个单元格', 'deletetable':'删除表格', 'cleardoc':'清空文档','insertparagraphbeforetable':"表格前插入行",'insertcode':'代码语言',
        'fontfamily':'字体', 'fontsize':'字号', 'paragraph':'段落格式', 'simpleupload':'单图上传', 'insertimage':'多图上传','edittable':'表格属性','edittd':'单元格属性', 'link':'超链接',
        'emotion':'表情', 'spechars':'特殊字符', 'searchreplace':'查询替换', 'map':'Baidu地图',
        'insertvideo':'视频', 'help':'帮助', 'justifyleft':'居左对齐', 'justifyright':'居右对齐', 'justifycenter':'居中对齐',
        'justifyjustify':'两端对齐', 'forecolor':'字体颜色', 'backcolor':'背景色', 'insertorderedlist':'有序列表',
        'insertunorderedlist':'无序列表', 'fullscreen':'全屏', 'directionalityltr':'从左向右输入', 'directionalityrtl':'从右向左输入',
        'rowspacingtop':'段前距', 'rowspacingbottom':'段后距',  'pagebreak':'分页', 'insertframe':'插入Iframe', 'imagenone':'默认',
        'imageleft':'左浮动', 'imageright':'右浮动', 'attachment':'附件', 'imagecenter':'居中', 'wordimage':'图片转存',
        'lineheight':'行间距','edittip' :'编辑提示','customstyle':'自定义标题', 'autotypeset':'自动排版',
        'webapp':'百度应用','touppercase':'字母大写', 'tolowercase':'字母小写','background':'背景','template':'模板','scrawl':'涂鸦',
        'music':'音乐','inserttable':'插入表格','drafts': '从草稿箱加载', 'charts': '图表'
    },
    'insertorderedlist':{
        'num':'1,2,3...',
        'num1':'1),2),3)...',
        'num2':'(1),(2),(3)...',
        'cn':'一,二,三....',
        'cn1':'一),二),三)....',
        'cn2':'(一),(二),(三)....',
        'decimal':'1,2,3...',
        'lower-alpha':'a,b,c...',
        'lower-roman':'i,ii,iii...',
        'upper-alpha':'A,B,C...',
        'upper-roman':'I,II,III...'
    },
    'insertunorderedlist':{
        'circle':'○ 大圆圈',
        'disc':'● 小黑点',
        'square':'■ 小方块 ',
        'dash' :'— 破折号',
        'dot':' 。 小圆圈'
    },
    'paragraph':{'p':'段落', 'h1':'标题 1', 'h2':'标题 2', 'h3':'标题 3', 'h4':'标题 4', 'h5':'标题 5', 'h6':'标题 6'},
    'fontfamily':{
        'songti':'宋体',
        'kaiti':'楷体',
        'heiti':'黑体',
        'lishu':'隶书',
        'yahei':'微软雅黑',
        'andaleMono':'andale mono',
        'arial': 'arial',
        'arialBlack':'arial black',
        'comicSansMs':'comic sans ms',
        'impact':'impact',
        'timesNewRoman':'times new roman'
    },
    'customstyle':{
        'tc':'标题居中',
        'tl':'标题居左',
        'im':'强调',
        'hi':'明显强调'
    },
    'autoupload': {
        'exceedSizeError': '文件大小超出限制',
        'exceedTypeError': '文件格式不允许',
        'jsonEncodeError': '服务器返回格式错误',
        'loading':"正在上传...",
        'loadError':"上传错误",
        'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!'
    },
    'simpleupload':{
        'exceedSizeError': '文件大小超出限制',
        'exceedTypeError': '文件格式不允许',
        'jsonEncodeError': '服务器返回格式错误',
        'loading':"正在上传...",
        'loadError':"上传错误",
        'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!'
    },
    'elementPathTip':"元素路径",
    'wordCountTip':"字数统计",
    'wordCountMsg':'当前已输入{#count}个字符, 您还可以输入{#leave}个字符。 ',
    'wordOverFlowMsg':'<span style="color:red;">字数超出最大允许值,服务器可能拒绝保存!</span>',
    'ok':"确认",
    'cancel':"取消",
    'closeDialog':"关闭对话框",
    'tableDrag':"表格拖动必须引入uiUtils.js文件!",
    'autofloatMsg':"工具栏浮动依赖编辑器UI,您首先需要引入UI文件!",
    'loadconfigError': '获取后台配置项请求出错,上传功能将不能正常使用!',
    'loadconfigFormatError': '后台配置项返回格式出错,上传功能将不能正常使用!',
    'loadconfigHttpError': '请求后台配置项http错误,上传功能将不能正常使用!',
    'snapScreen_plugin':{
        'browserMsg':"仅支持IE浏览器!",
        'callBackErrorMsg':"服务器返回数据有误,请检查配置项之后重试。",
        'uploadErrorMsg':"截图上传失败,请检查服务器端环境! "
    },
    'insertcode':{
        'as3':'ActionScript 3',
        'bash':'Bash/Shell',
        'cpp':'C/C++',
        'css':'CSS',
        'cf':'ColdFusion',
        'c#':'C#',
        'delphi':'Delphi',
        'diff':'Diff',
        'erlang':'Erlang',
        'groovy':'Groovy',
        'html':'HTML',
        'java':'Java',
        'jfx':'JavaFX',
        'js':'JavaScript',
        'pl':'Perl',
        'php':'PHP',
        'plain':'Plain Text',
        'ps':'PowerShell',
        'python':'Python',
        'ruby':'Ruby',
        'scala':'Scala',
        'sql':'SQL',
        'vb':'Visual Basic',
        'xml':'XML'
    },
    'confirmClear':"确定清空当前文档么?",
    'contextMenu':{
        'delete':"删除",
        'selectall':"全选",
        'deletecode':"删除代码",
        'cleardoc':"清空文档",
        'confirmclear':"确定清空当前文档么?",
        'unlink':"删除超链接",
        'paragraph':"段落格式",
        'edittable':"表格属性",
        'aligntd':"单元格对齐方式",
        'aligntable':'表格对齐方式',
        'tableleft':'左浮动',
        'tablecenter':'居中显示',
        'tableright':'右浮动',
        'edittd':"单元格属性",
        'setbordervisible':'设置表格边线可见',
        'justifyleft':'左对齐',
        'justifyright':'右对齐',
        'justifycenter':'居中对齐',
        'justifyjustify':'两端对齐',
        'table':"表格",
        'inserttable':'插入表格',
        'deletetable':"删除表格",
        'insertparagraphbefore':"前插入段落",
        'insertparagraphafter':'后插入段落',
        'deleterow':"删除当前行",
        'deletecol':"删除当前列",
        'insertrow':"前插入行",
        'insertcol':"左插入列",
        'insertrownext':'后插入行',
        'insertcolnext':'右插入列',
        'insertcaption':'插入表格名称',
        'deletecaption':'删除表格名称',
        'inserttitle':'插入表格标题行',
        'deletetitle':'删除表格标题行',
        'inserttitlecol':'插入表格标题列',
        'deletetitlecol':'删除表格标题列',
        'averageDiseRow':'平均分布各行',
        'averageDisCol':'平均分布各列',
        'mergeright':"向右合并",
        'mergeleft':"向左合并",
        'mergedown':"向下合并",
        'mergecells':"合并单元格",
        'splittocells':"完全拆分单元格",
        'splittocols':"拆分成列",
        'splittorows':"拆分成行",
        'tablesort':'表格排序',
        'enablesort':'设置表格可排序',
        'disablesort':'取消表格可排序',
        'reversecurrent':'逆序当前',
        'orderbyasc':'按ASCII字符升序',
        'reversebyasc':'按ASCII字符降序',
        'orderbynum':'按数值大小升序',
        'reversebynum':'按数值大小降序',
        'borderbk':'边框底纹',
        'setcolor':'表格隔行变色',
        'unsetcolor':'取消表格隔行变色',
        'setbackground':'选区背景隔行',
        'unsetbackground':'取消选区背景',
        'redandblue':'红蓝相间',
        'threecolorgradient':'三色渐变',
        'copy':"复制(Ctrl + c)",
        'copymsg': "浏览器不支持,请使用 'Ctrl + c'",
        'paste':"粘贴(Ctrl + v)",
         'pastemsg': "浏览器不支持,请使用 'Ctrl + v'"
    },
    'copymsg': "浏览器不支持,请使用 'Ctrl + c'",
    'pastemsg': "浏览器不支持,请使用 'Ctrl + v'",
    'anthorMsg':"链接",
    'clearColor':'清空颜色',
    'standardColor':'标准颜色',
    'themeColor':'主题颜色',
    'property':'属性',
    'default':'默认',
    'modify':'修改',
    'justifyleft':'左对齐',
    'justifyright':'右对齐',
    'justifycenter':'居中',
    'justify':'默认',
    'clear':'清除',
    'anchorMsg':'锚点',
    'delete':'删除',
    'clickToUpload':"点击上传",
    'unset':'尚未设置语言文件',
    't_row':'行',
    't_col':'列',
    'more':'更多',
    'pasteOpt':'粘贴选项',
    'pasteSourceFormat':"保留源格式",
    'tagFormat':'只保留标签',
    'pasteTextFormat':'只保留文本',
    'autoTypeSet':{
        'mergeLine':"合并空行",
        'delLine':"清除空行",
        'removeFormat':"清除格式",
        'indent':"首行缩进",
        'alignment':"对齐方式",
        'imageFloat':"图片浮动",
        'removeFontsize':"清除字号",
        'removeFontFamily':"清除字体",
        'removeHtml':"清除冗余HTML代码",
        'pasteFilter':"粘贴过滤",
        'run':"执行",
        'symbol':'符号转换',
        'bdc2sb':'全角转半角',
        'tobdc':'半角转全角'
    },
    'background':{
        'static':{
            'lang_background_normal':'背景设置',
            'lang_background_local':'在线图片',
            'lang_background_set':'选项',
            'lang_background_none':'无背景色',
            'lang_background_colored':'有背景色',
            'lang_background_color':'颜色设置',
            'lang_background_netimg':'网络图片',
            'lang_background_align':'对齐方式',
            'lang_background_position':'精确定位',
            'repeatType':{'options':["居中", "横向重复", "纵向重复", "平铺","自定义"]}
        },
        'noUploadImage':"当前未上传过任何图片!",
        'toggleSelect':"单击可切换选中状态\n原图尺寸: "
    },
    //===============dialog i18N=======================
    'insertimage':{
        'static':{
            'lang_tab_remote':"插入图片", //节点
            'lang_tab_upload':"本地上传",
            'lang_tab_online':"在线管理",
            'lang_tab_search':"图片搜索",
            'lang_input_url':"地 址:",
            'lang_input_size':"大 小:",
            'lang_input_width':"宽度",
            'lang_input_height':"高度",
            'lang_input_border':"边 框:",
            'lang_input_vhspace':"边 距:",
            'lang_input_title':"描 述:",
            'lang_input_align':'图片浮动方式:',
            'lang_imgLoading':" 图片加载中……",
            'lang_start_upload':"开始上传",
            'lock':{'title':"锁定宽高比例"}, //属性
            'searchType':{'title':"图片类型", 'options':["新闻", "壁纸", "表情", "头像"]}, //select的option
            'searchTxt':{'value':"请输入搜索关键词"},
            'searchBtn':{'value':"百度一下"},
            'searchReset':{'value':"清空搜索"},
            'noneAlign':{'title':'无浮动'},
            'leftAlign':{'title':'左浮动'},
            'rightAlign':{'title':'右浮动'},
            'centerAlign':{'title':'居中独占一行'}
        },
        'uploadSelectFile':'点击选择图片',
        'uploadAddFile':'继续添加',
        'uploadStart':'开始上传',
        'uploadPause':'暂停上传',
        'uploadContinue':'继续上传',
        'uploadRetry':'重试上传',
        'uploadDelete':'删除',
        'uploadTurnLeft':'向左旋转',
        'uploadTurnRight':'向右旋转',
        'uploadPreview':'预览中',
        'uploadNoPreview':'不能预览',
        'updateStatusReady': '选中_张图片,共_KB。',
        'updateStatusConfirm': '已成功上传_张照片,_张照片上传失败',
        'updateStatusFinish': '共_张(_KB),_张上传成功',
        'updateStatusError': ',_张上传失败。',
        'errorNotSupport': 'WebUploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器。',
        'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!',
        'errorExceedSize':'文件大小超出',
        'errorFileType':'文件格式不允许',
        'errorInterrupt':'文件传输中断',
        'errorUploadRetry':'上传失败,请重试',
        'errorHttp':'http请求错误',
        'errorServerUpload':'服务器返回出错',
        'remoteLockError':"宽高不正确,不能所定比例",
        'numError':"请输入正确的长度或者宽度值!例如:123,400",
        'imageUrlError':"不允许的图片格式或者图片域!",
        'imageLoadError':"图片加载失败!请检查链接地址或网络状态!",
        'searchRemind':"请输入搜索关键词",
        'searchLoading':"图片加载中,请稍后……",
        'searchRetry':" :( ,抱歉,没有找到图片!请重试一次!"
    },
    'attachment':{
        'static':{
            'lang_tab_upload': '上传附件',
            'lang_tab_online': '在线附件',
            'lang_start_upload':"开始上传",
            'lang_drop_remind':"可以将文件拖到这里,单次最多可选100个文件"
        },
        'uploadSelectFile':'点击选择文件',
        'uploadAddFile':'继续添加',
        'uploadStart':'开始上传',
        'uploadPause':'暂停上传',
        'uploadContinue':'继续上传',
        'uploadRetry':'重试上传',
        'uploadDelete':'删除',
        'uploadTurnLeft':'向左旋转',
        'uploadTurnRight':'向右旋转',
        'uploadPreview':'预览中',
        'updateStatusReady': '选中_个文件,共_KB。',
        'updateStatusConfirm': '已成功上传_个文件,_个文件上传失败',
        'updateStatusFinish': '共_个(_KB),_个上传成功',
        'updateStatusError': ',_张上传失败。',
        'errorNotSupport': 'WebUploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器。',
        'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!',
        'errorExceedSize':'文件大小超出',
        'errorFileType':'文件格式不允许',
        'errorInterrupt':'文件传输中断',
        'errorUploadRetry':'上传失败,请重试',
        'errorHttp':'http请求错误',
        'errorServerUpload':'服务器返回出错'
    },
    'insertvideo':{
        'static':{
            'lang_tab_insertV':"插入视频",
            'lang_tab_searchV':"搜索视频",
            'lang_tab_uploadV':"上传视频",
            'lang_video_url':"视频网址",
            'lang_video_size':"视频尺寸",
            'lang_videoW':"宽度",
            'lang_videoH':"高度",
            'lang_alignment':"对齐方式",
            'videoSearchTxt':{'value':"请输入搜索关键字!"},
            'videoType':{'options':["全部", "热门", "娱乐", "搞笑", "体育", "科技", "综艺"]},
            'videoSearchBtn':{'value':"百度一下"},
            'videoSearchReset':{'value':"清空结果"},
            'lang_input_fileStatus':' 当前未上传文件',
            'startUpload':{'style':"background:url(upload.png) no-repeat;"},
            'lang_upload_size':"视频尺寸",
            'lang_upload_width':"宽度",
            'lang_upload_height':"高度",
            'lang_upload_alignment':"对齐方式",
            'lang_format_advice':"建议使用mp4格式."
        },
        'numError':"请输入正确的数值,如123,400",
        'floatLeft':"左浮动",
        'floatRight':"右浮动",
        '"default"':"默认",
        'block':"独占一行",
        'urlError':"输入的视频地址有误,请检查后再试!",
        'loading':" &nbsp;视频加载中,请等待……",
        'clickToSelect':"点击选中",
        'goToSource':'访问源视频',
        'noVideo':" &nbsp; &nbsp;抱歉,找不到对应的视频,请重试!",
        'browseFiles':'浏览文件',
        'uploadSuccess':'上传成功!',
        'delSuccessFile':'从成功队列中移除',
        'delFailSaveFile':'移除保存失败文件',
        'statusPrompt':' 个文件已上传! ',
        'flashVersionError':'当前Flash版本过低,请更新FlashPlayer后重试!',
        'flashLoadingError':'Flash加载失败!请检查路径或网络状态',
        'fileUploadReady':'等待上传……',
        'delUploadQueue':'从上传队列中移除',
        'limitPrompt1':'单次不能选择超过',
        'limitPrompt2':'个文件!请重新选择!',
        'delFailFile':'移除失败文件',
        'fileSizeLimit':'文件大小超出限制!',
        'emptyFile':'空文件无法上传!',
        'fileTypeError':'文件类型不允许!',
        'unknownError':'未知错误!',
        'fileUploading':'上传中,请等待……',
        'cancelUpload':'取消上传',
        'netError':'网络错误',
        'failUpload':'上传失败!',
        'serverIOError':'服务器IO错误!',
        'noAuthority':'无权限!',
        'fileNumLimit':'上传个数限制',
        'failCheck':'验证失败,本次上传被跳过!',
        'fileCanceling':'取消中,请等待……',
        'stopUploading':'上传已停止……',
        'uploadSelectFile':'点击选择文件',
        'uploadAddFile':'继续添加',
        'uploadStart':'开始上传',
        'uploadPause':'暂停上传',
        'uploadContinue':'继续上传',
        'uploadRetry':'重试上传',
        'uploadDelete':'删除',
        'uploadTurnLeft':'向左旋转',
        'uploadTurnRight':'向右旋转',
        'uploadPreview':'预览中',
        'updateStatusReady': '选中_个文件,共_KB。',
        'updateStatusConfirm': '成功上传_个,_个失败',
        'updateStatusFinish': '共_个(_KB),_个成功上传',
        'updateStatusError': ',_张上传失败。',
        'errorNotSupport': 'WebUploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器。',
        'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!',
        'errorExceedSize':'文件大小超出',
        'errorFileType':'文件格式不允许',
        'errorInterrupt':'文件传输中断',
        'errorUploadRetry':'上传失败,请重试',
        'errorHttp':'http请求错误',
        'errorServerUpload':'服务器返回出错'
    },
    'webapp':{
        'tip1':"本功能由百度APP提供,如看到此页面,请各位站长首先申请百度APPKey!",
        'tip2':"申请完成之后请至ueditor.config.js中配置获得的appkey! ",
        'applyFor':"点此申请",
        'anthorApi':"百度API"
    },
    'template':{
        'static':{
            'lang_template_bkcolor':'背景颜色',
            'lang_template_clear' : '保留原有内容',
            'lang_template_select' : '选择模板'
        },
        'blank':"空白文档",
        'blog':"博客文章",
        'resume':"个人简历",
        'richText':"图文混排",
        'sciPapers':"科技论文"
    },
    'scrawl':{
        'static':{
            'lang_input_previousStep':"上一步",
            'lang_input_nextsStep':"下一步",
            'lang_input_clear':'清空',
            'lang_input_addPic':'添加背景',
            'lang_input_ScalePic':'缩放背景',
            'lang_input_removePic':'删除背景',
            'J_imgTxt':{title:'添加背景图片'}
        },
        'noScarwl':"尚未作画,白纸一张~",
        'scrawlUpLoading':"涂鸦上传中,别急哦~",
        'continueBtn':"继续",
        'imageError':"糟糕,图片读取失败了!",
        'backgroundUploading':'背景图片上传中,别急哦~'
    },
    'music':{
        'static':{
            'lang_input_tips':"输入歌手/歌曲/专辑,搜索您感兴趣的音乐!",
            'J_searchBtn':{value:'搜索歌曲'}
        },
        'emptyTxt':'未搜索到相关音乐结果,请换一个关键词试试。',
        'chapter':'歌曲',
        'singer':'歌手',
        'special':'专辑',
        'listenTest':'试听'
    },
    'anchor':{
        'static':{
            'lang_input_anchorName':'锚点名字:'
        }
    },
    'charts':{
        'static':{
            'lang_data_source':'数据源:',
            'lang_chart_format': '图表格式:',
            'lang_data_align': '数据对齐方式',
            'lang_chart_align_same': '数据源与图表X轴Y轴一致',
            'lang_chart_align_reverse': '数据源与图表X轴Y轴相反',
            'lang_chart_title': '图表标题',
            'lang_chart_main_title': '主标题:',
            'lang_chart_sub_title': '子标题:',
            'lang_chart_x_title': 'X轴标题:',
            'lang_chart_y_title': 'Y轴标题:',
            'lang_chart_tip': '提示文字',
            'lang_cahrt_tip_prefix': '提示文字前缀:',
            'lang_cahrt_tip_description': '仅饼图有效, 当鼠标移动到饼图中相应的块上时,提示框内的文字的前缀',
            'lang_chart_data_unit': '数据单位',
            'lang_chart_data_unit_title': '单位:',
            'lang_chart_data_unit_description': '显示在每个数据点上的数据的单位, 比如: 温度的单位 ℃',
            'lang_chart_type': '图表类型:',
            'lang_prev_btn': '上一个',
            'lang_next_btn': '下一个'
        }
    },
    'emotion':{
        'static':{
            'lang_input_choice':'精选',
            'lang_input_Tuzki':'兔斯基',
            'lang_input_BOBO':'BOBO',
            'lang_input_lvdouwa':'绿豆蛙',
            'lang_input_babyCat':'baby猫',
            'lang_input_bubble':'泡泡',
            'lang_input_youa':'有啊'
        }
    },
    'gmap':{
        'static':{
            'lang_input_address':'地址',
            'lang_input_search':'搜索',
            'address':{value:"北京"}
        },
        searchError:'无法定位到该地址!'
    },
    'help':{
        'static':{
            'lang_input_about':'关于UEditor',
            'lang_input_shortcuts':'快捷键',
            'lang_input_introduction':'UEditor是由百度web前端研发部开发的所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点。开源基于BSD协议,允许自由使用和修改代码。',
            'lang_Txt_shortcuts':'快捷键',
            'lang_Txt_func':'功能',
            'lang_Txt_bold':'给选中字设置为加粗',
            'lang_Txt_copy':'复制选中内容',
            'lang_Txt_cut':'剪切选中内容',
            'lang_Txt_Paste':'粘贴',
            'lang_Txt_undo':'重新执行上次操作',
            'lang_Txt_redo':'撤销上一次操作',
            'lang_Txt_italic':'给选中字设置为斜体',
            'lang_Txt_underline':'给选中字加下划线',
            'lang_Txt_selectAll':'全部选中',
            'lang_Txt_visualEnter':'软回车',
            'lang_Txt_fullscreen':'全屏'
        }
    },
    'insertframe':{
        'static':{
            'lang_input_address':'地址:',
            'lang_input_width':'宽度:',
            'lang_input_height':'高度:',
            'lang_input_isScroll':'允许滚动条:',
            'lang_input_frameborder':'显示框架边框:',
            'lang_input_alignMode':'对齐方式:',
            'align':{title:"对齐方式", options:["默认", "左对齐", "右对齐", "居中"]}
        },
        'enterAddress':'请输入地址!'
    },
    'link':{
        'static':{
            'lang_input_text':'文本内容:',
            'lang_input_url':'链接地址:',
            'lang_input_title':'标题:',
            'lang_input_target':'是否在新窗口打开:'
        },
        'validLink':'只支持选中一个链接时生效',
        'httpPrompt':'您输入的超链接中不包含http等协议名称,默认将为您添加http://前缀'
    },
    'map':{
        'static':{
            lang_city:"城市",
            lang_address:"地址",
            city:{value:"北京"},
            lang_search:"搜索",
            lang_dynamicmap:"插入动态地图"
        },
        cityMsg:"请选择城市",
        errorMsg:"抱歉,找不到该位置!"
    },
    'searchreplace':{
        'static':{
            lang_tab_search:"查找",
            lang_tab_replace:"替换",
            lang_search1:"查找",
            lang_search2:"查找",
            lang_replace:"替换",
            lang_searchReg:'支持正则表达式,添加前后斜杠标示为正则表达式,例如“/表达式/”',
            lang_searchReg1:'支持正则表达式,添加前后斜杠标示为正则表达式,例如“/表达式/”',
            lang_case_sensitive1:"区分大小写",
            lang_case_sensitive2:"区分大小写",
            nextFindBtn:{value:"下一个"},
            preFindBtn:{value:"上一个"},
            nextReplaceBtn:{value:"下一个"},
            preReplaceBtn:{value:"上一个"},
            repalceBtn:{value:"替换"},
            repalceAllBtn:{value:"全部替换"}
        },
        getEnd:"已经搜索到文章末尾!",
        getStart:"已经搜索到文章头部",
        countMsg:"总共替换了{#count}处!"
    },
    'snapscreen':{
        'static':{
            lang_showMsg:"截图功能需要首先安装UEditor截图插件! ",
            lang_download:"点此下载",
            lang_step1:"第一步,下载UEditor截图插件并运行安装。",
            lang_step2:"第二步,插件安装完成后即可使用,如不生效,请重启浏览器后再试!"
        }
    },
    'spechars':{
        'static':{},
        tsfh:"特殊字符",
        lmsz:"罗马字符",
        szfh:"数学字符",
        rwfh:"日文字符",
        xlzm:"希腊字母",
        ewzm:"俄文字符",
        pyzm:"拼音字母",
        yyyb:"英语音标",
        zyzf:"其他"
    },
    'edittable':{
        'static':{
            'lang_tableStyle':'表格样式',
            'lang_insertCaption':'添加表格名称行',
            'lang_insertTitle':'添加表格标题行',
            'lang_insertTitleCol':'添加表格标题列',
            'lang_orderbycontent':"使表格内容可排序",
            'lang_tableSize':'自动调整表格尺寸',
            'lang_autoSizeContent':'按表格文字自适应',
            'lang_autoSizePage':'按页面宽度自适应',
            'lang_example':'示例',
            'lang_borderStyle':'表格边框',
            'lang_color':'颜色:'
        },
        captionName:'表格名称',
        titleName:'标题',
        cellsName:'内容',
        errorMsg:'有合并单元格,不可排序'
    },
    'edittip':{
        'static':{
            lang_delRow:'删除整行',
            lang_delCol:'删除整列'
        }
    },
    'edittd':{
        'static':{
            lang_tdBkColor:'背景颜色:'
        }
    },
    'formula':{
        'static':{
        }
    },
    'wordimage':{
        'static':{
            lang_resave:"转存步骤",
            uploadBtn:{src:"upload.png",alt:"上传"},
            clipboard:{style:"background: url(copy.png) -153px -1px no-repeat;"},
            lang_step:"1、点击顶部复制按钮,将地址复制到剪贴板;2、点击添加照片按钮,在弹出的对话框中使用Ctrl+V粘贴地址;3、点击打开后选择图片上传流程。"
        },
        'fileType':"图片",
        'flashError':"FLASH初始化失败,请检查FLASH插件是否正确安装!",
        'netError':"网络连接错误,请重试!",
        'copySuccess':"图片地址已经复制!",
        'flashI18n':{} //留空默认中文
    },
    'autosave': {
        'saving':'保存中...',
        'success':'本地保存成功'
    }
};
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/Config.cs
New file
@@ -0,0 +1,55 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Web;
/// <summary>
/// Config 的摘要说明
/// </summary>
public static class Config
{
    private static bool noCache = true;
    private static JObject BuildItems()
    {
        var json = File.ReadAllText(HttpContext.Current.Server.MapPath("config.json"));
        return JObject.Parse(json);
    }
    public static JObject Items
    {
        get
        {
            if (noCache || _Items == null)
            {
                _Items = BuildItems();
            }
            return _Items;
        }
    }
    private static JObject _Items;
    public static T GetValue<T>(string key)
    {
        return Items[key].Value<T>();
    }
    public static String[] GetStringList(string key)
    {
        return Items[key].Select(x => x.Value<String>()).ToArray();
    }
    public static String GetString(string key)
    {
        return GetValue<String>(key);
    }
    public static int GetInt(string key)
    {
        return GetValue<int>(key);
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/ConfigHandler.cs
New file
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Config 的摘要说明
/// </summary>
public class ConfigHandler : Handler
{
    public ConfigHandler(HttpContext context) : base(context) { }
    public override void Process()
    {
        WriteJson(Config.Items);
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/CrawlerHandler.cs
New file
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
/// <summary>
/// Crawler 的摘要说明
/// </summary>
public class CrawlerHandler : Handler
{
    private string[] Sources;
    private Crawler[] Crawlers;
    public CrawlerHandler(HttpContext context) : base(context) { }
    public override void Process()
    {
        Sources = Request.Form.GetValues("source[]");
        if (Sources == null || Sources.Length == 0)
        {
            WriteJson(new
            {
                state = "参数错误:没有指定抓取源"
            });
            return;
        }
        Crawlers = Sources.Select(x => new Crawler(x, Server).Fetch()).ToArray();
        WriteJson(new
        {
            state = "SUCCESS",
            list = Crawlers.Select(x => new
            {
                state = x.State,
                source = x.SourceUrl,
                url = x.ServerUrl
            })
        });
    }
}
public class Crawler
{
    public string SourceUrl { get; set; }
    public string ServerUrl { get; set; }
    public string State { get; set; }
    private HttpServerUtility Server { get; set; }
    public Crawler(string sourceUrl, HttpServerUtility server)
    {
        this.SourceUrl = sourceUrl;
        this.Server = server;
    }
    public Crawler Fetch()
    {
        var request = HttpWebRequest.Create(this.SourceUrl) as HttpWebRequest;
        using (var response = request.GetResponse() as HttpWebResponse)
        {
            if (response.StatusCode != HttpStatusCode.OK)
            {
                State = "Url returns " + response.StatusCode + ", " + response.StatusDescription;
                return this;
            }
            if (response.ContentType.IndexOf("image") == -1)
            {
                State = "Url is not an image";
                return this;
            }
            ServerUrl = PathFormatter.Format(Path.GetFileName(this.SourceUrl), Config.GetString("catcherPathFormat"));
            var savePath = Server.MapPath(ServerUrl);
            if (!Directory.Exists(Path.GetDirectoryName(savePath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(savePath));
            }
            try
            {
                var stream = response.GetResponseStream();
                var reader = new BinaryReader(stream);
                byte[] bytes;
                using (var ms = new MemoryStream())
                {
                    byte[] buffer = new byte[4096];
                    int count;
                    while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        ms.Write(buffer, 0, count);
                    }
                    bytes = ms.ToArray();
                }
                File.WriteAllBytes(savePath, bytes);
                State = "SUCCESS";
            }
            catch (Exception e)
            {
                State = "抓取错误:" + e.Message;
            }
            return this;
        }
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/Handler.cs
New file
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
/// <summary>
/// Handler 的摘要说明
/// </summary>
public abstract class Handler
{
    public Handler(HttpContext context)
    {
        this.Request = context.Request;
        this.Response = context.Response;
        this.Context = context;
        this.Server = context.Server;
    }
    public abstract void Process();
    protected void WriteJson(object response)
    {
        string jsonpCallback = Request["callback"],
            json = JsonConvert.SerializeObject(response);
        if (String.IsNullOrWhiteSpace(jsonpCallback))
        {
            Response.AddHeader("Content-Type", "text/plain");
            Response.Write(json);
        }
        else
        {
            Response.AddHeader("Content-Type", "application/javascript");
            Response.Write(String.Format("{0}({1});", jsonpCallback, json));
        }
        Response.End();
    }
    public HttpRequest Request { get; private set; }
    public HttpResponse Response { get; private set; }
    public HttpContext Context { get; private set; }
    public HttpServerUtility Server { get; private set; }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/ListFileHandler.cs
New file
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
/// <summary>
/// FileManager 的摘要说明
/// </summary>
public class ListFileManager : Handler
{
    enum ResultState
    {
        Success,
        InvalidParam,
        AuthorizError,
        IOError,
        PathNotFound
    }
    private int Start;
    private int Size;
    private int Total;
    private ResultState State;
    private String PathToList;
    private String[] FileList;
    private String[] SearchExtensions;
    public ListFileManager(HttpContext context, string pathToList, string[] searchExtensions)
        : base(context)
    {
        this.SearchExtensions = searchExtensions.Select(x => x.ToLower()).ToArray();
        this.PathToList = pathToList;
    }
    public override void Process()
    {
        try
        {
            Start = String.IsNullOrEmpty(Request["start"]) ? 0 : Convert.ToInt32(Request["start"]);
            Size = String.IsNullOrEmpty(Request["size"]) ? Config.GetInt("imageManagerListSize") : Convert.ToInt32(Request["size"]);
        }
        catch (FormatException)
        {
            State = ResultState.InvalidParam;
            WriteResult();
            return;
        }
        var buildingList = new List<String>();
        try
        {
            var localPath = Server.MapPath(PathToList);
            buildingList.AddRange(Directory.GetFiles(localPath, "*", SearchOption.AllDirectories)
                .Where(x => SearchExtensions.Contains(Path.GetExtension(x).ToLower()))
                .Select(x => PathToList + x.Substring(localPath.Length).Replace("\\", "/")));
            Total = buildingList.Count;
            FileList = buildingList.OrderBy(x => x).Skip(Start).Take(Size).ToArray();
        }
        catch (UnauthorizedAccessException)
        {
            State = ResultState.AuthorizError;
        }
        catch (DirectoryNotFoundException)
        {
            State = ResultState.PathNotFound;
        }
        catch (IOException)
        {
            State = ResultState.IOError;
        }
        finally
        {
            WriteResult();
        }
    }
    private void WriteResult()
    {
        WriteJson(new
        {
            state = GetStateString(),
            list = FileList == null ? null : FileList.Select(x => new { url = x }),
            start = Start,
            size = Size,
            total = Total
        });
    }
    private string GetStateString()
    {
        switch (State)
        {
            case ResultState.Success:
                return "SUCCESS";
            case ResultState.InvalidParam:
                return "参数不正确";
            case ResultState.PathNotFound:
                return "路径不存在";
            case ResultState.AuthorizError:
                return "文件系统权限不足";
            case ResultState.IOError:
                return "文件系统读取错误";
        }
        return "未知错误";
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/NotSupportedHandler.cs
New file
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// NotSupportedHandler 的摘要说明
/// </summary>
public class NotSupportedHandler : Handler
{
    public NotSupportedHandler(HttpContext context)
        : base(context)
    {
    }
    public override void Process()
    {
        WriteJson(new
        {
            state = "action 参数为空或者 action 不被支持。"
        });
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/PathFormater.cs
New file
@@ -0,0 +1,50 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
/// <summary>
/// PathFormater 的摘要说明
/// </summary>
public static class PathFormatter
{
    public static string Format(string originFileName, string pathFormat)
    {
        if (String.IsNullOrWhiteSpace(pathFormat))
        {
            pathFormat = "{filename}{rand:6}";
        }
        var invalidPattern = new Regex(@"[\\\/\:\*\?\042\<\>\|]");
        originFileName = invalidPattern.Replace(originFileName, "");
        string extension = Path.GetExtension(originFileName);
        string filename = Path.GetFileNameWithoutExtension(originFileName);
        pathFormat = pathFormat.Replace("{filename}", filename);
        pathFormat = new Regex(@"\{rand(\:?)(\d+)\}", RegexOptions.Compiled).Replace(pathFormat, new MatchEvaluator(delegate(Match match)
        {
            var digit = 6;
            if (match.Groups.Count > 2)
            {
                digit = Convert.ToInt32(match.Groups[2].Value);
            }
            var rand = new Random();
            return rand.Next((int)Math.Pow(10, digit), (int)Math.Pow(10, digit + 1)).ToString();
        }));
        pathFormat = pathFormat.Replace("{time}", DateTime.Now.Ticks.ToString());
        pathFormat = pathFormat.Replace("{yyyy}", DateTime.Now.Year.ToString());
        pathFormat = pathFormat.Replace("{yy}", (DateTime.Now.Year % 100).ToString("D2"));
        pathFormat = pathFormat.Replace("{mm}", DateTime.Now.Month.ToString("D2"));
        pathFormat = pathFormat.Replace("{dd}", DateTime.Now.Day.ToString("D2"));
        pathFormat = pathFormat.Replace("{hh}", DateTime.Now.Hour.ToString("D2"));
        pathFormat = pathFormat.Replace("{ii}", DateTime.Now.Minute.ToString("D2"));
        pathFormat = pathFormat.Replace("{ss}", DateTime.Now.Second.ToString("D2"));
        return pathFormat + extension;
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/App_Code/UploadHandler.cs
New file
@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
/// <summary>
/// UploadHandler 的摘要说明
/// </summary>
public class UploadHandler : Handler
{
    public UploadConfig UploadConfig { get; private set; }
    public UploadResult Result { get; private set; }
    public UploadHandler(HttpContext context, UploadConfig config)
        : base(context)
    {
        this.UploadConfig = config;
        this.Result = new UploadResult() { State = UploadState.Unknown };
    }
    public override void Process()
    {
        byte[] uploadFileBytes = null;
        string uploadFileName = null;
        if (UploadConfig.Base64)
        {
            uploadFileName = UploadConfig.Base64Filename;
            uploadFileBytes = Convert.FromBase64String(Request[UploadConfig.UploadFieldName]);
        }
        else
        {
            var file = Request.Files[UploadConfig.UploadFieldName];
            uploadFileName = file.FileName;
            if (!CheckFileType(uploadFileName))
            {
                Result.State = UploadState.TypeNotAllow;
                WriteResult();
                return;
            }
            if (!CheckFileSize(file.ContentLength))
            {
                Result.State = UploadState.SizeLimitExceed;
                WriteResult();
                return;
            }
            uploadFileBytes = new byte[file.ContentLength];
            try
            {
                file.InputStream.Read(uploadFileBytes, 0, file.ContentLength);
            }
            catch (Exception)
            {
                Result.State = UploadState.NetworkError;
                WriteResult();
            }
        }
        Result.OriginFileName = uploadFileName;
        var savePath = PathFormatter.Format(uploadFileName, UploadConfig.PathFormat);
        var localPath = Server.MapPath(savePath);
        try
        {
            if (!Directory.Exists(Path.GetDirectoryName(localPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(localPath));
            }
            File.WriteAllBytes(localPath, uploadFileBytes);
            Result.Url = savePath;
            Result.State = UploadState.Success;
        }
        catch (Exception e)
        {
            Result.State = UploadState.FileAccessError;
            Result.ErrorMessage = e.Message;
        }
        finally
        {
            WriteResult();
        }
    }
    private void WriteResult()
    {
        this.WriteJson(new
        {
            state = GetStateMessage(Result.State),
            url = Result.Url,
            title = Result.OriginFileName,
            original = Result.OriginFileName,
            error = Result.ErrorMessage
        });
    }
    private string GetStateMessage(UploadState state)
    {
        switch (state)
        {
            case UploadState.Success:
                return "SUCCESS";
            case UploadState.FileAccessError:
                return "文件访问出错,请检查写入权限";
            case UploadState.SizeLimitExceed:
                return "文件大小超出服务器限制";
            case UploadState.TypeNotAllow:
                return "不允许的文件格式";
            case UploadState.NetworkError:
                return "网络错误";
        }
        return "未知错误";
    }
    private bool CheckFileType(string filename)
    {
        var fileExtension = Path.GetExtension(filename).ToLower();
        return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
    }
    private bool CheckFileSize(int size)
    {
        return size < UploadConfig.SizeLimit;
    }
}
public class UploadConfig
{
    /// <summary>
    /// 文件命名规则
    /// </summary>
    public string PathFormat { get; set; }
    /// <summary>
    /// 上传表单域名称
    /// </summary>
    public string UploadFieldName { get; set; }
    /// <summary>
    /// 上传大小限制
    /// </summary>
    public int SizeLimit { get; set; }
    /// <summary>
    /// 上传允许的文件格式
    /// </summary>
    public string[] AllowExtensions { get; set; }
    /// <summary>
    /// 文件是否以 Base64 的形式上传
    /// </summary>
    public bool Base64 { get; set; }
    /// <summary>
    /// Base64 字符串所表示的文件名
    /// </summary>
    public string Base64Filename { get; set; }
}
public class UploadResult
{
    public UploadState State { get; set; }
    public string Url { get; set; }
    public string OriginFileName { get; set; }
    public string ErrorMessage { get; set; }
}
public enum UploadState
{
    Success = 0,
    SizeLimitExceed = -1,
    TypeNotAllow = -2,
    FileAccessError = -3,
    NetworkError = -4,
    Unknown = 1,
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Bin/Newtonsoft.Json.dll
Binary files differ
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Bin/Newtonsoft.Json.pdb
Binary files differ
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Bin/Newtonsoft.Json.xml
New file
Diff too large
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/README.md
New file
@@ -0,0 +1,141 @@
UEditor ASP.NET 后台使用说明
=====
## 背景
UEditor 在 1.4 版本之后进行了一次[前后端统一配置](../_doc/3.1 后端请求规范.md)的整理,.Net 的后台也进行了一次重写,跟之前的版本差别较大,升级的用户注意阅读本文档。
本文档介绍 UEditor ASP.NET 后台的部署、配置、源码说明。
## 1. 部署说明
### 1.1. 安装并注册 .NET Framework 4.0
代码的运行时环境是 .NET Framework 4.0,首先要确认 IIS 已经安装了 .NET 4.0 的运行时框架。方法是打开「IIS 管理器」,选择根目录下的「应用程序池」,在右侧查看是否有一个应用程序池的版本是 v4.0,如果存在,则 IIS 已经安装了所需的运行时环境,此时读者可以跳过本节。
![检查 .NET 4.0 安装情况](../_doc/images/net-publish-1.png)
如果没有找到对应的应用程序池,需要手动安装。
Windows 7 和 Windows Server 2008 R2 默认安装了 .Net Framework 4.0,如果是 Server 03 和老掉牙的 Windows XP,则需要手动安装 [.NET Framework 4.0](http://www.microsoft.com/zh-cn/download/details.aspx?id=17718)。
安装完 .NET Framework 4.0 后,还需要向 IIS 注册应用程序池,注册的方法是,使用**管理员权限**打开命令提示符(CMD),输入以下命令:
```shell
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -i
```
安装完毕后,在 IIS 管理器刷新就能看到 4.0 的应用程序池。
### 1.2. 设置 .NET 应用程序
代码要求以应用程序的形式来运行(可以方便加入库依赖和组织代码)。需要把 `net` 目录转换为应用程序。
1. 在 IIS 中,展开到 `ueditor/net` 目录,在目录上右击,点击「转换为应用程序」。
   ![转换为应用程序](../_doc/images/net-publish-2.png)
2. 弹出的对话框中,点击「选择...」来指定使用的应用程序池。选择版本为 4.0 的应用程序池,然后点确定。
   ![选择应用程序池](../_doc/images/net-publish-3.png)
3. 设置连接凭据。点击「链接为...」按钮,在弹出的对话框中指定一个对目录具有读写权限的用户(如 administrator),然后点确定。
   ![设置连接凭据](../_doc/images/net-publish-4.png)
   设置完毕后,可以点击「测试设置...」来测试权限是否正常。
   ![设置连接凭据](../_doc/images/net-publish-5.png)
### 1.3. 运行测试
在浏览器中运行 `net/controller.ashx`,如果返回 "`{"state":"action 参数为空或者 action 不被支持。"}`",则表示应用程序运行成功。
如果你确认上述步骤已经执行,但是依然有问题,请给我们[提 Issue](https://github.com/fex-team/ueditor/issues/new?labels=NET%E5%90%8E%E5%8F%B0),我们会尽快答复解决。
## 2. 配置说明
前后端配置统一之后,配置文件由后台读取,返回给前端。但是部分配置是给后台使用的。
### 2.1. 上传配置说明
关于上传的部分,后台需要关心以下模板的配置项。
```json
{
    "{tpl}FieldName": "upfile",
    "{tpl}PathFormat": "upload/{tpl}/{yyyy}{mm}{dd}/{time}{rand:6}",
    "{tpl}UrlPrefix": "/ueditor/net/",
    "{tpl}AllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],
    "{tpl}MaxSize": 2048000
}
```
"{tpl}FieldName" 表示提交的表单的文件域名称。
"{tpl}PathFormat" 表示上传文件保存的路径和名称。注意,这里的路径是相对应用程序的,如果需要修改的话,请自行修改源码。
"{tpl}UrlPrefix" 表示上传文件访问的 URL 前缀。注意,这里应该给出应用程序的 URL 路径,否则上传的文件不能正确定位。
> 举个例子,如果你的 UEditor 的位置在 `http://www.mydomain.com/myapp/ueditor`,对应的本地路径是 `C:\iis_pub\www\myapp\ueditor`,那么 .NET 应用程序的位置在 `http://www.mydomain.com/myapp/ueditor/net`,对应的本地路径是 `C:\iis_pub\www\myapp\ueditor\net`。图片上传配置项应该如下:
>
> {
>    "imagePathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
>    "imageUrlPrefix": "/myapp/ueditor/net/",
> }
>
> 上传的文件会保存在 `C:\iis_pub\www\myapp\ueditor\net\upload\image\{日期}\{文件名}`
"{tpl}AllowFiles" 限制文件上传的类型,注意要有 "."。
"{tpl}MaxSize" 限制文件上传的大小。注意这里的限制是代码上的判断,应用程序本身还有一个请求报文大小限制。该限制在 web.config 文件中修改,注意要有以下的节:
```xml
<configuration>
  <system.web>
    <httpRuntime requestValidationMode="2.0" maxRequestLength="102400" />
  </system.web>
</configuration>
```
maxRequestLength 就是请求报文大小限制,该大小应该要比设置的所有上传大小都大,否则应用程序执行之前,请求会被被拒绝。
## 3. 源码说明
可以看到 net 目录内的源码结构是这样的:
```
net
    App_Code
        Config.cs
        Handler.cs
        PathFormatter.cs
        *Handler.cs
    Bin
        Newtonsoft.Json.dll
    config.json
    controller.ashx
    net.sln
    README.md
    Web.config
```
App_Code 上的文件是应用程序的源码。
- Config.cs 负责读取配置文件
- Handler.cs 是请求处理器的基类,提供了一些基本对象的访问以及输出控制。如果需要增加处理器,应该从该基类继承
- PathFormatter.cs 解析 PathFormat,把信息填充为运行时信息。
- *Handler.cs 是各种处理器,处理各种 UEditor 需要的请求。
Bin 里面的是应用程序的依赖库,当前依赖 Newtonsoft 的 Json 库。Bin 目录和 App_Code 目录受应用程序保护,不用担心被用户访问到。
config.json 是 UEditor 后端的配置文件,上一节已经介绍了比较重要的配置项。
controller.ashx 是 UEditor 请求的入口,它把不同的 action 分发到不同的 Handler 来处理。
net.sln 是项目的解决方案文件,安装 Visual Studio 2013 或以上的机器可以打开进行项目的改造。
README.md 是本说明文件。
Web.config 是应用程序的配置文件。
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/Web.config
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpRuntime requestValidationMode="2.0" maxRequestLength="102400 " />
    <pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"></pages>
    <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="zh-CN" />
  </system.web>
</configuration>
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/config.json
New file
@@ -0,0 +1,94 @@
/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
    /* 上传图片配置项 */
    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
    "imageFieldName": "upfile", /* 提交的图片表单名称 */
    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */
    "imagePathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                /* {time} 会替换成时间戳 */
                                /* {yyyy} 会替换成四位年份 */
                                /* {yy} 会替换成两位年份 */
                                /* {mm} 会替换成两位月份 */
                                /* {dd} 会替换成两位日期 */
                                /* {hh} 会替换成两位小时 */
                                /* {ii} 会替换成两位分钟 */
                                /* {ss} 会替换成两位秒 */
                                /* 非法字符 \ : * ? " < > | */
                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
    /* 涂鸦图片上传配置项 */
    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
    "scrawlPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
    "scrawlUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */
    "scrawlInsertAlign": "none",
    /* 截图工具上传 */
    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
    "snapscreenPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "snapscreenUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */
    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
    /* 抓取远程图片配置 */
    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
    "catcherPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "catcherUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */
    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
    /* 上传视频配置 */
    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
    "videoFieldName": "upfile", /* 提交的视频表单名称 */
    "videoPathFormat": "upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "videoUrlPrefix": "/ueditor/net/", /* 视频访问路径前缀 */
    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
    /* 上传文件配置 */
    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
    "fileFieldName": "upfile", /* 提交的文件表单名称 */
    "filePathFormat": "upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "fileUrlPrefix": "/ueditor/net/", /* 文件访问路径前缀 */
    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ], /* 上传文件格式显示 */
    /* 列出指定目录下的图片 */
    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
    "imageManagerListPath": "upload/image", /* 指定要列出图片的目录 */
    "imageManagerListSize": 20, /* 每次列出文件数量 */
    "imageManagerUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */
    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
    /* 列出指定目录下的文件 */
    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
    "fileManagerListPath": "upload/file", /* 指定要列出文件的目录 */
    "fileManagerUrlPrefix": "/ueditor/net/", /* 文件访问路径前缀 */
    "fileManagerListSize": 20, /* 每次列出文件数量 */
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ] /* 列出的文件类型 */
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/controller.ashx
New file
@@ -0,0 +1,80 @@
<%@ WebHandler Language="C#" Class="UEditorHandler" %>
using System;
using System.Web;
using System.IO;
using System.Collections;
using Newtonsoft.Json;
public class UEditorHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        Handler action = null;
        switch (context.Request["action"])
        {
            case "config":
                action = new ConfigHandler(context);
                break;
            case "uploadimage":
                action = new UploadHandler(context, new UploadConfig()
                {
                    AllowExtensions = Config.GetStringList("imageAllowFiles"),
                    PathFormat = Config.GetString("imagePathFormat"),
                    SizeLimit = Config.GetInt("imageMaxSize"),
                    UploadFieldName = Config.GetString("imageFieldName")
                });
                break;
            case "uploadscrawl":
                action = new UploadHandler(context, new UploadConfig()
                {
                    AllowExtensions = new string[] { ".png" },
                    PathFormat = Config.GetString("scrawlPathFormat"),
                    SizeLimit = Config.GetInt("scrawlMaxSize"),
                    UploadFieldName = Config.GetString("scrawlFieldName"),
                    Base64 = true,
                    Base64Filename = "scrawl.png"
                });
                break;
            case "uploadvideo":
                action = new UploadHandler(context, new UploadConfig()
                {
                    AllowExtensions = Config.GetStringList("videoAllowFiles"),
                    PathFormat = Config.GetString("videoPathFormat"),
                    SizeLimit = Config.GetInt("videoMaxSize"),
                    UploadFieldName = Config.GetString("videoFieldName")
                });
                break;
            case "uploadfile":
                action = new UploadHandler(context, new UploadConfig()
                {
                    AllowExtensions = Config.GetStringList("fileAllowFiles"),
                    PathFormat = Config.GetString("filePathFormat"),
                    SizeLimit = Config.GetInt("fileMaxSize"),
                    UploadFieldName = Config.GetString("fileFieldName")
                });
                break;
            case "listimage":
                action = new ListFileManager(context, Config.GetString("imageManagerListPath"), Config.GetStringList("imageManagerAllowFiles"));
                break;
            case "listfile":
                action = new ListFileManager(context, Config.GetString("fileManagerListPath"), Config.GetStringList("fileManagerAllowFiles"));
                break;
            case "catchimage":
                action = new CrawlerHandler(context);
                break;
            default:
                action = new NotSupportedHandler(context);
                break;
        }
        action.Process();
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/net/net.sln
New file
@@ -0,0 +1,38 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "net", "http://localhost:7957", "{36F65A7F-64E7-4E05-BBC2-EAB6E4EDAF30}"
    ProjectSection(WebsiteProperties) = preProject
        UseIISExpress = "true"
        TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
        Debug.AspNetCompiler.VirtualPath = "/localhost_7957"
        Debug.AspNetCompiler.PhysicalPath = "..\..\..\..\prj\ueditor\net\"
        Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_7957\"
        Debug.AspNetCompiler.Updateable = "true"
        Debug.AspNetCompiler.ForceOverwrite = "true"
        Debug.AspNetCompiler.FixedNames = "false"
        Debug.AspNetCompiler.Debug = "True"
        Release.AspNetCompiler.VirtualPath = "/localhost_7957"
        Release.AspNetCompiler.PhysicalPath = "..\..\..\..\prj\ueditor\net\"
        Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_7957\"
        Release.AspNetCompiler.Updateable = "true"
        Release.AspNetCompiler.ForceOverwrite = "true"
        Release.AspNetCompiler.FixedNames = "false"
        Release.AspNetCompiler.Debug = "False"
        SlnRelativePath = "..\..\..\..\prj\ueditor\net\"
    EndProjectSection
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {36F65A7F-64E7-4E05-BBC2-EAB6E4EDAF30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {36F65A7F-64E7-4E05-BBC2-EAB6E4EDAF30}.Debug|Any CPU.Build.0 = Debug|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
EndGlobal
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/Uploader.class.php
New file
@@ -0,0 +1,349 @@
<?php
/**
 * Created by JetBrains PhpStorm.
 * User: taoqili
 * Date: 12-7-18
 * Time: 上午11: 32
 * UEditor编辑器通用上传类
 */
class Uploader
{
    private $fileField; //文件域名
    private $file; //文件上传对象
    private $base64; //文件上传对象
    private $config; //配置信息
    private $oriName; //原始文件名
    private $fileName; //新文件名
    private $fullName; //完整文件名,即从当前配置目录开始的URL
    private $filePath; //完整文件名,即从当前配置目录开始的URL
    private $fileSize; //文件大小
    private $fileType; //文件类型
    private $stateInfo; //上传状态信息,
    private $stateMap = array( //上传状态映射表,国际化用户需考虑此处数据的国际化
        "SUCCESS", //上传成功标记,在UEditor中内不可改变,否则flash判断会出错
        "文件大小超出 upload_max_filesize 限制",
        "文件大小超出 MAX_FILE_SIZE 限制",
        "文件未被完整上传",
        "没有文件被上传",
        "上传文件为空",
        "ERROR_TMP_FILE" => "临时文件错误",
        "ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
        "ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
        "ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
        "ERROR_CREATE_DIR" => "目录创建失败",
        "ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
        "ERROR_FILE_MOVE" => "文件保存时出错",
        "ERROR_FILE_NOT_FOUND" => "找不到上传文件",
        "ERROR_WRITE_CONTENT" => "写入文件内容错误",
        "ERROR_UNKNOWN" => "未知错误",
        "ERROR_DEAD_LINK" => "链接不可用",
        "ERROR_HTTP_LINK" => "链接不是http链接",
        "ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确"
    );
    /**
     * 构造函数
     * @param string $fileField 表单名称
     * @param array $config 配置项
     * @param bool $base64 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名
     */
    public function __construct($fileField, $config, $type = "upload")
    {
        $this->fileField = $fileField;
        $this->config = $config;
        $this->type = $type;
        if ($type == "remote") {
            $this->saveRemote();
        } else if($type == "base64") {
            $this->upBase64();
        } else {
            $this->upFile();
        }
        $this->stateMap['ERROR_TYPE_NOT_ALLOWED'] = iconv('unicode', 'utf-8', $this->stateMap['ERROR_TYPE_NOT_ALLOWED']);
    }
    /**
     * 上传文件的主处理方法
     * @return mixed
     */
    private function upFile()
    {
        $file = $this->file = $_FILES[$this->fileField];
        if (!$file) {
            $this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");
            return;
        }
        if ($this->file['error']) {
            $this->stateInfo = $this->getStateInfo($file['error']);
            return;
        } else if (!file_exists($file['tmp_name'])) {
            $this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
            return;
        } else if (!is_uploaded_file($file['tmp_name'])) {
            $this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");
            return;
        }
        $this->oriName = $file['name'];
        $this->fileSize = $file['size'];
        $this->fileType = $this->getFileExt();
        $this->fullName = $this->getFullName();
        $this->filePath = $this->getFilePath();
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);
        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
            return;
        }
        //检查是否不允许的文件格式
        if (!$this->checkType()) {
            $this->stateInfo = $this->getStateInfo("ERROR_TYPE_NOT_ALLOWED");
            return;
        }
        //创建目录失败
        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
            $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
            return;
        } else if (!is_writeable($dirname)) {
            $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
            return;
        }
        //移动文件
        if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) { //移动失败
            $this->stateInfo = $this->getStateInfo("ERROR_FILE_MOVE");
        } else { //移动成功
            $this->stateInfo = $this->stateMap[0];
        }
    }
    /**
     * 处理base64编码的图片上传
     * @return mixed
     */
    private function upBase64()
    {
        $base64Data = $_POST[$this->fileField];
        $img = base64_decode($base64Data);
        $this->oriName = $this->config['oriName'];
        $this->fileSize = strlen($img);
        $this->fileType = $this->getFileExt();
        $this->fullName = $this->getFullName();
        $this->filePath = $this->getFilePath();
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);
        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
            return;
        }
        //创建目录失败
        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
            $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
            return;
        } else if (!is_writeable($dirname)) {
            $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
            return;
        }
        //移动文件
        if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
            $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
        } else { //移动成功
            $this->stateInfo = $this->stateMap[0];
        }
    }
    /**
     * 拉取远程图片
     * @return mixed
     */
    private function saveRemote()
    {
        $imgUrl = htmlspecialchars($this->fileField);
        $imgUrl = str_replace("&amp;", "&", $imgUrl);
        //http开头验证
        if (strpos($imgUrl, "http") !== 0) {
            $this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
            return;
        }
        //获取请求头并检测死链
        $heads = get_headers($imgUrl);
        if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
            $this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
            return;
        }
        //格式验证(扩展名验证和Content-Type验证)
        $fileType = strtolower(strrchr($imgUrl, '.'));
        if (!in_array($fileType, $this->config['allowFiles']) || stristr($heads['Content-Type'], "image")) {
            $this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
            return;
        }
        //打开输出缓冲区并获取远程图片
        ob_start();
        $context = stream_context_create(
            array('http' => array(
                'follow_location' => false // don't follow redirects
            ))
        );
        readfile($imgUrl, false, $context);
        $img = ob_get_contents();
        ob_end_clean();
        preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
        $this->oriName = $m ? $m[1]:"";
        $this->fileSize = strlen($img);
        $this->fileType = $this->getFileExt();
        $this->fullName = $this->getFullName();
        $this->filePath = $this->getFilePath();
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);
        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
            return;
        }
        //创建目录失败
        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
            $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
            return;
        } else if (!is_writeable($dirname)) {
            $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
            return;
        }
        //移动文件
        if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
            $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
        } else { //移动成功
            $this->stateInfo = $this->stateMap[0];
        }
    }
    /**
     * 上传错误检查
     * @param $errCode
     * @return string
     */
    private function getStateInfo($errCode)
    {
        return !$this->stateMap[$errCode] ? $this->stateMap["ERROR_UNKNOWN"] : $this->stateMap[$errCode];
    }
    /**
     * 获取文件扩展名
     * @return string
     */
    private function getFileExt()
    {
        return strtolower(strrchr($this->oriName, '.'));
    }
    /**
     * 重命名文件
     * @return string
     */
    private function getFullName()
    {
        //替换日期事件
        $t = time();
        $d = explode('-', date("Y-y-m-d-H-i-s"));
        $format = $this->config["pathFormat"];
        $format = str_replace("{yyyy}", $d[0], $format);
        $format = str_replace("{yy}", $d[1], $format);
        $format = str_replace("{mm}", $d[2], $format);
        $format = str_replace("{dd}", $d[3], $format);
        $format = str_replace("{hh}", $d[4], $format);
        $format = str_replace("{ii}", $d[5], $format);
        $format = str_replace("{ss}", $d[6], $format);
        $format = str_replace("{time}", $t, $format);
        //过滤文件名的非法自负,并替换文件名
        $oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));
        $oriName = preg_replace("/[\|\?\"\<\>\/\*\\\\]+/", '', $oriName);
        $format = str_replace("{filename}", $oriName, $format);
        //替换随机字符串
        $randNum = rand(1, 10000000000) . rand(1, 10000000000);
        if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
            $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
        }
        $ext = $this->getFileExt();
        return $format . $ext;
    }
    /**
     * 获取文件名
     * @return string
     */
    private function getFileName () {
        return substr($this->filePath, strrpos($this->filePath, '/') + 1);
    }
    /**
     * 获取文件完整路径
     * @return string
     */
    private function getFilePath()
    {
        $fullname = $this->fullName;
        $rootPath = $_SERVER['DOCUMENT_ROOT'];
        if (substr($fullname, 0, 1) != '/') {
            $fullname = '/' . $fullname;
        }
        return $rootPath . $fullname;
    }
    /**
     * 文件类型检测
     * @return bool
     */
    private function checkType()
    {
        return in_array($this->getFileExt(), $this->config["allowFiles"]);
    }
    /**
     * 文件大小检测
     * @return bool
     */
    private function  checkSize()
    {
        return $this->fileSize <= ($this->config["maxSize"]);
    }
    /**
     * 获取当前上传成功文件的各项信息
     * @return array
     */
    public function getFileInfo()
    {
        return array(
            "state" => $this->stateInfo,
            "url" => $this->fullName,
            "title" => $this->fileName,
            "original" => $this->oriName,
            "type" => $this->fileType,
            "size" => $this->fileSize
        );
    }
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/action_crawler.php
New file
@@ -0,0 +1,44 @@
<?php
/**
 * 抓取远程图片
 * User: Jinqn
 * Date: 14-04-14
 * Time: 下午19:18
 */
set_time_limit(0);
include("Uploader.class.php");
/* 上传配置 */
$config = array(
    "pathFormat" => $CONFIG['catcherPathFormat'],
    "maxSize" => $CONFIG['catcherMaxSize'],
    "allowFiles" => $CONFIG['catcherAllowFiles'],
    "oriName" => "remote.png"
);
$fieldName = $CONFIG['catcherFieldName'];
/* 抓取远程图片 */
$list = array();
if (isset($_POST[$fieldName])) {
    $source = $_POST[$fieldName];
} else {
    $source = $_GET[$fieldName];
}
foreach ($source as $imgUrl) {
    $item = new Uploader($imgUrl, $config, "remote");
    $info = $item->getFileInfo();
    array_push($list, array(
        "state" => $info["state"],
        "url" => $info["url"],
        "size" => $info["size"],
        "title" => htmlspecialchars($info["title"]),
        "original" => htmlspecialchars($info["original"]),
        "source" => htmlspecialchars($imgUrl)
    ));
}
/* 返回抓取数据 */
return json_encode(array(
    'state'=> count($list) ? 'SUCCESS':'ERROR',
    'list'=> $list
));
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/action_list.php
New file
@@ -0,0 +1,92 @@
<?php
/**
 * 获取已上传的文件列表
 * User: Jinqn
 * Date: 14-04-09
 * Time: 上午10:17
 */
include "Uploader.class.php";
/* 判断类型 */
switch ($_GET['action']) {
    /* 列出文件 */
    case 'listfile':
        $allowFiles = $CONFIG['fileManagerAllowFiles'];
        $listSize = $CONFIG['fileManagerListSize'];
        $path = $CONFIG['fileManagerListPath'];
        break;
    /* 列出图片 */
    case 'listimage':
    default:
        $allowFiles = $CONFIG['imageManagerAllowFiles'];
        $listSize = $CONFIG['imageManagerListSize'];
        $path = $CONFIG['imageManagerListPath'];
}
$allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1);
/* 获取参数 */
$size = isset($_GET['size']) ? htmlspecialchars($_GET['size']) : $listSize;
$start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0;
$end = $start + $size;
/* 获取文件列表 */
$path = $_SERVER['DOCUMENT_ROOT'] . (substr($path, 0, 1) == "/" ? "":"/") . $path;
$files = getfiles($path, $allowFiles);
if (!count($files)) {
    return json_encode(array(
        "state" => "no match file",
        "list" => array(),
        "start" => $start,
        "total" => count($files)
    ));
}
/* 获取指定范围的列表 */
$len = count($files);
for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
    $list[] = $files[$i];
}
//倒序
//for ($i = $end, $list = array(); $i < $len && $i < $end; $i++){
//    $list[] = $files[$i];
//}
/* 返回数据 */
$result = json_encode(array(
    "state" => "SUCCESS",
    "list" => $list,
    "start" => $start,
    "total" => count($files)
));
return $result;
/**
 * 遍历获取目录下的指定类型的文件
 * @param $path
 * @param array $files
 * @return array
 */
function getfiles($path, $allowFiles, &$files = array())
{
    if (!is_dir($path)) return null;
    if(substr($path, strlen($path) - 1) != '/') $path .= '/';
    $handle = opendir($path);
    while (false !== ($file = readdir($handle))) {
        if ($file != '.' && $file != '..') {
            $path2 = $path . $file;
            if (is_dir($path2)) {
                getfiles($path2, $allowFiles, $files);
            } else {
                if (preg_match("/\.(".$allowFiles.")$/i", $file)) {
                    $files[] = array(
                        'url'=> substr($path2, strlen($_SERVER['DOCUMENT_ROOT'])),
                        'mtime'=> filemtime($path2)
                    );
                }
            }
        }
    }
    return $files;
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/action_upload.php
New file
@@ -0,0 +1,66 @@
<?php
/**
 * 上传附件和上传视频
 * User: Jinqn
 * Date: 14-04-09
 * Time: 上午10:17
 */
include "Uploader.class.php";
/* 上传配置 */
$base64 = "upload";
switch (htmlspecialchars($_GET['action'])) {
    case 'uploadimage':
        $config = array(
            "pathFormat" => $CONFIG['imagePathFormat'],
            "maxSize" => $CONFIG['imageMaxSize'],
            "allowFiles" => $CONFIG['imageAllowFiles']
        );
        $fieldName = $CONFIG['imageFieldName'];
        break;
    case 'uploadscrawl':
        $config = array(
            "pathFormat" => $CONFIG['scrawlPathFormat'],
            "maxSize" => $CONFIG['scrawlMaxSize'],
            "allowFiles" => $CONFIG['scrawlAllowFiles'],
            "oriName" => "scrawl.png"
        );
        $fieldName = $CONFIG['scrawlFieldName'];
        $base64 = "base64";
        break;
    case 'uploadvideo':
        $config = array(
            "pathFormat" => $CONFIG['videoPathFormat'],
            "maxSize" => $CONFIG['videoMaxSize'],
            "allowFiles" => $CONFIG['videoAllowFiles']
        );
        $fieldName = $CONFIG['videoFieldName'];
        break;
    case 'uploadfile':
    default:
        $config = array(
            "pathFormat" => $CONFIG['filePathFormat'],
            "maxSize" => $CONFIG['fileMaxSize'],
            "allowFiles" => $CONFIG['fileAllowFiles']
        );
        $fieldName = $CONFIG['fileFieldName'];
        break;
}
/* 生成上传实例对象并完成上传 */
$up = new Uploader($fieldName, $config, $base64);
/**
 * 得到上传文件所对应的各个参数,数组结构
 * array(
 *     "state" => "",          //上传状态,上传成功时必须返回"SUCCESS"
 *     "url" => "",            //返回的地址
 *     "title" => "",          //新文件名
 *     "original" => "",       //原始文件名
 *     "type" => ""            //文件类型
 *     "size" => "",           //文件大小
 * )
 */
/* 返回数据 */
return json_encode($up->getFileInfo());
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/config.json
New file
@@ -0,0 +1,94 @@
/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
    /* 上传图片配置项 */
    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
    "imageFieldName": "upfile", /* 提交的图片表单名称 */
    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageUrlPrefix": "", /* 图片访问路径前缀 */
    "imagePathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                /* {time} 会替换成时间戳 */
                                /* {yyyy} 会替换成四位年份 */
                                /* {yy} 会替换成两位年份 */
                                /* {mm} 会替换成两位月份 */
                                /* {dd} 会替换成两位日期 */
                                /* {hh} 会替换成两位小时 */
                                /* {ii} 会替换成两位分钟 */
                                /* {ss} 会替换成两位秒 */
                                /* 非法字符 \ : * ? " < > | */
                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
    /* 涂鸦图片上传配置项 */
    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
    "scrawlPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
    "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
    "scrawlInsertAlign": "none",
    /* 截图工具上传 */
    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
    "snapscreenPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
    /* 抓取远程图片配置 */
    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
    "catcherPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "catcherUrlPrefix": "", /* 图片访问路径前缀 */
    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
    /* 上传视频配置 */
    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
    "videoFieldName": "upfile", /* 提交的视频表单名称 */
    "videoPathFormat": "/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "videoUrlPrefix": "", /* 视频访问路径前缀 */
    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
    /* 上传文件配置 */
    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
    "fileFieldName": "upfile", /* 提交的文件表单名称 */
    "filePathFormat": "/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "fileUrlPrefix": "", /* 文件访问路径前缀 */
    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ], /* 上传文件格式显示 */
    /* 列出指定目录下的图片 */
    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
    "imageManagerListPath": "/ueditor/php/upload/image/", /* 指定要列出图片的目录 */
    "imageManagerListSize": 20, /* 每次列出文件数量 */
    "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
    /* 列出指定目录下的文件 */
    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
    "fileManagerListPath": "/ueditor/php/upload/file/", /* 指定要列出文件的目录 */
    "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
    "fileManagerListSize": 20, /* 每次列出文件数量 */
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ] /* 列出的文件类型 */
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/php/controller.php
New file
@@ -0,0 +1,59 @@
<?php
//header('Access-Control-Allow-Origin: http://www.baidu.com'); //设置http://www.baidu.com允许跨域访问
//header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With'); //设置允许的跨域header
date_default_timezone_set("Asia/Chongqing");
error_reporting(E_ERROR);
header("Content-Type: text/html; charset=utf-8");
$CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents("config.json")), true);
$action = $_GET['action'];
switch ($action) {
    case 'config':
        $result =  json_encode($CONFIG);
        break;
    /* 上传图片 */
    case 'uploadimage':
    /* 上传涂鸦 */
    case 'uploadscrawl':
    /* 上传视频 */
    case 'uploadvideo':
    /* 上传文件 */
    case 'uploadfile':
        $result = include("action_upload.php");
        break;
    /* 列出图片 */
    case 'listimage':
        $result = include("action_list.php");
        break;
    /* 列出文件 */
    case 'listfile':
        $result = include("action_list.php");
        break;
    /* 抓取远程文件 */
    case 'catchimage':
        $result = include("action_crawler.php");
        break;
    default:
        $result = json_encode(array(
            'state'=> '请求地址出错'
        ));
        break;
}
/* 输出结果 */
if (isset($_GET["callback"])) {
    if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
        echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
    } else {
        echo json_encode(array(
            'state'=> 'callback参数不合法'
        ));
    }
} else {
    echo $result;
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/css/ueditor.css
New file
@@ -0,0 +1,1903 @@
/*基础UI构建
*/
/* common layer */
.edui-default .edui-box {
    border: none;
    padding: 0;
    margin: 0;
    overflow: hidden;
}
.edui-default a.edui-box {
    display: block;
    text-decoration: none;
    color: black;
}
.edui-default a.edui-box:hover {
    text-decoration: none;
}
.edui-default a.edui-box:active {
    text-decoration: none;
}
.edui-default table.edui-box {
    border-collapse: collapse;
}
.edui-default ul.edui-box {
    list-style-type: none;
}
div.edui-box {
    position: relative;
    display: -moz-inline-box !important;
    display: inline-block !important;
    vertical-align: top;
}
.edui-default .edui-clearfix {
    zoom: 1
}
.edui-default .edui-clearfix:after {
    content: '\20';
    display: block;
    clear: both;
}
 * html div.edui-box {
    display: inline !important;
}
*:first-child+html div.edui-box {
    display: inline !important;
}
/* control layout */
.edui-default .edui-button-body, .edui-splitbutton-body, .edui-menubutton-body, .edui-combox-body {
    position: relative;
}
.edui-default .edui-popup {
    position: absolute;
    -webkit-user-select: none;
    -moz-user-select: none;
}
.edui-default .edui-popup .edui-shadow {
    position: absolute;
    z-index: -1;
}
.edui-default .edui-popup .edui-bordereraser {
    position: absolute;
    overflow: hidden;
}
.edui-default .edui-tablepicker .edui-canvas {
    position: relative;
}
.edui-default .edui-tablepicker .edui-canvas .edui-overlay {
    position: absolute;
}
.edui-default .edui-dialog-modalmask, .edui-dialog-dragmask {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
.edui-default .edui-toolbar {
    position: relative;
}
/*
 * default theme
 */
.edui-default .edui-label {
    cursor: default;
}
.edui-default span.edui-clickable {
    color: blue;
    cursor: pointer;
    text-decoration: underline;
}
.edui-default span.edui-unclickable {
    color: gray;
    cursor: default;
}
/* 工具栏 */
.edui-default .edui-toolbar {
    cursor: default;
    -webkit-user-select: none;
    -moz-user-select: none;
    padding: 1px;
    overflow: hidden; /*全屏下单独一行不占位*/
    zoom: 1;
    width:auto;
    height:auto;
}
.edui-default .edui-toolbar .edui-button,
.edui-default .edui-toolbar .edui-splitbutton,
.edui-default .edui-toolbar .edui-menubutton,
.edui-default .edui-toolbar .edui-combox {
    margin: 1px;
}
/*UI工具栏、编辑区域、底部*/
.edui-default .edui-editor {
    border: 1px solid #d4d4d4;
    background-color: white;
    position: relative;
    overflow: visible;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
}
.edui-editor div{
    width:auto;
    height:auto;
}
.edui-default .edui-editor-toolbarbox {
    position: relative;
    zoom: 1;
    -webkit-box-shadow:0 1px 4px rgba(204, 204, 204, 0.6);
    -moz-box-shadow:0 1px 4px rgba(204, 204, 204, 0.6);
    box-shadow:0 1px 4px rgba(204, 204, 204, 0.6);
    border-top-left-radius:2px;
    border-top-right-radius:2px;
}
.edui-default .edui-editor-toolbarboxouter {
    border-bottom: 1px solid #d4d4d4;
    background-color: #fafafa;
    background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);
    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));
    background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);
    background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);
    background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);
    background-repeat: repeat-x;
    /*border: 1px solid #d4d4d4;*/
    -webkit-border-radius: 4px 4px 0 0;
    -moz-border-radius: 4px 4px 0 0;
    border-radius: 4px 4px 0 0;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);
    *zoom: 1;
    -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
    -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
}
.edui-default .edui-editor-toolbarboxinner {
    padding: 2px;
}
.edui-default .edui-editor-iframeholder {
    position: relative;
    /*for fix ie6 toolbarmsg under iframe bug. relative -> static */
    /*_position: static !important;*
}
.edui-default .edui-editor-iframeholder textarea {
    font-family: consolas, "Courier New", "lucida console", monospace;
    font-size: 12px;
    line-height: 18px;
}
.edui-default .edui-editor-bottombar {
    /*border-top: 1px solid #ccc;*/
    /*height: 20px;*/
    /*width: 40%;*/
    /*float: left;*/
    /*overflow: hidden;*/
}
.edui-default .edui-editor-bottomContainer {
    overflow: hidden;
}
.edui-default .edui-editor-bottomContainer table {
    width: 100%;
    height: 0;
    overflow: hidden;
    border-spacing: 0;
}
.edui-default .edui-editor-bottomContainer td {
    white-space: nowrap;
    border-top: 1px solid #ccc;
    line-height: 20px;
    font-size: 12px;
    font-family: Arial, Helvetica, Tahoma, Verdana, Sans-Serif;
}
.edui-default .edui-editor-wordcount {
    text-align: right;
    margin-right: 5px;
    color: #aaa;
}
.edui-default .edui-editor-scale {
    width: 12px;
}
.edui-default .edui-editor-scale .edui-editor-icon {
    float: right;
    width: 100%;
    height: 12px;
    margin-top: 10px;
    background: url(../images/scale.png) no-repeat;
    cursor: se-resize;
}
.edui-default .edui-editor-breadcrumb {
    margin: 2px 0 0 3px;
}
.edui-default .edui-editor-breadcrumb span {
    cursor: pointer;
    text-decoration: underline;
    color: blue;
}
.edui-default .edui-toolbar .edui-for-fullscreen {
    float: right;
}
.edui-default .edui-bubble .edui-popup-content {
    border: 1px solid #DCAC6C;
    background-color: #fff6d9;
    padding: 5px;
    font-size: 10pt;
    font-family: "宋体";
}
.edui-default .edui-bubble .edui-shadow {
    /*box-shadow: 1px 1px 3px #818181;*/
    /*-webkit-box-shadow: 2px 2px 3px #818181;*/
    /*-moz-box-shadow: 2px 2px 3px #818181;*/
    /*filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius = '2', MakeShadow = 'true', ShadowOpacity = '0.5');*/
}
.edui-default .edui-editor-toolbarmsg {
    background-color: #FFF6D9;
    border-bottom: 1px solid #ccc;
    position: absolute;
    bottom: -25px;
    left: 0;
    z-index: 1009;
    width: 99.9%;
}
.edui-default .edui-editor-toolbarmsg-upload {
    font-size: 14px;
    color: blue;
    width: 100px;
    height: 16px;
    line-height: 16px;
    cursor: pointer;
    position: absolute;
    top: 5px;
    left: 350px;
}
.edui-default .edui-editor-toolbarmsg-label {
    font-size: 12px;
    line-height: 16px;
    padding: 4px;
}
.edui-default .edui-editor-toolbarmsg-close {
    float: right;
    width: 20px;
    height: 16px;
    line-height: 16px;
    cursor: pointer;
    color: red;
}
/*可选中菜单按钮*/
.edui-default .edui-list .edui-bordereraser {
    display: none;
}
.edui-default .edui-listitem {
    padding: 1px;
    white-space: nowrap;
}
.edui-default .edui-list .edui-state-hover {
    position: relative;
    background-color: #fff5d4;
    border: 1px solid #dcac6c;
    padding: 0;
}
.edui-default .edui-for-fontfamily .edui-listitem-label {
    min-width: 130px;
    _width: 120px;
    font-size: 12px;
    height: 22px;
    line-height: 22px;
    padding-left: 5px;
}
.edui-default .edui-for-insertcode .edui-listitem-label {
    min-width: 120px;
    _width: 120px;
    font-size: 12px;
    height: 22px;
    line-height: 22px;
    padding-left: 5px;
}
.edui-default .edui-for-underline .edui-listitem-label {
    min-width: 120px;
    _width: 120px;
    padding: 3px 5px;
    font-size: 12px;
}
.edui-default .edui-for-fontsize .edui-listitem-label {
    min-width: 120px;
    _width: 120px;
    padding: 3px 5px;
}
.edui-default .edui-for-paragraph .edui-listitem-label {
    min-width: 200px;
    _width: 200px;
    padding: 2px 5px;
}
.edui-default .edui-for-rowspacingtop .edui-listitem-label,
.edui-default .edui-for-rowspacingbottom .edui-listitem-label {
    min-width: 53px;
    _width: 53px;
    padding: 2px 5px;
}
.edui-default .edui-for-lineheight .edui-listitem-label {
    min-width: 53px;
    _width: 53px;
    padding: 2px 5px;
}
.edui-default .edui-for-customstyle .edui-listitem-label {
    min-width: 200px;
    _width: 200px;
    width: 200px !important;
    padding: 2px 5px;
}
/* 可选中按钮弹出菜单*/
.edui-default .edui-menu {
    z-index: 3000;
}
.edui-default .edui-menu .edui-popup-content {
    padding: 3px;
}
.edui-default .edui-menu-body {
    _width: 150px;
    min-width: 170px;
    background: url("../images/sparator_v.png") repeat-y 25px;
}
.edui-default .edui-menuitem-body {
}
.edui-default .edui-menuitem {
    height: 20px;
    cursor: default;
    vertical-align: top;
}
.edui-default .edui-menuitem .edui-icon {
    width: 20px !important;
    height: 20px !important;
    background: url(../images/icons.png) 0 -4000px;
    background: url(../images/icons.gif) 0 -4000px\9;
}
.edui-default .edui-menuitem .edui-label {
    font-size: 12px;
    line-height: 20px;
    height: 20px;
    padding-left: 10px;
}
.edui-default .edui-state-checked .edui-menuitem-body {
    background: url("../images/icons-all.gif") no-repeat 6px -205px;
}
.edui-default .edui-state-disabled .edui-menuitem-label {
    color: gray;
}
/*不可选中菜单按钮 */
.edui-default .edui-toolbar .edui-combox-body .edui-button-body {
    width: 60px;
    font-size: 12px;
    height: 20px;
    line-height: 20px;
    padding-left: 5px;
    white-space: nowrap;
    margin: 0 3px 0 0;
}
.edui-default .edui-toolbar .edui-combox-body .edui-arrow {
    background: url(../images/icons.png) -741px 0;
    _background: url(../images/icons.gif) -741px 0;
    height: 20px;
    width: 9px;
}
.edui-default .edui-toolbar .edui-combox .edui-combox-body {
    border: 1px solid #CCC;
    background-color: white;
    border-radius: 2px;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
}
.edui-default .edui-toolbar .edui-combox-body .edui-splitborder {
    display: none;
}
.edui-default .edui-toolbar .edui-combox-body .edui-arrow {
    border-left: 1px solid #CCC;
}
.edui-default .edui-toolbar .edui-state-hover .edui-combox-body {
    background-color: #fff5d4;
    border: 1px solid #dcac6c;
}
.edui-default .edui-toolbar .edui-state-hover .edui-combox-body .edui-arrow {
    border-left: 1px solid #dcac6c;
}
.edui-default .edui-toolbar .edui-state-checked .edui-combox-body {
    background-color: #FFE69F;
    border: 1px solid #DCAC6C;
}
.edui-toolbar .edui-state-checked .edui-combox-body .edui-arrow {
    border-left: 1px solid #DCAC6C;
}
.edui-toolbar .edui-state-disabled .edui-combox-body {
    background-color: #F0F0EE;
    opacity: 0.3;
    filter: alpha(opacity = 30);
}
.edui-toolbar .edui-state-opened .edui-combox-body {
    background-color: white;
    border: 1px solid gray;
}
/*普通按钮样式及状态*/
.edui-default .edui-toolbar .edui-button .edui-icon,
.edui-default .edui-toolbar .edui-menubutton .edui-icon,
.edui-default .edui-toolbar .edui-splitbutton .edui-icon {
    height: 20px !important;
    width: 20px !important;
    background-image: url(../images/icons.png);
    background-image: url(../images/icons.gif) \9;
}
.edui-default .edui-toolbar .edui-button .edui-button-wrap {
    padding: 1px;
    position: relative;
}
.edui-default .edui-toolbar .edui-button .edui-state-hover .edui-button-wrap {
    background-color: #fff5d4;
    padding: 0;
    border: 1px solid #dcac6c;
}
.edui-default .edui-toolbar .edui-button .edui-state-checked .edui-button-wrap {
    background-color: #ffe69f;
    padding: 0;
    border: 1px solid #dcac6c;
    border-radius: 2px;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
}
.edui-default .edui-toolbar .edui-button .edui-state-active .edui-button-wrap {
    background-color: #ffffff;
    padding: 0;
    border: 1px solid gray;
}
.edui-default .edui-toolbar .edui-state-disabled .edui-label {
    color: #ccc;
}
.edui-default .edui-toolbar .edui-state-disabled .edui-icon {
    opacity: 0.3;
    filter: alpha(opacity = 30);
}
/* toolbar icons */
.edui-default .edui-for-undo .edui-icon {
    background-position: -160px 0;
}
.edui-default  .edui-for-redo .edui-icon {
    background-position: -100px 0;
}
.edui-default  .edui-for-bold .edui-icon {
    background-position: 0 0;
}
.edui-default  .edui-for-italic .edui-icon {
    background-position: -60px 0;
}
.edui-default  .edui-for-fontborder .edui-icon {
    background-position:-160px -40px;
}
.edui-default  .edui-for-underline .edui-icon {
    background-position: -140px 0;
}
.edui-default  .edui-for-strikethrough .edui-icon {
    background-position: -120px 0;
}
.edui-default  .edui-for-subscript .edui-icon {
    background-position: -600px 0;
}
.edui-default  .edui-for-superscript .edui-icon {
    background-position: -620px 0;
}
.edui-default  .edui-for-blockquote .edui-icon {
    background-position: -220px 0;
}
.edui-default  .edui-for-forecolor .edui-icon {
    background-position: -720px 0;
}
.edui-default  .edui-for-backcolor .edui-icon {
    background-position: -760px 0;
}
.edui-default  .edui-for-inserttable .edui-icon {
    background-position: -580px -20px;
}
.edui-default  .edui-for-autotypeset .edui-icon {
    background-position: -640px -40px;
}
.edui-default  .edui-for-justifyleft .edui-icon {
    background-position: -460px 0;
}
.edui-default  .edui-for-justifycenter .edui-icon {
    background-position: -420px 0;
}
.edui-default  .edui-for-justifyright .edui-icon {
    background-position: -480px 0;
}
.edui-default  .edui-for-justifyjustify .edui-icon {
    background-position: -440px 0;
}
.edui-default  .edui-for-insertorderedlist .edui-icon {
    background-position: -80px 0;
}
.edui-default  .edui-for-insertunorderedlist .edui-icon {
    background-position: -20px 0;
}
.edui-default  .edui-for-lineheight .edui-icon {
    background-position: -725px -40px;
}
.edui-default  .edui-for-rowspacingbottom .edui-icon {
    background-position: -745px -40px;
}
.edui-default  .edui-for-rowspacingtop .edui-icon {
    background-position: -765px -40px;
}
.edui-default  .edui-for-horizontal .edui-icon {
    background-position: -360px 0;
}
.edui-default  .edui-for-link .edui-icon {
    background-position: -500px 0;
}
.edui-default  .edui-for-code .edui-icon {
    background-position: -440px -40px;
}
.edui-default  .edui-for-insertimage .edui-icon {
    background-position: -726px -77px;
}
.edui-default  .edui-for-insertframe .edui-icon {
    background-position: -240px -40px;
}
.edui-default  .edui-for-emoticon .edui-icon {
    background-position: -60px -20px;
}
.edui-default  .edui-for-spechars .edui-icon {
    background-position: -240px 0;
}
.edui-default  .edui-for-help .edui-icon {
    background-position: -340px 0;
}
.edui-default  .edui-for-print .edui-icon {
    background-position: -440px -20px;
}
.edui-default  .edui-for-preview .edui-icon {
    background-position: -420px -20px;
}
.edui-default  .edui-for-selectall .edui-icon {
    background-position: -400px -20px;
}
.edui-default  .edui-for-searchreplace .edui-icon {
    background-position: -520px -20px;
}
.edui-default  .edui-for-map .edui-icon {
    background-position: -40px -40px;
}
.edui-default  .edui-for-gmap .edui-icon {
    background-position: -260px -40px;
}
.edui-default  .edui-for-insertvideo .edui-icon {
    background-position: -320px -20px;
}
.edui-default  .edui-for-time .edui-icon {
    background-position: -160px -20px;
}
.edui-default  .edui-for-date .edui-icon {
    background-position: -140px -20px;
}
.edui-default  .edui-for-cut .edui-icon {
    background-position: -680px 0;
}
.edui-default  .edui-for-copy .edui-icon {
    background-position: -700px 0;
}
.edui-default  .edui-for-paste .edui-icon {
    background-position: -560px 0;
}
.edui-default  .edui-for-formatmatch .edui-icon {
    background-position: -40px 0;
}
.edui-default  .edui-for-pasteplain .edui-icon {
    background-position: -360px -20px;
}
.edui-default  .edui-for-directionalityltr .edui-icon {
    background-position: -20px -20px;
}
.edui-default  .edui-for-directionalityrtl .edui-icon {
    background-position: -40px -20px;
}
.edui-default  .edui-for-source .edui-icon {
    background-position: -261px -0px;
}
.edui-default  .edui-for-removeformat .edui-icon {
    background-position: -580px 0;
}
.edui-default  .edui-for-unlink .edui-icon {
    background-position: -640px 0;
}
.edui-default  .edui-for-touppercase .edui-icon {
    background-position: -786px 0;
}
.edui-default  .edui-for-tolowercase .edui-icon {
    background-position: -806px 0;
}
.edui-default  .edui-for-insertrow .edui-icon {
    background-position: -478px -76px;
}
.edui-default  .edui-for-insertrownext .edui-icon {
    background-position: -498px -76px;
}
.edui-default  .edui-for-insertcol .edui-icon {
    background-position: -455px -76px;
}
.edui-default  .edui-for-insertcolnext  .edui-icon {
    background-position: -429px -76px;
}
.edui-default  .edui-for-mergeright .edui-icon {
    background-position: -60px -40px;
}
.edui-default  .edui-for-mergedown .edui-icon {
    background-position: -80px -40px;
}
.edui-default  .edui-for-splittorows .edui-icon {
    background-position: -100px -40px;
}
.edui-default  .edui-for-splittocols .edui-icon {
    background-position: -120px -40px;
}
.edui-default  .edui-for-insertparagraphbeforetable .edui-icon {
    background-position: -140px -40px;
}
.edui-default  .edui-for-deleterow .edui-icon {
    background-position: -660px -20px;
}
.edui-default  .edui-for-deletecol .edui-icon {
    background-position: -640px -20px;
}
.edui-default  .edui-for-splittocells .edui-icon {
    background-position: -800px -20px;
}
.edui-default  .edui-for-mergecells .edui-icon {
    background-position: -760px -20px;
}
.edui-default  .edui-for-deletetable .edui-icon {
    background-position: -620px -20px;
}
.edui-default  .edui-for-cleardoc .edui-icon {
    background-position: -520px 0;
}
.edui-default  .edui-for-fullscreen .edui-icon {
    background-position: -100px -20px;
}
.edui-default  .edui-for-anchor .edui-icon {
    background-position: -200px 0;
}
.edui-default  .edui-for-pagebreak .edui-icon {
    background-position: -460px -40px;
}
.edui-default  .edui-for-imagenone .edui-icon {
    background-position: -480px -40px;
}
.edui-default  .edui-for-imageleft .edui-icon {
    background-position: -500px -40px;
}
.edui-default  .edui-for-wordimage .edui-icon {
    background-position: -660px -40px;
}
.edui-default  .edui-for-imageright .edui-icon {
    background-position: -520px -40px;
}
.edui-default  .edui-for-imagecenter .edui-icon {
    background-position: -540px -40px;
}
.edui-default  .edui-for-indent .edui-icon {
    background-position: -400px 0;
}
.edui-default  .edui-for-outdent .edui-icon {
    background-position: -540px 0;
}
.edui-default  .edui-for-webapp .edui-icon {
    background-position: -601px -40px
}
.edui-default  .edui-for-table .edui-icon {
    background-position: -580px -20px;
}
.edui-default  .edui-for-edittable .edui-icon {
    background-position: -420px -40px;
}
.edui-default  .edui-for-template .edui-icon {
    background-position: -339px -40px;
}
.edui-default  .edui-for-delete .edui-icon {
    background-position: -360px -40px;
}
.edui-default  .edui-for-attachment .edui-icon {
    background-position: -620px -40px;
}
.edui-default  .edui-for-edittd .edui-icon {
    background-position: -700px -40px;
}
.edui-default  .edui-for-snapscreen .edui-icon {
    background-position: -581px -40px
}
.edui-default  .edui-for-scrawl .edui-icon {
    background-position: -801px -41px
}
.edui-default  .edui-for-background .edui-icon {
    background-position: -680px -40px;
}
.edui-default  .edui-for-music .edui-icon {
    background-position: -18px -40px
}
.edui-default  .edui-for-formula .edui-icon {
    background-position: -200px -40px
}
.edui-default  .edui-for-aligntd  .edui-icon {
    background-position: -236px -76px;
}
.edui-default  .edui-for-insertparagraphtrue  .edui-icon {
    background-position: -625px -76px;
}
.edui-default  .edui-for-insertparagraph  .edui-icon {
    background-position: -602px -76px;
}
.edui-default  .edui-for-insertcaption  .edui-icon {
    background-position: -336px -76px;
}
.edui-default  .edui-for-deletecaption  .edui-icon {
    background-position: -362px -76px;
}
.edui-default  .edui-for-inserttitle  .edui-icon {
    background-position: -286px -76px;
}
.edui-default  .edui-for-deletetitle  .edui-icon {
    background-position: -311px -76px;
}
.edui-default  .edui-for-aligntable  .edui-icon {
    background-position: -440px 0;
}
.edui-default  .edui-for-tablealignment-left  .edui-icon {
    background-position: -460px 0;
}
.edui-default  .edui-for-tablealignment-center  .edui-icon {
    background-position: -420px 0;
}
.edui-default  .edui-for-tablealignment-right  .edui-icon {
    background-position: -480px 0;
}
.edui-default  .edui-for-drafts  .edui-icon {
    background-position: -560px 0;
}
.edui-default  .edui-for-charts  .edui-icon {
    background: url( ../images/charts.png ) no-repeat 2px 3px!important;
}
.edui-default  .edui-for-inserttitlecol  .edui-icon {
    background-position: -673px -76px;
}
.edui-default  .edui-for-deletetitlecol  .edui-icon {
    background-position: -698px -76px;
}
.edui-default  .edui-for-simpleupload  .edui-icon {
    background-position: -380px 0px;
}
/*splitbutton*/
.edui-default .edui-toolbar .edui-splitbutton-body .edui-arrow,
.edui-default .edui-toolbar .edui-menubutton-body .edui-arrow {
    background: url(../images/icons.png) -741px 0;
    _background: url(../images/icons.gif) -741px 0;
    height: 20px;
    width: 9px;
}
.edui-default .edui-toolbar .edui-splitbutton .edui-splitbutton-body,
.edui-default .edui-toolbar .edui-menubutton .edui-menubutton-body {
    padding: 1px;
}
.edui-default .edui-toolbar .edui-splitborder {
    width: 1px;
    height: 20px;
}
.edui-default .edui-toolbar .edui-state-hover .edui-splitborder {
    width: 1px;
    border-left: 0px solid #dcac6c;
}
.edui-default .edui-toolbar .edui-state-active .edui-splitborder {
    width: 0;
    border-left: 1px solid gray;
}
.edui-default .edui-toolbar .edui-state-opened .edui-splitborder {
    width: 1px;
    border: 0;
}
.edui-default .edui-toolbar .edui-splitbutton .edui-state-hover .edui-splitbutton-body,
.edui-default .edui-toolbar .edui-menubutton .edui-state-hover .edui-menubutton-body {
    background-color: #fff5d4;
    border: 1px solid #dcac6c;
    padding: 0;
}
.edui-default .edui-toolbar .edui-splitbutton .edui-state-checked .edui-splitbutton-body,
.edui-default .edui-toolbar .edui-menubutton .edui-state-checked .edui-menubutton-body {
    background-color: #FFE69F;
    border: 1px solid #DCAC6C;
    padding: 0;
}
.edui-default .edui-toolbar .edui-splitbutton .edui-state-active .edui-splitbutton-body,
.edui-default .edui-toolbar .edui-menubutton .edui-state-active .edui-menubutton-body {
    background-color: #ffffff;
    border: 1px solid gray;
    padding: 0;
}
.edui-default .edui-state-disabled .edui-arrow {
    opacity: 0.3;
    _filter: alpha(opacity = 30);
}
.edui-default .edui-toolbar .edui-splitbutton .edui-state-opened .edui-splitbutton-body,
.edui-default .edui-toolbar .edui-menubutton .edui-state-opened .edui-menubutton-body {
    background-color: white;
    border: 1px solid gray;
    padding: 0;
}
.edui-default .edui-for-insertorderedlist .edui-bordereraser,
.edui-default .edui-for-lineheight .edui-bordereraser,
.edui-default .edui-for-rowspacingtop .edui-bordereraser,
.edui-default .edui-for-rowspacingbottom .edui-bordereraser,
.edui-default .edui-for-insertunorderedlist .edui-bordereraser {
    background-color: white;
}
/* 解决嵌套导致的图标问题 */
.edui-default .edui-for-insertorderedlist .edui-popup-body .edui-icon,
.edui-default .edui-for-lineheight .edui-popup-body .edui-icon,
.edui-default .edui-for-rowspacingtop .edui-popup-body .edui-icon,
.edui-default .edui-for-rowspacingbottom .edui-popup-body .edui-icon,
.edui-default .edui-for-insertunorderedlist .edui-popup-body .edui-icon {
    /*background-position: 0 -40px;*/
    background-image: none  ;
}
/* 弹出菜单 */
.edui-default .edui-popup {
    z-index: 3000;
    background-color: #ffffff;
    width:auto;
    height:auto;
}
.edui-default .edui-popup .edui-shadow {
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
.edui-default .edui-popup-content {
    border:1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    *border-right-width: 2px;
    *border-bottom-width: 2px;
    -webkit-border-radius: 6px;
    -moz-border-radius: 6px;
    border-radius: 6px;
    -webkit-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);
    -moz-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);
    box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);
    -webkit-background-clip: padding-box;
    -moz-background-clip: padding;
    background-clip: padding-box;
    padding: 5px;
    background:#ffffff;
}
.edui-default .edui-popup .edui-bordereraser {
    background-color: white;
    height: 3px;
}
.edui-default .edui-menu .edui-bordereraser {
    height: 3px;
}
.edui-default .edui-anchor-topleft .edui-bordereraser {
    left: 1px;
    top: -2px;
}
.edui-default .edui-anchor-topright .edui-bordereraser {
    right: 1px;
    top: -2px;
}
.edui-default .edui-anchor-bottomleft .edui-bordereraser {
    left: 0;
    bottom: -6px;
    height: 7px;
    border-left: 1px solid gray;
    border-right: 1px solid gray;
}
.edui-default .edui-anchor-bottomright .edui-bordereraser {
    right: 0;
    bottom: -6px;
    height: 7px;
    border-left: 1px solid gray;
    border-right: 1px solid gray;
}
.edui-popup div{
    width:auto;
    height:auto;
}
.edui-default .edui-editor-messageholder {
    display: block;
    width: 150px;
    height: auto;
    border: 0;
    margin: 0;
    padding: 0;
    position: absolute;
    top: 28px;
    right: 3px;
}
.edui-default .edui-message{
    min-height: 10px;
    text-shadow: 0 1px 0 rgba(255,255,255,0.5);
    padding: 0;
    margin-bottom: 3px;
    position: relative;
}
.edui-default .edui-message-body{
    border-radius: 3px;
    padding: 8px 15px 8px 8px;
    color: #c09853;
    background-color: #fcf8e3;
    border: 1px solid #fbeed5;
}
.edui-default .edui-message-type-info{
    color: #3a87ad;
    background-color: #d9edf7;
    border-color: #bce8f1
}
.edui-default .edui-message-type-success{
    color: #468847;
    background-color: #dff0d8;
    border-color: #d6e9c6
}
.edui-default .edui-message-type-danger,
.edui-default .edui-message-type-error{
    color: #b94a48;
    background-color: #f2dede;
    border-color: #eed3d7
}
.edui-default .edui-message .edui-message-closer {
    display: block;
    width: 16px;
    height: 16px;
    line-height: 16px;
    position: absolute;
    top: 0;
    right: 0;
    padding: 0;
    cursor: pointer;
    background: transparent;
    border: 0;
    float: right;
    font-size: 20px;
    font-weight: bold;
    color: #999;
    text-shadow: 0 1px 0 #fff;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
}
.edui-default .edui-message .edui-message-content {
    font-size: 10pt;
    word-wrap: break-word;
    word-break: normal;
}
/* 弹出对话框按钮和对话框大小 */
.edui-default .edui-dialog {
    z-index: 2000;
    position: absolute;
}
.edui-dialog div{
    width:auto;
}
.edui-default .edui-dialog-wrap {
    margin-right: 6px;
    margin-bottom: 6px;
}
.edui-default .edui-dialog-fullscreen-flag {
    margin-right: 0;
    margin-bottom: 0;
}
.edui-default .edui-dialog-body {
    position: relative;
    padding:2px 0 0 2px;
    _zoom: 1;
}
.edui-default .edui-dialog-fullscreen-flag .edui-dialog-body {
    padding: 0;
}
.edui-default .edui-dialog-shadow {
    position: absolute;
    z-index: -1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #ffffff;
    border: 1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    *border-right-width: 2px;
    *border-bottom-width: 2px;
    -webkit-border-radius: 6px;
    -moz-border-radius: 6px;
    border-radius: 6px;
    -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
    -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
    -webkit-background-clip: padding-box;
    -moz-background-clip: padding;
    background-clip: padding-box;
}
.edui-default .edui-dialog-foot {
    background-color: white;
}
.edui-default .edui-dialog-titlebar {
    height: 26px;
    border-bottom: 1px solid #c6c6c6;
    background: url(../images/dialog-title-bg.png) repeat-x bottom;
    position: relative;
    cursor: move;
}
.edui-default .edui-dialog-caption {
    font-weight: bold;
    font-size: 12px;
    line-height: 26px;
    padding-left: 5px;
}
.edui-default .edui-dialog-draghandle {
    height: 26px;
}
.edui-default .edui-dialog-closebutton {
    position: absolute !important;
    right: 5px;
    top: 3px;
}
.edui-default .edui-dialog-closebutton .edui-button-body {
    height: 20px;
    width: 20px;
    cursor: pointer;
    background: url("../images/icons-all.gif") no-repeat 0 -59px;
}
.edui-default .edui-dialog-closebutton .edui-state-hover .edui-button-body {
    background: url("../images/icons-all.gif") no-repeat 0 -89px;
}
.edui-default .edui-dialog-foot {
    height: 40px;
}
.edui-default .edui-dialog-buttons {
    position: absolute;
    right: 0;
}
.edui-default .edui-dialog-buttons .edui-button {
    margin-right: 10px;
}
.edui-default .edui-dialog-buttons .edui-button .edui-button-body {
    background: url("../images/icons-all.gif") no-repeat;
    height: 24px;
    width: 96px;
    font-size: 12px;
    line-height: 24px;
    text-align: center;
    cursor: default;
}
.edui-default .edui-dialog-buttons .edui-button .edui-state-hover .edui-button-body {
    background: url("../images/icons-all.gif") no-repeat 0 -30px;
}
.edui-default .edui-dialog iframe {
    border: 0;
    padding: 0;
    margin: 0;
    vertical-align: top;
}
.edui-default .edui-dialog-modalmask {
    opacity: 0.3;
    filter: alpha(opacity = 30);
    background-color: #ccc;
    position: absolute;
    /*z-index: 1999;*/
}
.edui-default .edui-dialog-dragmask {
    position: absolute;
    /*z-index: 2001;*/
    background-color: transparent;
    cursor: move;
}
.edui-default .edui-dialog-content {
    position: relative;
}
.edui-default .dialogcontmask {
    cursor: move;
    visibility: hidden;
    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
    opacity: 0;
    filter: alpha(opacity = 0);
}
/*link-dialog*/
.edui-default .edui-for-link .edui-dialog-content {
    width: 420px;
    height: 200px;
    overflow: hidden;
}
/*background-dialog*/
.edui-default .edui-for-background .edui-dialog-content {
    width: 440px;
    height: 280px;
    overflow: hidden;
}
/*template-dialog*/
.edui-default .edui-for-template .edui-dialog-content {
    width: 630px;
    height: 390px;
    overflow: hidden;
}
/*scrawl-dialog*/
.edui-default .edui-for-scrawl .edui-dialog-content {
    width: 515px;
    *width: 506px;
    height: 360px;
}
/*spechars-dialog*/
.edui-default .edui-for-spechars .edui-dialog-content {
    width: 620px;
    height: 500px;
    *width: 630px;
    *height: 570px;
}
/*image-dialog*/
.edui-default .edui-for-insertimage .edui-dialog-content {
    width: 650px;
    height: 400px;
    overflow: hidden;
}
/*webapp-dialog*/
.edui-default .edui-for-webapp .edui-dialog-content {
    width: 560px;
    _width: 565px;
    height: 450px;
    overflow: hidden;
}
/*image-insertframe*/
.edui-default .edui-for-insertframe .edui-dialog-content {
    width: 350px;
    height: 200px;
    overflow: hidden;
}
/*wordImage-dialog*/
.edui-default .edui-for-wordimage .edui-dialog-content {
    width: 620px;
    height: 380px;
    overflow: hidden;
}
/*attachment-dialog*/
.edui-default .edui-for-attachment .edui-dialog-content {
    width: 650px;
    height: 400px;
    overflow: hidden;
}
/*map-dialog*/
.edui-default .edui-for-map .edui-dialog-content {
    width: 550px;
    height: 400px;
}
/*gmap-dialog*/
.edui-default .edui-for-gmap .edui-dialog-content {
    width: 550px;
    height: 400px;
}
/*video-dialog*/
.edui-default .edui-for-insertvideo .edui-dialog-content {
    width: 590px;
    height: 390px;
}
/*anchor-dialog*/
.edui-default .edui-for-anchor .edui-dialog-content {
    width: 320px;
    height: 60px;
    overflow: hidden;
}
/*searchreplace-dialog*/
.edui-default .edui-for-searchreplace .edui-dialog-content {
    width: 400px;
    height: 220px;
}
/*help-dialog*/
.edui-default .edui-for-help .edui-dialog-content {
    width: 400px;
    height: 420px;
}
/*edittable-dialog*/
.edui-default .edui-for-edittable .edui-dialog-content {
    width: 540px;
    _width:590px;
    height: 335px;
}
/*edittip-dialog*/
.edui-default .edui-for-edittip .edui-dialog-content {
    width: 225px;
    height: 60px;
}
/*edittd-dialog*/
.edui-default .edui-for-edittd .edui-dialog-content {
    width: 240px;
    height: 50px;
}
/*snapscreen-dialog*/
.edui-default .edui-for-snapscreen .edui-dialog-content {
    width: 400px;
    height: 220px;
}
/*music-dialog*/
.edui-default .edui-for-music .edui-dialog-content {
    width: 515px;
    height: 360px;
}
/*段落弹出菜单*/
.edui-default .edui-for-paragraph .edui-listitem-label {
    font-family: Tahoma, Verdana, Arial, Helvetica;
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-p {
    font-size: 22px;
    line-height: 27px;
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h1 {
    font-weight: bolder;
    font-size: 32px;
    line-height: 36px;
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h2 {
    font-weight: bolder;
    font-size: 27px;
    line-height: 29px;
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h3 {
    font-weight: bolder;
    font-size: 19px;
    line-height: 23px;
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h4 {
    font-weight: bolder;
    font-size: 16px;
    line-height: 19px
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h5 {
    font-weight: bolder;
    font-size: 13px;
    line-height: 16px;
}
.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h6 {
    font-weight: bolder;
    font-size: 12px;
    line-height: 14px;
}
/* 表格弹出菜单 */
.edui-default .edui-for-inserttable .edui-splitborder {
    display: none
}
.edui-default .edui-for-inserttable  .edui-splitbutton-body .edui-arrow {
    width: 0
}
.edui-default .edui-toolbar .edui-for-inserttable  .edui-state-active .edui-splitborder{
    border-left: 1px solid transparent;
}
.edui-default .edui-tablepicker .edui-infoarea {
    height: 14px;
    line-height: 14px;
    font-size: 12px;
    width: 220px;
    margin-bottom: 3px;
    clear: both;
}
.edui-default .edui-tablepicker .edui-infoarea .edui-label {
    float: left;
}
.edui-default .edui-dialog-buttons .edui-label {
    line-height: 24px;
}
.edui-default .edui-tablepicker .edui-infoarea .edui-clickable {
    float: right;
}
.edui-default .edui-tablepicker .edui-pickarea {
    background: url("../images/unhighlighted.gif") repeat;
    height: 220px;
    width: 220px;
}
.edui-default .edui-tablepicker .edui-pickarea .edui-overlay {
    background: url("../images/highlighted.gif") repeat;
}
/* 颜色弹出菜单 */
.edui-default .edui-colorpicker-topbar {
    height: 27px;
    width: 200px;
    /*border-bottom: 1px gray dashed;*/
}
.edui-default .edui-colorpicker-preview {
    height: 20px;
    border: 1px inset black;
    margin-left: 1px;
    width: 128px;
    float: left;
}
.edui-default .edui-colorpicker-nocolor {
    float: right;
    margin-right: 1px;
    font-size: 12px;
    line-height: 14px;
    height: 14px;
    border: 1px solid #333;
    padding: 3px 5px;
    cursor: pointer;
}
.edui-default .edui-colorpicker-tablefirstrow {
    height: 30px;
}
.edui-default .edui-colorpicker-colorcell {
    width: 14px;
    height: 14px;
    display: block;
    margin: 0;
    cursor: pointer;
}
.edui-default .edui-colorpicker-colorcell:hover {
    width: 14px;
    height: 14px;
    margin: 0;
}
.edui-default .edui-colorpicker-advbtn{
    display: block;
    text-align: center;
    cursor: pointer;
    height:20px;
}
.arrow_down{
    background: white url('../images/arrow_down.png') no-repeat center;
}
.arrow_up{
    background: white url('../images/arrow_up.png') no-repeat center;
}
/*高级的样式*/
.edui-colorpicker-adv{
    position: relative;
    overflow: hidden;
    height: 180px;
    display: none;
}
.edui-colorpicker-plant, .edui-colorpicker-hue {
    border: solid 1px #666;
}
.edui-colorpicker-pad {
    width: 150px;
    height: 150px;
    left: 14px;
    top: 13px;
    position: absolute;
    background: red;
    overflow: hidden;
    cursor: crosshair;
}
.edui-colorpicker-cover{
    position: absolute;
    top: 0;
    left: 0;
    width: 150px;
    height: 150px;
    background: url("../images/tangram-colorpicker.png") -160px -200px;
}
.edui-colorpicker-padDot{
    position: absolute;
    top: 0;
    left: 0;
    width: 11px;
    height: 11px;
    overflow: hidden;
    background: url(../images/tangram-colorpicker.png) 0px -200px repeat-x;
    z-index: 1000;
}
.edui-colorpicker-sliderMain {
    position: absolute;
    left: 171px;
    top: 13px;
    width: 19px;
    height: 152px;
    background: url(../images/tangram-colorpicker.png) -179px -12px no-repeat;
}
.edui-colorpicker-slider {
    width: 100%;
    height: 100%;
    cursor: pointer;
}
.edui-colorpicker-thumb{
    position: absolute;
    top: 0;
    cursor: pointer;
    height: 3px;
    left: -1px;
    right: -1px;
    border: 1px solid black;
    background: white;
    opacity: .8;
}
/*自动排版弹出菜单*/
.edui-default .edui-autotypesetpicker .edui-autotypesetpicker-body {
    font-size: 12px;
    margin-bottom: 3px;
    clear: both;
}
.edui-default .edui-autotypesetpicker-body table {
    border-collapse: separate;
    border-spacing: 2px;
}
.edui-default .edui-autotypesetpicker-body td {
    font-size: 12px;
    word-wrap:break-word;
}
.edui-default .edui-autotypesetpicker-body td input {
    margin: 3px 3px 3px 4px;
    *margin: 1px 0 0 0;
}
/*自动排版弹出菜单*/
.edui-default .edui-cellalignpicker .edui-cellalignpicker-body {
    width: 70px;
    font-size: 12px;
    cursor: default;
}
.edui-default .edui-cellalignpicker-body table {
    border-collapse: separate;
    border-spacing: 0;
}
.edui-default .edui-cellalignpicker-body td{
    padding: 1px;
}
.edui-default .edui-cellalignpicker-body .edui-icon{
    height: 20px;
    width: 20px;
    padding: 1px;
    background-image: url(../images/table-cell-align.png);
}
.edui-default .edui-cellalignpicker-body .edui-left{
    background-position: 0 0;
}
.edui-default .edui-cellalignpicker-body .edui-center{
    background-position: -25px 0;
}
.edui-default .edui-cellalignpicker-body .edui-right{
    background-position: -51px 0;
}
.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-left{
    background-position: -73px 0;
}
.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-center{
    background-position: -98px 0;
}
.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-right{
    background-position: -124px 0;
}
.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-left {
    background-position: -146px 0;
    background-color: #f1f4f5;
}
.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-center {
    background-position: -245px 0;
}
.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-right {
    background-position: -271px 0;
}
/*分隔线*/
.edui-default .edui-toolbar .edui-separator {
    width: 2px;
    height: 20px;
    margin: 2px 4px 2px 3px;
    background: url(../images/icons.png) -181px 0;
    background: url(../images/icons.gif) -181px 0 \9;
}
/*颜色按钮 */
.edui-default .edui-toolbar .edui-colorbutton .edui-colorlump {
    position: absolute;
    overflow: hidden;
    bottom: 1px;
    left: 1px;
    width: 18px;
    height: 4px;
}
/*表情按钮及弹出菜单*/
/*去除了表情的下拉箭头*/
.edui-default .edui-for-emotion .edui-icon {
    background-position: -60px -20px;
}
.edui-default .edui-for-emotion .edui-popup-content iframe
{
    width: 514px;
    height: 380px;
    overflow: hidden;
}
.edui-default .edui-for-emotion .edui-popup-content
{
    position: relative;
    z-index: 555
}
.edui-default .edui-for-emotion .edui-splitborder {
    display: none
}
.edui-default .edui-for-emotion .edui-splitbutton-body .edui-arrow
{
    width: 0
}
.edui-default .edui-toolbar .edui-for-emotion  .edui-state-active .edui-splitborder
{
    border-left: 1px solid transparent;
}
/*contextmenu*/
.edui-default .edui-hassubmenu .edui-arrow {
    height: 20px;
    width: 20px;
    float: right;
    background: url("../images/icons-all.gif") no-repeat 10px -233px;
}
.edui-default .edui-menu-body .edui-menuitem {
    padding: 1px;
}
.edui-default .edui-menuseparator {
    margin: 2px 0;
    height: 1px;
    overflow: hidden;
}
.edui-default .edui-menuseparator-inner {
    border-bottom: 1px solid #e2e3e3;
    margin-left: 29px;
    margin-right: 1px;
}
.edui-default .edui-menu-body .edui-state-hover {
    padding: 0 !important;
    background-color: #fff5d4;
    border: 1px solid #dcac6c;
}
/*弹出菜单*/
.edui-default .edui-shortcutmenu {
    padding: 2px;
    width: 190px;
    height: 50px;
    background-color: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
}
/*粘贴弹出菜单*/
.edui-default .edui-wordpastepop .edui-popup-content{
    border: none;
    padding: 0;
    width: 54px;
    height: 21px;
}
.edui-default  .edui-pasteicon {
    width: 100%;
    height: 100%;
    background-image: url('../images/wordpaste.png');
    background-position: 0 0;
}
.edui-default  .edui-pasteicon.edui-state-opened {
    background-position: 0 -34px;
}
.edui-default  .edui-pastecontainer {
    position: relative;
    visibility: hidden;
    width: 97px;
    background: #fff;
    border: 1px solid #ccc;
}
.edui-default  .edui-pastecontainer .edui-title {
    font-weight: bold;
    background: #F8F8FF;
    height: 25px;
    line-height: 25px;
    font-size: 12px;
    padding-left: 5px;
}
.edui-default  .edui-pastecontainer .edui-button {
    overflow: hidden;
    margin: 3px 0;
}
.edui-default  .edui-pastecontainer .edui-button .edui-richtxticon,
.edui-default  .edui-pastecontainer .edui-button .edui-tagicon,
.edui-default  .edui-pastecontainer .edui-button .edui-plaintxticon{
    float: left;
    cursor: pointer;
    width: 29px;
    height: 29px;
    margin-left: 5px;
    background-image: url('../images/wordpaste.png');
    background-repeat: no-repeat;
}
.edui-default  .edui-pastecontainer .edui-button .edui-richtxticon {
    margin-left: 0;
    background-position: -109px 0;
}
.edui-default  .edui-pastecontainer .edui-button .edui-tagicon {
    background-position: -148px 1px;
}
.edui-default  .edui-pastecontainer .edui-button .edui-plaintxticon {
    background-position: -72px 0;
}
.edui-default  .edui-pastecontainer .edui-button .edui-state-hover .edui-richtxticon {
    background-position: -109px -34px;
}
.edui-default  .edui-pastecontainer .edui-button .edui-state-hover .edui-tagicon{
    background-position: -148px -34px;
}
.edui-default  .edui-pastecontainer .edui-button  .edui-state-hover .edui-plaintxticon{
    background-position: -72px -34px;
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/css/ueditor.min.css
New file
@@ -0,0 +1,8 @@
/*!
 * UEditor
 * version: ueditor
 * build: Thu May 29 2014 16:47:49 GMT+0800 (中国标准时间)
 */
.edui-default .edui-box{border:0;padding:0;margin:0;overflow:hidden}.edui-default a.edui-box{display:block;text-decoration:none;color:#000}.edui-default a.edui-box:hover{text-decoration:none}.edui-default a.edui-box:active{text-decoration:none}.edui-default table.edui-box{border-collapse:collapse}.edui-default ul.edui-box{list-style-type:none}div.edui-box{position:relative;display:-moz-inline-box!important;display:inline-block!important;vertical-align:top}.edui-default .edui-clearfix{zoom:1}.edui-default .edui-clearfix:after{content:'\20';display:block;clear:both}* html div.edui-box{display:inline!important}:first-child+html div.edui-box{display:inline!important}.edui-default .edui-button-body,.edui-splitbutton-body,.edui-menubutton-body,.edui-combox-body{position:relative}.edui-default .edui-popup{position:absolute;-webkit-user-select:none;-moz-user-select:none}.edui-default .edui-popup .edui-shadow{position:absolute;z-index:-1}.edui-default .edui-popup .edui-bordereraser{position:absolute;overflow:hidden}.edui-default .edui-tablepicker .edui-canvas{position:relative}.edui-default .edui-tablepicker .edui-canvas .edui-overlay{position:absolute}.edui-default .edui-dialog-modalmask,.edui-dialog-dragmask{position:absolute;left:0;top:0;width:100%;height:100%}.edui-default .edui-toolbar{position:relative}.edui-default .edui-label{cursor:default}.edui-default span.edui-clickable{color:#00f;cursor:pointer;text-decoration:underline}.edui-default span.edui-unclickable{color:gray;cursor:default}.edui-default .edui-toolbar{cursor:default;-webkit-user-select:none;-moz-user-select:none;padding:1px;overflow:hidden;zoom:1;width:auto;height:auto}.edui-default .edui-toolbar .edui-button,.edui-default .edui-toolbar .edui-splitbutton,.edui-default .edui-toolbar .edui-menubutton,.edui-default .edui-toolbar .edui-combox{margin:1px}.edui-default .edui-editor{border:1px solid #d4d4d4;background-color:#fff;position:relative;overflow:visible;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.edui-editor div{width:auto;height:auto}.edui-default .edui-editor-toolbarbox{position:relative;zoom:1;-webkit-box-shadow:0 1px 4px rgba(204,204,204,.6);-moz-box-shadow:0 1px 4px rgba(204,204,204,.6);box-shadow:0 1px 4px rgba(204,204,204,.6);border-top-left-radius:2px;border-top-right-radius:2px}.edui-default .edui-editor-toolbarboxouter{border-bottom:1px solid #d4d4d4;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,.065);box-shadow:0 1px 4px rgba(0,0,0,.065)}.edui-default .edui-editor-toolbarboxinner{padding:2px}.edui-default .edui-editor-iframeholder{position:relative}.edui-default .edui-editor-bottomContainer{overflow:hidden}.edui-default .edui-editor-bottomContainer table{width:100%;height:0;overflow:hidden;border-spacing:0}.edui-default .edui-editor-bottomContainer td{white-space:nowrap;border-top:1px solid #ccc;line-height:20px;font-size:12px;font-family:Arial,Helvetica,Tahoma,Verdana,Sans-Serif}.edui-default .edui-editor-wordcount{text-align:right;margin-right:5px;color:#aaa}.edui-default .edui-editor-scale{width:12px}.edui-default .edui-editor-scale .edui-editor-icon{float:right;width:100%;height:12px;margin-top:10px;background:url(../images/scale.png) no-repeat;cursor:se-resize}.edui-default .edui-editor-breadcrumb{margin:2px 0 0 3px}.edui-default .edui-editor-breadcrumb span{cursor:pointer;text-decoration:underline;color:#00f}.edui-default .edui-toolbar .edui-for-fullscreen{float:right}.edui-default .edui-bubble .edui-popup-content{border:1px solid #DCAC6C;background-color:#fff6d9;padding:5px;font-size:10pt;font-family:"宋体"}.edui-default .edui-bubble .edui-shadow{}.edui-default .edui-editor-toolbarmsg{background-color:#FFF6D9;border-bottom:1px solid #ccc;position:absolute;bottom:-25px;left:0;z-index:1009;width:99.9%}.edui-default .edui-editor-toolbarmsg-upload{font-size:14px;color:#00f;width:100px;height:16px;line-height:16px;cursor:pointer;position:absolute;top:5px;left:350px}.edui-default .edui-editor-toolbarmsg-label{font-size:12px;line-height:16px;padding:4px}.edui-default .edui-editor-toolbarmsg-close{float:right;width:20px;height:16px;line-height:16px;cursor:pointer;color:red}.edui-default .edui-list .edui-bordereraser{display:none}.edui-default .edui-listitem{padding:1px;white-space:nowrap}.edui-default .edui-list .edui-state-hover{position:relative;background-color:#fff5d4;border:1px solid #dcac6c;padding:0}.edui-default .edui-for-fontfamily .edui-listitem-label{min-width:130px;_width:120px;font-size:12px;height:22px;line-height:22px;padding-left:5px}.edui-default .edui-for-insertcode .edui-listitem-label{min-width:120px;_width:120px;font-size:12px;height:22px;line-height:22px;padding-left:5px}.edui-default .edui-for-underline .edui-listitem-label{min-width:120px;_width:120px;padding:3px 5px;font-size:12px}.edui-default .edui-for-fontsize .edui-listitem-label{min-width:120px;_width:120px;padding:3px 5px}.edui-default .edui-for-paragraph .edui-listitem-label{min-width:200px;_width:200px;padding:2px 5px}.edui-default .edui-for-rowspacingtop .edui-listitem-label,.edui-default .edui-for-rowspacingbottom .edui-listitem-label{min-width:53px;_width:53px;padding:2px 5px}.edui-default .edui-for-lineheight .edui-listitem-label{min-width:53px;_width:53px;padding:2px 5px}.edui-default .edui-for-customstyle .edui-listitem-label{min-width:200px;_width:200px;width:200px!important;padding:2px 5px}.edui-default .edui-menu{z-index:3000}.edui-default .edui-menu .edui-popup-content{padding:3px}.edui-default .edui-menu-body{_width:150px;min-width:170px;background:url(../images/sparator_v.png) repeat-y 25px}.edui-default .edui-menuitem-body{}.edui-default .edui-menuitem{height:20px;cursor:default;vertical-align:top}.edui-default .edui-menuitem .edui-icon{width:20px!important;height:20px!important;background:url(../images/icons.png) 0 -4000px;background:url(../images/icons.gif) 0 -4000px\9}.edui-default .edui-menuitem .edui-label{font-size:12px;line-height:20px;height:20px;padding-left:10px}.edui-default .edui-state-checked .edui-menuitem-body{background:url(../images/icons-all.gif) no-repeat 6px -205px}.edui-default .edui-state-disabled .edui-menuitem-label{color:gray}.edui-default .edui-toolbar .edui-combox-body .edui-button-body{width:60px;font-size:12px;height:20px;line-height:20px;padding-left:5px;white-space:nowrap;margin:0 3px 0 0}.edui-default .edui-toolbar .edui-combox-body .edui-arrow{background:url(../images/icons.png) -741px 0;_background:url(../images/icons.gif) -741px 0;height:20px;width:9px}.edui-default .edui-toolbar .edui-combox .edui-combox-body{border:1px solid #CCC;background-color:#fff;border-radius:2px;-webkit-border-radius:2px;-moz-border-radius:2px}.edui-default .edui-toolbar .edui-combox-body .edui-splitborder{display:none}.edui-default .edui-toolbar .edui-combox-body .edui-arrow{border-left:1px solid #CCC}.edui-default .edui-toolbar .edui-state-hover .edui-combox-body{background-color:#fff5d4;border:1px solid #dcac6c}.edui-default .edui-toolbar .edui-state-hover .edui-combox-body .edui-arrow{border-left:1px solid #dcac6c}.edui-default .edui-toolbar .edui-state-checked .edui-combox-body{background-color:#FFE69F;border:1px solid #DCAC6C}.edui-toolbar .edui-state-checked .edui-combox-body .edui-arrow{border-left:1px solid #DCAC6C}.edui-toolbar .edui-state-disabled .edui-combox-body{background-color:#F0F0EE;opacity:.3;filter:alpha(opacity=30)}.edui-toolbar .edui-state-opened .edui-combox-body{background-color:#fff;border:1px solid gray}.edui-default .edui-toolbar .edui-button .edui-icon,.edui-default .edui-toolbar .edui-menubutton .edui-icon,.edui-default .edui-toolbar .edui-splitbutton .edui-icon{height:20px!important;width:20px!important;background-image:url(../images/icons.png);background-image:url(../images/icons.gif) \9}.edui-default .edui-toolbar .edui-button .edui-button-wrap{padding:1px;position:relative}.edui-default .edui-toolbar .edui-button .edui-state-hover .edui-button-wrap{background-color:#fff5d4;padding:0;border:1px solid #dcac6c}.edui-default .edui-toolbar .edui-button .edui-state-checked .edui-button-wrap{background-color:#ffe69f;padding:0;border:1px solid #dcac6c;border-radius:2px;-webkit-border-radius:2px;-moz-border-radius:2px}.edui-default .edui-toolbar .edui-button .edui-state-active .edui-button-wrap{background-color:#fff;padding:0;border:1px solid gray}.edui-default .edui-toolbar .edui-state-disabled .edui-label{color:#ccc}.edui-default .edui-toolbar .edui-state-disabled .edui-icon{opacity:.3;filter:alpha(opacity=30)}.edui-default .edui-for-undo .edui-icon{background-position:-160px 0}.edui-default .edui-for-redo .edui-icon{background-position:-100px 0}.edui-default .edui-for-bold .edui-icon{background-position:0 0}.edui-default .edui-for-italic .edui-icon{background-position:-60px 0}.edui-default .edui-for-fontborder .edui-icon{background-position:-160px -40px}.edui-default .edui-for-underline .edui-icon{background-position:-140px 0}.edui-default .edui-for-strikethrough .edui-icon{background-position:-120px 0}.edui-default .edui-for-subscript .edui-icon{background-position:-600px 0}.edui-default .edui-for-superscript .edui-icon{background-position:-620px 0}.edui-default .edui-for-blockquote .edui-icon{background-position:-220px 0}.edui-default .edui-for-forecolor .edui-icon{background-position:-720px 0}.edui-default .edui-for-backcolor .edui-icon{background-position:-760px 0}.edui-default .edui-for-inserttable .edui-icon{background-position:-580px -20px}.edui-default .edui-for-autotypeset .edui-icon{background-position:-640px -40px}.edui-default .edui-for-justifyleft .edui-icon{background-position:-460px 0}.edui-default .edui-for-justifycenter .edui-icon{background-position:-420px 0}.edui-default .edui-for-justifyright .edui-icon{background-position:-480px 0}.edui-default .edui-for-justifyjustify .edui-icon{background-position:-440px 0}.edui-default .edui-for-insertorderedlist .edui-icon{background-position:-80px 0}.edui-default .edui-for-insertunorderedlist .edui-icon{background-position:-20px 0}.edui-default .edui-for-lineheight .edui-icon{background-position:-725px -40px}.edui-default .edui-for-rowspacingbottom .edui-icon{background-position:-745px -40px}.edui-default .edui-for-rowspacingtop .edui-icon{background-position:-765px -40px}.edui-default .edui-for-horizontal .edui-icon{background-position:-360px 0}.edui-default .edui-for-link .edui-icon{background-position:-500px 0}.edui-default .edui-for-code .edui-icon{background-position:-440px -40px}.edui-default .edui-for-insertimage .edui-icon{background-position:-726px -77px}.edui-default .edui-for-insertframe .edui-icon{background-position:-240px -40px}.edui-default .edui-for-emoticon .edui-icon{background-position:-60px -20px}.edui-default .edui-for-spechars .edui-icon{background-position:-240px 0}.edui-default .edui-for-help .edui-icon{background-position:-340px 0}.edui-default .edui-for-print .edui-icon{background-position:-440px -20px}.edui-default .edui-for-preview .edui-icon{background-position:-420px -20px}.edui-default .edui-for-selectall .edui-icon{background-position:-400px -20px}.edui-default .edui-for-searchreplace .edui-icon{background-position:-520px -20px}.edui-default .edui-for-map .edui-icon{background-position:-40px -40px}.edui-default .edui-for-gmap .edui-icon{background-position:-260px -40px}.edui-default .edui-for-insertvideo .edui-icon{background-position:-320px -20px}.edui-default .edui-for-time .edui-icon{background-position:-160px -20px}.edui-default .edui-for-date .edui-icon{background-position:-140px -20px}.edui-default .edui-for-cut .edui-icon{background-position:-680px 0}.edui-default .edui-for-copy .edui-icon{background-position:-700px 0}.edui-default .edui-for-paste .edui-icon{background-position:-560px 0}.edui-default .edui-for-formatmatch .edui-icon{background-position:-40px 0}.edui-default .edui-for-pasteplain .edui-icon{background-position:-360px -20px}.edui-default .edui-for-directionalityltr .edui-icon{background-position:-20px -20px}.edui-default .edui-for-directionalityrtl .edui-icon{background-position:-40px -20px}.edui-default .edui-for-source .edui-icon{background-position:-261px -0px}.edui-default .edui-for-removeformat .edui-icon{background-position:-580px 0}.edui-default .edui-for-unlink .edui-icon{background-position:-640px 0}.edui-default .edui-for-touppercase .edui-icon{background-position:-786px 0}.edui-default .edui-for-tolowercase .edui-icon{background-position:-806px 0}.edui-default .edui-for-insertrow .edui-icon{background-position:-478px -76px}.edui-default .edui-for-insertrownext .edui-icon{background-position:-498px -76px}.edui-default .edui-for-insertcol .edui-icon{background-position:-455px -76px}.edui-default .edui-for-insertcolnext .edui-icon{background-position:-429px -76px}.edui-default .edui-for-mergeright .edui-icon{background-position:-60px -40px}.edui-default .edui-for-mergedown .edui-icon{background-position:-80px -40px}.edui-default .edui-for-splittorows .edui-icon{background-position:-100px -40px}.edui-default .edui-for-splittocols .edui-icon{background-position:-120px -40px}.edui-default .edui-for-insertparagraphbeforetable .edui-icon{background-position:-140px -40px}.edui-default .edui-for-deleterow .edui-icon{background-position:-660px -20px}.edui-default .edui-for-deletecol .edui-icon{background-position:-640px -20px}.edui-default .edui-for-splittocells .edui-icon{background-position:-800px -20px}.edui-default .edui-for-mergecells .edui-icon{background-position:-760px -20px}.edui-default .edui-for-deletetable .edui-icon{background-position:-620px -20px}.edui-default .edui-for-cleardoc .edui-icon{background-position:-520px 0}.edui-default .edui-for-fullscreen .edui-icon{background-position:-100px -20px}.edui-default .edui-for-anchor .edui-icon{background-position:-200px 0}.edui-default .edui-for-pagebreak .edui-icon{background-position:-460px -40px}.edui-default .edui-for-imagenone .edui-icon{background-position:-480px -40px}.edui-default .edui-for-imageleft .edui-icon{background-position:-500px -40px}.edui-default .edui-for-wordimage .edui-icon{background-position:-660px -40px}.edui-default .edui-for-imageright .edui-icon{background-position:-520px -40px}.edui-default .edui-for-imagecenter .edui-icon{background-position:-540px -40px}.edui-default .edui-for-indent .edui-icon{background-position:-400px 0}.edui-default .edui-for-outdent .edui-icon{background-position:-540px 0}.edui-default .edui-for-webapp .edui-icon{background-position:-601px -40px}.edui-default .edui-for-table .edui-icon{background-position:-580px -20px}.edui-default .edui-for-edittable .edui-icon{background-position:-420px -40px}.edui-default .edui-for-template .edui-icon{background-position:-339px -40px}.edui-default .edui-for-delete .edui-icon{background-position:-360px -40px}.edui-default .edui-for-attachment .edui-icon{background-position:-620px -40px}.edui-default .edui-for-edittd .edui-icon{background-position:-700px -40px}.edui-default .edui-for-snapscreen .edui-icon{background-position:-581px -40px}.edui-default .edui-for-scrawl .edui-icon{background-position:-801px -41px}.edui-default .edui-for-background .edui-icon{background-position:-680px -40px}.edui-default .edui-for-music .edui-icon{background-position:-18px -40px}.edui-default .edui-for-formula .edui-icon{background-position:-200px -40px}.edui-default .edui-for-aligntd .edui-icon{background-position:-236px -76px}.edui-default .edui-for-insertparagraphtrue .edui-icon{background-position:-625px -76px}.edui-default .edui-for-insertparagraph .edui-icon{background-position:-602px -76px}.edui-default .edui-for-insertcaption .edui-icon{background-position:-336px -76px}.edui-default .edui-for-deletecaption .edui-icon{background-position:-362px -76px}.edui-default .edui-for-inserttitle .edui-icon{background-position:-286px -76px}.edui-default .edui-for-deletetitle .edui-icon{background-position:-311px -76px}.edui-default .edui-for-aligntable .edui-icon{background-position:-440px 0}.edui-default .edui-for-tablealignment-left .edui-icon{background-position:-460px 0}.edui-default .edui-for-tablealignment-center .edui-icon{background-position:-420px 0}.edui-default .edui-for-tablealignment-right .edui-icon{background-position:-480px 0}.edui-default .edui-for-drafts .edui-icon{background-position:-560px 0}.edui-default .edui-for-charts .edui-icon{background:url( ../images/charts.png ) no-repeat 2px 3px!important}.edui-default .edui-for-inserttitlecol .edui-icon{background-position:-673px -76px}.edui-default .edui-for-deletetitlecol .edui-icon{background-position:-698px -76px}.edui-default .edui-for-simpleupload .edui-icon{background-position:-380px 0}.edui-default .edui-toolbar .edui-splitbutton-body .edui-arrow,.edui-default .edui-toolbar .edui-menubutton-body .edui-arrow{background:url(../images/icons.png) -741px 0;_background:url(../images/icons.gif) -741px 0;height:20px;width:9px}.edui-default .edui-toolbar .edui-splitbutton .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-menubutton-body{padding:1px}.edui-default .edui-toolbar .edui-splitborder{width:1px;height:20px}.edui-default .edui-toolbar .edui-state-hover .edui-splitborder{width:1px;border-left:0 solid #dcac6c}.edui-default .edui-toolbar .edui-state-active .edui-splitborder{width:0;border-left:1px solid gray}.edui-default .edui-toolbar .edui-state-opened .edui-splitborder{width:1px;border:0}.edui-default .edui-toolbar .edui-splitbutton .edui-state-hover .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-hover .edui-menubutton-body{background-color:#fff5d4;border:1px solid #dcac6c;padding:0}.edui-default .edui-toolbar .edui-splitbutton .edui-state-checked .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-checked .edui-menubutton-body{background-color:#FFE69F;border:1px solid #DCAC6C;padding:0}.edui-default .edui-toolbar .edui-splitbutton .edui-state-active .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-active .edui-menubutton-body{background-color:#fff;border:1px solid gray;padding:0}.edui-default .edui-state-disabled .edui-arrow{opacity:.3;_filter:alpha(opacity=30)}.edui-default .edui-toolbar .edui-splitbutton .edui-state-opened .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-opened .edui-menubutton-body{background-color:#fff;border:1px solid gray;padding:0}.edui-default .edui-for-insertorderedlist .edui-bordereraser,.edui-default .edui-for-lineheight .edui-bordereraser,.edui-default .edui-for-rowspacingtop .edui-bordereraser,.edui-default .edui-for-rowspacingbottom .edui-bordereraser,.edui-default .edui-for-insertunorderedlist .edui-bordereraser{background-color:#fff}.edui-default .edui-for-insertorderedlist .edui-popup-body .edui-icon,.edui-default .edui-for-lineheight .edui-popup-body .edui-icon,.edui-default .edui-for-rowspacingtop .edui-popup-body .edui-icon,.edui-default .edui-for-rowspacingbottom .edui-popup-body .edui-icon,.edui-default .edui-for-insertunorderedlist .edui-popup-body .edui-icon{background-image:none}.edui-default .edui-popup{z-index:3000;background-color:#fff;width:auto;height:auto}.edui-default .edui-popup .edui-shadow{left:0;top:0;width:100%;height:100%}.edui-default .edui-popup-content{border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 4px rgba(0,0,0,.2);-moz-box-shadow:0 3px 4px rgba(0,0,0,.2);box-shadow:0 3px 4px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;padding:5px;background:#fff}.edui-default .edui-popup .edui-bordereraser{background-color:#fff;height:3px}.edui-default .edui-menu .edui-bordereraser{height:3px}.edui-default .edui-anchor-topleft .edui-bordereraser{left:1px;top:-2px}.edui-default .edui-anchor-topright .edui-bordereraser{right:1px;top:-2px}.edui-default .edui-anchor-bottomleft .edui-bordereraser{left:0;bottom:-6px;height:7px;border-left:1px solid gray;border-right:1px solid gray}.edui-default .edui-anchor-bottomright .edui-bordereraser{right:0;bottom:-6px;height:7px;border-left:1px solid gray;border-right:1px solid gray}.edui-popup div{width:auto;height:auto}.edui-default .edui-editor-messageholder{display:block;width:150px;height:auto;border:0;margin:0;padding:0;position:absolute;top:28px;right:3px}.edui-default .edui-message{min-height:10px;text-shadow:0 1px 0 rgba(255,255,255,.5);padding:0;margin-bottom:3px;position:relative}.edui-default .edui-message-body{border-radius:3px;padding:8px 15px 8px 8px;color:#c09853;background-color:#fcf8e3;border:1px solid #fbeed5}.edui-default .edui-message-type-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.edui-default .edui-message-type-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.edui-default .edui-message-type-danger,.edui-default .edui-message-type-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.edui-default .edui-message .edui-message-closer{display:block;width:16px;height:16px;line-height:16px;position:absolute;top:0;right:0;padding:0;cursor:pointer;background:transparent;border:0;float:right;font-size:20px;font-weight:700;color:#999;text-shadow:0 1px 0 #fff;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.edui-default .edui-message .edui-message-content{font-size:10pt;word-wrap:break-word;word-break:normal}.edui-default .edui-dialog{z-index:2000;position:absolute}.edui-dialog div{width:auto}.edui-default .edui-dialog-wrap{margin-right:6px;margin-bottom:6px}.edui-default .edui-dialog-fullscreen-flag{margin-right:0;margin-bottom:0}.edui-default .edui-dialog-body{position:relative;padding:2px 0 0 2px;_zoom:1}.edui-default .edui-dialog-fullscreen-flag .edui-dialog-body{padding:0}.edui-default .edui-dialog-shadow{position:absolute;z-index:-1;left:0;top:0;width:100%;height:100%;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.edui-default .edui-dialog-foot{background-color:#fff}.edui-default .edui-dialog-titlebar{height:26px;border-bottom:1px solid #c6c6c6;background:url(../images/dialog-title-bg.png) repeat-x bottom;position:relative;cursor:move}.edui-default .edui-dialog-caption{font-weight:700;font-size:12px;line-height:26px;padding-left:5px}.edui-default .edui-dialog-draghandle{height:26px}.edui-default .edui-dialog-closebutton{position:absolute!important;right:5px;top:3px}.edui-default .edui-dialog-closebutton .edui-button-body{height:20px;width:20px;cursor:pointer;background:url(../images/icons-all.gif) no-repeat 0 -59px}.edui-default .edui-dialog-closebutton .edui-state-hover .edui-button-body{background:url(../images/icons-all.gif) no-repeat 0 -89px}.edui-default .edui-dialog-foot{height:40px}.edui-default .edui-dialog-buttons{position:absolute;right:0}.edui-default .edui-dialog-buttons .edui-button{margin-right:10px}.edui-default .edui-dialog-buttons .edui-button .edui-button-body{background:url(../images/icons-all.gif) no-repeat;height:24px;width:96px;font-size:12px;line-height:24px;text-align:center;cursor:default}.edui-default .edui-dialog-buttons .edui-button .edui-state-hover .edui-button-body{background:url(../images/icons-all.gif) no-repeat 0 -30px}.edui-default .edui-dialog iframe{border:0;padding:0;margin:0;vertical-align:top}.edui-default .edui-dialog-modalmask{opacity:.3;filter:alpha(opacity=30);background-color:#ccc;position:absolute}.edui-default .edui-dialog-dragmask{position:absolute;background-color:transparent;cursor:move}.edui-default .edui-dialog-content{position:relative}.edui-default .dialogcontmask{cursor:move;visibility:hidden;display:block;position:absolute;width:100%;height:100%;opacity:0;filter:alpha(opacity=0)}.edui-default .edui-for-link .edui-dialog-content{width:420px;height:200px;overflow:hidden}.edui-default .edui-for-background .edui-dialog-content{width:440px;height:280px;overflow:hidden}.edui-default .edui-for-template .edui-dialog-content{width:630px;height:390px;overflow:hidden}.edui-default .edui-for-scrawl .edui-dialog-content{width:515px;*width:506px;height:360px}.edui-default .edui-for-spechars .edui-dialog-content{width:620px;height:500px;*width:630px;*height:570px}.edui-default .edui-for-insertimage .edui-dialog-content{width:650px;height:400px;overflow:hidden}.edui-default .edui-for-webapp .edui-dialog-content{width:560px;_width:565px;height:450px;overflow:hidden}.edui-default .edui-for-insertframe .edui-dialog-content{width:350px;height:200px;overflow:hidden}.edui-default .edui-for-wordimage .edui-dialog-content{width:620px;height:380px;overflow:hidden}.edui-default .edui-for-attachment .edui-dialog-content{width:650px;height:400px;overflow:hidden}.edui-default .edui-for-map .edui-dialog-content{width:550px;height:400px}.edui-default .edui-for-gmap .edui-dialog-content{width:550px;height:400px}.edui-default .edui-for-insertvideo .edui-dialog-content{width:590px;height:390px}.edui-default .edui-for-anchor .edui-dialog-content{width:320px;height:60px;overflow:hidden}.edui-default .edui-for-searchreplace .edui-dialog-content{width:400px;height:220px}.edui-default .edui-for-help .edui-dialog-content{width:400px;height:420px}.edui-default .edui-for-edittable .edui-dialog-content{width:540px;_width:590px;height:335px}.edui-default .edui-for-edittip .edui-dialog-content{width:225px;height:60px}.edui-default .edui-for-edittd .edui-dialog-content{width:240px;height:50px}.edui-default .edui-for-snapscreen .edui-dialog-content{width:400px;height:220px}.edui-default .edui-for-music .edui-dialog-content{width:515px;height:360px}.edui-default .edui-for-paragraph .edui-listitem-label{font-family:Tahoma,Verdana,Arial,Helvetica}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-p{font-size:22px;line-height:27px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h1{font-weight:bolder;font-size:32px;line-height:36px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h2{font-weight:bolder;font-size:27px;line-height:29px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h3{font-weight:bolder;font-size:19px;line-height:23px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h4{font-weight:bolder;font-size:16px;line-height:19px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h5{font-weight:bolder;font-size:13px;line-height:16px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h6{font-weight:bolder;font-size:12px;line-height:14px}.edui-default .edui-for-inserttable .edui-splitborder{display:none}.edui-default .edui-for-inserttable .edui-splitbutton-body .edui-arrow{width:0}.edui-default .edui-toolbar .edui-for-inserttable .edui-state-active .edui-splitborder{border-left:1px solid transparent}.edui-default .edui-tablepicker .edui-infoarea{height:14px;line-height:14px;font-size:12px;width:220px;margin-bottom:3px;clear:both}.edui-default .edui-tablepicker .edui-infoarea .edui-label{float:left}.edui-default .edui-dialog-buttons .edui-label{line-height:24px}.edui-default .edui-tablepicker .edui-infoarea .edui-clickable{float:right}.edui-default .edui-tablepicker .edui-pickarea{background:url(../images/unhighlighted.gif) repeat;height:220px;width:220px}.edui-default .edui-tablepicker .edui-pickarea .edui-overlay{background:url(../images/highlighted.gif) repeat}.edui-default .edui-colorpicker-topbar{height:27px;width:200px}.edui-default .edui-colorpicker-preview{height:20px;border:1px inset #000;margin-left:1px;width:128px;float:left}.edui-default .edui-colorpicker-nocolor{float:right;margin-right:1px;font-size:12px;line-height:14px;height:14px;border:1px solid #333;padding:3px 5px;cursor:pointer}.edui-default .edui-colorpicker-tablefirstrow{height:30px}.edui-default .edui-colorpicker-colorcell{width:14px;height:14px;display:block;margin:0;cursor:pointer}.edui-default .edui-colorpicker-colorcell:hover{width:14px;height:14px;margin:0}.edui-default .edui-colorpicker-advbtn{display:block;text-align:center;cursor:pointer;height:20px}.arrow_down{background:#fff url(../images/arrow_down.png) no-repeat center}.arrow_up{background:#fff url(../images/arrow_up.png) no-repeat center}.edui-colorpicker-adv{position:relative;overflow:hidden;height:180px;display:none}.edui-colorpicker-plant,.edui-colorpicker-hue{border:solid 1px #666}.edui-colorpicker-pad{width:150px;height:150px;left:14px;top:13px;position:absolute;background:red;overflow:hidden;cursor:crosshair}.edui-colorpicker-cover{position:absolute;top:0;left:0;width:150px;height:150px;background:url(../images/tangram-colorpicker.png) -160px -200px}.edui-colorpicker-padDot{position:absolute;top:0;left:0;width:11px;height:11px;overflow:hidden;background:url(../images/tangram-colorpicker.png) 0 -200px repeat-x;z-index:1000}.edui-colorpicker-sliderMain{position:absolute;left:171px;top:13px;width:19px;height:152px;background:url(../images/tangram-colorpicker.png) -179px -12px no-repeat}.edui-colorpicker-slider{width:100%;height:100%;cursor:pointer}.edui-colorpicker-thumb{position:absolute;top:0;cursor:pointer;height:3px;left:-1px;right:-1px;border:1px solid #000;background:#fff;opacity:.8}.edui-default .edui-autotypesetpicker .edui-autotypesetpicker-body{font-size:12px;margin-bottom:3px;clear:both}.edui-default .edui-autotypesetpicker-body table{border-collapse:separate;border-spacing:2px}.edui-default .edui-autotypesetpicker-body td{font-size:12px;word-wrap:break-word}.edui-default .edui-autotypesetpicker-body td input{margin:3px 3px 3px 4px;*margin:1px 0 0}.edui-default .edui-cellalignpicker .edui-cellalignpicker-body{width:70px;font-size:12px;cursor:default}.edui-default .edui-cellalignpicker-body table{border-collapse:separate;border-spacing:0}.edui-default .edui-cellalignpicker-body td{padding:1px}.edui-default .edui-cellalignpicker-body .edui-icon{height:20px;width:20px;padding:1px;background-image:url(../images/table-cell-align.png)}.edui-default .edui-cellalignpicker-body .edui-left{background-position:0 0}.edui-default .edui-cellalignpicker-body .edui-center{background-position:-25px 0}.edui-default .edui-cellalignpicker-body .edui-right{background-position:-51px 0}.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-left{background-position:-73px 0}.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-center{background-position:-98px 0}.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-right{background-position:-124px 0}.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-left{background-position:-146px 0;background-color:#f1f4f5}.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-center{background-position:-245px 0}.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-right{background-position:-271px 0}.edui-default .edui-toolbar .edui-separator{width:2px;height:20px;margin:2px 4px 2px 3px;background:url(../images/icons.png) -181px 0;background:url(../images/icons.gif) -181px 0 \9}.edui-default .edui-toolbar .edui-colorbutton .edui-colorlump{position:absolute;overflow:hidden;bottom:1px;left:1px;width:18px;height:4px}.edui-default .edui-for-emotion .edui-icon{background-position:-60px -20px}.edui-default .edui-for-emotion .edui-popup-content iframe{width:514px;height:380px;overflow:hidden}.edui-default .edui-for-emotion .edui-popup-content{position:relative;z-index:555}.edui-default .edui-for-emotion .edui-splitborder{display:none}.edui-default .edui-for-emotion .edui-splitbutton-body .edui-arrow{width:0}.edui-default .edui-toolbar .edui-for-emotion .edui-state-active .edui-splitborder{border-left:1px solid transparent}.edui-default .edui-hassubmenu .edui-arrow{height:20px;width:20px;float:right;background:url(../images/icons-all.gif) no-repeat 10px -233px}.edui-default .edui-menu-body .edui-menuitem{padding:1px}.edui-default .edui-menuseparator{margin:2px 0;height:1px;overflow:hidden}.edui-default .edui-menuseparator-inner{border-bottom:1px solid #e2e3e3;margin-left:29px;margin-right:1px}.edui-default .edui-menu-body .edui-state-hover{padding:0!important;background-color:#fff5d4;border:1px solid #dcac6c}.edui-default .edui-shortcutmenu{padding:2px;width:190px;height:50px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.edui-default .edui-wordpastepop .edui-popup-content{border:0;padding:0;width:54px;height:21px}.edui-default .edui-pasteicon{width:100%;height:100%;background-image:url(../images/wordpaste.png);background-position:0 0}.edui-default .edui-pasteicon.edui-state-opened{background-position:0 -34px}.edui-default .edui-pastecontainer{position:relative;visibility:hidden;width:97px;background:#fff;border:1px solid #ccc}.edui-default .edui-pastecontainer .edui-title{font-weight:700;background:#F8F8FF;height:25px;line-height:25px;font-size:12px;padding-left:5px}.edui-default .edui-pastecontainer .edui-button{overflow:hidden;margin:3px 0}.edui-default .edui-pastecontainer .edui-button .edui-richtxticon,.edui-default .edui-pastecontainer .edui-button .edui-tagicon,.edui-default .edui-pastecontainer .edui-button .edui-plaintxticon{float:left;cursor:pointer;width:29px;height:29px;margin-left:5px;background-image:url(../images/wordpaste.png);background-repeat:no-repeat}.edui-default .edui-pastecontainer .edui-button .edui-richtxticon{margin-left:0;background-position:-109px 0}.edui-default .edui-pastecontainer .edui-button .edui-tagicon{background-position:-148px 1px}.edui-default .edui-pastecontainer .edui-button .edui-plaintxticon{background-position:-72px 0}.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-richtxticon{background-position:-109px -34px}.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-tagicon{background-position:-148px -34px}.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-plaintxticon{background-position:-72px -34px}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/dialogbase.css
New file
@@ -0,0 +1,100 @@
/*弹出对话框页面样式组件
*/
/*reset
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
    margin: 0;
    padding: 0;
    outline: 0;
    font-size: 100%;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
ins {
    text-decoration: none;
}
del {
    text-decoration: line-through;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}
/*module
*/
body {
    background-color: #fff;
    font: 12px/1.5 sans-serif, "宋体", "Arial Narrow", HELVETICA;
    color: #646464;
}
/*tab*/
.tabhead {
    position: relative;
    z-index: 10;
}
.tabhead span {
    display: inline-block;
    padding: 0 5px;
    height: 30px;
    border: 1px solid #ccc;
    background: url("images/dialog-title-bg.png") repeat-x;
    text-align: center;
    line-height: 30px;
    cursor: pointer;
    *margin-right: 5px;
}
.tabhead span.focus {
    height: 31px;
    border-bottom: none;
    background: #fff;
}
.tabbody {
    position: relative;
    top: -1px;
    margin: 0 auto;
    border: 1px solid #ccc;
}
/*button*/
a.button {
    display: block;
    text-align: center;
    line-height: 24px;
    text-decoration: none;
    height: 24px;
    width: 95px;
    border: 0;
    color: #838383;
    background: url(../../themes/default/images/icons-all.gif) no-repeat;
}
a.button:hover {
    background-position: 0 -30px;
}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/anchor.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/arrow.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/arrow_down.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/arrow_up.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/button-bg.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cancelbutton.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/charts.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_h.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_h.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_v.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/cursor_v.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/dialog-title-bg.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/filescan.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/highlighted.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/icons-all.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/icons.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/icons.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/loaderror.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/loading.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/lock.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/neweditor-tab-bg.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/pagebreak.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/scale.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/sortable.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/spacer.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/sparator_v.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/table-cell-align.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/tangram-colorpicker.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/toolbar_bg.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/unhighlighted.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/upload.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/videologo.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/word.gif
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/default/images/wordpaste.png
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/themes/iframe.css
New file
@@ -0,0 +1 @@
/*可以在这里添加你自己的css*/
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/SyntaxHighlighter/shCore.js
New file
@@ -0,0 +1,3655 @@
// XRegExp 1.5.1
// (c) 2007-2012 Steven Levithan
// MIT License
// <http://xregexp.com>
// Provides an augmented, extensible, cross-browser implementation of regular expressions,
// including support for additional syntax, flags, and methods
var XRegExp;
if (XRegExp) {
    // Avoid running twice, since that would break references to native globals
    throw Error("can't load XRegExp twice in the same frame");
}
// Run within an anonymous function to protect variables and avoid new globals
(function (undefined) {
    //---------------------------------
    //  Constructor
    //---------------------------------
    // Accepts a pattern and flags; returns a new, extended `RegExp` object. Differs from a native
    // regular expression in that additional syntax and flags are supported and cross-browser
    // syntax inconsistencies are ameliorated. `XRegExp(/regex/)` clones an existing regex and
    // converts to type XRegExp
    XRegExp = function (pattern, flags) {
        var output = [],
            currScope = XRegExp.OUTSIDE_CLASS,
            pos = 0,
            context, tokenResult, match, chr, regex;
        if (XRegExp.isRegExp(pattern)) {
            if (flags !== undefined)
                throw TypeError("can't supply flags when constructing one RegExp from another");
            return clone(pattern);
        }
        // Tokens become part of the regex construction process, so protect against infinite
        // recursion when an XRegExp is constructed within a token handler or trigger
        if (isInsideConstructor)
            throw Error("can't call the XRegExp constructor within token definition functions");
        flags = flags || "";
        context = { // `this` object for custom tokens
            hasNamedCapture: false,
            captureNames: [],
            hasFlag: function (flag) {return flags.indexOf(flag) > -1;},
            setFlag: function (flag) {flags += flag;}
        };
        while (pos < pattern.length) {
            // Check for custom tokens at the current position
            tokenResult = runTokens(pattern, pos, currScope, context);
            if (tokenResult) {
                output.push(tokenResult.output);
                pos += (tokenResult.match[0].length || 1);
            } else {
                // Check for native multicharacter metasequences (excluding character classes) at
                // the current position
                if (match = nativ.exec.call(nativeTokens[currScope], pattern.slice(pos))) {
                    output.push(match[0]);
                    pos += match[0].length;
                } else {
                    chr = pattern.charAt(pos);
                    if (chr === "[")
                        currScope = XRegExp.INSIDE_CLASS;
                    else if (chr === "]")
                        currScope = XRegExp.OUTSIDE_CLASS;
                    // Advance position one character
                    output.push(chr);
                    pos++;
                }
            }
        }
        regex = RegExp(output.join(""), nativ.replace.call(flags, flagClip, ""));
        regex._xregexp = {
            source: pattern,
            captureNames: context.hasNamedCapture ? context.captureNames : null
        };
        return regex;
    };
    //---------------------------------
    //  Public properties
    //---------------------------------
    XRegExp.version = "1.5.1";
    // Token scope bitflags
    XRegExp.INSIDE_CLASS = 1;
    XRegExp.OUTSIDE_CLASS = 2;
    //---------------------------------
    //  Private variables
    //---------------------------------
    var replacementToken = /\$(?:(\d\d?|[$&`'])|{([$\w]+)})/g,
        flagClip = /[^gimy]+|([\s\S])(?=[\s\S]*\1)/g, // Nonnative and duplicate flags
        quantifier = /^(?:[?*+]|{\d+(?:,\d*)?})\??/,
        isInsideConstructor = false,
        tokens = [],
    // Copy native globals for reference ("native" is an ES3 reserved keyword)
        nativ = {
            exec: RegExp.prototype.exec,
            test: RegExp.prototype.test,
            match: String.prototype.match,
            replace: String.prototype.replace,
            split: String.prototype.split
        },
        compliantExecNpcg = nativ.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
        compliantLastIndexIncrement = function () {
            var x = /^/g;
            nativ.test.call(x, "");
            return !x.lastIndex;
        }(),
        hasNativeY = RegExp.prototype.sticky !== undefined,
        nativeTokens = {};
    // `nativeTokens` match native multicharacter metasequences only (including deprecated octals,
    // excluding character classes)
    nativeTokens[XRegExp.INSIDE_CLASS] = /^(?:\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S]))/;
    nativeTokens[XRegExp.OUTSIDE_CLASS] = /^(?:\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??)/;
    //---------------------------------
    //  Public methods
    //---------------------------------
    // Lets you extend or change XRegExp syntax and create custom flags. This is used internally by
    // the XRegExp library and can be used to create XRegExp plugins. This function is intended for
    // users with advanced knowledge of JavaScript's regular expression syntax and behavior. It can
    // be disabled by `XRegExp.freezeTokens`
    XRegExp.addToken = function (regex, handler, scope, trigger) {
        tokens.push({
            pattern: clone(regex, "g" + (hasNativeY ? "y" : "")),
            handler: handler,
            scope: scope || XRegExp.OUTSIDE_CLASS,
            trigger: trigger || null
        });
    };
    // Accepts a pattern and flags; returns an extended `RegExp` object. If the pattern and flag
    // combination has previously been cached, the cached copy is returned; otherwise the newly
    // created regex is cached
    XRegExp.cache = function (pattern, flags) {
        var key = pattern + "/" + (flags || "");
        return XRegExp.cache[key] || (XRegExp.cache[key] = XRegExp(pattern, flags));
    };
    // Accepts a `RegExp` instance; returns a copy with the `/g` flag set. The copy has a fresh
    // `lastIndex` (set to zero). If you want to copy a regex without forcing the `global`
    // property, use `XRegExp(regex)`. Do not use `RegExp(regex)` because it will not preserve
    // special properties required for named capture
    XRegExp.copyAsGlobal = function (regex) {
        return clone(regex, "g");
    };
    // Accepts a string; returns the string with regex metacharacters escaped. The returned string
    // can safely be used at any point within a regex to match the provided literal string. Escaped
    // characters are [ ] { } ( ) * + ? - . , \ ^ $ | # and whitespace
    XRegExp.escape = function (str) {
        return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    };
    // Accepts a string to search, regex to search with, position to start the search within the
    // string (default: 0), and an optional Boolean indicating whether matches must start at-or-
    // after the position or at the specified position only. This function ignores the `lastIndex`
    // of the provided regex in its own handling, but updates the property for compatibility
    XRegExp.execAt = function (str, regex, pos, anchored) {
        var r2 = clone(regex, "g" + ((anchored && hasNativeY) ? "y" : "")),
            match;
        r2.lastIndex = pos = pos || 0;
        match = r2.exec(str); // Run the altered `exec` (required for `lastIndex` fix, etc.)
        if (anchored && match && match.index !== pos)
            match = null;
        if (regex.global)
            regex.lastIndex = match ? r2.lastIndex : 0;
        return match;
    };
    // Breaks the unrestorable link to XRegExp's private list of tokens, thereby preventing
    // syntax and flag changes. Should be run after XRegExp and any plugins are loaded
    XRegExp.freezeTokens = function () {
        XRegExp.addToken = function () {
            throw Error("can't run addToken after freezeTokens");
        };
    };
    // Accepts any value; returns a Boolean indicating whether the argument is a `RegExp` object.
    // Note that this is also `true` for regex literals and regexes created by the `XRegExp`
    // constructor. This works correctly for variables created in another frame, when `instanceof`
    // and `constructor` checks would fail to work as intended
    XRegExp.isRegExp = function (o) {
        return Object.prototype.toString.call(o) === "[object RegExp]";
    };
    // Executes `callback` once per match within `str`. Provides a simpler and cleaner way to
    // iterate over regex matches compared to the traditional approaches of subverting
    // `String.prototype.replace` or repeatedly calling `exec` within a `while` loop
    XRegExp.iterate = function (str, regex, callback, context) {
        var r2 = clone(regex, "g"),
            i = -1, match;
        while (match = r2.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.)
            if (regex.global)
                regex.lastIndex = r2.lastIndex; // Doing this to follow expectations if `lastIndex` is checked within `callback`
            callback.call(context, match, ++i, str, regex);
            if (r2.lastIndex === match.index)
                r2.lastIndex++;
        }
        if (regex.global)
            regex.lastIndex = 0;
    };
    // Accepts a string and an array of regexes; returns the result of using each successive regex
    // to search within the matches of the previous regex. The array of regexes can also contain
    // objects with `regex` and `backref` properties, in which case the named or numbered back-
    // references specified are passed forward to the next regex or returned. E.g.:
    // var xregexpImgFileNames = XRegExp.matchChain(html, [
    //     {regex: /<img\b([^>]+)>/i, backref: 1}, // <img> tag attributes
    //     {regex: XRegExp('(?ix) \\s src=" (?<src> [^"]+ )'), backref: "src"}, // src attribute values
    //     {regex: XRegExp("^http://xregexp\\.com(/[^#?]+)", "i"), backref: 1}, // xregexp.com paths
    //     /[^\/]+$/ // filenames (strip directory paths)
    // ]);
    XRegExp.matchChain = function (str, chain) {
        return function recurseChain (values, level) {
            var item = chain[level].regex ? chain[level] : {regex: chain[level]},
                regex = clone(item.regex, "g"),
                matches = [], i;
            for (i = 0; i < values.length; i++) {
                XRegExp.iterate(values[i], regex, function (match) {
                    matches.push(item.backref ? (match[item.backref] || "") : match[0]);
                });
            }
            return ((level === chain.length - 1) || !matches.length) ?
                matches : recurseChain(matches, level + 1);
        }([str], 0);
    };
    //---------------------------------
    //  New RegExp prototype methods
    //---------------------------------
    // Accepts a context object and arguments array; returns the result of calling `exec` with the
    // first value in the arguments array. the context is ignored but is accepted for congruity
    // with `Function.prototype.apply`
    RegExp.prototype.apply = function (context, args) {
        return this.exec(args[0]);
    };
    // Accepts a context object and string; returns the result of calling `exec` with the provided
    // string. the context is ignored but is accepted for congruity with `Function.prototype.call`
    RegExp.prototype.call = function (context, str) {
        return this.exec(str);
    };
    //---------------------------------
    //  Overriden native methods
    //---------------------------------
    // Adds named capture support (with backreferences returned as `result.name`), and fixes two
    // cross-browser issues per ES3:
    // - Captured values for nonparticipating capturing groups should be returned as `undefined`,
    //   rather than the empty string.
    // - `lastIndex` should not be incremented after zero-length matches.
    RegExp.prototype.exec = function (str) {
        var match, name, r2, origLastIndex;
        if (!this.global)
            origLastIndex = this.lastIndex;
        match = nativ.exec.apply(this, arguments);
        if (match) {
            // Fix browsers whose `exec` methods don't consistently return `undefined` for
            // nonparticipating capturing groups
            if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
                r2 = RegExp(this.source, nativ.replace.call(getNativeFlags(this), "g", ""));
                // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed
                // matching due to characters outside the match
                nativ.replace.call((str + "").slice(match.index), r2, function () {
                    for (var i = 1; i < arguments.length - 2; i++) {
                        if (arguments[i] === undefined)
                            match[i] = undefined;
                    }
                });
            }
            // Attach named capture properties
            if (this._xregexp && this._xregexp.captureNames) {
                for (var i = 1; i < match.length; i++) {
                    name = this._xregexp.captureNames[i - 1];
                    if (name)
                        match[name] = match[i];
                }
            }
            // Fix browsers that increment `lastIndex` after zero-length matches
            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
                this.lastIndex--;
        }
        if (!this.global)
            this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)
        return match;
    };
    // Fix browser bugs in native method
    RegExp.prototype.test = function (str) {
        // Use the native `exec` to skip some processing overhead, even though the altered
        // `exec` would take care of the `lastIndex` fixes
        var match, origLastIndex;
        if (!this.global)
            origLastIndex = this.lastIndex;
        match = nativ.exec.call(this, str);
        // Fix browsers that increment `lastIndex` after zero-length matches
        if (match && !compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
            this.lastIndex--;
        if (!this.global)
            this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)
        return !!match;
    };
    // Adds named capture support and fixes browser bugs in native method
    String.prototype.match = function (regex) {
        if (!XRegExp.isRegExp(regex))
            regex = RegExp(regex); // Native `RegExp`
        if (regex.global) {
            var result = nativ.match.apply(this, arguments);
            regex.lastIndex = 0; // Fix IE bug
            return result;
        }
        return regex.exec(this); // Run the altered `exec`
    };
    // Adds support for `${n}` tokens for named and numbered backreferences in replacement text,
    // and provides named backreferences to replacement functions as `arguments[0].name`. Also
    // fixes cross-browser differences in replacement text syntax when performing a replacement
    // using a nonregex search value, and the value of replacement regexes' `lastIndex` property
    // during replacement iterations. Note that this doesn't support SpiderMonkey's proprietary
    // third (`flags`) parameter
    String.prototype.replace = function (search, replacement) {
        var isRegex = XRegExp.isRegExp(search),
            captureNames, result, str, origLastIndex;
        // There are too many combinations of search/replacement types/values and browser bugs that
        // preclude passing to native `replace`, so don't try
        //if (...)
        //    return nativ.replace.apply(this, arguments);
        if (isRegex) {
            if (search._xregexp)
                captureNames = search._xregexp.captureNames; // Array or `null`
            if (!search.global)
                origLastIndex = search.lastIndex;
        } else {
            search = search + ""; // Type conversion
        }
        if (Object.prototype.toString.call(replacement) === "[object Function]") {
            result = nativ.replace.call(this + "", search, function () {
                if (captureNames) {
                    // Change the `arguments[0]` string primitive to a String object which can store properties
                    arguments[0] = new String(arguments[0]);
                    // Store named backreferences on `arguments[0]`
                    for (var i = 0; i < captureNames.length; i++) {
                        if (captureNames[i])
                            arguments[0][captureNames[i]] = arguments[i + 1];
                    }
                }
                // Update `lastIndex` before calling `replacement` (fix browsers)
                if (isRegex && search.global)
                    search.lastIndex = arguments[arguments.length - 2] + arguments[0].length;
                return replacement.apply(null, arguments);
            });
        } else {
            str = this + ""; // Type conversion, so `args[args.length - 1]` will be a string (given nonstring `this`)
            result = nativ.replace.call(str, search, function () {
                var args = arguments; // Keep this function's `arguments` available through closure
                return nativ.replace.call(replacement + "", replacementToken, function ($0, $1, $2) {
                    // Numbered backreference (without delimiters) or special variable
                    if ($1) {
                        switch ($1) {
                            case "$": return "$";
                            case "&": return args[0];
                            case "`": return args[args.length - 1].slice(0, args[args.length - 2]);
                            case "'": return args[args.length - 1].slice(args[args.length - 2] + args[0].length);
                            // Numbered backreference
                            default:
                                // What does "$10" mean?
                                // - Backreference 10, if 10 or more capturing groups exist
                                // - Backreference 1 followed by "0", if 1-9 capturing groups exist
                                // - Otherwise, it's the string "$10"
                                // Also note:
                                // - Backreferences cannot be more than two digits (enforced by `replacementToken`)
                                // - "$01" is equivalent to "$1" if a capturing group exists, otherwise it's the string "$01"
                                // - There is no "$0" token ("$&" is the entire match)
                                var literalNumbers = "";
                                $1 = +$1; // Type conversion; drop leading zero
                                if (!$1) // `$1` was "0" or "00"
                                    return $0;
                                while ($1 > args.length - 3) {
                                    literalNumbers = String.prototype.slice.call($1, -1) + literalNumbers;
                                    $1 = Math.floor($1 / 10); // Drop the last digit
                                }
                                return ($1 ? args[$1] || "" : "$") + literalNumbers;
                        }
                        // Named backreference or delimited numbered backreference
                    } else {
                        // What does "${n}" mean?
                        // - Backreference to numbered capture n. Two differences from "$n":
                        //   - n can be more than two digits
                        //   - Backreference 0 is allowed, and is the entire match
                        // - Backreference to named capture n, if it exists and is not a number overridden by numbered capture
                        // - Otherwise, it's the string "${n}"
                        var n = +$2; // Type conversion; drop leading zeros
                        if (n <= args.length - 3)
                            return args[n];
                        n = captureNames ? indexOf(captureNames, $2) : -1;
                        return n > -1 ? args[n + 1] : $0;
                    }
                });
            });
        }
        if (isRegex) {
            if (search.global)
                search.lastIndex = 0; // Fix IE, Safari bug (last tested IE 9.0.5, Safari 5.1.2 on Windows)
            else
                search.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)
        }
        return result;
    };
    // A consistent cross-browser, ES3 compliant `split`
    String.prototype.split = function (s /* separator */, limit) {
        // If separator `s` is not a regex, use the native `split`
        if (!XRegExp.isRegExp(s))
            return nativ.split.apply(this, arguments);
        var str = this + "", // Type conversion
            output = [],
            lastLastIndex = 0,
            match, lastLength;
        // Behavior for `limit`: if it's...
        // - `undefined`: No limit
        // - `NaN` or zero: Return an empty array
        // - A positive number: Use `Math.floor(limit)`
        // - A negative number: No limit
        // - Other: Type-convert, then use the above rules
        if (limit === undefined || +limit < 0) {
            limit = Infinity;
        } else {
            limit = Math.floor(+limit);
            if (!limit)
                return [];
        }
        // This is required if not `s.global`, and it avoids needing to set `s.lastIndex` to zero
        // and restore it to its original value when we're done using the regex
        s = XRegExp.copyAsGlobal(s);
        while (match = s.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.)
            if (s.lastIndex > lastLastIndex) {
                output.push(str.slice(lastLastIndex, match.index));
                if (match.length > 1 && match.index < str.length)
                    Array.prototype.push.apply(output, match.slice(1));
                lastLength = match[0].length;
                lastLastIndex = s.lastIndex;
                if (output.length >= limit)
                    break;
            }
            if (s.lastIndex === match.index)
                s.lastIndex++;
        }
        if (lastLastIndex === str.length) {
            if (!nativ.test.call(s, "") || lastLength)
                output.push("");
        } else {
            output.push(str.slice(lastLastIndex));
        }
        return output.length > limit ? output.slice(0, limit) : output;
    };
    //---------------------------------
    //  Private helper functions
    //---------------------------------
    // Supporting function for `XRegExp`, `XRegExp.copyAsGlobal`, etc. Returns a copy of a `RegExp`
    // instance with a fresh `lastIndex` (set to zero), preserving properties required for named
    // capture. Also allows adding new flags in the process of copying the regex
    function clone (regex, additionalFlags) {
        if (!XRegExp.isRegExp(regex))
            throw TypeError("type RegExp expected");
        var x = regex._xregexp;
        regex = XRegExp(regex.source, getNativeFlags(regex) + (additionalFlags || ""));
        if (x) {
            regex._xregexp = {
                source: x.source,
                captureNames: x.captureNames ? x.captureNames.slice(0) : null
            };
        }
        return regex;
    }
    function getNativeFlags (regex) {
        return (regex.global     ? "g" : "") +
            (regex.ignoreCase ? "i" : "") +
            (regex.multiline  ? "m" : "") +
            (regex.extended   ? "x" : "") + // Proposed for ES4; included in AS3
            (regex.sticky     ? "y" : "");
    }
    function runTokens (pattern, index, scope, context) {
        var i = tokens.length,
            result, match, t;
        // Protect against constructing XRegExps within token handler and trigger functions
        isInsideConstructor = true;
        // Must reset `isInsideConstructor`, even if a `trigger` or `handler` throws
        try {
            while (i--) { // Run in reverse order
                t = tokens[i];
                if ((scope & t.scope) && (!t.trigger || t.trigger.call(context))) {
                    t.pattern.lastIndex = index;
                    match = t.pattern.exec(pattern); // Running the altered `exec` here allows use of named backreferences, etc.
                    if (match && match.index === index) {
                        result = {
                            output: t.handler.call(context, match, scope),
                            match: match
                        };
                        break;
                    }
                }
            }
        } catch (err) {
            throw err;
        } finally {
            isInsideConstructor = false;
        }
        return result;
    }
    function indexOf (array, item, from) {
        if (Array.prototype.indexOf) // Use the native array method if available
            return array.indexOf(item, from);
        for (var i = from || 0; i < array.length; i++) {
            if (array[i] === item)
                return i;
        }
        return -1;
    }
    //---------------------------------
    //  Built-in tokens
    //---------------------------------
    // Augment XRegExp's regular expression syntax and flags. Note that when adding tokens, the
    // third (`scope`) argument defaults to `XRegExp.OUTSIDE_CLASS`
    // Comment pattern: (?# )
    XRegExp.addToken(
        /\(\?#[^)]*\)/,
        function (match) {
            // Keep tokens separated unless the following token is a quantifier
            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)";
        }
    );
    // Capturing group (match the opening parenthesis only).
    // Required for support of named capturing groups
    XRegExp.addToken(
        /\((?!\?)/,
        function () {
            this.captureNames.push(null);
            return "(";
        }
    );
    // Named capturing group (match the opening delimiter only): (?<name>
    XRegExp.addToken(
        /\(\?<([$\w]+)>/,
        function (match) {
            this.captureNames.push(match[1]);
            this.hasNamedCapture = true;
            return "(";
        }
    );
    // Named backreference: \k<name>
    XRegExp.addToken(
        /\\k<([\w$]+)>/,
        function (match) {
            var index = indexOf(this.captureNames, match[1]);
            // Keep backreferences separate from subsequent literal numbers. Preserve back-
            // references to named groups that are undefined at this point as literal strings
            return index > -1 ?
                "\\" + (index + 1) + (isNaN(match.input.charAt(match.index + match[0].length)) ? "" : "(?:)") :
                match[0];
        }
    );
    // Empty character class: [] or [^]
    XRegExp.addToken(
        /\[\^?]/,
        function (match) {
            // For cross-browser compatibility with ES3, convert [] to \b\B and [^] to [\s\S].
            // (?!) should work like \b\B, but is unreliable in Firefox
            return match[0] === "[]" ? "\\b\\B" : "[\\s\\S]";
        }
    );
    // Mode modifier at the start of the pattern only, with any combination of flags imsx: (?imsx)
    // Does not support x(?i), (?-i), (?i-m), (?i: ), (?i)(?m), etc.
    XRegExp.addToken(
        /^\(\?([imsx]+)\)/,
        function (match) {
            this.setFlag(match[1]);
            return "";
        }
    );
    // Whitespace and comments, in free-spacing (aka extended) mode only
    XRegExp.addToken(
        /(?:\s+|#.*)+/,
        function (match) {
            // Keep tokens separated unless the following token is a quantifier
            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)";
        },
        XRegExp.OUTSIDE_CLASS,
        function () {return this.hasFlag("x");}
    );
    // Dot, in dotall (aka singleline) mode only
    XRegExp.addToken(
        /\./,
        function () {return "[\\s\\S]";},
        XRegExp.OUTSIDE_CLASS,
        function () {return this.hasFlag("s");}
    );
    //---------------------------------
    //  Backward compatibility
    //---------------------------------
    // Uncomment the following block for compatibility with XRegExp 1.0-1.2:
    /*
     XRegExp.matchWithinChain = XRegExp.matchChain;
     RegExp.prototype.addFlags = function (s) {return clone(this, s);};
     RegExp.prototype.execAll = function (s) {var r = []; XRegExp.iterate(s, this, function (m) {r.push(m);}); return r;};
     RegExp.prototype.forEachExec = function (s, f, c) {return XRegExp.iterate(s, this, f, c);};
     RegExp.prototype.validate = function (s) {var r = RegExp("^(?:" + this.source + ")$(?!\\s)", getNativeFlags(this)); if (this.global) this.lastIndex = 0; return s.search(r) === 0;};
     */
})();
//
// Begin anonymous function. This is used to contain local scope variables without polutting global scope.
//
if (typeof(SyntaxHighlighter) == 'undefined') var SyntaxHighlighter = function() {
// CommonJS
    if (typeof(require) != 'undefined' && typeof(XRegExp) == 'undefined')
    {
        XRegExp = require('XRegExp').XRegExp;
    }
// Shortcut object which will be assigned to the SyntaxHighlighter variable.
// This is a shorthand for local reference in order to avoid long namespace
// references to SyntaxHighlighter.whatever...
    var sh = {
        defaults : {
            /** Additional CSS class names to be added to highlighter elements. */
            'class-name' : '',
            /** First line number. */
            'first-line' : 1,
            /**
             * Pads line numbers. Possible values are:
             *
             *   false - don't pad line numbers.
             *   true  - automaticaly pad numbers with minimum required number of leading zeroes.
             *   [int] - length up to which pad line numbers.
             */
            'pad-line-numbers' : false,
            /** Lines to highlight. */
            'highlight' : false,
            /** Title to be displayed above the code block. */
            'title' : null,
            /** Enables or disables smart tabs. */
            'smart-tabs' : true,
            /** Gets or sets tab size. */
            'tab-size' : 4,
            /** Enables or disables gutter. */
            'gutter' : true,
            /** Enables or disables toolbar. */
            'toolbar' : true,
            /** Enables quick code copy and paste from double click. */
            'quick-code' : true,
            /** Forces code view to be collapsed. */
            'collapse' : false,
            /** Enables or disables automatic links. */
            'auto-links' : false,
            /** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */
            'light' : false,
            'unindent' : true,
            'html-script' : false
        },
        config : {
            space : '&nbsp;',
            /** Enables use of <SCRIPT type="syntaxhighlighter" /> tags. */
            useScriptTags : true,
            /** Blogger mode flag. */
            bloggerMode : false,
            stripBrs : false,
            /** Name of the tag that SyntaxHighlighter will automatically look for. */
            tagName : 'pre',
            strings : {
                expandSource : 'expand source',
                help : '?',
                alert: 'SyntaxHighlighter\n\n',
                noBrush : 'Can\'t find brush for: ',
                brushNotHtmlScript : 'Brush wasn\'t configured for html-script option: ',
                // this is populated by the build script
                aboutDialog : '@ABOUT@'
            }
        },
        /** Internal 'global' variables. */
        vars : {
            discoveredBrushes : null,
            highlighters : {}
        },
        /** This object is populated by user included external brush files. */
        brushes : {},
        /** Common regular expressions. */
        regexLib : {
            multiLineCComments            : /\/\*[\s\S]*?\*\//gm,
            singleLineCComments            : /\/\/.*$/gm,
            singleLinePerlComments        : /#.*$/gm,
            doubleQuotedString            : /"([^\\"\n]|\\.)*"/g,
            singleQuotedString            : /'([^\\'\n]|\\.)*'/g,
            multiLineDoubleQuotedString    : new XRegExp('"([^\\\\"]|\\\\.)*"', 'gs'),
            multiLineSingleQuotedString    : new XRegExp("'([^\\\\']|\\\\.)*'", 'gs'),
            xmlComments                    : /(&lt;|<)!--[\s\S]*?--(&gt;|>)/gm,
            url                            : /\w+:\/\/[\w-.\/?%&=:@;#]*/g,
            /** <?= ?> tags. */
            phpScriptTags                 : { left: /(&lt;|<)\?(?:=|php)?/g, right: /\?(&gt;|>)/g, 'eof' : true },
            /** <%= %> tags. */
            aspScriptTags                : { left: /(&lt;|<)%=?/g, right: /%(&gt;|>)/g },
            /** <script> tags. */
            scriptScriptTags            : { left: /(&lt;|<)\s*script.*?(&gt;|>)/gi, right: /(&lt;|<)\/\s*script\s*(&gt;|>)/gi }
        },
        toolbar: {
            /**
             * Generates HTML markup for the toolbar.
             * @param {Highlighter} highlighter Highlighter instance.
             * @return {String} Returns HTML markup.
             */
            getHtml: function(highlighter)
            {
                var html = '<div class="toolbar">',
                    items = sh.toolbar.items,
                    list = items.list
                    ;
                function defaultGetHtml(highlighter, name)
                {
                    return sh.toolbar.getButtonHtml(highlighter, name, sh.config.strings[name]);
                };
                for (var i = 0; i < list.length; i++)
                    html += (items[list[i]].getHtml || defaultGetHtml)(highlighter, list[i]);
                html += '</div>';
                return html;
            },
            /**
             * Generates HTML markup for a regular button in the toolbar.
             * @param {Highlighter} highlighter Highlighter instance.
             * @param {String} commandName        Command name that would be executed.
             * @param {String} label            Label text to display.
             * @return {String}                    Returns HTML markup.
             */
            getButtonHtml: function(highlighter, commandName, label)
            {
                return '<span><a href="#" class="toolbar_item'
                    + ' command_' + commandName
                    + ' ' + commandName
                    + '">' + label + '</a></span>'
                    ;
            },
            /**
             * Event handler for a toolbar anchor.
             */
            handler: function(e)
            {
                var target = e.target,
                    className = target.className || ''
                    ;
                function getValue(name)
                {
                    var r = new RegExp(name + '_(\\w+)'),
                        match = r.exec(className)
                        ;
                    return match ? match[1] : null;
                };
                var highlighter = getHighlighterById(findParentElement(target, '.syntaxhighlighter').id),
                    commandName = getValue('command')
                    ;
                // execute the toolbar command
                if (highlighter && commandName)
                    sh.toolbar.items[commandName].execute(highlighter);
                // disable default A click behaviour
                e.preventDefault();
            },
            /** Collection of toolbar items. */
            items : {
                // Ordered lis of items in the toolbar. Can't expect `for (var n in items)` to be consistent.
                list: ['expandSource', 'help'],
                expandSource: {
                    getHtml: function(highlighter)
                    {
                        if (highlighter.getParam('collapse') != true)
                            return '';
                        var title = highlighter.getParam('title');
                        return sh.toolbar.getButtonHtml(highlighter, 'expandSource', title ? title : sh.config.strings.expandSource);
                    },
                    execute: function(highlighter)
                    {
                        var div = getHighlighterDivById(highlighter.id);
                        removeClass(div, 'collapsed');
                    }
                },
                /** Command to display the about dialog window. */
                help: {
                    execute: function(highlighter)
                    {
                        var wnd = popup('', '_blank', 500, 250, 'scrollbars=0'),
                            doc = wnd.document
                            ;
                        doc.write(sh.config.strings.aboutDialog);
                        doc.close();
                        wnd.focus();
                    }
                }
            }
        },
        /**
         * Finds all elements on the page which should be processes by SyntaxHighlighter.
         *
         * @param {Object} globalParams        Optional parameters which override element's
         *                                     parameters. Only used if element is specified.
         *
         * @param {Object} element    Optional element to highlight. If none is
         *                             provided, all elements in the current document
         *                             are returned which qualify.
         *
         * @return {Array}    Returns list of <code>{ target: DOMElement, params: Object }</code> objects.
         */
        findElements: function(globalParams, element)
        {
            var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)),
                conf = sh.config,
                result = []
                ;
            // support for <SCRIPT TYPE="syntaxhighlighter" /> feature
            if (conf.useScriptTags)
                elements = elements.concat(getSyntaxHighlighterScriptTags());
            if (elements.length === 0)
                return result;
            for (var i = 0; i < elements.length; i++)
            {
                var item = {
                    target: elements[i],
                    // local params take precedence over globals
                    params: merge(globalParams, parseParams(elements[i].className))
                };
                if (item.params['brush'] == null)
                    continue;
                result.push(item);
            }
            return result;
        },
        /**
         * Shorthand to highlight all elements on the page that are marked as
         * SyntaxHighlighter source code.
         *
         * @param {Object} globalParams        Optional parameters which override element's
         *                                     parameters. Only used if element is specified.
         *
         * @param {Object} element    Optional element to highlight. If none is
         *                             provided, all elements in the current document
         *                             are highlighted.
         */
        highlight: function(globalParams, element)
        {
            var elements = this.findElements(globalParams, element),
                propertyName = 'innerHTML',
                highlighter = null,
                conf = sh.config
                ;
            if (elements.length === 0)
                return;
            for (var i = 0; i < elements.length; i++)
            {
                var element = elements[i],
                    target = element.target,
                    params = element.params,
                    brushName = params.brush,
                    code
                    ;
                if (brushName == null)
                    continue;
                // Instantiate a brush
                if (params['html-script'] == 'true' || sh.defaults['html-script'] == true)
                {
                    highlighter = new sh.HtmlScript(brushName);
                    brushName = 'htmlscript';
                }
                else
                {
                    var brush = findBrush(brushName);
                    if (brush)
                        highlighter = new brush();
                    else
                        continue;
                }
                code = target[propertyName];
                // remove CDATA from <SCRIPT/> tags if it's present
                if (conf.useScriptTags)
                    code = stripCData(code);
                // Inject title if the attribute is present
                if ((target.title || '') != '')
                    params.title = target.title;
                params['brush'] = brushName;
                highlighter.init(params);
                element = highlighter.getDiv(code);
                // carry over ID
                if ((target.id || '') != '')
                    element.id = target.id;
                //by zhanyi 去掉多余的外围div
                var tmp = element.firstChild.firstChild;
                tmp.className = element.firstChild.className;
                target.parentNode.replaceChild(tmp, target);
            }
        },
        /**
         * Main entry point for the SyntaxHighlighter.
         * @param {Object} params Optional params to apply to all highlighted elements.
         */
        all: function(params)
        {
            attachEvent(
                window,
                'load',
                function() { sh.highlight(params); }
            );
        }
    }; // end of sh
    /**
     * Checks if target DOM elements has specified CSS class.
     * @param {DOMElement} target Target DOM element to check.
     * @param {String} className Name of the CSS class to check for.
     * @return {Boolean} Returns true if class name is present, false otherwise.
     */
    function hasClass(target, className)
    {
        return target.className.indexOf(className) != -1;
    };
    /**
     * Adds CSS class name to the target DOM element.
     * @param {DOMElement} target Target DOM element.
     * @param {String} className New CSS class to add.
     */
    function addClass(target, className)
    {
        if (!hasClass(target, className))
            target.className += ' ' + className;
    };
    /**
     * Removes CSS class name from the target DOM element.
     * @param {DOMElement} target Target DOM element.
     * @param {String} className CSS class to remove.
     */
    function removeClass(target, className)
    {
        target.className = target.className.replace(className, '');
    };
    /**
     * Converts the source to array object. Mostly used for function arguments and
     * lists returned by getElementsByTagName() which aren't Array objects.
     * @param {List} source Source list.
     * @return {Array} Returns array.
     */
    function toArray(source)
    {
        var result = [];
        for (var i = 0; i < source.length; i++)
            result.push(source[i]);
        return result;
    };
    /**
     * Splits block of text into lines.
     * @param {String} block Block of text.
     * @return {Array} Returns array of lines.
     */
    function splitLines(block)
    {
        return block.split(/\r?\n/);
    }
    /**
     * Generates HTML ID for the highlighter.
     * @param {String} highlighterId Highlighter ID.
     * @return {String} Returns HTML ID.
     */
    function getHighlighterId(id)
    {
        var prefix = 'highlighter_';
        return id.indexOf(prefix) == 0 ? id : prefix + id;
    };
    /**
     * Finds Highlighter instance by ID.
     * @param {String} highlighterId Highlighter ID.
     * @return {Highlighter} Returns instance of the highlighter.
     */
    function getHighlighterById(id)
    {
        return sh.vars.highlighters[getHighlighterId(id)];
    };
    /**
     * Finds highlighter's DIV container.
     * @param {String} highlighterId Highlighter ID.
     * @return {Element} Returns highlighter's DIV element.
     */
    function getHighlighterDivById(id)
    {
        return document.getElementById(getHighlighterId(id));
    };
    /**
     * Stores highlighter so that getHighlighterById() can do its thing. Each
     * highlighter must call this method to preserve itself.
     * @param {Highilghter} highlighter Highlighter instance.
     */
    function storeHighlighter(highlighter)
    {
        sh.vars.highlighters[getHighlighterId(highlighter.id)] = highlighter;
    };
    /**
     * Looks for a child or parent node which has specified classname.
     * Equivalent to jQuery's $(container).find(".className")
     * @param {Element} target Target element.
     * @param {String} search Class name or node name to look for.
     * @param {Boolean} reverse If set to true, will go up the node tree instead of down.
     * @return {Element} Returns found child or parent element on null.
     */
    function findElement(target, search, reverse /* optional */)
    {
        if (target == null)
            return null;
        var nodes            = reverse != true ? target.childNodes : [ target.parentNode ],
            propertyToFind    = { '#' : 'id', '.' : 'className' }[search.substr(0, 1)] || 'nodeName',
            expectedValue,
            found
            ;
        expectedValue = propertyToFind != 'nodeName'
            ? search.substr(1)
            : search.toUpperCase()
        ;
        // main return of the found node
        if ((target[propertyToFind] || '').indexOf(expectedValue) != -1)
            return target;
        for (var i = 0; nodes && i < nodes.length && found == null; i++)
            found = findElement(nodes[i], search, reverse);
        return found;
    };
    /**
     * Looks for a parent node which has specified classname.
     * This is an alias to <code>findElement(container, className, true)</code>.
     * @param {Element} target Target element.
     * @param {String} className Class name to look for.
     * @return {Element} Returns found parent element on null.
     */
    function findParentElement(target, className)
    {
        return findElement(target, className, true);
    };
    /**
     * Finds an index of element in the array.
     * @ignore
     * @param {Object} searchElement
     * @param {Number} fromIndex
     * @return {Number} Returns index of element if found; -1 otherwise.
     */
    function indexOf(array, searchElement, fromIndex)
    {
        fromIndex = Math.max(fromIndex || 0, 0);
        for (var i = fromIndex; i < array.length; i++)
            if(array[i] == searchElement)
                return i;
        return -1;
    };
    /**
     * Generates a unique element ID.
     */
    function guid(prefix)
    {
        return (prefix || '') + Math.round(Math.random() * 1000000).toString();
    };
    /**
     * Merges two objects. Values from obj2 override values in obj1.
     * Function is NOT recursive and works only for one dimensional objects.
     * @param {Object} obj1 First object.
     * @param {Object} obj2 Second object.
     * @return {Object} Returns combination of both objects.
     */
    function merge(obj1, obj2)
    {
        var result = {}, name;
        for (name in obj1)
            result[name] = obj1[name];
        for (name in obj2)
            result[name] = obj2[name];
        return result;
    };
    /**
     * Attempts to convert string to boolean.
     * @param {String} value Input string.
     * @return {Boolean} Returns true if input was "true", false if input was "false" and value otherwise.
     */
    function toBoolean(value)
    {
        var result = { "true" : true, "false" : false }[value];
        return result == null ? value : result;
    };
    /**
     * Opens up a centered popup window.
     * @param {String} url        URL to open in the window.
     * @param {String} name        Popup name.
     * @param {int} width        Popup width.
     * @param {int} height        Popup height.
     * @param {String} options    window.open() options.
     * @return {Window}            Returns window instance.
     */
    function popup(url, name, width, height, options)
    {
        var x = (screen.width - width) / 2,
            y = (screen.height - height) / 2
            ;
        options +=    ', left=' + x +
            ', top=' + y +
            ', width=' + width +
            ', height=' + height
        ;
        options = options.replace(/^,/, '');
        var win = window.open(url, name, options);
        win.focus();
        return win;
    };
    /**
     * Adds event handler to the target object.
     * @param {Object} obj        Target object.
     * @param {String} type        Name of the event.
     * @param {Function} func    Handling function.
     */
    function attachEvent(obj, type, func, scope)
    {
        function handler(e)
        {
            e = e || window.event;
            if (!e.target)
            {
                e.target = e.srcElement;
                e.preventDefault = function()
                {
                    this.returnValue = false;
                };
            }
            func.call(scope || window, e);
        };
        if (obj.attachEvent)
        {
            obj.attachEvent('on' + type, handler);
        }
        else
        {
            obj.addEventListener(type, handler, false);
        }
    };
    /**
     * Displays an alert.
     * @param {String} str String to display.
     */
    function alert(str)
    {
        window.alert(sh.config.strings.alert + str);
    };
    /**
     * Finds a brush by its alias.
     *
     * @param {String} alias        Brush alias.
     * @param {Boolean} showAlert    Suppresses the alert if false.
     * @return {Brush}                Returns bursh constructor if found, null otherwise.
     */
    function findBrush(alias, showAlert)
    {
        var brushes = sh.vars.discoveredBrushes,
            result = null
            ;
        if (brushes == null)
        {
            brushes = {};
            // Find all brushes
            for (var brush in sh.brushes)
            {
                var info = sh.brushes[brush],
                    aliases = info.aliases
                    ;
                if (aliases == null)
                    continue;
                // keep the brush name
                info.brushName = brush.toLowerCase();
                for (var i = 0; i < aliases.length; i++)
                    brushes[aliases[i]] = brush;
            }
            sh.vars.discoveredBrushes = brushes;
        }
        result = sh.brushes[brushes[alias]];
        if (result == null && showAlert)
            alert(sh.config.strings.noBrush + alias);
        return result;
    };
    /**
     * Executes a callback on each line and replaces each line with result from the callback.
     * @param {Object} str            Input string.
     * @param {Object} callback        Callback function taking one string argument and returning a string.
     */
    function eachLine(str, callback)
    {
        var lines = splitLines(str);
        for (var i = 0; i < lines.length; i++)
            lines[i] = callback(lines[i], i);
        // include \r to enable copy-paste on windows (ie8) without getting everything on one line
        return lines.join('\r\n');
    };
    /**
     * This is a special trim which only removes first and last empty lines
     * and doesn't affect valid leading space on the first line.
     *
     * @param {String} str   Input string
     * @return {String}      Returns string without empty first and last lines.
     */
    function trimFirstAndLastLines(str)
    {
        return str.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g, '');
    };
    /**
     * Parses key/value pairs into hash object.
     *
     * Understands the following formats:
     * - name: word;
     * - name: [word, word];
     * - name: "string";
     * - name: 'string';
     *
     * For example:
     *   name1: value; name2: [value, value]; name3: 'value'
     *
     * @param {String} str    Input string.
     * @return {Object}       Returns deserialized object.
     */
    function parseParams(str)
    {
        var match,
            result = {},
            arrayRegex = new XRegExp("^\\[(?<values>(.*?))\\]$"),
            regex = new XRegExp(
                "(?<name>[\\w-]+)" +
                    "\\s*:\\s*" +
                    "(?<value>" +
                    "[\\w-%#]+|" +        // word
                    "\\[.*?\\]|" +        // [] array
                    '".*?"|' +            // "" string
                    "'.*?'" +            // '' string
                    ")\\s*;?",
                "g"
            )
            ;
        while ((match = regex.exec(str)) != null)
        {
            var value = match.value
                    .replace(/^['"]|['"]$/g, '') // strip quotes from end of strings
                ;
            // try to parse array value
            if (value != null && arrayRegex.test(value))
            {
                var m = arrayRegex.exec(value);
                value = m.values.length > 0 ? m.values.split(/\s*,\s*/) : [];
            }
            result[match.name] = value;
        }
        return result;
    };
    /**
     * Wraps each line of the string into <code/> tag with given style applied to it.
     *
     * @param {String} str   Input string.
     * @param {String} css   Style name to apply to the string.
     * @return {String}      Returns input string with each line surrounded by <span/> tag.
     */
    function wrapLinesWithCode(str, css)
    {
        if (str == null || str.length == 0 || str == '\n')
            return str;
        str = str.replace(/</g, '&lt;');
        // Replace two or more sequential spaces with &nbsp; leaving last space untouched.
        str = str.replace(/ {2,}/g, function(m)
        {
            var spaces = '';
            for (var i = 0; i < m.length - 1; i++)
                spaces += sh.config.space;
            return spaces + ' ';
        });
        // Split each line and apply <span class="...">...</span> to them so that
        // leading spaces aren't included.
        if (css != null)
            str = eachLine(str, function(line)
            {
                if (line.length == 0)
                    return '';
                var spaces = '';
                line = line.replace(/^(&nbsp;| )+/, function(s)
                {
                    spaces = s;
                    return '';
                });
                if (line.length == 0)
                    return spaces;
                return spaces + '<code class="' + css + '">' + line + '</code>';
            });
        return str;
    };
    /**
     * Pads number with zeros until it's length is the same as given length.
     *
     * @param {Number} number    Number to pad.
     * @param {Number} length    Max string length with.
     * @return {String}            Returns a string padded with proper amount of '0'.
     */
    function padNumber(number, length)
    {
        var result = number.toString();
        while (result.length < length)
            result = '0' + result;
        return result;
    };
    /**
     * Replaces tabs with spaces.
     *
     * @param {String} code        Source code.
     * @param {Number} tabSize    Size of the tab.
     * @return {String}            Returns code with all tabs replaces by spaces.
     */
    function processTabs(code, tabSize)
    {
        var tab = '';
        for (var i = 0; i < tabSize; i++)
            tab += ' ';
        return code.replace(/\t/g, tab);
    };
    /**
     * Replaces tabs with smart spaces.
     *
     * @param {String} code    Code to fix the tabs in.
     * @param {Number} tabSize Number of spaces in a column.
     * @return {String}        Returns code with all tabs replaces with roper amount of spaces.
     */
    function processSmartTabs(code, tabSize)
    {
        var lines = splitLines(code),
            tab = '\t',
            spaces = ''
            ;
        // Create a string with 1000 spaces to copy spaces from...
        // It's assumed that there would be no indentation longer than that.
        for (var i = 0; i < 50; i++)
            spaces += '                    '; // 20 spaces * 50
        // This function inserts specified amount of spaces in the string
        // where a tab is while removing that given tab.
        function insertSpaces(line, pos, count)
        {
            return line.substr(0, pos)
                + spaces.substr(0, count)
                + line.substr(pos + 1, line.length) // pos + 1 will get rid of the tab
                ;
        };
        // Go through all the lines and do the 'smart tabs' magic.
        code = eachLine(code, function(line)
        {
            if (line.indexOf(tab) == -1)
                return line;
            var pos = 0;
            while ((pos = line.indexOf(tab)) != -1)
            {
                // This is pretty much all there is to the 'smart tabs' logic.
                // Based on the position within the line and size of a tab,
                // calculate the amount of spaces we need to insert.
                var spaces = tabSize - pos % tabSize;
                line = insertSpaces(line, pos, spaces);
            }
            return line;
        });
        return code;
    };
    /**
     * Performs various string fixes based on configuration.
     */
    function fixInputString(str)
    {
        var br = /<br\s*\/?>|&lt;br\s*\/?&gt;/gi;
        if (sh.config.bloggerMode == true)
            str = str.replace(br, '\n');
        if (sh.config.stripBrs == true)
            str = str.replace(br, '');
        return str;
    };
    /**
     * Removes all white space at the begining and end of a string.
     *
     * @param {String} str   String to trim.
     * @return {String}      Returns string without leading and following white space characters.
     */
    function trim(str)
    {
        return str.replace(/^\s+|\s+$/g, '');
    };
    /**
     * Unindents a block of text by the lowest common indent amount.
     * @param {String} str   Text to unindent.
     * @return {String}      Returns unindented text block.
     */
    function unindent(str)
    {
        var lines = splitLines(fixInputString(str)),
            indents = new Array(),
            regex = /^\s*/,
            min = 1000
            ;
        // go through every line and check for common number of indents
        for (var i = 0; i < lines.length && min > 0; i++)
        {
            var line = lines[i];
            if (trim(line).length == 0)
                continue;
            var matches = regex.exec(line);
            // In the event that just one line doesn't have leading white space
            // we can't unindent anything, so bail completely.
            if (matches == null)
                return str;
            min = Math.min(matches[0].length, min);
        }
        // trim minimum common number of white space from the begining of every line
        if (min > 0)
            for (var i = 0; i < lines.length; i++)
                lines[i] = lines[i].substr(min);
        return lines.join('\n');
    };
    /**
     * Callback method for Array.sort() which sorts matches by
     * index position and then by length.
     *
     * @param {Match} m1    Left object.
     * @param {Match} m2    Right object.
     * @return {Number}     Returns -1, 0 or -1 as a comparison result.
     */
    function matchesSortCallback(m1, m2)
    {
        // sort matches by index first
        if(m1.index < m2.index)
            return -1;
        else if(m1.index > m2.index)
            return 1;
        else
        {
            // if index is the same, sort by length
            if(m1.length < m2.length)
                return -1;
            else if(m1.length > m2.length)
                return 1;
        }
        return 0;
    };
    /**
     * Executes given regular expression on provided code and returns all
     * matches that are found.
     *
     * @param {String} code    Code to execute regular expression on.
     * @param {Object} regex   Regular expression item info from <code>regexList</code> collection.
     * @return {Array}         Returns a list of Match objects.
     */
    function getMatches(code, regexInfo)
    {
        function defaultAdd(match, regexInfo)
        {
            return match[0];
        };
        var index = 0,
            match = null,
            matches = [],
            func = regexInfo.func ? regexInfo.func : defaultAdd
            ;
        while((match = regexInfo.regex.exec(code)) != null)
        {
            var resultMatch = func(match, regexInfo);
            if (typeof(resultMatch) == 'string')
                resultMatch = [new sh.Match(resultMatch, match.index, regexInfo.css)];
            matches = matches.concat(resultMatch);
        }
        return matches;
    };
    /**
     * Turns all URLs in the code into <a/> tags.
     * @param {String} code Input code.
     * @return {String} Returns code with </a> tags.
     */
    function processUrls(code)
    {
        var gt = /(.*)((&gt;|&lt;).*)/;
        return code.replace(sh.regexLib.url, function(m)
        {
            var suffix = '',
                match = null
                ;
            // We include &lt; and &gt; in the URL for the common cases like <http://google.com>
            // The problem is that they get transformed into &lt;http://google.com&gt;
            // Where as &gt; easily looks like part of the URL string.
            if (match = gt.exec(m))
            {
                m = match[1];
                suffix = match[2];
            }
            return '<a href="' + m + '">' + m + '</a>' + suffix;
        });
    };
    /**
     * Finds all <SCRIPT TYPE="syntaxhighlighter" /> elementss.
     * @return {Array} Returns array of all found SyntaxHighlighter tags.
     */
    function getSyntaxHighlighterScriptTags()
    {
        var tags = document.getElementsByTagName('script'),
            result = []
            ;
        for (var i = 0; i < tags.length; i++)
            if (tags[i].type == 'syntaxhighlighter')
                result.push(tags[i]);
        return result;
    };
    /**
     * Strips <![CDATA[]]> from <SCRIPT /> content because it should be used
     * there in most cases for XHTML compliance.
     * @param {String} original    Input code.
     * @return {String} Returns code without leading <![CDATA[]]> tags.
     */
    function stripCData(original)
    {
        var left = '<![CDATA[',
            right = ']]>',
        // for some reason IE inserts some leading blanks here
            copy = trim(original),
            changed = false,
            leftLength = left.length,
            rightLength = right.length
            ;
        if (copy.indexOf(left) == 0)
        {
            copy = copy.substring(leftLength);
            changed = true;
        }
        var copyLength = copy.length;
        if (copy.indexOf(right) == copyLength - rightLength)
        {
            copy = copy.substring(0, copyLength - rightLength);
            changed = true;
        }
        return changed ? copy : original;
    };
    /**
     * Quick code mouse double click handler.
     */
    function quickCodeHandler(e)
    {
        var target = e.target,
            highlighterDiv = findParentElement(target, '.syntaxhighlighter'),
            container = findParentElement(target, '.container'),
            textarea = document.createElement('textarea'),
            highlighter
            ;
        if (!container || !highlighterDiv || findElement(container, 'textarea'))
            return;
        highlighter = getHighlighterById(highlighterDiv.id);
        // add source class name
        addClass(highlighterDiv, 'source');
        // Have to go over each line and grab it's text, can't just do it on the
        // container because Firefox loses all \n where as Webkit doesn't.
        var lines = container.childNodes,
            code = []
            ;
        for (var i = 0; i < lines.length; i++)
            code.push(lines[i].innerText || lines[i].textContent);
        // using \r instead of \r or \r\n makes this work equally well on IE, FF and Webkit
        code = code.join('\r');
        // For Webkit browsers, replace nbsp with a breaking space
        code = code.replace(/\u00a0/g, " ");
        // inject <textarea/> tag
        textarea.appendChild(document.createTextNode(code));
        container.appendChild(textarea);
        // preselect all text
        textarea.focus();
        textarea.select();
        // set up handler for lost focus
        attachEvent(textarea, 'blur', function(e)
        {
            textarea.parentNode.removeChild(textarea);
            removeClass(highlighterDiv, 'source');
        });
    };
    /**
     * Match object.
     */
    sh.Match = function(value, index, css)
    {
        this.value = value;
        this.index = index;
        this.length = value.length;
        this.css = css;
        this.brushName = null;
    };
    sh.Match.prototype.toString = function()
    {
        return this.value;
    };
    /**
     * Simulates HTML code with a scripting language embedded.
     *
     * @param {String} scriptBrushName Brush name of the scripting language.
     */
    sh.HtmlScript = function(scriptBrushName)
    {
        var brushClass = findBrush(scriptBrushName),
            scriptBrush,
            xmlBrush = new sh.brushes.Xml(),
            bracketsRegex = null,
            ref = this,
            methodsToExpose = 'getDiv getHtml init'.split(' ')
            ;
        if (brushClass == null)
            return;
        scriptBrush = new brushClass();
        for(var i = 0; i < methodsToExpose.length; i++)
            // make a closure so we don't lose the name after i changes
            (function() {
                var name = methodsToExpose[i];
                ref[name] = function()
                {
                    return xmlBrush[name].apply(xmlBrush, arguments);
                };
            })();
        if (scriptBrush.htmlScript == null)
        {
            alert(sh.config.strings.brushNotHtmlScript + scriptBrushName);
            return;
        }
        xmlBrush.regexList.push(
            { regex: scriptBrush.htmlScript.code, func: process }
        );
        function offsetMatches(matches, offset)
        {
            for (var j = 0; j < matches.length; j++)
                matches[j].index += offset;
        }
        function process(match, info)
        {
            var code = match.code,
                matches = [],
                regexList = scriptBrush.regexList,
                offset = match.index + match.left.length,
                htmlScript = scriptBrush.htmlScript,
                result
                ;
            // add all matches from the code
            for (var i = 0; i < regexList.length; i++)
            {
                result = getMatches(code, regexList[i]);
                offsetMatches(result, offset);
                matches = matches.concat(result);
            }
            // add left script bracket
            if (htmlScript.left != null && match.left != null)
            {
                result = getMatches(match.left, htmlScript.left);
                offsetMatches(result, match.index);
                matches = matches.concat(result);
            }
            // add right script bracket
            if (htmlScript.right != null && match.right != null)
            {
                result = getMatches(match.right, htmlScript.right);
                offsetMatches(result, match.index + match[0].lastIndexOf(match.right));
                matches = matches.concat(result);
            }
            for (var j = 0; j < matches.length; j++)
                matches[j].brushName = brushClass.brushName;
            return matches;
        }
    };
    /**
     * Main Highlither class.
     * @constructor
     */
    sh.Highlighter = function()
    {
        // not putting any code in here because of the prototype inheritance
    };
    sh.Highlighter.prototype = {
        /**
         * Returns value of the parameter passed to the highlighter.
         * @param {String} name                Name of the parameter.
         * @param {Object} defaultValue        Default value.
         * @return {Object}                    Returns found value or default value otherwise.
         */
        getParam: function(name, defaultValue)
        {
            var result = this.params[name];
            return toBoolean(result == null ? defaultValue : result);
        },
        /**
         * Shortcut to document.createElement().
         * @param {String} name        Name of the element to create (DIV, A, etc).
         * @return {HTMLElement}    Returns new HTML element.
         */
        create: function(name)
        {
            return document.createElement(name);
        },
        /**
         * Applies all regular expression to the code and stores all found
         * matches in the `this.matches` array.
         * @param {Array} regexList        List of regular expressions.
         * @param {String} code            Source code.
         * @return {Array}                Returns list of matches.
         */
        findMatches: function(regexList, code)
        {
            var result = [];
            if (regexList != null)
                for (var i = 0; i < regexList.length; i++)
                    // BUG: length returns len+1 for array if methods added to prototype chain (oising@gmail.com)
                    if (typeof (regexList[i]) == "object")
                        result = result.concat(getMatches(code, regexList[i]));
            // sort and remove nested the matches
            return this.removeNestedMatches(result.sort(matchesSortCallback));
        },
        /**
         * Checks to see if any of the matches are inside of other matches.
         * This process would get rid of highligted strings inside comments,
         * keywords inside strings and so on.
         */
        removeNestedMatches: function(matches)
        {
            // Optimized by Jose Prado (http://joseprado.com)
            for (var i = 0; i < matches.length; i++)
            {
                if (matches[i] === null)
                    continue;
                var itemI = matches[i],
                    itemIEndPos = itemI.index + itemI.length
                    ;
                for (var j = i + 1; j < matches.length && matches[i] !== null; j++)
                {
                    var itemJ = matches[j];
                    if (itemJ === null)
                        continue;
                    else if (itemJ.index > itemIEndPos)
                        break;
                    else if (itemJ.index == itemI.index && itemJ.length > itemI.length)
                        matches[i] = null;
                    else if (itemJ.index >= itemI.index && itemJ.index < itemIEndPos)
                        matches[j] = null;
                }
            }
            return matches;
        },
        /**
         * Creates an array containing integer line numbers starting from the 'first-line' param.
         * @return {Array} Returns array of integers.
         */
        figureOutLineNumbers: function(code)
        {
            var lines = [],
                firstLine = parseInt(this.getParam('first-line'))
                ;
            eachLine(code, function(line, index)
            {
                lines.push(index + firstLine);
            });
            return lines;
        },
        /**
         * Determines if specified line number is in the highlighted list.
         */
        isLineHighlighted: function(lineNumber)
        {
            var list = this.getParam('highlight', []);
            if (typeof(list) != 'object' && list.push == null)
                list = [ list ];
            return indexOf(list, lineNumber.toString()) != -1;
        },
        /**
         * Generates HTML markup for a single line of code while determining alternating line style.
         * @param {Integer} lineNumber    Line number.
         * @param {String} code Line    HTML markup.
         * @return {String}                Returns HTML markup.
         */
        getLineHtml: function(lineIndex, lineNumber, code)
        {
            var classes = [
                'line',
                'number' + lineNumber,
                'index' + lineIndex,
                'alt' + (lineNumber % 2 == 0 ? 1 : 2).toString()
            ];
            if (this.isLineHighlighted(lineNumber))
                classes.push('highlighted');
            if (lineNumber == 0)
                classes.push('break');
            return '<div class="' + classes.join(' ') + '">' + code + '</div>';
        },
        /**
         * Generates HTML markup for line number column.
         * @param {String} code            Complete code HTML markup.
         * @param {Array} lineNumbers    Calculated line numbers.
         * @return {String}                Returns HTML markup.
         */
        getLineNumbersHtml: function(code, lineNumbers)
        {
            var html = '',
                count = splitLines(code).length,
                firstLine = parseInt(this.getParam('first-line')),
                pad = this.getParam('pad-line-numbers')
                ;
            if (pad == true)
                pad = (firstLine + count - 1).toString().length;
            else if (isNaN(pad) == true)
                pad = 0;
            for (var i = 0; i < count; i++)
            {
                var lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i,
                    code = lineNumber == 0 ? sh.config.space : padNumber(lineNumber, pad)
                    ;
                html += this.getLineHtml(i, lineNumber, code);
            }
            return html;
        },
        /**
         * Splits block of text into individual DIV lines.
         * @param {String} code            Code to highlight.
         * @param {Array} lineNumbers    Calculated line numbers.
         * @return {String}                Returns highlighted code in HTML form.
         */
        getCodeLinesHtml: function(html, lineNumbers)
        {
            html = trim(html);
            var lines = splitLines(html),
                padLength = this.getParam('pad-line-numbers'),
                firstLine = parseInt(this.getParam('first-line')),
                html = '',
                brushName = this.getParam('brush')
                ;
            for (var i = 0; i < lines.length; i++)
            {
                var line = lines[i],
                    indent = /^(&nbsp;|\s)+/.exec(line),
                    spaces = null,
                    lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i;
                ;
                if (indent != null)
                {
                    spaces = indent[0].toString();
                    line = line.substr(spaces.length);
                    spaces = spaces.replace(' ', sh.config.space);
                }
                line = trim(line);
                if (line.length == 0)
                    line = sh.config.space;
                html += this.getLineHtml(
                    i,
                    lineNumber,
                    (spaces != null ? '<code class="' + brushName + ' spaces">' + spaces + '</code>' : '') + line
                );
            }
            return html;
        },
        /**
         * Returns HTML for the table title or empty string if title is null.
         */
        getTitleHtml: function(title)
        {
            return title ? '<caption>' + title + '</caption>' : '';
        },
        /**
         * Finds all matches in the source code.
         * @param {String} code        Source code to process matches in.
         * @param {Array} matches    Discovered regex matches.
         * @return {String} Returns formatted HTML with processed mathes.
         */
        getMatchesHtml: function(code, matches)
        {
            var pos = 0,
                result = '',
                brushName = this.getParam('brush', '')
                ;
            function getBrushNameCss(match)
            {
                var result = match ? (match.brushName || brushName) : brushName;
                return result ? result + ' ' : '';
            };
            // Finally, go through the final list of matches and pull the all
            // together adding everything in between that isn't a match.
            for (var i = 0; i < matches.length; i++)
            {
                var match = matches[i],
                    matchBrushName
                    ;
                if (match === null || match.length === 0)
                    continue;
                matchBrushName = getBrushNameCss(match);
                result += wrapLinesWithCode(code.substr(pos, match.index - pos), matchBrushName + 'plain')
                    + wrapLinesWithCode(match.value, matchBrushName + match.css)
                ;
                pos = match.index + match.length + (match.offset || 0);
            }
            // don't forget to add whatever's remaining in the string
            result += wrapLinesWithCode(code.substr(pos), getBrushNameCss() + 'plain');
            return result;
        },
        /**
         * Generates HTML markup for the whole syntax highlighter.
         * @param {String} code Source code.
         * @return {String} Returns HTML markup.
         */
        getHtml: function(code)
        {
            var html = '',
                classes = [ 'syntaxhighlighter' ],
                tabSize,
                matches,
                lineNumbers
                ;
            // process light mode
            if (this.getParam('light') == true)
                this.params.toolbar = this.params.gutter = false;
            className = 'syntaxhighlighter';
            if (this.getParam('collapse') == true)
                classes.push('collapsed');
            if ((gutter = this.getParam('gutter')) == false)
                classes.push('nogutter');
            // add custom user style name
            classes.push(this.getParam('class-name'));
            // add brush alias to the class name for custom CSS
            classes.push(this.getParam('brush'));
            code = trimFirstAndLastLines(code)
                .replace(/\r/g, ' ') // IE lets these buggers through
            ;
            tabSize = this.getParam('tab-size');
            // replace tabs with spaces
            code = this.getParam('smart-tabs') == true
                ? processSmartTabs(code, tabSize)
                : processTabs(code, tabSize)
            ;
            // unindent code by the common indentation
            if (this.getParam('unindent'))
                code = unindent(code);
            if (gutter)
                lineNumbers = this.figureOutLineNumbers(code);
            // find matches in the code using brushes regex list
            matches = this.findMatches(this.regexList, code);
            // processes found matches into the html
            html = this.getMatchesHtml(code, matches);
            // finally, split all lines so that they wrap well
            html = this.getCodeLinesHtml(html, lineNumbers);
            // finally, process the links
            if (this.getParam('auto-links'))
                html = processUrls(html);
            if (typeof(navigator) != 'undefined' && navigator.userAgent && navigator.userAgent.match(/MSIE/))
                classes.push('ie');
            html =
                '<div id="' + getHighlighterId(this.id) + '" class="' + classes.join(' ') + '">'
                    + (this.getParam('toolbar') ? sh.toolbar.getHtml(this) : '')
                    + '<table border="0" cellpadding="0" cellspacing="0">'
                    + this.getTitleHtml(this.getParam('title'))
                    + '<tbody>'
                    + '<tr>'
                    + (gutter ? '<td class="gutter">' + this.getLineNumbersHtml(code) + '</td>' : '')
                    + '<td class="code">'
                    + '<div class="container">'
                    + html
                    + '</div>'
                    + '</td>'
                    + '</tr>'
                    + '</tbody>'
                    + '</table>'
                    + '</div>'
            ;
            return html;
        },
        /**
         * Highlights the code and returns complete HTML.
         * @param {String} code     Code to highlight.
         * @return {Element}        Returns container DIV element with all markup.
         */
        getDiv: function(code)
        {
            if (code === null)
                code = '';
            this.code = code;
            var div = this.create('div');
            // create main HTML
            div.innerHTML = this.getHtml(code);
            // set up click handlers
            if (this.getParam('toolbar'))
                attachEvent(findElement(div, '.toolbar'), 'click', sh.toolbar.handler);
            if (this.getParam('quick-code'))
                attachEvent(findElement(div, '.code'), 'dblclick', quickCodeHandler);
            return div;
        },
        /**
         * Initializes the highlighter/brush.
         *
         * Constructor isn't used for initialization so that nothing executes during necessary
         * `new SyntaxHighlighter.Highlighter()` call when setting up brush inheritence.
         *
         * @param {Hash} params Highlighter parameters.
         */
        init: function(params)
        {
            this.id = guid();
            // register this instance in the highlighters list
            storeHighlighter(this);
            // local params take precedence over defaults
            this.params = merge(sh.defaults, params || {})
            // process light mode
            if (this.getParam('light') == true)
                this.params.toolbar = this.params.gutter = false;
        },
        /**
         * Converts space separated list of keywords into a regular expression string.
         * @param {String} str    Space separated keywords.
         * @return {String}       Returns regular expression string.
         */
        getKeywords: function(str)
        {
            str = str
                .replace(/^\s+|\s+$/g, '')
                .replace(/\s+/g, '|')
            ;
            return '\\b(?:' + str + ')\\b';
        },
        /**
         * Makes a brush compatible with the `html-script` functionality.
         * @param {Object} regexGroup Object containing `left` and `right` regular expressions.
         */
        forHtmlScript: function(regexGroup)
        {
            var regex = { 'end' : regexGroup.right.source };
            if(regexGroup.eof)
                regex.end = "(?:(?:" + regex.end + ")|$)";
            this.htmlScript = {
                left : { regex: regexGroup.left, css: 'script' },
                right : { regex: regexGroup.right, css: 'script' },
                code : new XRegExp(
                    "(?<left>" + regexGroup.left.source + ")" +
                        "(?<code>.*?)" +
                        "(?<right>" + regex.end + ")",
                    "sgi"
                )
            };
        }
    }; // end of Highlighter
    return sh;
}(); // end of anonymous function
// CommonJS
typeof(exports) != 'undefined' ? exports.SyntaxHighlighter = SyntaxHighlighter : null;
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Created by Peter Atoria @ http://iAtoria.com
        var inits      =  'class interface function package';
        var keywords =    '-Infinity ...rest Array as AS3 Boolean break case catch const continue Date decodeURI ' +
                'decodeURIComponent default delete do dynamic each else encodeURI encodeURIComponent escape ' +
                'extends false final finally flash_proxy for get if implements import in include Infinity ' +
                'instanceof int internal is isFinite isNaN isXMLName label namespace NaN native new null ' +
                'Null Number Object object_proxy override parseFloat parseInt private protected public ' +
                'return set static String super switch this throw true try typeof uint undefined unescape ' +
                'use void while with'
            ;
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    css: 'comments' },        // one line comments
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,        css: 'comments' },        // multiline comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },        // double quoted strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },        // single quoted strings
            { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi,                css: 'value' },            // numbers
            { regex: new RegExp(this.getKeywords(inits), 'gm'),            css: 'color3' },        // initializations
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword' },        // keywords
            { regex: new RegExp('var', 'gm'),                            css: 'variable' },        // variable
            { regex: new RegExp('trace', 'gm'),                            css: 'color1' }            // trace
        ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.scriptScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['actionscript3', 'as3'];
    SyntaxHighlighter.brushes.AS3 = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // AppleScript brush by David Chambers
        // http://davidchambersdesign.com/
        var keywords   = 'after before beginning continue copy each end every from return get global in local named of set some that the then times to where whose with without';
        var ordinals   = 'first second third fourth fifth sixth seventh eighth ninth tenth last front back middle';
        var specials   = 'activate add alias AppleScript ask attachment boolean class constant delete duplicate empty exists false id integer list make message modal modified new no paragraph pi properties quit real record remove rest result reveal reverse run running save string true word yes';
        this.regexList = [
            { regex: /(--|#).*$/gm,
                css: 'comments' },
            { regex: /\(\*(?:[\s\S]*?\(\*[\s\S]*?\*\))*[\s\S]*?\*\)/gm, // support nested comments
                css: 'comments' },
            { regex: /"[\s\S]*?"/gm,
                css: 'string' },
            { regex: /(?:,|:|¬|'s\b|\(|\)|\{|\}|«|\b\w*»)/g,
                css: 'color1' },
            { regex: /(-)?(\d)+(\.(\d)?)?(E\+(\d)+)?/g, // numbers
                css: 'color1' },
            { regex: /(?:&(amp;|gt;|lt;)?|=|� |>|<|≥|>=|≤|<=|\*|\+|-|\/|÷|\^)/g,
                css: 'color2' },
            { regex: /\b(?:and|as|div|mod|not|or|return(?!\s&)(ing)?|equals|(is(n't| not)? )?equal( to)?|does(n't| not) equal|(is(n't| not)? )?(greater|less) than( or equal( to)?)?|(comes|does(n't| not) come) (after|before)|is(n't| not)?( in)? (back|front) of|is(n't| not)? behind|is(n't| not)?( (in|contained by))?|does(n't| not) contain|contain(s)?|(start|begin|end)(s)? with|((but|end) )?(consider|ignor)ing|prop(erty)?|(a )?ref(erence)?( to)?|repeat (until|while|with)|((end|exit) )?repeat|((else|end) )?if|else|(end )?(script|tell|try)|(on )?error|(put )?into|(of )?(it|me)|its|my|with (timeout( of)?|transaction)|end (timeout|transaction))\b/g,
                css: 'keyword' },
            { regex: /\b\d+(st|nd|rd|th)\b/g, // ordinals
                css: 'keyword' },
            { regex: /\b(?:about|above|against|around|at|below|beneath|beside|between|by|(apart|aside) from|(instead|out) of|into|on(to)?|over|since|thr(ough|u)|under)\b/g,
                css: 'color3' },
            { regex: /\b(?:adding folder items to|after receiving|choose( ((remote )?application|color|folder|from list|URL))?|clipboard info|set the clipboard to|(the )?clipboard|entire contents|display(ing| (alert|dialog|mode))?|document( (edited|file|nib name))?|file( (name|type))?|(info )?for|giving up after|(name )?extension|quoted form|return(ed)?|second(?! item)(s)?|list (disks|folder)|text item(s| delimiters)?|(Unicode )?text|(disk )?item(s)?|((current|list) )?view|((container|key) )?window|with (data|icon( (caution|note|stop))?|parameter(s)?|prompt|properties|seed|title)|case|diacriticals|hyphens|numeric strings|punctuation|white space|folder creation|application(s( folder)?| (processes|scripts position|support))?|((desktop )?(pictures )?|(documents|downloads|favorites|home|keychain|library|movies|music|public|scripts|sites|system|users|utilities|workflows) )folder|desktop|Folder Action scripts|font(s| panel)?|help|internet plugins|modem scripts|(system )?preferences|printer descriptions|scripting (additions|components)|shared (documents|libraries)|startup (disk|items)|temporary items|trash|on server|in AppleTalk zone|((as|long|short) )?user name|user (ID|locale)|(with )?password|in (bundle( with identifier)?|directory)|(close|open for) access|read|write( permission)?|(g|s)et eof|using( delimiters)?|starting at|default (answer|button|color|country code|entr(y|ies)|identifiers|items|name|location|script editor)|hidden( answer)?|open(ed| (location|untitled))?|error (handling|reporting)|(do( shell)?|load|run|store) script|administrator privileges|altering line endings|get volume settings|(alert|boot|input|mount|output|set) volume|output muted|(fax|random )?number|round(ing)?|up|down|toward zero|to nearest|as taught in school|system (attribute|info)|((AppleScript( Studio)?|system) )?version|(home )?directory|(IPv4|primary Ethernet) address|CPU (type|speed)|physical memory|time (stamp|to GMT)|replacing|ASCII (character|number)|localized string|from table|offset|summarize|beep|delay|say|(empty|multiple) selections allowed|(of|preferred) type|invisibles|showing( package contents)?|editable URL|(File|FTP|News|Media|Web) [Ss]ervers|Telnet hosts|Directory services|Remote applications|waiting until completion|saving( (in|to))?|path (for|to( (((current|frontmost) )?application|resource))?)|POSIX (file|path)|(background|RGB) color|(OK|cancel) button name|cancel button|button(s)?|cubic ((centi)?met(re|er)s|yards|feet|inches)|square ((kilo)?met(re|er)s|miles|yards|feet)|(centi|kilo)?met(re|er)s|miles|yards|feet|inches|lit(re|er)s|gallons|quarts|(kilo)?grams|ounces|pounds|degrees (Celsius|Fahrenheit|Kelvin)|print( (dialog|settings))?|clos(e(able)?|ing)|(de)?miniaturized|miniaturizable|zoom(ed|able)|attribute run|action (method|property|title)|phone|email|((start|end)ing|home) page|((birth|creation|current|custom|modification) )?date|((((phonetic )?(first|last|middle))|computer|host|maiden|related) |nick)?name|aim|icq|jabber|msn|yahoo|address(es)?|save addressbook|should enable action|city|country( code)?|formatte(r|d address)|(palette )?label|state|street|zip|AIM [Hh]andle(s)?|my card|select(ion| all)?|unsaved|(alpha )?value|entr(y|ies)|group|(ICQ|Jabber|MSN) handle|person|people|company|department|icon image|job title|note|organization|suffix|vcard|url|copies|collating|pages (across|down)|request print time|target( printer)?|((GUI Scripting|Script menu) )?enabled|show Computer scripts|(de)?activated|awake from nib|became (key|main)|call method|of (class|object)|center|clicked toolbar item|closed|for document|exposed|(can )?hide|idle|keyboard (down|up)|event( (number|type))?|launch(ed)?|load (image|movie|nib|sound)|owner|log|mouse (down|dragged|entered|exited|moved|up)|move|column|localization|resource|script|register|drag (info|types)|resigned (active|key|main)|resiz(e(d)?|able)|right mouse (down|dragged|up)|scroll wheel|(at )?index|should (close|open( untitled)?|quit( after last window closed)?|zoom)|((proposed|screen) )?bounds|show(n)?|behind|in front of|size (mode|to fit)|update(d| toolbar item)?|was (hidden|miniaturized)|will (become active|close|finish launching|hide|miniaturize|move|open|quit|(resign )?active|((maximum|minimum|proposed) )?size|show|zoom)|bundle|data source|movie|pasteboard|sound|tool(bar| tip)|(color|open|save) panel|coordinate system|frontmost|main( (bundle|menu|window))?|((services|(excluded from )?windows) )?menu|((executable|frameworks|resource|scripts|shared (frameworks|support)) )?path|(selected item )?identifier|data|content(s| view)?|character(s)?|click count|(command|control|option|shift) key down|context|delta (x|y|z)|key( code)?|location|pressure|unmodified characters|types|(first )?responder|playing|(allowed|selectable) identifiers|allows customization|(auto saves )?configuration|visible|image( name)?|menu form representation|tag|user(-| )defaults|associated file name|(auto|needs) display|current field editor|floating|has (resize indicator|shadow)|hides when deactivated|level|minimized (image|title)|opaque|position|release when closed|sheet|title(d)?)\b/g,
                css: 'color3' },
            { regex: new RegExp(this.getKeywords(specials), 'gm'), css: 'color3' },
            { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' },
            { regex: new RegExp(this.getKeywords(ordinals), 'gm'), css: 'keyword' }
        ];
    };
    Brush.prototype = new SyntaxHighlighter.Highlighter();
    Brush.aliases = ['applescript'];
    SyntaxHighlighter.brushes.AppleScript = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var keywords =    'if fi then elif else for do done until while break continue case esac function return in eq ne ge le';
        var commands =  'alias apropos awk basename bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' +
                        'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' +
                        'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' +
                        'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' +
                        'free fsck ftp gawk getopts grep groups gzip hash head history hostname id ifconfig ' +
                        'import install join kill less let ln local locate logname logout look lpc lpr lprint ' +
                        'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' +
                        'mv netstat nice nl nohup nslookup open op passwd paste pathchk ping popd pr printcap ' +
                        'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' +
                        'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' +
                        'sleep sort source split ssh strace su sudo sum symlink sync tail tar tee test time ' +
                        'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' +
                        'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' +
                        'vi watch wc whereis which who whoami Wget xargs yes'
                        ;
        this.regexList = [
            { regex: /^#!.*$/gm,                                            css: 'preprocessor bold' },
            { regex: /\/[\w-\/]+/gm,                                        css: 'plain' },
            { regex: SyntaxHighlighter.regexLib.singleLinePerlComments,        css: 'comments' },        // one line comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,            css: 'string' },        // double quoted strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,            css: 'string' },        // single quoted strings
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),            css: 'keyword' },        // keywords
            { regex: new RegExp(this.getKeywords(commands), 'gm'),            css: 'functions' }        // commands
            ];
    }
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['bash', 'shell', 'sh'];
    SyntaxHighlighter.brushes.Bash = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Jen
        // http://www.jensbits.com/2009/05/14/coldfusion-brush-for-syntaxhighlighter-plus
        var funcs    =    'Abs ACos AddSOAPRequestHeader AddSOAPResponseHeader AjaxLink AjaxOnLoad ArrayAppend ArrayAvg ArrayClear ArrayDeleteAt ' +
                        'ArrayInsertAt ArrayIsDefined ArrayIsEmpty ArrayLen ArrayMax ArrayMin ArraySet ArraySort ArraySum ArraySwap ArrayToList ' +
                        'Asc ASin Atn BinaryDecode BinaryEncode BitAnd BitMaskClear BitMaskRead BitMaskSet BitNot BitOr BitSHLN BitSHRN BitXor ' +
                        'Ceiling CharsetDecode CharsetEncode Chr CJustify Compare CompareNoCase Cos CreateDate CreateDateTime CreateObject ' +
                        'CreateODBCDate CreateODBCDateTime CreateODBCTime CreateTime CreateTimeSpan CreateUUID DateAdd DateCompare DateConvert ' +
                        'DateDiff DateFormat DatePart Day DayOfWeek DayOfWeekAsString DayOfYear DaysInMonth DaysInYear DE DecimalFormat DecrementValue ' +
                        'Decrypt DecryptBinary DeleteClientVariable DeserializeJSON DirectoryExists DollarFormat DotNetToCFType Duplicate Encrypt ' +
                        'EncryptBinary Evaluate Exp ExpandPath FileClose FileCopy FileDelete FileExists FileIsEOF FileMove FileOpen FileRead ' +
                        'FileReadBinary FileReadLine FileSetAccessMode FileSetAttribute FileSetLastModified FileWrite Find FindNoCase FindOneOf ' +
                        'FirstDayOfMonth Fix FormatBaseN GenerateSecretKey GetAuthUser GetBaseTagData GetBaseTagList GetBaseTemplatePath ' +
                        'GetClientVariablesList GetComponentMetaData GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' +
                        'GetException GetFileFromPath GetFileInfo GetFunctionList GetGatewayHelper GetHttpRequestData GetHttpTimeString ' +
                        'GetK2ServerDocCount GetK2ServerDocCountLimit GetLocale GetLocaleDisplayName GetLocalHostIP GetMetaData GetMetricData ' +
                        'GetPageContext GetPrinterInfo GetProfileSections GetProfileString GetReadableImageFormats GetSOAPRequest GetSOAPRequestHeader ' +
                        'GetSOAPResponse GetSOAPResponseHeader GetTempDirectory GetTempFile GetTemplatePath GetTickCount GetTimeZoneInfo GetToken ' +
                        'GetUserRoles GetWriteableImageFormats Hash Hour HTMLCodeFormat HTMLEditFormat IIf ImageAddBorder ImageBlur ImageClearRect ' +
                        'ImageCopy ImageCrop ImageDrawArc ImageDrawBeveledRect ImageDrawCubicCurve ImageDrawLine ImageDrawLines ImageDrawOval ' +
                        'ImageDrawPoint ImageDrawQuadraticCurve ImageDrawRect ImageDrawRoundRect ImageDrawText ImageFlip ImageGetBlob ImageGetBufferedImage ' +
                        'ImageGetEXIFTag ImageGetHeight ImageGetIPTCTag ImageGetWidth ImageGrayscale ImageInfo ImageNegative ImageNew ImageOverlay ImagePaste ' +
                        'ImageRead ImageReadBase64 ImageResize ImageRotate ImageRotateDrawingAxis ImageScaleToFit ImageSetAntialiasing ImageSetBackgroundColor ' +
                        'ImageSetDrawingColor ImageSetDrawingStroke ImageSetDrawingTransparency ImageSharpen ImageShear ImageShearDrawingAxis ImageTranslate ' +
                        'ImageTranslateDrawingAxis ImageWrite ImageWriteBase64 ImageXORDrawingMode IncrementValue InputBaseN Insert Int IsArray IsBinary ' +
                        'IsBoolean IsCustomFunction IsDate IsDDX IsDebugMode IsDefined IsImage IsImageFile IsInstanceOf IsJSON IsLeapYear IsLocalHost ' +
                        'IsNumeric IsNumericDate IsObject IsPDFFile IsPDFObject IsQuery IsSimpleValue IsSOAPRequest IsStruct IsUserInAnyRole IsUserInRole ' +
                        'IsUserLoggedIn IsValid IsWDDX IsXML IsXmlAttribute IsXmlDoc IsXmlElem IsXmlNode IsXmlRoot JavaCast JSStringFormat LCase Left Len ' +
                        'ListAppend ListChangeDelims ListContains ListContainsNoCase ListDeleteAt ListFind ListFindNoCase ListFirst ListGetAt ListInsertAt ' +
                        'ListLast ListLen ListPrepend ListQualify ListRest ListSetAt ListSort ListToArray ListValueCount ListValueCountNoCase LJustify Log ' +
                        'Log10 LSCurrencyFormat LSDateFormat LSEuroCurrencyFormat LSIsCurrency LSIsDate LSIsNumeric LSNumberFormat LSParseCurrency LSParseDateTime ' +
                        'LSParseEuroCurrency LSParseNumber LSTimeFormat LTrim Max Mid Min Minute Month MonthAsString Now NumberFormat ParagraphFormat ParseDateTime ' +
                        'Pi PrecisionEvaluate PreserveSingleQuotes Quarter QueryAddColumn QueryAddRow QueryConvertForGrid QueryNew QuerySetCell QuotedValueList Rand ' +
                        'Randomize RandRange REFind REFindNoCase ReleaseComObject REMatch REMatchNoCase RemoveChars RepeatString Replace ReplaceList ReplaceNoCase ' +
                        'REReplace REReplaceNoCase Reverse Right RJustify Round RTrim Second SendGatewayMessage SerializeJSON SetEncoding SetLocale SetProfileString ' +
                        'SetVariable Sgn Sin Sleep SpanExcluding SpanIncluding Sqr StripCR StructAppend StructClear StructCopy StructCount StructDelete StructFind ' +
                        'StructFindKey StructFindValue StructGet StructInsert StructIsEmpty StructKeyArray StructKeyExists StructKeyList StructKeyList StructNew ' +
                        'StructSort StructUpdate Tan TimeFormat ToBase64 ToBinary ToScript ToString Trim UCase URLDecode URLEncodedFormat URLSessionFormat Val ' +
                        'ValueList VerifyClient Week Wrap Wrap WriteOutput XmlChildPos XmlElemNew XmlFormat XmlGetNodeType XmlNew XmlParse XmlSearch XmlTransform ' +
                        'XmlValidate Year YesNoFormat';
        var keywords =    'cfabort cfajaximport cfajaxproxy cfapplet cfapplication cfargument cfassociate cfbreak cfcache cfcalendar ' +
                        'cfcase cfcatch cfchart cfchartdata cfchartseries cfcol cfcollection cfcomponent cfcontent cfcookie cfdbinfo ' +
                        'cfdefaultcase cfdirectory cfdiv cfdocument cfdocumentitem cfdocumentsection cfdump cfelse cfelseif cferror ' +
                        'cfexchangecalendar cfexchangeconnection cfexchangecontact cfexchangefilter cfexchangemail cfexchangetask ' +
                        'cfexecute cfexit cffeed cffile cfflush cfform cfformgroup cfformitem cfftp cffunction cfgrid cfgridcolumn ' +
                        'cfgridrow cfgridupdate cfheader cfhtmlhead cfhttp cfhttpparam cfif cfimage cfimport cfinclude cfindex ' +
                        'cfinput cfinsert cfinterface cfinvoke cfinvokeargument cflayout cflayoutarea cfldap cflocation cflock cflog ' +
                        'cflogin cfloginuser cflogout cfloop cfmail cfmailparam cfmailpart cfmenu cfmenuitem cfmodule cfNTauthenticate ' +
                        'cfobject cfobjectcache cfoutput cfparam cfpdf cfpdfform cfpdfformparam cfpdfparam cfpdfsubform cfpod cfpop ' +
                        'cfpresentation cfpresentationslide cfpresenter cfprint cfprocessingdirective cfprocparam cfprocresult ' +
                        'cfproperty cfquery cfqueryparam cfregistry cfreport cfreportparam cfrethrow cfreturn cfsavecontent cfschedule ' +
                        'cfscript cfsearch cfselect cfset cfsetting cfsilent cfslider cfsprydataset cfstoredproc cfswitch cftable ' +
                        'cftextarea cfthread cfthrow cftimer cftooltip cftrace cftransaction cftree cftreeitem cftry cfupdate cfwddx ' +
                        'cfwindow cfxml cfzip cfzipparam';
        var operators =    'all and any between cross in join like not null or outer some';
        this.regexList = [
            { regex: new RegExp('--(.*)$', 'gm'),                        css: 'comments' },  // one line and multiline comments
            { regex: SyntaxHighlighter.regexLib.xmlComments,            css: 'comments' },    // single quoted strings
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },    // double quoted strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },    // single quoted strings
            { regex: new RegExp(this.getKeywords(funcs), 'gmi'),        css: 'functions' }, // functions
            { regex: new RegExp(this.getKeywords(operators), 'gmi'),    css: 'color1' },    // operators and such
            { regex: new RegExp(this.getKeywords(keywords), 'gmi'),        css: 'keyword' }    // keyword
            ];
    }
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['coldfusion','cf'];
    SyntaxHighlighter.brushes.ColdFusion = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Copyright 2006 Shin, YoungJin
        var datatypes =    'ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR ' +
                        'DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH ' +
                        'HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP ' +
                        'HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY ' +
                        'HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT ' +
                        'HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE ' +
                        'LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF ' +
                        'LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR ' +
                        'LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR ' +
                        'PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT ' +
                        'PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 ' +
                        'POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR ' +
                        'PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 ' +
                        'PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT ' +
                        'SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG ' +
                        'ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM ' +
                        'char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t ' +
                        'clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS ' +
                        'FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t ' +
                        '__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t ' +
                        'jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler ' +
                        'sig_atomic_t size_t _stat __stat64 _stati64 terminate_function ' +
                        'time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf ' +
                        'va_list wchar_t wctrans_t wctype_t wint_t signed';
        var keywords =    'auto break case catch class const decltype __finally __exception __try ' +
                        'const_cast continue private public protected __declspec ' +
                        'default delete deprecated dllexport dllimport do dynamic_cast ' +
                        'else enum explicit extern if for friend goto inline ' +
                        'mutable naked namespace new noinline noreturn nothrow ' +
                        'register reinterpret_cast return selectany ' +
                        'sizeof static static_cast struct switch template this ' +
                        'thread throw true false try typedef typeid typename union ' +
                        'using uuid virtual void volatile whcar_t while';
        var functions =    'assert isalnum isalpha iscntrl isdigit isgraph islower isprint' +
                        'ispunct isspace isupper isxdigit tolower toupper errno localeconv ' +
                        'setlocale acos asin atan atan2 ceil cos cosh exp fabs floor fmod ' +
                        'frexp ldexp log log10 modf pow sin sinh sqrt tan tanh jmp_buf ' +
                        'longjmp setjmp raise signal sig_atomic_t va_arg va_end va_start ' +
                        'clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen ' +
                        'fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell ' +
                        'fwrite getc getchar gets perror printf putc putchar puts remove ' +
                        'rename rewind scanf setbuf setvbuf sprintf sscanf tmpfile tmpnam ' +
                        'ungetc vfprintf vprintf vsprintf abort abs atexit atof atoi atol ' +
                        'bsearch calloc div exit free getenv labs ldiv malloc mblen mbstowcs ' +
                        'mbtowc qsort rand realloc srand strtod strtol strtoul system ' +
                        'wcstombs wctomb memchr memcmp memcpy memmove memset strcat strchr ' +
                        'strcmp strcoll strcpy strcspn strerror strlen strncat strncmp ' +
                        'strncpy strpbrk strrchr strspn strstr strtok strxfrm asctime ' +
                        'clock ctime difftime gmtime localtime mktime strftime time';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    css: 'comments' },            // one line comments
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,        css: 'comments' },            // multiline comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },            // strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },            // strings
            { regex: /^ *#.*/gm,                                        css: 'preprocessor' },
            { regex: new RegExp(this.getKeywords(datatypes), 'gm'),        css: 'color1 bold' },
            { regex: new RegExp(this.getKeywords(functions), 'gm'),        css: 'functions bold' },
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword bold' }
            ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['cpp', 'c'];
    SyntaxHighlighter.brushes.Cpp = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var keywords =    'abstract as base bool break byte case catch char checked class const ' +
                        'continue decimal default delegate do double else enum event explicit volatile ' +
                        'extern false finally fixed float for foreach get goto if implicit in int ' +
                        'interface internal is lock long namespace new null object operator out ' +
                        'override params private protected public readonly ref return sbyte sealed set ' +
                        'short sizeof stackalloc static string struct switch this throw true try ' +
                        'typeof uint ulong unchecked unsafe ushort using virtual void while var ' +
                        'from group by into select let where orderby join on equals ascending descending';
        function fixComments(match, regexInfo)
        {
            var css = (match[0].indexOf("///") == 0)
                ? 'color1'
                : 'comments'
                ;
            return [new SyntaxHighlighter.Match(match[0], match.index, css)];
        }
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    func : fixComments },        // one line comments
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,        css: 'comments' },            // multiline comments
            { regex: /@"(?:[^"]|"")*"/g,                                css: 'string' },            // @-quoted strings
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },            // strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },            // strings
            { regex: /^\s*#.*/gm,                                        css: 'preprocessor' },        // preprocessor tags like #region and #endregion
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword' },            // c# keyword
            { regex: /\bpartial(?=\s+(?:class|interface|struct)\b)/g,    css: 'keyword' },            // contextual keyword: 'partial'
            { regex: /\byield(?=\s+(?:return|break)\b)/g,                css: 'keyword' }            // contextual keyword: 'yield'
            ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['c#', 'c-sharp', 'csharp'];
    SyntaxHighlighter.brushes.CSharp = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        function getKeywordsCSS(str)
        {
            return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
        };
        function getValuesCSS(str)
        {
            return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
        };
        var keywords =    'ascent azimuth background-attachment background-color background-image background-position ' +
                        'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
                        'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
                        'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
                        'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
                        'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
                        'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
                        'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
                        'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
                        'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
                        'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
                        'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
                        'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
                        'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
        var values =    'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
                        'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
                        'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+
                        'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
                        'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
                        'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
                        'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
                        'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
                        'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
                        'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
                        'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
                        'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
                        'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
                        'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
        var fonts =        '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,        css: 'comments' },    // multiline comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },    // double quoted strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },    // single quoted strings
            { regex: /\#[a-fA-F0-9]{3,6}/g,                                css: 'value' },        // html colors
            { regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g,                css: 'value' },        // sizes
            { regex: /!important/g,                                        css: 'color3' },    // !important
            { regex: new RegExp(getKeywordsCSS(keywords), 'gm'),        css: 'keyword' },    // keywords
            { regex: new RegExp(getValuesCSS(values), 'g'),                css: 'value' },        // values
            { regex: new RegExp(this.getKeywords(fonts), 'g'),            css: 'color1' }        // fonts
            ];
        this.forHtmlScript({
            left: /(&lt;|<)\s*style.*?(&gt;|>)/gi,
            right: /(&lt;|<)\/\s*style\s*(&gt;|>)/gi
            });
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['css'];
    SyntaxHighlighter.brushes.CSS = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var keywords =    'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' +
                        'case char class comp const constructor currency destructor div do double ' +
                        'downto else end except exports extended false file finalization finally ' +
                        'for function goto if implementation in inherited int64 initialization ' +
                        'integer interface is label library longint longword mod nil not object ' +
                        'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' +
                        'pint64 pointer private procedure program property pshortstring pstring ' +
                        'pvariant pwidechar pwidestring protected public published raise real real48 ' +
                        'record repeat set shl shortint shortstring shr single smallint string then ' +
                        'threadvar to true try type unit until uses val var varirnt while widechar ' +
                        'widestring with word write writeln xor';
        this.regexList = [
            { regex: /\(\*[\s\S]*?\*\)/gm,                                css: 'comments' },      // multiline comments (* *)
            { regex: /{(?!\$)[\s\S]*?}/gm,                                css: 'comments' },      // multiline comments { }
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    css: 'comments' },      // one line
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },        // strings
            { regex: /\{\$[a-zA-Z]+ .+\}/g,                                css: 'color1' },        // compiler Directives and Region tags
            { regex: /\b[\d\.]+\b/g,                                    css: 'value' },            // numbers 12345
            { regex: /\$[a-zA-Z0-9]+\b/g,                                css: 'value' },            // numbers $F5D3
            { regex: new RegExp(this.getKeywords(keywords), 'gmi'),        css: 'keyword' }        // keyword
            ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['delphi', 'pascal', 'pas'];
    SyntaxHighlighter.brushes.Delphi = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        this.regexList = [
            { regex: /^\+\+\+ .*$/gm,    css: 'color2' },    // new file
            { regex: /^\-\-\- .*$/gm,    css: 'color2' },    // old file
            { regex: /^\s.*$/gm,        css: 'color1' },    // unchanged
            { regex: /^@@.*@@.*$/gm,    css: 'variable' },    // location
            { regex: /^\+.*$/gm,        css: 'string' },    // additions
            { regex: /^\-.*$/gm,        css: 'color3' }        // deletions
            ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['diff', 'patch'];
    SyntaxHighlighter.brushes.Diff = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Jean-Lou Dupont
        // http://jldupont.blogspot.com/2009/06/erlang-syntax-highlighter.html
        // According to: http://erlang.org/doc/reference_manual/introduction.html#1.5
        var keywords = 'after and andalso band begin bnot bor bsl bsr bxor '+
            'case catch cond div end fun if let not of or orelse '+
            'query receive rem try when xor'+
            // additional
            ' module export import define';
        this.regexList = [
            { regex: new RegExp("[A-Z][A-Za-z0-9_]+", 'g'),             css: 'constants' },
            { regex: new RegExp("\\%.+", 'gm'),                         css: 'comments' },
            { regex: new RegExp("\\?[A-Za-z0-9_]+", 'g'),                 css: 'preprocessor' },
            { regex: new RegExp("[a-z0-9_]+:[a-z0-9_]+", 'g'),             css: 'functions' },
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },
            { regex: new RegExp(this.getKeywords(keywords),    'gm'),        css: 'keyword' }
            ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['erl', 'erlang'];
    SyntaxHighlighter.brushes.Erland = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Andres Almiray
        // http://jroller.com/aalmiray/entry/nice_source_code_syntax_highlighter
        var keywords =    'as assert break case catch class continue def default do else extends finally ' +
                        'if in implements import instanceof interface new package property return switch ' +
                        'throw throws try while public protected private static';
        var types    =  'void boolean byte char short int long float double';
        var constants = 'null';
        var methods   = 'allProperties count get size '+
                        'collect each eachProperty eachPropertyName eachWithIndex find findAll ' +
                        'findIndexOf grep inject max min reverseEach sort ' +
                        'asImmutable asSynchronized flatten intersect join pop reverse subMap toList ' +
                        'padRight padLeft contains eachMatch toCharacter toLong toUrl tokenize ' +
                        'eachFile eachFileRecurse eachB yte eachLine readBytes readLine getText ' +
                        'splitEachLine withReader append encodeBase64 decodeBase64 filterLine ' +
                        'transformChar transformLine withOutputStream withPrintWriter withStream ' +
                        'withStreams withWriter withWriterAppend write writeLine '+
                        'dump inspect invokeMethod print println step times upto use waitForOrKill '+
                        'getText';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,                css: 'comments' },        // one line comments
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,                    css: 'comments' },        // multiline comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,                    css: 'string' },        // strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,                    css: 'string' },        // strings
            { regex: /""".*"""/g,                                                    css: 'string' },        // GStrings
            { regex: new RegExp('\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b', 'gi'),    css: 'value' },            // numbers
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),                    css: 'keyword' },        // goovy keyword
            { regex: new RegExp(this.getKeywords(types), 'gm'),                        css: 'color1' },        // goovy/java type
            { regex: new RegExp(this.getKeywords(constants), 'gm'),                    css: 'constants' },        // constants
            { regex: new RegExp(this.getKeywords(methods), 'gm'),                    css: 'functions' }        // methods
            ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
    }
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['groovy'];
    SyntaxHighlighter.brushes.Groovy = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var keywords =    'abstract assert boolean break byte case catch char class const ' +
                        'continue default do double else enum extends ' +
                        'false final finally float for goto if implements import ' +
                        'instanceof int interface long native new null ' +
                        'package private protected public return ' +
                        'short static strictfp super switch synchronized this throw throws true ' +
                        'transient try void volatile while';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    css: 'comments' },        // one line comments
            { regex: /\/\*([^\*][\s\S]*)?\*\//gm,                        css: 'comments' },         // multiline comments
            { regex: /\/\*(?!\*\/)\*[\s\S]*?\*\//gm,                    css: 'preprocessor' },    // documentation comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },        // strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },        // strings
            { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi,                css: 'value' },            // numbers
            { regex: /(?!\@interface\b)\@[\$\w]+\b/g,                    css: 'color1' },        // annotation @anno
            { regex: /\@interface\b/g,                                    css: 'color2' },        // @interface keyword
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword' }        // java keyword
            ];
        this.forHtmlScript({
            left    : /(&lt;|<)%[@!=]?/g,
            right    : /%(&gt;|>)/g
        });
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['java'];
    SyntaxHighlighter.brushes.Java = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Patrick Webster
        // http://patrickwebster.blogspot.com/2009/04/javafx-brush-for-syntaxhighlighter.html
        var datatypes =    'Boolean Byte Character Double Duration '
                        + 'Float Integer Long Number Short String Void'
                        ;
        var keywords = 'abstract after and as assert at before bind bound break catch class '
                        + 'continue def delete else exclusive extends false finally first for from '
                        + 'function if import in indexof init insert instanceof into inverse last '
                        + 'lazy mixin mod nativearray new not null on or override package postinit '
                        + 'protected public public-init public-read replace return reverse sizeof '
                        + 'step super then this throw true try tween typeof var where while with '
                        + 'attribute let private readonly static trigger'
                        ;
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    css: 'comments' },
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,        css: 'comments' },
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },
            { regex: /(-?\.?)(\b(\d*\.?\d+|\d+\.?\d*)(e[+-]?\d+)?|0x[a-f\d]+)\b\.?/gi, css: 'color2' },    // numbers
            { regex: new RegExp(this.getKeywords(datatypes), 'gm'),        css: 'variable' },    // datatypes
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword' }
        ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['jfx', 'javafx'];
    SyntaxHighlighter.brushes.JavaFX = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var keywords =    'break case catch continue ' +
                        'default delete do else false  ' +
                        'for function if in instanceof ' +
                        'new null return super switch ' +
                        'this throw true try typeof var while with'
                        ;
        var r = SyntaxHighlighter.regexLib;
        this.regexList = [
            { regex: r.multiLineDoubleQuotedString,                    css: 'string' },            // double quoted strings
            { regex: r.multiLineSingleQuotedString,                    css: 'string' },            // single quoted strings
            { regex: r.singleLineCComments,                            css: 'comments' },            // one line comments
            { regex: r.multiLineCComments,                            css: 'comments' },            // multiline comments
            { regex: /\s*#.*/gm,                                    css: 'preprocessor' },        // preprocessor tags like #region and #endregion
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),    css: 'keyword' }            // keywords
            ];
        this.forHtmlScript(r.scriptScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['js', 'jscript', 'javascript'];
    SyntaxHighlighter.brushes.JScript = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by David Simmons-Duffin and Marty Kube
        var funcs =
            'abs accept alarm atan2 bind binmode chdir chmod chomp chop chown chr ' +
            'chroot close closedir connect cos crypt defined delete each endgrent ' +
            'endhostent endnetent endprotoent endpwent endservent eof exec exists ' +
            'exp fcntl fileno flock fork format formline getc getgrent getgrgid ' +
            'getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr ' +
            'getnetbyname getnetent getpeername getpgrp getppid getpriority ' +
            'getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid ' +
            'getservbyname getservbyport getservent getsockname getsockopt glob ' +
            'gmtime grep hex index int ioctl join keys kill lc lcfirst length link ' +
            'listen localtime lock log lstat map mkdir msgctl msgget msgrcv msgsnd ' +
            'oct open opendir ord pack pipe pop pos print printf prototype push ' +
            'quotemeta rand read readdir readline readlink readpipe recv rename ' +
            'reset reverse rewinddir rindex rmdir scalar seek seekdir select semctl ' +
            'semget semop send setgrent sethostent setnetent setpgrp setpriority ' +
            'setprotoent setpwent setservent setsockopt shift shmctl shmget shmread ' +
            'shmwrite shutdown sin sleep socket socketpair sort splice split sprintf ' +
            'sqrt srand stat study substr symlink syscall sysopen sysread sysseek ' +
            'system syswrite tell telldir time times tr truncate uc ucfirst umask ' +
            'undef unlink unpack unshift utime values vec wait waitpid warn write ' +
            // feature
            'say';
        var keywords =
            'bless caller continue dbmclose dbmopen die do dump else elsif eval exit ' +
            'for foreach goto if import last local my next no our package redo ref ' +
            'require return sub tie tied unless untie until use wantarray while ' +
            // feature
            'given when default ' +
            // Try::Tiny
            'try catch finally ' +
            // Moose
            'has extends with before after around override augment';
        this.regexList = [
            { regex: /(<<|&lt;&lt;)((\w+)|(['"])(.+?)\4)[\s\S]+?\n\3\5\n/g,    css: 'string' },    // here doc (maybe html encoded)
            { regex: /#.*$/gm,                                        css: 'comments' },
            { regex: /^#!.*\n/g,                                    css: 'preprocessor' },    // shebang
            { regex: /-?\w+(?=\s*=(>|&gt;))/g,    css: 'string' }, // fat comma
            // is this too much?
            { regex: /\bq[qwxr]?\([\s\S]*?\)/g,    css: 'string' }, // quote-like operators ()
            { regex: /\bq[qwxr]?\{[\s\S]*?\}/g,    css: 'string' }, // quote-like operators {}
            { regex: /\bq[qwxr]?\[[\s\S]*?\]/g,    css: 'string' }, // quote-like operators []
            { regex: /\bq[qwxr]?(<|&lt;)[\s\S]*?(>|&gt;)/g,    css: 'string' }, // quote-like operators <>
            { regex: /\bq[qwxr]?([^\w({<[])[\s\S]*?\1/g,    css: 'string' }, // quote-like operators non-paired
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,    css: 'string' },
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,    css: 'string' },
            // currently ignoring single quote package separator and utf8 names
            { regex: /(?:&amp;|[$@%*]|\$#)[a-zA-Z_](\w+|::)*/g,           css: 'variable' },
            { regex: /\b__(?:END|DATA)__\b[\s\S]*$/g,                css: 'comments' },
            { regex: /(^|\n)=\w[\s\S]*?(\n=cut\s*\n|$)/g,                css: 'comments' },        // pod
            { regex: new RegExp(this.getKeywords(funcs), 'gm'),        css: 'functions' },
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),    css: 'keyword' }
        ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);
    }
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases        = ['perl', 'Perl', 'pl'];
    SyntaxHighlighter.brushes.Perl = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var funcs    =    'abs acos acosh addcslashes addslashes ' +
                        'array_change_key_case array_chunk array_combine array_count_values array_diff '+
                        'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+
                        'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+
                        'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+
                        'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+
                        'array_push array_rand array_reduce array_reverse array_search array_shift '+
                        'array_slice array_splice array_sum array_udiff array_udiff_assoc '+
                        'array_udiff_uassoc array_uintersect array_uintersect_assoc '+
                        'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+
                        'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+
                        'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+
                        'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+
                        'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+
                        'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+
                        'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+
                        'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+
                        'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+
                        'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+
                        'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+
                        'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+
                        'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+
                        'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+
                        'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+
                        'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+
                        'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+
                        'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+
                        'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+
                        'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+
                        'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+
                        'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+
                        'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+
                        'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+
                        'strtoupper strtr strval substr substr_compare';
        var keywords =    'abstract and array as break case catch cfunction class clone const continue declare default die do ' +
                        'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach ' +
                        'function global goto if implements include include_once interface instanceof insteadof namespace new ' +
                        'old_function or private protected public return require require_once static switch ' +
                        'trait throw try use var while xor ';
        var constants    = '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,    css: 'comments' },            // one line comments
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,        css: 'comments' },            // multiline comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },            // double quoted strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },            // single quoted strings
            { regex: /\$\w+/g,                                            css: 'variable' },            // variables
            { regex: new RegExp(this.getKeywords(funcs), 'gmi'),        css: 'functions' },            // common functions
            { regex: new RegExp(this.getKeywords(constants), 'gmi'),    css: 'constants' },            // constants
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword' }            // keyword
            ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['php'];
    SyntaxHighlighter.brushes.Php = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['text', 'plain'];
    SyntaxHighlighter.brushes.Plain = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Joel 'Jaykul' Bennett, http://PoshCode.org | http://HuddledMasses.org
        var keywords =    'while validateset validaterange validatepattern validatelength validatecount ' +
                        'until trap switch return ref process param parameter in if global: '+
                        'function foreach for finally filter end elseif else dynamicparam do default ' +
                        'continue cmdletbinding break begin alias \\? % #script #private #local #global '+
                        'mandatory parametersetname position valuefrompipeline ' +
                        'valuefrompipelinebypropertyname valuefromremainingarguments helpmessage ';
        var operators =    ' and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle ' +
                        'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains ' +
                        'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt ' +
                        'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like ' +
                        'lt match ne not notcontains notlike notmatch or regex replace wildcard';
        var verbs =        'write where wait use update unregister undo trace test tee take suspend ' +
                        'stop start split sort skip show set send select scroll resume restore ' +
                        'restart resolve resize reset rename remove register receive read push ' +
                        'pop ping out new move measure limit join invoke import group get format ' +
                        'foreach export expand exit enter enable disconnect disable debug cxnew ' +
                        'copy convertto convertfrom convert connect complete compare clear ' +
                        'checkpoint aggregate add';
        // I can't find a way to match the comment based help in multi-line comments, because SH won't highlight in highlights, and javascript doesn't support lookbehind
        var commenthelp = ' component description example externalhelp forwardhelpcategory forwardhelptargetname forwardhelptargetname functionality inputs link notes outputs parameter remotehelprunspace role synopsis';
        this.regexList = [
            { regex: new RegExp('^\\s*#[#\\s]*\\.('+this.getKeywords(commenthelp)+').*$', 'gim'),            css: 'preprocessor help bold' },        // comment-based help
            { regex: SyntaxHighlighter.regexLib.singleLinePerlComments,                                        css: 'comments' },                        // one line comments
            { regex: /(&lt;|<)#[\s\S]*?#(&gt;|>)/gm,                                                        css: 'comments here' },                    // multi-line comments
            { regex: new RegExp('@"\\n[\\s\\S]*?\\n"@', 'gm'),                                                css: 'script string here' },            // double quoted here-strings
            { regex: new RegExp("@'\\n[\\s\\S]*?\\n'@", 'gm'),                                                css: 'script string single here' },        // single quoted here-strings
            { regex: new RegExp('"(?:\\$\\([^\\)]*\\)|[^"]|`"|"")*[^`]"','g'),                                css: 'string' },                        // double quoted strings
            { regex: new RegExp("'(?:[^']|'')*'", 'g'),                                                        css: 'string single' },                    // single quoted strings
            { regex: new RegExp('[\\$|@|@@](?:(?:global|script|private|env):)?[A-Z0-9_]+', 'gi'),            css: 'variable' },                        // $variables
            { regex: new RegExp('(?:\\b'+verbs.replace(/ /g, '\\b|\\b')+')-[a-zA-Z_][a-zA-Z0-9_]*', 'gmi'),    css: 'functions' },                        // functions and cmdlets
            { regex: new RegExp(this.getKeywords(keywords), 'gmi'),                                            css: 'keyword' },                        // keywords
            { regex: new RegExp('-'+this.getKeywords(operators), 'gmi'),                                    css: 'operator value' },                // operators
            { regex: new RegExp('\\[[A-Z_\\[][A-Z0-9_. `,\\[\\]]*\\]', 'gi'),                                css: 'constants' },                        // .Net [Type]s
            { regex: new RegExp('\\s+-(?!'+this.getKeywords(operators)+')[a-zA-Z_][a-zA-Z0-9_]*', 'gmi'),    css: 'color1' },                        // parameters
        ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['powershell', 'ps', 'posh'];
    SyntaxHighlighter.brushes.PowerShell = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Gheorghe Milas and Ahmad Sherif
        var keywords =  'and assert break class continue def del elif else ' +
                        'except exec finally for from global if import in is ' +
                        'lambda not or pass print raise return try yield while';
        var funcs = '__import__ abs all any apply basestring bin bool buffer callable ' +
                    'chr classmethod cmp coerce compile complex delattr dict dir ' +
                    'divmod enumerate eval execfile file filter float format frozenset ' +
                    'getattr globals hasattr hash help hex id input int intern ' +
                    'isinstance issubclass iter len list locals long map max min next ' +
                    'object oct open ord pow print property range raw_input reduce ' +
                    'reload repr reversed round set setattr slice sorted staticmethod ' +
                    'str sum super tuple type type unichr unicode vars xrange zip';
        var special =  'None True False self cls class_';
        this.regexList = [
                { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' },
                { regex: /^\s*@\w+/gm,                                         css: 'decorator' },
                { regex: /(['\"]{3})([^\1])*?\1/gm,                         css: 'comments' },
                { regex: /"(?!")(?:\.|\\\"|[^\""\n])*"/gm,                     css: 'string' },
                { regex: /'(?!')(?:\.|(\\\')|[^\''\n])*'/gm,                 css: 'string' },
                { regex: /\+|\-|\*|\/|\%|=|==/gm,                             css: 'keyword' },
                { regex: /\b\d+\.?\w*/g,                                     css: 'value' },
                { regex: new RegExp(this.getKeywords(funcs), 'gmi'),        css: 'functions' },
                { regex: new RegExp(this.getKeywords(keywords), 'gm'),         css: 'keyword' },
                { regex: new RegExp(this.getKeywords(special), 'gm'),         css: 'color1' }
                ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['py', 'python'];
    SyntaxHighlighter.brushes.Python = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Erik Peterson.
        var keywords =    'alias and BEGIN begin break case class def define_method defined do each else elsif ' +
                        'END end ensure false for if in module new next nil not or raise redo rescue retry return ' +
                        'self super then throw true undef unless until when while yield';
        var builtins =    'Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload ' +
                        'Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ' +
                        'ThreadGroup Thread Time TrueClass';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLinePerlComments,    css: 'comments' },        // one line comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,        css: 'string' },        // double quoted strings
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,        css: 'string' },        // single quoted strings
            { regex: /\b[A-Z0-9_]+\b/g,                                    css: 'constants' },        // constants
            { regex: /:[a-z][A-Za-z0-9_]*/g,                            css: 'color2' },        // symbols
            { regex: /(\$|@@|@)\w+/g,                                    css: 'variable bold' },    // $global, @instance, and @@class variables
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),        css: 'keyword' },        // keywords
            { regex: new RegExp(this.getKeywords(builtins), 'gm'),        css: 'color1' }            // builtins
            ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['ruby', 'rails', 'ror', 'rb'];
    SyntaxHighlighter.brushes.Ruby = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        function getKeywordsCSS(str)
        {
            return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
        };
        function getValuesCSS(str)
        {
            return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
        };
        var keywords =    'ascent azimuth background-attachment background-color background-image background-position ' +
                        'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
                        'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
                        'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
                        'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
                        'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
                        'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
                        'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
                        'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
                        'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
                        'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
                        'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
                        'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
                        'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
        var values =    'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
                        'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
                        'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero digits disc dotted double '+
                        'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
                        'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
                        'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
                        'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
                        'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
                        'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
                        'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
                        'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
                        'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
                        'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
                        'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
        var fonts =        '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
        var statements        = '!important !default';
        var preprocessor    = '@import @extend @debug @warn @if @for @while @mixin @include';
        var r = SyntaxHighlighter.regexLib;
        this.regexList = [
            { regex: r.multiLineCComments,                                css: 'comments' },        // multiline comments
            { regex: r.singleLineCComments,                                css: 'comments' },        // singleline comments
            { regex: r.doubleQuotedString,                                css: 'string' },        // double quoted strings
            { regex: r.singleQuotedString,                                css: 'string' },        // single quoted strings
            { regex: /\#[a-fA-F0-9]{3,6}/g,                                css: 'value' },            // html colors
            { regex: /\b(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)\b/g,            css: 'value' },            // sizes
            { regex: /\$\w+/g,                                            css: 'variable' },        // variables
            { regex: new RegExp(this.getKeywords(statements), 'g'),        css: 'color3' },        // statements
            { regex: new RegExp(this.getKeywords(preprocessor), 'g'),    css: 'preprocessor' },    // preprocessor
            { regex: new RegExp(getKeywordsCSS(keywords), 'gm'),        css: 'keyword' },        // keywords
            { regex: new RegExp(getValuesCSS(values), 'g'),                css: 'value' },            // values
            { regex: new RegExp(this.getKeywords(fonts), 'g'),            css: 'color1' }            // fonts
            ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['sass', 'scss'];
    SyntaxHighlighter.brushes.Sass = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        // Contributed by Yegor Jbanov and David Bernard.
        var keywords =    'val sealed case def true trait implicit forSome import match object null finally super ' +
                        'override try lazy for var catch throw type extends class while with new final yield abstract ' +
                        'else do if return protected private this package false';
        var keyops =    '[_:=><%#@]+';
        this.regexList = [
            { regex: SyntaxHighlighter.regexLib.singleLineCComments,            css: 'comments' },    // one line comments
            { regex: SyntaxHighlighter.regexLib.multiLineCComments,                css: 'comments' },    // multiline comments
            { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString,    css: 'string' },    // multi-line strings
            { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString,    css: 'string' },    // double-quoted string
            { regex: SyntaxHighlighter.regexLib.singleQuotedString,                css: 'string' },    // strings
            { regex: /0x[a-f0-9]+|\d+(\.\d+)?/gi,                                css: 'value' },        // numbers
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),                css: 'keyword' },    // keywords
            { regex: new RegExp(keyops, 'gm'),                                    css: 'keyword' }    // scala keyword
            ];
    }
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['scala'];
    SyntaxHighlighter.brushes.Scala = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var funcs    =    'abs avg case cast coalesce convert count current_timestamp ' +
                        'current_user day isnull left lower month nullif replace right ' +
                        'session_user space substring sum system_user upper user year';
        var keywords =    'absolute action add after alter as asc at authorization begin bigint ' +
                        'binary bit by cascade char character check checkpoint close collate ' +
                        'column commit committed connect connection constraint contains continue ' +
                        'create cube current current_date current_time cursor database date ' +
                        'deallocate dec decimal declare default delete desc distinct double drop ' +
                        'dynamic else end end-exec escape except exec execute false fetch first ' +
                        'float for force foreign forward free from full function global goto grant ' +
                        'group grouping having hour ignore index inner insensitive insert instead ' +
                        'int integer intersect into is isolation key last level load local max min ' +
                        'minute modify move name national nchar next no numeric of off on only ' +
                        'open option order out output partial password precision prepare primary ' +
                        'prior privileges procedure public read real references relative repeatable ' +
                        'restrict return returns revoke rollback rollup rows rule schema scroll ' +
                        'second section select sequence serializable set size smallint static ' +
                        'statistics table temp temporary then time timestamp to top transaction ' +
                        'translation trigger true truncate uncommitted union unique update values ' +
                        'varchar varying view when where with work';
        var operators =    'all and any between cross in join like not null or outer some';
        this.regexList = [
            { regex: /--(.*)$/gm,                                                css: 'comments' },            // one line and multiline comments
            { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString,    css: 'string' },            // double quoted strings
            { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString,    css: 'string' },            // single quoted strings
            { regex: new RegExp(this.getKeywords(funcs), 'gmi'),                css: 'color2' },            // functions
            { regex: new RegExp(this.getKeywords(operators), 'gmi'),            css: 'color1' },            // operators and such
            { regex: new RegExp(this.getKeywords(keywords), 'gmi'),                css: 'keyword' }            // keyword
            ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['sql'];
    SyntaxHighlighter.brushes.Sql = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        var keywords =    'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' +
                        'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' +
                        'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' +
                        'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' +
                        'Else ElseIf End Enum Erase Error Event Exit False 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 Nothing ' +
                        'NotInheritable NotOverridable Object On Option Optional Or OrElse ' +
                        'Overloads Overridable Overrides ParamArray Preserve Private Property ' +
                        'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' +
                        'Return Select Set Shadows Shared Short Single Static Step Stop String ' +
                        'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' +
                        'Variant When While With WithEvents WriteOnly Xor';
        this.regexList = [
            { regex: /'.*$/gm,                                        css: 'comments' },            // one line comments
            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,    css: 'string' },            // strings
            { regex: /^\s*#.*$/gm,                                    css: 'preprocessor' },        // preprocessor tags like #region and #endregion
            { regex: new RegExp(this.getKeywords(keywords), 'gm'),    css: 'keyword' }            // vb keyword
            ];
        this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['vb', 'vbnet'];
    SyntaxHighlighter.brushes.Vb = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
;(function()
{
    // CommonJS
    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
    function Brush()
    {
        function process(match, regexInfo)
        {
            var constructor = SyntaxHighlighter.Match,
                code = match[0],
                tag = new XRegExp('(&lt;|<)[\\s\\/\\?]*(?<name>[:\\w-\\.]+)', 'xg').exec(code),
                result = []
                ;
            if (match.attributes != null)
            {
                var attributes,
                    regex = new XRegExp('(?<name> [\\w:\\-\\.]+)' +
                                        '\\s*=\\s*' +
                                        '(?<value> ".*?"|\'.*?\'|\\w+)',
                                        'xg');
                while ((attributes = regex.exec(code)) != null)
                {
                    result.push(new constructor(attributes.name, match.index + attributes.index, 'color1'));
                    result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string'));
                }
            }
            if (tag != null)
                result.push(
                    new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword')
                );
            return result;
        }
        this.regexList = [
            { regex: new XRegExp('(\\&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\&gt;|>)', 'gm'),            css: 'color2' },    // <![ ... [ ... ]]>
            { regex: SyntaxHighlighter.regexLib.xmlComments,                                                css: 'comments' },    // <!-- ... -->
            { regex: new XRegExp('(&lt;|<)[\\s\\/\\?]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(&gt;|>)', 'sg'), func: process }
        ];
    };
    Brush.prototype    = new SyntaxHighlighter.Highlighter();
    Brush.aliases    = ['xml', 'xhtml', 'xslt', 'html'];
    SyntaxHighlighter.brushes.Xml = Brush;
    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/SyntaxHighlighter/shCoreDefault.css
New file
@@ -0,0 +1 @@
.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter,.syntaxhighlighter td,.syntaxhighlighter tr,.syntaxhighlighter tbody,.syntaxhighlighter thead,.syntaxhighlighter caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0!important;-webkit-border-radius:0 0 0 0!important;background:none!important;border:0!important;bottom:auto!important;float:none!important;left:auto!important;line-height:1.1em!important;margin:0!important;outline:0!important;overflow:visible!important;padding:0!important;position:static!important;right:auto!important;text-align:left!important;top:auto!important;vertical-align:baseline!important;width:auto!important;box-sizing:content-box!important;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-weight:normal!important;font-style:normal!important;min-height:inherit!important;min-height:auto!important;font-size:13px!important}.syntaxhighlighter{width:100%!important;margin:.3em 0 .3em 0!important;position:relative!important;overflow:auto!important;background-color:#f5f5f5!important;border:1px solid #ccc!important;border-radius:4px!important;border-collapse:separate!important}.syntaxhighlighter.source{overflow:hidden!important}.syntaxhighlighter .bold{font-weight:bold!important}.syntaxhighlighter .italic{font-style:italic!important}.syntaxhighlighter .gutter div{white-space:pre!important;word-wrap:normal}.syntaxhighlighter caption{text-align:left!important;padding:.5em 0 .5em 1em!important}.syntaxhighlighter td.code{width:100%!important}.syntaxhighlighter td.code .container{position:relative!important}.syntaxhighlighter td.code .container textarea{box-sizing:border-box!important;position:absolute!important;left:0!important;top:0!important;width:100%!important;border:none!important;background:white!important;padding-left:1em!important;overflow:hidden!important;white-space:pre!important}.syntaxhighlighter td.gutter .line{text-align:right!important;padding:0 .5em 0 1em!important}.syntaxhighlighter td.code .line{padding:0 1em!important}.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0!important}.syntaxhighlighter.show{display:block!important}.syntaxhighlighter.collapsed table{display:none!important}.syntaxhighlighter.collapsed .toolbar{padding:.1em .8em 0 .8em!important;font-size:1em!important;position:static!important;width:auto!important}.syntaxhighlighter.collapsed .toolbar span{display:inline!important;margin-right:1em!important}.syntaxhighlighter.collapsed .toolbar span a{padding:0!important;display:none!important}.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline!important}.syntaxhighlighter .toolbar{position:absolute!important;right:1px!important;top:1px!important;width:11px!important;height:11px!important;font-size:10px!important;z-index:10!important}.syntaxhighlighter .toolbar span.title{display:inline!important}.syntaxhighlighter .toolbar a{display:block!important;text-align:center!important;text-decoration:none!important;padding-top:1px!important}.syntaxhighlighter .toolbar a.expandSource{display:none!important}.syntaxhighlighter.ie{font-size:.9em!important;padding:1px 0 1px 0!important}.syntaxhighlighter.ie .toolbar{line-height:8px!important}.syntaxhighlighter.ie .toolbar a{padding-top:0!important}.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none!important}.syntaxhighlighter.printing .line .number{color:#bbb!important}.syntaxhighlighter.printing .line .content{color:black!important}.syntaxhighlighter.printing .toolbar{display:none!important}.syntaxhighlighter.printing a{text-decoration:none!important}.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black!important}.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200!important}.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue!important}.syntaxhighlighter.printing .keyword{color:#ff7800!important;font-weight:bold!important}.syntaxhighlighter.printing .preprocessor{color:gray!important}.syntaxhighlighter.printing .variable{color:#a70!important}.syntaxhighlighter.printing .value{color:#090!important}.syntaxhighlighter.printing .functions{color:#ff1493!important}.syntaxhighlighter.printing .constants{color:#06c!important}.syntaxhighlighter.printing .script{font-weight:bold!important}.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray!important}.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493!important}.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red!important}.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black!important}.syntaxhighlighter{background-color:#f5f5f5!important}.syntaxhighlighter .line.highlighted.number{color:black!important}.syntaxhighlighter caption{color:black!important}.syntaxhighlighter .gutter{color:#afafaf!important;background-color:#f7f7f9!important;border-right:1px solid #e1e1e8!important;padding:9.5px 0 9.5px 9.5px!important;border-top-left-radius:4px!important;border-bottom-left-radius:4px!important;user-select:none!important;-moz-user-select:none!important;-webkit-user-select:none!important}.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c!important;color:white!important}.syntaxhighlighter.printing .line .content{border:none!important}.syntaxhighlighter.collapsed{overflow:visible!important}.syntaxhighlighter.collapsed .toolbar{color:blue!important;background:white!important;border:1px solid #6ce26c!important}.syntaxhighlighter.collapsed .toolbar a{color:blue!important}.syntaxhighlighter.collapsed .toolbar a:hover{color:red!important}.syntaxhighlighter .toolbar{color:white!important;background:#6ce26c!important;border:none!important}.syntaxhighlighter .toolbar a{color:white!important}.syntaxhighlighter .toolbar a:hover{color:black!important}.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black!important}.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200!important}.syntaxhighlighter .string,.syntaxhighlighter .string a{color:blue!important}.syntaxhighlighter .keyword{color:#ff7800!important}.syntaxhighlighter .preprocessor{color:gray!important}.syntaxhighlighter .variable{color:#a70!important}.syntaxhighlighter .value{color:#090!important}.syntaxhighlighter .functions{color:#ff1493!important}.syntaxhighlighter .constants{color:#06c!important}.syntaxhighlighter .script{font-weight:bold!important;color:#ff7800!important;background-color:none!important}.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray!important}.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493!important}.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red!important}.syntaxhighlighter .keyword{font-weight:bold!important}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/codemirror/codemirror.css
New file
@@ -0,0 +1,104 @@
.CodeMirror {
    line-height: 1em;
    font-family: monospace;
}
.CodeMirror-scroll {
    overflow: auto;
    height: 300px;
    /* This is needed to prevent an IE[67] bug where the scrolled content
       is visible outside of the scrolling box. */
    position: relative;
}
.CodeMirror-gutter {
    position: absolute; left: 0; top: 0;
    z-index: 10;
    background-color: #f7f7f7;
    border-right: 1px solid #eee;
    min-width: 2em;
    height: 100%;
}
.CodeMirror-gutter-text {
    color: #aaa;
    text-align: right;
    padding: .4em .2em .4em .4em;
    white-space: pre !important;
}
.CodeMirror-lines {
    padding: .4em;
}
.CodeMirror pre {
    -moz-border-radius: 0;
    -webkit-border-radius: 0;
    -o-border-radius: 0;
    border-radius: 0;
    border-width: 0; margin: 0; padding: 0; background: transparent;
    font-family: inherit;
    font-size: inherit;
    padding: 0; margin: 0;
    white-space: pre;
    word-wrap: normal;
}
.CodeMirror-wrap pre {
    word-wrap: break-word;
    white-space: pre-wrap;
}
.CodeMirror-wrap .CodeMirror-scroll {
    overflow-x: hidden;
}
.CodeMirror textarea {
    outline: none !important;
}
.CodeMirror pre.CodeMirror-cursor {
    z-index: 10;
    position: absolute;
    visibility: hidden;
    border-left: 1px solid black;
}
.CodeMirror-focused pre.CodeMirror-cursor {
    visibility: visible;
}
span.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused span.CodeMirror-selected { background: #d2dcf8; }
.CodeMirror-searching {background: #ffa;}
/* Default theme */
.cm-s-default span.cm-keyword {color: #708;}
.cm-s-default span.cm-atom {color: #219;}
.cm-s-default span.cm-number {color: #164;}
.cm-s-default span.cm-def {color: #00f;}
.cm-s-default span.cm-variable {color: black;}
.cm-s-default span.cm-variable-2 {color: #05a;}
.cm-s-default span.cm-variable-3 {color: #085;}
.cm-s-default span.cm-property {color: black;}
.cm-s-default span.cm-operator {color: black;}
.cm-s-default span.cm-comment {color: #a50;}
.cm-s-default span.cm-string {color: #a11;}
.cm-s-default span.cm-string-2 {color: #f50;}
.cm-s-default span.cm-meta {color: #555;}
.cm-s-default span.cm-error {color: #f00;}
.cm-s-default span.cm-qualifier {color: #555;}
.cm-s-default span.cm-builtin {color: #30a;}
.cm-s-default span.cm-bracket {color: #cc7;}
.cm-s-default span.cm-tag {color: #170;}
.cm-s-default span.cm-attribute {color: #00c;}
.cm-s-default span.cm-header {color: #a0a;}
.cm-s-default span.cm-quote {color: #090;}
.cm-s-default span.cm-hr {color: #999;}
.cm-s-default span.cm-link {color: #00c;}
span.cm-header, span.cm-strong {font-weight: bold;}
span.cm-em {font-style: italic;}
span.cm-emstrong {font-style: italic; font-weight: bold;}
span.cm-link {text-decoration: underline;}
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/codemirror/codemirror.js
New file
@@ -0,0 +1,3581 @@
// CodeMirror version 2.2
//
// All functions that need access to the editor's state live inside
// the CodeMirror function. Below that, at the bottom of the file,
// some utilities are defined.
// CodeMirror is the only global var we claim
var CodeMirror = (function() {
    // This is the function that produces an editor instance. It's
    // closure is used to store the editor state.
    function CodeMirror(place, givenOptions) {
        // Determine effective options based on given values and defaults.
        var options = {}, defaults = CodeMirror.defaults;
        for (var opt in defaults)
            if (defaults.hasOwnProperty(opt))
                options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
        var targetDocument = options["document"];
        // The element in which the editor lives.
        var wrapper = targetDocument.createElement("div");
        wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
        // This mess creates the base DOM structure for the editor.
        wrapper.innerHTML =
            '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea
                '<textarea style="position: absolute; padding: 0; width: 1px;" wrap="off" ' +
                'autocorrect="off" autocapitalize="off"></textarea></div>' +
                '<div class="CodeMirror-scroll" tabindex="-1">' +
                '<div style="position: relative">' + // Set to the height of the text, causes scrolling
                '<div style="position: relative">' + // Moved around its parent to cover visible view
                '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
                // Provides positioning relative to (visible) text origin
                '<div class="CodeMirror-lines"><div style="position: relative">' +
                '<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden"></div>' +
                '<pre class="CodeMirror-cursor">&#160;</pre>' + // Absolutely positioned blinky cursor
                '<div></div>' + // This DIV contains the actual code
                '</div></div></div></div></div>';
        if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
        // I've never seen more elegant code in my life.
        var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
            scroller = wrapper.lastChild, code = scroller.firstChild,
            mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
            lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
            cursor = measure.nextSibling, lineDiv = cursor.nextSibling;
        themeChanged();
        // Needed to hide big blue blinking cursor on Mobile Safari
        if (/AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent)) input.style.width = "0px";
        if (!webkit) lineSpace.draggable = true;
        if (options.tabindex != null) input.tabIndex = options.tabindex;
        if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
        // Check for problem with IE innerHTML not working when we have a
        // P (or similar) parent node.
        try { stringWidth("x"); }
        catch (e) {
            if (e.message.match(/runtime/i))
                e = new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)");
            throw e;
        }
        // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
        var poll = new Delayed(), highlight = new Delayed(), blinker;
        // mode holds a mode API object. doc is the tree of Line objects,
        // work an array of lines that should be parsed, and history the
        // undo history (instance of History constructor).
        var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), work, focused;
        loadMode();
        // The selection. These are always maintained to point at valid
        // positions. Inverted is used to remember that the user is
        // selecting bottom-to-top.
        var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
        // Selection-related flags. shiftSelecting obviously tracks
        // whether the user is holding shift.
        var shiftSelecting, lastClick, lastDoubleClick, draggingText, overwrite = false;
        // Variables used by startOperation/endOperation to track what
        // happened during the operation.
        var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone,
            gutterDirty, callbacks;
        // Current visible range (may be bigger than the view window).
        var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
        // bracketHighlighted is used to remember that a backet has been
        // marked.
        var bracketHighlighted;
        // Tracks the maximum line length so that the horizontal scrollbar
        // can be kept static when scrolling.
        var maxLine = "", maxWidth, tabText = computeTabText();
        // Initialize the content.
        operation(function(){setValue(options.value || ""); updateInput = false;})();
        var history = new History();
        // Register our event handlers.
        connect(scroller, "mousedown", operation(onMouseDown));
        connect(scroller, "dblclick", operation(onDoubleClick));
        connect(lineSpace, "dragstart", onDragStart);
        connect(lineSpace, "selectstart", e_preventDefault);
        // Gecko browsers fire contextmenu *after* opening the menu, at
        // which point we can't mess with it anymore. Context menu is
        // handled in onMouseDown for Gecko.
        if (!gecko) connect(scroller, "contextmenu", onContextMenu);
        connect(scroller, "scroll", function() {
            updateDisplay([]);
            if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
            if (options.onScroll) options.onScroll(instance);
        });
        connect(window, "resize", function() {updateDisplay(true);});
        connect(input, "keyup", operation(onKeyUp));
        connect(input, "input", fastPoll);
        connect(input, "keydown", operation(onKeyDown));
        connect(input, "keypress", operation(onKeyPress));
        connect(input, "focus", onFocus);
        connect(input, "blur", onBlur);
        connect(scroller, "dragenter", e_stop);
        connect(scroller, "dragover", e_stop);
        connect(scroller, "drop", operation(onDrop));
        connect(scroller, "paste", function(){focusInput(); fastPoll();});
        connect(input, "paste", fastPoll);
        connect(input, "cut", operation(function(){replaceSelection("");}));
        // IE throws unspecified error in certain cases, when
        // trying to access activeElement before onload
        var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
        if (hasFocus) setTimeout(onFocus, 20);
        else onBlur();
        function isLine(l) {return l >= 0 && l < doc.size;}
        // The instance object that we'll return. Mostly calls out to
        // local functions in the CodeMirror function. Some do some extra
        // range checking and/or clipping. operation is used to wrap the
        // call so that changes it makes are tracked, and the display is
        // updated afterwards.
        var instance = wrapper.CodeMirror = {
            getValue: getValue,
            setValue: operation(setValue),
            getSelection: getSelection,
            replaceSelection: operation(replaceSelection),
            focus: function(){focusInput(); onFocus(); fastPoll();},
            setOption: function(option, value) {
                var oldVal = options[option];
                options[option] = value;
                if (option == "mode" || option == "indentUnit") loadMode();
                else if (option == "readOnly" && value) {onBlur(); input.blur();}
                else if (option == "theme") themeChanged();
                else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
                else if (option == "tabSize") operation(tabsChanged)();
                if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme")
                    operation(gutterChanged)();
            },
            getOption: function(option) {return options[option];},
            undo: operation(undo),
            redo: operation(redo),
            indentLine: operation(function(n, dir) {
                if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
            }),
            indentSelection: operation(indentSelected),
            historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
            clearHistory: function() {history = new History();},
            matchBrackets: operation(function(){matchBrackets(true);}),
            getTokenAt: operation(function(pos) {
                pos = clipPos(pos);
                return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);
            }),
            getStateAfter: function(line) {
                line = clipLine(line == null ? doc.size - 1: line);
                return getStateBefore(line + 1);
            },
            cursorCoords: function(start){
                if (start == null) start = sel.inverted;
                return pageCoords(start ? sel.from : sel.to);
            },
            charCoords: function(pos){return pageCoords(clipPos(pos));},
            coordsChar: function(coords) {
                var off = eltOffset(lineSpace);
                return coordsChar(coords.x - off.left, coords.y - off.top);
            },
            markText: operation(markText),
            setBookmark: setBookmark,
            setMarker: operation(addGutterMarker),
            clearMarker: operation(removeGutterMarker),
            setLineClass: operation(setLineClass),
            hideLine: operation(function(h) {return setLineHidden(h, true);}),
            showLine: operation(function(h) {return setLineHidden(h, false);}),
            onDeleteLine: function(line, f) {
                if (typeof line == "number") {
                    if (!isLine(line)) return null;
                    line = getLine(line);
                }
                (line.handlers || (line.handlers = [])).push(f);
                return line;
            },
            lineInfo: lineInfo,
            addWidget: function(pos, node, scroll, vert, horiz) {
                pos = localCoords(clipPos(pos));
                var top = pos.yBot, left = pos.x;
                node.style.position = "absolute";
                code.appendChild(node);
                if (vert == "over") top = pos.y;
                else if (vert == "near") {
                    var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
                        hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
                    if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
                        top = pos.y - node.offsetHeight;
                    if (left + node.offsetWidth > hspace)
                        left = hspace - node.offsetWidth;
                }
                node.style.top = (top + paddingTop()) + "px";
                node.style.left = node.style.right = "";
                if (horiz == "right") {
                    left = code.clientWidth - node.offsetWidth;
                    node.style.right = "0px";
                } else {
                    if (horiz == "left") left = 0;
                    else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
                    node.style.left = (left + paddingLeft()) + "px";
                }
                if (scroll)
                    scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
            },
            lineCount: function() {return doc.size;},
            clipPos: clipPos,
            getCursor: function(start) {
                if (start == null) start = sel.inverted;
                return copyPos(start ? sel.from : sel.to);
            },
            somethingSelected: function() {return !posEq(sel.from, sel.to);},
            setCursor: operation(function(line, ch, user) {
                if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch, user);
                else setCursor(line, ch, user);
            }),
            setSelection: operation(function(from, to, user) {
                (user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));
            }),
            getLine: function(line) {if (isLine(line)) return getLine(line).text;},
            getLineHandle: function(line) {if (isLine(line)) return getLine(line);},
            setLine: operation(function(line, text) {
                if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
            }),
            removeLine: operation(function(line) {
                if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
            }),
            replaceRange: operation(replaceRange),
            getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
            execCommand: function(cmd) {return commands[cmd](instance);},
            // Stuff used by commands, probably not much use to outside code.
            moveH: operation(moveH),
            deleteH: operation(deleteH),
            moveV: operation(moveV),
            toggleOverwrite: function() {overwrite = !overwrite;},
            posFromIndex: function(off) {
                var lineNo = 0, ch;
                doc.iter(0, doc.size, function(line) {
                    var sz = line.text.length + 1;
                    if (sz > off) { ch = off; return true; }
                    off -= sz;
                    ++lineNo;
                });
                return clipPos({line: lineNo, ch: ch});
            },
            indexFromPos: function (coords) {
                if (coords.line < 0 || coords.ch < 0) return 0;
                var index = coords.ch;
                doc.iter(0, coords.line, function (line) {
                    index += line.text.length + 1;
                });
                return index;
            },
            operation: function(f){return operation(f)();},
            refresh: function(){updateDisplay(true);},
            getInputField: function(){return input;},
            getWrapperElement: function(){return wrapper;},
            getScrollerElement: function(){return scroller;},
            getGutterElement: function(){return gutter;}
        };
        function getLine(n) { return getLineAt(doc, n); }
        function updateLineHeight(line, height) {
            gutterDirty = true;
            var diff = height - line.height;
            for (var n = line; n; n = n.parent) n.height += diff;
        }
        function setValue(code) {
            var top = {line: 0, ch: 0};
            updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
                splitLines(code), top, top);
            updateInput = true;
        }
        function getValue(code) {
            var text = [];
            doc.iter(0, doc.size, function(line) { text.push(line.text); });
            return text.join("\n");
        }
        function onMouseDown(e) {
            setShift(e.shiftKey);
            // Check whether this is a click in a widget
            for (var n = e_target(e); n != wrapper; n = n.parentNode)
                if (n.parentNode == code && n != mover) return;
            // See if this is a click in the gutter
            for (var n = e_target(e); n != wrapper; n = n.parentNode)
                if (n.parentNode == gutterText) {
                    if (options.onGutterClick)
                        options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
                    return e_preventDefault(e);
                }
            var start = posFromMouse(e);
            switch (e_button(e)) {
                case 3:
                    if (gecko && !mac) onContextMenu(e);
                    return;
                case 2:
                    if (start) setCursor(start.line, start.ch, true);
                    return;
            }
            // For button 1, if it was clicked inside the editor
            // (posFromMouse returning non-null), we have to adjust the
            // selection.
            if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
            if (!focused) onFocus();
            var now = +new Date;
            if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
                e_preventDefault(e);
                setTimeout(focusInput, 20);
                return selectLine(start.line);
            } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
                lastDoubleClick = {time: now, pos: start};
                e_preventDefault(e);
                return selectWordAt(start);
            } else { lastClick = {time: now, pos: start}; }
            var last = start, going;
            if (dragAndDrop && !posEq(sel.from, sel.to) &&
                !posLess(start, sel.from) && !posLess(sel.to, start)) {
                // Let the drag handler handle this.
                if (webkit) lineSpace.draggable = true;
                var up = connect(targetDocument, "mouseup", operation(function(e2) {
                    if (webkit) lineSpace.draggable = false;
                    draggingText = false;
                    up();
                    if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
                        e_preventDefault(e2);
                        setCursor(start.line, start.ch, true);
                        focusInput();
                    }
                }), true);
                draggingText = true;
                return;
            }
            e_preventDefault(e);
            setCursor(start.line, start.ch, true);
            function extend(e) {
                var cur = posFromMouse(e, true);
                if (cur && !posEq(cur, last)) {
                    if (!focused) onFocus();
                    last = cur;
                    setSelectionUser(start, cur);
                    updateInput = false;
                    var visible = visibleLines();
                    if (cur.line >= visible.to || cur.line < visible.from)
                        going = setTimeout(operation(function(){extend(e);}), 150);
                }
            }
            var move = connect(targetDocument, "mousemove", operation(function(e) {
                clearTimeout(going);
                e_preventDefault(e);
                extend(e);
            }), true);
            var up = connect(targetDocument, "mouseup", operation(function(e) {
                clearTimeout(going);
                var cur = posFromMouse(e);
                if (cur) setSelectionUser(start, cur);
                e_preventDefault(e);
                focusInput();
                updateInput = true;
                move(); up();
            }), true);
        }
        function onDoubleClick(e) {
            for (var n = e_target(e); n != wrapper; n = n.parentNode)
                if (n.parentNode == gutterText) return e_preventDefault(e);
            var start = posFromMouse(e);
            if (!start) return;
            lastDoubleClick = {time: +new Date, pos: start};
            e_preventDefault(e);
            selectWordAt(start);
        }
        function onDrop(e) {
            e.preventDefault();
            var pos = posFromMouse(e, true), files = e.dataTransfer.files;
            if (!pos || options.readOnly) return;
            if (files && files.length && window.FileReader && window.File) {
                function loadFile(file, i) {
                    var reader = new FileReader;
                    reader.onload = function() {
                        text[i] = reader.result;
                        if (++read == n) {
                            pos = clipPos(pos);
                            operation(function() {
                                var end = replaceRange(text.join(""), pos, pos);
                                setSelectionUser(pos, end);
                            })();
                        }
                    };
                    reader.readAsText(file);
                }
                var n = files.length, text = Array(n), read = 0;
                for (var i = 0; i < n; ++i) loadFile(files[i], i);
            }
            else {
                try {
                    var text = e.dataTransfer.getData("Text");
                    if (text) {
                        var end = replaceRange(text, pos, pos);
                        var curFrom = sel.from, curTo = sel.to;
                        setSelectionUser(pos, end);
                        if (draggingText) replaceRange("", curFrom, curTo);
                        focusInput();
                    }
                }
                catch(e){}
            }
        }
        function onDragStart(e) {
            var txt = getSelection();
            // This will reset escapeElement
            htmlEscape(txt);
            e.dataTransfer.setDragImage(escapeElement, 0, 0);
            e.dataTransfer.setData("Text", txt);
        }
        function handleKeyBinding(e) {
            var name = keyNames[e.keyCode], next = keyMap[options.keyMap].auto, bound, dropShift;
            if (name == null || e.altGraphKey) {
                if (next) options.keyMap = next;
                return null;
            }
            if (e.altKey) name = "Alt-" + name;
            if (e.ctrlKey) name = "Ctrl-" + name;
            if (e.metaKey) name = "Cmd-" + name;
            if (e.shiftKey && (bound = lookupKey("Shift-" + name, options.extraKeys, options.keyMap))) {
                dropShift = true;
            } else {
                bound = lookupKey(name, options.extraKeys, options.keyMap);
            }
            if (typeof bound == "string") {
                if (commands.propertyIsEnumerable(bound)) bound = commands[bound];
                else bound = null;
            }
            if (next && (bound || !isModifierKey(e))) options.keyMap = next;
            if (!bound) return false;
            if (dropShift) {
                var prevShift = shiftSelecting;
                shiftSelecting = null;
                bound(instance);
                shiftSelecting = prevShift;
            } else bound(instance);
            e_preventDefault(e);
            return true;
        }
        var lastStoppedKey = null;
        function onKeyDown(e) {
            if (!focused) onFocus();
            var code = e.keyCode;
            // IE does strange things with escape.
            if (ie && code == 27) { e.returnValue = false; }
            setShift(code == 16 || e.shiftKey);
            // First give onKeyEvent option a chance to handle this.
            if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
            var handled = handleKeyBinding(e);
            if (window.opera) {
                lastStoppedKey = handled ? e.keyCode : null;
                // Opera has no cut event... we try to at least catch the key combo
                if (!handled && (mac ? e.metaKey : e.ctrlKey) && e.keyCode == 88)
                    replaceSelection("");
            }
        }
        function onKeyPress(e) {
            if (window.opera && e.keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
            if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
            if (window.opera && !e.which && handleKeyBinding(e)) return;
            if (options.electricChars && mode.electricChars) {
                var ch = String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode);
                if (mode.electricChars.indexOf(ch) > -1)
                    setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
            }
            fastPoll();
        }
        function onKeyUp(e) {
            if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
            if (e.keyCode == 16) shiftSelecting = null;
        }
        function onFocus() {
            if (options.readOnly) return;
            if (!focused) {
                if (options.onFocus) options.onFocus(instance);
                focused = true;
                if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
                    wrapper.className += " CodeMirror-focused";
                if (!leaveInputAlone) resetInput(true);
            }
            slowPoll();
            restartBlink();
        }
        function onBlur() {
            if (focused) {
                if (options.onBlur) options.onBlur(instance);
                focused = false;
                wrapper.className = wrapper.className.replace(" CodeMirror-focused", "");
            }
            clearInterval(blinker);
            setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
        }
        // Replace the range from from to to by the strings in newText.
        // Afterwards, set the selection to selFrom, selTo.
        function updateLines(from, to, newText, selFrom, selTo) {
            if (history) {
                var old = [];
                doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });
                history.addChange(from.line, newText.length, old);
                while (history.done.length > options.undoDepth) history.done.shift();
            }
            updateLinesNoUndo(from, to, newText, selFrom, selTo);
        }
        function unredoHelper(from, to) {
            var change = from.pop();
            if (change) {
                var replaced = [], end = change.start + change.added;
                doc.iter(change.start, end, function(line) { replaced.push(line.text); });
                to.push({start: change.start, added: change.old.length, old: replaced});
                var pos = clipPos({line: change.start + change.old.length - 1,
                    ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
                updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);
                updateInput = true;
            }
        }
        function undo() {unredoHelper(history.done, history.undone);}
        function redo() {unredoHelper(history.undone, history.done);}
        function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
            var recomputeMaxLength = false, maxLineLength = maxLine.length;
            if (!options.lineWrapping)
                doc.iter(from.line, to.line, function(line) {
                    if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
                });
            if (from.line != to.line || newText.length > 1) gutterDirty = true;
            var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
            // First adjust the line structure, taking some care to leave highlighting intact.
            if (from.ch == 0 && to.ch == 0 && newText[newText.length - 1] == "") {
                // This is a whole-line replace. Treated specially to make
                // sure line objects move the way they are supposed to.
                var added = [], prevLine = null;
                if (from.line) {
                    prevLine = getLine(from.line - 1);
                    prevLine.fixMarkEnds(lastLine);
                } else lastLine.fixMarkStarts();
                for (var i = 0, e = newText.length - 1; i < e; ++i)
                    added.push(Line.inheritMarks(newText[i], prevLine));
                if (nlines) doc.remove(from.line, nlines, callbacks);
                if (added.length) doc.insert(from.line, added);
            } else if (firstLine == lastLine) {
                if (newText.length == 1)
                    firstLine.replace(from.ch, to.ch, newText[0]);
                else {
                    lastLine = firstLine.split(to.ch, newText[newText.length-1]);
                    firstLine.replace(from.ch, null, newText[0]);
                    firstLine.fixMarkEnds(lastLine);
                    var added = [];
                    for (var i = 1, e = newText.length - 1; i < e; ++i)
                        added.push(Line.inheritMarks(newText[i], firstLine));
                    added.push(lastLine);
                    doc.insert(from.line + 1, added);
                }
            } else if (newText.length == 1) {
                firstLine.replace(from.ch, null, newText[0]);
                lastLine.replace(null, to.ch, "");
                firstLine.append(lastLine);
                doc.remove(from.line + 1, nlines, callbacks);
            } else {
                var added = [];
                firstLine.replace(from.ch, null, newText[0]);
                lastLine.replace(null, to.ch, newText[newText.length-1]);
                firstLine.fixMarkEnds(lastLine);
                for (var i = 1, e = newText.length - 1; i < e; ++i)
                    added.push(Line.inheritMarks(newText[i], firstLine));
                if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
                doc.insert(from.line + 1, added);
            }
            if (options.lineWrapping) {
                var perLine = scroller.clientWidth / charWidth() - 3;
                doc.iter(from.line, from.line + newText.length, function(line) {
                    if (line.hidden) return;
                    var guess = Math.ceil(line.text.length / perLine) || 1;
                    if (guess != line.height) updateLineHeight(line, guess);
                });
            } else {
                doc.iter(from.line, i + newText.length, function(line) {
                    var l = line.text;
                    if (l.length > maxLineLength) {
                        maxLine = l; maxLineLength = l.length; maxWidth = null;
                        recomputeMaxLength = false;
                    }
                });
                if (recomputeMaxLength) {
                    maxLineLength = 0; maxLine = ""; maxWidth = null;
                    doc.iter(0, doc.size, function(line) {
                        var l = line.text;
                        if (l.length > maxLineLength) {
                            maxLineLength = l.length; maxLine = l;
                        }
                    });
                }
            }
            // Add these lines to the work array, so that they will be
            // highlighted. Adjust work lines if lines were added/removed.
            var newWork = [], lendiff = newText.length - nlines - 1;
            for (var i = 0, l = work.length; i < l; ++i) {
                var task = work[i];
                if (task < from.line) newWork.push(task);
                else if (task > to.line) newWork.push(task + lendiff);
            }
            var hlEnd = from.line + Math.min(newText.length, 500);
            highlightLines(from.line, hlEnd);
            newWork.push(hlEnd);
            work = newWork;
            startWorker(100);
            // Remember that these lines changed, for updating the display
            changes.push({from: from.line, to: to.line + 1, diff: lendiff});
            var changeObj = {from: from, to: to, text: newText};
            if (textChanged) {
                for (var cur = textChanged; cur.next; cur = cur.next) {}
                cur.next = changeObj;
            } else textChanged = changeObj;
            // Update the selection
            function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
            setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
            // Make sure the scroll-size div has the correct height.
            code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
        }
        function replaceRange(code, from, to) {
            from = clipPos(from);
            if (!to) to = from; else to = clipPos(to);
            code = splitLines(code);
            function adjustPos(pos) {
                if (posLess(pos, from)) return pos;
                if (!posLess(to, pos)) return end;
                var line = pos.line + code.length - (to.line - from.line) - 1;
                var ch = pos.ch;
                if (pos.line == to.line)
                    ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0));
                return {line: line, ch: ch};
            }
            var end;
            replaceRange1(code, from, to, function(end1) {
                end = end1;
                return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
            });
            return end;
        }
        function replaceSelection(code, collapse) {
            replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
                if (collapse == "end") return {from: end, to: end};
                else if (collapse == "start") return {from: sel.from, to: sel.from};
                else return {from: sel.from, to: end};
            });
        }
        function replaceRange1(code, from, to, computeSel) {
            var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length;
            var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
            updateLines(from, to, code, newSel.from, newSel.to);
        }
        function getRange(from, to) {
            var l1 = from.line, l2 = to.line;
            if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
            var code = [getLine(l1).text.slice(from.ch)];
            doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
            code.push(getLine(l2).text.slice(0, to.ch));
            return code.join("\n");
        }
        function getSelection() {
            return getRange(sel.from, sel.to);
        }
        var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
        function slowPoll() {
            if (pollingFast) return;
            poll.set(options.pollInterval, function() {
                startOperation();
                readInput();
                if (focused) slowPoll();
                endOperation();
            });
        }
        function fastPoll() {
            var missed = false;
            pollingFast = true;
            function p() {
                startOperation();
                var changed = readInput();
                if (!changed && !missed) {missed = true; poll.set(60, p);}
                else {pollingFast = false; slowPoll();}
                endOperation();
            }
            poll.set(20, p);
        }
        // Previnput is a hack to work with IME. If we reset the textarea
        // on every change, that breaks IME. So we look for changes
        // compared to the previous content instead. (Modern browsers have
        // events that indicate IME taking place, but these are not widely
        // supported or compatible enough yet to rely on.)
        var prevInput = "";
        function readInput() {
            if (leaveInputAlone || !focused || hasSelection(input)) return false;
            var text = input.value;
            if (text == prevInput) return false;
            shiftSelecting = null;
            var same = 0, l = Math.min(prevInput.length, text.length);
            while (same < l && prevInput[same] == text[same]) ++same;
            if (same < prevInput.length)
                sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
            else if (overwrite && posEq(sel.from, sel.to))
                sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
            replaceSelection(text.slice(same), "end");
            prevInput = text;
            return true;
        }
        function resetInput(user) {
            if (!posEq(sel.from, sel.to)) {
                prevInput = "";
                input.value = getSelection();
                input.select();
            } else if (user) prevInput = input.value = "";
        }
        function focusInput() {
            if (!options.readOnly) input.focus();
        }
        function scrollEditorIntoView() {
            if (!cursor.getBoundingClientRect) return;
            var rect = cursor.getBoundingClientRect();
            // IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden
            if (ie && rect.top == rect.bottom) return;
            var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
            if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
        }
        function scrollCursorIntoView() {
            var cursor = localCoords(sel.inverted ? sel.from : sel.to);
            var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
            return scrollIntoView(x, cursor.y, x, cursor.yBot);
        }
        function scrollIntoView(x1, y1, x2, y2) {
            var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();
            y1 += pt; y2 += pt; x1 += pl; x2 += pl;
            var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
            if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
            else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
            var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
            var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
            if (x1 < screenleft + gutterw) {
                if (x1 < 50) x1 = 0;
                scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
                scrolled = true;
            }
            else if (x2 > screenw + screenleft - 3) {
                scroller.scrollLeft = x2 + 10 - screenw;
                scrolled = true;
                if (x2 > code.clientWidth) result = false;
            }
            if (scrolled && options.onScroll) options.onScroll(instance);
            return result;
        }
        function visibleLines() {
            var lh = textHeight(), top = scroller.scrollTop - paddingTop();
            var from_height = Math.max(0, Math.floor(top / lh));
            var to_height = Math.ceil((top + scroller.clientHeight) / lh);
            return {from: lineAtHeight(doc, from_height),
                to: lineAtHeight(doc, to_height)};
        }
        // Uses a set of changes plus the current scroll position to
        // determine which DOM updates have to be made, and makes the
        // updates.
        function updateDisplay(changes, suppressCallback) {
            if (!scroller.clientWidth) {
                showingFrom = showingTo = displayOffset = 0;
                return;
            }
            // Compute the new visible window
            var visible = visibleLines();
            // Bail out if the visible area is already rendered and nothing changed.
            if (changes !== true && changes.length == 0 && visible.from >= showingFrom && visible.to <= showingTo) return;
            var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
            if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
            if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
            // Create a range of theoretically intact lines, and punch holes
            // in that using the change info.
            var intact = changes === true ? [] :
                computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
            // Clip off the parts that won't be visible
            var intactLines = 0;
            for (var i = 0; i < intact.length; ++i) {
                var range = intact[i];
                if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
                if (range.to > to) range.to = to;
                if (range.from >= range.to) intact.splice(i--, 1);
                else intactLines += range.to - range.from;
            }
            if (intactLines == to - from) return;
            intact.sort(function(a, b) {return a.domStart - b.domStart;});
            var th = textHeight(), gutterDisplay = gutter.style.display;
            lineDiv.style.display = gutter.style.display = "none";
            patchDisplay(from, to, intact);
            lineDiv.style.display = "";
            // Position the mover div to align with the lines it's supposed
            // to be showing (which will cover the visible display)
            var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
            // This is just a bogus formula that detects when the editor is
            // resized or the font size changes.
            if (different) lastSizeC = scroller.clientHeight + th;
            showingFrom = from; showingTo = to;
            displayOffset = heightAtLine(doc, from);
            mover.style.top = (displayOffset * th) + "px";
            code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
            // Since this is all rather error prone, it is honoured with the
            // only assertion in the whole file.
            if (lineDiv.childNodes.length != showingTo - showingFrom)
                throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
                    " nodes=" + lineDiv.childNodes.length);
            if (options.lineWrapping) {
                maxWidth = scroller.clientWidth;
                var curNode = lineDiv.firstChild;
                doc.iter(showingFrom, showingTo, function(line) {
                    if (!line.hidden) {
                        var height = Math.round(curNode.offsetHeight / th) || 1;
                        if (line.height != height) {updateLineHeight(line, height); gutterDirty = true;}
                    }
                    curNode = curNode.nextSibling;
                });
            } else {
                if (maxWidth == null) maxWidth = stringWidth(maxLine);
                if (maxWidth > scroller.clientWidth) {
                    lineSpace.style.width = maxWidth + "px";
                    // Needed to prevent odd wrapping/hiding of widgets placed in here.
                    code.style.width = "";
                    code.style.width = scroller.scrollWidth + "px";
                } else {
                    lineSpace.style.width = code.style.width = "";
                }
            }
            gutter.style.display = gutterDisplay;
            if (different || gutterDirty) updateGutter();
            updateCursor();
            if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
            return true;
        }
        function computeIntact(intact, changes) {
            for (var i = 0, l = changes.length || 0; i < l; ++i) {
                var change = changes[i], intact2 = [], diff = change.diff || 0;
                for (var j = 0, l2 = intact.length; j < l2; ++j) {
                    var range = intact[j];
                    if (change.to <= range.from && change.diff)
                        intact2.push({from: range.from + diff, to: range.to + diff,
                            domStart: range.domStart});
                    else if (change.to <= range.from || change.from >= range.to)
                        intact2.push(range);
                    else {
                        if (change.from > range.from)
                            intact2.push({from: range.from, to: change.from, domStart: range.domStart});
                        if (change.to < range.to)
                            intact2.push({from: change.to + diff, to: range.to + diff,
                                domStart: range.domStart + (change.to - range.from)});
                    }
                }
                intact = intact2;
            }
            return intact;
        }
        function patchDisplay(from, to, intact) {
            // The first pass removes the DOM nodes that aren't intact.
            if (!intact.length) lineDiv.innerHTML = "";
            else {
                function killNode(node) {
                    var tmp = node.nextSibling;
                    node.parentNode.removeChild(node);
                    return tmp;
                }
                var domPos = 0, curNode = lineDiv.firstChild, n;
                for (var i = 0; i < intact.length; ++i) {
                    var cur = intact[i];
                    while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
                    for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
                }
                while (curNode) curNode = killNode(curNode);
            }
            // This pass fills in the lines that actually changed.
            var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
            var sfrom = sel.from.line, sto = sel.to.line, inSel = sfrom < from && sto >= from;
            var scratch = targetDocument.createElement("div"), newElt;
            doc.iter(from, to, function(line) {
                var ch1 = null, ch2 = null;
                if (inSel) {
                    ch1 = 0;
                    if (sto == j) {inSel = false; ch2 = sel.to.ch;}
                } else if (sfrom == j) {
                    if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
                    else {inSel = true; ch1 = sel.from.ch;}
                }
                if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
                if (!nextIntact || nextIntact.from > j) {
                    if (line.hidden) scratch.innerHTML = "<pre></pre>";
                    else scratch.innerHTML = line.getHTML(ch1, ch2, true, tabText);
                    lineDiv.insertBefore(scratch.firstChild, curNode);
                } else {
                    curNode = curNode.nextSibling;
                }
                ++j;
            });
        }
        function updateGutter() {
            if (!options.gutter && !options.lineNumbers) return;
            var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
            gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
            var html = [], i = showingFrom;
            doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
                if (line.hidden) {
                    html.push("<pre></pre>");
                } else {
                    var marker = line.gutterMarker;
                    var text = options.lineNumbers ? i + options.firstLineNumber : null;
                    if (marker && marker.text)
                        text = marker.text.replace("%N%", text != null ? text : "");
                    else if (text == null)
                        text = "\u00a0";
                    html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
                    for (var j = 1; j < line.height; ++j) html.push("<br/>&#160;");
                    html.push("</pre>");
                }
                ++i;
            });
            gutter.style.display = "none";
            gutterText.innerHTML = html.join("");
            var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
            while (val.length + pad.length < minwidth) pad += "\u00a0";
            if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
            gutter.style.display = "";
            lineSpace.style.marginLeft = gutter.offsetWidth + "px";
            gutterDirty = false;
        }
        function updateCursor() {
            var head = sel.inverted ? sel.from : sel.to, lh = textHeight();
            var pos = localCoords(head, true);
            var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);
            inputDiv.style.top = (pos.y + lineOff.top - wrapOff.top) + "px";
            inputDiv.style.left = (pos.x + lineOff.left - wrapOff.left) + "px";
            if (posEq(sel.from, sel.to)) {
                cursor.style.top = pos.y + "px";
                cursor.style.left = (options.lineWrapping ? Math.min(pos.x, lineSpace.offsetWidth) : pos.x) + "px";
                cursor.style.display = "";
            }
            else cursor.style.display = "none";
        }
        function setShift(val) {
            if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
            else shiftSelecting = null;
        }
        function setSelectionUser(from, to) {
            var sh = shiftSelecting && clipPos(shiftSelecting);
            if (sh) {
                if (posLess(sh, from)) from = sh;
                else if (posLess(to, sh)) to = sh;
            }
            setSelection(from, to);
            userSelChange = true;
        }
        // Update the selection. Last two args are only used by
        // updateLines, since they have to be expressed in the line
        // numbers before the update.
        function setSelection(from, to, oldFrom, oldTo) {
            goalColumn = null;
            if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
            if (posEq(sel.from, from) && posEq(sel.to, to)) return;
            if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
            // Skip over hidden lines.
            if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);
            if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
            if (posEq(from, to)) sel.inverted = false;
            else if (posEq(from, sel.to)) sel.inverted = false;
            else if (posEq(to, sel.from)) sel.inverted = true;
            // Some ugly logic used to only mark the lines that actually did
            // see a change in selection as changed, rather than the whole
            // selected range.
            if (posEq(from, to)) {
                if (!posEq(sel.from, sel.to))
                    changes.push({from: oldFrom, to: oldTo + 1});
            }
            else if (posEq(sel.from, sel.to)) {
                changes.push({from: from.line, to: to.line + 1});
            }
            else {
                if (!posEq(from, sel.from)) {
                    if (from.line < oldFrom)
                        changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1});
                    else
                        changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1});
                }
                if (!posEq(to, sel.to)) {
                    if (to.line < oldTo)
                        changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1});
                    else
                        changes.push({from: Math.max(from.line, oldTo), to: to.line + 1});
                }
            }
            sel.from = from; sel.to = to;
            selectionChanged = true;
        }
        function skipHidden(pos, oldLine, oldCh) {
            function getNonHidden(dir) {
                var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
                while (lNo != end) {
                    var line = getLine(lNo);
                    if (!line.hidden) {
                        var ch = pos.ch;
                        if (ch > oldCh || ch > line.text.length) ch = line.text.length;
                        return {line: lNo, ch: ch};
                    }
                    lNo += dir;
                }
            }
            var line = getLine(pos.line);
            if (!line.hidden) return pos;
            if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
            else return getNonHidden(-1) || getNonHidden(1);
        }
        function setCursor(line, ch, user) {
            var pos = clipPos({line: line, ch: ch || 0});
            (user ? setSelectionUser : setSelection)(pos, pos);
        }
        function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
        function clipPos(pos) {
            if (pos.line < 0) return {line: 0, ch: 0};
            if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
            var ch = pos.ch, linelen = getLine(pos.line).text.length;
            if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
            else if (ch < 0) return {line: pos.line, ch: 0};
            else return pos;
        }
        function findPosH(dir, unit) {
            var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;
            var lineObj = getLine(line);
            function findNextLine() {
                for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {
                    var lo = getLine(l);
                    if (!lo.hidden) { line = l; lineObj = lo; return true; }
                }
            }
            function moveOnce(boundToLine) {
                if (ch == (dir < 0 ? 0 : lineObj.text.length)) {
                    if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;
                    else return false;
                } else ch += dir;
                return true;
            }
            if (unit == "char") moveOnce();
            else if (unit == "column") moveOnce(true);
            else if (unit == "word") {
                var sawWord = false;
                for (;;) {
                    if (dir < 0) if (!moveOnce()) break;
                    if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
                    else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
                    if (dir > 0) if (!moveOnce()) break;
                }
            }
            return {line: line, ch: ch};
        }
        function moveH(dir, unit) {
            var pos = dir < 0 ? sel.from : sel.to;
            if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);
            setCursor(pos.line, pos.ch, true);
        }
        function deleteH(dir, unit) {
            if (!posEq(sel.from, sel.to)) replaceRange("", sel.from, sel.to);
            else if (dir < 0) replaceRange("", findPosH(dir, unit), sel.to);
            else replaceRange("", sel.from, findPosH(dir, unit));
            userSelChange = true;
        }
        var goalColumn = null;
        function moveV(dir, unit) {
            var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
            if (goalColumn != null) pos.x = goalColumn;
            if (unit == "page") dist = scroller.clientHeight;
            else if (unit == "line") dist = textHeight();
            var target = coordsChar(pos.x, pos.y + dist * dir + 2);
            setCursor(target.line, target.ch, true);
            goalColumn = pos.x;
        }
        function selectWordAt(pos) {
            var line = getLine(pos.line).text;
            var start = pos.ch, end = pos.ch;
            while (start > 0 && isWordChar(line.charAt(start - 1))) --start;
            while (end < line.length && isWordChar(line.charAt(end))) ++end;
            setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
        }
        function selectLine(line) {
            setSelectionUser({line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
        }
        function indentSelected(mode) {
            if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
            var e = sel.to.line - (sel.to.ch ? 0 : 1);
            for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
        }
        function indentLine(n, how) {
            if (!how) how = "add";
            if (how == "smart") {
                if (!mode.indent) how = "prev";
                else var state = getStateBefore(n);
            }
            var line = getLine(n), curSpace = line.indentation(options.tabSize),
                curSpaceString = line.text.match(/^\s*/)[0], indentation;
            if (how == "prev") {
                if (n) indentation = getLine(n-1).indentation(options.tabSize);
                else indentation = 0;
            }
            else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
            else if (how == "add") indentation = curSpace + options.indentUnit;
            else if (how == "subtract") indentation = curSpace - options.indentUnit;
            indentation = Math.max(0, indentation);
            var diff = indentation - curSpace;
            if (!diff) {
                if (sel.from.line != n && sel.to.line != n) return;
                var indentString = curSpaceString;
            }
            else {
                var indentString = "", pos = 0;
                if (options.indentWithTabs)
                    for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
                while (pos < indentation) {++pos; indentString += " ";}
            }
            replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
        }
        function loadMode() {
            mode = CodeMirror.getMode(options, options.mode);
            doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
            work = [0];
            startWorker();
        }
        function gutterChanged() {
            var visible = options.gutter || options.lineNumbers;
            gutter.style.display = visible ? "" : "none";
            if (visible) gutterDirty = true;
            else lineDiv.parentNode.style.marginLeft = 0;
        }
        function wrappingChanged(from, to) {
            if (options.lineWrapping) {
                wrapper.className += " CodeMirror-wrap";
                var perLine = scroller.clientWidth / charWidth() - 3;
                doc.iter(0, doc.size, function(line) {
                    if (line.hidden) return;
                    var guess = Math.ceil(line.text.length / perLine) || 1;
                    if (guess != 1) updateLineHeight(line, guess);
                });
                lineSpace.style.width = code.style.width = "";
            } else {
                wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
                maxWidth = null; maxLine = "";
                doc.iter(0, doc.size, function(line) {
                    if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
                    if (line.text.length > maxLine.length) maxLine = line.text;
                });
            }
            changes.push({from: 0, to: doc.size});
        }
        function computeTabText() {
            for (var str = '<span class="cm-tab">', i = 0; i < options.tabSize; ++i) str += " ";
            return str + "</span>";
        }
        function tabsChanged() {
            tabText = computeTabText();
            updateDisplay(true);
        }
        function themeChanged() {
            scroller.className = scroller.className.replace(/\s*cm-s-\w+/g, "") +
                options.theme.replace(/(^|\s)\s*/g, " cm-s-");
        }
        function TextMarker() { this.set = []; }
        TextMarker.prototype.clear = operation(function() {
            var min = Infinity, max = -Infinity;
            for (var i = 0, e = this.set.length; i < e; ++i) {
                var line = this.set[i], mk = line.marked;
                if (!mk || !line.parent) continue;
                var lineN = lineNo(line);
                min = Math.min(min, lineN); max = Math.max(max, lineN);
                for (var j = 0; j < mk.length; ++j)
                    if (mk[j].set == this.set) mk.splice(j--, 1);
            }
            if (min != Infinity)
                changes.push({from: min, to: max + 1});
        });
        TextMarker.prototype.find = function() {
            var from, to;
            for (var i = 0, e = this.set.length; i < e; ++i) {
                var line = this.set[i], mk = line.marked;
                for (var j = 0; j < mk.length; ++j) {
                    var mark = mk[j];
                    if (mark.set == this.set) {
                        if (mark.from != null || mark.to != null) {
                            var found = lineNo(line);
                            if (found != null) {
                                if (mark.from != null) from = {line: found, ch: mark.from};
                                if (mark.to != null) to = {line: found, ch: mark.to};
                            }
                        }
                    }
                }
            }
            return {from: from, to: to};
        };
        function markText(from, to, className) {
            from = clipPos(from); to = clipPos(to);
            var tm = new TextMarker();
            function add(line, from, to, className) {
                getLine(line).addMark(new MarkedText(from, to, className, tm.set));
            }
            if (from.line == to.line) add(from.line, from.ch, to.ch, className);
            else {
                add(from.line, from.ch, null, className);
                for (var i = from.line + 1, e = to.line; i < e; ++i)
                    add(i, null, null, className);
                add(to.line, null, to.ch, className);
            }
            changes.push({from: from.line, to: to.line + 1});
            return tm;
        }
        function setBookmark(pos) {
            pos = clipPos(pos);
            var bm = new Bookmark(pos.ch);
            getLine(pos.line).addMark(bm);
            return bm;
        }
        function addGutterMarker(line, text, className) {
            if (typeof line == "number") line = getLine(clipLine(line));
            line.gutterMarker = {text: text, style: className};
            gutterDirty = true;
            return line;
        }
        function removeGutterMarker(line) {
            if (typeof line == "number") line = getLine(clipLine(line));
            line.gutterMarker = null;
            gutterDirty = true;
        }
        function changeLine(handle, op) {
            var no = handle, line = handle;
            if (typeof handle == "number") line = getLine(clipLine(handle));
            else no = lineNo(handle);
            if (no == null) return null;
            if (op(line, no)) changes.push({from: no, to: no + 1});
            else return null;
            return line;
        }
        function setLineClass(handle, className) {
            return changeLine(handle, function(line) {
                if (line.className != className) {
                    line.className = className;
                    return true;
                }
            });
        }
        function setLineHidden(handle, hidden) {
            return changeLine(handle, function(line, no) {
                if (line.hidden != hidden) {
                    line.hidden = hidden;
                    updateLineHeight(line, hidden ? 0 : 1);
                    if (hidden && (sel.from.line == no || sel.to.line == no))
                        setSelection(skipHidden(sel.from, sel.from.line, sel.from.ch),
                            skipHidden(sel.to, sel.to.line, sel.to.ch));
                    return (gutterDirty = true);
                }
            });
        }
        function lineInfo(line) {
            if (typeof line == "number") {
                if (!isLine(line)) return null;
                var n = line;
                line = getLine(line);
                if (!line) return null;
            }
            else {
                var n = lineNo(line);
                if (n == null) return null;
            }
            var marker = line.gutterMarker;
            return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
                markerClass: marker && marker.style, lineClass: line.className};
        }
        function stringWidth(str) {
            measure.innerHTML = "<pre><span>x</span></pre>";
            measure.firstChild.firstChild.firstChild.nodeValue = str;
            return measure.firstChild.firstChild.offsetWidth || 10;
        }
        // These are used to go from pixel positions to character
        // positions, taking varying character widths into account.
        function charFromX(line, x) {
            if (x <= 0) return 0;
            var lineObj = getLine(line), text = lineObj.text;
            function getX(len) {
                measure.innerHTML = "<pre><span>" + lineObj.getHTML(null, null, false, tabText, len) + "</span></pre>";
                return measure.firstChild.firstChild.offsetWidth;
            }
            var from = 0, fromX = 0, to = text.length, toX;
            // Guess a suitable upper bound for our search.
            var estimated = Math.min(to, Math.ceil(x / charWidth()));
            for (;;) {
                var estX = getX(estimated);
                if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
                else {toX = estX; to = estimated; break;}
            }
            if (x > toX) return to;
            // Try to guess a suitable lower bound as well.
            estimated = Math.floor(to * 0.8); estX = getX(estimated);
            if (estX < x) {from = estimated; fromX = estX;}
            // Do a binary search between these bounds.
            for (;;) {
                if (to - from <= 1) return (toX - x > x - fromX) ? from : to;
                var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
                if (middleX > x) {to = middle; toX = middleX;}
                else {from = middle; fromX = middleX;}
            }
        }
        var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
        function measureLine(line, ch) {
            var extra = "";
            // Include extra text at the end to make sure the measured line is wrapped in the right way.
            if (options.lineWrapping) {
                var end = line.text.indexOf(" ", ch + 2);
                extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
            }
            measure.innerHTML = "<pre>" + line.getHTML(null, null, false, tabText, ch) +
                '<span id="CodeMirror-temp-' + tempId + '">' + htmlEscape(line.text.charAt(ch) || " ") + "</span>" +
                extra + "</pre>";
            var elt = document.getElementById("CodeMirror-temp-" + tempId);
            var top = elt.offsetTop, left = elt.offsetLeft;
            // Older IEs report zero offsets for spans directly after a wrap
            if (ie && ch && top == 0 && left == 0) {
                var backup = document.createElement("span");
                backup.innerHTML = "x";
                elt.parentNode.insertBefore(backup, elt.nextSibling);
                top = backup.offsetTop;
            }
            return {top: top, left: left};
        }
        function localCoords(pos, inLineWrap) {
            var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
            if (pos.ch == 0) x = 0;
            else {
                var sp = measureLine(getLine(pos.line), pos.ch);
                x = sp.left;
                if (options.lineWrapping) y += Math.max(0, sp.top);
            }
            return {x: x, y: y, yBot: y + lh};
        }
        // Coords must be lineSpace-local
        function coordsChar(x, y) {
            if (y < 0) y = 0;
            var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
            var lineNo = lineAtHeight(doc, heightPos);
            if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
            var lineObj = getLine(lineNo), text = lineObj.text;
            var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
            if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
            function getX(len) {
                var sp = measureLine(lineObj, len);
                if (tw) {
                    var off = Math.round(sp.top / th);
                    return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
                }
                return sp.left;
            }
            var from = 0, fromX = 0, to = text.length, toX;
            // Guess a suitable upper bound for our search.
            var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
            for (;;) {
                var estX = getX(estimated);
                if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
                else {toX = estX; to = estimated; break;}
            }
            if (x > toX) return {line: lineNo, ch: to};
            // Try to guess a suitable lower bound as well.
            estimated = Math.floor(to * 0.8); estX = getX(estimated);
            if (estX < x) {from = estimated; fromX = estX;}
            // Do a binary search between these bounds.
            for (;;) {
                if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to};
                var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
                if (middleX > x) {to = middle; toX = middleX;}
                else {from = middle; fromX = middleX;}
            }
        }
        function pageCoords(pos) {
            var local = localCoords(pos, true), off = eltOffset(lineSpace);
            return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
        }
        var cachedHeight, cachedHeightFor, measureText;
        function textHeight() {
            if (measureText == null) {
                measureText = "<pre>";
                for (var i = 0; i < 49; ++i) measureText += "x<br/>";
                measureText += "x</pre>";
            }
            var offsetHeight = lineDiv.clientHeight;
            if (offsetHeight == cachedHeightFor) return cachedHeight;
            cachedHeightFor = offsetHeight;
            measure.innerHTML = measureText;
            cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
            measure.innerHTML = "";
            return cachedHeight;
        }
        var cachedWidth, cachedWidthFor = 0;
        function charWidth() {
            if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
            cachedWidthFor = scroller.clientWidth;
            return (cachedWidth = stringWidth("x"));
        }
        function paddingTop() {return lineSpace.offsetTop;}
        function paddingLeft() {return lineSpace.offsetLeft;}
        function posFromMouse(e, liberal) {
            var offW = eltOffset(scroller, true), x, y;
            // Fails unpredictably on IE[67] when mouse is dragged around quickly.
            try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
            // This is a mess of a heuristic to try and determine whether a
            // scroll-bar was clicked or not, and to return null if one was
            // (and !liberal).
            if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
                return null;
            var offL = eltOffset(lineSpace, true);
            return coordsChar(x - offL.left, y - offL.top);
        }
        function onContextMenu(e) {
            var pos = posFromMouse(e);
            if (!pos || window.opera) return; // Opera is difficult.
            if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
                operation(setCursor)(pos.line, pos.ch);
            var oldCSS = input.style.cssText;
            inputDiv.style.position = "absolute";
            input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
                "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
                "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
            leaveInputAlone = true;
            var val = input.value = getSelection();
            focusInput();
            input.select();
            function rehide() {
                var newVal = splitLines(input.value).join("\n");
                if (newVal != val) operation(replaceSelection)(newVal, "end");
                inputDiv.style.position = "relative";
                input.style.cssText = oldCSS;
                leaveInputAlone = false;
                resetInput(true);
                slowPoll();
            }
            if (gecko) {
                e_stop(e);
                var mouseup = connect(window, "mouseup", function() {
                    mouseup();
                    setTimeout(rehide, 20);
                }, true);
            }
            else {
                setTimeout(rehide, 50);
            }
        }
        // Cursor-blinking
        function restartBlink() {
            clearInterval(blinker);
            var on = true;
            cursor.style.visibility = "";
            blinker = setInterval(function() {
                cursor.style.visibility = (on = !on) ? "" : "hidden";
            }, 650);
        }
        var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
        function matchBrackets(autoclear) {
            var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
            var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
            if (!match) return;
            var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
            for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
                if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
            var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
            function scan(line, from, to) {
                if (!line.text) return;
                var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
                for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
                    var text = st[i];
                    if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}
                    for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
                        if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
                            var match = matching[cur];
                            if (match.charAt(1) == ">" == forward) stack.push(cur);
                            else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
                            else if (!stack.length) return {pos: pos, match: true};
                        }
                    }
                }
            }
            for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
                var line = getLine(i), first = i == head.line;
                var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
                if (found) break;
            }
            if (!found) found = {pos: null, match: false};
            var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
            var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
                two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
            var clear = operation(function(){one.clear(); two && two.clear();});
            if (autoclear) setTimeout(clear, 800);
            else bracketHighlighted = clear;
        }
        // Finds the line to start with when starting a parse. Tries to
        // find a line with a stateAfter, so that it can start with a
        // valid state. If that fails, it returns the line with the
        // smallest indentation, which tends to need the least context to
        // parse correctly.
        function findStartLine(n) {
            var minindent, minline;
            for (var search = n, lim = n - 40; search > lim; --search) {
                if (search == 0) return 0;
                var line = getLine(search-1);
                if (line.stateAfter) return search;
                var indented = line.indentation(options.tabSize);
                if (minline == null || minindent > indented) {
                    minline = search - 1;
                    minindent = indented;
                }
            }
            return minline;
        }
        function getStateBefore(n) {
            var start = findStartLine(n), state = start && getLine(start-1).stateAfter;
            if (!state) state = startState(mode);
            else state = copyState(mode, state);
            doc.iter(start, n, function(line) {
                line.highlight(mode, state, options.tabSize);
                line.stateAfter = copyState(mode, state);
            });
            if (start < n) changes.push({from: start, to: n});
            if (n < doc.size && !getLine(n).stateAfter) work.push(n);
            return state;
        }
        function highlightLines(start, end) {
            var state = getStateBefore(start);
            doc.iter(start, end, function(line) {
                line.highlight(mode, state, options.tabSize);
                line.stateAfter = copyState(mode, state);
            });
        }
        function highlightWorker() {
            var end = +new Date + options.workTime;
            var foundWork = work.length;
            while (work.length) {
                if (!getLine(showingFrom).stateAfter) var task = showingFrom;
                else var task = work.pop();
                if (task >= doc.size) continue;
                var start = findStartLine(task), state = start && getLine(start-1).stateAfter;
                if (state) state = copyState(mode, state);
                else state = startState(mode);
                var unchanged = 0, compare = mode.compareStates, realChange = false,
                    i = start, bail = false;
                doc.iter(i, doc.size, function(line) {
                    var hadState = line.stateAfter;
                    if (+new Date > end) {
                        work.push(i);
                        startWorker(options.workDelay);
                        if (realChange) changes.push({from: task, to: i + 1});
                        return (bail = true);
                    }
                    var changed = line.highlight(mode, state, options.tabSize);
                    if (changed) realChange = true;
                    line.stateAfter = copyState(mode, state);
                    if (compare) {
                        if (hadState && compare(hadState, state)) return true;
                    } else {
                        if (changed !== false || !hadState) unchanged = 0;
                        else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
                            return true;
                    }
                    ++i;
                });
                if (bail) return;
                if (realChange) changes.push({from: task, to: i + 1});
            }
            if (foundWork && options.onHighlightComplete)
                options.onHighlightComplete(instance);
        }
        function startWorker(time) {
            if (!work.length) return;
            highlight.set(time, operation(highlightWorker));
        }
        // Operations are used to wrap changes in such a way that each
        // change won't have to update the cursor and display (which would
        // be awkward, slow, and error-prone), but instead updates are
        // batched and then all combined and executed at once.
        function startOperation() {
            updateInput = userSelChange = textChanged = null;
            changes = []; selectionChanged = false; callbacks = [];
        }
        function endOperation() {
            var reScroll = false, updated;
            if (selectionChanged) reScroll = !scrollCursorIntoView();
            if (changes.length) updated = updateDisplay(changes, true);
            else {
                if (selectionChanged) updateCursor();
                if (gutterDirty) updateGutter();
            }
            if (reScroll) scrollCursorIntoView();
            if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
            if (focused && !leaveInputAlone &&
                (updateInput === true || (updateInput !== false && selectionChanged)))
                resetInput(userSelChange);
            if (selectionChanged && options.matchBrackets)
                setTimeout(operation(function() {
                    if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
                    if (posEq(sel.from, sel.to)) matchBrackets(false);
                }), 20);
            var tc = textChanged, cbs = callbacks; // these can be reset by callbacks
            if (selectionChanged && options.onCursorActivity)
                options.onCursorActivity(instance);
            if (tc && options.onChange && instance)
                options.onChange(instance, tc);
            for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
            if (updated && options.onUpdate) options.onUpdate(instance);
        }
        var nestedOperation = 0;
        function operation(f) {
            return function() {
                if (!nestedOperation++) startOperation();
                try {var result = f.apply(this, arguments);}
                finally {if (!--nestedOperation) endOperation();}
                return result;
            };
        }
        for (var ext in extensions)
            if (extensions.propertyIsEnumerable(ext) &&
                !instance.propertyIsEnumerable(ext))
                instance[ext] = extensions[ext];
        return instance;
    } // (end of function CodeMirror)
    // The default configuration options.
    CodeMirror.defaults = {
        value: "",
        mode: null,
        theme: "default",
        indentUnit: 2,
        indentWithTabs: false,
        tabSize: 4,
        keyMap: "default",
        extraKeys: null,
        electricChars: true,
        onKeyEvent: null,
        lineWrapping: false,
        lineNumbers: false,
        gutter: false,
        fixedGutter: false,
        firstLineNumber: 1,
        readOnly: false,
        onChange: null,
        onCursorActivity: null,
        onGutterClick: null,
        onHighlightComplete: null,
        onUpdate: null,
        onFocus: null, onBlur: null, onScroll: null,
        matchBrackets: false,
        workTime: 100,
        workDelay: 200,
        pollInterval: 100,
        undoDepth: 40,
        tabindex: null,
        document: window.document
    };
    var mac = /Mac/.test(navigator.platform);
    var win = /Win/.test(navigator.platform);
    // Known modes, by name and by MIME
    var modes = {}, mimeModes = {};
    CodeMirror.defineMode = function(name, mode) {
        if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
        modes[name] = mode;
    };
    CodeMirror.defineMIME = function(mime, spec) {
        mimeModes[mime] = spec;
    };
    CodeMirror.getMode = function(options, spec) {
        if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
            spec = mimeModes[spec];
        if (typeof spec == "string")
            var mname = spec, config = {};
        else if (spec != null)
            var mname = spec.name, config = spec;
        var mfactory = modes[mname];
        if (!mfactory) {
            if (window.console) console.warn("No mode " + mname + " found, falling back to plain text.");
            return CodeMirror.getMode(options, "text/plain");
        }
        return mfactory(options, config || {});
    };
    CodeMirror.listModes = function() {
        var list = [];
        for (var m in modes)
            if (modes.propertyIsEnumerable(m)) list.push(m);
        return list;
    };
    CodeMirror.listMIMEs = function() {
        var list = [];
        for (var m in mimeModes)
            if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
        return list;
    };
    var extensions = CodeMirror.extensions = {};
    CodeMirror.defineExtension = function(name, func) {
        extensions[name] = func;
    };
    var commands = CodeMirror.commands = {
        selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
        killLine: function(cm) {
            var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
            if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange("", from, {line: from.line + 1, ch: 0});
            else cm.replaceRange("", from, sel ? to : {line: from.line});
        },
        deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange("", {line: l, ch: 0}, {line: l});},
        undo: function(cm) {cm.undo();},
        redo: function(cm) {cm.redo();},
        goDocStart: function(cm) {cm.setCursor(0, 0, true);},
        goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},
        goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},
        goLineStartSmart: function(cm) {
            var cur = cm.getCursor();
            var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\S/));
            cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);
        },
        goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},
        goLineUp: function(cm) {cm.moveV(-1, "line");},
        goLineDown: function(cm) {cm.moveV(1, "line");},
        goPageUp: function(cm) {cm.moveV(-1, "page");},
        goPageDown: function(cm) {cm.moveV(1, "page");},
        goCharLeft: function(cm) {cm.moveH(-1, "char");},
        goCharRight: function(cm) {cm.moveH(1, "char");},
        goColumnLeft: function(cm) {cm.moveH(-1, "column");},
        goColumnRight: function(cm) {cm.moveH(1, "column");},
        goWordLeft: function(cm) {cm.moveH(-1, "word");},
        goWordRight: function(cm) {cm.moveH(1, "word");},
        delCharLeft: function(cm) {cm.deleteH(-1, "char");},
        delCharRight: function(cm) {cm.deleteH(1, "char");},
        delWordLeft: function(cm) {cm.deleteH(-1, "word");},
        delWordRight: function(cm) {cm.deleteH(1, "word");},
        indentAuto: function(cm) {cm.indentSelection("smart");},
        indentMore: function(cm) {cm.indentSelection("add");},
        indentLess: function(cm) {cm.indentSelection("subtract");},
        insertTab: function(cm) {cm.replaceSelection("\t", "end");},
        transposeChars: function(cm) {
            var cur = cm.getCursor(), line = cm.getLine(cur.line);
            if (cur.ch > 0 && cur.ch < line.length - 1)
                cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
                    {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
        },
        newlineAndIndent: function(cm) {
            cm.replaceSelection("\n", "end");
            cm.indentLine(cm.getCursor().line);
        },
        toggleOverwrite: function(cm) {cm.toggleOverwrite();}
    };
    var keyMap = CodeMirror.keyMap = {};
    keyMap.basic = {
        "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
        "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
        "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "indentMore", "Shift-Tab": "indentLess",
        "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
    };
    // Note that the save and find-related commands aren't defined by
    // default. Unknown commands are simply ignored.
    keyMap.pcDefault = {
        "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
        "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
        "Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
        "Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
        "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
        fallthrough: "basic"
    };
    keyMap.macDefault = {
        "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
        "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
        "Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
        "Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
        "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
        fallthrough: ["basic", "emacsy"]
    };
    keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
    keyMap.emacsy = {
        "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
        "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
        "Ctrl-V": "goPageUp", "Shift-Ctrl-V": "goPageDown", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft",
        "Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
    };
    function lookupKey(name, extraMap, map) {
        function lookup(name, map, ft) {
            var found = map[name];
            if (found != null) return found;
            if (ft == null) ft = map.fallthrough;
            if (ft == null) return map.catchall;
            if (typeof ft == "string") return lookup(name, keyMap[ft]);
            for (var i = 0, e = ft.length; i < e; ++i) {
                found = lookup(name, keyMap[ft[i]]);
                if (found != null) return found;
            }
            return null;
        }
        return extraMap ? lookup(name, extraMap, map) : lookup(name, keyMap[map]);
    }
    function isModifierKey(event) {
        var name = keyNames[event.keyCode];
        return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
    }
    CodeMirror.fromTextArea = function(textarea, options) {
        if (!options) options = {};
        options.value = textarea.value;
        if (!options.tabindex && textarea.tabindex)
            options.tabindex = textarea.tabindex;
        function save() {textarea.value = instance.getValue();}
        if (textarea.form) {
            // Deplorable hack to make the submit method do the right thing.
            var rmSubmit = connect(textarea.form, "submit", save, true);
            if (typeof textarea.form.submit == "function") {
                var realSubmit = textarea.form.submit;
                function wrappedSubmit() {
                    save();
                    textarea.form.submit = realSubmit;
                    textarea.form.submit();
                    textarea.form.submit = wrappedSubmit;
                }
                textarea.form.submit = wrappedSubmit;
            }
        }
        textarea.style.display = "none";
        var instance = CodeMirror(function(node) {
            textarea.parentNode.insertBefore(node, textarea.nextSibling);
        }, options);
        instance.save = save;
        instance.getTextArea = function() { return textarea; };
        instance.toTextArea = function() {
            save();
            textarea.parentNode.removeChild(instance.getWrapperElement());
            textarea.style.display = "";
            if (textarea.form) {
                rmSubmit();
                if (typeof textarea.form.submit == "function")
                    textarea.form.submit = realSubmit;
            }
        };
        return instance;
    };
    // Utility functions for working with state. Exported because modes
    // sometimes need to do this.
    function copyState(mode, state) {
        if (state === true) return state;
        if (mode.copyState) return mode.copyState(state);
        var nstate = {};
        for (var n in state) {
            var val = state[n];
            if (val instanceof Array) val = val.concat([]);
            nstate[n] = val;
        }
        return nstate;
    }
    CodeMirror.copyState = copyState;
    function startState(mode, a1, a2) {
        return mode.startState ? mode.startState(a1, a2) : true;
    }
    CodeMirror.startState = startState;
    // The character stream used by a mode's parser.
    function StringStream(string, tabSize) {
        this.pos = this.start = 0;
        this.string = string;
        this.tabSize = tabSize || 8;
    }
    StringStream.prototype = {
        eol: function() {return this.pos >= this.string.length;},
        sol: function() {return this.pos == 0;},
        peek: function() {return this.string.charAt(this.pos);},
        next: function() {
            if (this.pos < this.string.length)
                return this.string.charAt(this.pos++);
        },
        eat: function(match) {
            var ch = this.string.charAt(this.pos);
            if (typeof match == "string") var ok = ch == match;
            else var ok = ch && (match.test ? match.test(ch) : match(ch));
            if (ok) {++this.pos; return ch;}
        },
        eatWhile: function(match) {
            var start = this.pos;
            while (this.eat(match)){}
            return this.pos > start;
        },
        eatSpace: function() {
            var start = this.pos;
            while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
            return this.pos > start;
        },
        skipToEnd: function() {this.pos = this.string.length;},
        skipTo: function(ch) {
            var found = this.string.indexOf(ch, this.pos);
            if (found > -1) {this.pos = found; return true;}
        },
        backUp: function(n) {this.pos -= n;},
        column: function() {return countColumn(this.string, this.start, this.tabSize);},
        indentation: function() {return countColumn(this.string, null, this.tabSize);},
        match: function(pattern, consume, caseInsensitive) {
            if (typeof pattern == "string") {
                function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
                if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
                    if (consume !== false) this.pos += pattern.length;
                    return true;
                }
            }
            else {
                var match = this.string.slice(this.pos).match(pattern);
                if (match && consume !== false) this.pos += match[0].length;
                return match;
            }
        },
        current: function(){return this.string.slice(this.start, this.pos);}
    };
    CodeMirror.StringStream = StringStream;
    function MarkedText(from, to, className, set) {
        this.from = from; this.to = to; this.style = className; this.set = set;
    }
    MarkedText.prototype = {
        attach: function(line) { this.set.push(line); },
        detach: function(line) {
            var ix = indexOf(this.set, line);
            if (ix > -1) this.set.splice(ix, 1);
        },
        split: function(pos, lenBefore) {
            if (this.to <= pos && this.to != null) return null;
            var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
            var to = this.to == null ? null : this.to - pos + lenBefore;
            return new MarkedText(from, to, this.style, this.set);
        },
        dup: function() { return new MarkedText(null, null, this.style, this.set); },
        clipTo: function(fromOpen, from, toOpen, to, diff) {
            if (this.from != null && this.from >= from)
                this.from = Math.max(to, this.from) + diff;
            if (this.to != null && this.to > from)
                this.to = to < this.to ? this.to + diff : from;
            if (fromOpen && to > this.from && (to < this.to || this.to == null))
                this.from = null;
            if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
                this.to = null;
        },
        isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
        sameSet: function(x) { return this.set == x.set; }
    };
    function Bookmark(pos) {
        this.from = pos; this.to = pos; this.line = null;
    }
    Bookmark.prototype = {
        attach: function(line) { this.line = line; },
        detach: function(line) { if (this.line == line) this.line = null; },
        split: function(pos, lenBefore) {
            if (pos < this.from) {
                this.from = this.to = (this.from - pos) + lenBefore;
                return this;
            }
        },
        isDead: function() { return this.from > this.to; },
        clipTo: function(fromOpen, from, toOpen, to, diff) {
            if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {
                this.from = 0; this.to = -1;
            } else if (this.from > from) {
                this.from = this.to = Math.max(to, this.from) + diff;
            }
        },
        sameSet: function(x) { return false; },
        find: function() {
            if (!this.line || !this.line.parent) return null;
            return {line: lineNo(this.line), ch: this.from};
        },
        clear: function() {
            if (this.line) {
                var found = indexOf(this.line.marked, this);
                if (found != -1) this.line.marked.splice(found, 1);
                this.line = null;
            }
        }
    };
    // Line objects. These hold state related to a line, including
    // highlighting info (the styles array).
    function Line(text, styles) {
        this.styles = styles || [text, null];
        this.text = text;
        this.height = 1;
        this.marked = this.gutterMarker = this.className = this.handlers = null;
        this.stateAfter = this.parent = this.hidden = null;
    }
    Line.inheritMarks = function(text, orig) {
        var ln = new Line(text), mk = orig && orig.marked;
        if (mk) {
            for (var i = 0; i < mk.length; ++i) {
                if (mk[i].to == null && mk[i].style) {
                    var newmk = ln.marked || (ln.marked = []), mark = mk[i];
                    var nmark = mark.dup(); newmk.push(nmark); nmark.attach(ln);
                }
            }
        }
        return ln;
    }
    Line.prototype = {
        // Replace a piece of a line, keeping the styles around it intact.
        replace: function(from, to_, text) {
            var st = [], mk = this.marked, to = to_ == null ? this.text.length : to_;
            copyStyles(0, from, this.styles, st);
            if (text) st.push(text, null);
            copyStyles(to, this.text.length, this.styles, st);
            this.styles = st;
            this.text = this.text.slice(0, from) + text + this.text.slice(to);
            this.stateAfter = null;
            if (mk) {
                var diff = text.length - (to - from);
                for (var i = 0, mark = mk[i]; i < mk.length; ++i) {
                    mark.clipTo(from == null, from || 0, to_ == null, to, diff);
                    if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}
                }
            }
        },
        // Split a part off a line, keeping styles and markers intact.
        split: function(pos, textBefore) {
            var st = [textBefore, null], mk = this.marked;
            copyStyles(pos, this.text.length, this.styles, st);
            var taken = new Line(textBefore + this.text.slice(pos), st);
            if (mk) {
                for (var i = 0; i < mk.length; ++i) {
                    var mark = mk[i];
                    var newmark = mark.split(pos, textBefore.length);
                    if (newmark) {
                        if (!taken.marked) taken.marked = [];
                        taken.marked.push(newmark); newmark.attach(taken);
                    }
                }
            }
            return taken;
        },
        append: function(line) {
            var mylen = this.text.length, mk = line.marked, mymk = this.marked;
            this.text += line.text;
            copyStyles(0, line.text.length, line.styles, this.styles);
            if (mymk) {
                for (var i = 0; i < mymk.length; ++i)
                    if (mymk[i].to == null) mymk[i].to = mylen;
            }
            if (mk && mk.length) {
                if (!mymk) this.marked = mymk = [];
                outer: for (var i = 0; i < mk.length; ++i) {
                    var mark = mk[i];
                    if (!mark.from) {
                        for (var j = 0; j < mymk.length; ++j) {
                            var mymark = mymk[j];
                            if (mymark.to == mylen && mymark.sameSet(mark)) {
                                mymark.to = mark.to == null ? null : mark.to + mylen;
                                if (mymark.isDead()) {
                                    mymark.detach(this);
                                    mk.splice(i--, 1);
                                }
                                continue outer;
                            }
                        }
                    }
                    mymk.push(mark);
                    mark.attach(this);
                    mark.from += mylen;
                    if (mark.to != null) mark.to += mylen;
                }
            }
        },
        fixMarkEnds: function(other) {
            var mk = this.marked, omk = other.marked;
            if (!mk) return;
            for (var i = 0; i < mk.length; ++i) {
                var mark = mk[i], close = mark.to == null;
                if (close && omk) {
                    for (var j = 0; j < omk.length; ++j)
                        if (omk[j].sameSet(mark)) {close = false; break;}
                }
                if (close) mark.to = this.text.length;
            }
        },
        fixMarkStarts: function() {
            var mk = this.marked;
            if (!mk) return;
            for (var i = 0; i < mk.length; ++i)
                if (mk[i].from == null) mk[i].from = 0;
        },
        addMark: function(mark) {
            mark.attach(this);
            if (this.marked == null) this.marked = [];
            this.marked.push(mark);
            this.marked.sort(function(a, b){return (a.from || 0) - (b.from || 0);});
        },
        // Run the given mode's parser over a line, update the styles
        // array, which contains alternating fragments of text and CSS
        // classes.
        highlight: function(mode, state, tabSize) {
            var stream = new StringStream(this.text, tabSize), st = this.styles, pos = 0;
            var changed = false, curWord = st[0], prevWord;
            if (this.text == "" && mode.blankLine) mode.blankLine(state);
            while (!stream.eol()) {
                var style = mode.token(stream, state);
                var substr = this.text.slice(stream.start, stream.pos);
                stream.start = stream.pos;
                if (pos && st[pos-1] == style)
                    st[pos-2] += substr;
                else if (substr) {
                    if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;
                    st[pos++] = substr; st[pos++] = style;
                    prevWord = curWord; curWord = st[pos];
                }
                // Give up when line is ridiculously long
                if (stream.pos > 5000) {
                    st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
                    break;
                }
            }
            if (st.length != pos) {st.length = pos; changed = true;}
            if (pos && st[pos-2] != prevWord) changed = true;
            // Short lines with simple highlights return null, and are
            // counted as changed by the driver because they are likely to
            // highlight the same way in various contexts.
            return changed || (st.length < 5 && this.text.length < 10 ? null : false);
        },
        // Fetch the parser token for a given character. Useful for hacks
        // that want to inspect the mode state (say, for completion).
        getTokenAt: function(mode, state, ch) {
            var txt = this.text, stream = new StringStream(txt);
            while (stream.pos < ch && !stream.eol()) {
                stream.start = stream.pos;
                var style = mode.token(stream, state);
            }
            return {start: stream.start,
                end: stream.pos,
                string: stream.current(),
                className: style || null,
                state: state};
        },
        indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
        // Produces an HTML fragment for the line, taking selection,
        // marking, and highlighting into account.
        getHTML: function(sfrom, sto, includePre, tabText, endAt) {
            var html = [], first = true;
            if (includePre)
                html.push(this.className ? '<pre class="' + this.className + '">': "<pre>");
            function span(text, style) {
                if (!text) return;
                // Work around a bug where, in some compat modes, IE ignores leading spaces
                if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
                first = false;
                if (style) html.push('<span class="', style, '">', htmlEscape(text).replace(/\t/g, tabText), "</span>");
                else html.push(htmlEscape(text).replace(/\t/g, tabText));
            }
            var st = this.styles, allText = this.text, marked = this.marked;
            if (sfrom == sto) sfrom = null;
            var len = allText.length;
            if (endAt != null) len = Math.min(endAt, len);
            if (!allText && endAt == null)
                span(" ", sfrom != null && sto == null ? "CodeMirror-selected" : null);
            else if (!marked && sfrom == null)
                for (var i = 0, ch = 0; ch < len; i+=2) {
                    var str = st[i], style = st[i+1], l = str.length;
                    if (ch + l > len) str = str.slice(0, len - ch);
                    ch += l;
                    span(str, style && "cm-" + style);
                }
            else {
                var pos = 0, i = 0, text = "", style, sg = 0;
                var markpos = -1, mark = null;
                function nextMark() {
                    if (marked) {
                        markpos += 1;
                        mark = (markpos < marked.length) ? marked[markpos] : null;
                    }
                }
                nextMark();
                while (pos < len) {
                    var upto = len;
                    var extraStyle = "";
                    if (sfrom != null) {
                        if (sfrom > pos) upto = sfrom;
                        else if (sto == null || sto > pos) {
                            extraStyle = " CodeMirror-selected";
                            if (sto != null) upto = Math.min(upto, sto);
                        }
                    }
                    while (mark && mark.to != null && mark.to <= pos) nextMark();
                    if (mark) {
                        if (mark.from > pos) upto = Math.min(upto, mark.from);
                        else {
                            extraStyle += " " + mark.style;
                            if (mark.to != null) upto = Math.min(upto, mark.to);
                        }
                    }
                    for (;;) {
                        var end = pos + text.length;
                        var appliedStyle = style;
                        if (extraStyle) appliedStyle = style ? style + extraStyle : extraStyle;
                        span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
                        if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
                        pos = end;
                        text = st[i++]; style = "cm-" + st[i++];
                    }
                }
                if (sfrom != null && sto == null) span(" ", "CodeMirror-selected");
            }
            if (includePre) html.push("</pre>");
            return html.join("");
        },
        cleanUp: function() {
            this.parent = null;
            if (this.marked)
                for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);
        }
    };
    // Utility used by replace and split above
    function copyStyles(from, to, source, dest) {
        for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {
            var part = source[i], end = pos + part.length;
            if (state == 0) {
                if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
                if (end >= from) state = 1;
            }
            else if (state == 1) {
                if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
                else dest.push(part, source[i+1]);
            }
            pos = end;
        }
    }
    // Data structure that holds the sequence of lines.
    function LeafChunk(lines) {
        this.lines = lines;
        this.parent = null;
        for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
            lines[i].parent = this;
            height += lines[i].height;
        }
        this.height = height;
    }
    LeafChunk.prototype = {
        chunkSize: function() { return this.lines.length; },
        remove: function(at, n, callbacks) {
            for (var i = at, e = at + n; i < e; ++i) {
                var line = this.lines[i];
                this.height -= line.height;
                line.cleanUp();
                if (line.handlers)
                    for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);
            }
            this.lines.splice(at, n);
        },
        collapse: function(lines) {
            lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
        },
        insertHeight: function(at, lines, height) {
            this.height += height;
            this.lines.splice.apply(this.lines, [at, 0].concat(lines));
            for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
        },
        iterN: function(at, n, op) {
            for (var e = at + n; at < e; ++at)
                if (op(this.lines[at])) return true;
        }
    };
    function BranchChunk(children) {
        this.children = children;
        var size = 0, height = 0;
        for (var i = 0, e = children.length; i < e; ++i) {
            var ch = children[i];
            size += ch.chunkSize(); height += ch.height;
            ch.parent = this;
        }
        this.size = size;
        this.height = height;
        this.parent = null;
    }
    BranchChunk.prototype = {
        chunkSize: function() { return this.size; },
        remove: function(at, n, callbacks) {
            this.size -= n;
            for (var i = 0; i < this.children.length; ++i) {
                var child = this.children[i], sz = child.chunkSize();
                if (at < sz) {
                    var rm = Math.min(n, sz - at), oldHeight = child.height;
                    child.remove(at, rm, callbacks);
                    this.height -= oldHeight - child.height;
                    if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
                    if ((n -= rm) == 0) break;
                    at = 0;
                } else at -= sz;
            }
            if (this.size - n < 25) {
                var lines = [];
                this.collapse(lines);
                this.children = [new LeafChunk(lines)];
            }
        },
        collapse: function(lines) {
            for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
        },
        insert: function(at, lines) {
            var height = 0;
            for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
            this.insertHeight(at, lines, height);
        },
        insertHeight: function(at, lines, height) {
            this.size += lines.length;
            this.height += height;
            for (var i = 0, e = this.children.length; i < e; ++i) {
                var child = this.children[i], sz = child.chunkSize();
                if (at <= sz) {
                    child.insertHeight(at, lines, height);
                    if (child.lines && child.lines.length > 50) {
                        while (child.lines.length > 50) {
                            var spilled = child.lines.splice(child.lines.length - 25, 25);
                            var newleaf = new LeafChunk(spilled);
                            child.height -= newleaf.height;
                            this.children.splice(i + 1, 0, newleaf);
                            newleaf.parent = this;
                        }
                        this.maybeSpill();
                    }
                    break;
                }
                at -= sz;
            }
        },
        maybeSpill: function() {
            if (this.children.length <= 10) return;
            var me = this;
            do {
                var spilled = me.children.splice(me.children.length - 5, 5);
                var sibling = new BranchChunk(spilled);
                if (!me.parent) { // Become the parent node
                    var copy = new BranchChunk(me.children);
                    copy.parent = me;
                    me.children = [copy, sibling];
                    me = copy;
                } else {
                    me.size -= sibling.size;
                    me.height -= sibling.height;
                    var myIndex = indexOf(me.parent.children, me);
                    me.parent.children.splice(myIndex + 1, 0, sibling);
                }
                sibling.parent = me.parent;
            } while (me.children.length > 10);
            me.parent.maybeSpill();
        },
        iter: function(from, to, op) { this.iterN(from, to - from, op); },
        iterN: function(at, n, op) {
            for (var i = 0, e = this.children.length; i < e; ++i) {
                var child = this.children[i], sz = child.chunkSize();
                if (at < sz) {
                    var used = Math.min(n, sz - at);
                    if (child.iterN(at, used, op)) return true;
                    if ((n -= used) == 0) break;
                    at = 0;
                } else at -= sz;
            }
        }
    };
    function getLineAt(chunk, n) {
        while (!chunk.lines) {
            for (var i = 0;; ++i) {
                var child = chunk.children[i], sz = child.chunkSize();
                if (n < sz) { chunk = child; break; }
                n -= sz;
            }
        }
        return chunk.lines[n];
    }
    function lineNo(line) {
        if (line.parent == null) return null;
        var cur = line.parent, no = indexOf(cur.lines, line);
        for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
            for (var i = 0, e = chunk.children.length; ; ++i) {
                if (chunk.children[i] == cur) break;
                no += chunk.children[i].chunkSize();
            }
        }
        return no;
    }
    function lineAtHeight(chunk, h) {
        var n = 0;
        outer: do {
            for (var i = 0, e = chunk.children.length; i < e; ++i) {
                var child = chunk.children[i], ch = child.height;
                if (h < ch) { chunk = child; continue outer; }
                h -= ch;
                n += child.chunkSize();
            }
            return n;
        } while (!chunk.lines);
        for (var i = 0, e = chunk.lines.length; i < e; ++i) {
            var line = chunk.lines[i], lh = line.height;
            if (h < lh) break;
            h -= lh;
        }
        return n + i;
    }
    function heightAtLine(chunk, n) {
        var h = 0;
        outer: do {
            for (var i = 0, e = chunk.children.length; i < e; ++i) {
                var child = chunk.children[i], sz = child.chunkSize();
                if (n < sz) { chunk = child; continue outer; }
                n -= sz;
                h += child.height;
            }
            return h;
        } while (!chunk.lines);
        for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
        return h;
    }
    // The history object 'chunks' changes that are made close together
    // and at almost the same time into bigger undoable units.
    function History() {
        this.time = 0;
        this.done = []; this.undone = [];
    }
    History.prototype = {
        addChange: function(start, added, old) {
            this.undone.length = 0;
            var time = +new Date, last = this.done[this.done.length - 1];
            if (time - this.time > 400 || !last ||
                last.start > start + added || last.start + last.added < start - last.added + last.old.length)
                this.done.push({start: start, added: added, old: old});
            else {
                var oldoff = 0;
                if (start < last.start) {
                    for (var i = last.start - start - 1; i >= 0; --i)
                        last.old.unshift(old[i]);
                    last.added += last.start - start;
                    last.start = start;
                }
                else if (last.start < start) {
                    oldoff = start - last.start;
                    added += oldoff;
                }
                for (var i = last.added - oldoff, e = old.length; i < e; ++i)
                    last.old.push(old[i]);
                if (last.added < added) last.added = added;
            }
            this.time = time;
        }
    };
    function stopMethod() {e_stop(this);}
    // Ensure an event has a stop method.
    function addStop(event) {
        if (!event.stop) event.stop = stopMethod;
        return event;
    }
    function e_preventDefault(e) {
        if (e.preventDefault) e.preventDefault();
        else e.returnValue = false;
    }
    function e_stopPropagation(e) {
        if (e.stopPropagation) e.stopPropagation();
        else e.cancelBubble = true;
    }
    function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
    CodeMirror.e_stop = e_stop;
    CodeMirror.e_preventDefault = e_preventDefault;
    CodeMirror.e_stopPropagation = e_stopPropagation;
    function e_target(e) {return e.target || e.srcElement;}
    function e_button(e) {
        if (e.which) return e.which;
        else if (e.button & 1) return 1;
        else if (e.button & 2) return 3;
        else if (e.button & 4) return 2;
    }
    // Event handler registration. If disconnect is true, it'll return a
    // function that unregisters the handler.
    function connect(node, type, handler, disconnect) {
        if (typeof node.addEventListener == "function") {
            node.addEventListener(type, handler, false);
            if (disconnect) return function() {node.removeEventListener(type, handler, false);};
        }
        else {
            var wrapHandler = function(event) {handler(event || window.event);};
            node.attachEvent("on" + type, wrapHandler);
            if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
        }
    }
    CodeMirror.connect = connect;
    function Delayed() {this.id = null;}
    Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
    // Detect drag-and-drop
    var dragAndDrop = function() {
        // IE8 has ondragstart and ondrop properties, but doesn't seem to
        // actually support ondragstart the way it's supposed to work.
        if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
        var div = document.createElement('div');
        return "draggable" in div;
    }();
    var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
    var ie = /MSIE \d/.test(navigator.userAgent);
    var webkit = /WebKit\//.test(navigator.userAgent);
    var lineSep = "\n";
    // Feature-detect whether newlines in textareas are converted to \r\n
    (function () {
        var te = document.createElement("textarea");
        te.value = "foo\nbar";
        if (te.value.indexOf("\r") > -1) lineSep = "\r\n";
    }());
    // Counts the column offset in a string, taking tabs into account.
    // Used mostly to find indentation.
    function countColumn(string, end, tabSize) {
        if (end == null) {
            end = string.search(/[^\s\u00a0]/);
            if (end == -1) end = string.length;
        }
        for (var i = 0, n = 0; i < end; ++i) {
            if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
            else ++n;
        }
        return n;
    }
    function computedStyle(elt) {
        if (elt.currentStyle) return elt.currentStyle;
        return window.getComputedStyle(elt, null);
    }
    // Find the position of an element by following the offsetParent chain.
    // If screen==true, it returns screen (rather than page) coordinates.
    function eltOffset(node, screen) {
        var bod = node.ownerDocument.body;
        var x = 0, y = 0, skipBody = false;
        for (var n = node; n; n = n.offsetParent) {
            var ol = n.offsetLeft, ot = n.offsetTop;
            // Firefox reports weird inverted offsets when the body has a border.
            if (n == bod) { x += Math.abs(ol); y += Math.abs(ot); }
            else { x += ol, y += ot; }
            if (screen && computedStyle(n).position == "fixed")
                skipBody = true;
        }
        var e = screen && !skipBody ? null : bod;
        for (var n = node.parentNode; n != e; n = n.parentNode)
            if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}
        return {left: x, top: y};
    }
    // Use the faster and saner getBoundingClientRect method when possible.
    if (document.documentElement.getBoundingClientRect != null) eltOffset = function(node, screen) {
        // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
        // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
        try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }
        catch(e) { box = {top: 0, left: 0}; }
        if (!screen) {
            // Get the toplevel scroll, working around browser differences.
            if (window.pageYOffset == null) {
                var t = document.documentElement || document.body.parentNode;
                if (t.scrollTop == null) t = document.body;
                box.top += t.scrollTop; box.left += t.scrollLeft;
            } else {
                box.top += window.pageYOffset; box.left += window.pageXOffset;
            }
        }
        return box;
    };
    // Get a node's text content.
    function eltText(node) {
        return node.textContent || node.innerText || node.nodeValue || "";
    }
    // Operations on {line, ch} objects.
    function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
    function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
    function copyPos(x) {return {line: x.line, ch: x.ch};}
    var escapeElement = document.createElement("pre");
    function htmlEscape(str) {
        escapeElement.textContent = str;
        return escapeElement.innerHTML;
    }
    // Recent (late 2011) Opera betas insert bogus newlines at the start
    // of the textContent, so we strip those.
    if (htmlEscape("a") == "\na")
        htmlEscape = function(str) {
            escapeElement.textContent = str;
            return escapeElement.innerHTML.slice(1);
        };
    // Some IEs don't preserve tabs through innerHTML
    else if (htmlEscape("\t") != "\t")
        htmlEscape = function(str) {
            escapeElement.innerHTML = "";
            escapeElement.appendChild(document.createTextNode(str));
            return escapeElement.innerHTML;
        };
    CodeMirror.htmlEscape = htmlEscape;
    // Used to position the cursor after an undo/redo by finding the
    // last edited character.
    function editEnd(from, to) {
        if (!to) return from ? from.length : 0;
        if (!from) return to.length;
        for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
            if (from.charAt(i) != to.charAt(j)) break;
        return j + 1;
    }
    function indexOf(collection, elt) {
        if (collection.indexOf) return collection.indexOf(elt);
        for (var i = 0, e = collection.length; i < e; ++i)
            if (collection[i] == elt) return i;
        return -1;
    }
    function isWordChar(ch) {
        return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase();
    }
    // See if "".split is the broken IE version, if so, provide an
    // alternative way to split lines.
    var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
        var pos = 0, nl, result = [];
        while ((nl = string.indexOf("\n", pos)) > -1) {
            result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl));
            pos = nl + 1;
        }
        result.push(string.slice(pos));
        return result;
    } : function(string){return string.split(/\r?\n/);};
    CodeMirror.splitLines = splitLines;
    var hasSelection = window.getSelection ? function(te) {
        try { return te.selectionStart != te.selectionEnd; }
        catch(e) { return false; }
    } : function(te) {
        try {var range = te.ownerDocument.selection.createRange();}
        catch(e) {}
        if (!range || range.parentElement() != te) return false;
        return range.compareEndPoints("StartToEnd", range) != 0;
    };
    CodeMirror.defineMode("null", function() {
        return {token: function(stream) {stream.skipToEnd();}};
    });
    CodeMirror.defineMIME("text/plain", "null");
    var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
        19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
        36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
        46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 186: ";", 187: "=", 188: ",",
        189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp",
        63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right",
        63233: "Down", 63302: "Insert", 63272: "Delete"};
    CodeMirror.keyNames = keyNames;
    (function() {
        // Number keys
        for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
        // Alphabetic keys
        for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
        // Function keys
        for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
    })();
    return CodeMirror;
})();
CodeMirror.defineMode("xml", function(config, parserConfig) {
    var indentUnit = config.indentUnit;
    var Kludges = parserConfig.htmlMode ? {
        autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
            "meta": true, "col": true, "frame": true, "base": true, "area": true},
        doNotIndent: {"pre": true},
        allowUnquoted: true
    } : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false};
    var alignCDATA = parserConfig.alignCDATA;
    // Return variables for tokenizers
    var tagName, type;
    function inText(stream, state) {
        function chain(parser) {
            state.tokenize = parser;
            return parser(stream, state);
        }
        var ch = stream.next();
        if (ch == "<") {
            if (stream.eat("!")) {
                if (stream.eat("[")) {
                    if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
                    else return null;
                }
                else if (stream.match("--")) return chain(inBlock("comment", "-->"));
                else if (stream.match("DOCTYPE", true, true)) {
                    stream.eatWhile(/[\w\._\-]/);
                    return chain(doctype(1));
                }
                else return null;
            }
            else if (stream.eat("?")) {
                stream.eatWhile(/[\w\._\-]/);
                state.tokenize = inBlock("meta", "?>");
                return "meta";
            }
            else {
                type = stream.eat("/") ? "closeTag" : "openTag";
                stream.eatSpace();
                tagName = "";
                var c;
                while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
                state.tokenize = inTag;
                return "tag";
            }
        }
        else if (ch == "&") {
            stream.eatWhile(/[^;]/);
            stream.eat(";");
            return "atom";
        }
        else {
            stream.eatWhile(/[^&<]/);
            return null;
        }
    }
    function inTag(stream, state) {
        var ch = stream.next();
        if (ch == ">" || (ch == "/" && stream.eat(">"))) {
            state.tokenize = inText;
            type = ch == ">" ? "endTag" : "selfcloseTag";
            return "tag";
        }
        else if (ch == "=") {
            type = "equals";
            return null;
        }
        else if (/[\'\"]/.test(ch)) {
            state.tokenize = inAttribute(ch);
            return state.tokenize(stream, state);
        }
        else {
            stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
            return "word";
        }
    }
    function inAttribute(quote) {
        return function(stream, state) {
            while (!stream.eol()) {
                if (stream.next() == quote) {
                    state.tokenize = inTag;
                    break;
                }
            }
            return "string";
        };
    }
    function inBlock(style, terminator) {
        return function(stream, state) {
            while (!stream.eol()) {
                if (stream.match(terminator)) {
                    state.tokenize = inText;
                    break;
                }
                stream.next();
            }
            return style;
        };
    }
    function doctype(depth) {
        return function(stream, state) {
            var ch;
            while ((ch = stream.next()) != null) {
                if (ch == "<") {
                    state.tokenize = doctype(depth + 1);
                    return state.tokenize(stream, state);
                } else if (ch == ">") {
                    if (depth == 1) {
                        state.tokenize = inText;
                        break;
                    } else {
                        state.tokenize = doctype(depth - 1);
                        return state.tokenize(stream, state);
                    }
                }
            }
            return "meta";
        };
    }
    var curState, setStyle;
    function pass() {
        for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
    }
    function cont() {
        pass.apply(null, arguments);
        return true;
    }
    function pushContext(tagName, startOfLine) {
        var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
        curState.context = {
            prev: curState.context,
            tagName: tagName,
            indent: curState.indented,
            startOfLine: startOfLine,
            noIndent: noIndent
        };
    }
    function popContext() {
        if (curState.context) curState.context = curState.context.prev;
    }
    function element(type) {
        if (type == "openTag") {
            curState.tagName = tagName;
            return cont(attributes, endtag(curState.startOfLine));
        } else if (type == "closeTag") {
            var err = false;
            if (curState.context) {
                err = curState.context.tagName != tagName;
            } else {
                err = true;
            }
            if (err) setStyle = "error";
            return cont(endclosetag(err));
        }
        return cont();
    }
    function endtag(startOfLine) {
        return function(type) {
            if (type == "selfcloseTag" ||
                (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
                return cont();
            if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
            return cont();
        };
    }
    function endclosetag(err) {
        return function(type) {
            if (err) setStyle = "error";
            if (type == "endTag") { popContext(); return cont(); }
            setStyle = "error";
            return cont(arguments.callee);
        }
    }
    function attributes(type) {
        if (type == "word") {setStyle = "attribute"; return cont(attributes);}
        if (type == "equals") return cont(attvalue, attributes);
        if (type == "string") {setStyle = "error"; return cont(attributes);}
        return pass();
    }
    function attvalue(type) {
        if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
        if (type == "string") return cont(attvaluemaybe);
        return pass();
    }
    function attvaluemaybe(type) {
        if (type == "string") return cont(attvaluemaybe);
        else return pass();
    }
    return {
        startState: function() {
            return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
        },
        token: function(stream, state) {
            if (stream.sol()) {
                state.startOfLine = true;
                state.indented = stream.indentation();
            }
            if (stream.eatSpace()) return null;
            setStyle = type = tagName = null;
            var style = state.tokenize(stream, state);
            state.type = type;
            if ((style || type) && style != "comment") {
                curState = state;
                while (true) {
                    var comb = state.cc.pop() || element;
                    if (comb(type || style)) break;
                }
            }
            state.startOfLine = false;
            return setStyle || style;
        },
        indent: function(state, textAfter, fullLine) {
            var context = state.context;
            if ((state.tokenize != inTag && state.tokenize != inText) ||
                context && context.noIndent)
                return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
            if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
            if (context && /^<\//.test(textAfter))
                context = context.prev;
            while (context && !context.startOfLine)
                context = context.prev;
            if (context) return context.indent + indentUnit;
            else return 0;
        },
        compareStates: function(a, b) {
            if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
            for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
                if (!ca || !cb) return ca == cb;
                if (ca.tagName != cb.tagName) return false;
            }
        },
        electricChars: "/"
    };
});
CodeMirror.defineMIME("application/xml", "xml");
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
CodeMirror.defineMode("javascript", function(config, parserConfig) {
    var indentUnit = config.indentUnit;
    var jsonMode = parserConfig.json;
    // Tokenizer
    var keywords = function(){
        function kw(type) {return {type: type, style: "keyword"};}
        var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
        var operator = kw("operator"), atom = {type: "atom", style: "atom"};
        return {
            "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
            "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
            "var": kw("var"), "const": kw("var"), "let": kw("var"),
            "function": kw("function"), "catch": kw("catch"),
            "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
            "in": operator, "typeof": operator, "instanceof": operator,
            "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
        };
    }();
    var isOperatorChar = /[+\-*&%=<>!?|]/;
    function chain(stream, state, f) {
        state.tokenize = f;
        return f(stream, state);
    }
    function nextUntilUnescaped(stream, end) {
        var escaped = false, next;
        while ((next = stream.next()) != null) {
            if (next == end && !escaped)
                return false;
            escaped = !escaped && next == "\\";
        }
        return escaped;
    }
    // Used as scratch variables to communicate multiple values without
    // consing up tons of objects.
    var type, content;
    function ret(tp, style, cont) {
        type = tp; content = cont;
        return style;
    }
    function jsTokenBase(stream, state) {
        var ch = stream.next();
        if (ch == '"' || ch == "'")
            return chain(stream, state, jsTokenString(ch));
        else if (/[\[\]{}\(\),;\:\.]/.test(ch))
            return ret(ch);
        else if (ch == "0" && stream.eat(/x/i)) {
            stream.eatWhile(/[\da-f]/i);
            return ret("number", "number");
        }
        else if (/\d/.test(ch)) {
            stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
            return ret("number", "number");
        }
        else if (ch == "/") {
            if (stream.eat("*")) {
                return chain(stream, state, jsTokenComment);
            }
            else if (stream.eat("/")) {
                stream.skipToEnd();
                return ret("comment", "comment");
            }
            else if (state.reAllowed) {
                nextUntilUnescaped(stream, "/");
                stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
                return ret("regexp", "string");
            }
            else {
                stream.eatWhile(isOperatorChar);
                return ret("operator", null, stream.current());
            }
        }
        else if (ch == "#") {
            stream.skipToEnd();
            return ret("error", "error");
        }
        else if (isOperatorChar.test(ch)) {
            stream.eatWhile(isOperatorChar);
            return ret("operator", null, stream.current());
        }
        else {
            stream.eatWhile(/[\w\$_]/);
            var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
            return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
                ret("variable", "variable", word);
        }
    }
    function jsTokenString(quote) {
        return function(stream, state) {
            if (!nextUntilUnescaped(stream, quote))
                state.tokenize = jsTokenBase;
            return ret("string", "string");
        };
    }
    function jsTokenComment(stream, state) {
        var maybeEnd = false, ch;
        while (ch = stream.next()) {
            if (ch == "/" && maybeEnd) {
                state.tokenize = jsTokenBase;
                break;
            }
            maybeEnd = (ch == "*");
        }
        return ret("comment", "comment");
    }
    // Parser
    var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
    function JSLexical(indented, column, type, align, prev, info) {
        this.indented = indented;
        this.column = column;
        this.type = type;
        this.prev = prev;
        this.info = info;
        if (align != null) this.align = align;
    }
    function inScope(state, varname) {
        for (var v = state.localVars; v; v = v.next)
            if (v.name == varname) return true;
    }
    function parseJS(state, style, type, content, stream) {
        var cc = state.cc;
        // Communicate our context to the combinators.
        // (Less wasteful than consing up a hundred closures on every call.)
        cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
        if (!state.lexical.hasOwnProperty("align"))
            state.lexical.align = true;
        while(true) {
            var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
            if (combinator(type, content)) {
                while(cc.length && cc[cc.length - 1].lex)
                    cc.pop()();
                if (cx.marked) return cx.marked;
                if (type == "variable" && inScope(state, content)) return "variable-2";
                return style;
            }
        }
    }
    // Combinator utils
    var cx = {state: null, column: null, marked: null, cc: null};
    function pass() {
        for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
    }
    function cont() {
        pass.apply(null, arguments);
        return true;
    }
    function register(varname) {
        var state = cx.state;
        if (state.context) {
            cx.marked = "def";
            for (var v = state.localVars; v; v = v.next)
                if (v.name == varname) return;
            state.localVars = {name: varname, next: state.localVars};
        }
    }
    // Combinators
    var defaultVars = {name: "this", next: {name: "arguments"}};
    function pushcontext() {
        if (!cx.state.context) cx.state.localVars = defaultVars;
        cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
    }
    function popcontext() {
        cx.state.localVars = cx.state.context.vars;
        cx.state.context = cx.state.context.prev;
    }
    function pushlex(type, info) {
        var result = function() {
            var state = cx.state;
            state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
        };
        result.lex = true;
        return result;
    }
    function poplex() {
        var state = cx.state;
        if (state.lexical.prev) {
            if (state.lexical.type == ")")
                state.indented = state.lexical.indented;
            state.lexical = state.lexical.prev;
        }
    }
    poplex.lex = true;
    function expect(wanted) {
        return function expecting(type) {
            if (type == wanted) return cont();
            else if (wanted == ";") return pass();
            else return cont(arguments.callee);
        };
    }
    function statement(type) {
        if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
        if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
        if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
        if (type == "{") return cont(pushlex("}"), block, poplex);
        if (type == ";") return cont();
        if (type == "function") return cont(functiondef);
        if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
            poplex, statement, poplex);
        if (type == "variable") return cont(pushlex("stat"), maybelabel);
        if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
            block, poplex, poplex);
        if (type == "case") return cont(expression, expect(":"));
        if (type == "default") return cont(expect(":"));
        if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
            statement, poplex, popcontext);
        return pass(pushlex("stat"), expression, expect(";"), poplex);
    }
    function expression(type) {
        if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
        if (type == "function") return cont(functiondef);
        if (type == "keyword c") return cont(maybeexpression);
        if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
        if (type == "operator") return cont(expression);
        if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
        if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
        return cont();
    }
    function maybeexpression(type) {
        if (type.match(/[;\}\)\],]/)) return pass();
        return pass(expression);
    }
    function maybeoperator(type, value) {
        if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
        if (type == "operator") return cont(expression);
        if (type == ";") return;
        if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
        if (type == ".") return cont(property, maybeoperator);
        if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
    }
    function maybelabel(type) {
        if (type == ":") return cont(poplex, statement);
        return pass(maybeoperator, expect(";"), poplex);
    }
    function property(type) {
        if (type == "variable") {cx.marked = "property"; return cont();}
    }
    function objprop(type) {
        if (type == "variable") cx.marked = "property";
        if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
    }
    function commasep(what, end) {
        function proceed(type) {
            if (type == ",") return cont(what, proceed);
            if (type == end) return cont();
            return cont(expect(end));
        }
        return function commaSeparated(type) {
            if (type == end) return cont();
            else return pass(what, proceed);
        };
    }
    function block(type) {
        if (type == "}") return cont();
        return pass(statement, block);
    }
    function vardef1(type, value) {
        if (type == "variable"){register(value); return cont(vardef2);}
        return cont();
    }
    function vardef2(type, value) {
        if (value == "=") return cont(expression, vardef2);
        if (type == ",") return cont(vardef1);
    }
    function forspec1(type) {
        if (type == "var") return cont(vardef1, forspec2);
        if (type == ";") return pass(forspec2);
        if (type == "variable") return cont(formaybein);
        return pass(forspec2);
    }
    function formaybein(type, value) {
        if (value == "in") return cont(expression);
        return cont(maybeoperator, forspec2);
    }
    function forspec2(type, value) {
        if (type == ";") return cont(forspec3);
        if (value == "in") return cont(expression);
        return cont(expression, expect(";"), forspec3);
    }
    function forspec3(type) {
        if (type != ")") cont(expression);
    }
    function functiondef(type, value) {
        if (type == "variable") {register(value); return cont(functiondef);}
        if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
    }
    function funarg(type, value) {
        if (type == "variable") {register(value); return cont();}
    }
    // Interface
    return {
        startState: function(basecolumn) {
            return {
                tokenize: jsTokenBase,
                reAllowed: true,
                kwAllowed: true,
                cc: [],
                lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
                localVars: null,
                context: null,
                indented: 0
            };
        },
        token: function(stream, state) {
            if (stream.sol()) {
                if (!state.lexical.hasOwnProperty("align"))
                    state.lexical.align = false;
                state.indented = stream.indentation();
            }
            if (stream.eatSpace()) return null;
            var style = state.tokenize(stream, state);
            if (type == "comment") return style;
            state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
            state.kwAllowed = type != '.';
            return parseJS(state, style, type, content, stream);
        },
        indent: function(state, textAfter) {
            if (state.tokenize != jsTokenBase) return 0;
            var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
                type = lexical.type, closing = firstChar == type;
            if (type == "vardef") return lexical.indented + 4;
            else if (type == "form" && firstChar == "{") return lexical.indented;
            else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
            else if (lexical.info == "switch" && !closing)
                return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
            else if (lexical.align) return lexical.column + (closing ? 0 : 1);
            else return lexical.indented + (closing ? 0 : indentUnit);
        },
        electricChars: ":{}"
    };
});
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMode("css", function(config) {
    var indentUnit = config.indentUnit, type;
    function ret(style, tp) {type = tp; return style;}
    function tokenBase(stream, state) {
        var ch = stream.next();
        if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
        else if (ch == "/" && stream.eat("*")) {
            state.tokenize = tokenCComment;
            return tokenCComment(stream, state);
        }
        else if (ch == "<" && stream.eat("!")) {
            state.tokenize = tokenSGMLComment;
            return tokenSGMLComment(stream, state);
        }
        else if (ch == "=") ret(null, "compare");
        else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
        else if (ch == "\"" || ch == "'") {
            state.tokenize = tokenString(ch);
            return state.tokenize(stream, state);
        }
        else if (ch == "#") {
            stream.eatWhile(/[\w\\\-]/);
            return ret("atom", "hash");
        }
        else if (ch == "!") {
            stream.match(/^\s*\w*/);
            return ret("keyword", "important");
        }
        else if (/\d/.test(ch)) {
            stream.eatWhile(/[\w.%]/);
            return ret("number", "unit");
        }
        else if (/[,.+>*\/]/.test(ch)) {
            return ret(null, "select-op");
        }
        else if (/[;{}:\[\]]/.test(ch)) {
            return ret(null, ch);
        }
        else {
            stream.eatWhile(/[\w\\\-]/);
            return ret("variable", "variable");
        }
    }
    function tokenCComment(stream, state) {
        var maybeEnd = false, ch;
        while ((ch = stream.next()) != null) {
            if (maybeEnd && ch == "/") {
                state.tokenize = tokenBase;
                break;
            }
            maybeEnd = (ch == "*");
        }
        return ret("comment", "comment");
    }
    function tokenSGMLComment(stream, state) {
        var dashes = 0, ch;
        while ((ch = stream.next()) != null) {
            if (dashes >= 2 && ch == ">") {
                state.tokenize = tokenBase;
                break;
            }
            dashes = (ch == "-") ? dashes + 1 : 0;
        }
        return ret("comment", "comment");
    }
    function tokenString(quote) {
        return function(stream, state) {
            var escaped = false, ch;
            while ((ch = stream.next()) != null) {
                if (ch == quote && !escaped)
                    break;
                escaped = !escaped && ch == "\\";
            }
            if (!escaped) state.tokenize = tokenBase;
            return ret("string", "string");
        };
    }
    return {
        startState: function(base) {
            return {tokenize: tokenBase,
                baseIndent: base || 0,
                stack: []};
        },
        token: function(stream, state) {
            if (stream.eatSpace()) return null;
            var style = state.tokenize(stream, state);
            var context = state.stack[state.stack.length-1];
            if (type == "hash" && context == "rule") style = "atom";
            else if (style == "variable") {
                if (context == "rule") style = "number";
                else if (!context || context == "@media{") style = "tag";
            }
            if (context == "rule" && /^[\{\};]$/.test(type))
                state.stack.pop();
            if (type == "{") {
                if (context == "@media") state.stack[state.stack.length-1] = "@media{";
                else state.stack.push("{");
            }
            else if (type == "}") state.stack.pop();
            else if (type == "@media") state.stack.push("@media");
            else if (context == "{" && type != "comment") state.stack.push("rule");
            return style;
        },
        indent: function(state, textAfter) {
            var n = state.stack.length;
            if (/^\}/.test(textAfter))
                n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
            return state.baseIndent + n * indentUnit;
        },
        electricChars: "}"
    };
});
CodeMirror.defineMIME("text/css", "css");
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
    var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
    var jsMode = CodeMirror.getMode(config, "javascript");
    var cssMode = CodeMirror.getMode(config, "css");
    function html(stream, state) {
        var style = htmlMode.token(stream, state.htmlState);
        if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
            if (/^script$/i.test(state.htmlState.context.tagName)) {
                state.token = javascript;
                state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
                state.mode = "javascript";
            }
            else if (/^style$/i.test(state.htmlState.context.tagName)) {
                state.token = css;
                state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
                state.mode = "css";
            }
        }
        return style;
    }
    function maybeBackup(stream, pat, style) {
        var cur = stream.current();
        var close = cur.search(pat);
        if (close > -1) stream.backUp(cur.length - close);
        return style;
    }
    function javascript(stream, state) {
        if (stream.match(/^<\/\s*script\s*>/i, false)) {
            state.token = html;
            state.curState = null;
            state.mode = "html";
            return html(stream, state);
        }
        return maybeBackup(stream, /<\/\s*script\s*>/,
            jsMode.token(stream, state.localState));
    }
    function css(stream, state) {
        if (stream.match(/^<\/\s*style\s*>/i, false)) {
            state.token = html;
            state.localState = null;
            state.mode = "html";
            return html(stream, state);
        }
        return maybeBackup(stream, /<\/\s*style\s*>/,
            cssMode.token(stream, state.localState));
    }
    return {
        startState: function() {
            var state = htmlMode.startState();
            return {token: html, localState: null, mode: "html", htmlState: state};
        },
        copyState: function(state) {
            if (state.localState)
                var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
            return {token: state.token, localState: local, mode: state.mode,
                htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
        },
        token: function(stream, state) {
            return state.token(stream, state);
        },
        indent: function(state, textAfter) {
            if (state.token == html || /^\s*<\//.test(textAfter))
                return htmlMode.indent(state.htmlState, textAfter);
            else if (state.token == javascript)
                return jsMode.indent(state.localState, textAfter);
            else
                return cssMode.indent(state.localState, textAfter);
        },
        compareStates: function(a, b) {
            return htmlMode.compareStates(a.htmlState, b.htmlState);
        },
        electricChars: "/{}:"
    }
});
CodeMirror.defineMIME("text/html", "htmlmixed");
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/mootools-adapter.js
New file
@@ -0,0 +1,13 @@
/*
 Highcharts JS v3.0.6 (2013-10-04)
 MooTools adapter
 (c) 2010-2013 Torstein Hønsi
 License: www.highcharts.com/license
*/
(function(){var e=window,h=document,f=e.MooTools.version.substring(0,3),i=f==="1.2"||f==="1.1",j=i||f==="1.3",g=e.$extend||function(){return Object.append.apply(Object,arguments)};e.HighchartsAdapter={init:function(a){var b=Fx.prototype,c=b.start,d=Fx.Morph.prototype,e=d.compute;b.start=function(b,d){var e=this.element;if(b.d)this.paths=a.init(e,e.d,this.toD);c.apply(this,arguments);return this};d.compute=function(b,c,d){var f=this.paths;if(f)this.element.attr("d",a.step(f[0],f[1],d,this.toD));else return e.apply(this,
arguments)}},adapterRun:function(a,b){if(b==="width"||b==="height")return parseInt($(a).getStyle(b),10)},getScript:function(a,b){var c=h.getElementsByTagName("head")[0],d=h.createElement("script");d.type="text/javascript";d.src=a;d.onload=b;c.appendChild(d)},animate:function(a,b,c){var d=a.attr,f=c&&c.complete;if(d&&!a.setStyle)a.getStyle=a.attr,a.setStyle=function(){var a=arguments;this.attr.call(this,a[0],a[1][0])},a.$family=function(){return!0};e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),
g({transition:Fx.Transitions.Quad.easeInOut},c));if(d)c.element=a;if(b.d)c.toD=b.d;f&&c.addEvent("complete",f);c.start(b);a.fx=c},each:function(a,b){return i?$each(a,b):Array.each(a,b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},inArray:function(a,b,c){return b?b.indexOf(a,c):-1},offset:function(a){a=a.getPosition();return{left:a.x,top:a.y}},extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):g(a,new Events))},addEvent:function(a,b,c){typeof b==="string"&&(b===
"unload"&&(b="beforeunload"),e.HighchartsAdapter.extendWithEvents(a),a.addEvent(b,c))},removeEvent:function(a,b,c){typeof a!=="string"&&a.addEvent&&(b?(b==="unload"&&(b="beforeunload"),c?a.removeEvent(b,c):a.removeEvents&&a.removeEvents(b)):a.removeEvents())},fireEvent:function(a,b,c,d){b={type:b,target:a};b=j?new Event(b):new DOMEvent(b);b=g(b,c);if(!b.target&&b.event)b.target=b.event.target;b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},washMouseEvent:function(a){if(a.page)a.pageX=
a.page.x,a.pageY=a.page.y;return a},stop:function(a){a.fx&&a.fx.cancel()}}})();
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/mootools-adapter.src.js
New file
@@ -0,0 +1,313 @@
/**
 * @license Highcharts JS v3.0.6 (2013-10-04)
 * MooTools adapter
 *
 * (c) 2010-2013 Torstein Hønsi
 *
 * License: www.highcharts.com/license
 */
// JSLint options:
/*global Fx, $, $extend, $each, $merge, Events, Event, DOMEvent */
(function () {
var win = window,
    doc = document,
    mooVersion = win.MooTools.version.substring(0, 3), // Get the first three characters of the version number
    legacy = mooVersion === '1.2' || mooVersion === '1.1', // 1.1 && 1.2 considered legacy, 1.3 is not.
    legacyEvent = legacy || mooVersion === '1.3', // In versions 1.1 - 1.3 the event class is named Event, in newer versions it is named DOMEvent.
    $extend = win.$extend || function () {
        return Object.append.apply(Object, arguments);
    };
win.HighchartsAdapter = {
    /**
     * Initialize the adapter. This is run once as Highcharts is first run.
     * @param {Object} pathAnim The helper object to do animations across adapters.
     */
    init: function (pathAnim) {
        var fxProto = Fx.prototype,
            fxStart = fxProto.start,
            morphProto = Fx.Morph.prototype,
            morphCompute = morphProto.compute;
        // override Fx.start to allow animation of SVG element wrappers
        /*jslint unparam: true*//* allow unused parameters in fx functions */
        fxProto.start = function (from, to) {
            var fx = this,
                elem = fx.element;
            // special for animating paths
            if (from.d) {
                //this.fromD = this.element.d.split(' ');
                fx.paths = pathAnim.init(
                    elem,
                    elem.d,
                    fx.toD
                );
            }
            fxStart.apply(fx, arguments);
            return this; // chainable
        };
        // override Fx.step to allow animation of SVG element wrappers
        morphProto.compute = function (from, to, delta) {
            var fx = this,
                paths = fx.paths;
            if (paths) {
                fx.element.attr(
                    'd',
                    pathAnim.step(paths[0], paths[1], delta, fx.toD)
                );
            } else {
                return morphCompute.apply(fx, arguments);
            }
        };
        /*jslint unparam: false*/
    },
    /**
     * Run a general method on the framework, following jQuery syntax
     * @param {Object} el The HTML element
     * @param {String} method Which method to run on the wrapped element
     */
    adapterRun: function (el, method) {
        // This currently works for getting inner width and height. If adding
        // more methods later, we need a conditional implementation for each.
        if (method === 'width' || method === 'height') {
            return parseInt($(el).getStyle(method), 10);
        }
    },
    /**
     * Downloads a script and executes a callback when done.
     * @param {String} scriptLocation
     * @param {Function} callback
     */
    getScript: function (scriptLocation, callback) {
        // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.
        var head = doc.getElementsByTagName('head')[0];
        var script = doc.createElement('script');
        script.type = 'text/javascript';
        script.src = scriptLocation;
        script.onload = callback;
        head.appendChild(script);
    },
    /**
     * Animate a HTML element or SVG element wrapper
     * @param {Object} el
     * @param {Object} params
     * @param {Object} options jQuery-like animation options: duration, easing, callback
     */
    animate: function (el, params, options) {
        var isSVGElement = el.attr,
            effect,
            complete = options && options.complete;
        if (isSVGElement && !el.setStyle) {
            // add setStyle and getStyle methods for internal use in Moo
            el.getStyle = el.attr;
            el.setStyle = function () { // property value is given as array in Moo - break it down
                var args = arguments;
                this.attr.call(this, args[0], args[1][0]);
            };
            // dirty hack to trick Moo into handling el as an element wrapper
            el.$family = function () { return true; };
        }
        // stop running animations
        win.HighchartsAdapter.stop(el);
        // define and run the effect
        effect = new Fx.Morph(
            isSVGElement ? el : $(el),
            $extend({
                transition: Fx.Transitions.Quad.easeInOut
            }, options)
        );
        // Make sure that the element reference is set when animating svg elements
        if (isSVGElement) {
            effect.element = el;
        }
        // special treatment for paths
        if (params.d) {
            effect.toD = params.d;
        }
        // jQuery-like events
        if (complete) {
            effect.addEvent('complete', complete);
        }
        // run
        effect.start(params);
        // record for use in stop method
        el.fx = effect;
    },
    /**
     * MooTool's each function
     *
     */
    each: function (arr, fn) {
        return legacy ?
            $each(arr, fn) :
            Array.each(arr, fn);
    },
    /**
     * Map an array
     * @param {Array} arr
     * @param {Function} fn
     */
    map: function (arr, fn) {
        return arr.map(fn);
    },
    /**
     * Grep or filter an array
     * @param {Array} arr
     * @param {Function} fn
     */
    grep: function (arr, fn) {
        return arr.filter(fn);
    },
    /**
     * Return the index of an item in an array, or -1 if not matched
     */
    inArray: function (item, arr, from) {
        return arr ? arr.indexOf(item, from) : -1;
    },
    /**
     * Get the offset of an element relative to the top left corner of the web page
     */
    offset: function (el) {
        var offsets = el.getPosition(); // #1496
        return {
            left: offsets.x,
            top: offsets.y
        };
    },
    /**
     * Extends an object with Events, if its not done
     */
    extendWithEvents: function (el) {
        // if the addEvent method is not defined, el is a custom Highcharts object
        // like series or point
        if (!el.addEvent) {
            if (el.nodeName) {
                el = $(el); // a dynamically generated node
            } else {
                $extend(el, new Events()); // a custom object
            }
        }
    },
    /**
     * Add an event listener
     * @param {Object} el HTML element or custom object
     * @param {String} type Event type
     * @param {Function} fn Event handler
     */
    addEvent: function (el, type, fn) {
        if (typeof type === 'string') { // chart broke due to el being string, type function
            if (type === 'unload') { // Moo self destructs before custom unload events
                type = 'beforeunload';
            }
            win.HighchartsAdapter.extendWithEvents(el);
            el.addEvent(type, fn);
        }
    },
    removeEvent: function (el, type, fn) {
        if (typeof el === 'string') {
            // el.removeEvents below apperantly calls this method again. Do not quite understand why, so for now just bail out.
            return;
        }
        if (el.addEvent) { // If el doesn't have an addEvent method, there are no events to remove
            if (type) {
                if (type === 'unload') { // Moo self destructs before custom unload events
                    type = 'beforeunload';
                }
                if (fn) {
                    el.removeEvent(type, fn);
                } else if (el.removeEvents) { // #958
                    el.removeEvents(type);
                }
            } else {
                el.removeEvents();
            }
        }
    },
    fireEvent: function (el, event, eventArguments, defaultFunction) {
        var eventArgs = {
            type: event,
            target: el
        };
        // create an event object that keeps all functions
        event = legacyEvent ? new Event(eventArgs) : new DOMEvent(eventArgs);
        event = $extend(event, eventArguments);
        // When running an event on the Chart.prototype, MooTools nests the target in event.event
        if (!event.target && event.event) {
            event.target = event.event.target;
        }
        // override the preventDefault function to be able to use
        // this for custom events
        event.preventDefault = function () {
            defaultFunction = null;
        };
        // if fireEvent is not available on the object, there hasn't been added
        // any events to it above
        if (el.fireEvent) {
            el.fireEvent(event.type, event);
        }
        // fire the default if it is passed and it is not prevented above
        if (defaultFunction) {
            defaultFunction(event);
        }
    },
    /**
     * Set back e.pageX and e.pageY that MooTools has abstracted away. #1165, #1346.
     */
    washMouseEvent: function (e) {
        if (e.page) {
            e.pageX = e.page.x;
            e.pageY = e.page.y;
        }
        return e;
    },
    /**
     * Stop running animations on the object
     */
    stop: function (el) {
        if (el.fx) {
            el.fx.cancel();
        }
    }
};
}());
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/prototype-adapter.js
New file
@@ -0,0 +1,15 @@
/*
 Highcharts JS v3.0.6 (2013-10-04)
 Prototype adapter
 @author Michael Nelson, Torstein Hønsi.
 Feel free to use and modify this script.
 Highcharts license: www.highcharts.com/license.
*/
var HighchartsAdapter=function(){var f=typeof Effect!=="undefined";return{init:function(a){if(f)Effect.HighchartsTransition=Class.create(Effect.Base,{initialize:function(b,c,d,g){var e;this.element=b;this.key=c;e=b.attr?b.attr(c):$(b).getStyle(c);if(c==="d")this.paths=a.init(b,b.d,d),this.toD=d,e=0,d=1;this.start(Object.extend(g||{},{from:e,to:d,attribute:c}))},setup:function(){HighchartsAdapter._extend(this.element);if(!this.element._highchart_animation)this.element._highchart_animation={};this.element._highchart_animation[this.key]=
this},update:function(b){var c=this.paths,d=this.element;c&&(b=a.step(c[0],c[1],b,this.toD));d.attr?d.element&&d.attr(this.options.attribute,b):(c={},c[this.options.attribute]=b,$(d).setStyle(c))},finish:function(){this.element&&this.element._highchart_animation&&delete this.element._highchart_animation[this.key]}})},adapterRun:function(a,b){return parseInt($(a).getStyle(b),10)},getScript:function(a,b){var c=$$("head")[0];c&&c.appendChild((new Element("script",{type:"text/javascript",src:a})).observe("load",
b))},addNS:function(a){var b=/^(?:click|mouse(?:down|up|over|move|out))$/;return/^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/.test(a)||b.test(a)?a:"h:"+a},addEvent:function(a,b,c){a.addEventListener||a.attachEvent?Event.observe($(a),HighchartsAdapter.addNS(b),c):(HighchartsAdapter._extend(a),a._highcharts_observe(b,c))},animate:function(a,b,c){var d,c=c||{};c.delay=0;c.duration=(c.duration||500)/1E3;c.afterFinish=c.complete;if(f)for(d in b)new Effect.HighchartsTransition($(a),
d,b[d],c);else{if(a.attr)for(d in b)a.attr(d,b[d]);c.complete&&c.complete()}a.attr||$(a).setStyle(b)},stop:function(a){var b;if(a._highcharts_extended&&a._highchart_animation)for(b in a._highchart_animation)a._highchart_animation[b].cancel()},each:function(a,b){$A(a).each(b)},inArray:function(a,b,c){return b?b.indexOf(a,c):-1},offset:function(a){return $(a).cumulativeOffset()},fireEvent:function(a,b,c,d){a.fire?a.fire(HighchartsAdapter.addNS(b),c):a._highcharts_extended&&(c=c||{},a._highcharts_fire(b,
c));c&&c.defaultPrevented&&(d=null);d&&d(c)},removeEvent:function(a,b,c){$(a).stopObserving&&(b&&(b=HighchartsAdapter.addNS(b)),$(a).stopObserving(b,c));window===a?Event.stopObserving(a,b,c):(HighchartsAdapter._extend(a),a._highcharts_stop_observing(b,c))},washMouseEvent:function(a){return a},grep:function(a,b){return a.findAll(b)},map:function(a,b){return a.map(b)},_extend:function(a){a._highcharts_extended||Object.extend(a,{_highchart_events:{},_highchart_animation:null,_highcharts_extended:!0,
_highcharts_observe:function(b,a){this._highchart_events[b]=[this._highchart_events[b],a].compact().flatten()},_highcharts_stop_observing:function(b,a){b?a?this._highchart_events[b]=[this._highchart_events[b]].compact().flatten().without(a):delete this._highchart_events[b]:this._highchart_events={}},_highcharts_fire:function(a,c){var d=this;(this._highchart_events[a]||[]).each(function(a){if(!c.stopped)c.preventDefault=function(){c.defaultPrevented=!0},c.target=d,a.bind(this)(c)===!1&&c.preventDefault()}.bind(this))}})}}}();
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/prototype-adapter.src.js
New file
@@ -0,0 +1,316 @@
/**
 * @license Highcharts JS v3.0.6 (2013-10-04)
 * Prototype adapter
 *
 * @author Michael Nelson, Torstein Hønsi.
 *
 * Feel free to use and modify this script.
 * Highcharts license: www.highcharts.com/license.
 */
// JSLint options:
/*global Effect, Class, Event, Element, $, $$, $A */
// Adapter interface between prototype and the Highcharts charting library
var HighchartsAdapter = (function () {
var hasEffect = typeof Effect !== 'undefined';
return {
    /**
     * Initialize the adapter. This is run once as Highcharts is first run.
     * @param {Object} pathAnim The helper object to do animations across adapters.
     */
    init: function (pathAnim) {
        if (hasEffect) {
            /**
             * Animation for Highcharts SVG element wrappers only
             * @param {Object} element
             * @param {Object} attribute
             * @param {Object} to
             * @param {Object} options
             */
            Effect.HighchartsTransition = Class.create(Effect.Base, {
                initialize: function (element, attr, to, options) {
                    var from,
                        opts;
                    this.element = element;
                    this.key = attr;
                    from = element.attr ? element.attr(attr) : $(element).getStyle(attr);
                    // special treatment for paths
                    if (attr === 'd') {
                        this.paths = pathAnim.init(
                            element,
                            element.d,
                            to
                        );
                        this.toD = to;
                        // fake values in order to read relative position as a float in update
                        from = 0;
                        to = 1;
                    }
                    opts = Object.extend((options || {}), {
                        from: from,
                        to: to,
                        attribute: attr
                    });
                    this.start(opts);
                },
                setup: function () {
                    HighchartsAdapter._extend(this.element);
                    // If this is the first animation on this object, create the _highcharts_animation helper that
                    // contain pointers to the animation objects.
                    if (!this.element._highchart_animation) {
                        this.element._highchart_animation = {};
                    }
                    // Store a reference to this animation instance.
                    this.element._highchart_animation[this.key] = this;
                },
                update: function (position) {
                    var paths = this.paths,
                        element = this.element,
                        obj;
                    if (paths) {
                        position = pathAnim.step(paths[0], paths[1], position, this.toD);
                    }
                    if (element.attr) { // SVGElement
                        if (element.element) { // If not, it has been destroyed (#1405)
                            element.attr(this.options.attribute, position);
                        }
                    } else { // HTML, #409
                        obj = {};
                        obj[this.options.attribute] = position;
                        $(element).setStyle(obj);
                    }
                },
                finish: function () {
                    // Delete the property that holds this animation now that it is finished.
                    // Both canceled animations and complete ones gets a 'finish' call.
                    if (this.element && this.element._highchart_animation) { // #1405
                        delete this.element._highchart_animation[this.key];
                    }
                }
            });
        }
    },
    /**
     * Run a general method on the framework, following jQuery syntax
     * @param {Object} el The HTML element
     * @param {String} method Which method to run on the wrapped element
     */
    adapterRun: function (el, method) {
        // This currently works for getting inner width and height. If adding
        // more methods later, we need a conditional implementation for each.
        return parseInt($(el).getStyle(method), 10);
    },
    /**
     * Downloads a script and executes a callback when done.
     * @param {String} scriptLocation
     * @param {Function} callback
     */
    getScript: function (scriptLocation, callback) {
        var head = $$('head')[0]; // Returns an array, so pick the first element.
        if (head) {
            // Append a new 'script' element, set its type and src attributes, add a 'load' handler that calls the callback
            head.appendChild(new Element('script', { type: 'text/javascript', src: scriptLocation}).observe('load', callback));
        }
    },
    /**
     * Custom events in prototype needs to be namespaced. This method adds a namespace 'h:' in front of
     * events that are not recognized as native.
     */
    addNS: function (eventName) {
        var HTMLEvents = /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
            MouseEvents = /^(?:click|mouse(?:down|up|over|move|out))$/;
        return (HTMLEvents.test(eventName) || MouseEvents.test(eventName)) ?
            eventName :
            'h:' + eventName;
    },
    // el needs an event to be attached. el is not necessarily a dom element
    addEvent: function (el, event, fn) {
        if (el.addEventListener || el.attachEvent) {
            Event.observe($(el), HighchartsAdapter.addNS(event), fn);
        } else {
            HighchartsAdapter._extend(el);
            el._highcharts_observe(event, fn);
        }
    },
    // motion makes things pretty. use it if effects is loaded, if not... still get to the end result.
    animate: function (el, params, options) {
        var key,
            fx;
        // default options
        options = options || {};
        options.delay = 0;
        options.duration = (options.duration || 500) / 1000;
        options.afterFinish = options.complete;
        // animate wrappers and DOM elements
        if (hasEffect) {
            for (key in params) {
                // The fx variable is seemingly thrown away here, but the Effect.setup will add itself to the _highcharts_animation object
                // on the element itself so its not really lost.
                fx = new Effect.HighchartsTransition($(el), key, params[key], options);
            }
        } else {
            if (el.attr) { // #409 without effects
                for (key in params) {
                    el.attr(key, params[key]);
                }
            }
            if (options.complete) {
                options.complete();
            }
        }
        if (!el.attr) { // HTML element, #409
            $(el).setStyle(params);
        }
    },
    // this only occurs in higcharts 2.0+
    stop: function (el) {
        var key;
        if (el._highcharts_extended && el._highchart_animation) {
            for (key in el._highchart_animation) {
                // Cancel the animation
                // The 'finish' function in the Effect object will remove the reference
                el._highchart_animation[key].cancel();
            }
        }
    },
    // um.. each
    each: function (arr, fn) {
        $A(arr).each(fn);
    },
    inArray: function (item, arr, from) {
        return arr ? arr.indexOf(item, from) : -1;
    },
    /**
     * Get the cumulative offset relative to the top left of the page. This method, unlike its
     * jQuery and MooTools counterpart, still suffers from issue #208 regarding the position
     * of a chart within a fixed container.
     */
    offset: function (el) {
        return $(el).cumulativeOffset();
    },
    // fire an event based on an event name (event) and an object (el).
    // again, el may not be a dom element
    fireEvent: function (el, event, eventArguments, defaultFunction) {
        if (el.fire) {
            el.fire(HighchartsAdapter.addNS(event), eventArguments);
        } else if (el._highcharts_extended) {
            eventArguments = eventArguments || {};
            el._highcharts_fire(event, eventArguments);
        }
        if (eventArguments && eventArguments.defaultPrevented) {
            defaultFunction = null;
        }
        if (defaultFunction) {
            defaultFunction(eventArguments);
        }
    },
    removeEvent: function (el, event, handler) {
        if ($(el).stopObserving) {
            if (event) {
                event = HighchartsAdapter.addNS(event);
            }
            $(el).stopObserving(event, handler);
        } if (window === el) {
            Event.stopObserving(el, event, handler);
        } else {
            HighchartsAdapter._extend(el);
            el._highcharts_stop_observing(event, handler);
        }
    },
    washMouseEvent: function (e) {
        return e;
    },
    // um, grep
    grep: function (arr, fn) {
        return arr.findAll(fn);
    },
    // um, map
    map: function (arr, fn) {
        return arr.map(fn);
    },
    // extend an object to handle highchart events (highchart objects, not svg elements).
    // this is a very simple way of handling events but whatever, it works (i think)
    _extend: function (object) {
        if (!object._highcharts_extended) {
            Object.extend(object, {
                _highchart_events: {},
                _highchart_animation: null,
                _highcharts_extended: true,
                _highcharts_observe: function (name, fn) {
                    this._highchart_events[name] = [this._highchart_events[name], fn].compact().flatten();
                },
                _highcharts_stop_observing: function (name, fn) {
                    if (name) {
                        if (fn) {
                            this._highchart_events[name] = [this._highchart_events[name]].compact().flatten().without(fn);
                        } else {
                            delete this._highchart_events[name];
                        }
                    } else {
                        this._highchart_events = {};
                    }
                },
                _highcharts_fire: function (name, args) {
                    var target = this;
                    (this._highchart_events[name] || []).each(function (fn) {
                        // args is never null here
                        if (args.stopped) {
                            return; // "throw $break" wasn't working. i think because of the scope of 'this'.
                        }
                        // Attach a simple preventDefault function to skip default handler if called
                        args.preventDefault = function () {
                            args.defaultPrevented = true;
                        };
                        args.target = target;
                        // If the event handler return false, prevent the default handler from executing
                        if (fn.bind(this)(args) === false) {
                            args.preventDefault();
                        }
                    }
.bind(this));
                }
            });
        }
    }
};
}());
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/standalone-framework.js
New file
@@ -0,0 +1,17 @@
/*
 Highcharts JS v3.0.6 (2013-10-04)
 Standalone Highcharts Framework
 License: MIT License
*/
var HighchartsAdapter=function(){function o(c){function a(a,b,d){a.removeEventListener(b,d,!1)}function d(a,b,d){d=a.HCProxiedMethods[d.toString()];a.detachEvent("on"+b,d)}function b(b,c){var f=b.HCEvents,i,g,k,j;if(b.removeEventListener)i=a;else if(b.attachEvent)i=d;else return;c?(g={},g[c]=!0):g=f;for(j in g)if(f[j])for(k=f[j].length;k--;)i(b,j,f[j][k])}c.HCExtended||Highcharts.extend(c,{HCExtended:!0,HCEvents:{},bind:function(b,a){var d=this,c=this.HCEvents,g;if(d.addEventListener)d.addEventListener(b,
a,!1);else if(d.attachEvent){g=function(b){a.call(d,b)};if(!d.HCProxiedMethods)d.HCProxiedMethods={};d.HCProxiedMethods[a.toString()]=g;d.attachEvent("on"+b,g)}c[b]===r&&(c[b]=[]);c[b].push(a)},unbind:function(c,h){var f,i;c?(f=this.HCEvents[c]||[],h?(i=HighchartsAdapter.inArray(h,f),i>-1&&(f.splice(i,1),this.HCEvents[c]=f),this.removeEventListener?a(this,c,h):this.attachEvent&&d(this,c,h)):(b(this,c),this.HCEvents[c]=[])):(b(this),this.HCEvents={})},trigger:function(b,a){var d=this.HCEvents[b]||
[],c=d.length,g,k,j;k=function(){a.defaultPrevented=!0};for(g=0;g<c;g++){j=d[g];if(a.stopped)break;a.preventDefault=k;a.target=this;a.type=b;j.call(this,a)===!1&&a.preventDefault()}}});return c}var r,l=document,p=[],m=[],q,n;Math.easeInOutSine=function(c,a,d,b){return-d/2*(Math.cos(Math.PI*c/b)-1)+a};return{init:function(c){if(!l.defaultView)this._getStyle=function(a,d){var b;return a.style[d]?a.style[d]:(d==="opacity"&&(d="filter"),b=a.currentStyle[d.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()})],
d==="filter"&&(b=b.replace(/alpha\(opacity=([0-9]+)\)/,function(b,a){return a/100})),b===""?1:b)},this.adapterRun=function(a,d){var b={width:"clientWidth",height:"clientHeight"}[d];if(b)return a.style.zoom=1,a[b]-2*parseInt(HighchartsAdapter._getStyle(a,"padding"),10)};if(!Array.prototype.forEach)this.each=function(a,d){for(var b=0,c=a.length;b<c;b++)if(d.call(a[b],a[b],b,a)===!1)return b};if(!Array.prototype.indexOf)this.inArray=function(a,d){var b,c=0;if(d)for(b=d.length;c<b;c++)if(d[c]===a)return c;
return-1};if(!Array.prototype.filter)this.grep=function(a,d){for(var b=[],c=0,h=a.length;c<h;c++)d(a[c],c)&&b.push(a[c]);return b};n=function(a,c,b){this.options=c;this.elem=a;this.prop=b};n.prototype={update:function(){var a;a=this.paths;var d=this.elem,b=d.element;a&&b?d.attr("d",c.step(a[0],a[1],this.now,this.toD)):d.attr?b&&d.attr(this.prop,this.now):(a={},a[d]=this.now+this.unit,Highcharts.css(d,a));this.options.step&&this.options.step.call(this.elem,this.now,this)},custom:function(a,c,b){var e=
this,h=function(a){return e.step(a)},f;this.startTime=+new Date;this.start=a;this.end=c;this.unit=b;this.now=this.start;this.pos=this.state=0;h.elem=this.elem;h()&&m.push(h)===1&&(q=setInterval(function(){for(f=0;f<m.length;f++)m[f]()||m.splice(f--,1);m.length||clearInterval(q)},13))},step:function(a){var c=+new Date,b;b=this.options;var e;if(this.elem.stopAnimation)b=!1;else if(a||c>=b.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();a=this.options.curAnim[this.prop]=
!0;for(e in b.curAnim)b.curAnim[e]!==!0&&(a=!1);a&&b.complete&&b.complete.call(this.elem);b=!1}else e=c-this.startTime,this.state=e/b.duration,this.pos=b.easing(e,0,1,b.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update(),b=!0;return b}};this.animate=function(a,d,b){var e,h="",f,i,g;a.stopAnimation=!1;if(typeof b!=="object"||b===null)e=arguments,b={duration:e[2],easing:e[3],complete:e[4]};if(typeof b.duration!=="number")b.duration=400;b.easing=Math[b.easing]||Math.easeInOutSine;
b.curAnim=Highcharts.extend({},d);for(g in d)i=new n(a,b,g),f=null,g==="d"?(i.paths=c.init(a,a.d,d.d),i.toD=d.d,e=0,f=1):a.attr?e=a.attr(g):(e=parseFloat(HighchartsAdapter._getStyle(a,g))||0,g!=="opacity"&&(h="px")),f||(f=parseFloat(d[g])),i.custom(e,f,h)}},_getStyle:function(c,a){return window.getComputedStyle(c).getPropertyValue(a)},getScript:function(c,a){var d=l.getElementsByTagName("head")[0],b=l.createElement("script");b.type="text/javascript";b.src=c;b.onload=a;d.appendChild(b)},inArray:function(c,
a){return a.indexOf?a.indexOf(c):p.indexOf.call(a,c)},adapterRun:function(c,a){return parseInt(HighchartsAdapter._getStyle(c,a),10)},grep:function(c,a){return p.filter.call(c,a)},map:function(c,a){for(var d=[],b=0,e=c.length;b<e;b++)d[b]=a.call(c[b],c[b],b,c);return d},offset:function(c){for(var a=0,d=0;c;)a+=c.offsetLeft,d+=c.offsetTop,c=c.offsetParent;return{left:a,top:d}},addEvent:function(c,a,d){o(c).bind(a,d)},removeEvent:function(c,a,d){o(c).unbind(a,d)},fireEvent:function(c,a,d,b){var e;l.createEvent&&
(c.dispatchEvent||c.fireEvent)?(e=l.createEvent("Events"),e.initEvent(a,!0,!0),e.target=c,Highcharts.extend(e,d),c.dispatchEvent?c.dispatchEvent(e):c.fireEvent(a,e)):c.HCExtended===!0&&(d=d||{},c.trigger(a,d));d&&d.defaultPrevented&&(b=null);b&&b(d)},washMouseEvent:function(c){return c},stop:function(c){c.stopAnimation=!0},each:function(c,a){return Array.prototype.forEach.call(c,a)}}}();
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/adapters/standalone-framework.src.js
New file
@@ -0,0 +1,583 @@
/**
 * @license Highcharts JS v3.0.6 (2013-10-04)
 *
 * Standalone Highcharts Framework
 *
 * License: MIT License
 */
/*global Highcharts */
var HighchartsAdapter = (function () {
var UNDEFINED,
    doc = document,
    emptyArray = [],
    timers = [],
    timerId,
    Fx;
Math.easeInOutSine = function (t, b, c, d) {
    return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
};
/**
 * Extend given object with custom events
 */
function augment(obj) {
    function removeOneEvent(el, type, fn) {
        el.removeEventListener(type, fn, false);
    }
    function IERemoveOneEvent(el, type, fn) {
        fn = el.HCProxiedMethods[fn.toString()];
        el.detachEvent('on' + type, fn);
    }
    function removeAllEvents(el, type) {
        var events = el.HCEvents,
            remove,
            types,
            len,
            n;
        if (el.removeEventListener) {
            remove = removeOneEvent;
        } else if (el.attachEvent) {
            remove = IERemoveOneEvent;
        } else {
            return; // break on non-DOM events
        }
        if (type) {
            types = {};
            types[type] = true;
        } else {
            types = events;
        }
        for (n in types) {
            if (events[n]) {
                len = events[n].length;
                while (len--) {
                    remove(el, n, events[n][len]);
                }
            }
        }
    }
    if (!obj.HCExtended) {
        Highcharts.extend(obj, {
            HCExtended: true,
            HCEvents: {},
            bind: function (name, fn) {
                var el = this,
                    events = this.HCEvents,
                    wrappedFn;
                // handle DOM events in modern browsers
                if (el.addEventListener) {
                    el.addEventListener(name, fn, false);
                // handle old IE implementation
                } else if (el.attachEvent) {
                    wrappedFn = function (e) {
                        fn.call(el, e);
                    };
                    if (!el.HCProxiedMethods) {
                        el.HCProxiedMethods = {};
                    }
                    // link wrapped fn with original fn, so we can get this in removeEvent
                    el.HCProxiedMethods[fn.toString()] = wrappedFn;
                    el.attachEvent('on' + name, wrappedFn);
                }
                if (events[name] === UNDEFINED) {
                    events[name] = [];
                }
                events[name].push(fn);
            },
            unbind: function (name, fn) {
                var events,
                    index;
                if (name) {
                    events = this.HCEvents[name] || [];
                    if (fn) {
                        index = HighchartsAdapter.inArray(fn, events);
                        if (index > -1) {
                            events.splice(index, 1);
                            this.HCEvents[name] = events;
                        }
                        if (this.removeEventListener) {
                            removeOneEvent(this, name, fn);
                        } else if (this.attachEvent) {
                            IERemoveOneEvent(this, name, fn);
                        }
                    } else {
                        removeAllEvents(this, name);
                        this.HCEvents[name] = [];
                    }
                } else {
                    removeAllEvents(this);
                    this.HCEvents = {};
                }
            },
            trigger: function (name, args) {
                var events = this.HCEvents[name] || [],
                    target = this,
                    len = events.length,
                    i,
                    preventDefault,
                    fn;
                // Attach a simple preventDefault function to skip default handler if called
                preventDefault = function () {
                    args.defaultPrevented = true;
                };
                for (i = 0; i < len; i++) {
                    fn = events[i];
                    // args is never null here
                    if (args.stopped) {
                        return;
                    }
                    args.preventDefault = preventDefault;
                    args.target = target;
                    args.type = name; // #2297
                    // If the event handler return false, prevent the default handler from executing
                    if (fn.call(this, args) === false) {
                        args.preventDefault();
                    }
                }
            }
        });
    }
    return obj;
}
return {
    /**
     * Initialize the adapter. This is run once as Highcharts is first run.
     */
    init: function (pathAnim) {
        /**
         * Compatibility section to add support for legacy IE. This can be removed if old IE
         * support is not needed.
         */
        if (!doc.defaultView) {
            this._getStyle = function (el, prop) {
                var val;
                if (el.style[prop]) {
                    return el.style[prop];
                } else {
                    if (prop === 'opacity') {
                        prop = 'filter';
                    }
                    /*jslint unparam: true*/
                    val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b) { return b.toUpperCase(); })];
                    if (prop === 'filter') {
                        val = val.replace(
                            /alpha\(opacity=([0-9]+)\)/,
                            function (a, b) {
                                return b / 100;
                            }
                        );
                    }
                    /*jslint unparam: false*/
                    return val === '' ? 1 : val;
                }
            };
            this.adapterRun = function (elem, method) {
                var alias = { width: 'clientWidth', height: 'clientHeight' }[method];
                if (alias) {
                    elem.style.zoom = 1;
                    return elem[alias] - 2 * parseInt(HighchartsAdapter._getStyle(elem, 'padding'), 10);
                }
            };
        }
        if (!Array.prototype.forEach) {
            this.each = function (arr, fn) { // legacy
                var i = 0,
                    len = arr.length;
                for (; i < len; i++) {
                    if (fn.call(arr[i], arr[i], i, arr) === false) {
                        return i;
                    }
                }
            };
        }
        if (!Array.prototype.indexOf) {
            this.inArray = function (item, arr) {
                var len,
                    i = 0;
                if (arr) {
                    len = arr.length;
                    for (; i < len; i++) {
                        if (arr[i] === item) {
                            return i;
                        }
                    }
                }
                return -1;
            };
        }
        if (!Array.prototype.filter) {
            this.grep = function (elements, callback) {
                var ret = [],
                    i = 0,
                    length = elements.length;
                for (; i < length; i++) {
                    if (!!callback(elements[i], i)) {
                        ret.push(elements[i]);
                    }
                }
                return ret;
            };
        }
        //--- End compatibility section ---
        /**
         * Start of animation specific code
         */
        Fx = function (elem, options, prop) {
            this.options = options;
            this.elem = elem;
            this.prop = prop;
        };
        Fx.prototype = {
            update: function () {
                var styles,
                    paths = this.paths,
                    elem = this.elem,
                    elemelem = elem.element; // if destroyed, it is null
                // Animating a path definition on SVGElement
                if (paths && elemelem) {
                    elem.attr('d', pathAnim.step(paths[0], paths[1], this.now, this.toD));
                // Other animations on SVGElement
                } else if (elem.attr) {
                    if (elemelem) {
                        elem.attr(this.prop, this.now);
                    }
                // HTML styles
                } else {
                    styles = {};
                    styles[elem] = this.now + this.unit;
                    Highcharts.css(elem, styles);
                }
                if (this.options.step) {
                    this.options.step.call(this.elem, this.now, this);
                }
            },
            custom: function (from, to, unit) {
                var self = this,
                    t = function (gotoEnd) {
                        return self.step(gotoEnd);
                    },
                    i;
                this.startTime = +new Date();
                this.start = from;
                this.end = to;
                this.unit = unit;
                this.now = this.start;
                this.pos = this.state = 0;
                t.elem = this.elem;
                if (t() && timers.push(t) === 1) {
                    timerId = setInterval(function () {
                        for (i = 0; i < timers.length; i++) {
                            if (!timers[i]()) {
                                timers.splice(i--, 1);
                            }
                        }
                        if (!timers.length) {
                            clearInterval(timerId);
                        }
                    }, 13);
                }
            },
            step: function (gotoEnd) {
                var t = +new Date(),
                    ret,
                    done,
                    options = this.options,
                    i;
                if (this.elem.stopAnimation) {
                    ret = false;
                } else if (gotoEnd || t >= options.duration + this.startTime) {
                    this.now = this.end;
                    this.pos = this.state = 1;
                    this.update();
                    this.options.curAnim[this.prop] = true;
                    done = true;
                    for (i in options.curAnim) {
                        if (options.curAnim[i] !== true) {
                            done = false;
                        }
                    }
                    if (done) {
                        if (options.complete) {
                            options.complete.call(this.elem);
                        }
                    }
                    ret = false;
                } else {
                    var n = t - this.startTime;
                    this.state = n / options.duration;
                    this.pos = options.easing(n, 0, 1, options.duration);
                    this.now = this.start + ((this.end - this.start) * this.pos);
                    this.update();
                    ret = true;
                }
                return ret;
            }
        };
        /**
         * The adapter animate method
         */
        this.animate = function (el, prop, opt) {
            var start,
                unit = '',
                end,
                fx,
                args,
                name;
            el.stopAnimation = false; // ready for new
            if (typeof opt !== 'object' || opt === null) {
                args = arguments;
                opt = {
                    duration: args[2],
                    easing: args[3],
                    complete: args[4]
                };
            }
            if (typeof opt.duration !== 'number') {
                opt.duration = 400;
            }
            opt.easing = Math[opt.easing] || Math.easeInOutSine;
            opt.curAnim = Highcharts.extend({}, prop);
            for (name in prop) {
                fx = new Fx(el, opt, name);
                end = null;
                if (name === 'd') {
                    fx.paths = pathAnim.init(
                        el,
                        el.d,
                        prop.d
                    );
                    fx.toD = prop.d;
                    start = 0;
                    end = 1;
                } else if (el.attr) {
                    start = el.attr(name);
                } else {
                    start = parseFloat(HighchartsAdapter._getStyle(el, name)) || 0;
                    if (name !== 'opacity') {
                        unit = 'px';
                    }
                }
                if (!end) {
                    end = parseFloat(prop[name]);
                }
                fx.custom(start, end, unit);
            }
        };
    },
    /**
     * Internal method to return CSS value for given element and property
     */
    _getStyle: function (el, prop) {
        return window.getComputedStyle(el).getPropertyValue(prop);
    },
    /**
     * Downloads a script and executes a callback when done.
     * @param {String} scriptLocation
     * @param {Function} callback
     */
    getScript: function (scriptLocation, callback) {
        // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.
        var head = doc.getElementsByTagName('head')[0],
            script = doc.createElement('script');
        script.type = 'text/javascript';
        script.src = scriptLocation;
        script.onload = callback;
        head.appendChild(script);
    },
    /**
     * Return the index of an item in an array, or -1 if not found
     */
    inArray: function (item, arr) {
        return arr.indexOf ? arr.indexOf(item) : emptyArray.indexOf.call(arr, item);
    },
    /**
     * A direct link to adapter methods
     */
    adapterRun: function (elem, method) {
        return parseInt(HighchartsAdapter._getStyle(elem, method), 10);
    },
    /**
     * Filter an array
     */
    grep: function (elements, callback) {
        return emptyArray.filter.call(elements, callback);
    },
    /**
     * Map an array
     */
    map: function (arr, fn) {
        var results = [], i = 0, len = arr.length;
        for (; i < len; i++) {
            results[i] = fn.call(arr[i], arr[i], i, arr);
        }
        return results;
    },
    offset: function (el) {
        var left = 0,
            top = 0;
        while (el) {
            left += el.offsetLeft;
            top += el.offsetTop;
            el = el.offsetParent;
        }
        return {
            left: left,
            top: top
        };
    },
    /**
     * Add an event listener
     */
    addEvent: function (el, type, fn) {
        augment(el).bind(type, fn);
    },
    /**
     * Remove event added with addEvent
     */
    removeEvent: function (el, type, fn) {
        augment(el).unbind(type, fn);
    },
    /**
     * Fire an event on a custom object
     */
    fireEvent: function (el, type, eventArguments, defaultFunction) {
        var e;
        if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
            e = doc.createEvent('Events');
            e.initEvent(type, true, true);
            e.target = el;
            Highcharts.extend(e, eventArguments);
            if (el.dispatchEvent) {
                el.dispatchEvent(e);
            } else {
                el.fireEvent(type, e);
            }
        } else if (el.HCExtended === true) {
            eventArguments = eventArguments || {};
            el.trigger(type, eventArguments);
        }
        if (eventArguments && eventArguments.defaultPrevented) {
            defaultFunction = null;
        }
        if (defaultFunction) {
            defaultFunction(eventArguments);
        }
    },
    washMouseEvent: function (e) {
        return e;
    },
    /**
     * Stop running animation
     */
    stop: function (el) {
        el.stopAnimation = true;
    },
    /**
     * Utility for iterating over an array. Parameters are reversed compared to jQuery.
     * @param {Array} arr
     * @param {Function} fn
     */
    each: function (arr, fn) { // modern browsers
        return Array.prototype.forEach.call(arr, fn);
    }
};
}());
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts-more.js
New file
@@ -0,0 +1,50 @@
/*
 Highcharts JS v3.0.6 (2013-10-04)
 (c) 2009-2013 Torstein Hønsi
 License: www.highcharts.com/license
*/
(function(j,C){function J(a,b,c){this.init.call(this,a,b,c)}function K(a,b,c){a.call(this,b,c);if(this.chart.polar)this.closeSegment=function(a){var c=this.xAxis.center;a.push("L",c[0],c[1])},this.closedStacks=!0}function L(a,b){var c=this.chart,d=this.options.animation,g=this.group,f=this.markerGroup,e=this.xAxis.center,i=c.plotLeft,n=c.plotTop;if(c.polar){if(c.renderer.isSVG)if(d===!0&&(d={}),b){if(c={translateX:e[0]+i,translateY:e[1]+n,scaleX:0.001,scaleY:0.001},g.attr(c),f)f.attrSetters=g.attrSetters,
f.attr(c)}else c={translateX:i,translateY:n,scaleX:1,scaleY:1},g.animate(c,d),f&&f.animate(c,d),this.animate=null}else a.call(this,b)}var P=j.arrayMin,Q=j.arrayMax,s=j.each,F=j.extend,p=j.merge,R=j.map,r=j.pick,v=j.pInt,m=j.getOptions().plotOptions,h=j.seriesTypes,x=j.extendClass,M=j.splat,o=j.wrap,N=j.Axis,u=j.Tick,z=j.Series,q=h.column.prototype,t=Math,D=t.round,A=t.floor,S=t.max,w=function(){};F(J.prototype,{init:function(a,b,c){var d=this,g=d.defaultOptions;d.chart=b;if(b.angular)g.background=
{};d.options=a=p(g,a);(a=a.background)&&s([].concat(M(a)).reverse(),function(a){var b=a.backgroundColor,a=p(d.defaultBackgroundOptions,a);if(b)a.backgroundColor=b;a.color=a.backgroundColor;c.options.plotBands.unshift(a)})},defaultOptions:{center:["50%","50%"],size:"85%",startAngle:0},defaultBackgroundOptions:{shape:"circle",borderWidth:1,borderColor:"silver",backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,"#FFF"],[1,"#DDD"]]},from:Number.MIN_VALUE,innerRadius:0,to:Number.MAX_VALUE,
outerRadius:"105%"}});var G=N.prototype,u=u.prototype,T={getOffset:w,redraw:function(){this.isDirty=!1},render:function(){this.isDirty=!1},setScale:w,setCategories:w,setTitle:w},O={isRadial:!0,defaultRadialGaugeOptions:{labels:{align:"center",x:0,y:null},minorGridLineWidth:0,minorTickInterval:"auto",minorTickLength:10,minorTickPosition:"inside",minorTickWidth:1,plotBands:[],tickLength:10,tickPosition:"inside",tickWidth:2,title:{rotation:0},zIndex:2},defaultRadialXOptions:{gridLineWidth:1,labels:{align:null,
distance:15,x:0,y:null},maxPadding:0,minPadding:0,plotBands:[],showLastLabel:!1,tickLength:0},defaultRadialYOptions:{gridLineInterpolation:"circle",labels:{align:"right",x:-3,y:-2},plotBands:[],showLastLabel:!1,title:{x:4,text:null,rotation:90}},setOptions:function(a){this.options=p(this.defaultOptions,this.defaultRadialOptions,a)},getOffset:function(){G.getOffset.call(this);this.chart.axisOffset[this.side]=0},getLinePath:function(a,b){var c=this.center,b=r(b,c[2]/2-this.offset);return this.chart.renderer.symbols.arc(this.left+
c[0],this.top+c[1],b,b,{start:this.startAngleRad,end:this.endAngleRad,open:!0,innerR:0})},setAxisTranslation:function(){G.setAxisTranslation.call(this);if(this.center&&(this.transA=this.isCircular?(this.endAngleRad-this.startAngleRad)/(this.max-this.min||1):this.center[2]/2/(this.max-this.min||1),this.isXAxis))this.minPixelPadding=this.transA*this.minPointOffset+(this.reversed?(this.endAngleRad-this.startAngleRad)/4:0)},beforeSetTickPositions:function(){this.autoConnect&&(this.max+=this.categories&&
1||this.pointRange||this.closestPointRange||0)},setAxisSize:function(){G.setAxisSize.call(this);if(this.isRadial)this.center=this.pane.center=h.pie.prototype.getCenter.call(this.pane),this.len=this.width=this.height=this.isCircular?this.center[2]*(this.endAngleRad-this.startAngleRad)/2:this.center[2]/2},getPosition:function(a,b){if(!this.isCircular)b=this.translate(a),a=this.min;return this.postTranslate(this.translate(a),r(b,this.center[2]/2)-this.offset)},postTranslate:function(a,b){var c=this.chart,
d=this.center,a=this.startAngleRad+a;return{x:c.plotLeft+d[0]+Math.cos(a)*b,y:c.plotTop+d[1]+Math.sin(a)*b}},getPlotBandPath:function(a,b,c){var d=this.center,g=this.startAngleRad,f=d[2]/2,e=[r(c.outerRadius,"100%"),c.innerRadius,r(c.thickness,10)],i=/%$/,n,l=this.isCircular;this.options.gridLineInterpolation==="polygon"?d=this.getPlotLinePath(a).concat(this.getPlotLinePath(b,!0)):(l||(e[0]=this.translate(a),e[1]=this.translate(b)),e=R(e,function(a){i.test(a)&&(a=v(a,10)*f/100);return a}),c.shape===
"circle"||!l?(a=-Math.PI/2,b=Math.PI*1.5,n=!0):(a=g+this.translate(a),b=g+this.translate(b)),d=this.chart.renderer.symbols.arc(this.left+d[0],this.top+d[1],e[0],e[0],{start:a,end:b,innerR:r(e[1],e[0]-e[2]),open:n}));return d},getPlotLinePath:function(a,b){var c=this.center,d=this.chart,g=this.getPosition(a),f,e,i;this.isCircular?i=["M",c[0]+d.plotLeft,c[1]+d.plotTop,"L",g.x,g.y]:this.options.gridLineInterpolation==="circle"?(a=this.translate(a))&&(i=this.getLinePath(0,a)):(f=d.xAxis[0],i=[],a=this.translate(a),
c=f.tickPositions,f.autoConnect&&(c=c.concat([c[0]])),b&&(c=[].concat(c).reverse()),s(c,function(c,b){e=f.getPosition(c,a);i.push(b?"L":"M",e.x,e.y)}));return i},getTitlePosition:function(){var a=this.center,b=this.chart,c=this.options.title;return{x:b.plotLeft+a[0]+(c.x||0),y:b.plotTop+a[1]-{high:0.5,middle:0.25,low:0}[c.align]*a[2]+(c.y||0)}}};o(G,"init",function(a,b,c){var k;var d=b.angular,g=b.polar,f=c.isX,e=d&&f,i,n;n=b.options;var l=c.pane||0;if(d){if(F(this,e?T:O),i=!f)this.defaultRadialOptions=
this.defaultRadialGaugeOptions}else if(g)F(this,O),this.defaultRadialOptions=(i=f)?this.defaultRadialXOptions:p(this.defaultYAxisOptions,this.defaultRadialYOptions);a.call(this,b,c);if(!e&&(d||g)){a=this.options;if(!b.panes)b.panes=[];this.pane=(k=b.panes[l]=b.panes[l]||new J(M(n.pane)[l],b,this),l=k);l=l.options;b.inverted=!1;n.chart.zoomType=null;this.startAngleRad=b=(l.startAngle-90)*Math.PI/180;this.endAngleRad=n=(r(l.endAngle,l.startAngle+360)-90)*Math.PI/180;this.offset=a.offset||0;if((this.isCircular=
i)&&c.max===C&&n-b===2*Math.PI)this.autoConnect=!0}});o(u,"getPosition",function(a,b,c,d,g){var f=this.axis;return f.getPosition?f.getPosition(c):a.call(this,b,c,d,g)});o(u,"getLabelPosition",function(a,b,c,d,g,f,e,i,n){var l=this.axis,k=f.y,h=f.align,j=(l.translate(this.pos)+l.startAngleRad+Math.PI/2)/Math.PI*180%360;l.isRadial?(a=l.getPosition(this.pos,l.center[2]/2+r(f.distance,-25)),f.rotation==="auto"?d.attr({rotation:j}):k===null&&(k=v(d.styles.lineHeight)*0.9-d.getBBox().height/2),h===null&&
(h=l.isCircular?j>20&&j<160?"left":j>200&&j<340?"right":"center":"center",d.attr({align:h})),a.x+=f.x,a.y+=k):a=a.call(this,b,c,d,g,f,e,i,n);return a});o(u,"getMarkPath",function(a,b,c,d,g,f,e){var i=this.axis;i.isRadial?(a=i.getPosition(this.pos,i.center[2]/2+d),b=["M",b,c,"L",a.x,a.y]):b=a.call(this,b,c,d,g,f,e);return b});m.arearange=p(m.area,{lineWidth:1,marker:null,threshold:null,tooltip:{pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.low}</b> - <b>{point.high}</b><br/>'},
trackByArea:!0,dataLabels:{verticalAlign:null,xLow:0,xHigh:0,yLow:0,yHigh:0}});h.arearange=j.extendClass(h.area,{type:"arearange",pointArrayMap:["low","high"],toYData:function(a){return[a.low,a.high]},pointValKey:"low",getSegments:function(){var a=this;s(a.points,function(b){if(!a.options.connectNulls&&(b.low===null||b.high===null))b.y=null;else if(b.low===null&&b.high!==null)b.y=b.high});z.prototype.getSegments.call(this)},translate:function(){var a=this.yAxis;h.area.prototype.translate.apply(this);
s(this.points,function(b){var c=b.low,d=b.high,g=b.plotY;d===null&&c===null?b.y=null:c===null?(b.plotLow=b.plotY=null,b.plotHigh=a.translate(d,0,1,0,1)):d===null?(b.plotLow=g,b.plotHigh=null):(b.plotLow=g,b.plotHigh=a.translate(d,0,1,0,1))})},getSegmentPath:function(a){var b,c=[],d=a.length,g=z.prototype.getSegmentPath,f,e;e=this.options;var i=e.step;for(b=HighchartsAdapter.grep(a,function(a){return a.plotLow!==null});d--;)f=a[d],f.plotHigh!==null&&c.push({plotX:f.plotX,plotY:f.plotHigh});a=g.call(this,
b);if(i)i===!0&&(i="left"),e.step={left:"right",center:"center",right:"left"}[i];c=g.call(this,c);e.step=i;e=[].concat(a,c);c[0]="L";this.areaPath=this.areaPath.concat(a,c);return e},drawDataLabels:function(){var a=this.data,b=a.length,c,d=[],g=z.prototype,f=this.options.dataLabels,e,i=this.chart.inverted;if(f.enabled||this._hasPointLabels){for(c=b;c--;)e=a[c],e.y=e.high,e.plotY=e.plotHigh,d[c]=e.dataLabel,e.dataLabel=e.dataLabelUpper,e.below=!1,i?(f.align="left",f.x=f.xHigh):f.y=f.yHigh;g.drawDataLabels.apply(this,
arguments);for(c=b;c--;)e=a[c],e.dataLabelUpper=e.dataLabel,e.dataLabel=d[c],e.y=e.low,e.plotY=e.plotLow,e.below=!0,i?(f.align="right",f.x=f.xLow):f.y=f.yLow;g.drawDataLabels.apply(this,arguments)}},alignDataLabel:h.column.prototype.alignDataLabel,getSymbol:h.column.prototype.getSymbol,drawPoints:w});m.areasplinerange=p(m.arearange);h.areasplinerange=x(h.arearange,{type:"areasplinerange",getPointSpline:h.spline.prototype.getPointSpline});m.columnrange=p(m.column,m.arearange,{lineWidth:1,pointRange:null});
h.columnrange=x(h.arearange,{type:"columnrange",translate:function(){var a=this,b=a.yAxis,c;q.translate.apply(a);s(a.points,function(d){var g=d.shapeArgs,f=a.options.minPointLength,e;d.plotHigh=c=b.translate(d.high,0,1,0,1);d.plotLow=d.plotY;e=c;d=d.plotY-c;d<f&&(f-=d,d+=f,e-=f/2);g.height=d;g.y=e})},trackerGroups:["group","dataLabels"],drawGraph:w,pointAttrToOptions:q.pointAttrToOptions,drawPoints:q.drawPoints,drawTracker:q.drawTracker,animate:q.animate,getColumnMetrics:q.getColumnMetrics});m.gauge=
p(m.line,{dataLabels:{enabled:!0,y:15,borderWidth:1,borderColor:"silver",borderRadius:3,style:{fontWeight:"bold"},verticalAlign:"top",zIndex:2},dial:{},pivot:{},tooltip:{headerFormat:""},showInLegend:!1});u={type:"gauge",pointClass:j.extendClass(j.Point,{setState:function(a){this.state=a}}),angular:!0,drawGraph:w,fixedBox:!0,trackerGroups:["group","dataLabels"],translate:function(){var a=this.yAxis,b=this.options,c=a.center;this.generatePoints();s(this.points,function(d){var g=p(b.dial,d.dial),f=
v(r(g.radius,80))*c[2]/200,e=v(r(g.baseLength,70))*f/100,i=v(r(g.rearLength,10))*f/100,n=g.baseWidth||3,l=g.topWidth||1,k=a.startAngleRad+a.translate(d.y,null,null,null,!0);b.wrap===!1&&(k=Math.max(a.startAngleRad,Math.min(a.endAngleRad,k)));k=k*180/Math.PI;d.shapeType="path";d.shapeArgs={d:g.path||["M",-i,-n/2,"L",e,-n/2,f,-l/2,f,l/2,e,n/2,-i,n/2,"z"],translateX:c[0],translateY:c[1],rotation:k};d.plotX=c[0];d.plotY=c[1]})},drawPoints:function(){var a=this,b=a.yAxis.center,c=a.pivot,d=a.options,g=
d.pivot,f=a.chart.renderer;s(a.points,function(c){var b=c.graphic,g=c.shapeArgs,l=g.d,k=p(d.dial,c.dial);b?(b.animate(g),g.d=l):c.graphic=f[c.shapeType](g).attr({stroke:k.borderColor||"none","stroke-width":k.borderWidth||0,fill:k.backgroundColor||"black",rotation:g.rotation}).add(a.group)});c?c.animate({translateX:b[0],translateY:b[1]}):a.pivot=f.circle(0,0,r(g.radius,5)).attr({"stroke-width":g.borderWidth||0,stroke:g.borderColor||"silver",fill:g.backgroundColor||"black"}).translate(b[0],b[1]).add(a.group)},
animate:function(a){var b=this;if(!a)s(b.points,function(a){var d=a.graphic;d&&(d.attr({rotation:b.yAxis.startAngleRad*180/Math.PI}),d.animate({rotation:a.shapeArgs.rotation},b.options.animation))}),b.animate=null},render:function(){this.group=this.plotGroup("group","series",this.visible?"visible":"hidden",this.options.zIndex,this.chart.seriesGroup);h.pie.prototype.render.call(this);this.group.clip(this.chart.clipRect)},setData:h.pie.prototype.setData,drawTracker:h.column.prototype.drawTracker};h.gauge=
j.extendClass(h.line,u);m.boxplot=p(m.column,{fillColor:"#FFFFFF",lineWidth:1,medianWidth:2,states:{hover:{brightness:-0.3}},threshold:null,tooltip:{pointFormat:'<span style="color:{series.color};font-weight:bold">{series.name}</span><br/>Maximum: {point.high}<br/>Upper quartile: {point.q3}<br/>Median: {point.median}<br/>Lower quartile: {point.q1}<br/>Minimum: {point.low}<br/>'},whiskerLength:"50%",whiskerWidth:2});h.boxplot=x(h.column,{type:"boxplot",pointArrayMap:["low","q1","median","q3","high"],
toYData:function(a){return[a.low,a.q1,a.median,a.q3,a.high]},pointValKey:"high",pointAttrToOptions:{fill:"fillColor",stroke:"color","stroke-width":"lineWidth"},drawDataLabels:w,translate:function(){var a=this.yAxis,b=this.pointArrayMap;h.column.prototype.translate.apply(this);s(this.points,function(c){s(b,function(b){c[b]!==null&&(c[b+"Plot"]=a.translate(c[b],0,1,0,1))})})},drawPoints:function(){var a=this,b=a.points,c=a.options,d=a.chart.renderer,g,f,e,i,n,l,k,h,j,m,o,H,p,E,I,q,w,t,v,u,z,y,x=a.doQuartiles!==
!1,B=parseInt(a.options.whiskerLength,10)/100;s(b,function(b){j=b.graphic;z=b.shapeArgs;o={};E={};q={};y=b.color||a.color;if(b.plotY!==C)if(g=b.pointAttr[b.selected?"selected":""],w=z.width,t=A(z.x),v=t+w,u=D(w/2),f=A(x?b.q1Plot:b.lowPlot),e=A(x?b.q3Plot:b.lowPlot),i=A(b.highPlot),n=A(b.lowPlot),o.stroke=b.stemColor||c.stemColor||y,o["stroke-width"]=r(b.stemWidth,c.stemWidth,c.lineWidth),o.dashstyle=b.stemDashStyle||c.stemDashStyle,E.stroke=b.whiskerColor||c.whiskerColor||y,E["stroke-width"]=r(b.whiskerWidth,
c.whiskerWidth,c.lineWidth),q.stroke=b.medianColor||c.medianColor||y,q["stroke-width"]=r(b.medianWidth,c.medianWidth,c.lineWidth),k=o["stroke-width"]%2/2,h=t+u+k,m=["M",h,e,"L",h,i,"M",h,f,"L",h,n,"z"],x&&(k=g["stroke-width"]%2/2,h=A(h)+k,f=A(f)+k,e=A(e)+k,t+=k,v+=k,H=["M",t,e,"L",t,f,"L",v,f,"L",v,e,"L",t,e,"z"]),B&&(k=E["stroke-width"]%2/2,i+=k,n+=k,p=["M",h-u*B,i,"L",h+u*B,i,"M",h-u*B,n,"L",h+u*B,n]),k=q["stroke-width"]%2/2,l=D(b.medianPlot)+k,I=["M",t,l,"L",v,l,"z"],j)b.stem.animate({d:m}),B&&
b.whiskers.animate({d:p}),x&&b.box.animate({d:H}),b.medianShape.animate({d:I});else{b.graphic=j=d.g().add(a.group);b.stem=d.path(m).attr(o).add(j);if(B)b.whiskers=d.path(p).attr(E).add(j);if(x)b.box=d.path(H).attr(g).add(j);b.medianShape=d.path(I).attr(q).add(j)}})}});m.errorbar=p(m.boxplot,{color:"#000000",grouping:!1,linkedTo:":previous",tooltip:{pointFormat:m.arearange.tooltip.pointFormat},whiskerWidth:null});h.errorbar=x(h.boxplot,{type:"errorbar",pointArrayMap:["low","high"],toYData:function(a){return[a.low,
a.high]},pointValKey:"high",doQuartiles:!1,getColumnMetrics:function(){return this.linkedParent&&this.linkedParent.columnMetrics||h.column.prototype.getColumnMetrics.call(this)}});m.waterfall=p(m.column,{lineWidth:1,lineColor:"#333",dashStyle:"dot",borderColor:"#333"});h.waterfall=x(h.column,{type:"waterfall",upColorProp:"fill",pointArrayMap:["low","y"],pointValKey:"y",init:function(a,b){b.stacking=!0;h.column.prototype.init.call(this,a,b)},translate:function(){var a=this.options,b=this.yAxis,c,d,
g,f,e,i,n,l,k;c=a.threshold;a=a.borderWidth%2/2;h.column.prototype.translate.apply(this);l=c;g=this.points;for(d=0,c=g.length;d<c;d++){f=g[d];e=f.shapeArgs;i=this.getStack(d);k=i.points[this.index];if(isNaN(f.y))f.y=this.yData[d];n=S(l,l+f.y)+k[0];e.y=b.translate(n,0,1);f.isSum||f.isIntermediateSum?(e.y=b.translate(k[1],0,1),e.height=b.translate(k[0],0,1)-e.y):l+=i.total;e.height<0&&(e.y+=e.height,e.height*=-1);f.plotY=e.y=D(e.y)-a;e.height=D(e.height);f.yBottom=e.y+e.height}},processData:function(a){var b=
this.yData,c=this.points,d,g=b.length,f=this.options.threshold||0,e,i,h,l,k,j;i=e=h=l=f;for(j=0;j<g;j++)k=b[j],d=c&&c[j]?c[j]:{},k==="sum"||d.isSum?b[j]=i:k==="intermediateSum"||d.isIntermediateSum?(b[j]=e,e=f):(i+=k,e+=k),h=Math.min(i,h),l=Math.max(i,l);z.prototype.processData.call(this,a);this.dataMin=h;this.dataMax=l},toYData:function(a){if(a.isSum)return"sum";else if(a.isIntermediateSum)return"intermediateSum";return a.y},getAttribs:function(){h.column.prototype.getAttribs.apply(this,arguments);
var a=this.options,b=a.states,c=a.upColor||this.color,a=j.Color(c).brighten(0.1).get(),d=p(this.pointAttr),g=this.upColorProp;d[""][g]=c;d.hover[g]=b.hover.upColor||a;d.select[g]=b.select.upColor||c;s(this.points,function(a){if(a.y>0&&!a.color)a.pointAttr=d,a.color=c})},getGraphPath:function(){var a=this.data,b=a.length,c=D(this.options.lineWidth+this.options.borderWidth)%2/2,d=[],g,f,e;for(e=1;e<b;e++)f=a[e].shapeArgs,g=a[e-1].shapeArgs,f=["M",g.x+g.width,g.y+c,"L",f.x,g.y+c],a[e-1].y<0&&(f[2]+=
g.height,f[5]+=g.height),d=d.concat(f);return d},getExtremes:w,getStack:function(a){var b=this.yAxis.stacks,c=this.stackKey;this.processedYData[a]<this.options.threshold&&(c="-"+c);return b[c][a]},drawGraph:z.prototype.drawGraph});m.bubble=p(m.scatter,{dataLabels:{inside:!0,style:{color:"white",textShadow:"0px 0px 3px black"},verticalAlign:"middle"},marker:{lineColor:null,lineWidth:1},minSize:8,maxSize:"20%",tooltip:{pointFormat:"({point.x}, {point.y}), Size: {point.z}"},turboThreshold:0,zThreshold:0});
h.bubble=x(h.scatter,{type:"bubble",pointArrayMap:["y","z"],trackerGroups:["group","dataLabelsGroup"],pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor"},applyOpacity:function(a){var b=this.options.marker,c=r(b.fillOpacity,0.5),a=a||b.fillColor||this.color;c!==1&&(a=j.Color(a).setOpacity(c).get("rgba"));return a},convertAttribs:function(){var a=z.prototype.convertAttribs.apply(this,arguments);a.fill=this.applyOpacity(a.fill);return a},getRadii:function(a,b,c,d){var g,
f,e,i=this.zData,h=[];for(f=0,g=i.length;f<g;f++)e=b-a,e=e>0?(i[f]-a)/(b-a):0.5,h.push(t.ceil(c+e*(d-c))/2);this.radii=h},animate:function(a){var b=this.options.animation;if(!a)s(this.points,function(a){var d=a.graphic,a=a.shapeArgs;d&&a&&(d.attr("r",1),d.animate({r:a.r},b))}),this.animate=null},translate:function(){var a,b=this.data,c,d,g=this.radii;h.scatter.prototype.translate.call(this);for(a=b.length;a--;)c=b[a],d=g?g[a]:0,c.negative=c.z<(this.options.zThreshold||0),d>=this.minPxSize/2?(c.shapeType=
"circle",c.shapeArgs={x:c.plotX,y:c.plotY,r:d},c.dlBox={x:c.plotX-d,y:c.plotY-d,width:2*d,height:2*d}):c.shapeArgs=c.plotY=c.dlBox=C},drawLegendSymbol:function(a,b){var c=v(a.itemStyle.fontSize)/2;b.legendSymbol=this.chart.renderer.circle(c,a.baseline-c,c).attr({zIndex:3}).add(b.legendGroup);b.legendSymbol.isMarker=!0},drawPoints:h.column.prototype.drawPoints,alignDataLabel:h.column.prototype.alignDataLabel});N.prototype.beforePadding=function(){var a=this,b=this.len,c=this.chart,d=0,g=b,f=this.isXAxis,
e=f?"xData":"yData",i=this.min,h={},j=t.min(c.plotWidth,c.plotHeight),k=Number.MAX_VALUE,m=-Number.MAX_VALUE,o=this.max-i,p=b/o,q=[];this.tickPositions&&(s(this.series,function(b){var c=b.options;if(b.type==="bubble"&&b.visible&&(a.allowZoomOutside=!0,q.push(b),f))s(["minSize","maxSize"],function(a){var b=c[a],d=/%$/.test(b),b=v(b);h[a]=d?j*b/100:b}),b.minPxSize=h.minSize,b=b.zData,b.length&&(k=t.min(k,t.max(P(b),c.displayNegative===!1?c.zThreshold:-Number.MAX_VALUE)),m=t.max(m,Q(b)))}),s(q,function(a){var b=
a[e],c=b.length,j;f&&a.getRadii(k,m,h.minSize,h.maxSize);if(o>0)for(;c--;)j=a.radii[c],d=Math.min((b[c]-i)*p-j,d),g=Math.max((b[c]-i)*p+j,g)}),q.length&&o>0&&r(this.options.min,this.userMin)===C&&r(this.options.max,this.userMax)===C&&(g-=b,p*=(b+d-g)/b,this.min+=d/p,this.max+=g/p))};var y=z.prototype,m=j.Pointer.prototype;y.toXY=function(a){var b,c=this.chart;b=a.plotX;var d=a.plotY;a.rectPlotX=b;a.rectPlotY=d;a.clientX=(b/Math.PI*180+this.xAxis.pane.options.startAngle)%360;b=this.xAxis.postTranslate(a.plotX,
this.yAxis.len-d);a.plotX=a.polarPlotX=b.x-c.plotLeft;a.plotY=a.polarPlotY=b.y-c.plotTop};y.orderTooltipPoints=function(a){if(this.chart.polar&&(a.sort(function(a,c){return a.clientX-c.clientX}),a[0]))a[0].wrappedClientX=a[0].clientX+360,a.push(a[0])};o(h.area.prototype,"init",K);o(h.areaspline.prototype,"init",K);o(h.spline.prototype,"getPointSpline",function(a,b,c,d){var g,f,e,i,h,j,k;if(this.chart.polar){g=c.plotX;f=c.plotY;a=b[d-1];e=b[d+1];this.connectEnds&&(a||(a=b[b.length-2]),e||(e=b[1]));
if(a&&e)i=a.plotX,h=a.plotY,b=e.plotX,j=e.plotY,i=(1.5*g+i)/2.5,h=(1.5*f+h)/2.5,e=(1.5*g+b)/2.5,k=(1.5*f+j)/2.5,b=Math.sqrt(Math.pow(i-g,2)+Math.pow(h-f,2)),j=Math.sqrt(Math.pow(e-g,2)+Math.pow(k-f,2)),i=Math.atan2(h-f,i-g),h=Math.atan2(k-f,e-g),k=Math.PI/2+(i+h)/2,Math.abs(i-k)>Math.PI/2&&(k-=Math.PI),i=g+Math.cos(k)*b,h=f+Math.sin(k)*b,e=g+Math.cos(Math.PI+k)*j,k=f+Math.sin(Math.PI+k)*j,c.rightContX=e,c.rightContY=k;d?(c=["C",a.rightContX||a.plotX,a.rightContY||a.plotY,i||g,h||f,g,f],a.rightContX=
a.rightContY=null):c=["M",g,f]}else c=a.call(this,b,c,d);return c});o(y,"translate",function(a){a.call(this);if(this.chart.polar&&!this.preventPostTranslate)for(var a=this.points,b=a.length;b--;)this.toXY(a[b])});o(y,"getSegmentPath",function(a,b){var c=this.points;if(this.chart.polar&&this.options.connectEnds!==!1&&b[b.length-1]===c[c.length-1]&&c[0].y!==null)this.connectEnds=!0,b=[].concat(b,[c[0]]);return a.call(this,b)});o(y,"animate",L);o(q,"animate",L);o(y,"setTooltipPoints",function(a,b){this.chart.polar&&
F(this.xAxis,{tooltipLen:360});return a.call(this,b)});o(q,"translate",function(a){var b=this.xAxis,c=this.yAxis.len,d=b.center,g=b.startAngleRad,f=this.chart.renderer,e,h;this.preventPostTranslate=!0;a.call(this);if(b.isRadial){b=this.points;for(h=b.length;h--;)e=b[h],a=e.barX+g,e.shapeType="path",e.shapeArgs={d:f.symbols.arc(d[0],d[1],c-e.plotY,null,{start:a,end:a+e.pointWidth,innerR:c-r(e.yBottom,c)})},this.toXY(e)}});o(q,"alignDataLabel",function(a,b,c,d,g,f){if(this.chart.polar){a=b.rectPlotX/
Math.PI*180;if(d.align===null)d.align=a>20&&a<160?"left":a>200&&a<340?"right":"center";if(d.verticalAlign===null)d.verticalAlign=a<45||a>315?"bottom":a>135&&a<225?"top":"middle";y.alignDataLabel.call(this,b,c,d,g,f)}else a.call(this,b,c,d,g,f)});o(m,"getIndex",function(a,b){var c,d=this.chart,g;d.polar?(g=d.xAxis[0].center,c=b.chartX-g[0]-d.plotLeft,d=b.chartY-g[1]-d.plotTop,c=180-Math.round(Math.atan2(c,d)/Math.PI*180)):c=a.call(this,b);return c});o(m,"getCoordinates",function(a,b){var c=this.chart,
d={xAxis:[],yAxis:[]};c.polar?s(c.axes,function(a){var f=a.isXAxis,e=a.center,h=b.chartX-e[0]-c.plotLeft,e=b.chartY-e[1]-c.plotTop;d[f?"xAxis":"yAxis"].push({axis:a,value:a.translate(f?Math.PI-Math.atan2(h,e):Math.sqrt(Math.pow(h,2)+Math.pow(e,2)),!0)})}):d=a.call(this,b);return d})})(Highcharts);
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts-more.src.js
New file
@@ -0,0 +1,2430 @@
// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
/**
 * @license Highcharts JS v3.0.6 (2013-10-04)
 *
 * (c) 2009-2013 Torstein Hønsi
 *
 * License: www.highcharts.com/license
 */
// JSLint options:
/*global Highcharts, HighchartsAdapter, document, window, navigator, setInterval, clearInterval, clearTimeout, setTimeout, location, jQuery, $, console */
(function (Highcharts, UNDEFINED) {
var arrayMin = Highcharts.arrayMin,
    arrayMax = Highcharts.arrayMax,
    each = Highcharts.each,
    extend = Highcharts.extend,
    merge = Highcharts.merge,
    map = Highcharts.map,
    pick = Highcharts.pick,
    pInt = Highcharts.pInt,
    defaultPlotOptions = Highcharts.getOptions().plotOptions,
    seriesTypes = Highcharts.seriesTypes,
    extendClass = Highcharts.extendClass,
    splat = Highcharts.splat,
    wrap = Highcharts.wrap,
    Axis = Highcharts.Axis,
    Tick = Highcharts.Tick,
    Series = Highcharts.Series,
    colProto = seriesTypes.column.prototype,
    math = Math,
    mathRound = math.round,
    mathFloor = math.floor,
    mathMax = math.max,
    noop = function () {};/**
 * The Pane object allows options that are common to a set of X and Y axes.
 *
 * In the future, this can be extended to basic Highcharts and Highstock.
 */
function Pane(options, chart, firstAxis) {
    this.init.call(this, options, chart, firstAxis);
}
// Extend the Pane prototype
extend(Pane.prototype, {
    /**
     * Initiate the Pane object
     */
    init: function (options, chart, firstAxis) {
        var pane = this,
            backgroundOption,
            defaultOptions = pane.defaultOptions;
        pane.chart = chart;
        // Set options
        if (chart.angular) { // gauges
            defaultOptions.background = {}; // gets extended by this.defaultBackgroundOptions
        }
        pane.options = options = merge(defaultOptions, options);
        backgroundOption = options.background;
        // To avoid having weighty logic to place, update and remove the backgrounds,
        // push them to the first axis' plot bands and borrow the existing logic there.
        if (backgroundOption) {
            each([].concat(splat(backgroundOption)).reverse(), function (config) {
                var backgroundColor = config.backgroundColor; // if defined, replace the old one (specific for gradients)
                config = merge(pane.defaultBackgroundOptions, config);
                if (backgroundColor) {
                    config.backgroundColor = backgroundColor;
                }
                config.color = config.backgroundColor; // due to naming in plotBands
                firstAxis.options.plotBands.unshift(config);
            });
        }
    },
    /**
     * The default options object
     */
    defaultOptions: {
        // background: {conditional},
        center: ['50%', '50%'],
        size: '85%',
        startAngle: 0
        //endAngle: startAngle + 360
    },
    /**
     * The default background options
     */
    defaultBackgroundOptions: {
        shape: 'circle',
        borderWidth: 1,
        borderColor: 'silver',
        backgroundColor: {
            linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
            stops: [
                [0, '#FFF'],
                [1, '#DDD']
            ]
        },
        from: Number.MIN_VALUE, // corrected to axis min
        innerRadius: 0,
        to: Number.MAX_VALUE, // corrected to axis max
        outerRadius: '105%'
    }
});
var axisProto = Axis.prototype,
    tickProto = Tick.prototype;
/**
 * Augmented methods for the x axis in order to hide it completely, used for the X axis in gauges
 */
var hiddenAxisMixin = {
    getOffset: noop,
    redraw: function () {
        this.isDirty = false; // prevent setting Y axis dirty
    },
    render: function () {
        this.isDirty = false; // prevent setting Y axis dirty
    },
    setScale: noop,
    setCategories: noop,
    setTitle: noop
};
/**
 * Augmented methods for the value axis
 */
/*jslint unparam: true*/
var radialAxisMixin = {
    isRadial: true,
    /**
     * The default options extend defaultYAxisOptions
     */
    defaultRadialGaugeOptions: {
        labels: {
            align: 'center',
            x: 0,
            y: null // auto
        },
        minorGridLineWidth: 0,
        minorTickInterval: 'auto',
        minorTickLength: 10,
        minorTickPosition: 'inside',
        minorTickWidth: 1,
        plotBands: [],
        tickLength: 10,
        tickPosition: 'inside',
        tickWidth: 2,
        title: {
            rotation: 0
        },
        zIndex: 2 // behind dials, points in the series group
    },
    // Circular axis around the perimeter of a polar chart
    defaultRadialXOptions: {
        gridLineWidth: 1, // spokes
        labels: {
            align: null, // auto
            distance: 15,
            x: 0,
            y: null // auto
        },
        maxPadding: 0,
        minPadding: 0,
        plotBands: [],
        showLastLabel: false,
        tickLength: 0
    },
    // Radial axis, like a spoke in a polar chart
    defaultRadialYOptions: {
        gridLineInterpolation: 'circle',
        labels: {
            align: 'right',
            x: -3,
            y: -2
        },
        plotBands: [],
        showLastLabel: false,
        title: {
            x: 4,
            text: null,
            rotation: 90
        }
    },
    /**
     * Merge and set options
     */
    setOptions: function (userOptions) {
        this.options = merge(
            this.defaultOptions,
            this.defaultRadialOptions,
            userOptions
        );
    },
    /**
     * Wrap the getOffset method to return zero offset for title or labels in a radial
     * axis
     */
    getOffset: function () {
        // Call the Axis prototype method (the method we're in now is on the instance)
        axisProto.getOffset.call(this);
        // Title or label offsets are not counted
        this.chart.axisOffset[this.side] = 0;
    },
    /**
     * Get the path for the axis line. This method is also referenced in the getPlotLinePath
     * method.
     */
    getLinePath: function (lineWidth, radius) {
        var center = this.center;
        radius = pick(radius, center[2] / 2 - this.offset);
        return this.chart.renderer.symbols.arc(
            this.left + center[0],
            this.top + center[1],
            radius,
            radius,
            {
                start: this.startAngleRad,
                end: this.endAngleRad,
                open: true,
                innerR: 0
            }
        );
    },
    /**
     * Override setAxisTranslation by setting the translation to the difference
     * in rotation. This allows the translate method to return angle for
     * any given value.
     */
    setAxisTranslation: function () {
        // Call uber method
        axisProto.setAxisTranslation.call(this);
        // Set transA and minPixelPadding
        if (this.center) { // it's not defined the first time
            if (this.isCircular) {
                this.transA = (this.endAngleRad - this.startAngleRad) /
                    ((this.max - this.min) || 1);
            } else {
                this.transA = (this.center[2] / 2) / ((this.max - this.min) || 1);
            }
            if (this.isXAxis) {
                this.minPixelPadding = this.transA * this.minPointOffset +
                    (this.reversed ? (this.endAngleRad - this.startAngleRad) / 4 : 0); // ???
            }
        }
    },
    /**
     * In case of auto connect, add one closestPointRange to the max value right before
     * tickPositions are computed, so that ticks will extend passed the real max.
     */
    beforeSetTickPositions: function () {
        if (this.autoConnect) {
            this.max += (this.categories && 1) || this.pointRange || this.closestPointRange || 0; // #1197, #2260
        }
    },
    /**
     * Override the setAxisSize method to use the arc's circumference as length. This
     * allows tickPixelInterval to apply to pixel lengths along the perimeter
     */
    setAxisSize: function () {
        axisProto.setAxisSize.call(this);
        if (this.isRadial) {
            // Set the center array
            this.center = this.pane.center = seriesTypes.pie.prototype.getCenter.call(this.pane);
            this.len = this.width = this.height = this.isCircular ?
                this.center[2] * (this.endAngleRad - this.startAngleRad) / 2 :
                this.center[2] / 2;
        }
    },
    /**
     * Returns the x, y coordinate of a point given by a value and a pixel distance
     * from center
     */
    getPosition: function (value, length) {
        if (!this.isCircular) {
            length = this.translate(value);
            value = this.min;
        }
        return this.postTranslate(
            this.translate(value),
            pick(length, this.center[2] / 2) - this.offset
        );
    },
    /**
     * Translate from intermediate plotX (angle), plotY (axis.len - radius) to final chart coordinates.
     */
    postTranslate: function (angle, radius) {
        var chart = this.chart,
            center = this.center;
        angle = this.startAngleRad + angle;
        return {
            x: chart.plotLeft + center[0] + Math.cos(angle) * radius,
            y: chart.plotTop + center[1] + Math.sin(angle) * radius
        };
    },
    /**
     * Find the path for plot bands along the radial axis
     */
    getPlotBandPath: function (from, to, options) {
        var center = this.center,
            startAngleRad = this.startAngleRad,
            fullRadius = center[2] / 2,
            radii = [
                pick(options.outerRadius, '100%'),
                options.innerRadius,
                pick(options.thickness, 10)
            ],
            percentRegex = /%$/,
            start,
            end,
            open,
            isCircular = this.isCircular, // X axis in a polar chart
            ret;
        // Polygonal plot bands
        if (this.options.gridLineInterpolation === 'polygon') {
            ret = this.getPlotLinePath(from).concat(this.getPlotLinePath(to, true));
        // Circular grid bands
        } else {
            // Plot bands on Y axis (radial axis) - inner and outer radius depend on to and from
            if (!isCircular) {
                radii[0] = this.translate(from);
                radii[1] = this.translate(to);
            }
            // Convert percentages to pixel values
            radii = map(radii, function (radius) {
                if (percentRegex.test(radius)) {
                    radius = (pInt(radius, 10) * fullRadius) / 100;
                }
                return radius;
            });
            // Handle full circle
            if (options.shape === 'circle' || !isCircular) {
                start = -Math.PI / 2;
                end = Math.PI * 1.5;
                open = true;
            } else {
                start = startAngleRad + this.translate(from);
                end = startAngleRad + this.translate(to);
            }
            ret = this.chart.renderer.symbols.arc(
                this.left + center[0],
                this.top + center[1],
                radii[0],
                radii[0],
                {
                    start: start,
                    end: end,
                    innerR: pick(radii[1], radii[0] - radii[2]),
                    open: open
                }
            );
        }
        return ret;
    },
    /**
     * Find the path for plot lines perpendicular to the radial axis.
     */
    getPlotLinePath: function (value, reverse) {
        var axis = this,
            center = axis.center,
            chart = axis.chart,
            end = axis.getPosition(value),
            xAxis,
            xy,
            tickPositions,
            ret;
        // Spokes
        if (axis.isCircular) {
            ret = ['M', center[0] + chart.plotLeft, center[1] + chart.plotTop, 'L', end.x, end.y];
        // Concentric circles
        } else if (axis.options.gridLineInterpolation === 'circle') {
            value = axis.translate(value);
            if (value) { // a value of 0 is in the center
                ret = axis.getLinePath(0, value);
            }
        // Concentric polygons
        } else {
            xAxis = chart.xAxis[0];
            ret = [];
            value = axis.translate(value);
            tickPositions = xAxis.tickPositions;
            if (xAxis.autoConnect) {
                tickPositions = tickPositions.concat([tickPositions[0]]);
            }
            // Reverse the positions for concatenation of polygonal plot bands
            if (reverse) {
                tickPositions = [].concat(tickPositions).reverse();
            }
            each(tickPositions, function (pos, i) {
                xy = xAxis.getPosition(pos, value);
                ret.push(i ? 'L' : 'M', xy.x, xy.y);
            });
        }
        return ret;
    },
    /**
     * Find the position for the axis title, by default inside the gauge
     */
    getTitlePosition: function () {
        var center = this.center,
            chart = this.chart,
            titleOptions = this.options.title;
        return {
            x: chart.plotLeft + center[0] + (titleOptions.x || 0),
            y: chart.plotTop + center[1] - ({ high: 0.5, middle: 0.25, low: 0 }[titleOptions.align] *
                center[2]) + (titleOptions.y || 0)
        };
    }
};
/*jslint unparam: false*/
/**
 * Override axisProto.init to mix in special axis instance functions and function overrides
 */
wrap(axisProto, 'init', function (proceed, chart, userOptions) {
    var axis = this,
        angular = chart.angular,
        polar = chart.polar,
        isX = userOptions.isX,
        isHidden = angular && isX,
        isCircular,
        startAngleRad,
        endAngleRad,
        options,
        chartOptions = chart.options,
        paneIndex = userOptions.pane || 0,
        pane,
        paneOptions;
    // Before prototype.init
    if (angular) {
        extend(this, isHidden ? hiddenAxisMixin : radialAxisMixin);
        isCircular =  !isX;
        if (isCircular) {
            this.defaultRadialOptions = this.defaultRadialGaugeOptions;
        }
    } else if (polar) {
        //extend(this, userOptions.isX ? radialAxisMixin : radialAxisMixin);
        extend(this, radialAxisMixin);
        isCircular = isX;
        this.defaultRadialOptions = isX ? this.defaultRadialXOptions : merge(this.defaultYAxisOptions, this.defaultRadialYOptions);
    }
    // Run prototype.init
    proceed.call(this, chart, userOptions);
    if (!isHidden && (angular || polar)) {
        options = this.options;
        // Create the pane and set the pane options.
        if (!chart.panes) {
            chart.panes = [];
        }
        this.pane = pane = chart.panes[paneIndex] = chart.panes[paneIndex] || new Pane(
            splat(chartOptions.pane)[paneIndex],
            chart,
            axis
        );
        paneOptions = pane.options;
        // Disable certain features on angular and polar axes
        chart.inverted = false;
        chartOptions.chart.zoomType = null;
        // Start and end angle options are
        // given in degrees relative to top, while internal computations are
        // in radians relative to right (like SVG).
        this.startAngleRad = startAngleRad = (paneOptions.startAngle - 90) * Math.PI / 180;
        this.endAngleRad = endAngleRad = (pick(paneOptions.endAngle, paneOptions.startAngle + 360)  - 90) * Math.PI / 180;
        this.offset = options.offset || 0;
        this.isCircular = isCircular;
        // Automatically connect grid lines?
        if (isCircular && userOptions.max === UNDEFINED && endAngleRad - startAngleRad === 2 * Math.PI) {
            this.autoConnect = true;
        }
    }
});
/**
 * Add special cases within the Tick class' methods for radial axes.
 */
wrap(tickProto, 'getPosition', function (proceed, horiz, pos, tickmarkOffset, old) {
    var axis = this.axis;
    return axis.getPosition ?
        axis.getPosition(pos) :
        proceed.call(this, horiz, pos, tickmarkOffset, old);
});
/**
 * Wrap the getLabelPosition function to find the center position of the label
 * based on the distance option
 */
wrap(tickProto, 'getLabelPosition', function (proceed, x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {
    var axis = this.axis,
        optionsY = labelOptions.y,
        ret,
        align = labelOptions.align,
        angle = ((axis.translate(this.pos) + axis.startAngleRad + Math.PI / 2) / Math.PI * 180) % 360;
    if (axis.isRadial) {
        ret = axis.getPosition(this.pos, (axis.center[2] / 2) + pick(labelOptions.distance, -25));
        // Automatically rotated
        if (labelOptions.rotation === 'auto') {
            label.attr({
                rotation: angle
            });
        // Vertically centered
        } else if (optionsY === null) {
            optionsY = pInt(label.styles.lineHeight) * 0.9 - label.getBBox().height / 2;
        }
        // Automatic alignment
        if (align === null) {
            if (axis.isCircular) {
                if (angle > 20 && angle < 160) {
                    align = 'left'; // right hemisphere
                } else if (angle > 200 && angle < 340) {
                    align = 'right'; // left hemisphere
                } else {
                    align = 'center'; // top or bottom
                }
            } else {
                align = 'center';
            }
            label.attr({
                align: align
            });
        }
        ret.x += labelOptions.x;
        ret.y += optionsY;
    } else {
        ret = proceed.call(this, x, y, label, horiz, labelOptions, tickmarkOffset, index, step);
    }
    return ret;
});
/**
 * Wrap the getMarkPath function to return the path of the radial marker
 */
wrap(tickProto, 'getMarkPath', function (proceed, x, y, tickLength, tickWidth, horiz, renderer) {
    var axis = this.axis,
        endPoint,
        ret;
    if (axis.isRadial) {
        endPoint = axis.getPosition(this.pos, axis.center[2] / 2 + tickLength);
        ret = [
            'M',
            x,
            y,
            'L',
            endPoint.x,
            endPoint.y
        ];
    } else {
        ret = proceed.call(this, x, y, tickLength, tickWidth, horiz, renderer);
    }
    return ret;
});/*
 * The AreaRangeSeries class
 *
 */
/**
 * Extend the default options with map options
 */
defaultPlotOptions.arearange = merge(defaultPlotOptions.area, {
    lineWidth: 1,
    marker: null,
    threshold: null,
    tooltip: {
        pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.low}</b> - <b>{point.high}</b><br/>'
    },
    trackByArea: true,
    dataLabels: {
        verticalAlign: null,
        xLow: 0,
        xHigh: 0,
        yLow: 0,
        yHigh: 0
    }
});
/**
 * Add the series type
 */
seriesTypes.arearange = Highcharts.extendClass(seriesTypes.area, {
    type: 'arearange',
    pointArrayMap: ['low', 'high'],
    toYData: function (point) {
        return [point.low, point.high];
    },
    pointValKey: 'low',
    /**
     * Extend getSegments to force null points if the higher value is null. #1703.
     */
    getSegments: function () {
        var series = this;
        each(series.points, function (point) {
            if (!series.options.connectNulls && (point.low === null || point.high === null)) {
                point.y = null;
            } else if (point.low === null && point.high !== null) {
                point.y = point.high;
            }
        });
        Series.prototype.getSegments.call(this);
    },
    /**
     * Translate data points from raw values x and y to plotX and plotY
     */
    translate: function () {
        var series = this,
            yAxis = series.yAxis;
        seriesTypes.area.prototype.translate.apply(series);
        // Set plotLow and plotHigh
        each(series.points, function (point) {
            var low = point.low,
                high = point.high,
                plotY = point.plotY;
            if (high === null && low === null) {
                point.y = null;
            } else if (low === null) {
                point.plotLow = point.plotY = null;
                point.plotHigh = yAxis.translate(high, 0, 1, 0, 1);
            } else if (high === null) {
                point.plotLow = plotY;
                point.plotHigh = null;
            } else {
                point.plotLow = plotY;
                point.plotHigh = yAxis.translate(high, 0, 1, 0, 1);
            }
        });
    },
    /**
     * Extend the line series' getSegmentPath method by applying the segment
     * path to both lower and higher values of the range
     */
    getSegmentPath: function (segment) {
        var lowSegment,
            highSegment = [],
            i = segment.length,
            baseGetSegmentPath = Series.prototype.getSegmentPath,
            point,
            linePath,
            lowerPath,
            options = this.options,
            step = options.step,
            higherPath;
        // Remove nulls from low segment
        lowSegment = HighchartsAdapter.grep(segment, function (point) {
            return point.plotLow !== null;
        });
        // Make a segment with plotX and plotY for the top values
        while (i--) {
            point = segment[i];
            if (point.plotHigh !== null) {
                highSegment.push({
                    plotX: point.plotX,
                    plotY: point.plotHigh
                });
            }
        }
        // Get the paths
        lowerPath = baseGetSegmentPath.call(this, lowSegment);
        if (step) {
            if (step === true) {
                step = 'left';
            }
            options.step = { left: 'right', center: 'center', right: 'left' }[step]; // swap for reading in getSegmentPath
        }
        higherPath = baseGetSegmentPath.call(this, highSegment);
        options.step = step;
        // Create a line on both top and bottom of the range
        linePath = [].concat(lowerPath, higherPath);
        // For the area path, we need to change the 'move' statement into 'lineTo' or 'curveTo'
        higherPath[0] = 'L'; // this probably doesn't work for spline
        this.areaPath = this.areaPath.concat(lowerPath, higherPath);
        return linePath;
    },
    /**
     * Extend the basic drawDataLabels method by running it for both lower and higher
     * values.
     */
    drawDataLabels: function () {
        var data = this.data,
            length = data.length,
            i,
            originalDataLabels = [],
            seriesProto = Series.prototype,
            dataLabelOptions = this.options.dataLabels,
            point,
            inverted = this.chart.inverted;
        if (dataLabelOptions.enabled || this._hasPointLabels) {
            // Step 1: set preliminary values for plotY and dataLabel and draw the upper labels
            i = length;
            while (i--) {
                point = data[i];
                // Set preliminary values
                point.y = point.high;
                point.plotY = point.plotHigh;
                // Store original data labels and set preliminary label objects to be picked up
                // in the uber method
                originalDataLabels[i] = point.dataLabel;
                point.dataLabel = point.dataLabelUpper;
                // Set the default offset
                point.below = false;
                if (inverted) {
                    dataLabelOptions.align = 'left';
                    dataLabelOptions.x = dataLabelOptions.xHigh;
                } else {
                    dataLabelOptions.y = dataLabelOptions.yHigh;
                }
            }
            seriesProto.drawDataLabels.apply(this, arguments); // #1209
            // Step 2: reorganize and handle data labels for the lower values
            i = length;
            while (i--) {
                point = data[i];
                // Move the generated labels from step 1, and reassign the original data labels
                point.dataLabelUpper = point.dataLabel;
                point.dataLabel = originalDataLabels[i];
                // Reset values
                point.y = point.low;
                point.plotY = point.plotLow;
                // Set the default offset
                point.below = true;
                if (inverted) {
                    dataLabelOptions.align = 'right';
                    dataLabelOptions.x = dataLabelOptions.xLow;
                } else {
                    dataLabelOptions.y = dataLabelOptions.yLow;
                }
            }
            seriesProto.drawDataLabels.apply(this, arguments);
        }
    },
    alignDataLabel: seriesTypes.column.prototype.alignDataLabel,
    getSymbol: seriesTypes.column.prototype.getSymbol,
    drawPoints: noop
});/**
 * The AreaSplineRangeSeries class
 */
defaultPlotOptions.areasplinerange = merge(defaultPlotOptions.arearange);
/**
 * AreaSplineRangeSeries object
 */
seriesTypes.areasplinerange = extendClass(seriesTypes.arearange, {
    type: 'areasplinerange',
    getPointSpline: seriesTypes.spline.prototype.getPointSpline
});/**
 * The ColumnRangeSeries class
 */
defaultPlotOptions.columnrange = merge(defaultPlotOptions.column, defaultPlotOptions.arearange, {
    lineWidth: 1,
    pointRange: null
});
/**
 * ColumnRangeSeries object
 */
seriesTypes.columnrange = extendClass(seriesTypes.arearange, {
    type: 'columnrange',
    /**
     * Translate data points from raw values x and y to plotX and plotY
     */
    translate: function () {
        var series = this,
            yAxis = series.yAxis,
            plotHigh;
        colProto.translate.apply(series);
        // Set plotLow and plotHigh
        each(series.points, function (point) {
            var shapeArgs = point.shapeArgs,
                minPointLength = series.options.minPointLength,
                heightDifference,
                height,
                y;
            point.plotHigh = plotHigh = yAxis.translate(point.high, 0, 1, 0, 1);
            point.plotLow = point.plotY;
            // adjust shape
            y = plotHigh;
            height = point.plotY - plotHigh;
            if (height < minPointLength) {
                heightDifference = (minPointLength - height);
                height += heightDifference;
                y -= heightDifference / 2;
            }
            shapeArgs.height = height;
            shapeArgs.y = y;
        });
    },
    trackerGroups: ['group', 'dataLabels'],
    drawGraph: noop,
    pointAttrToOptions: colProto.pointAttrToOptions,
    drawPoints: colProto.drawPoints,
    drawTracker: colProto.drawTracker,
    animate: colProto.animate,
    getColumnMetrics: colProto.getColumnMetrics
});
/*
 * The GaugeSeries class
 */
/**
 * Extend the default options
 */
defaultPlotOptions.gauge = merge(defaultPlotOptions.line, {
    dataLabels: {
        enabled: true,
        y: 15,
        borderWidth: 1,
        borderColor: 'silver',
        borderRadius: 3,
        style: {
            fontWeight: 'bold'
        },
        verticalAlign: 'top',
        zIndex: 2
    },
    dial: {
        // radius: '80%',
        // backgroundColor: 'black',
        // borderColor: 'silver',
        // borderWidth: 0,
        // baseWidth: 3,
        // topWidth: 1,
        // baseLength: '70%' // of radius
        // rearLength: '10%'
    },
    pivot: {
        //radius: 5,
        //borderWidth: 0
        //borderColor: 'silver',
        //backgroundColor: 'black'
    },
    tooltip: {
        headerFormat: ''
    },
    showInLegend: false
});
/**
 * Extend the point object
 */
var GaugePoint = Highcharts.extendClass(Highcharts.Point, {
    /**
     * Don't do any hover colors or anything
     */
    setState: function (state) {
        this.state = state;
    }
});
/**
 * Add the series type
 */
var GaugeSeries = {
    type: 'gauge',
    pointClass: GaugePoint,
    // chart.angular will be set to true when a gauge series is present, and this will
    // be used on the axes
    angular: true,
    drawGraph: noop,
    fixedBox: true,
    trackerGroups: ['group', 'dataLabels'],
    /**
     * Calculate paths etc
     */
    translate: function () {
        var series = this,
            yAxis = series.yAxis,
            options = series.options,
            center = yAxis.center;
        series.generatePoints();
        each(series.points, function (point) {
            var dialOptions = merge(options.dial, point.dial),
                radius = (pInt(pick(dialOptions.radius, 80)) * center[2]) / 200,
                baseLength = (pInt(pick(dialOptions.baseLength, 70)) * radius) / 100,
                rearLength = (pInt(pick(dialOptions.rearLength, 10)) * radius) / 100,
                baseWidth = dialOptions.baseWidth || 3,
                topWidth = dialOptions.topWidth || 1,
                rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true);
            // Handle the wrap option
            if (options.wrap === false) {
                rotation = Math.max(yAxis.startAngleRad, Math.min(yAxis.endAngleRad, rotation));
            }
            rotation = rotation * 180 / Math.PI;
            point.shapeType = 'path';
            point.shapeArgs = {
                d: dialOptions.path || [
                    'M',
                    -rearLength, -baseWidth / 2,
                    'L',
                    baseLength, -baseWidth / 2,
                    radius, -topWidth / 2,
                    radius, topWidth / 2,
                    baseLength, baseWidth / 2,
                    -rearLength, baseWidth / 2,
                    'z'
                ],
                translateX: center[0],
                translateY: center[1],
                rotation: rotation
            };
            // Positions for data label
            point.plotX = center[0];
            point.plotY = center[1];
        });
    },
    /**
     * Draw the points where each point is one needle
     */
    drawPoints: function () {
        var series = this,
            center = series.yAxis.center,
            pivot = series.pivot,
            options = series.options,
            pivotOptions = options.pivot,
            renderer = series.chart.renderer;
        each(series.points, function (point) {
            var graphic = point.graphic,
                shapeArgs = point.shapeArgs,
                d = shapeArgs.d,
                dialOptions = merge(options.dial, point.dial); // #1233
            if (graphic) {
                graphic.animate(shapeArgs);
                shapeArgs.d = d; // animate alters it
            } else {
                point.graphic = renderer[point.shapeType](shapeArgs)
                    .attr({
                        stroke: dialOptions.borderColor || 'none',
                        'stroke-width': dialOptions.borderWidth || 0,
                        fill: dialOptions.backgroundColor || 'black',
                        rotation: shapeArgs.rotation // required by VML when animation is false
                    })
                    .add(series.group);
            }
        });
        // Add or move the pivot
        if (pivot) {
            pivot.animate({ // #1235
                translateX: center[0],
                translateY: center[1]
            });
        } else {
            series.pivot = renderer.circle(0, 0, pick(pivotOptions.radius, 5))
                .attr({
                    'stroke-width': pivotOptions.borderWidth || 0,
                    stroke: pivotOptions.borderColor || 'silver',
                    fill: pivotOptions.backgroundColor || 'black'
                })
                .translate(center[0], center[1])
                .add(series.group);
        }
    },
    /**
     * Animate the arrow up from startAngle
     */
    animate: function (init) {
        var series = this;
        if (!init) {
            each(series.points, function (point) {
                var graphic = point.graphic;
                if (graphic) {
                    // start value
                    graphic.attr({
                        rotation: series.yAxis.startAngleRad * 180 / Math.PI
                    });
                    // animate
                    graphic.animate({
                        rotation: point.shapeArgs.rotation
                    }, series.options.animation);
                }
            });
            // delete this function to allow it only once
            series.animate = null;
        }
    },
    render: function () {
        this.group = this.plotGroup(
            'group',
            'series',
            this.visible ? 'visible' : 'hidden',
            this.options.zIndex,
            this.chart.seriesGroup
        );
        seriesTypes.pie.prototype.render.call(this);
        this.group.clip(this.chart.clipRect);
    },
    setData: seriesTypes.pie.prototype.setData,
    drawTracker: seriesTypes.column.prototype.drawTracker
};
seriesTypes.gauge = Highcharts.extendClass(seriesTypes.line, GaugeSeries);/* ****************************************************************************
 * Start Box plot series code                                                  *
 *****************************************************************************/
// Set default options
defaultPlotOptions.boxplot = merge(defaultPlotOptions.column, {
    fillColor: '#FFFFFF',
    lineWidth: 1,
    //medianColor: null,
    medianWidth: 2,
    states: {
        hover: {
            brightness: -0.3
        }
    },
    //stemColor: null,
    //stemDashStyle: 'solid'
    //stemWidth: null,
    threshold: null,
    tooltip: {
        pointFormat: '<span style="color:{series.color};font-weight:bold">{series.name}</span><br/>' +
            'Maximum: {point.high}<br/>' +
            'Upper quartile: {point.q3}<br/>' +
            'Median: {point.median}<br/>' +
            'Lower quartile: {point.q1}<br/>' +
            'Minimum: {point.low}<br/>'
    },
    //whiskerColor: null,
    whiskerLength: '50%',
    whiskerWidth: 2
});
// Create the series object
seriesTypes.boxplot = extendClass(seriesTypes.column, {
    type: 'boxplot',
    pointArrayMap: ['low', 'q1', 'median', 'q3', 'high'], // array point configs are mapped to this
    toYData: function (point) { // return a plain array for speedy calculation
        return [point.low, point.q1, point.median, point.q3, point.high];
    },
    pointValKey: 'high', // defines the top of the tracker
    /**
     * One-to-one mapping from options to SVG attributes
     */
    pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
        fill: 'fillColor',
        stroke: 'color',
        'stroke-width': 'lineWidth'
    },
    /**
     * Disable data labels for box plot
     */
    drawDataLabels: noop,
    /**
     * Translate data points from raw values x and y to plotX and plotY
     */
    translate: function () {
        var series = this,
            yAxis = series.yAxis,
            pointArrayMap = series.pointArrayMap;
        seriesTypes.column.prototype.translate.apply(series);
        // do the translation on each point dimension
        each(series.points, function (point) {
            each(pointArrayMap, function (key) {
                if (point[key] !== null) {
                    point[key + 'Plot'] = yAxis.translate(point[key], 0, 1, 0, 1);
                }
            });
        });
    },
    /**
     * Draw the data points
     */
    drawPoints: function () {
        var series = this,  //state = series.state,
            points = series.points,
            options = series.options,
            chart = series.chart,
            renderer = chart.renderer,
            pointAttr,
            q1Plot,
            q3Plot,
            highPlot,
            lowPlot,
            medianPlot,
            crispCorr,
            crispX,
            graphic,
            stemPath,
            stemAttr,
            boxPath,
            whiskersPath,
            whiskersAttr,
            medianPath,
            medianAttr,
            width,
            left,
            right,
            halfWidth,
            shapeArgs,
            color,
            doQuartiles = series.doQuartiles !== false, // error bar inherits this series type but doesn't do quartiles
            whiskerLength = parseInt(series.options.whiskerLength, 10) / 100;
        each(points, function (point) {
            graphic = point.graphic;
            shapeArgs = point.shapeArgs; // the box
            stemAttr = {};
            whiskersAttr = {};
            medianAttr = {};
            color = point.color || series.color;
            if (point.plotY !== UNDEFINED) {
                pointAttr = point.pointAttr[point.selected ? 'selected' : ''];
                // crisp vector coordinates
                width = shapeArgs.width;
                left = mathFloor(shapeArgs.x);
                right = left + width;
                halfWidth = mathRound(width / 2);
                //crispX = mathRound(left + halfWidth) + crispCorr;
                q1Plot = mathFloor(doQuartiles ? point.q1Plot : point.lowPlot);// + crispCorr;
                q3Plot = mathFloor(doQuartiles ? point.q3Plot : point.lowPlot);// + crispCorr;
                highPlot = mathFloor(point.highPlot);// + crispCorr;
                lowPlot = mathFloor(point.lowPlot);// + crispCorr;
                // Stem attributes
                stemAttr.stroke = point.stemColor || options.stemColor || color;
                stemAttr['stroke-width'] = pick(point.stemWidth, options.stemWidth, options.lineWidth);
                stemAttr.dashstyle = point.stemDashStyle || options.stemDashStyle;
                // Whiskers attributes
                whiskersAttr.stroke = point.whiskerColor || options.whiskerColor || color;
                whiskersAttr['stroke-width'] = pick(point.whiskerWidth, options.whiskerWidth, options.lineWidth);
                // Median attributes
                medianAttr.stroke = point.medianColor || options.medianColor || color;
                medianAttr['stroke-width'] = pick(point.medianWidth, options.medianWidth, options.lineWidth);
                // The stem
                crispCorr = (stemAttr['stroke-width'] % 2) / 2;
                crispX = left + halfWidth + crispCorr;
                stemPath = [
                    // stem up
                    'M',
                    crispX, q3Plot,
                    'L',
                    crispX, highPlot,
                    // stem down
                    'M',
                    crispX, q1Plot,
                    'L',
                    crispX, lowPlot,
                    'z'
                ];
                // The box
                if (doQuartiles) {
                    crispCorr = (pointAttr['stroke-width'] % 2) / 2;
                    crispX = mathFloor(crispX) + crispCorr;
                    q1Plot = mathFloor(q1Plot) + crispCorr;
                    q3Plot = mathFloor(q3Plot) + crispCorr;
                    left += crispCorr;
                    right += crispCorr;
                    boxPath = [
                        'M',
                        left, q3Plot,
                        'L',
                        left, q1Plot,
                        'L',
                        right, q1Plot,
                        'L',
                        right, q3Plot,
                        'L',
                        left, q3Plot,
                        'z'
                    ];
                }
                // The whiskers
                if (whiskerLength) {
                    crispCorr = (whiskersAttr['stroke-width'] % 2) / 2;
                    highPlot = highPlot + crispCorr;
                    lowPlot = lowPlot + crispCorr;
                    whiskersPath = [
                        // High whisker
                        'M',
                        crispX - halfWidth * whiskerLength,
                        highPlot,
                        'L',
                        crispX + halfWidth * whiskerLength,
                        highPlot,
                        // Low whisker
                        'M',
                        crispX - halfWidth * whiskerLength,
                        lowPlot,
                        'L',
                        crispX + halfWidth * whiskerLength,
                        lowPlot
                    ];
                }
                // The median
                crispCorr = (medianAttr['stroke-width'] % 2) / 2;
                medianPlot = mathRound(point.medianPlot) + crispCorr;
                medianPath = [
                    'M',
                    left,
                    medianPlot,
                    'L',
                    right,
                    medianPlot,
                    'z'
                ];
                // Create or update the graphics
                if (graphic) { // update
                    point.stem.animate({ d: stemPath });
                    if (whiskerLength) {
                        point.whiskers.animate({ d: whiskersPath });
                    }
                    if (doQuartiles) {
                        point.box.animate({ d: boxPath });
                    }
                    point.medianShape.animate({ d: medianPath });
                } else { // create new
                    point.graphic = graphic = renderer.g()
                        .add(series.group);
                    point.stem = renderer.path(stemPath)
                        .attr(stemAttr)
                        .add(graphic);
                    if (whiskerLength) {
                        point.whiskers = renderer.path(whiskersPath)
                            .attr(whiskersAttr)
                            .add(graphic);
                    }
                    if (doQuartiles) {
                        point.box = renderer.path(boxPath)
                            .attr(pointAttr)
                            .add(graphic);
                    }
                    point.medianShape = renderer.path(medianPath)
                        .attr(medianAttr)
                        .add(graphic);
                }
            }
        });
    }
});
/* ****************************************************************************
 * End Box plot series code                                                *
 *****************************************************************************/
/* ****************************************************************************
 * Start error bar series code                                                *
 *****************************************************************************/
// 1 - set default options
defaultPlotOptions.errorbar = merge(defaultPlotOptions.boxplot, {
    color: '#000000',
    grouping: false,
    linkedTo: ':previous',
    tooltip: {
        pointFormat: defaultPlotOptions.arearange.tooltip.pointFormat
    },
    whiskerWidth: null
});
// 2 - Create the series object
seriesTypes.errorbar = extendClass(seriesTypes.boxplot, {
    type: 'errorbar',
    pointArrayMap: ['low', 'high'], // array point configs are mapped to this
    toYData: function (point) { // return a plain array for speedy calculation
        return [point.low, point.high];
    },
    pointValKey: 'high', // defines the top of the tracker
    doQuartiles: false,
    /**
     * Get the width and X offset, either on top of the linked series column
     * or standalone
     */
    getColumnMetrics: function () {
        return (this.linkedParent && this.linkedParent.columnMetrics) ||
            seriesTypes.column.prototype.getColumnMetrics.call(this);
    }
});
/* ****************************************************************************
 * End error bar series code                                                  *
 *****************************************************************************/
/* ****************************************************************************
 * Start Waterfall series code                                                *
 *****************************************************************************/
// 1 - set default options
defaultPlotOptions.waterfall = merge(defaultPlotOptions.column, {
    lineWidth: 1,
    lineColor: '#333',
    dashStyle: 'dot',
    borderColor: '#333'
});
// 2 - Create the series object
seriesTypes.waterfall = extendClass(seriesTypes.column, {
    type: 'waterfall',
    upColorProp: 'fill',
    pointArrayMap: ['low', 'y'],
    pointValKey: 'y',
    /**
     * Init waterfall series, force stacking
     */
    init: function (chart, options) {
        // force stacking
        options.stacking = true;
        seriesTypes.column.prototype.init.call(this, chart, options);
    },
    /**
     * Translate data points from raw values
     */
    translate: function () {
        var series = this,
            options = series.options,
            axis = series.yAxis,
            len,
            i,
            points,
            point,
            shapeArgs,
            stack,
            y,
            previousY,
            stackPoint,
            threshold = options.threshold,
            crispCorr = (options.borderWidth % 2) / 2;
        // run column series translate
        seriesTypes.column.prototype.translate.apply(this);
        previousY = threshold;
        points = series.points;
        for (i = 0, len = points.length; i < len; i++) {
            // cache current point object
            point = points[i];
            shapeArgs = point.shapeArgs;
            // get current stack
            stack = series.getStack(i);
            stackPoint = stack.points[series.index];
            // override point value for sums
            if (isNaN(point.y)) {
                point.y = series.yData[i];
            }
            // up points
            y = mathMax(previousY, previousY + point.y) + stackPoint[0];
            shapeArgs.y = axis.translate(y, 0, 1);
            // sum points
            if (point.isSum || point.isIntermediateSum) {
                shapeArgs.y = axis.translate(stackPoint[1], 0, 1);
                shapeArgs.height = axis.translate(stackPoint[0], 0, 1) - shapeArgs.y;
            // if it's not the sum point, update previous stack end position
            } else {
                previousY += stack.total;
            }
            // negative points
            if (shapeArgs.height < 0) {
                shapeArgs.y += shapeArgs.height;
                shapeArgs.height *= -1;
            }
            point.plotY = shapeArgs.y = mathRound(shapeArgs.y) - crispCorr;
            shapeArgs.height = mathRound(shapeArgs.height);
            point.yBottom = shapeArgs.y + shapeArgs.height;
        }
    },
    /**
     * Call default processData then override yData to reflect waterfall's extremes on yAxis
     */
    processData: function (force) {
        var series = this,
            options = series.options,
            yData = series.yData,
            points = series.points,
            point,
            dataLength = yData.length,
            threshold = options.threshold || 0,
            subSum,
            sum,
            dataMin,
            dataMax,
            y,
            i;
        sum = subSum = dataMin = dataMax = threshold;
        for (i = 0; i < dataLength; i++) {
            y = yData[i];
            point = points && points[i] ? points[i] : {};
            if (y === "sum" || point.isSum) {
                yData[i] = sum;
            } else if (y === "intermediateSum" || point.isIntermediateSum) {
                yData[i] = subSum;
                subSum = threshold;
            } else {
                sum += y;
                subSum += y;
            }
            dataMin = Math.min(sum, dataMin);
            dataMax = Math.max(sum, dataMax);
        }
        Series.prototype.processData.call(this, force);
        // Record extremes
        series.dataMin = dataMin;
        series.dataMax = dataMax;
    },
    /**
     * Return y value or string if point is sum
     */
    toYData: function (pt) {
        if (pt.isSum) {
            return "sum";
        } else if (pt.isIntermediateSum) {
            return "intermediateSum";
        }
        return pt.y;
    },
    /**
     * Postprocess mapping between options and SVG attributes
     */
    getAttribs: function () {
        seriesTypes.column.prototype.getAttribs.apply(this, arguments);
        var series = this,
            options = series.options,
            stateOptions = options.states,
            upColor = options.upColor || series.color,
            hoverColor = Highcharts.Color(upColor).brighten(0.1).get(),
            seriesDownPointAttr = merge(series.pointAttr),
            upColorProp = series.upColorProp;
        seriesDownPointAttr[''][upColorProp] = upColor;
        seriesDownPointAttr.hover[upColorProp] = stateOptions.hover.upColor || hoverColor;
        seriesDownPointAttr.select[upColorProp] = stateOptions.select.upColor || upColor;
        each(series.points, function (point) {
            if (point.y > 0 && !point.color) {
                point.pointAttr = seriesDownPointAttr;
                point.color = upColor;
            }
        });
    },
    /**
     * Draw columns' connector lines
     */
    getGraphPath: function () {
        var data = this.data,
            length = data.length,
            lineWidth = this.options.lineWidth + this.options.borderWidth,
            normalizer = mathRound(lineWidth) % 2 / 2,
            path = [],
            M = 'M',
            L = 'L',
            prevArgs,
            pointArgs,
            i,
            d;
        for (i = 1; i < length; i++) {
            pointArgs = data[i].shapeArgs;
            prevArgs = data[i - 1].shapeArgs;
            d = [
                M,
                prevArgs.x + prevArgs.width, prevArgs.y + normalizer,
                L,
                pointArgs.x, prevArgs.y + normalizer
            ];
            if (data[i - 1].y < 0) {
                d[2] += prevArgs.height;
                d[5] += prevArgs.height;
            }
            path = path.concat(d);
        }
        return path;
    },
    /**
     * Extremes are recorded in processData
     */
    getExtremes: noop,
    /**
     * Return stack for given index
     */
    getStack: function (i) {
        var axis = this.yAxis,
            stacks = axis.stacks,
            key = this.stackKey;
        if (this.processedYData[i] < this.options.threshold) {
            key = '-' + key;
        }
        return stacks[key][i];
    },
    drawGraph: Series.prototype.drawGraph
});
/* ****************************************************************************
 * End Waterfall series code                                                  *
 *****************************************************************************/
/* ****************************************************************************
 * Start Bubble series code                                                      *
 *****************************************************************************/
// 1 - set default options
defaultPlotOptions.bubble = merge(defaultPlotOptions.scatter, {
    dataLabels: {
        inside: true,
        style: {
            color: 'white',
            textShadow: '0px 0px 3px black'
        },
        verticalAlign: 'middle'
    },
    // displayNegative: true,
    marker: {
        // fillOpacity: 0.5,
        lineColor: null, // inherit from series.color
        lineWidth: 1
    },
    minSize: 8,
    maxSize: '20%',
    // negativeColor: null,
    tooltip: {
        pointFormat: '({point.x}, {point.y}), Size: {point.z}'
    },
    turboThreshold: 0,
    zThreshold: 0
});
// 2 - Create the series object
seriesTypes.bubble = extendClass(seriesTypes.scatter, {
    type: 'bubble',
    pointArrayMap: ['y', 'z'],
    trackerGroups: ['group', 'dataLabelsGroup'],
    /**
     * Mapping between SVG attributes and the corresponding options
     */
    pointAttrToOptions: {
        stroke: 'lineColor',
        'stroke-width': 'lineWidth',
        fill: 'fillColor'
    },
    /**
     * Apply the fillOpacity to all fill positions
     */
    applyOpacity: function (fill) {
        var markerOptions = this.options.marker,
            fillOpacity = pick(markerOptions.fillOpacity, 0.5);
        // When called from Legend.colorizeItem, the fill isn't predefined
        fill = fill || markerOptions.fillColor || this.color;
        if (fillOpacity !== 1) {
            fill = Highcharts.Color(fill).setOpacity(fillOpacity).get('rgba');
        }
        return fill;
    },
    /**
     * Extend the convertAttribs method by applying opacity to the fill
     */
    convertAttribs: function () {
        var obj = Series.prototype.convertAttribs.apply(this, arguments);
        obj.fill = this.applyOpacity(obj.fill);
        return obj;
    },
    /**
     * Get the radius for each point based on the minSize, maxSize and each point's Z value. This
     * must be done prior to Series.translate because the axis needs to add padding in
     * accordance with the point sizes.
     */
    getRadii: function (zMin, zMax, minSize, maxSize) {
        var len,
            i,
            pos,
            zData = this.zData,
            radii = [],
            zRange;
        // Set the shape type and arguments to be picked up in drawPoints
        for (i = 0, len = zData.length; i < len; i++) {
            zRange = zMax - zMin;
            pos = zRange > 0 ? // relative size, a number between 0 and 1
                (zData[i] - zMin) / (zMax - zMin) :
                0.5;
            radii.push(math.ceil(minSize + pos * (maxSize - minSize)) / 2);
        }
        this.radii = radii;
    },
    /**
     * Perform animation on the bubbles
     */
    animate: function (init) {
        var animation = this.options.animation;
        if (!init) { // run the animation
            each(this.points, function (point) {
                var graphic = point.graphic,
                    shapeArgs = point.shapeArgs;
                if (graphic && shapeArgs) {
                    // start values
                    graphic.attr('r', 1);
                    // animate
                    graphic.animate({
                        r: shapeArgs.r
                    }, animation);
                }
            });
            // delete this function to allow it only once
            this.animate = null;
        }
    },
    /**
     * Extend the base translate method to handle bubble size
     */
    translate: function () {
        var i,
            data = this.data,
            point,
            radius,
            radii = this.radii;
        // Run the parent method
        seriesTypes.scatter.prototype.translate.call(this);
        // Set the shape type and arguments to be picked up in drawPoints
        i = data.length;
        while (i--) {
            point = data[i];
            radius = radii ? radii[i] : 0; // #1737
            // Flag for negativeColor to be applied in Series.js
            point.negative = point.z < (this.options.zThreshold || 0);
            if (radius >= this.minPxSize / 2) {
                // Shape arguments
                point.shapeType = 'circle';
                point.shapeArgs = {
                    x: point.plotX,
                    y: point.plotY,
                    r: radius
                };
                // Alignment box for the data label
                point.dlBox = {
                    x: point.plotX - radius,
                    y: point.plotY - radius,
                    width: 2 * radius,
                    height: 2 * radius
                };
            } else { // below zThreshold
                point.shapeArgs = point.plotY = point.dlBox = UNDEFINED; // #1691
            }
        }
    },
    /**
     * Get the series' symbol in the legend
     *
     * @param {Object} legend The legend object
     * @param {Object} item The series (this) or point
     */
    drawLegendSymbol: function (legend, item) {
        var radius = pInt(legend.itemStyle.fontSize) / 2;
        item.legendSymbol = this.chart.renderer.circle(
            radius,
            legend.baseline - radius,
            radius
        ).attr({
            zIndex: 3
        }).add(item.legendGroup);
        item.legendSymbol.isMarker = true;
    },
    drawPoints: seriesTypes.column.prototype.drawPoints,
    alignDataLabel: seriesTypes.column.prototype.alignDataLabel
});
/**
 * Add logic to pad each axis with the amount of pixels
 * necessary to avoid the bubbles to overflow.
 */
Axis.prototype.beforePadding = function () {
    var axis = this,
        axisLength = this.len,
        chart = this.chart,
        pxMin = 0,
        pxMax = axisLength,
        isXAxis = this.isXAxis,
        dataKey = isXAxis ? 'xData' : 'yData',
        min = this.min,
        extremes = {},
        smallestSize = math.min(chart.plotWidth, chart.plotHeight),
        zMin = Number.MAX_VALUE,
        zMax = -Number.MAX_VALUE,
        range = this.max - min,
        transA = axisLength / range,
        activeSeries = [];
    // Handle padding on the second pass, or on redraw
    if (this.tickPositions) {
        each(this.series, function (series) {
            var seriesOptions = series.options,
                zData;
            if (series.type === 'bubble' && series.visible) {
                // Correction for #1673
                axis.allowZoomOutside = true;
                // Cache it
                activeSeries.push(series);
                if (isXAxis) { // because X axis is evaluated first
                    // For each series, translate the size extremes to pixel values
                    each(['minSize', 'maxSize'], function (prop) {
                        var length = seriesOptions[prop],
                            isPercent = /%$/.test(length);
                        length = pInt(length);
                        extremes[prop] = isPercent ?
                            smallestSize * length / 100 :
                            length;
                    });
                    series.minPxSize = extremes.minSize;
                    // Find the min and max Z
                    zData = series.zData;
                    if (zData.length) { // #1735
                        zMin = math.min(
                            zMin,
                            math.max(
                                arrayMin(zData),
                                seriesOptions.displayNegative === false ? seriesOptions.zThreshold : -Number.MAX_VALUE
                            )
                        );
                        zMax = math.max(zMax, arrayMax(zData));
                    }
                }
            }
        });
        each(activeSeries, function (series) {
            var data = series[dataKey],
                i = data.length,
                radius;
            if (isXAxis) {
                series.getRadii(zMin, zMax, extremes.minSize, extremes.maxSize);
            }
            if (range > 0) {
                while (i--) {
                    radius = series.radii[i];
                    pxMin = Math.min(((data[i] - min) * transA) - radius, pxMin);
                    pxMax = Math.max(((data[i] - min) * transA) + radius, pxMax);
                }
            }
        });
        if (activeSeries.length && range > 0 && pick(this.options.min, this.userMin) === UNDEFINED && pick(this.options.max, this.userMax) === UNDEFINED) {
            pxMax -= axisLength;
            transA *= (axisLength + pxMin - pxMax) / axisLength;
            this.min += pxMin / transA;
            this.max += pxMax / transA;
        }
    }
};
/* ****************************************************************************
 * End Bubble series code                                                     *
 *****************************************************************************/
/**
 * Extensions for polar charts. Additionally, much of the geometry required for polar charts is
 * gathered in RadialAxes.js.
 *
 */
var seriesProto = Series.prototype,
    pointerProto = Highcharts.Pointer.prototype;
/**
 * Translate a point's plotX and plotY from the internal angle and radius measures to
 * true plotX, plotY coordinates
 */
seriesProto.toXY = function (point) {
    var xy,
        chart = this.chart,
        plotX = point.plotX,
        plotY = point.plotY;
    // Save rectangular plotX, plotY for later computation
    point.rectPlotX = plotX;
    point.rectPlotY = plotY;
    // Record the angle in degrees for use in tooltip
    point.clientX = ((plotX / Math.PI * 180) + this.xAxis.pane.options.startAngle) % 360;
    // Find the polar plotX and plotY
    xy = this.xAxis.postTranslate(point.plotX, this.yAxis.len - plotY);
    point.plotX = point.polarPlotX = xy.x - chart.plotLeft;
    point.plotY = point.polarPlotY = xy.y - chart.plotTop;
};
/**
 * Order the tooltip points to get the mouse capture ranges correct. #1915.
 */
seriesProto.orderTooltipPoints = function (points) {
    if (this.chart.polar) {
        points.sort(function (a, b) {
            return a.clientX - b.clientX;
        });
        // Wrap mouse tracking around to capture movement on the segment to the left
        // of the north point (#1469, #2093).
        if (points[0]) {
            points[0].wrappedClientX = points[0].clientX + 360;
            points.push(points[0]);
        }
    }
};
/**
 * Add some special init logic to areas and areasplines
 */
function initArea(proceed, chart, options) {
    proceed.call(this, chart, options);
    if (this.chart.polar) {
        /**
         * Overridden method to close a segment path. While in a cartesian plane the area
         * goes down to the threshold, in the polar chart it goes to the center.
         */
        this.closeSegment = function (path) {
            var center = this.xAxis.center;
            path.push(
                'L',
                center[0],
                center[1]
            );
        };
        // Instead of complicated logic to draw an area around the inner area in a stack,
        // just draw it behind
        this.closedStacks = true;
    }
}
wrap(seriesTypes.area.prototype, 'init', initArea);
wrap(seriesTypes.areaspline.prototype, 'init', initArea);
/**
 * Overridden method for calculating a spline from one point to the next
 */
wrap(seriesTypes.spline.prototype, 'getPointSpline', function (proceed, segment, point, i) {
    var ret,
        smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc;
        denom = smoothing + 1,
        plotX,
        plotY,
        lastPoint,
        nextPoint,
        lastX,
        lastY,
        nextX,
        nextY,
        leftContX,
        leftContY,
        rightContX,
        rightContY,
        distanceLeftControlPoint,
        distanceRightControlPoint,
        leftContAngle,
        rightContAngle,
        jointAngle;
    if (this.chart.polar) {
        plotX = point.plotX;
        plotY = point.plotY;
        lastPoint = segment[i - 1];
        nextPoint = segment[i + 1];
        // Connect ends
        if (this.connectEnds) {
            if (!lastPoint) {
                lastPoint = segment[segment.length - 2]; // not the last but the second last, because the segment is already connected
            }
            if (!nextPoint) {
                nextPoint = segment[1];
            }
        }
        // find control points
        if (lastPoint && nextPoint) {
            lastX = lastPoint.plotX;
            lastY = lastPoint.plotY;
            nextX = nextPoint.plotX;
            nextY = nextPoint.plotY;
            leftContX = (smoothing * plotX + lastX) / denom;
            leftContY = (smoothing * plotY + lastY) / denom;
            rightContX = (smoothing * plotX + nextX) / denom;
            rightContY = (smoothing * plotY + nextY) / denom;
            distanceLeftControlPoint = Math.sqrt(Math.pow(leftContX - plotX, 2) + Math.pow(leftContY - plotY, 2));
            distanceRightControlPoint = Math.sqrt(Math.pow(rightContX - plotX, 2) + Math.pow(rightContY - plotY, 2));
            leftContAngle = Math.atan2(leftContY - plotY, leftContX - plotX);
            rightContAngle = Math.atan2(rightContY - plotY, rightContX - plotX);
            jointAngle = (Math.PI / 2) + ((leftContAngle + rightContAngle) / 2);
            // Ensure the right direction, jointAngle should be in the same quadrant as leftContAngle
            if (Math.abs(leftContAngle - jointAngle) > Math.PI / 2) {
                jointAngle -= Math.PI;
            }
            // Find the corrected control points for a spline straight through the point
            leftContX = plotX + Math.cos(jointAngle) * distanceLeftControlPoint;
            leftContY = plotY + Math.sin(jointAngle) * distanceLeftControlPoint;
            rightContX = plotX + Math.cos(Math.PI + jointAngle) * distanceRightControlPoint;
            rightContY = plotY + Math.sin(Math.PI + jointAngle) * distanceRightControlPoint;
            // Record for drawing in next point
            point.rightContX = rightContX;
            point.rightContY = rightContY;
        }
        // moveTo or lineTo
        if (!i) {
            ret = ['M', plotX, plotY];
        } else { // curve from last point to this
            ret = [
                'C',
                lastPoint.rightContX || lastPoint.plotX,
                lastPoint.rightContY || lastPoint.plotY,
                leftContX || plotX,
                leftContY || plotY,
                plotX,
                plotY
            ];
            lastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later
        }
    } else {
        ret = proceed.call(this, segment, point, i);
    }
    return ret;
});
/**
 * Extend translate. The plotX and plotY values are computed as if the polar chart were a
 * cartesian plane, where plotX denotes the angle in radians and (yAxis.len - plotY) is the pixel distance from
 * center.
 */
wrap(seriesProto, 'translate', function (proceed) {
    // Run uber method
    proceed.call(this);
    // Postprocess plot coordinates
    if (this.chart.polar && !this.preventPostTranslate) {
        var points = this.points,
            i = points.length;
        while (i--) {
            // Translate plotX, plotY from angle and radius to true plot coordinates
            this.toXY(points[i]);
        }
    }
});
/**
 * Extend getSegmentPath to allow connecting ends across 0 to provide a closed circle in
 * line-like series.
 */
wrap(seriesProto, 'getSegmentPath', function (proceed, segment) {
    var points = this.points;
    // Connect the path
    if (this.chart.polar && this.options.connectEnds !== false &&
            segment[segment.length - 1] === points[points.length - 1] && points[0].y !== null) {
        this.connectEnds = true; // re-used in splines
        segment = [].concat(segment, [points[0]]);
    }
    // Run uber method
    return proceed.call(this, segment);
});
function polarAnimate(proceed, init) {
    var chart = this.chart,
        animation = this.options.animation,
        group = this.group,
        markerGroup = this.markerGroup,
        center = this.xAxis.center,
        plotLeft = chart.plotLeft,
        plotTop = chart.plotTop,
        attribs;
    // Specific animation for polar charts
    if (chart.polar) {
        // Enable animation on polar charts only in SVG. In VML, the scaling is different, plus animation
        // would be so slow it would't matter.
        if (chart.renderer.isSVG) {
            if (animation === true) {
                animation = {};
            }
            // Initialize the animation
            if (init) {
                // Scale down the group and place it in the center
                attribs = {
                    translateX: center[0] + plotLeft,
                    translateY: center[1] + plotTop,
                    scaleX: 0.001, // #1499
                    scaleY: 0.001
                };
                group.attr(attribs);
                if (markerGroup) {
                    markerGroup.attrSetters = group.attrSetters;
                    markerGroup.attr(attribs);
                }
            // Run the animation
            } else {
                attribs = {
                    translateX: plotLeft,
                    translateY: plotTop,
                    scaleX: 1,
                    scaleY: 1
                };
                group.animate(attribs, animation);
                if (markerGroup) {
                    markerGroup.animate(attribs, animation);
                }
                // Delete this function to allow it only once
                this.animate = null;
            }
        }
    // For non-polar charts, revert to the basic animation
    } else {
        proceed.call(this, init);
    }
}
// Define the animate method for both regular series and column series and their derivatives
wrap(seriesProto, 'animate', polarAnimate);
wrap(colProto, 'animate', polarAnimate);
/**
 * Throw in a couple of properties to let setTooltipPoints know we're indexing the points
 * in degrees (0-360), not plot pixel width.
 */
wrap(seriesProto, 'setTooltipPoints', function (proceed, renew) {
    if (this.chart.polar) {
        extend(this.xAxis, {
            tooltipLen: 360 // degrees are the resolution unit of the tooltipPoints array
        });
    }
    // Run uber method
    return proceed.call(this, renew);
});
/**
 * Extend the column prototype's translate method
 */
wrap(colProto, 'translate', function (proceed) {
    var xAxis = this.xAxis,
        len = this.yAxis.len,
        center = xAxis.center,
        startAngleRad = xAxis.startAngleRad,
        renderer = this.chart.renderer,
        start,
        points,
        point,
        i;
    this.preventPostTranslate = true;
    // Run uber method
    proceed.call(this);
    // Postprocess plot coordinates
    if (xAxis.isRadial) {
        points = this.points;
        i = points.length;
        while (i--) {
            point = points[i];
            start = point.barX + startAngleRad;
            point.shapeType = 'path';
            point.shapeArgs = {
                d: renderer.symbols.arc(
                    center[0],
                    center[1],
                    len - point.plotY,
                    null,
                    {
                        start: start,
                        end: start + point.pointWidth,
                        innerR: len - pick(point.yBottom, len)
                    }
                )
            };
            this.toXY(point); // provide correct plotX, plotY for tooltip
        }
    }
});
/**
 * Align column data labels outside the columns. #1199.
 */
wrap(colProto, 'alignDataLabel', function (proceed, point, dataLabel, options, alignTo, isNew) {
    if (this.chart.polar) {
        var angle = point.rectPlotX / Math.PI * 180,
            align,
            verticalAlign;
        // Align nicely outside the perimeter of the columns
        if (options.align === null) {
            if (angle > 20 && angle < 160) {
                align = 'left'; // right hemisphere
            } else if (angle > 200 && angle < 340) {
                align = 'right'; // left hemisphere
            } else {
                align = 'center'; // top or bottom
            }
            options.align = align;
        }
        if (options.verticalAlign === null) {
            if (angle < 45 || angle > 315) {
                verticalAlign = 'bottom'; // top part
            } else if (angle > 135 && angle < 225) {
                verticalAlign = 'top'; // bottom part
            } else {
                verticalAlign = 'middle'; // left or right
            }
            options.verticalAlign = verticalAlign;
        }
        seriesProto.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
    } else {
        proceed.call(this, point, dataLabel, options, alignTo, isNew);
    }
});
/**
 * Extend the mouse tracker to return the tooltip position index in terms of
 * degrees rather than pixels
 */
wrap(pointerProto, 'getIndex', function (proceed, e) {
    var ret,
        chart = this.chart,
        center,
        x,
        y;
    if (chart.polar) {
        center = chart.xAxis[0].center;
        x = e.chartX - center[0] - chart.plotLeft;
        y = e.chartY - center[1] - chart.plotTop;
        ret = 180 - Math.round(Math.atan2(x, y) / Math.PI * 180);
    } else {
        // Run uber method
        ret = proceed.call(this, e);
    }
    return ret;
});
/**
 * Extend getCoordinates to prepare for polar axis values
 */
wrap(pointerProto, 'getCoordinates', function (proceed, e) {
    var chart = this.chart,
        ret = {
            xAxis: [],
            yAxis: []
        };
    if (chart.polar) {
        each(chart.axes, function (axis) {
            var isXAxis = axis.isXAxis,
                center = axis.center,
                x = e.chartX - center[0] - chart.plotLeft,
                y = e.chartY - center[1] - chart.plotTop;
            ret[isXAxis ? 'xAxis' : 'yAxis'].push({
                axis: axis,
                value: axis.translate(
                    isXAxis ?
                        Math.PI - Math.atan2(x, y) : // angle
                        Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), // distance from center
                    true
                )
            });
        });
    } else {
        ret = proceed.call(this, e);
    }
    return ret;
});
}(Highcharts));
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts.js
New file
@@ -0,0 +1,283 @@
/*
 Highcharts JS v3.0.6 (2013-10-04)
 (c) 2009-2013 Torstein Hønsi
 License: www.highcharts.com/license
*/
(function(){function r(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function x(){var a,b=arguments.length,c={},d=function(a,b){var c,h;typeof a!=="object"&&(a={});for(h in b)b.hasOwnProperty(h)&&(c=b[h],a[h]=c&&typeof c==="object"&&Object.prototype.toString.call(c)!=="[object Array]"&&typeof c.nodeType!=="number"?d(a[h]||{},c):b[h]);return a};for(a=0;a<b;a++)c=d(c,arguments[a]);return c}function C(a,b){return parseInt(a,b||10)}function ea(a){return typeof a==="string"}function T(a){return typeof a===
"object"}function Ia(a){return Object.prototype.toString.call(a)==="[object Array]"}function sa(a){return typeof a==="number"}function na(a){return R.log(a)/R.LN10}function fa(a){return R.pow(10,a)}function ga(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function u(a){return a!==w&&a!==null}function v(a,b,c){var d,e;if(ea(b))u(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(u(b)&&T(b))for(d in b)a.setAttribute(d,b[d]);return e}function ja(a){return Ia(a)?
a:[a]}function o(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!=="undefined"&&c!==null)return c}function K(a,b){if(ta&&b&&b.opacity!==w)b.filter="alpha(opacity="+b.opacity*100+")";r(a.style,b)}function U(a,b,c,d,e){a=y.createElement(a);b&&r(a,b);e&&K(a,{padding:0,border:S,margin:0});c&&K(a,c);d&&d.appendChild(a);return a}function ha(a,b){var c=function(){};c.prototype=new a;r(c.prototype,b);return c}function Aa(a,b,c,d){var e=M.lang,a=+a||0,f=b===-1?(a.toString().split(".")[1]||
"").length:isNaN(b=N(b))?2:b,b=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=a<0?"-":"",c=String(C(a=N(a).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:"")+c.substr(g).replace(/(\d{3})(?=\d)/g,"$1"+d)+(f?b+N(a-c).toFixed(f).slice(2):"")}function Ba(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function mb(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);a.unshift(d);return c.apply(this,a)}}function Ca(a,b){for(var c="{",d=!1,
e,f,g,h,i,j=[];(c=a.indexOf(c))!==-1;){e=a.slice(0,c);if(d){f=e.split(":");g=f.shift().split(".");i=g.length;e=b;for(h=0;h<i;h++)e=e[g[h]];if(f.length)f=f.join(":"),g=/\.([0-9])/,h=M.lang,i=void 0,/f$/.test(f)?(i=(i=f.match(g))?i[1]:-1,e=Aa(e,i,h.decimalPoint,f.indexOf(",")>-1?h.thousandsSep:"")):e=Xa(f,e)}j.push(e);a=a.slice(c+1);c=(d=!d)?"}":"{"}j.push(a);return j.join("")}function nb(a){return R.pow(10,P(R.log(a)/R.LN10))}function ob(a,b,c,d){var e,c=o(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===
!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function Cb(a,b){var c=b||[[Db,[1,2,5,10,20,25,50,100,200,500]],[pb,[1,2,5,10,15,30]],[Ya,[1,2,5,10,15,30]],[Qa,[1,2,3,4,6,8,12]],[ua,[1,2]],[Za,[1,2]],[Ra,[1,2,3,4,6]],[Da,null]],d=c[c.length-1],e=D[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d=c[g],e=D[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+D[c[g+1][0]])/2)break;e===D[Da]&&a<5*e&&(f=[1,2,5]);c=ob(a/e,f,d[0]===Da?nb(a/e):1);
return{unitRange:e,count:c,unitName:d[0]}}function Eb(a,b,c,d){var e=[],f={},g=M.global.useUTC,h,i=new Date(b),j=a.unitRange,k=a.count;if(u(b)){j>=D[pb]&&(i.setMilliseconds(0),i.setSeconds(j>=D[Ya]?0:k*P(i.getSeconds()/k)));if(j>=D[Ya])i[Fb](j>=D[Qa]?0:k*P(i[qb]()/k));if(j>=D[Qa])i[Gb](j>=D[ua]?0:k*P(i[rb]()/k));if(j>=D[ua])i[sb](j>=D[Ra]?1:k*P(i[Sa]()/k));j>=D[Ra]&&(i[Hb](j>=D[Da]?0:k*P(i[$a]()/k)),h=i[ab]());j>=D[Da]&&(h-=h%k,i[Ib](h));if(j===D[Za])i[sb](i[Sa]()-i[tb]()+o(d,1));b=1;h=i[ab]();for(var d=
i.getTime(),l=i[$a](),m=i[Sa](),p=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;d<c;)e.push(d),j===D[Da]?d=bb(h+b*k,0):j===D[Ra]?d=bb(h,l+b*k):!g&&(j===D[ua]||j===D[Za])?d=bb(h,l,m+b*k*(j===D[ua]?1:7)):d+=j*k,b++;e.push(d);n(ub(e,function(a){return j<=D[Qa]&&a%D[ua]===p}),function(a){f[a]=ua})}e.info=r(a,{higherRanks:f,totalRange:j*k});return e}function Jb(){this.symbol=this.color=0}function Kb(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0?a.ss_i-c.ss_i:
d});for(e=0;e<c;e++)delete a[e].ss_i}function Ja(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function va(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Ka(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Ta(a){cb||(cb=U(Ea));a&&cb.appendChild(a);cb.innerHTML=""}function ka(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else O.console&&console.log(c)}function ia(a){return parseFloat(a.toPrecision(14))}
function La(a,b){Fa=o(a,b.animation)}function Lb(){var a=M.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";bb=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,o(c,1),o(g,0),o(h,0),o(i,0))).getTime()};qb=b+"Minutes";rb=b+"Hours";tb=b+"Day";Sa=b+"Date";$a=b+"Month";ab=b+"FullYear";Fb=c+"Minutes";Gb=c+"Hours";sb=c+"Date";Hb=c+"Month";Ib=c+"FullYear"}function wa(){}function Ma(a,b,c,d){this.axis=a;this.pos=b;this.type=c||"";this.isNew=!0;!c&&!d&&this.addLabel()}function vb(a,b){this.axis=a;if(b)this.options=
b,this.id=b.id}function Mb(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.total=null;this.points={};this.stack=e;this.percent=f==="percent";this.alignOptions={align:b.align||(g?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(g?"middle":c?"bottom":"top"),y:o(b.y,g?4:c?14:-6),x:o(b.x,g?c?-6:6:0)};this.textAlign=b.textAlign||(g?c?"right":"left":"center")}function db(){this.init.apply(this,arguments)}function wb(){this.init.apply(this,arguments)}
function xb(a,b){this.init(a,b)}function eb(a,b){this.init(a,b)}function yb(){this.init.apply(this,arguments)}var w,y=document,O=window,R=Math,t=R.round,P=R.floor,xa=R.ceil,s=R.max,I=R.min,N=R.abs,V=R.cos,ca=R.sin,ya=R.PI,Ua=ya*2/360,oa=navigator.userAgent,Nb=O.opera,ta=/msie/i.test(oa)&&!Nb,fb=y.documentMode===8,gb=/AppleWebKit/.test(oa),hb=/Firefox/.test(oa),Ob=/(Mobile|Android|Windows Phone)/.test(oa),za="http://www.w3.org/2000/svg",Z=!!y.createElementNS&&!!y.createElementNS(za,"svg").createSVGRect,
Ub=hb&&parseInt(oa.split("Firefox/")[1],10)<4,$=!Z&&!ta&&!!y.createElement("canvas").getContext,Va,ib=y.documentElement.ontouchstart!==w,Pb={},zb=0,cb,M,Xa,Fa,Ab,D,pa=function(){},Ga=[],Ea="div",S="none",Qb="rgba(192,192,192,"+(Z?1.0E-4:0.002)+")",Db="millisecond",pb="second",Ya="minute",Qa="hour",ua="day",Za="week",Ra="month",Da="year",Rb="stroke-width",bb,qb,rb,tb,Sa,$a,ab,Fb,Gb,sb,Hb,Ib,W={};O.Highcharts=O.Highcharts?ka(16,!0):{};Xa=function(a,b,c){if(!u(b)||isNaN(b))return"Invalid date";var a=
o(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[rb](),g=d[tb](),h=d[Sa](),i=d[$a](),j=d[ab](),k=M.lang,l=k.weekdays,d=r({a:l[g].substr(0,3),A:l[g],d:Ba(h),e:h,b:k.shortMonths[i],B:k.months[i],m:Ba(i+1),y:j.toString().substr(2,2),Y:j,H:Ba(f),I:Ba(f%12||12),l:f%12||12,M:Ba(d[qb]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:Ba(d.getSeconds()),L:Ba(t(b%1E3),3)},Highcharts.dateFormats);for(e in d)for(;a.indexOf("%"+e)!==-1;)a=a.replace("%"+e,typeof d[e]==="function"?d[e](b):d[e]);return c?a.substr(0,1).toUpperCase()+
a.substr(1):a};Jb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};D=function(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}(Db,1,pb,1E3,Ya,6E4,Qa,36E5,ua,864E5,Za,6048E5,Ra,26784E5,Da,31556952E3);Ab={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]==="M"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&
(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<=c.length/f&&b.length===c.length)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}};
(function(a){O.HighchartsAdapter=O.HighchartsAdapter||a&&{init:function(b){var c=a.fx,d=c.step,e,f=a.Tween,g=f&&f.propHooks;e=a.cssHooks.opacity;a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});a.each(["cur","_default","width","height","opacity"],function(a,b){var e=d,k,l;b==="cur"?e=c.prototype:b==="_default"&&f&&(e=g[b],b="set");(k=e[b])&&(e[b]=function(c){c=a?c:this;if(c.prop!=="align")return l=c.elem,l.attr?l.attr(c.prop,b==="cur"?w:c.now):k.apply(this,arguments)})});
mb(e,"get",function(a,b,c){return b.attr?b.opacity||0:a.call(this,b,c)});e=function(a){var c=a.elem,d;if(!a.started)d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0;c.attr("d",b.step(a.start,a.end,a.pos,c.toD))};f?g.d={set:e}:d.d=e;this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c};a.fn.highcharts=function(){var a="Chart",b=arguments,c,d;ea(b[0])&&(a=b[0],b=Array.prototype.slice.call(b,
1));c=b[0];if(c!==w)c.chart=c.chart||{},c.chart.renderTo=this[0],new Highcharts[a](c,b[1]),d=this;c===w&&(d=Ga[v(this[0],"data-highcharts-chart")]);return d}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;e<f;e++)d[e]=c.call(a[e],a[e],e,a);return d},offset:function(b){return a(b).offset()},addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=y.removeEventListener?"removeEventListener":
"detachEvent";y[e]&&b&&!b[e]&&(b[e]=function(){});a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var f=a.Event(c),g="detached"+c,h;!ta&&d&&(delete d.layerX,delete d.layerY);r(f,d);b[c]&&(b[g]=b[c],b[c]=null);a.each(["preventDefault","stopPropagation"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){b==="preventDefault"&&(h=!0)}}});a(b).trigger(f);b[g]&&(b[c]=b[g],b[g]=null);e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;if(c.pageX===w)c.pageX=
a.pageX,c.pageY=a.pageY;return c},animate:function(b,c,d){var e=a(b);if(!b.style)b.style={};if(c.d)b.toD=c.d,c.d=1;e.stop();c.opacity!==w&&b.attr&&(c.opacity+="px");e.animate(c,d)},stop:function(b){a(b).stop()}}})(O.jQuery);var X=O.HighchartsAdapter,G=X||{};X&&X.init.call(X,Ab);var jb=G.adapterRun,Vb=G.getScript,qa=G.inArray,n=G.each,ub=G.grep,Wb=G.offset,Na=G.map,J=G.addEvent,aa=G.removeEvent,z=G.fireEvent,Xb=G.washMouseEvent,Bb=G.animate,Wa=G.stop,G={enabled:!0,x:0,y:15,style:{color:"#666",cursor:"default",
fontSize:"11px",lineHeight:"14px"}};M={colors:"#2f7ed8,#0d233a,#8bbc21,#910000,#1aadce,#492970,#f28f43,#77a1e5,#c42525,#a6c96a".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),decimalPoint:".",
numericSymbols:"k,M,G,T,P,E".split(","),resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/3.0.6/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/3.0.6/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:5,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],style:{fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',
fontSize:"12px"},backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",margin:15,style:{color:"#274b6d",fontSize:"16px"}},subtitle:{text:"",align:"center",style:{color:"#4d759e"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0},select:{fillColor:"#FFFFFF",
lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:x(G,{align:"center",enabled:!1,formatter:function(){return this.y===null?"":Aa(this.y,-1)},verticalAlign:"bottom",y:0}),cropThreshold:300,pointRange:0,showInLegend:!0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:"absolute",color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderWidth:1,borderColor:"#909090",borderRadius:5,navigation:{activeColor:"#274b6d",
inactiveColor:"#CCC"},shadow:!1,itemStyle:{cursor:"pointer",color:"#274b6d",fontSize:"12px"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:"absolute",width:"13px",height:"13px"},symbolWidth:16,symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold",position:"relative",top:"1em"},style:{position:"absolute",backgroundColor:"white",opacity:0.5,textAlign:"center"}},tooltip:{enabled:!0,animation:Z,
backgroundColor:"rgba(255, 255, 255, .85)",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',shadow:!0,snap:Ob?25:10,style:{color:"#333333",cursor:"default",
fontSize:"12px",padding:"8px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var Y=M.plotOptions,X=Y.line;Lb();var ra=function(a){var b=[],c,d;(function(a){a&&a.stops?d=Na(a.stops,function(a){return ra(a[1])}):(c=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(a))?b=[C(c[1]),C(c[2]),
C(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))?b=[C(c[1],16),C(c[2],16),C(c[3],16),1]:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(a))&&(b=[C(c[1]),C(c[2]),C(c[3]),1])})(a);return{get:function(c){var f;d?(f=x(a),f.stops=[].concat(f.stops),n(d,function(a,b){f.stops[b]=[f.stops[b][0],a.get(c)]})):f=b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"?b[3]:"rgba("+b.join(",")+")":a;return f},brighten:function(a){if(d)n(d,
function(b){b.brighten(a)});else if(sa(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=C(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},rgba:b,setOpacity:function(a){b[3]=a;return this}}};wa.prototype={init:function(a,b){this.element=b==="span"?U(b):y.createElementNS(za,b);this.renderer=a;this.attrSetters={}},opacity:1,animate:function(a,b,c){b=o(b,Fa,!0);Wa(this);if(b){b=x(b);if(c)b.complete=c;Bb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(),
i=this.renderer,j,k=this.attrSetters,l=this.shadows,m,p,q=this;ea(a)&&u(b)&&(c=a,a={},a[c]=b);if(ea(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),q=v(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&&c!=="fill"&&(q=parseFloat(q));else{for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==w&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&&(d="M 0 0");else if(c==="x"&&h==="text")for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],v(f,"x")===
v(g,"x")&&v(f,"x",d);else if(this.rotation&&(c==="x"||c==="y"))p=!0;else if(c==="fill")d=i.color(d,g,c);else if(h==="circle"&&(c==="x"||c==="y"))c={x:"cx",y:"cy"}[c]||c;else if(h==="rect"&&c==="r")v(g,{rx:d,ry:d}),j=!0;else if(c==="translateX"||c==="translateY"||c==="rotation"||c==="verticalAlign"||c==="scaleX"||c==="scaleY")j=p=!0;else if(c==="stroke")d=i.color(d,g,c);else if(c==="dashstyle")if(c="stroke-dasharray",d=d&&d.toLowerCase(),d==="solid")d=S;else{if(d){d=d.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot",
"3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(",");for(e=d.length;e--;)d[e]=C(d[e])*o(a["stroke-width"],this["stroke-width"]);d=d.join(",")}}else if(c==="width")d=C(d);else if(c==="align")c="text-anchor",d={left:"start",center:"middle",right:"end"}[d];else if(c==="title")e=g.getElementsByTagName("title")[0],e||(e=y.createElementNS(za,"title"),g.appendChild(e)),e.textContent=d;c==="strokeWidth"&&
(c="stroke-width");if(c==="stroke-width"||c==="stroke"){this[c]=d;if(this.stroke&&this["stroke-width"])v(g,"stroke",this.stroke),v(g,"stroke-width",this["stroke-width"]),this.hasStroke=!0;else if(c==="stroke-width"&&d===0&&this.hasStroke)g.removeAttribute("stroke"),this.hasStroke=!1;j=!0}this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(m||(this.symbolAttr(a),m=!0),j=!0);if(l&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(c))for(e=l.length;e--;)v(l[e],
c,c==="height"?s(d-(l[e].cutHeight||0),0):d);if((c==="width"||c==="height")&&h==="rect"&&d<0)d=0;this[c]=d;c==="text"?(d!==this.textStr&&delete this.bBox,this.textStr=d,this.added&&i.buildText(this)):j||v(g,c,d)}p&&this.updateTransform()}return q},addClass:function(a){var b=this.element,c=v(b,"class")||"";c.indexOf(a)===-1&&v(b,"class",c+" "+a);return this},symbolAttr:function(a){var b=this;n("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=o(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,
b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path",a?"url("+this.renderer.url+"#"+a.id+")":S)},crisp:function(a,b,c,d,e){var f,g={},h={},i,a=a||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;i=t(a)%2/2;h.x=P(b||this.x||0)+i;h.y=P(c||this.y||0)+i;h.width=P((d||this.width||0)-2*i);h.height=P((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},css:function(a){var b=this.element,c=a&&a.width&&b.nodeName.toLowerCase()==="text",
d,e="",f=function(a,b){return"-"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=r(this.styles,a);$&&c&&delete a.width;if(ta&&!Z)c&&delete a.width,K(this.element,a);else{for(d in a)e+=d.replace(/([A-Z])/g,f)+":"+a[d]+";";v(b,"style",e)}c&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){var c=this,d=c.element;ib&&a==="click"?(d.ontouchstart=function(a){c.touchEventFired=Date.now();a.preventDefault();b.call(d,a)},d.onclick=function(a){(oa.indexOf("Android")===-1||
Date.now()-(c.touchEventFired||0)>1100)&&b.call(d,a)}):d["on"+a]=b;return this},setRadialReference:function(a){this.element.radialReference=a;return this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},htmlCss:function(a){var b=this.element;if(b=a&&b.tagName==="SPAN"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=r(this.styles,a);K(this.element,a);return this},htmlGetBBox:function(){var a=
this.element,b=this.bBox;if(!b){if(a.nodeName==="text")a.style.position="absolute";b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}}return b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:0.5,right:1}[g],i=g&&g!=="left",j=this.shadows;K(b,{marginLeft:c,marginTop:d});j&&n(j,function(a){K(a,{marginLeft:c+1,marginTop:d+1})});
this.inverted&&n(b.childNodes,function(c){a.invertChild(c,b)});if(b.tagName==="SPAN"){var k,l,j=this.rotation,m;k=0;var p=1,q=0,ba;m=C(this.textWidth);var A=this.xCorr||0,L=this.yCorr||0,Sb=[j,g,b.innerHTML,this.textWidth].join(",");if(Sb!==this.cTT){u(j)&&(k=j*Ua,p=V(k),q=ca(k),this.setSpanRotation(j,q,p));k=o(this.elemWidth,b.offsetWidth);l=o(this.elemHeight,b.offsetHeight);if(k>m&&/[ \-]/.test(b.textContent||b.innerText))K(b,{width:m+"px",display:"block",whiteSpace:"normal"}),k=m;m=a.fontMetrics(b.style.fontSize).b;
A=p<0&&-k;L=q<0&&-l;ba=p*q<0;A+=q*m*(ba?1-h:h);L-=p*m*(j?ba?h:1-h:1);i&&(A-=k*h*(p<0?-1:1),j&&(L-=l*h*(q<0?-1:1)),K(b,{textAlign:g}));this.xCorr=A;this.yCorr=L}K(b,{left:e+A+"px",top:f+L+"px"});if(gb)l=b.offsetHeight;this.cTT=Sb}}else this.alignOnAdd=!0},setSpanRotation:function(a){var b={};b[ta?"-ms-transform":gb?"-webkit-transform":hb?"MozTransform":Nb?"-o-transform":""]=b.transform="rotate("+a+"deg)";K(this.element,b)},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=
this.scaleX,d=this.scaleY,e=this.inverted,f=this.rotation;e&&(a+=this.attr("width"),b+=this.attr("height"));a=["translate("+a+","+b+")"];e?a.push("rotate(90) scale(-1,1)"):f&&a.push("rotate("+f+" "+(this.x||0)+" "+(this.y||0)+")");(u(c)||u(d))&&a.push("scale("+o(c,1)+" "+o(d,1)+")");a.length&&v(this.element,"transform",a.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){var d,e,f,g,h={};e=this.renderer;f=e.alignedObjects;if(a){if(this.alignOptions=
a,this.alignByTranslate=b,!c||ea(c))this.alignTo=d=c||"renderer",ga(f,this),f.push(this),c=null}else a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo;c=o(c,e[d],e);d=a.align;e=a.verticalAlign;f=(c.x||0)+(a.x||0);g=(c.y||0)+(a.y||0);if(d==="right"||d==="center")f+=(c.width-(a.width||0))/{right:1,center:2}[d];h[b?"translateX":"x"]=t(f);if(e==="bottom"||e==="middle")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?"translateY":"y"]=t(g);this[this.placed?"animate":"attr"](h);this.placed=
!0;this.alignAttr=h;return this},getBBox:function(){var a=this.bBox,b=this.renderer,c,d=this.rotation;c=this.element;var e=this.styles,f=d*Ua;if(!a){if(c.namespaceURI===za||b.forExport){try{a=c.getBBox?r({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(g){}if(!a||a.width<0)a={width:0,height:0}}else a=this.htmlGetBBox();if(b.isSVG){b=a.width;c=a.height;if(ta&&e&&e.fontSize==="11px"&&c.toPrecision(3)==="22.7")a.height=c=14;if(d)a.width=N(c*ca(f))+N(b*V(f)),a.height=N(c*V(f))+N(b*ca(f))}this.bBox=
a}return a},show:function(){return this.attr({visibility:"visible"})},hide:function(){return this.attr({visibility:"hidden"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.hide()}})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=v(f,"zIndex"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=!0,g=C(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a=
e[c],b=v(a,"zIndex"),a!==f&&(C(b)>g||!u(g)&&u(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;z(this,"add");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d=a.renderer.isSVG&&b.nodeName==="SPAN"&&b.parentNode,e,f;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null;Wa(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy();
a.stops=null}a.safeRemoveChild(b);for(c&&n(c,function(b){a.safeRemoveChild(b)});d&&d.childNodes.length===0;)b=d.parentNode,a.safeRemoveChild(d),d=b;a.alignTo&&ga(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},shadow:function(a,b,c){var d=[],e,f,g=this.element,h,i,j,k;if(a){i=o(a.width,3);j=(a.opacity||0.15)/i;k=this.parentInverted?"(-1,-1)":"("+o(a.offsetX,1)+", "+o(a.offsetY,1)+")";for(e=1;e<=i;e++){f=g.cloneNode(0);h=i*2+1-2*e;v(f,{isShadow:"true",stroke:a.color||"black","stroke-opacity":j*
e,"stroke-width":h,transform:"translate"+k,fill:S});if(c)v(f,"height",s(v(f,"height")-h,0)),f.cutHeight=h;b?b.element.appendChild(f):g.parentNode.insertBefore(f,g);d.push(f)}this.shadows=d}return this}};var Ha=function(){this.init.apply(this,arguments)};Ha.prototype={Element:wa,init:function(a,b,c,d){var e=location,f,g;f=this.createElement("svg").attr({version:"1.1"});g=f.element;a.appendChild(g);a.innerHTML.indexOf("xmlns")===-1&&v(g,"xmlns",za);this.isSVG=!0;this.box=g;this.boxWrapper=f;this.alignedObjects=
[];this.url=(hb||gb)&&y.getElementsByTagName("base").length?e.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"";this.createElement("desc").add().element.appendChild(y.createTextNode("Created with Highcharts 3.0.6"));this.defs=this.createElement("defs").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1);var h;if(hb&&a.getBoundingClientRect)this.subPixelFix=b=function(){K(a,{left:0,top:0});h=a.getBoundingClientRect();K(a,{left:xa(h.left)-h.left+"px",top:xa(h.top)-
h.top+"px"})},b(),J(O,"resize",b)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Ka(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();this.subPixelFix&&aa(O,"resize",this.subPixelFix);return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a);return b},draw:function(){},buildText:function(a){for(var b=a.element,c=this,d=c.forExport,e=o(a.textStr,
"").toString().replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g),f=b.childNodes,g=/style="([^"]+)"/,h=/href="(http[^"]+)"/,i=v(b,"x"),j=a.styles,k=j&&j.width&&C(j.width),l=j&&j.lineHeight,m=f.length;m--;)b.removeChild(f[m]);k&&!a.added&&this.box.appendChild(b);e[e.length-1]===""&&e.pop();n(e,function(e,f){var m,o=0,e=e.replace(/<span/g,"|||<span").replace(/<\/span>/g,
"</span>|||");m=e.split("|||");n(m,function(e){if(e!==""||m.length===1){var p={},n=y.createElementNS(za,"tspan"),s;g.test(e)&&(s=e.match(g)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),v(n,"style",s));h.test(e)&&!d&&(v(n,"onclick",'location.href="'+e.match(h)[1]+'"'),K(n,{cursor:"pointer"}));e=(e.replace(/<(.|\n)*?>/g,"")||" ").replace(/&lt;/g,"<").replace(/&gt;/g,">");if(e!==" "&&(n.appendChild(y.createTextNode(e)),o?p.dx=0:p.x=i,v(n,p),!o&&f&&(!Z&&d&&K(n,{display:"block"}),v(n,"dy",l||c.fontMetrics(/px$/.test(n.style.fontSize)?
n.style.fontSize:j.fontSize).h,gb&&n.offsetHeight)),b.appendChild(n),o++,k))for(var e=e.replace(/([^\^])-/g,"$1- ").split(" "),u,t,p=a._clipHeight,E=[],w=C(l||16),B=1;e.length||E.length;)delete a.bBox,u=a.getBBox(),t=u.width,u=t>k,!u||e.length===1?(e=E,E=[],e.length&&(B++,p&&B*w>p?(e=["..."],a.attr("title",a.textStr)):(n=y.createElementNS(za,"tspan"),v(n,{dy:w,x:i}),s&&v(n,"style",s),b.appendChild(n),t>k&&(k=t)))):(n.removeChild(n.firstChild),E.unshift(e.pop())),e.length&&n.appendChild(y.createTextNode(e.join(" ").replace(/- /g,
"-")))}})})},button:function(a,b,c,d,e,f,g,h){var i=this.label(a,b,c,null,null,null,null,null,"button"),j=0,k,l,m,p,q,n,a={x1:0,y1:0,x2:0,y2:1},e=x({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:a,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},e);m=e.style;delete e.style;f=x(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#FFF"],[1,"#ACF"]]}},f);p=f.style;delete f.style;g=x(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#9BD"],[1,"#CDF"]]}},g);q=g.style;
delete g.style;h=x(e,{style:{color:"#CCC"}},h);n=h.style;delete h.style;J(i.element,ta?"mouseover":"mouseenter",function(){j!==3&&i.attr(f).css(p)});J(i.element,ta?"mouseout":"mouseleave",function(){j!==3&&(k=[e,f,g][j],l=[m,p,q][j],i.attr(k).css(l))});i.setState=function(a){(i.state=j=a)?a===2?i.attr(g).css(q):a===3&&i.attr(h).css(n):i.attr(e).css(m)};return i.on("click",function(){j!==3&&d.call(i)}).attr(e).css(r({cursor:"default"},m))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=t(a[1])-b%
2/2);a[2]===a[5]&&(a[2]=a[5]=t(a[2])+b%2/2);return a},path:function(a){var b={fill:S};Ia(a)?b.d=a:T(a)&&r(b,a);return this.createElement("path").attr(b)},circle:function(a,b,c){a=T(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(T(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;a=this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0});a.r=c;return a},rect:function(a,b,c,d,e,f){e=T(a)?a.r:e;e=this.createElement("rect").attr({rx:e,ry:e,
fill:S});return e.attr(T(a)?a:e.crisp(f,a,b,s(c,0),s(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[o(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return u(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:S};arguments.length>1&&r(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink",
"href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(t(b),t(c),d,e,f),i=/^url\((.*?)\)$/,j,k;if(h)g=this.path(h),r(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&r(g,f);else if(i.test(a))k=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(t((d-b[0])/2),t((e-b[1])/2)))},j=a.match(i)[1],a=Pb[j],g=this.image(j).attr({x:b,y:c}),g.isImg=!0,a?k(g,a):(g.attr({width:0,height:0}),U("img",{onload:function(){k(g,
Pb[j]=[this.width,this.height])},src:j}));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,
e){var f=e.start,c=e.r||c||d,g=e.end-0.001,d=e.innerR,h=e.open,i=V(f),j=ca(f),k=V(g),g=ca(g),e=e.end-f<ya?0:1;return["M",a+c*i,b+c*j,"A",c,c,0,e,1,a+c*k,b+c*g,h?"M":"L",a+d*k,b+d*g,"A",d,d,0,e,0,a+d*i,b+d*j,h?"":"Z"]}},clipRect:function(a,b,c,d){var e="highcharts-"+zb++,f=this.createElement("clipPath").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d=this,e,f=/^rgba/,g,h,i,j,k,l,m,p=[];a&&a.linearGradient?g="linearGradient":a&&a.radialGradient&&
(g="radialGradient");if(g){c=a[g];h=d.gradients;j=a.stops;b=b.radialReference;Ia(c)&&(a[g]=c={x1:c[0],y1:c[1],x2:c[2],y2:c[3],gradientUnits:"userSpaceOnUse"});g==="radialGradient"&&b&&!u(c.gradientUnits)&&(c=x(c,{cx:b[0]-b[2]/2+c.cx*b[2],cy:b[1]-b[2]/2+c.cy*b[2],r:c.r*b[2],gradientUnits:"userSpaceOnUse"}));for(m in c)m!=="id"&&p.push(m,c[m]);for(m in j)p.push(j[m]);p=p.join(",");h[p]?a=h[p].id:(c.id=a="highcharts-"+zb++,h[p]=i=d.createElement(g).attr(c).add(d.defs),i.stops=[],n(j,function(a){f.test(a[1])?
(e=ra(a[1]),k=e.get("rgb"),l=e.get("a")):(k=a[1],l=1);a=d.createElement("stop").attr({offset:a[0],"stop-color":k,"stop-opacity":l}).add(i);i.stops.push(a)}));return"url("+d.url+"#"+a+")"}else return f.test(a)?(e=ra(a),v(b,c+"-opacity",e.get("a")),e.get("rgb")):(b.removeAttribute(c+"-opacity"),a)},text:function(a,b,c,d){var e=M.chart.style,f=$||!Z&&this.forExport;if(d&&!this.forExport)return this.html(a,b,c);b=t(o(b,0));c=t(o(c,0));a=this.createElement("text").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,
fontSize:e.fontSize});f&&a.css({position:"absolute"});a.x=b;a.y=c;return a},html:function(a,b,c){var d=M.chart.style,e=this.createElement("span"),f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){a!==g.innerHTML&&delete this.bBox;g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b==="align"&&(b="textAlign");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:t(b),y:t(c)}).css({position:"absolute",whiteSpace:"nowrap",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;
if(h.isSVG)e.add=function(a){var b,c=h.box.parentNode,d=[];if(a){if(b=a.div,!b){for(;a;)d.push(a),a=a.parentGroup;n(d.reverse(),function(a){var d;b=a.div=a.div||U(Ea,{className:v(a.element,"class")},{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px"},b||c);d=b.style;r(a.attrSetters,{translateX:function(a){d.left=a+"px"},translateY:function(a){d.top=a+"px"},visibility:function(a,b){d[b]=a}})})}}else b=c;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};
return e},fontMetrics:function(a){var a=C(a||11),a=a<24?a+4:t(a*1.2),b=t(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a,b;a=o.element.style;L=(Oa===void 0||la===void 0||q.styles.textAlign)&&o.getBBox();q.width=(Oa||L.width||0)+2*da+kb;q.height=(la||L.height||0)+2*da;v=da+p.fontMetrics(a&&a.fontSize).b;if(C){if(!A)a=t(-s*da),b=h?-v:0,q.box=A=d?p.symbol(d,a,b,q.width,q.height):p.rect(a,b,q.width,q.height,0,lb[Rb]),A.add(q);A.isImg||A.attr(x({width:q.width,height:q.height},
lb));lb=null}}function k(){var a=q.styles,a=a&&a.textAlign,b=kb+da*(1-s),c;c=h?0:v;if(u(Oa)&&(a==="center"||a==="right"))b+={center:0.5,right:1}[a]*(Oa-L.width);(b!==o.x||c!==o.y)&&o.attr({x:b,y:c});o.x=b;o.y=c}function l(a,b){A?A.attr(a,b):lb[a]=b}function m(){o.add(q);q.attr({text:a,x:b,y:c});A&&u(e)&&q.attr({anchorX:e,anchorY:f})}var p=this,q=p.g(i),o=p.text("",0,0,g).attr({zIndex:1}),A,L,s=0,da=3,kb=0,Oa,la,E,H,B=0,lb={},v,g=q.attrSetters,C;J(q,"add",m);g.width=function(a){Oa=a;return!1};g.height=
function(a){la=a;return!1};g.padding=function(a){u(a)&&a!==da&&(da=a,k());return!1};g.paddingLeft=function(a){u(a)&&a!==kb&&(kb=a,k());return!1};g.align=function(a){s={left:0,center:0.5,right:1}[a];return!1};g.text=function(a,b){o.attr(b,a);j();k();return!1};g[Rb]=function(a,b){C=!0;B=a%2/2;l(b,a);return!1};g.stroke=g.fill=g.r=function(a,b){b==="fill"&&(C=!0);l(b,a);return!1};g.anchorX=function(a,b){e=a;l(b,a+B-E);return!1};g.anchorY=function(a,b){f=a;l(b,a-H);return!1};g.x=function(a){q.x=a;a-=s*
((Oa||L.width)+da);E=t(a);q.attr("translateX",E);return!1};g.y=function(a){H=q.y=t(a);q.attr("translateY",H);return!1};var y=q.css;return r(q,{css:function(a){if(a){var b={},a=x(a);n("fontSize,fontWeight,fontFamily,color,lineHeight,width,textDecoration,textShadow".split(","),function(c){a[c]!==w&&(b[c]=a[c],delete a[c])});o.css(b)}return y.call(q,a)},getBBox:function(){return{width:L.width+2*da,height:L.height+2*da,x:L.x-da,y:L.y-da}},shadow:function(a){A&&A.shadow(a);return q},destroy:function(){aa(q,
"add",m);aa(q.element,"mouseenter");aa(q.element,"mouseleave");o&&(o=o.destroy());A&&(A=A.destroy());wa.prototype.destroy.call(q);q=p=j=k=l=m=null}})}};Va=Ha;var F;if(!Z&&!$){Highcharts.VMLElement=F={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ","absolute",";"],e=b===Ea;(b==="shape"||e)&&d.push("left:0;top:0;width:1px;height:1px;");d.push("visibility: ",e?"hidden":"visible");c.push(' style="',d.join(""),'"/>');if(b)c=e||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=
U(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();z(this,"add");return this},updateTransform:wa.prototype.htmlUpdateTransform,setSpanRotation:function(a,b,c){K(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11=",c,", M12=",-b,", M21=",b,", M22=",c,", sizingMethod='auto expand')"].join(""):
S})},pathToVML:function(a){for(var b=a.length,c=[],d;b--;)if(sa(a[b]))c[b]=t(a[b]*10)-5;else if(a[b]==="Z")c[b]="x";else if(c[b]=a[b],a.isArc&&(a[b]==="wa"||a[b]==="at"))d=a[b]==="wa"?1:-1,c[b+5]===c[b+7]&&(c[b+7]-=d),c[b+6]===c[b+8]&&(c[b+8]-=d);return c.join(" ")||"x"},attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,l=this.shadows,m,p=this.attrSetters,q=this;ea(a)&&u(b)&&(c=a,a={},a[c]=b);if(ea(a))c=a,q=c==="strokeWidth"||c==="stroke-width"?
this.strokeweight:this[c];else for(c in a)if(d=a[c],m=!1,e=p[c]&&p[c].call(this,d,c),e!==!1&&d!==null){e!==w&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a),k=!0),m=!0;else if(c==="d"){d=d||[];this.d=d.join(" ");f.path=d=this.pathToVML(d);if(l)for(e=l.length;e--;)l[e].path=l[e].cutOff?this.cutOffPath(d,l[e].cutOff):d;m=!0}else if(c==="visibility"){if(l)for(e=l.length;e--;)l[e].style[c]=d;h==="DIV"&&(d=d==="hidden"?"-999em":0,fb||(g[c]=d?"visible":
"hidden"),c="top");g[c]=d;m=!0}else if(c==="zIndex")d&&(g[c]=d),m=!0;else if(qa(c,["x","y","width","height"])!==-1)this[c]=d,c==="x"||c==="y"?c={x:"left",y:"top"}[c]:d=s(0,d),this.updateClipping?(this[c]=d,this.updateClipping()):g[c]=d,m=!0;else if(c==="class"&&h==="DIV")f.className=d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,sa(d)&&(d+="px");else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||
U(i.prepVML(["<stroke/>"]),null,null,f))[c]=d||"solid",this.dashstyle=d,m=!0;else if(c==="fill")if(h==="SPAN")g.color=d;else{if(h!=="IMG")f.filled=d!==S?!0:!1,d=i.color(d,f,c,this),c="fillcolor"}else if(c==="opacity")m=!0;else if(h==="shape"&&c==="rotation")this[c]=f.style[c]=d,f.style.left=-t(ca(d*Ua)+1)+"px",f.style.top=t(V(d*Ua))+"px";else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),m=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,m=!0;m||(fb?f[c]=
d:v(f,c,d))}return q},clip:function(a){var b=this,c;a?(c=a.members,ga(c,b),c.push(b),b.destroyClip=function(){ga(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:fb?"inherit":"rect(auto)"});return b.css(a)},css:wa.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Ta(a)},destroy:function(){this.destroyClip&&this.destroyClip();return wa.prototype.destroy.apply(this)},on:function(a,b){this.element["on"+a]=function(){var a=O.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,
b){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=C(a[c-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,l,m,p,q;k&&typeof k.value!=="string"&&(k="x");m=k;if(a){p=o(a.width,3);q=(a.opacity||0.15)/p;for(e=1;e<=3;e++){l=p*2+1-2*e;c&&(m=this.cutOffPath(k.value,l+0.5));j=['<shape isShadow="true" strokeweight="',l,'" filled="false" path="',m,'" coordsize="10 10" style="',f.style.cssText,'" />'];h=U(g.prepVML(j),null,
{left:C(i.left)+o(a.offsetX,1),top:C(i.top)+o(a.offsetY,1)});if(c)h.cutOff=l+1;j=['<stroke color="',a.color||"black",'" opacity="',q*e,'"/>'];U(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};F=ha(wa,F);var ma={Element:F,isIE8:oa.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(Ea);e=d.element;e.style.position="relative";a.appendChild(d.element);this.isVML=!0;this.box=e;this.boxWrapper=
d;this.setSize(b,c,!1);y.namespaces.hcv||(y.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),(y.styleSheets.length?y.styleSheets[0]:y.createStyleSheet()).cssText+="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } ")},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=T(a);return r(e,{members:[],left:(f?a.x:a)+1,top:(f?a.y:b)+1,width:(f?a.width:c)-1,height:(f?a.height:d)-1,getCSS:function(a){var b=
a.element,c=b.nodeName,a=a.inverted,d=this.top-(c==="shape"?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:"rect("+t(a?e:d)+"px,"+t(a?f:b)+"px,"+t(a?b:f)+"px,"+t(a?d:e)+"px)"};!a&&fb&&c==="DIV"&&r(d,{width:b+"px",height:f+"px"});return d},updateClipping:function(){n(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=S;a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern");if(i){var k,l,m=a.linearGradient||a.radialGradient,
p,q,o,A,L,s="",a=a.stops,u,t=[],w=function(){h=['<fill colors="'+t.join(",")+'" opacity="',o,'" o:opacity2="',q,'" type="',i,'" ',s,'focus="100%" method="any" />'];U(e.prepVML(h),null,null,b)};p=a[0];u=a[a.length-1];p[0]>0&&a.unshift([0,p[1]]);u[0]<1&&a.push([1,u[1]]);n(a,function(a,b){g.test(a[1])?(f=ra(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1);t.push(a[0]*100+"% "+k);b?(o=l,A=k):(q=l,L=k)});if(c==="fill")if(i==="gradient")c=m.x1||m[0]||0,a=m.y1||m[1]||0,p=m.x2||m[2]||0,m=m.y2||m[3]||0,s='angle="'+
(90-R.atan((m-a)/(p-c))*180/ya)+'"',w();else{var j=m.r,r=j*2,E=j*2,H=m.cx,B=m.cy,x=b.radialReference,v,j=function(){x&&(v=d.getBBox(),H+=(x[0]-v.x)/v.width-0.5,B+=(x[1]-v.y)/v.height-0.5,r*=x[2]/v.width,E*=x[2]/v.height);s='src="'+M.global.VMLRadialGradientURL+'" size="'+r+","+E+'" origin="0.5,0.5" position="'+H+","+B+'" color2="'+L+'" ';w()};d.added?j():J(d,"add",j);j=A}else j=k}else if(g.test(a)&&b.tagName!=="IMG")f=ra(a),h=["<",c,' opacity="',f.get("a"),'"/>'],U(this.prepVML(h),null,null,b),j=
f.get("rgb");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1,j[0].type="solid";j=a}return j},prepVML:function(a){var b=this.isIE8,a=a.join("");b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===-1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:");return a},text:Ha.prototype.html,path:function(a){var b={coordsize:"10 10"};
Ia(a)?b.d=a:T(a)&&r(b,a);return this.createElement("shape").attr(b)},circle:function(a,b,c){var d=this.symbol("circle");if(T(a))c=a.r,b=a.y,a=a.x;d.isCircle=!0;d.r=c;return d.attr({x:a,y:b})},g:function(a){var b;a&&(b={className:"highcharts-"+a,"class":"highcharts-"+a});return this.createElement(Ea).attr(b)},image:function(a,b,c,d,e){var f=this.createElement("img").attr({src:a});arguments.length>1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){var g=this.symbol("rect");g.r=
T(a)?a.r:e;return g.attr(T(a)?a:g.crisp(f,a,b,s(c,0),s(d,0)))},invertChild:function(a,b){var c=b.style;K(a,{flip:"x",left:C(c.width)-1,top:C(c.height)-1,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=V(f),i=ca(f),j=V(g),k=ca(g);if(g-f===0)return["x"];f=["wa",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*j,b+h*k];e.open&&!c&&f.push("e","M",a,b);f.push("at",a-c,b-c,a+c,b+c,a+c*j,b+c*k,a+c*d,b+c*i,"x","e");f.isArc=!0;return f},circle:function(a,b,c,d,e){e&&(c=d=2*e.r);
e&&e.isCircle&&(a-=c/2,b-=d/2);return["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){var f=a+c,g=b+d,h;!u(e)||!e.r?f=Ha.prototype.symbols.square.apply(0,arguments):(h=I(e.r,c,d),f=["M",a+h,b,"L",f-h,b,"wa",f-2*h,b,f,b+2*h,f-h,b,f,b+h,"L",f,g-h,"wa",f-2*h,g-2*h,f,g,f,g-h,f-h,g,"L",a+h,g,"wa",a,g-2*h,a+2*h,g,a+h,g,a,g-h,"L",a,b+h,"wa",a,b,a+2*h,b+2*h,a,b+h,a+h,b,"x","e"]);return f}}};Highcharts.VMLRenderer=F=function(){this.init.apply(this,arguments)};F.prototype=x(Ha.prototype,
ma);Va=F}var Tb;if($)Highcharts.CanVGRenderer=F=function(){za="http://www.w3.org/1999/xhtml"},F.prototype.symbols={},Tb=function(){function a(){var a=b.length,d;for(d=0;d<a;d++)b[d]();b=[]}var b=[];return{push:function(c,d){b.length===0&&Vb(d,a);b.push(c)}}}(),Va=F;Ma.prototype={addLabel:function(){var a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=a.series[0]&&a.series[0].names,g=this.pos,h=b.labels,i=a.tickPositions,d=d&&e&&!h.step&&!h.staggerLines&&!h.rotation&&c.plotWidth/i.length||
!d&&(c.margin[3]||c.chartWidth*0.33),j=g===i[0],k=g===i[i.length-1],l,f=e?o(e[g],f&&f[g],g):g,e=this.label,m=i.info;a.isDatetimeAxis&&m&&(l=b.dateTimeLabelFormats[m.higherRanks[g]||m.unitName]);this.isFirst=j;this.isLast=k;b=a.labelFormatter.call({axis:a,chart:c,isFirst:j,isLast:k,dateTimeLabelFormat:l,value:a.isLog?ia(fa(f)):f});g=d&&{width:s(1,t(d-2*(h.padding||10)))+"px"};g=r(g,h.style);if(u(e))e&&e.attr({text:b}).css(g);else{l={align:a.labelAlign};if(sa(h.rotation))l.rotation=h.rotation;if(d&&
h.ellipsis)l._clipHeight=a.len/i.length;this.label=u(b)&&h.enabled?c.renderer.text(b,0,0,h.useHTML).attr(l).css(g).add(a.labelGroup):null}},getLabelSize:function(){var a=this.label,b=this.axis;return a?(this.labelBBox=a.getBBox())[b.horiz?"height":"width"]:0},getLabelSides:function(){var a=this.axis,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.labelAlign]-a.options.labels.x;return[-a,b-a]},handleOverflow:function(a,b){var c=!0,d=this.axis,e=d.chart,f=this.isFirst,g=this.isLast,h=b.x,i=
d.reversed,j=d.tickPositions;if(f||g){var k=this.getLabelSides(),l=k[0],k=k[1],e=e.plotLeft,m=e+d.len,j=(d=d.ticks[j[a+(f?1:-1)]])&&d.label.xy&&d.label.xy.x+d.getLabelSides()[f?0:1];f&&!i||g&&i?h+l<e&&(h=e-l,d&&h+k>j&&(c=!1)):h+k>m&&(h=m-k,d&&h+l<j&&(c=!1));b.x=h}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?
g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,l=i.staggerLines,m=i.chart.renderer.fontMetrics(e.style.fontSize).b,p=e.rotation,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):0);p&&i.side===2&&(b-=m-m*V(p*Ua));!u(e.y)&&!p&&(b+=m-c.getBBox().height/2);l&&(b+=g/(h||1)%l*(i.labelOffset/l));return{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine(["M",a,b,"L",
a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,j=this.pos,k=e.labels,l=this.gridLine,m=h?h+"Grid":"grid",p=h?h+"Tick":"tick",q=e[m+"LineWidth"],n=e[m+"LineColor"],A=e[m+"LineDashStyle"],s=e[p+"Length"],m=e[p+"Width"]||0,u=e[p+"Color"],t=e[p+"Position"],p=this.mark,r=k.step,v=!0,x=d.tickmarkOffset,E=this.getPosition(g,j,x,b),H=E.x,E=E.y,B=g&&H===d.pos+d.len||!g&&E===d.pos?-1:1,C=d.staggerLines;this.isActive=!0;if(q){j=
d.getPlotLinePath(j+x,q*B,b,!0);if(l===w){l={stroke:n,"stroke-width":q};if(A)l.dashstyle=A;if(!h)l.zIndex=1;if(b)l.opacity=0;this.gridLine=l=q?f.path(j).attr(l).add(d.gridGroup):null}if(!b&&l&&j)l[this.isNew?"attr":"animate"]({d:j,opacity:c})}if(m&&s)t==="inside"&&(s=-s),d.opposite&&(s=-s),b=this.getMarkPath(H,E,s,m*B,g,f),p?p.animate({d:b,opacity:c}):this.mark=f.path(b).attr({stroke:u,"stroke-width":m,opacity:c}).add(d.axisGroup);if(i&&!isNaN(H))i.xy=E=this.getLabelPosition(H,E,i,g,k,x,a,r),this.isFirst&&
!this.isLast&&!o(e.showFirstLabel,1)||this.isLast&&!this.isFirst&&!o(e.showLastLabel,1)?v=!1:!C&&g&&k.overflow==="justify"&&!this.handleOverflow(a,E)&&(v=!1),r&&a%r&&(v=!1),v&&!isNaN(E.y)?(E.opacity=c,i[this.isNew?"attr":"animate"](E),this.isNew=!1):i.attr("y",-9999)},destroy:function(){Ka(this,this.axis)}};vb.prototype={render:function(){var a=this,b=a.axis,c=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=u(j)&&u(i),l=e.value,m=e.dashStyle,p=a.svgElem,q=
[],n,A=e.color,L=e.zIndex,t=e.events,w=b.chart.renderer;b.isLog&&(j=na(j),i=na(i),l=na(l));if(h){if(q=b.getPlotLinePath(l,h),d={stroke:A,"stroke-width":h},m)d.dashstyle=m}else if(k){if(j=s(j,b.min-d),i=I(i,b.max+d),q=b.getPlotBandPath(j,i,e),d={fill:A},e.borderWidth)d.stroke=e.borderColor,d["stroke-width"]=e.borderWidth}else return;if(u(L))d.zIndex=L;if(p)q?p.animate({d:q},null,p.onGetPath):(p.hide(),p.onGetPath=function(){p.show()});else if(q&&q.length&&(a.svgElem=p=w.path(q).attr(d).add(),t))for(n in e=
function(b){p.on(b,function(c){t[b].apply(a,[c])})},t)e(n);if(f&&u(f.text)&&q&&q.length&&b.width>0&&b.height>0){f=x({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=w.text(f.text,0,0,f.useHTML).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:L}).css(f.style).add();b=[q[1],q[4],o(q[6],q[1])];q=[q[2],q[5],o(q[7],q[2])];c=Ja(b);k=Ja(q);g.align(f,!1,{x:c,y:k,width:va(b)-c,height:va(q)-k});g.show()}else g&&g.hide();return a},
destroy:function(){ga(this.axis.plotLinesAndBands,this);delete this.axis;Ka(this)}};Mb.prototype={destroy:function(){Ka(this,this.axis)},render:function(a){var b=this.options,c=b.format,c=c?Ca(c,this):b.formatter.call(this);this.label?this.label.attr({text:c,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(c,0,0,b.useHTML).css(b.style).attr({align:this.textAlign,rotation:b.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,
g=c.translate(this.percent?100:this.total,0,0,0,1),c=c.translate(0),c=N(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?Z?"inherit":"visible":"hidden"})}};db.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",
month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#C0C0C0",labels:G,lineColor:"#C0D0E0",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#4d759e",fontWeight:"bold"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,
gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return Aa(this.total,-1)},style:G.style}},defaultLeftAxisOptions:{labels:{x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:8,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{x:0,y:-5},
title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c;this.xOrY=(this.isXAxis=c)?"x":"y";this.opposite=b.opposite;this.side=this.horiz?this.opposite?0:2:this.opposite?1:3;this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.userOptions=b;this.minPixelPadding=0;this.chart=a;this.reversed=d.reversed;this.zoomEnabled=d.zoomEnabled!==!1;this.categories=d.categories||e==="category";this.isLog=e==="logarithmic";this.isDatetimeAxis=
e==="datetime";this.isLinked=u(d.linkedTo);this.tickmarkOffset=this.categories&&d.tickmarkPlacement==="between"?0.5:0;this.ticks={};this.minorTicks={};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;this.stacks={};this.oldStacks={};this.stackExtremes={};this.min=this.max=null;var f,d=this.options.events;qa(this,a.axes)===-1&&(a.axes.push(this),a[c?"xAxis":"yAxis"].push(this));this.series=this.series||
[];if(a.inverted&&c&&this.reversed===w)this.reversed=!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)J(this,f,d[f]);if(this.isLog)this.val2lin=na,this.lin2val=fa},setOptions:function(a){this.options=x(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],x(M[this.isXAxis?"xAxis":"yAxis"],a))},update:function(a,b){var c=this.chart,a=c.options[this.xOrY+
"Axis"][this.options.index]=x(this.userOptions,a);this.destroy(!0);this._addedPlotLB=this.userMin=this.userMax=w;this.init(c,r(a,{events:w}));c.isDirtyBox=!0;o(b,!0)&&c.redraw()},remove:function(a){var b=this.chart,c=this.xOrY+"Axis";n(this.series,function(a){a.remove(!1)});ga(b.axes,this);ga(b[c],this);b.options[c].splice(this.options.index,1);n(b[c],function(a,b){a.options.index=b});this.destroy();b.isDirtyBox=!0;o(a,!0)&&b.redraw()},defaultLabelFormatter:function(){var a=this.axis,b=this.value,
c=a.categories,d=this.dateTimeLabelFormat,e=M.lang.numericSymbols,f=e&&e.length,g,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ca(h,this);else if(c)g=b;else if(d)g=Xa(d,b);else if(f&&a>=1E3)for(;f--&&g===w;)c=Math.pow(1E3,f+1),a>=c&&e[f]!==null&&(g=Aa(b/c,-1)+e[f]);g===w&&(g=b>=1E3?Aa(b,0):Aa(b,-1));return g},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;a.stackExtremes={};a.buildStacks();n(a.series,function(c){if(c.visible||!b.options.chart.ignoreHiddenSeries){var d;
d=c.options.threshold;var e;a.hasVisibleSeries=!0;a.isLog&&d<=0&&(d=null);if(a.isXAxis){if(d=c.xData,d.length)a.dataMin=I(o(a.dataMin,d[0]),Ja(d)),a.dataMax=s(o(a.dataMax,d[0]),va(d))}else{c.getExtremes();e=c.dataMax;c=c.dataMin;if(u(c)&&u(e))a.dataMin=I(o(a.dataMin,c),c),a.dataMax=s(o(a.dataMax,e),e);if(u(d))if(a.dataMin>=d)a.dataMin=d,a.ignoreMinPadding=!0;else if(a.dataMax<d)a.dataMax=d,a.ignoreMaxPadding=!0}}})},translate:function(a,b,c,d,e,f){var g=this.len,h=1,i=0,j=d?this.oldTransA:this.transA,
d=d?this.oldMin:this.min,k=this.minPixelPadding,e=(this.options.ordinal||this.isLog&&e)&&this.lin2val;if(!j)j=this.transA;c&&(h*=-1,i=g);this.reversed&&(h*=-1,i-=h*g);b?(a=a*h+i,a-=k,a=a/j+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),f==="between"&&(f=0.5),a=h*(a-d)*j+i+h*k+(sa(f)?j*f*this.pointRange:0));return a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a-(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,
b,c,d){var e=this.chart,f=this.left,g=this.top,h,i,j,a=this.translate(a,null,null,c),k=c&&e.oldChartHeight||e.chartHeight,l=c&&e.oldChartWidth||e.chartWidth,m;h=this.transB;c=i=t(a+h);h=j=t(k-a-h);if(isNaN(a))m=!0;else if(this.horiz){if(h=g,j=k-this.bottom,c<f||c>f+this.width)m=!0}else if(c=f,i=l-this.right,h<g||h>g+this.height)m=!0;return m&&!d?null:e.renderer.crispLine(["M",c,h,"L",i,j],b||0)},getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],
c[5],c[1],c[2]):d=null;return d},getLinearTickPositions:function(a,b,c){for(var d,b=ia(P(b/a)*a),c=ia(xa(c/a)*a),e=[];b<=c;){e.push(b);b=ia(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=t(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=P(b),h,i,j,k,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];f<c+1&&!l;f++){i=e.length;for(h=0;h<i&&!l;h++)j=na(fa(f)*e[h]),j>b&&(!d||
k<=c)&&g.push(k),k>c&&(l=!0),k=j}else if(b=fa(b),c=fa(c),a=e[d?"minorTickInterval":"tickInterval"],a=o(a==="auto"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=ob(a,null,nb(a)),g=Na(this.getLinearTickPositions(a,b,c),na),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[],e;if(this.isLog){e=b.length;for(a=1;a<e;a++)d=d.concat(this.getLogTickPositions(c,
b[a-1],b[a],!0))}else if(this.isDatetimeAxis&&a.minorTickInterval==="auto")d=d.concat(Eb(Cb(c),this.min,this.max,a.startOfWeek)),d[0]<this.min&&d.shift();else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var a=this.options,b=this.min,c=this.max,d,e=this.dataMax-this.dataMin>=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===w&&!this.isLog)u(a.min)||u(a.max)?this.minRange=null:(n(this.series,function(a){i=a.xData;for(g=j=a.xIncrement?1:i.length-
1;g>0;g--)if(h=i[g]-i[g-1],f===w||h<f)f=h}),this.minRange=I(f*5,this.dataMax-this.dataMin));if(c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2;d=[b-d,o(a.min,b-d)];if(e)d[2]=this.dataMin;b=va(d);c=[b+k,o(a.max,b+k)];if(e)c[2]=this.dataMax;c=Ja(c);c-b<k&&(d[0]=c-k,d[1]=o(a.min,c-k),b=va(d))}this.min=b;this.max=c},setAxisTranslation:function(a){var b=this.max-this.min,c=0,d,e=0,f=0,g=this.linkedParent,h=this.transA;if(this.isXAxis)g?(e=g.minPointOffset,f=g.pointRangePadding):n(this.series,function(a){var g=
a.pointRange,h=a.options.pointPlacement,l=a.closestPointRange;g>b&&(g=0);c=s(c,g);e=s(e,ea(h)?0:g/2);f=s(f,h==="on"?0:g);!a.noSharedTooltip&&u(l)&&(d=u(d)?I(d,l):l)}),g=this.ordinalSlope&&d?this.ordinalSlope/d:1,this.minPointOffset=e*=g,this.pointRangePadding=f*=g,this.pointRange=I(c,b),this.closestPointRange=d;if(a)this.oldTransA=h;this.translationSlope=this.transA=h=this.len/(b+f||1);this.transB=this.horiz?this.left:this.bottom;this.minPixelPadding=h*e},setTickPositions:function(a){var b=this,c=
b.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,l=d.tickInterval,m=d.minTickInterval,p=d.tickPixelInterval,q,ba=b.categories;h?(b.linkedParent=c[g?"xAxis":"yAxis"][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=o(c.min,c.dataMin),b.max=o(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&ka(11,1)):(b.min=o(b.userMin,d.min,b.dataMin),b.max=o(b.userMax,d.max,b.dataMax));if(e)!a&&I(b.min,o(b.dataMin,b.min))<=0&&
ka(10,1),b.min=ia(na(b.min)),b.max=ia(na(b.max));if(b.range&&(b.userMin=b.min=s(b.min,b.max-b.range),b.userMax=b.max,a))b.range=null;b.beforePadding&&b.beforePadding();b.adjustForMinRange();if(!ba&&!b.usePercentage&&!h&&u(b.min)&&u(b.max)&&(c=b.max-b.min)){if(!u(d.min)&&!u(b.userMin)&&k&&(b.dataMin<0||!b.ignoreMinPadding))b.min-=c*k;if(!u(d.max)&&!u(b.userMax)&&j&&(b.dataMax>0||!b.ignoreMaxPadding))b.max+=c*j}b.min===b.max||b.min===void 0||b.max===void 0?b.tickInterval=1:h&&!l&&p===b.linkedParent.options.tickPixelInterval?
b.tickInterval=b.linkedParent.tickInterval:(b.tickInterval=o(l,ba?1:(b.max-b.min)*p/s(b.len,p)),!u(l)&&b.len<p&&!this.isRadial&&(q=!0,b.tickInterval/=4));g&&!a&&n(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(!0);b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval);if(b.pointRange)b.tickInterval=s(b.pointRange,b.tickInterval);if(!l&&b.tickInterval<m)b.tickInterval=
m;if(!f&&!e&&!l)b.tickInterval=ob(b.tickInterval,null,nb(b.tickInterval),d);b.minorTickInterval=d.minorTickInterval==="auto"&&b.tickInterval?b.tickInterval/5:d.minorTickInterval;b.tickPositions=a=d.tickPositions?[].concat(d.tickPositions):i&&i.apply(b,[b.min,b.max]);if(!a)!b.ordinalPositions&&(b.max-b.min)/b.tickInterval>s(2*b.len,200)&&ka(19,!0),a=f?(b.getNonLinearTimeTicks||Eb)(Cb(b.tickInterval,d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,
b.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),q&&a.splice(1,a.length-2),b.tickPositions=a;if(!h)e=a[0],f=a[a.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&a.shift(),d.endOnTick?b.max=f:b.max+h<f&&a.pop(),a.length===1&&(b.min-=0.001,b.max+=0.001)},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey=[this.xOrY,this.pos,this.len].join("-");if(!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==
!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this._maxTicksKey,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(e<a){for(;b.length<a;)b.push(ia(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a-1);this.max=b[b.length-1]}if(u(d)&&a!==d)this.isDirty=!0}},setScale:function(){var a=this.stacks,b,c,d,e;this.oldMin=this.min;this.oldMax=
this.max;this.oldAxisLength=this.len;this.setAxisSize();e=this.len!==this.oldAxisLength;n(this.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)d=!0});if(e||d||this.isLinked||this.forceRedraw||this.userMin!==this.oldUserMin||this.userMax!==this.oldUserMax){if(!this.isXAxis)for(b in a)delete a[b];this.forceRedraw=!1;this.getSeriesExtremes();this.setTickPositions();this.oldUserMin=this.userMin;this.oldUserMax=this.userMax;if(!this.isDirty)this.isDirty=e||this.min!==this.oldMin||this.max!==
this.oldMax}else if(!this.isXAxis){if(this.oldStacks)a=this.stacks=this.oldStacks;for(b in a)for(c in a[b])a[b][c].cum=a[b][c].total}this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=o(c,!0),e=r(e,{min:a,max:b});z(f,"setExtremes",e,function(){f.userMin=a;f.userMax=b;f.eventArgs=e;f.isDirtyExtremes=!0;c&&g.redraw(d)})},zoom:function(a,b){this.allowZoomOutside||(u(this.dataMin)&&a<=this.dataMin&&(a=w),u(this.dataMax)&&b>=this.dataMax&&(b=w));this.displayBtn=a!==w||b!==w;this.setExtremes(a,
b,!1,w,{trigger:"zoom"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=b.offsetRight||0,e=this.horiz,f,g;this.left=g=o(b.left,a.plotLeft+c);this.top=f=o(b.top,a.plotTop);this.width=c=o(b.width,a.plotWidth-c+d);this.height=b=o(b.height,a.plotHeight);this.bottom=a.chartHeight-b-f;this.right=a.chartWidth-c-g;this.len=s(e?c:b,0);this.pos=e?g:f},getExtremes:function(){var a=this.isLog;return{min:a?ia(fa(this.min)):this.min,max:a?ia(fa(this.max)):this.max,dataMin:this.dataMin,
dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?fa(this.min):this.min,b=b?fa(this.max):this.max;c>a||a===null?a=c:b<a&&(a=b);return this.translate(a,0,1,0,1)},addPlotBand:function(a){this.addPlotBandOrLine(a,"plotBands")},addPlotLine:function(a){this.addPlotBandOrLine(a,"plotLines")},addPlotBandOrLine:function(a,b){var c=(new vb(this,a)).render(),d=this.userOptions;c&&(b&&(d[b]=d[b]||[],d[b].push(a)),this.plotLinesAndBands.push(c));return c},
autoLabelAlign:function(a){a=(o(a,0)-this.side*90+720)%360;return a>15&&a<165?"right":a>195&&a<345?"left":"center"},getOffset:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,j,k=0,l,m=0,p=d.title,q=d.labels,ba=0,A=b.axisOffset,L=b.clipOffset,t=[-1,1,1,-1][h],r,v=1,x=o(q.maxStaggerLines,5),la,E,H,B;a.hasData=j=a.hasVisibleSeries||u(a.min)&&u(a.max)&&!!e;a.showAxis=b=j||o(d.showEmpty,!0);a.staggerLines=a.horiz&&q.staggerLines;
if(!a.axisGroup)a.gridGroup=c.g("grid").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g("axis-labels").attr({zIndex:q.zIndex||7}).add();if(j||a.isLinked){a.labelAlign=o(q.align||a.autoLabelAlign(q.rotation));n(e,function(b){f[b]?f[b].addLabel():f[b]=new Ma(a,b)});if(a.horiz&&!a.staggerLines&&x&&!q.rotation){for(r=a.reversed?[].concat(e).reverse():e;v<x;){j=[];la=!1;for(q=0;q<r.length;q++)E=r[q],H=(H=f[E].label&&f[E].label.getBBox())?H.width:
0,B=q%v,H&&(E=a.translate(E),j[B]!==w&&E<j[B]&&(la=!0),j[B]=E+H);if(la)v++;else break}if(v>1)a.staggerLines=v}n(e,function(b){if(h===0||h===2||{1:"left",3:"right"}[h]===a.labelAlign)ba=s(f[b].getLabelSize(),ba)});if(a.staggerLines)ba*=a.staggerLines,a.labelOffset=ba}else for(r in f)f[r].destroy(),delete f[r];if(p&&p.text&&p.enabled!==!1){if(!a.axisTitle)a.axisTitle=c.text(p.text,0,0,p.useHTML).attr({zIndex:7,rotation:p.rotation||0,align:p.textAlign||{low:"left",middle:"center",high:"right"}[p.align]}).css(p.style).add(a.axisGroup),
a.axisTitle.isNew=!0;if(b)k=a.axisTitle.getBBox()[g?"height":"width"],m=o(p.margin,g?5:10),l=p.offset;a.axisTitle[b?"show":"hide"]()}a.offset=t*o(d.offset,A[h]);a.axisTitleMargin=o(l,ba+m+(h!==2&&ba&&t*d.labels[g?"y":"x"]));A[h]=s(A[h],a.axisTitleMargin+k+t*a.offset);L[i]=s(L[i],P(d.lineWidth/2)*2)},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d,d=b.chartHeight-this.bottom-(c?this.height:0)+d;c&&(a*=-1);return b.renderer.crispLine(["M",
e?this.left:f,e?d:this.top,"L",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=C(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(this.side===2?i:0);return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var a=this,
b=a.chart,c=b.renderer,d=a.options,e=a.isLog,f=a.isLinked,g=a.tickPositions,h=a.axisTitle,i=a.stacks,j=a.ticks,k=a.minorTicks,l=a.alternateBands,m=d.stackLabels,p=d.alternateGridColor,q=a.tickmarkOffset,o=d.lineWidth,A,s=b.hasRendered&&u(a.oldMin)&&!isNaN(a.oldMin);A=a.hasData;var t=a.showAxis,r,v;n([j,k,l],function(a){for(var b in a)a[b].isActive=!1});if(A||f)if(a.minorTickInterval&&!a.categories&&n(a.getMinorTickPositions(),function(b){k[b]||(k[b]=new Ma(a,b,"minor"));s&&k[b].isNew&&k[b].render(null,
!0);k[b].render(null,!1,1)}),g.length&&(n(g.slice(1).concat([g[0]]),function(b,c){c=c===g.length-1?0:c+1;if(!f||b>=a.min&&b<=a.max)j[b]||(j[b]=new Ma(a,b)),s&&j[b].isNew&&j[b].render(c,!0),j[b].render(c,!1,1)}),q&&a.min===0&&(j[-1]||(j[-1]=new Ma(a,-1,null,!0)),j[-1].render(-1))),p&&n(g,function(b,c){if(c%2===0&&b<a.max)l[b]||(l[b]=new vb(a)),r=b+q,v=g[c+1]!==w?g[c+1]+q:a.max,l[b].options={from:e?fa(r):r,to:e?fa(v):v,color:p},l[b].render(),l[b].isActive=!0}),!a._addedPlotLB)n((d.plotLines||[]).concat(d.plotBands||
[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0;n([j,k,l],function(a){var c,d,e=[],f=Fa?Fa.duration||500:0,g=function(){for(d=e.length;d--;)a[e[d]]&&!a[e[d]].isActive&&(a[e[d]].destroy(),delete a[e[d]])};for(c in a)if(!a[c].isActive)a[c].render(c,!1,0),a[c].isActive=!1,e.push(c);a===l||!b.hasRendered||!f?g():f&&setTimeout(g,f)});if(o)A=a.getLinePath(o),a.axisLine?a.axisLine.animate({d:A}):a.axisLine=c.path(A).attr({stroke:d.lineColor,"stroke-width":o,zIndex:7}).add(a.axisGroup),a.axisLine[t?
"show":"hide"]();if(h&&t)h[h.isNew?"attr":"animate"](a.getTitlePosition()),h.isNew=!1;if(m&&m.enabled){var x,la,d=a.stackTotalGroup;if(!d)a.stackTotalGroup=d=c.g("stack-labels").attr({visibility:"visible",zIndex:6}).add();d.translate(b.plotLeft,b.plotTop);for(x in i)for(la in c=i[x],c)c[la].render(d)}a.isDirty=!1},removePlotBandOrLine:function(a){for(var b=this.plotLinesAndBands,c=this.options,d=this.userOptions,e=b.length;e--;)b[e].id===a&&b[e].destroy();n([c.plotLines||[],d.plotLines||[],c.plotBands||
[],d.plotBands||[]],function(b){for(e=b.length;e--;)b[e].id===a&&ga(b,b[e])})},setTitle:function(a,b){this.update({title:a},b)},redraw:function(){var a=this.chart.pointer;a.reset&&a.reset(!0);this.render();n(this.plotLinesAndBands,function(a){a.render()});n(this.series,function(a){a.isDirty=!0})},buildStacks:function(){var a=this.series,b=a.length;if(!this.isXAxis){for(;b--;)a[b].setStackedPoints();if(this.usePercentage)for(b=0;b<a.length;b++)a[b].setPercentStacks()}},setCategories:function(a,b){this.update({categories:a},
b)},destroy:function(a){var b=this,c=b.stacks,d,e=b.plotLinesAndBands;a||aa(b);for(d in c)Ka(c[d]),c[d]=null;n([b.ticks,b.minorTicks,b.alternateBands],function(a){Ka(a)});for(a=e.length;a--;)e[a].destroy();n("stackTotalGroup,axisLine,axisGroup,gridGroup,labelGroup,axisTitle".split(","),function(a){b[a]&&(b[a]=b[a].destroy())})}};wb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=C(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=
a.renderer.label("",0,0,b.shape,null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).add().attr({y:-999});$||this.label.shadow(b.shadow);this.shared=b.shared},destroy:function(){n(this.crosshairs,function(a){a&&a.destroy()});if(this.label)this.label=this.label.destroy();clearTimeout(this.hideTimer);clearTimeout(this.tooltipTimeout)},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden;
r(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:g?(2*f.anchorX+c)/3:c,anchorY:g?(f.anchorY+d)/2:d});e.label.attr(f);if(g&&(N(a-f.x)>1||N(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){var a=this,b;clearTimeout(this.hideTimer);if(!this.isHidden)b=this.chart.hoverPoints,this.hideTimer=setTimeout(function(){a.label.fadeOut();a.isHidden=!0},o(this.options.hideDelay,500)),b&&n(b,function(a){a.setState()}),this.chart.hoverPoints=
null},hideCrosshairs:function(){n(this.crosshairs,function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f=d.plotTop,g=0,h=0,i,a=ja(a);c=a[0].tooltipPos;this.followPointer&&b&&(b.chartX===w&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]);c||(n(a,function(a){i=a.series.yAxis;g+=a.plotX;h+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&i?i.top-f:0)}),g/=a.length,h/=a.length,c=[e?d.plotWidth-h:g,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-g:
h]);return Na(c,t)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=o(this.options.distance,12),j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,l;d<7&&(d=e+s(j,0)+i);d+a>e+g&&(d-=d+a-(e+g),k=c-b+f-i,l=!0);k<f+5&&(k=f+5,l&&c>=k&&c<=k+b&&(k=c+f+i));k+b>f+h&&(k=s(f,f+h-b-i));return{x:d,y:k}},defaultFormatter:function(a){var b=this.points||ja(this),c=b[0].series,d;d=[c.tooltipHeaderFormatter(b[0])];n(b,function(a){c=a.series;d.push(c.tooltipFormatter&&
c.tooltipFormatter(a)||a.point.tooltipFormatter(c.tooltipOptions.pointFormat))});d.push(a.options.footerFormat||"");return d.join("")},refresh:function(a,b){var c=this.chart,d=this.label,e=this.options,f,g,h={},i,j=[];i=e.formatter||this.defaultFormatter;var h=c.hoverPoints,k,l=e.crosshairs,m=this.shared;clearTimeout(this.hideTimer);this.followPointer=ja(a)[0].series.tooltipOptions.followPointer;g=this.getAnchor(a,b);f=g[0];g=g[1];m&&(!a.series||!a.series.noSharedTooltip)?(c.hoverPoints=a,h&&n(h,
function(a){a.setState()}),n(a,function(a){a.setState("hover");j.push(a.getLabelConfig())}),h={x:a[0].category,y:a[0].y},h.points=j,a=a[0]):h=a.getLabelConfig();i=i.call(h,this);h=a.series;i===!1?this.hide():(this.isHidden&&(Wa(d),d.attr("opacity",1).show()),d.attr({text:i}),k=e.borderColor||a.color||h.color||"#606060",d.attr({stroke:k}),this.updatePosition({plotX:f,plotY:g}),this.isHidden=!1);if(l){l=ja(l);for(d=l.length;d--;)if(m=a.series,e=m[d?"yAxis":"xAxis"],l[d]&&e)if(h=d?o(a.stackY,a.y):a.x,
e.isLog&&(h=na(h)),d===1&&m.modifyValue&&(h=m.modifyValue(h)),e=e.getPlotLinePath(h,1),this.crosshairs[d])this.crosshairs[d].attr({d:e,visibility:"visible"});else{h={"stroke-width":l[d].width||1,stroke:l[d].color||"#C0C0C0",zIndex:l[d].zIndex||2};if(l[d].dashStyle)h.dashstyle=l[d].dashStyle;this.crosshairs[d]=c.renderer.path(e).attr(h).add()}}z(c,"tooltipRefresh",{text:i,x:f+c.plotLeft,y:g+c.plotTop,borderColor:k})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||
this.getPosition).call(this,c.width,c.height,a);this.move(t(c.x),t(c.y),a.plotX+b.plotLeft,a.plotY+b.plotTop)}};xb.prototype={init:function(a,b){var c=b.chart,d=c.events,e=$?"":c.zoomType,c=a.inverted,f;this.options=b;this.chart=a;this.zoomX=f=/x/.test(e);this.zoomY=e=/y/.test(e);this.zoomHor=f&&!c||e&&c;this.zoomVert=e&&!c||f&&c;this.runChartClick=d&&!!d.click;this.pinchDown=[];this.lastValidTouch={};if(b.tooltip.enabled)a.tooltip=new wb(a,b.tooltip);this.setDOMEvents()},normalize:function(a,b){var c,
d,a=a||O.event;if(!a.target)a.target=a.srcElement;a=Xb(a);d=a.touches?a.touches.item(0):a;if(!b)this.chartPosition=b=Wb(this.chart.container);d.pageX===w?(c=s(a.x,a.clientX-b.left),d=a.y):(c=d.pageX-b.left,d=d.pageY-b.top);return r(a,{chartX:t(c),chartY:t(d)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};n(this.chart.axes,function(c){b[c.isXAxis?"xAxis":"yAxis"].push({axis:c,value:c.toValue(a[c.horiz?"chartX":"chartY"])})});return b},getIndex:function(a){var b=this.chart;return b.inverted?
b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},runPointActions:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g||!g.noSharedTooltip)){e=[];h=c.length;for(i=0;i<h;i++)if(c[i].visible&&c[i].options.enableMouseTracking!==!1&&!c[i].noSharedTooltip&&c[i].tooltipPoints.length&&(b=c[i].tooltipPoints[k])&&b.series)b._dist=N(k-b.clientX),j=I(j,b._dist),e.push(b);for(h=e.length;h--;)e[h]._dist>
j&&e.splice(h,1);if(e.length&&e[0].clientX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].clientX}if(g&&g.tracker){if((b=g.tooltipPoints[k])&&b!==f)b.onMouseOver(a)}else d&&d.followPointer&&!d.isHidden&&(a=d.getAnchor([{}],a),d.updatePosition({plotX:a[0],plotY:a[1]}))},reset:function(a){var b=this.chart,c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&&ja(b)[0].plotX===w&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());
this.hoverX=null}},scaleGroups:function(a,b){var c=this.chart,d;n(c.series,function(e){d=a||e.getPlotBox();e.xAxis&&e.xAxis.zoomEnabled&&(e.group.attr(d),e.markerGroup&&(e.markerGroup.attr(d),e.markerGroup.clip(b?c.clipRect:null)),e.dataLabelsGroup&&e.dataLabelsGroup.attr(d))});c.clipRect.attr(b||c.clipBox)},pinchTranslateDirection:function(a,b,c,d,e,f,g){var h=this.chart,i=a?"x":"y",j=a?"X":"Y",k="chart"+j,l=a?"width":"height",m=h["plot"+(a?"Left":"Top")],p,q,o=1,n=h.inverted,s=h.bounds[a?"h":"v"],
t=b.length===1,u=b[0][k],r=c[0][k],w=!t&&b[1][k],v=!t&&c[1][k],x,c=function(){!t&&N(u-w)>20&&(o=N(r-v)/N(u-w));q=(m-r)/o+u;p=h["plot"+(a?"Width":"Height")]/o};c();b=q;b<s.min?(b=s.min,x=!0):b+p>s.max&&(b=s.max-p,x=!0);x?(r-=0.8*(r-g[i][0]),t||(v-=0.8*(v-g[i][1])),c()):g[i]=[r,v];n||(f[i]=q-m,f[l]=p);f=n?1/o:o;e[l]=p;e[i]=b;d[n?a?"scaleY":"scaleX":"scale"+j]=o;d["translate"+j]=f*m+(r-f*u)},pinch:function(a){var b=this,c=b.chart,d=b.pinchDown,e=c.tooltip&&c.tooltip.options.followTouchMove,f=a.touches,
g=f.length,h=b.lastValidTouch,i=b.zoomHor||b.pinchHor,j=b.zoomVert||b.pinchVert,k=i||j,l=b.selectionMarker,m={},p=g===1&&(b.inClass(a.target,"highcharts-tracker")&&c.runTrackerClick||c.runChartClick),q={};(k||e)&&!p&&a.preventDefault();Na(f,function(a){return b.normalize(a)});if(a.type==="touchstart")n(f,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),h.x=[d[0].chartX,d[1]&&d[1].chartX],h.y=[d[0].chartY,d[1]&&d[1].chartY],n(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?"h":"v"],
d=a.minPixelPadding,e=a.toPixels(a.dataMin),f=a.toPixels(a.dataMax),g=I(e,f),e=s(e,f);b.min=I(a.pos,g-d);b.max=s(a.pos+a.len,e+d)}});else if(d.length){if(!l)b.selectionMarker=l=r({destroy:pa},c.plotBox);i&&b.pinchTranslateDirection(!0,d,f,m,l,q,h);j&&b.pinchTranslateDirection(!1,d,f,m,l,q,h);b.hasPinched=k;b.scaleGroups(m,q);!k&&e&&g===1&&this.runPointActions(b.normalize(a))}},dragStart:function(a){var b=this.chart;b.mouseIsDown=a.type;b.cancelClick=!1;b.mouseDownX=this.mouseDownX=a.chartX;b.mouseDownY=
this.mouseDownY=a.chartY},drag:function(a){var b=this.chart,c=b.options.chart,d=a.chartX,e=a.chartY,f=this.zoomHor,g=this.zoomVert,h=b.plotLeft,i=b.plotTop,j=b.plotWidth,k=b.plotHeight,l,m=this.mouseDownX,p=this.mouseDownY;d<h?d=h:d>h+j&&(d=h+j);e<i?e=i:e>i+k&&(e=i+k);this.hasDragged=Math.sqrt(Math.pow(m-d,2)+Math.pow(p-e,2));if(this.hasDragged>10){l=b.isInsidePlot(m-h,p-i);if(b.hasCartesianSeries&&(this.zoomX||this.zoomY)&&l&&!this.selectionMarker)this.selectionMarker=b.renderer.rect(h,i,f?1:j,g?
1:k,0).attr({fill:c.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add();this.selectionMarker&&f&&(d-=m,this.selectionMarker.attr({width:N(d),x:(d>0?0:d)+m}));this.selectionMarker&&g&&(d=e-p,this.selectionMarker.attr({height:N(d),y:(d>0?0:d)+p}));l&&!this.selectionMarker&&c.panning&&b.pan(a,c.panning)}},drop:function(a){var b=this.chart,c=this.hasPinched;if(this.selectionMarker){var d={xAxis:[],yAxis:[],originalEvent:a.originalEvent||a},e=this.selectionMarker,f=e.x,g=e.y,h;if(this.hasDragged||
c)n(b.axes,function(a){if(a.zoomEnabled){var b=a.horiz,c=a.toValue(b?f:g),b=a.toValue(b?f+e.width:g+e.height);!isNaN(c)&&!isNaN(b)&&(d[a.xOrY+"Axis"].push({axis:a,min:I(c,b),max:s(c,b)}),h=!0)}}),h&&z(b,"selection",d,function(a){b.zoom(r(a,c?{animation:!1}:null))});this.selectionMarker=this.selectionMarker.destroy();c&&this.scaleGroups()}if(b)K(b.container,{cursor:b._cursor}),b.cancelClick=this.hasDragged>10,b.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[]},onContainerMouseDown:function(a){a=
this.normalize(a);a.preventDefault&&a.preventDefault();this.dragStart(a)},onDocumentMouseUp:function(a){this.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,d=b.hoverSeries,a=this.normalize(a,c);c&&d&&!this.inClass(a.target,"highcharts-tracker")&&!b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.reset()},onContainerMouseLeave:function(){this.reset();this.chartPosition=null},onContainerMouseMove:function(a){var b=this.chart,a=this.normalize(a);a.returnValue=
!1;b.mouseIsDown==="mousedown"&&this.drag(a);(this.inClass(a.target,"highcharts-tracker")||b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop))&&!b.openMenu&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c=v(a,"class"))if(c.indexOf(b)!==-1)return!0;else if(c.indexOf("highcharts-container")!==-1)return!1;a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries;if(b&&!b.options.stickyTracking&&!this.inClass(a.toElement||a.relatedTarget,"highcharts-tooltip"))b.onMouseOut()},
onContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,f=b.inverted,g,h,i,a=this.normalize(a);a.cancelBubble=!0;if(!b.cancelClick)c&&this.inClass(a.target,"highcharts-tracker")?(g=this.chartPosition,h=c.plotX,i=c.plotY,r(c,{pageX:g.left+d+(f?b.plotWidth-i:h),pageY:g.top+e+(f?b.plotHeight-h:i)}),z(c.series,"click",r(a,{point:c})),b.hoverPoint&&c.firePointEvent("click",a)):(r(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-e)&&z(b,"click",a))},onContainerTouchStart:function(a){var b=
this.chart;a.touches.length===1?(a=this.normalize(a),b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)?(this.runPointActions(a),this.pinch(a)):this.reset()):a.touches.length===2&&this.pinch(a)},onContainerTouchMove:function(a){(a.touches.length===1||a.touches.length===2)&&this.pinch(a)},onDocumentTouchEnd:function(a){this.drop(a)},setDOMEvents:function(){var a=this,b=a.chart.container,c;this._events=c=[[b,"onmousedown","onContainerMouseDown"],[b,"onmousemove","onContainerMouseMove"],[b,"onclick",
"onContainerClick"],[b,"mouseleave","onContainerMouseLeave"],[y,"mousemove","onDocumentMouseMove"],[y,"mouseup","onDocumentMouseUp"]];ib&&c.push([b,"ontouchstart","onContainerTouchStart"],[b,"ontouchmove","onContainerTouchMove"],[y,"touchend","onDocumentTouchEnd"]);n(c,function(b){a["_"+b[2]]=function(c){a[b[2]](c)};b[1].indexOf("on")===0?b[0][b[1]]=a["_"+b[2]]:J(b[0],b[1],a["_"+b[2]])})},destroy:function(){var a=this;n(a._events,function(b){b[1].indexOf("on")===0?b[0][b[1]]=null:aa(b[0],b[1],a["_"+
b[2]])});delete a._events;clearInterval(a.tooltipTimeout)}};eb.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=o(b.padding,8),f=b.itemMarginTop||0;this.options=b;if(b.enabled)c.baseline=C(d.fontSize)+3+f,c.itemStyle=d,c.itemHiddenStyle=x(d,b.itemHiddenStyle),c.itemMarginTop=f,c.padding=e,c.initialItemX=e,c.initialItemY=e-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.lastLineHeight=0,c.render(),J(c.chart,"endResize",function(){c.positionCheckboxes()})},colorizeItem:function(a,b){var c=this.options,
d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c,color:c});e&&e.attr({stroke:h});if(f){if(g&&f.isMarker)for(j in g=a.convertAttribs(g),g)d=g[j],d!==w&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=
e,f.y=d},destroyItem:function(a){var b=a.checkbox;n(["legendItem","legendLine","legendSymbol","legendGroup"],function(b){a[b]&&(a[b]=a[b].destroy())});b&&Ta(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()},positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight;if(b)c=b.translateY,n(this.allItems,function(e){var f=e.checkbox,g;f&&(g=c+f.y+(a||0)+3,K(f,{left:b.translateX+e.legendItemWidth+f.x-
20+"px",top:g+"px",display:g>c-6&&g<c+d-6?"":S}))})},renderTitle:function(){var a=this.padding,b=this.options.title,c=0;if(b.text){if(!this.title)this.title=this.chart.renderer.label(b.text,a-3,a-4,null,null,null,null,null,"legend-title").attr({zIndex:1}).css(b.style).add(this.group);a=this.title.getBBox();c=a.height;this.offsetWidth=a.width;this.contentGroup.attr({translateY:c})}this.titleHeight=c},renderItem:function(a){var B;var b=this,c=b.chart,d=c.renderer,e=b.options,f=e.layout==="horizontal",
g=e.symbolWidth,h=e.symbolPadding,i=b.itemStyle,j=b.itemHiddenStyle,k=b.padding,l=f?o(e.itemDistance,8):0,m=!e.rtl,p=e.width,q=e.itemMarginBottom||0,n=b.itemMarginTop,A=b.initialItemX,t=a.legendItem,u=a.series||a,r=u.options,w=r.showCheckbox,v=e.useHTML;if(!t&&(a.legendGroup=d.g("legend-item").attr({zIndex:1}).add(b.scrollGroup),u.drawLegendSymbol(b,a),a.legendItem=t=d.text(e.labelFormat?Ca(e.labelFormat,a):e.labelFormatter.call(a),m?g+h:-h,b.baseline,v).css(x(a.visible?i:j)).attr({align:m?"left":
"right",zIndex:2}).add(a.legendGroup),(v?t:a.legendGroup).on("mouseover",function(){a.setState("hover");t.css(b.options.itemHoverStyle)}).on("mouseout",function(){t.css(a.visible?i:j);a.setState()}).on("click",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent("legendItemClick",b,c):z(a,"legendItemClick",b,c)}),b.colorizeItem(a,a.visible),r&&w))a.checkbox=U("input",{type:"checkbox",checked:a.selected,defaultChecked:a.selected},e.itemCheckboxStyle,c.container),
J(a.checkbox,"click",function(b){z(a,"checkboxClick",{checked:b.target.checked},function(){a.select()})});d=t.getBBox();B=a.legendItemWidth=e.itemWidth||g+h+d.width+l+(w?20:0),e=B;b.itemHeight=g=d.height;if(f&&b.itemX-A+e>(p||c.chartWidth-2*k-A))b.itemX=A,b.itemY+=n+b.lastLineHeight+q,b.lastLineHeight=0;b.maxItemWidth=s(b.maxItemWidth,e);b.lastItemY=n+b.itemY+q;b.lastLineHeight=s(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=n+g+q,b.lastLineHeight=g);b.offsetWidth=
p||s((f?b.itemX-A-l:e)+k,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,m=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup);a.renderTitle();e=[];n(b.series,function(a){var b=a.options;b.showInLegend&&!u(b.linkedTo)&&(e=e.concat(a.legendItems||
(b.legendType==="point"?a.data:a)))});Kb(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;n(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight+a.titleHeight;h=a.handleOverflow(h);if(l||m){g+=k;h+=k;if(i){if(g>0&&h>0)i[i.isNew?"attr":"animate"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius,l||0).attr({stroke:j.borderColor,
"stroke-width":l||0,fill:m||S}).add(d).shadow(j.shadow),i.isNew=!0;i[f?"show":"hide"]()}a.legendWidth=g;a.legendHeight=h;n(e,function(b){a.positionItem(b)});f&&d.align(r({width:g,height:h},j),!0,"spacingBox");b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+(e.verticalAlign==="top"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=o(i.animation,!0),k=i.arrowSize||12,l=this.nav;e.layout===
"horizontal"&&(f/=2);g&&(f=I(f,g));if(a>f&&!e.useHTML){this.clipHeight=c=f-20-this.titleHeight;this.pageCount=xa(a/c);this.currentPage=o(this.currentPage,1);this.fullHeight=a;if(!h)h=b.clipRect=d.clipRect(0,0,9999,0),b.contentGroup.clip(h);h.attr({height:c});if(!l)this.nav=l=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,k,k).on("click",function(){b.scroll(-1,j)}).add(l),this.pager=d.text("",15,10).css(i.style).add(l),this.down=d.symbol("triangle-down",0,0,k,k).on("click",
function(){b.scroll(1,j)}).add(l);b.scroll(0);a=f}else if(l)h.attr({height:c.chartHeight}),l.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,h=f.inactiveColor,f=this.pager,i=this.padding;d>c&&(d=c);if(d>0)b!==w&&La(b,this.chart),this.nav.attr({translateX:i,translateY:e+7+this.titleHeight,visibility:"visible"}),this.up.attr({fill:d===1?h:g}).css({cursor:d===
1?"default":"pointer"}),f.attr({text:d+"/"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width,fill:d===c?h:g}).css({cursor:d===c?"default":"pointer"}),e=-I(e*(d-1),this.fullHeight-e+i)+1,this.scrollGroup.animate({translateY:e}),f.attr({text:d+"/"+c}),this.currentPage=d,this.positionCheckboxes(e)}};/Trident.*?11\.0/.test(oa)&&mb(eb.prototype,"positionItem",function(a,b){var c=this;setTimeout(function(){a.call(c,b)})});yb.prototype={init:function(a,b){var c,d=a.series;a.series=null;c=
x(M,a);c.series=a.series=d;d=c.chart;this.margin=this.splashArray("margin",d);this.spacing=this.splashArray("spacing",d);var e=d.events;this.bounds={h:{},v:{}};this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f=this,g;f.index=Ga.length;Ga.push(f);d.reflow!==!1&&J(f,"load",function(){f.initReflow()});if(e)for(g in e)J(f,g,e[g]);f.xAxis=[];f.yAxis=[];f.animation=$?!1:o(d.animation,!0);f.pointCount=0;f.counters=new Jb;f.firstRender()},
initSeries:function(a){var b=this.options.chart;(b=W[a.type||b.type||b.defaultSeriesType])||ka(17,!0);b=new b;b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(b=o(b,!0),z(e,"addSeries",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;e.linkSeries();b&&e.redraw(c)}));return d},addAxis:function(a,b,c,d){var e=b?"xAxis":"yAxis",f=this.options;new db(this,x(a,{index:this[e].length,isX:b}));f[e]=ja(f[e]||{});f[e].push(a);o(c,!0)&&this.redraw(d)},isInsidePlot:function(a,b,
c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&n(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,g,h,i=this.isDirtyBox,j=c.length,k=j,l=this.renderer,m=l.isHidden(),p=[];La(a,this);m&&this.cloneRenderTo();for(this.layOutTitles();k--;)if(a=c[k],a.options.stacking&&(g=!0,a.isDirty)){h=!0;
break}if(h)for(k=j;k--;)if(a=c[k],a.options.stacking)a.isDirty=!0;n(c,function(a){a.isDirty&&a.options.legendType==="point"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;g&&this.getStacks();if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,n(b,function(a){a.setScale()});this.adjustTickAmounts();this.getMargins();n(b,function(a){a.isDirty&&(i=!0)});n(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,p.push(function(){z(a,"afterSetExtremes",r(a.eventArgs,
a.getExtremes()));delete a.eventArgs});(i||g)&&a.redraw()})}i&&this.drawChartBox();n(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.reset&&d.reset(!0);l.draw();z(this,"redraw");m&&this.cloneRenderTo(!0);n(p,function(a){a.call()})},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;if(!c)this.loadingDiv=c=U(Ea,{className:"highcharts-loading"},r(d.style,{zIndex:10,display:S}),this.container),this.loadingSpan=U("span",null,d.labelStyle,c);this.loadingSpan.innerHTML=
a||b.lang.loading;if(!this.loadingShown)K(c,{opacity:0,display:"",left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+"px",height:this.plotHeight+"px"}),Bb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&Bb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){K(b,{display:S})}});this.loadingShown=!1},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;d<b.length;d++)if(b[d].options.id===
a)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++){e=c[d].points||[];for(b=0;b<e.length;b++)if(e[b].id===a)return e[b]}return null},getAxes:function(){var a=this,b=this.options,c=b.xAxis=ja(b.xAxis||{}),b=b.yAxis=ja(b.yAxis||{});n(c,function(a,b){a.index=b;a.isX=!0});n(b,function(a,b){a.index=b});c=c.concat(b);n(c,function(b){new db(a,b)});a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];n(this.series,function(b){a=a.concat(ub(b.points||[],
function(a){return a.selected}))});return a},getSelectedSeries:function(){return ub(this.series,function(a){return a.selected})},getStacks:function(){var a=this;n(a.yAxis,function(a){if(a.stacks&&a.hasVisibleSeries)a.oldStacks=a.stacks});n(a.series,function(b){if(b.options.stacking&&(b.visible===!0||a.options.chart.ignoreHiddenSeries===!1))b.stackKey=b.type+o(b.options.stack,"")})},showResetZoom:function(){var a=this,b=M.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,f=c.relativeTo===
"chart"?null:"plotBox";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,title:b.resetZoomTitle}).add().align(c.position,!1,f)},zoomOut:function(){var a=this;z(a,"selection",{resetSelection:!0},function(){a.zoom()})},zoom:function(a){var b,c=this.pointer,d=!1,e;!a||a.resetSelection?n(this.axes,function(a){b=a.zoom()}):n(a.xAxis.concat(a.yAxis),function(a){var e=a.axis,h=e.isXAxis;if(c[h?"zoomX":"zoomY"]||c[h?"pinchX":"pinchY"])b=
e.zoom(a.min,a.max),e.displayBtn&&(d=!0)});e=this.resetZoomButton;if(d&&!e)this.showResetZoom();else if(!d&&T(e))this.resetZoomButton=e.destroy();b&&this.redraw(o(this.options.chart.animation,a&&a.animation,this.pointCount<100))},pan:function(a,b){var c=this,d=c.hoverPoints,e;d&&n(d,function(a){a.setState()});n(b==="xy"?[1,0]:[1],function(b){var d=a[b?"chartX":"chartY"],h=c[b?"xAxis":"yAxis"][0],i=c[b?"mouseDownX":"mouseDownY"],j=(h.pointRange||0)/2,k=h.getExtremes(),l=h.toValue(i-d,!0)+j,i=h.toValue(i+
c[b?"plotWidth":"plotHeight"]-d,!0)-j;h.series.length&&l>I(k.dataMin,k.min)&&i<s(k.dataMax,k.max)&&(h.setExtremes(l,i,!1,!1,{trigger:"pan"}),e=!0);c[b?"mouseDownX":"mouseDownY"]=d});e&&c.redraw(!1);K(c.container,{cursor:"move"})},setTitle:function(a,b){var f;var c=this,d=c.options,e;e=d.title=x(d.title,a);f=d.subtitle=x(d.subtitle,b),d=f;n([["title",a,e],["subtitle",b,d]],function(a){var b=a[0],d=c[b],e=a[1],a=a[2];d&&e&&(c[b]=d=d.destroy());a&&a.text&&!d&&(c[b]=c.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,
"class":"highcharts-"+b,zIndex:a.zIndex||4}).css(a.style).add())});c.layOutTitles()},layOutTitles:function(){var a=0,b=this.title,c=this.subtitle,d=this.options,e=d.title,d=d.subtitle,f=this.spacingBox.width-44;if(b&&(b.css({width:(e.width||f)+"px"}).align(r({y:15},e),!1,"spacingBox"),!e.floating&&!e.verticalAlign))a=b.getBBox().height,a>=18&&a<=25&&(a=15);c&&(c.css({width:(d.width||f)+"px"}).align(r({y:a+e.margin},d),!1,"spacingBox"),!d.floating&&!d.verticalAlign&&(a=xa(a+c.getBBox().height)));this.titleOffset=
a},getChartSize:function(){var a=this.options.chart,b=this.renderToClone||this.renderTo;this.containerWidth=jb(b,"width");this.containerHeight=jb(b,"height");this.chartWidth=s(0,a.width||this.containerWidth||600);this.chartHeight=s(0,o(a.height,this.containerHeight>19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Ta(b),delete this.renderToClone):(c&&c.parentNode===this.renderTo&&this.renderTo.removeChild(c),this.renderToClone=
b=this.renderTo.cloneNode(0),K(b,{position:"absolute",top:"-9999px",display:"block"}),y.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e="highcharts-"+zb++;if(ea(a))this.renderTo=a=y.getElementById(a);a||ka(13,!0);c=C(v(a,"data-highcharts-chart"));!isNaN(c)&&Ga[c]&&Ga[c].destroy();v(a,"data-highcharts-chart",this.index);a.innerHTML="";a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;
this.container=a=U(Ea,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},r({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0,"-webkit-tap-highlight-color":"rgba(0,0,0,0)"},b.style),this.renderToClone||a);this._cursor=a.style.cursor;this.renderer=b.forExport?new Ha(a,c,d,!0):new Va(a,c,d);$&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.spacing,b,c=this.legend,d=this.margin,e=this.options.legend,
f=o(e.margin,10),g=e.x,h=e.y,i=e.align,j=e.verticalAlign,k=this.titleOffset;this.resetMargins();b=this.axisOffset;if(k&&!u(d[0]))this.plotTop=s(this.plotTop,k+this.options.title.margin+a[0]);if(c.display&&!e.floating)if(i==="right"){if(!u(d[1]))this.marginRight=s(this.marginRight,c.legendWidth-g+f+a[1])}else if(i==="left"){if(!u(d[3]))this.plotLeft=s(this.plotLeft,c.legendWidth+g+f+a[3])}else if(j==="top"){if(!u(d[0]))this.plotTop=s(this.plotTop,c.legendHeight+h+f+a[0])}else if(j==="bottom"&&!u(d[2]))this.marginBottom=
s(this.marginBottom,c.legendHeight-h+f+a[2]);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);this.hasCartesianSeries&&n(this.axes,function(a){a.getOffset()});u(d[3])||(this.plotLeft+=b[3]);u(d[0])||(this.plotTop+=b[0]);u(d[2])||(this.marginBottom+=b[2]);u(d[1])||(this.marginRight+=b[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||jb(d,"width"),h=c.height||jb(d,"height"),a=a?a.target:O;if(!b.hasUserSize&&
g&&h&&(a===O||a===y)){if(g!==b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){if(b.container)b.setSize(g,h,!1),b.hasUserSize=null},100);b.containerWidth=g;b.containerHeight=h}}var b=this,c=b.options.chart,d=b.renderTo,e;b.reflow=a;J(O,"resize",a);J(b,"destroy",function(){aa(O,"resize",a)})},setSize:function(a,b,c){var d=this,e,f,g;d.isResizing+=1;g=function(){d&&z(d,"endResize",null,function(){d.isResizing-=1})};La(c,d);d.oldChartHeight=d.chartHeight;
d.oldChartWidth=d.chartWidth;if(u(a))d.chartWidth=e=s(0,t(a)),d.hasUserSize=!!e;if(u(b))d.chartHeight=f=s(0,t(b));K(d.container,{width:e+"px",height:f+"px"});d.setChartSize(!0);d.renderer.setSize(e,f,c);d.maxTicks=null;n(d.axes,function(a){a.isDirty=!0;a.setScale()});n(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();d.redraw(c);d.oldChartHeight=null;z(d,"resize");Fa===!1?g():setTimeout(g,Fa&&Fa.duration||500)},setChartSize:function(a){var b=this.inverted,c=this.renderer,
d=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=this.spacing,h=this.clipOffset,i,j,k,l;this.plotLeft=i=t(this.plotLeft);this.plotTop=j=t(this.plotTop);this.plotWidth=k=s(0,t(d-i-this.marginRight));this.plotHeight=l=s(0,t(e-j-this.marginBottom));this.plotSizeX=b?l:k;this.plotSizeY=b?k:l;this.plotBorderWidth=f.plotBorderWidth||0;this.spacingBox=c.spacingBox={x:g[3],y:g[0],width:d-g[3]-g[1],height:e-g[0]-g[2]};this.plotBox=c.plotBox={x:i,y:j,width:k,height:l};d=2*P(this.plotBorderWidth/2);
b=xa(s(d,h[3])/2);c=xa(s(d,h[0])/2);this.clipBox={x:b,y:c,width:P(this.plotSizeX-s(d,h[1])/2-b),height:P(this.plotSizeY-s(d,h[2])/2-c)};a||n(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this.spacing,b=this.margin;this.plotTop=o(b[0],a[0]);this.marginRight=o(b[1],a[1]);this.marginBottom=o(b[2],a[2]);this.plotLeft=o(b[3],a[3]);this.axisOffset=[0,0,0,0];this.clipOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,
d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,p,q=this.plotLeft,o=this.plotTop,n=this.plotWidth,s=this.plotHeight,t=this.plotBox,u=this.clipRect,r=this.clipBox;p=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null,null,null,c-p,d-p));else{e={fill:j||S};if(i)e.stroke=a.borderColor,e["stroke-width"]=i;this.chartBackground=b.rect(p/2,p/
2,c-p,d-p,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(t):this.plotBackground=b.rect(q,o,n,s,0).attr({fill:k}).add().shadow(a.plotShadow);if(l)h?h.animate(t):this.plotBGImage=b.image(l,q,o,n,s).add();u?u.animate({width:r.width,height:r.height}):this.clipRect=b.clipRect(r);if(m)g?g.animate(g.crisp(null,q,o,n,s)):this.plotBorder=b.rect(q,o,n,s,0,-m).attr({stroke:a.plotBorderColor,"stroke-width":m,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,
c,d=a.options.series,e,f;n(["inverted","angular","polar"],function(g){c=W[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=W[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},linkSeries:function(){var a=this,b=a.series;n(b,function(a){a.linkedSeries.length=0});n(b,function(b){var d=b.options.linkedTo;if(ea(d)&&(d=d===":previous"?a.series[b.index-1]:a.get(d)))d.linkedSeries.push(b),b.linkedParent=d})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,
e=d.labels,f=d.credits,g;a.setTitle();a.legend=new eb(a,d.legend);a.getStacks();n(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null;n(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox();a.hasCartesianSeries&&n(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g("series-group").attr({zIndex:3}).add();n(a.series,function(a){a.translate();a.setTooltipPoints();a.render()});e.items&&n(e.items,function(b){var d=r(e.style,b.style),
f=C(d.left)+a.plotLeft,g=C(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,g).attr({zIndex:2}).css(d).add()});if(f.enabled&&!a.credits)g=f.href,a.credits=c.text(f.text,0,0).on("click",function(){if(g)location.href=g}).attr({align:f.position.align,zIndex:8}).css(f.style).add().align(f.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;z(a,"destroy");Ga[a.index]=w;a.renderTo.removeAttribute("data-highcharts-chart");aa(a);for(e=
b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();n("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML="",aa(d),f&&Ta(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!Z&&O==O.top&&y.readyState!=="complete"||$&&!O.canvg?($?Tb.push(function(){a.firstRender()},
a.options.global.canvasToolsURL):y.attachEvent("onreadystatechange",function(){y.detachEvent("onreadystatechange",a.firstRender);y.readyState==="complete"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;if(a.isReadyToRender())a.getContainer(),z(a,"init"),a.resetMargins(),a.setChartSize(),a.propFromSeries(),a.getAxes(),n(b.series||[],function(b){a.initSeries(b)}),a.linkSeries(),z(a,"beforeRender"),a.pointer=new xb(a,b),a.render(),a.renderer.draw(),c&&c.apply(a,
[a]),n(a.callbacks,function(b){b.apply(a,[a])}),a.cloneRenderTo(!0),z(a,"load")},splashArray:function(a,b){var c=b[a],c=T(c)?c:[c,c,c,c];return[o(b[a+"Top"],c[0]),o(b[a+"Right"],c[1]),o(b[a+"Bottom"],c[2]),o(b[a+"Left"],c[3])]}};yb.prototype.callbacks=[];var Pa=function(){};Pa.prototype={init:function(a,b,c){this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors,this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length))a.colorCounter=
0;a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=c.pointValKey,a=Pa.prototype.optionsToObject.call(this,a);r(this,a);this.options=this.options?r(this.options,a):a;if(d)this.y=this[d];if(this.x===w&&c)this.x=b===w?c.autoIncrement():b;return this},optionsToObject:function(a){var b,c=this.series,d=c.pointArrayMap||["y"],e=d.length,f=0,g=0;if(typeof a==="number"||a===null)b={y:a};else if(Ia(a)){b={};if(a.length>e){c=typeof a[0];if(c==="string")b.name=a[0];else if(c===
"number")b.x=a[0];f++}for(;g<e;)b[d[g++]]=a[f++]}else if(typeof a==="object"){b=a;if(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}return b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),ga(b,this),!b.length))a.hoverPoints=null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)aa(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a=
"graphic,dataLabel,dataLabelUpper,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series,e=d.chart,a=o(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=c.options.selected=a;d.options.data[qa(c,d.data)]=
c.options;c.setState(a&&"select");b||n(e.getSelectedPoints(),function(a){if(a.selected&&a!==c)a.selected=a.options.selected=!1,d.options.data[qa(a,d.data)]=a.options,a.setState(""),a.firePointEvent("unselect")})})},onMouseOver:function(a){var b=this.series,c=b.chart,d=c.tooltip,e=c.hoverPoint;if(e&&e!==this)e.onMouseOut();this.firePointEvent("mouseOver");d&&(!d.shared||b.noSharedTooltip)&&d.refresh(this,a);this.setState("hover");c.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;
if(!b||qa(this,b)===-1)this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=o(c.valueDecimals,""),e=c.valuePrefix||"",f=c.valueSuffix||"";n(b.pointArrayMap||["y"],function(b){b="{point."+b;if(e||f)a=a.replace(b+"}",e+b+"}"+f);a=a.replace(b+"}",b+":,."+d+"f}")});return Ca(a,{point:this,series:this.series})},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=e.chart,j=e.options,b=o(b,!0);d.firePointEvent("update",
{options:a},function(){d.applyOptions(a);if(T(a)&&(e.getAttribs(),f))a.marker&&a.marker.symbol?d.graphic=f.destroy():f.attr(d.pointAttr[d.state||""]);g=qa(d,h);e.xData[g]=d.x;e.yData[g]=e.toYData?e.toYData(d):d.y;e.zData[g]=d.z;j.data[g]=d.options;e.isDirty=e.isDirtyData=!0;if(!e.fixedBox&&e.hasCartesianSeries)i.isDirtyBox=!0;j.legendType==="point"&&i.legend.destroyItem(d);b&&i.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.points,f=d.chart,g,h=d.data;La(b,f);a=o(a,!0);c.firePointEvent("remove",
null,function(){g=qa(c,h);h.length===e.length&&e.splice(g,1);h.splice(g,1);d.options.data.splice(g,1);d.xData.splice(g,1);d.yData.splice(g,1);d.zData.splice(g,1);c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&f.redraw()})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a==="click"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});z(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=
x(this.series.options.point,this.options).events,b;this.events=a;for(b in a)J(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=Y[d.type].marker&&d.options.marker,g=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,j=d.stateMarkerGraphic,k=this.marker||{},l=d.chart,m=this.pointAttr,a=a||"";if(!(a===this.state||this.selected&&a!=="select"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled))){if(this.graphic)e=f&&this.graphic.symbolName&&
m[a].r,this.graphic.attr(x(m[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a&&h)e=h.radius,k=k.symbol||d.symbol,j&&j.currentSymbol!==k&&(j=j.destroy()),j?j.attr({x:b-e,y:c-e}):(d.stateMarkerGraphic=j=l.renderer.symbol(k,b-e,c-e,2*e,2*e).attr(m[a]).add(d.markerGroup),j.currentSymbol=k);if(j)j[a&&l.isInsidePlot(b,c)?"show":"hide"]()}this.state=a}}};var Q=function(){};Q.prototype={isCartesian:!0,type:"line",pointClass:Pa,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",
fill:"fillColor",r:"radius"},colorCounter:0,init:function(a,b){var c,d,e=a.series;this.chart=a;this.options=b=this.setOptions(b);this.linkedSeries=[];this.bindAxes();r(this,{name:b.name,state:"",pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0});if($)b.animation=!1;d=b.events;for(c in d)J(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1);if(this.isCartesian)a.hasCartesianSeries=
!0;e.push(this);this._i=e.length-1;Kb(e,function(a,b){return o(a.options.index,a._i)-o(b.options.index,a._i)});n(e,function(a,b){a.index=b;a.name=a.name||"Series "+(b+1)})},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&n(["xAxis","yAxis"],function(e){n(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]!==w&&b[e]===d.id||b[e]===w&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0});a[e]||ka(18,!0)})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=o(b,a.pointStart,
0);this.pointInterval=o(this.pointInterval,a.pointInterval,1);this.xIncrement=b+this.pointInterval;return b},getSegments:function(){var a=-1,b=[],c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else n(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type];this.userOptions=a;a=x(d,c.series,
a);this.tooltipOptions=x(b.tooltip,a.tooltip);d.marker===null&&delete a.marker;return a},getColor:function(){var a=this.options,b=this.userOptions,c=this.chart.options.colors,d=this.chart.counters,e;e=a.color||Y[this.type].color;if(!e&&!a.colorByPoint)u(b._colorIndex)?a=b._colorIndex:(b._colorIndex=d.color,a=d.color++),e=c[a];this.color=e;d.wrapColor(c.length)},getSymbol:function(){var a=this.userOptions,b=this.options.marker,c=this.chart,d=c.options.symbols,c=c.counters;this.symbol=b.symbol;if(!this.symbol)u(a._symbolIndex)?
a=a._symbolIndex:(a._symbolIndex=c.symbol,a=c.symbol++),this.symbol=d[a];if(/^url/.test(this.symbol))b.radius=0;c.wrapSymbol(d.length)},drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options,e;e=d.symbolWidth;var f=this.chart.renderer,g=this.legendGroup,a=a.baseline-t(f.fontMetrics(d.itemStyle.fontSize).b*0.3);if(b.lineWidth){d={"stroke-width":b.lineWidth};if(b.dashStyle)d.dashstyle=b.dashStyle;this.legendLine=f.path(["M",0,a,"L",e,a]).attr(d).add(g)}if(c&&c.enabled)b=c.radius,this.legendSymbol=
e=f.symbol(this.symbol,e/2-b,a-b,2*b,2*b).add(g),e.isMarker=!0},addPoint:function(a,b,c,d){var e=this.options,f=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xData,k=this.yData,l=this.zData,m=this.names,p=g&&g.shift||0,q=e.data,s;La(d,i);c&&n([g,h,this.graphNeg,this.areaNeg],function(a){if(a)a.shift=p+1});if(h)h.isArea=!0;b=o(b,!0);d={series:this};this.pointClass.prototype.applyOptions.apply(d,[a]);g=d.x;h=j.length;if(this.requireSorting&&g<j[h-1])for(s=!0;h&&j[h-1]>g;)h--;j.splice(h,0,g);
k.splice(h,0,this.toYData?this.toYData(d):d.y);l.splice(h,0,d.z);if(m)m[g]=d.name;q.splice(h,0,a);s&&(this.data.splice(h,0,null),this.processData());e.legendType==="point"&&this.generatePoints();c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),j.shift(),k.shift(),l.shift(),q.shift()));this.isDirtyData=this.isDirty=!0;b&&(this.getAttribs(),i.redraw())},setData:function(a,b){var c=this.points,d=this.options,e=this.chart,f=null,g=this.xAxis,h=g&&g.categories&&!g.categories.length?[]:null,i;this.xIncrement=
null;this.pointRange=g&&g.categories?1:d.pointRange;this.colorCounter=0;var j=[],k=[],l=[],m=a?a.length:[];i=o(d.turboThreshold,1E3);var p=this.pointArrayMap,p=p&&p.length,q=!!this.toYData;if(i&&m>i){for(i=0;f===null&&i<m;)f=a[i],i++;if(sa(f)){f=o(d.pointStart,0);d=o(d.pointInterval,1);for(i=0;i<m;i++)j[i]=f,k[i]=a[i],f+=d;this.xIncrement=f}else if(Ia(f))if(p)for(i=0;i<m;i++)d=a[i],j[i]=d[0],k[i]=d.slice(1,p+1);else for(i=0;i<m;i++)d=a[i],j[i]=d[0],k[i]=d[1];else ka(12)}else for(i=0;i<m;i++)if(a[i]!==
w&&(d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a[i]]),j[i]=d.x,k[i]=q?this.toYData(d):d.y,l[i]=d.z,h&&d.name))h[d.x]=d.name;ea(k[0])&&ka(14,!0);this.data=[];this.options.data=a;this.xData=j;this.yData=k;this.zData=l;this.names=h;for(i=c&&c.length||0;i--;)c[i]&&c[i].destroy&&c[i].destroy();if(g)g.minRange=g.userMinRange;this.isDirty=this.isDirtyData=e.isDirtyBox=!0;o(b,!0)&&e.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=o(a,!0);if(!c.isRemoving)c.isRemoving=!0,z(c,"remove",
null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;d.linkSeries();a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData,d=b.length,e;e=0;var f,g,h=this.xAxis,i=this.options,j=i.cropThreshold,k=this.isCartesian;if(k&&!this.isDirty&&!h.isDirty&&!this.yAxis.isDirty&&!a)return!1;if(k&&this.sorted&&(!j||d>j||this.forceCrop))if(a=h.min,h=h.max,b[d-1]<a||b[0]>h)b=[],c=[];else if(b[0]<a||b[d-1]>h)e=this.cropData(this.xData,this.yData,a,h),b=e.xData,c=e.yData,e=e.start,
f=!0;for(h=b.length-1;h>=0;h--)d=b[h]-b[h-1],d>0&&(g===w||d<g)?g=d:d<0&&this.requireSorting&&ka(15);this.cropped=f;this.cropStart=e;this.processedXData=b;this.processedYData=c;if(i.pointRange===null)this.pointRange=g||1;this.closestPointRange=g},cropData:function(a,b,c,d){var e=a.length,f=0,g=e,h=o(this.cropShoulder,1),i;for(i=0;i<e;i++)if(a[i]>=c){f=s(0,i-h);break}for(;i<e;i++)if(a[i]>d){g=i+h;break}return{xData:a.slice(f,g),yData:b.slice(f,g),start:f,end:g}},generatePoints:function(){var a=this.options.data,
b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,j=this.hasGroupedData,k,l=[],m;if(!b&&!j)b=[],b.length=a.length,b=this.data=b;for(m=0;m<g;m++)i=h+m,j?l[m]=(new f).init(this,[d[m]].concat(ja(e[m]))):(b[i]?k=b[i]:a[i]!==w&&(b[i]=k=(new f).init(this,a[i],d[m])),l[m]=k);if(b&&(g!==(c=b.length)||j))for(m=0;m<c;m++)if(m===h&&!j&&(m+=g),b[m])b[m].destroyElements(),b[m].plotX=w;this.data=b;this.points=l},setStackedPoints:function(){if(this.options.stacking&&
!(this.visible!==!0&&this.chart.options.chart.ignoreHiddenSeries!==!1)){var a=this.processedXData,b=this.processedYData,c=[],d=b.length,e=this.options,f=e.threshold,g=e.stack,e=e.stacking,h=this.stackKey,i="-"+h,j=this.negStacks,k=this.yAxis,l=k.stacks,m=k.oldStacks,p,q,o,n,t;for(o=0;o<d;o++){n=a[o];t=b[o];q=(p=j&&t<f)?i:h;l[q]||(l[q]={});if(!l[q][n])m[q]&&m[q][n]?(l[q][n]=m[q][n],l[q][n].total=null):l[q][n]=new Mb(k,k.options.stackLabels,p,n,g,e);q=l[q][n];q.points[this.index]=[q.cum||0];e==="percent"?
(p=p?h:i,j&&l[p]&&l[p][n]?(p=l[p][n],q.total=p.total=s(p.total,q.total)+N(t)||0):q.total+=N(t)||0):q.total+=t||0;q.cum=(q.cum||0)+(t||0);q.points[this.index].push(q.cum);c[o]=q.cum}if(e==="percent")k.usePercentage=!0;this.stackedYData=c;k.oldStacks={}}},setPercentStacks:function(){var a=this,b=a.stackKey,c=a.yAxis.stacks;n([b,"-"+b],function(b){var d;for(var e=a.xData.length,f,g;e--;)if(f=a.xData[e],d=(g=c[b]&&c[b][f])&&g.points[a.index],f=d)g=g.total?100/g.total:0,f[0]=ia(f[0]*g),f[1]=ia(f[1]*g),
a.stackedYData[e]=f[1]})},getExtremes:function(){var a=this.yAxis,b=this.processedXData,c=this.stackedYData||this.processedYData,d=c.length,e=[],f=0,g=this.xAxis.getExtremes(),h=g.min,g=g.max,i,j,k,l;for(l=0;l<d;l++)if(j=b[l],k=c[l],i=k!==null&&k!==w&&(!a.isLog||k.length||k>0),j=this.getExtremesFromAll||this.cropped||(b[l+1]||j)>=h&&(b[l-1]||j)<=g,i&&j)if(i=k.length)for(;i--;)k[i]!==null&&(e[f++]=k[i]);else e[f++]=k;this.dataMin=o(void 0,Ja(e));this.dataMax=o(void 0,va(e))},translate:function(){this.processedXData||
this.processData();this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue,i=a.pointPlacement,j=i==="between"||sa(i),k=a.threshold,a=0;a<g;a++){var l=f[a],m=l.x,p=l.y,q=l.low,n=e.stacks[(this.negStacks&&p<k?"-":"")+this.stackKey];if(e.isLog&&p<=0)l.y=p=null;l.plotX=c.translate(m,0,0,0,1,i,this.type==="flags");if(b&&this.visible&&n&&n[m])n=n[m],p=n.points[this.index],q=p[0],p=p[1],q===0&&(q=o(k,e.min)),e.isLog&&
q<=0&&(q=null),l.percentage=b==="percent"&&p,l.total=l.stackTotal=n.total,l.stackY=p,n.setOffset(this.pointXOffset||0,this.barW||0);l.yBottom=u(q)?e.translate(q,0,1,0,1):null;h&&(p=this.modifyValue(p,l));l.plotY=typeof p==="number"&&p!==Infinity?e.translate(p,0,1,0,1):w;l.clientX=j?c.translate(m,0,0,0,1):l.plotX;l.negative=l.y<(k||0);l.category=d&&d[l.x]!==w?d[l.x]:l.x}this.getSegments()},setTooltipPoints:function(a){var b=[],c,d,e=this.xAxis,f=e&&e.getExtremes(),g=e?e.tooltipLen||e.len:this.chart.plotSizeX,
h,i,j=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints=null;n(this.segments||this.points,function(a){b=b.concat(a)});e&&e.reversed&&(b=b.reverse());this.orderTooltipPoints&&this.orderTooltipPoints(b);a=b.length;for(i=0;i<a;i++)if(e=b[i],c=e.x,c>=f.min&&c<=f.max){h=b[i+1];c=d===w?0:d+1;for(d=b[i+1]?I(s(0,P((e.clientX+(h?h.wrappedClientX||h.clientX:g))/2)),g):g;c>=0&&c<=d;)j[c++]=e}this.tooltipPoints=j}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,
d=b.dateTimeLabelFormats,e=this.xAxis,f=e&&e.options.type==="datetime",b=b.headerFormat,e=e&&e.closestPointRange,g;if(f&&!c)if(e)for(g in D){if(D[g]>=e){c=d[g];break}}else c=d.day;f&&c&&sa(a.key)&&(b=b.replace("{point.key}","{point.key:"+c+"}"));return Ca(b,{point:a,series:this})},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&z(this,"mouseOver");this.setState("hover");a.hoverSeries=this},onMouseOut:function(){var a=this.options,
b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&z(this,"mouseOut");c&&!a.stickyTracking&&(!c.shared||this.noSharedTooltip)&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!T(e))e=Y[b.type].animation;h="_sharedClip"+e.duration+e.easing;if(a)a=c[h],e=c[h+"m"],a||(c[h]=a=d.clipRect(r(f,{width:0})),c[h+"m"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?
c.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey=h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+"m"].animate({width:c.plotSizeX+99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()},e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group;c&&this.options.clip!==!1&&(c.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+"m"]=a[b+"m"].destroy())},100)},drawPoints:function(){var a,
b=this.points,c=this.chart,d,e,f,g,h,i,j,k,l=this.options.marker,m,p=this.markerGroup;if(l.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g=b[f],d=P(g.plotX),e=g.plotY,k=g.graphic,i=g.marker||{},a=l.enabled&&i.enabled===w||i.enabled,m=c.isInsidePlot(t(d),e,c.inverted),a&&e!==w&&!isNaN(e)&&g.y!==null)if(a=g.pointAttr[g.selected?"select":""],h=a.r,i=o(i.symbol,this.symbol),j=i.indexOf("url")===0,k)k.attr({visibility:m?Z?"inherit":"visible":"hidden"}).animate(r({x:d-h,y:e-h},k.symbolName?{width:2*
h,height:2*h}:{}));else{if(m&&(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(p)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=o(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=a.options,c=Y[a.type].marker?b.marker:b,d=c.states,e=d.hover,f,g=a.color,h={stroke:g,fill:g},i=a.points||[],j=[],k,l=a.pointAttrToOptions,m=b.negativeColor,p=c.lineColor,q;
b.marker?(e.radius=e.radius||c.radius+2,e.lineWidth=e.lineWidth||c.lineWidth+1):e.color=e.color||ra(e.color||g).brighten(e.brightness).get();j[""]=a.convertAttribs(c,h);n(["hover","select"],function(b){j[b]=a.convertAttribs(d[b],j[""])});a.pointAttr=j;for(g=i.length;g--;){h=i[g];if((c=h.options&&h.options.marker||h.options)&&c.enabled===!1)c.radius=0;if(h.negative&&m)h.color=h.fillColor=m;f=b.colorByPoint||h.color;if(h.options)for(q in l)u(c[l[q]])&&(f=!0);if(f){c=c||{};k=[];d=c.states||{};f=d.hover=
d.hover||{};if(!b.marker)f.color=ra(f.color||h.color).brighten(f.brightness||e.brightness).get();k[""]=a.convertAttribs(r({color:h.color,fillColor:h.color,lineColor:p===null?h.color:w},c),j[""]);k.hover=a.convertAttribs(d.hover,j.hover,k[""]);k.select=a.convertAttribs(d.select,j.select,k[""])}else k=j;h.pointAttr=k}},update:function(a,b){var c=this.chart,d=this.type,e=W[d].prototype,f,a=x(this.userOptions,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},a);this.remove(!1);
for(f in e)e.hasOwnProperty(f)&&(this[f]=w);r(this,W[a.type||d].prototype);this.init(c,a);o(b,!0)&&c.redraw(!1)},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\/533/.test(oa),d,e,f=a.data||[],g,h,i;z(a,"destroy");aa(a);n(["xAxis","yAxis"],function(b){if(i=a[b])ga(i.series,a),i.isDirty=i.forceRedraw=!0,i.stacks={}});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout);n("area,graph,dataLabelsGroup,group,markerGroup,tracker,graphNeg,areaNeg,posClip,negClip".split(","),
function(b){a[b]&&(d=c&&b==="group"?"hide":"destroy",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;ga(b.series,a);for(h in a)delete a[h]},drawDataLabels:function(){var a=this,b=a.options.dataLabels,c=a.points,d,e,f,g;if(b.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(b),g=a.plotGroup("dataLabelsGroup","data-labels",a.visible?"visible":"hidden",b.zIndex||6),e=b,n(c,function(c){var i,j=c.dataLabel,k,l,m=c.connector,p=!0;d=c.options&&c.options.dataLabels;i=o(d&&d.enabled,e.enabled);
if(j&&!i)c.dataLabel=j.destroy();else if(i){b=x(e,d);i=b.rotation;k=c.getLabelConfig();f=b.format?Ca(b.format,k):b.formatter.call(k,b);b.style.color=o(b.color,b.style.color,a.color,"black");if(j)if(u(f))j.attr({text:f}),p=!1;else{if(c.dataLabel=j=j.destroy(),m)c.connector=m.destroy()}else if(u(f)){j={fill:b.backgroundColor,stroke:b.borderColor,"stroke-width":b.borderWidth,r:b.borderRadius||0,rotation:i,padding:b.padding,zIndex:1};for(l in j)j[l]===w&&delete j[l];j=c.dataLabel=a.chart.renderer[i?"text":
"label"](f,0,-999,null,null,null,b.useHTML).attr(j).css(b.style).add(g).shadow(b.shadow)}j&&a.alignDataLabel(c,j,b,null,p)}})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=o(a.plotX,-999),i=o(a.plotY,-999),j=b.getBBox();if(a=this.visible&&f.isInsidePlot(a.plotX,a.plotY,g))d=r({x:g?f.plotWidth-i:h,y:t(g?f.plotHeight-h:i),width:0,height:0},d),r(c,{width:j.width,height:j.height}),c.rotation?(g={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](g)):(b.align(c,
null,d),g=b.alignAttr,o(c.overflow,"justify")==="justify"?this.justifyDataLabel(b,c,g,j,d,e):o(c.crop,!0)&&(a=f.isInsidePlot(g.x,g.y)&&f.isInsidePlot(g.x+j.width,g.y+j.height)));a||b.attr({y:-999})},justifyDataLabel:function(a,b,c,d,e,f){var g=this.chart,h=b.align,i=b.verticalAlign,j,k;j=c.x;if(j<0)h==="right"?b.align="left":b.x=-j,k=!0;j=c.x+d.width;if(j>g.plotWidth)h==="left"?b.align="right":b.x=g.plotWidth-j,k=!0;j=c.y;if(j<0)i==="bottom"?b.verticalAlign="top":b.y=-j,k=!0;j=c.y+d.height;if(j>g.plotHeight)i===
"top"?b.verticalAlign="bottom":b.y=g.plotHeight-j,k=!0;if(k)a.placed=!f,a.align(b,null,e)},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;n(a,function(e,f){var g=e.plotX,h=e.plotY,i;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?"L":"M"),d&&f&&(i=a[f-1],d==="right"?c.push(i.plotX,h):d==="center"?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];n(a.segments,function(e){c=
a.getSegmentPath(e);e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints=d;return a.graphPath=b},drawGraph:function(){var a=this,b=this.options,c=[["graph",b.lineColor||this.color]],d=b.lineWidth,e=b.dashStyle,f=this.getGraphPath(),g=b.negativeColor;g&&c.push(["graphNeg",g]);n(c,function(c,g){var j=c[0],k=a[j];if(k)Wa(k),k.animate({d:f});else if(d&&f.length)k={stroke:c[1],"stroke-width":d,zIndex:1},e?k.dashstyle=e:k["stroke-linecap"]=k["stroke-linejoin"]="round",a[j]=a.chart.renderer.path(f).attr(k).add(a.group).shadow(!g&&
b.shadow)})},clipNeg:function(){var a=this.options,b=this.chart,c=b.renderer,d=a.negativeColor||a.negativeFillColor,e,f=this.graph,g=this.area,h=this.posClip,i=this.negClip;e=b.chartWidth;var j=b.chartHeight,k=s(e,j),l=this.yAxis;if(d&&(f||g)){d=t(l.toPixels(a.threshold||0,!0));a={x:0,y:0,width:k,height:d};k={x:0,y:d,width:k,height:k};if(b.inverted)a.height=k.y=b.plotWidth-d,c.isVML&&(a={x:b.plotWidth-d-b.plotLeft,y:0,width:e,height:j},k={x:d+b.plotLeft-e,y:0,width:b.plotLeft+d,height:e});l.reversed?
(b=k,e=a):(b=a,e=k);h?(h.animate(b),i.animate(e)):(this.posClip=h=c.clipRect(b),this.negClip=i=c.clipRect(e),f&&this.graphNeg&&(f.clip(h),this.graphNeg.clip(i)),g&&(g.clip(h),this.areaNeg.clip(i)))}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};n(["group","markerGroup"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;if(b.xAxis)J(c,"resize",a),J(b,"destroy",function(){aa(c,"resize",a)}),a(),b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],
g=!f;g&&(this[a]=f=this.chart.renderer.g(b).attr({visibility:c,zIndex:d||0.1}).add(e));f[g?"attr":"animate"](this.getPlotBox());return f},getPlotBox:function(){return{translateX:this.xAxis?this.xAxis.left:this.chart.plotLeft,translateY:this.yAxis?this.yAxis.top:this.chart.plotTop,scaleX:1,scaleY:1}},render:function(){var a=this.chart,b,c=this.options,d=c.animation&&!!this.animate&&a.renderer.isSVG,e=this.visible?"visible":"hidden",f=c.zIndex,g=this.hasRendered,h=a.seriesGroup;b=this.plotGroup("group",
"series",e,f,h);this.markerGroup=this.plotGroup("markerGroup","markers",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=this.isCartesian?a.inverted:!1;this.drawGraph&&(this.drawGraph(),this.clipNeg());this.drawDataLabels();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&&b.clip(a.clipRect);d?this.animate():g||this.afterAnimate();this.isDirty=this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=
this.chart,b=this.isDirtyData,c=this.group,d=this.xAxis,e=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:o(d&&d.left,a.plotLeft),translateY:o(e&&e.top,a.plotTop)}));this.translate();this.setTooltipPoints(!0);this.render();b&&z(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph,d=this.graphNeg,e=b.states,b=b.lineWidth,a=a||"";if(this.state!==a)this.state=a,e[a]&&e[a].enabled===!1||(a&&(b=e[a].lineWidth||b+1),c&&!c.dashstyle&&
(a={"stroke-width":b},c.attr(a),d&&d.attr(a)))},setVisible:function(a,b){var c=this,d=c.chart,e=c.legendItem,f,g=d.options.chart.ignoreHiddenSeries,h=c.visible;f=(c.visible=a=c.userOptions.visible=a===w?!h:a)?"show":"hide";n(["group","dataLabelsGroup","markerGroup","tracker"],function(a){if(c[a])c[a][f]()});if(d.hoverSeries===c)c.onMouseOut();e&&d.legend.colorizeItem(c,a);c.isDirty=!0;c.options.stacking&&n(d.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});n(c.linkedSeries,function(b){b.setVisible(a,
!1)});if(g)d.isDirtyBox=!0;b!==!1&&d.redraw();z(c,f)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===w?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;z(this,a?"select":"unselect")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.pointer,h=f.renderer,i=f.options.tooltip.snap,j=a.tracker,k=b.cursor,l=k&&{cursor:k},k=a.singlePoints,m,p=function(){if(f.hoverSeries!==
a)a.onMouseOver()};if(e&&!c)for(m=e+1;m--;)d[m]==="M"&&d.splice(m+1,0,d[m+1]-i,d[m+2],"L"),(m&&d[m]==="M"||m===e)&&d.splice(m,0,"L",d[m-2]+i,d[m-1]);for(m=0;m<k.length;m++)e=k[m],d.push("M",e.plotX-i,e.plotY,"L",e.plotX+i,e.plotY);j?j.attr({d:d}):(a.tracker=h.path(d).attr({"stroke-linejoin":"round",visibility:a.visible?"visible":"hidden",stroke:Qb,fill:c?Qb:S,"stroke-width":b.lineWidth+(c?0:2*i),zIndex:2}).add(a.group),n([a.tracker,a.markerGroup],function(a){a.addClass("highcharts-tracker").on("mouseover",
p).on("mouseout",function(a){g.onTrackerMouseOut(a)}).css(l);if(ib)a.on("touchstart",p)}))}};G=ha(Q);W.line=G;Y.area=x(X,{threshold:0});G=ha(Q,{type:"area",getSegments:function(){var a=[],b=[],c=[],d=this.xAxis,e=this.yAxis,f=e.stacks[this.stackKey],g={},h,i,j=this.points,k=this.options.connectNulls,l,m,p;if(this.options.stacking&&!this.cropped){for(m=0;m<j.length;m++)g[j[m].x]=j[m];for(p in f)c.push(+p);c.sort(function(a,b){return a-b});n(c,function(a){if(!k||g[a]&&g[a].y!==null)g[a]?b.push(g[a]):
(h=d.translate(a),l=f[a].percent?f[a].total?f[a].cum*100/f[a].total:0:f[a].cum,i=e.toPixels(l,!0),b.push({y:null,plotX:h,clientX:h,plotY:i,yBottom:i,onMouseOver:pa}))});b.length&&a.push(b)}else Q.prototype.getSegments.call(this),a=this.segments;this.segments=a},getSegmentPath:function(a){var b=Q.prototype.getSegmentPath.call(this,a),c=[].concat(b),d,e=this.options;d=b.length;var f=this.yAxis.getThreshold(e.threshold),g;d===3&&c.push("L",b[1],b[2]);if(e.stacking&&!this.closedStacks)for(d=a.length-
1;d>=0;d--)g=o(a[d].yBottom,f),d<a.length-1&&e.step&&c.push(a[d+1].plotX,g),c.push(a[d].plotX,g);else this.closeSegment(c,a,f);this.areaPath=this.areaPath.concat(c);return b},closeSegment:function(a,b,c){a.push("L",b[b.length-1].plotX,c,"L",b[0].plotX,c)},drawGraph:function(){this.areaPath=[];Q.prototype.drawGraph.apply(this);var a=this,b=this.areaPath,c=this.options,d=c.negativeColor,e=c.negativeFillColor,f=[["area",this.color,c.fillColor]];(d||e)&&f.push(["areaNeg",d,e]);n(f,function(d){var e=d[0],
f=a[e];f?f.animate({d:b}):a[e]=a.chart.renderer.path(b).attr({fill:o(d[2],ra(d[1]).setOpacity(o(c.fillOpacity,0.75)).get()),zIndex:0}).add(a.group)})},drawLegendSymbol:function(a,b){b.legendSymbol=this.chart.renderer.rect(0,a.baseline-11,a.options.symbolWidth,12,2).attr({zIndex:3}).add(b.legendGroup)}});W.area=G;Y.spline=x(X);F=ha(Q,{type:"spline",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,j,k;if(f&&g){a=f.plotY;j=g.plotX;var g=g.plotY,l;h=(1.5*d+f.plotX)/2.5;i=(1.5*
e+a)/2.5;j=(1.5*d+j)/2.5;k=(1.5*e+g)/2.5;l=(k-i)*(j-d)/(j-h)+e-k;i+=l;k+=l;i>a&&i>e?(i=s(a,e),k=2*e-i):i<a&&i<e&&(i=I(a,e),k=2*e-i);k>g&&k>e?(k=s(g,e),i=2*e-k):k<g&&k<e&&(k=I(g,e),i=2*e-k);b.rightContX=j;b.rightContY=k}c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=["M",d,e];return b}});W.spline=F;Y.areaspline=x(Y.area);ma=G.prototype;F=ha(F,{type:"areaspline",closedStacks:!0,getSegmentPath:ma.getSegmentPath,closeSegment:ma.closeSegment,drawGraph:ma.drawGraph,
drawLegendSymbol:ma.drawLegendSymbol});W.areaspline=F;Y.column=x(X,{borderColor:"#FFFFFF",borderWidth:1,borderRadius:0,groupPadding:0.2,marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},stickyTracking:!1,threshold:0});F=ha(Q,{type:"column",pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",
r:"borderRadius"},cropShoulder:0,trackerGroups:["group","dataLabelsGroup"],negStacks:!0,init:function(){Q.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0})},getColumnMetrics:function(){var a=this,b=a.options,c=a.xAxis,d=a.yAxis,e=c.reversed,f,g={},h,i=0;b.grouping===!1?i=1:n(a.chart.series,function(b){var c=b.options,e=b.yAxis;if(b.type===a.type&&b.visible&&d.len===e.len&&d.pos===e.pos)c.stacking?(f=b.stackKey,g[f]===
w&&(g[f]=i++),h=g[f]):c.grouping!==!1&&(h=i++),b.columnIndex=h});var c=I(N(c.transA)*(c.ordinalSlope||b.pointRange||c.closestPointRange||1),c.len),j=c*b.groupPadding,k=(c-2*j)/i,l=b.pointWidth,b=u(l)?(k-l)/2:k*b.pointPadding,l=o(l,k-2*b);return a.columnMetrics={width:l,offset:b+(j+((e?i-(a.columnIndex||0):a.columnIndex)||0)*k-c/2)*(e?-1:1)}},translate:function(){var a=this.chart,b=this.options,c=b.borderWidth,d=this.yAxis,e=this.translatedThreshold=d.getThreshold(b.threshold),f=o(b.minPointLength,
5),b=this.getColumnMetrics(),g=b.width,h=this.barW=xa(s(g,1+2*c)),i=this.pointXOffset=b.offset,j=-(c%2?0.5:0),k=c%2?0.5:1;a.renderer.isVML&&a.inverted&&(k+=1);Q.prototype.translate.apply(this);n(this.points,function(a){var b=o(a.yBottom,e),c=I(s(-999-b,a.plotY),d.len+999+b),n=a.plotX+i,u=h,r=I(c,b),w,c=s(c,b)-r;N(c)<f&&f&&(c=f,r=t(N(r-e)>f?b-f:e-(d.translate(a.y,0,1,0,1)<=e?f:0)));a.barX=n;a.pointWidth=g;b=N(n)<0.5;u=t(n+u)+j;n=t(n)+j;u-=n;w=N(r)<0.5;c=t(r+c)+k;r=t(r)+k;c-=r;b&&(n+=1,u-=1);w&&(r-=
1,c+=1);a.shapeType="rect";a.shapeArgs={x:n,y:r,width:u,height:c}})},getSymbol:pa,drawLegendSymbol:G.prototype.drawLegendSymbol,drawGraph:pa,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;n(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==w&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(Wa(g),g.animate(x(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected?"select":""]).add(a.group).shadow(b.shadow,null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){var a=
this,b=a.chart,c=b.pointer,d=a.options.cursor,e=d&&{cursor:d},f=function(c){var d=c.target,e;if(b.hoverSeries!==a)a.onMouseOver();for(;d&&!e;)e=d.point,d=d.parentNode;if(e!==w&&e!==b.hoverPoint)e.onMouseOver(c)};n(a.points,function(a){if(a.graphic)a.graphic.element.point=a;if(a.dataLabel)a.dataLabel.element.point=a});if(!a._hasTracking)n(a.trackerGroups,function(b){if(a[b]&&(a[b].addClass("highcharts-tracker").on("mouseover",f).on("mouseout",function(a){c.onTrackerMouseOut(a)}).css(e),ib))a[b].on("touchstart",
f)}),a._hasTracking=!0},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.dlBox||a.shapeArgs,i=a.below||a.plotY>o(this.translatedThreshold,f.plotSizeY),j=o(c.inside,!!this.options.stacking);if(h&&(d=x(h),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!j))g?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0);c.align=o(c.align,!g||j?"center":i?"right":"left");c.verticalAlign=o(c.verticalAlign,g||j?"middle":i?"top":"bottom");Q.prototype.alignDataLabel.call(this,
a,b,c,d,e)},animate:function(a){var b=this.yAxis,c=this.options,d=this.chart.inverted,e={};if(Z)a?(e.scaleY=0.001,a=I(b.pos+b.len,s(b.pos,b.toPixels(c.threshold))),d?e.translateX=a-b.len:e.translateY=a,this.group.attr(e)):(e.scaleY=1,e[d?"translateX":"translateY"]=b.pos,this.group.animate(e,this.options.animation),this.animate=null)},remove:function(){var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0});Q.prototype.remove.apply(a,arguments)}});W.column=F;Y.bar=
x(Y.column);ma=ha(F,{type:"bar",inverted:!0});W.bar=ma;Y.scatter=x(X,{lineWidth:0,tooltip:{headerFormat:'<span style="font-size: 10px; color:{series.color}">{series.name}</span><br/>',pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>",followPointer:!0},stickyTracking:!1});ma=ha(Q,{type:"scatter",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["markerGroup"],drawTracker:F.prototype.drawTracker,setTooltipPoints:pa});W.scatter=ma;Y.pie=x(X,{borderColor:"#FFFFFF",borderWidth:1,
center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}});X={type:"pie",isCartesian:!1,pointClass:ha(Pa,{init:function(){Pa.prototype.init.apply(this,arguments);var a=this,b;if(a.y<0)a.y=null;r(a,{visible:a.visible!==!1,name:o(a.name,"Slice")});b=function(b){a.slice(b.type===
"select")};J(a,"select",b);J(a,"unselect",b);return a},setVisible:function(a){var b=this,c=b.series,d=c.chart,e;b.visible=b.options.visible=a=a===w?!b.visible:a;c.options.data[qa(b,c.data)]=b.options;e=a?"show":"hide";n(["graphic","dataLabel","connector","shadowGroup"],function(a){if(b[a])b[a][e]()});b.legendItem&&d.legend.colorizeItem(b,a);if(!c.isDirty&&c.options.ignoreHiddenPoint)c.isDirty=!0,d.redraw()},slice:function(a,b,c){var d=this.series;La(c,d.chart);o(b,!0);this.sliced=this.options.sliced=
a=u(a)?a:!this.sliced;d.options.data[qa(this,d.data)]=this.options;a=a?this.slicedTranslation:{translateX:0,translateY:0};this.graphic.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:pa,animate:function(a){var b=this,c=b.points,d=b.startAngleRad;if(!a)n(c,function(a){var c=a.graphic,a=a.shapeArgs;c&&(c.attr({r:b.center[3]/
2,start:d,end:d}),c.animate({r:a.r,start:a.start,end:a.end},b.options.animation))}),b.animate=null},setData:function(a,b){Q.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();o(b,!0)&&this.chart.redraw()},generatePoints:function(){var a,b=0,c,d,e,f=this.options.ignoreHiddenPoint;Q.prototype.generatePoints.call(this);c=this.points;d=c.length;for(a=0;a<d;a++)e=c[a],b+=f&&!e.visible?0:e.y;this.total=b;for(a=0;a<d;a++)e=c[a],e.percentage=b>0?e.y/b*100:0,e.total=b},getCenter:function(){var a=
this.options,b=this.chart,c=2*(a.slicedOffset||0),d,e=b.plotWidth-2*c,f=b.plotHeight-2*c,b=a.center,a=[o(b[0],"50%"),o(b[1],"50%"),a.size||"100%",a.innerSize||0],g=I(e,f),h;return Na(a,function(a,b){h=/%$/.test(a);d=b<2||b===2&&h;return(h?[e,f,g,g][b]*C(a)/100:a)+(d?c:0)})},translate:function(a){this.generatePoints();var b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g,h,i=c.startAngle||0,j=this.startAngleRad=ya/180*(i-90),i=(this.endAngleRad=ya/180*((c.endAngle||i+360)-90))-j,k=this.points,
l=c.dataLabels.distance,c=c.ignoreHiddenPoint,m,n=k.length,o;if(!a)this.center=a=this.getCenter();this.getX=function(b,c){h=R.asin((b-a[1])/(a[2]/2+l));return a[0]+(c?-1:1)*V(h)*(a[2]/2+l)};for(m=0;m<n;m++){o=k[m];f=j+b*i;if(!c||o.visible)b+=o.percentage/100;g=j+b*i;o.shapeType="arc";o.shapeArgs={x:a[0],y:a[1],r:a[2]/2,innerR:a[3]/2,start:t(f*1E3)/1E3,end:t(g*1E3)/1E3};h=(g+f)/2;h>0.75*i&&(h-=2*ya);o.slicedTranslation={translateX:t(V(h)*d),translateY:t(ca(h)*d)};f=V(h)*a[2]/2;g=ca(h)*a[2]/2;o.tooltipPos=
[a[0]+f*0.7,a[1]+g*0.7];o.half=h<-ya/2||h>ya/2?1:0;o.angle=h;e=I(e,l/2);o.labelPos=[a[0]+f+V(h)*l,a[1]+g+ca(h)*l,a[0]+f+V(h)*e,a[1]+g+ca(h)*e,a[0]+f,a[1]+g,l<0?"center":o.half?"right":"left",h]}},setTooltipPoints:pa,drawGraph:null,drawPoints:function(){var a=this,b=a.chart.renderer,c,d,e=a.options.shadow,f,g;if(e&&!a.shadowGroup)a.shadowGroup=b.g("shadow").add(a.group);n(a.points,function(h){d=h.graphic;g=h.shapeArgs;f=h.shadowGroup;if(e&&!f)f=h.shadowGroup=b.g("shadow").add(a.shadowGroup);c=h.sliced?
h.slicedTranslation:{translateX:0,translateY:0};f&&f.attr(c);d?d.animate(r(g,c)):h.graphic=d=b.arc(g).setRadialReference(a.center).attr(h.pointAttr[h.selected?"select":""]).attr({"stroke-linejoin":"round"}).attr(c).add(a.group).shadow(e,f);h.visible===!1&&h.setVisible(!1)})},sortByAngle:function(a,b){a.sort(function(a,d){return a.angle!==void 0&&(d.angle-a.angle)*b})},drawDataLabels:function(){var a=this,b=a.data,c,d=a.chart,e=a.options.dataLabels,f=o(e.connectorPadding,10),g=o(e.connectorWidth,1),
h=d.plotWidth,d=d.plotHeight,i,j,k=o(e.softConnector,!0),l=e.distance,m=a.center,p=m[2]/2,q=m[1],u=l>0,r,w,v,x,C=[[],[]],y,z,E,H,B,D=[0,0,0,0],I=function(a,b){return b.y-a.y};if(a.visible&&(e.enabled||a._hasPointLabels)){Q.prototype.drawDataLabels.apply(a);n(b,function(a){a.dataLabel&&C[a.half].push(a)});for(H=0;!x&&b[H];)x=b[H]&&b[H].dataLabel&&(b[H].dataLabel.getBBox().height||21),H++;for(H=2;H--;){var b=[],K=[],G=C[H],J=G.length,F;a.sortByAngle(G,H-0.5);if(l>0){for(B=q-p-l;B<=q+p+l;B+=x)b.push(B);
w=b.length;if(J>w){c=[].concat(G);c.sort(I);for(B=J;B--;)c[B].rank=B;for(B=J;B--;)G[B].rank>=w&&G.splice(B,1);J=G.length}for(B=0;B<J;B++){c=G[B];v=c.labelPos;c=9999;var O,M;for(M=0;M<w;M++)O=N(b[M]-v[1]),O<c&&(c=O,F=M);if(F<B&&b[B]!==null)F=B;else for(w<J-B+F&&b[B]!==null&&(F=w-J+B);b[F]===null;)F++;K.push({i:F,y:b[F]});b[F]=null}K.sort(I)}for(B=0;B<J;B++){c=G[B];v=c.labelPos;r=c.dataLabel;E=c.visible===!1?"hidden":"visible";c=v[1];if(l>0){if(w=K.pop(),F=w.i,z=w.y,c>z&&b[F+1]!==null||c<z&&b[F-1]!==
null)z=c}else z=c;y=e.justify?m[0]+(H?-1:1)*(p+l):a.getX(F===0||F===b.length-1?c:z,H);r._attr={visibility:E,align:v[6]};r._pos={x:y+e.x+({left:f,right:-f}[v[6]]||0),y:z+e.y-10};r.connX=y;r.connY=z;if(this.options.size===null)w=r.width,y-w<f?D[3]=s(t(w-y+f),D[3]):y+w>h-f&&(D[1]=s(t(y+w-h+f),D[1])),z-x/2<0?D[0]=s(t(-z+x/2),D[0]):z+x/2>d&&(D[2]=s(t(z+x/2-d),D[2]))}}if(va(D)===0||this.verifyDataLabelOverflow(D))this.placeDataLabels(),u&&g&&n(this.points,function(b){i=b.connector;v=b.labelPos;if((r=b.dataLabel)&&
r._pos)E=r._attr.visibility,y=r.connX,z=r.connY,j=k?["M",y+(v[6]==="left"?5:-5),z,"C",y,z,2*v[2]-v[4],2*v[3]-v[5],v[2],v[3],"L",v[4],v[5]]:["M",y+(v[6]==="left"?5:-5),z,"L",v[2],v[3],"L",v[4],v[5]],i?(i.animate({d:j}),i.attr("visibility",E)):b.connector=i=a.chart.renderer.path(j).attr({"stroke-width":g,stroke:e.connectorColor||b.color||"#606060",visibility:E}).add(a.group);else if(i)b.connector=i.destroy()})}},verifyDataLabelOverflow:function(a){var b=this.center,c=this.options,d=c.center,e=c=c.minSize||
80,f;d[0]!==null?e=s(b[2]-s(a[1],a[3]),c):(e=s(b[2]-a[1]-a[3],c),b[0]+=(a[3]-a[1])/2);d[1]!==null?e=s(I(e,b[2]-s(a[0],a[2])),c):(e=s(I(e,b[2]-a[0]-a[2]),c),b[1]+=(a[0]-a[2])/2);e<b[2]?(b[2]=e,this.translate(b),n(this.points,function(a){if(a.dataLabel)a.dataLabel._pos=null}),this.drawDataLabels()):f=!0;return f},placeDataLabels:function(){n(this.points,function(a){var a=a.dataLabel,b;if(a)(b=a._pos)?(a.attr(a._attr),a[a.moved?"animate":"attr"](b),a.moved=!0):a&&a.attr({y:-999})})},alignDataLabel:pa,
drawTracker:F.prototype.drawTracker,drawLegendSymbol:G.prototype.drawLegendSymbol,getSymbol:pa};X=ha(Q,X);W.pie=X;r(Highcharts,{Axis:db,Chart:yb,Color:ra,Legend:eb,Pointer:xb,Point:Pa,Tick:Ma,Tooltip:wb,Renderer:Va,Series:Q,SVGElement:wa,SVGRenderer:Ha,arrayMin:Ja,arrayMax:va,charts:Ga,dateFormat:Xa,format:Ca,pathAnim:Ab,getOptions:function(){return M},hasBidiBug:Ub,isTouchDevice:Ob,numberFormat:Aa,seriesTypes:W,setOptions:function(a){M=x(M,a);Lb();return M},addEvent:J,removeEvent:aa,createElement:U,
discardElement:Ta,css:K,each:n,extend:r,map:Na,merge:x,pick:o,splat:ja,extendClass:ha,pInt:C,wrap:mb,svg:Z,canvas:$,vml:!Z&&!$,product:"Highcharts",version:"3.0.6"})})();
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/highcharts.src.js
New file
Diff too large
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/annotations.js
New file
@@ -0,0 +1,7 @@
(function(i,C){function m(a){return typeof a==="number"}function n(a){return a!==D&&a!==null}var D,p,r,s=i.Chart,t=i.extend,z=i.each;r=["path","rect","circle"];p={top:0,left:0,center:0.5,middle:0.5,bottom:1,right:1};var u=C.inArray,A=i.merge,B=function(){this.init.apply(this,arguments)};B.prototype={init:function(a,d){var c=d.shape&&d.shape.type;this.chart=a;var b,f;f={xAxis:0,yAxis:0,title:{style:{},text:"",x:0,y:0},shape:{params:{stroke:"#000000",fill:"transparent",strokeWidth:2}}};b={circle:{params:{x:0,
y:0}}};if(b[c])f.shape=A(f.shape,b[c]);this.options=A({},f,d)},render:function(a){var d=this.chart,c=this.chart.renderer,b=this.group,f=this.title,e=this.shape,h=this.options,i=h.title,l=h.shape;if(!b)b=this.group=c.g();if(!e&&l&&u(l.type,r)!==-1)e=this.shape=c[h.shape.type](l.params),e.add(b);if(!f&&i)f=this.title=c.label(i),f.add(b);b.add(d.annotations.group);this.linkObjects();a!==!1&&this.redraw()},redraw:function(){var a=this.options,d=this.chart,c=this.group,b=this.title,f=this.shape,e=this.linkedObject,
h=d.xAxis[a.xAxis],v=d.yAxis[a.yAxis],l=a.width,w=a.height,x=p[a.anchorY],y=p[a.anchorX],j,o,g,q;if(e)j=e instanceof i.Point?"point":e instanceof i.Series?"series":null,j==="point"?(a.xValue=e.x,a.yValue=e.y,o=e.series):j==="series"&&(o=e),c.visibility!==o.group.visibility&&c.attr({visibility:o.group.visibility});e=n(a.xValue)?h.toPixels(a.xValue+h.minPointOffset)-h.minPixelPadding:a.x;j=n(a.yValue)?v.toPixels(a.yValue):a.y;if(!isNaN(e)&&!isNaN(j)&&m(e)&&m(j)){b&&(b.attr(a.title),b.css(a.title.style));
if(f){b=t({},a.shape.params);if(a.units==="values"){for(g in b)u(g,["width","x"])>-1?b[g]=h.translate(b[g]):u(g,["height","y"])>-1&&(b[g]=v.translate(b[g]));b.width&&(b.width-=h.toPixels(0)-h.left);b.x&&(b.x+=h.minPixelPadding);if(a.shape.type==="path"){g=b.d;o=e;for(var r=j,s=g.length,k=0;k<s;)typeof g[k]==="number"&&typeof g[k+1]==="number"?(g[k]=h.toPixels(g[k])-o,g[k+1]=v.toPixels(g[k+1])-r,k+=2):k+=1}}a.shape.type==="circle"&&(b.x+=b.r,b.y+=b.r);f.attr(b)}c.bBox=null;if(!m(l))q=c.getBBox(),l=
q.width;if(!m(w))q||(q=c.getBBox()),w=q.height;if(!m(y))y=p.center;if(!m(x))x=p.center;e-=l*y;j-=w*x;d.animation&&n(c.translateX)&&n(c.translateY)?c.animate({translateX:e,translateY:j}):c.translate(e,j)}},destroy:function(){var a=this,d=this.chart.annotations.allItems,c=d.indexOf(a);c>-1&&d.splice(c,1);z(["title","shape","group"],function(b){a[b]&&(a[b].destroy(),a[b]=null)});a.group=a.title=a.shape=a.chart=a.options=null},update:function(a,d){t(this.options,a);this.linkObjects();this.render(d)},
linkObjects:function(){var a=this.chart,d=this.linkedObject,c=d&&(d.id||d.options.id),b=this.options.linkedTo;if(n(b)){if(!n(d)||b!==c)this.linkedObject=a.get(b)}else this.linkedObject=null}};t(s.prototype,{annotations:{add:function(a,d){var c=this.allItems,b=this.chart,f,e;Object.prototype.toString.call(a)==="[object Array]"||(a=[a]);for(e=a.length;e--;)f=new B(b,a[e]),c.push(f),f.render(d)},redraw:function(){z(this.allItems,function(a){a.redraw()})}}});s.prototype.callbacks.push(function(a){var d=
a.options.annotations,c;c=a.renderer.g("annotations");c.attr({zIndex:7});c.add();a.annotations.allItems=[];a.annotations.chart=a;a.annotations.group=c;Object.prototype.toString.call(d)==="[object Array]"&&d.length>0&&a.annotations.add(a.options.annotations);i.addEvent(a,"redraw",function(){a.annotations.redraw()})})})(Highcharts,HighchartsAdapter);
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/annotations.src.js
New file
@@ -0,0 +1,401 @@
(function (Highcharts, HighchartsAdapter) {
var UNDEFINED,
    ALIGN_FACTOR,
    ALLOWED_SHAPES,
    Chart = Highcharts.Chart,
    extend = Highcharts.extend,
    each = Highcharts.each;
ALLOWED_SHAPES = ["path", "rect", "circle"];
ALIGN_FACTOR = {
    top: 0,
    left: 0,
    center: 0.5,
    middle: 0.5,
    bottom: 1,
    right: 1
};
// Highcharts helper methods
var inArray = HighchartsAdapter.inArray,
    merge = Highcharts.merge;
function defaultOptions(shapeType) {
    var shapeOptions,
        options;
    options = {
        xAxis: 0,
        yAxis: 0,
        title: {
            style: {},
            text: "",
            x: 0,
            y: 0
        },
        shape: {
            params: {
                stroke: "#000000",
                fill: "transparent",
                strokeWidth: 2
            }
        }
    };
    shapeOptions = {
        circle: {
            params: {
                x: 0,
                y: 0
            }
        }
    };
    if (shapeOptions[shapeType]) {
        options.shape = merge(options.shape, shapeOptions[shapeType]);
    }
    return options;
}
function isArray(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
}
function isNumber(n) {
    return typeof n === 'number';
}
function defined(obj) {
    return obj !== UNDEFINED && obj !== null;
}
function translatePath(d, xAxis, yAxis, xOffset, yOffset) {
    var len = d.length,
        i = 0;
    while (i < len) {
        if (typeof d[i] === 'number' && typeof d[i + 1] === 'number') {
            d[i] = xAxis.toPixels(d[i]) - xOffset;
            d[i + 1] = yAxis.toPixels(d[i + 1]) - yOffset;
            i += 2;
        } else {
            i += 1;
        }
    }
    return d;
}
// Define annotation prototype
var Annotation = function () {
    this.init.apply(this, arguments);
};
Annotation.prototype = {
    /*
     * Initialize the annotation
     */
    init: function (chart, options) {
        var shapeType = options.shape && options.shape.type;
        this.chart = chart;
        this.options = merge({}, defaultOptions(shapeType), options);
    },
    /*
     * Render the annotation
     */
    render: function (redraw) {
        var annotation = this,
            chart = this.chart,
            renderer = annotation.chart.renderer,
            group = annotation.group,
            title = annotation.title,
            shape = annotation.shape,
            options = annotation.options,
            titleOptions = options.title,
            shapeOptions = options.shape;
        if (!group) {
            group = annotation.group = renderer.g();
        }
        if (!shape && shapeOptions && inArray(shapeOptions.type, ALLOWED_SHAPES) !== -1) {
            shape = annotation.shape = renderer[options.shape.type](shapeOptions.params);
            shape.add(group);
        }
        if (!title && titleOptions) {
            title = annotation.title = renderer.label(titleOptions);
            title.add(group);
        }
        group.add(chart.annotations.group);
        // link annotations to point or series
        annotation.linkObjects();
        if (redraw !== false) {
            annotation.redraw();
        }
    },
    /*
     * Redraw the annotation title or shape after options update
     */
    redraw: function () {
        var options = this.options,
            chart = this.chart,
            group = this.group,
            title = this.title,
            shape = this.shape,
            linkedTo = this.linkedObject,
            xAxis = chart.xAxis[options.xAxis],
            yAxis = chart.yAxis[options.yAxis],
            width = options.width,
            height = options.height,
            anchorY = ALIGN_FACTOR[options.anchorY],
            anchorX = ALIGN_FACTOR[options.anchorX],
            resetBBox = false,
            shapeParams,
            linkType,
            series,
            param,
            bbox,
            x,
            y;
        if (linkedTo) {
            linkType = (linkedTo instanceof Highcharts.Point) ? 'point' :
                        (linkedTo instanceof Highcharts.Series) ? 'series' : null;
            if (linkType === 'point') {
                options.xValue = linkedTo.x;
                options.yValue = linkedTo.y;
                series = linkedTo.series;
            } else if (linkType === 'series') {
                series = linkedTo;
            }
            if (group.visibility !== series.group.visibility) {
                group.attr({
                    visibility: series.group.visibility
                });
            }
        }
        // Based on given options find annotation pixel position
        x = (defined(options.xValue) ? xAxis.toPixels(options.xValue + xAxis.minPointOffset) - xAxis.minPixelPadding : options.x);
        y = defined(options.yValue) ? yAxis.toPixels(options.yValue) : options.y;
        if (isNaN(x) || isNaN(y) || !isNumber(x) || !isNumber(y)) {
            return;
        }
        if (title) {
            title.attr(options.title);
            title.css(options.title.style);
            resetBBox = true;
        }
        if (shape) {
            shapeParams = extend({}, options.shape.params);
            if (options.units === 'values') {
                for (param in shapeParams) {
                    if (inArray(param, ['width', 'x']) > -1) {
                        shapeParams[param] = xAxis.translate(shapeParams[param]);
                    } else if (inArray(param, ['height', 'y']) > -1) {
                        shapeParams[param] = yAxis.translate(shapeParams[param]);
                    }
                }
                if (shapeParams.width) {
                    shapeParams.width -= xAxis.toPixels(0) - xAxis.left;
                }
                if (shapeParams.x) {
                    shapeParams.x += xAxis.minPixelPadding;
                }
                if (options.shape.type === 'path') {
                    translatePath(shapeParams.d, xAxis, yAxis, x, y);
                }
            }
            // move the center of the circle to shape x/y
            if (options.shape.type === 'circle') {
                shapeParams.x += shapeParams.r;
                shapeParams.y += shapeParams.r;
            }
            resetBBox = true;
            shape.attr(shapeParams);
        }
        group.bBox = null;
        // If annotation width or height is not defined in options use bounding box size
        if (!isNumber(width)) {
            bbox = group.getBBox();
            width = bbox.width;
        }
        if (!isNumber(height)) {
            // get bbox only if it wasn't set before
            if (!bbox) {
                bbox = group.getBBox();
            }
            height = bbox.height;
        }
        // Calculate anchor point
        if (!isNumber(anchorX)) {
            anchorX = ALIGN_FACTOR.center;
        }
        if (!isNumber(anchorY)) {
            anchorY = ALIGN_FACTOR.center;
        }
        // Translate group according to its dimension and anchor point
        x = x - width * anchorX;
        y = y - height * anchorY;
        if (chart.animation && defined(group.translateX) && defined(group.translateY)) {
            group.animate({
                translateX: x,
                translateY: y
            });
        } else {
            group.translate(x, y);
        }
    },
    /*
     * Destroy the annotation
     */
    destroy: function () {
        var annotation = this,
            chart = this.chart,
            allItems = chart.annotations.allItems,
            index = allItems.indexOf(annotation);
        if (index > -1) {
            allItems.splice(index, 1);
        }
        each(['title', 'shape', 'group'], function (element) {
            if (annotation[element]) {
                annotation[element].destroy();
                annotation[element] = null;
            }
        });
        annotation.group = annotation.title = annotation.shape = annotation.chart = annotation.options = null;
    },
    /*
     * Update the annotation with a given options
     */
    update: function (options, redraw) {
        extend(this.options, options);
        // update link to point or series
        this.linkObjects();
        this.render(redraw);
    },
    linkObjects: function () {
        var annotation = this,
            chart = annotation.chart,
            linkedTo = annotation.linkedObject,
            linkedId = linkedTo && (linkedTo.id || linkedTo.options.id),
            options = annotation.options,
            id = options.linkedTo;
        if (!defined(id)) {
            annotation.linkedObject = null;
        } else if (!defined(linkedTo) || id !== linkedId) {
            annotation.linkedObject = chart.get(id);
        }
    }
};
// Add annotations methods to chart prototype
extend(Chart.prototype, {
    annotations: {
        /*
         * Unified method for adding annotations to the chart
         */
        add: function (options, redraw) {
            var annotations = this.allItems,
                chart = this.chart,
                item,
                len;
            if (!isArray(options)) {
                options = [options];
            }
            len = options.length;
            while (len--) {
                item = new Annotation(chart, options[len]);
                annotations.push(item);
                item.render(redraw);
            }
        },
        /**
         * Redraw all annotations, method used in chart events
         */
        redraw: function () {
            each(this.allItems, function (annotation) {
                annotation.redraw();
            });
        }
    }
});
// Initialize on chart load
Chart.prototype.callbacks.push(function (chart) {
    var options = chart.options.annotations,
        group;
    group = chart.renderer.g("annotations");
    group.attr({
        zIndex: 7
    });
    group.add();
    // initialize empty array for annotations
    chart.annotations.allItems = [];
    // link chart object to annotations
    chart.annotations.chart = chart;
    // link annotations group element to the chart
    chart.annotations.group = group;
    if (isArray(options) && options.length > 0) {
        chart.annotations.add(chart.options.annotations);
    }
    // update annotations after chart redraw
    Highcharts.addEvent(chart, 'redraw', function () {
        chart.annotations.redraw();
    });
});
}(Highcharts, HighchartsAdapter));
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/canvas-tools.js
New file
@@ -0,0 +1,133 @@
/*
 A class to parse color values
 @author Stoyan Stefanov <sstoo@gmail.com>
 @link   http://www.phpied.com/rgb-color-parser-in-javascript/
 Use it if you like it
 canvg.js - Javascript SVG parser and renderer on Canvas
 MIT Licensed
 Gabe Lerner (gabelerner@gmail.com)
 http://code.google.com/p/canvg/
 Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/
 Highcharts JS v3.0.6 (2013-10-04)
 CanVGRenderer Extension module
 (c) 2011-2012 Torstein Hønsi, Erik Olsson
 License: www.highcharts.com/license
*/
function RGBColor(m){this.ok=!1;m.charAt(0)=="#"&&(m=m.substr(1,6));var m=m.replace(/ /g,""),m=m.toLowerCase(),a={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",
darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",feldspar:"d19275",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",
gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",
lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",
oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",
slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"},c;for(c in a)m==c&&(m=a[c]);var d=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(b){return[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/,
example:["#00ff00","336699"],process:function(b){return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(b){return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)]}}];for(c=0;c<d.length;c++){var b=d[c].process,k=d[c].re.exec(m);if(k)channels=b(k),this.r=channels[0],this.g=channels[1],this.b=channels[2],this.ok=!0}this.r=this.r<0||isNaN(this.r)?0:this.r>255?255:this.r;this.g=this.g<0||isNaN(this.g)?0:
this.g>255?255:this.g;this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b;this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var b=this.r.toString(16),a=this.g.toString(16),d=this.b.toString(16);b.length==1&&(b="0"+b);a.length==1&&(a="0"+a);d.length==1&&(d="0"+d);return"#"+b+a+d};this.getHelpXML=function(){for(var b=[],k=0;k<d.length;k++)for(var c=d[k].example,j=0;j<c.length;j++)b[b.length]=c[j];for(var h in a)b[b.length]=h;c=document.createElement("ul");
c.setAttribute("id","rgbcolor-examples");for(k=0;k<b.length;k++)try{var l=document.createElement("li"),o=new RGBColor(b[k]),n=document.createElement("div");n.style.cssText="margin: 3px; border: 1px solid black; background:"+o.toHex()+"; color:"+o.toHex();n.appendChild(document.createTextNode("test"));var q=document.createTextNode(" "+b[k]+" -> "+o.toRGB()+" -> "+o.toHex());l.appendChild(n);l.appendChild(q);c.appendChild(l)}catch(p){}return c}}
if(!window.console)window.console={},window.console.log=function(){},window.console.dir=function(){};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(m){for(var a=0;a<this.length;a++)if(this[a]==m)return a;return-1};
(function(){function m(){var a={FRAMERATE:30,MAX_VIRTUAL_PIXELS:3E4};a.init=function(c){a.Definitions={};a.Styles={};a.Animations=[];a.Images=[];a.ctx=c;a.ViewPort=new function(){this.viewPorts=[];this.Clear=function(){this.viewPorts=[]};this.SetCurrent=function(a,b){this.viewPorts.push({width:a,height:b})};this.RemoveCurrent=function(){this.viewPorts.pop()};this.Current=function(){return this.viewPorts[this.viewPorts.length-1]};this.width=function(){return this.Current().width};this.height=function(){return this.Current().height};
this.ComputeSize=function(a){return a!=null&&typeof a=="number"?a:a=="x"?this.width():a=="y"?this.height():Math.sqrt(Math.pow(this.width(),2)+Math.pow(this.height(),2))/Math.sqrt(2)}}};a.init();a.ImagesLoaded=function(){for(var c=0;c<a.Images.length;c++)if(!a.Images[c].loaded)return!1;return!0};a.trim=function(a){return a.replace(/^\s+|\s+$/g,"")};a.compressSpaces=function(a){return a.replace(/[\s\r\t\n]+/gm," ")};a.ajax=function(a){var d;return(d=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP"))?
(d.open("GET",a,!1),d.send(null),d.responseText):null};a.parseXml=function(a){if(window.DOMParser)return(new DOMParser).parseFromString(a,"text/xml");else{var a=a.replace(/<!DOCTYPE svg[^>]*>/,""),d=new ActiveXObject("Microsoft.XMLDOM");d.async="false";d.loadXML(a);return d}};a.Property=function(c,d){this.name=c;this.value=d;this.hasValue=function(){return this.value!=null&&this.value!==""};this.numValue=function(){if(!this.hasValue())return 0;var b=parseFloat(this.value);(this.value+"").match(/%$/)&&
(b/=100);return b};this.valueOrDefault=function(b){return this.hasValue()?this.value:b};this.numValueOrDefault=function(b){return this.hasValue()?this.numValue():b};var b=this;this.Color={addOpacity:function(d){var c=b.value;if(d!=null&&d!=""){var f=new RGBColor(b.value);f.ok&&(c="rgba("+f.r+", "+f.g+", "+f.b+", "+d+")")}return new a.Property(b.name,c)}};this.Definition={getDefinition:function(){var d=b.value.replace(/^(url\()?#([^\)]+)\)?$/,"$2");return a.Definitions[d]},isUrl:function(){return b.value.indexOf("url(")==
0},getFillStyle:function(b){var d=this.getDefinition();return d!=null&&d.createGradient?d.createGradient(a.ctx,b):d!=null&&d.createPattern?d.createPattern(a.ctx,b):null}};this.Length={DPI:function(){return 96},EM:function(b){var d=12,c=new a.Property("fontSize",a.Font.Parse(a.ctx.font).fontSize);c.hasValue()&&(d=c.Length.toPixels(b));return d},toPixels:function(d){if(!b.hasValue())return 0;var c=b.value+"";return c.match(/em$/)?b.numValue()*this.EM(d):c.match(/ex$/)?b.numValue()*this.EM(d)/2:c.match(/px$/)?
b.numValue():c.match(/pt$/)?b.numValue()*1.25:c.match(/pc$/)?b.numValue()*15:c.match(/cm$/)?b.numValue()*this.DPI(d)/2.54:c.match(/mm$/)?b.numValue()*this.DPI(d)/25.4:c.match(/in$/)?b.numValue()*this.DPI(d):c.match(/%$/)?b.numValue()*a.ViewPort.ComputeSize(d):b.numValue()}};this.Time={toMilliseconds:function(){if(!b.hasValue())return 0;var a=b.value+"";if(a.match(/s$/))return b.numValue()*1E3;a.match(/ms$/);return b.numValue()}};this.Angle={toRadians:function(){if(!b.hasValue())return 0;var a=b.value+
"";return a.match(/deg$/)?b.numValue()*(Math.PI/180):a.match(/grad$/)?b.numValue()*(Math.PI/200):a.match(/rad$/)?b.numValue():b.numValue()*(Math.PI/180)}}};a.Font=new function(){this.Styles=["normal","italic","oblique","inherit"];this.Variants=["normal","small-caps","inherit"];this.Weights="normal,bold,bolder,lighter,100,200,300,400,500,600,700,800,900,inherit".split(",");this.CreateFont=function(d,b,c,e,f,g){g=g!=null?this.Parse(g):this.CreateFont("","","","","",a.ctx.font);return{fontFamily:f||
g.fontFamily,fontSize:e||g.fontSize,fontStyle:d||g.fontStyle,fontWeight:c||g.fontWeight,fontVariant:b||g.fontVariant,toString:function(){return[this.fontStyle,this.fontVariant,this.fontWeight,this.fontSize,this.fontFamily].join(" ")}}};var c=this;this.Parse=function(d){for(var b={},d=a.trim(a.compressSpaces(d||"")).split(" "),k=!1,e=!1,f=!1,g=!1,j="",h=0;h<d.length;h++)if(!e&&c.Styles.indexOf(d[h])!=-1){if(d[h]!="inherit")b.fontStyle=d[h];e=!0}else if(!g&&c.Variants.indexOf(d[h])!=-1){if(d[h]!="inherit")b.fontVariant=
d[h];e=g=!0}else if(!f&&c.Weights.indexOf(d[h])!=-1){if(d[h]!="inherit")b.fontWeight=d[h];e=g=f=!0}else if(k)d[h]!="inherit"&&(j+=d[h]);else{if(d[h]!="inherit")b.fontSize=d[h].split("/")[0];e=g=f=k=!0}if(j!="")b.fontFamily=j;return b}};a.ToNumberArray=function(c){for(var c=a.trim(a.compressSpaces((c||"").replace(/,/g," "))).split(" "),d=0;d<c.length;d++)c[d]=parseFloat(c[d]);return c};a.Point=function(a,d){this.x=a;this.y=d;this.angleTo=function(b){return Math.atan2(b.y-this.y,b.x-this.x)};this.applyTransform=
function(b){var a=this.x*b[1]+this.y*b[3]+b[5];this.x=this.x*b[0]+this.y*b[2]+b[4];this.y=a}};a.CreatePoint=function(c){c=a.ToNumberArray(c);return new a.Point(c[0],c[1])};a.CreatePath=function(c){for(var c=a.ToNumberArray(c),d=[],b=0;b<c.length;b+=2)d.push(new a.Point(c[b],c[b+1]));return d};a.BoundingBox=function(a,d,b,k){this.y2=this.x2=this.y1=this.x1=Number.NaN;this.x=function(){return this.x1};this.y=function(){return this.y1};this.width=function(){return this.x2-this.x1};this.height=function(){return this.y2-
this.y1};this.addPoint=function(b,a){if(b!=null){if(isNaN(this.x1)||isNaN(this.x2))this.x2=this.x1=b;if(b<this.x1)this.x1=b;if(b>this.x2)this.x2=b}if(a!=null){if(isNaN(this.y1)||isNaN(this.y2))this.y2=this.y1=a;if(a<this.y1)this.y1=a;if(a>this.y2)this.y2=a}};this.addX=function(b){this.addPoint(b,null)};this.addY=function(b){this.addPoint(null,b)};this.addBoundingBox=function(b){this.addPoint(b.x1,b.y1);this.addPoint(b.x2,b.y2)};this.addQuadraticCurve=function(b,a,d,c,k,l){d=b+2/3*(d-b);c=a+2/3*(c-
a);this.addBezierCurve(b,a,d,d+1/3*(k-b),c,c+1/3*(l-a),k,l)};this.addBezierCurve=function(b,a,d,c,k,l,o,n){var q=[b,a],p=[d,c],t=[k,l],m=[o,n];this.addPoint(q[0],q[1]);this.addPoint(m[0],m[1]);for(i=0;i<=1;i++)b=function(b){return Math.pow(1-b,3)*q[i]+3*Math.pow(1-b,2)*b*p[i]+3*(1-b)*Math.pow(b,2)*t[i]+Math.pow(b,3)*m[i]},a=6*q[i]-12*p[i]+6*t[i],d=-3*q[i]+9*p[i]-9*t[i]+3*m[i],c=3*p[i]-3*q[i],d==0?a!=0&&(a=-c/a,0<a&&a<1&&(i==0&&this.addX(b(a)),i==1&&this.addY(b(a)))):(c=Math.pow(a,2)-4*c*d,c<0||(k=
(-a+Math.sqrt(c))/(2*d),0<k&&k<1&&(i==0&&this.addX(b(k)),i==1&&this.addY(b(k))),a=(-a-Math.sqrt(c))/(2*d),0<a&&a<1&&(i==0&&this.addX(b(a)),i==1&&this.addY(b(a)))))};this.isPointInBox=function(b,a){return this.x1<=b&&b<=this.x2&&this.y1<=a&&a<=this.y2};this.addPoint(a,d);this.addPoint(b,k)};a.Transform=function(c){var d=this;this.Type={};this.Type.translate=function(b){this.p=a.CreatePoint(b);this.apply=function(b){b.translate(this.p.x||0,this.p.y||0)};this.applyToPoint=function(b){b.applyTransform([1,
0,0,1,this.p.x||0,this.p.y||0])}};this.Type.rotate=function(b){b=a.ToNumberArray(b);this.angle=new a.Property("angle",b[0]);this.cx=b[1]||0;this.cy=b[2]||0;this.apply=function(b){b.translate(this.cx,this.cy);b.rotate(this.angle.Angle.toRadians());b.translate(-this.cx,-this.cy)};this.applyToPoint=function(b){var a=this.angle.Angle.toRadians();b.applyTransform([1,0,0,1,this.p.x||0,this.p.y||0]);b.applyTransform([Math.cos(a),Math.sin(a),-Math.sin(a),Math.cos(a),0,0]);b.applyTransform([1,0,0,1,-this.p.x||
0,-this.p.y||0])}};this.Type.scale=function(b){this.p=a.CreatePoint(b);this.apply=function(b){b.scale(this.p.x||1,this.p.y||this.p.x||1)};this.applyToPoint=function(b){b.applyTransform([this.p.x||0,0,0,this.p.y||0,0,0])}};this.Type.matrix=function(b){this.m=a.ToNumberArray(b);this.apply=function(b){b.transform(this.m[0],this.m[1],this.m[2],this.m[3],this.m[4],this.m[5])};this.applyToPoint=function(b){b.applyTransform(this.m)}};this.Type.SkewBase=function(b){this.base=d.Type.matrix;this.base(b);this.angle=
new a.Property("angle",b)};this.Type.SkewBase.prototype=new this.Type.matrix;this.Type.skewX=function(b){this.base=d.Type.SkewBase;this.base(b);this.m=[1,0,Math.tan(this.angle.Angle.toRadians()),1,0,0]};this.Type.skewX.prototype=new this.Type.SkewBase;this.Type.skewY=function(b){this.base=d.Type.SkewBase;this.base(b);this.m=[1,Math.tan(this.angle.Angle.toRadians()),0,1,0,0]};this.Type.skewY.prototype=new this.Type.SkewBase;this.transforms=[];this.apply=function(b){for(var a=0;a<this.transforms.length;a++)this.transforms[a].apply(b)};
this.applyToPoint=function(b){for(var a=0;a<this.transforms.length;a++)this.transforms[a].applyToPoint(b)};for(var c=a.trim(a.compressSpaces(c)).split(/\s(?=[a-z])/),b=0;b<c.length;b++){var k=c[b].split("(")[0],e=c[b].split("(")[1].replace(")","");this.transforms.push(new this.Type[k](e))}};a.AspectRatio=function(c,d,b,k,e,f,g,j,h,l){var d=a.compressSpaces(d),d=d.replace(/^defer\s/,""),o=d.split(" ")[0]||"xMidYMid",d=d.split(" ")[1]||"meet",n=b/k,q=e/f,p=Math.min(n,q),m=Math.max(n,q);d=="meet"&&(k*=
p,f*=p);d=="slice"&&(k*=m,f*=m);h=new a.Property("refX",h);l=new a.Property("refY",l);h.hasValue()&&l.hasValue()?c.translate(-p*h.Length.toPixels("x"),-p*l.Length.toPixels("y")):(o.match(/^xMid/)&&(d=="meet"&&p==q||d=="slice"&&m==q)&&c.translate(b/2-k/2,0),o.match(/YMid$/)&&(d=="meet"&&p==n||d=="slice"&&m==n)&&c.translate(0,e/2-f/2),o.match(/^xMax/)&&(d=="meet"&&p==q||d=="slice"&&m==q)&&c.translate(b-k,0),o.match(/YMax$/)&&(d=="meet"&&p==n||d=="slice"&&m==n)&&c.translate(0,e-f));o=="none"?c.scale(n,
q):d=="meet"?c.scale(p,p):d=="slice"&&c.scale(m,m);c.translate(g==null?0:-g,j==null?0:-j)};a.Element={};a.Element.ElementBase=function(c){this.attributes={};this.styles={};this.children=[];this.attribute=function(b,d){var c=this.attributes[b];if(c!=null)return c;c=new a.Property(b,"");d==!0&&(this.attributes[b]=c);return c};this.style=function(b,d){var c=this.styles[b];if(c!=null)return c;c=this.attribute(b);if(c!=null&&c.hasValue())return c;c=this.parent;if(c!=null&&(c=c.style(b),c!=null&&c.hasValue()))return c;
c=new a.Property(b,"");d==!0&&(this.styles[b]=c);return c};this.render=function(b){if(this.style("display").value!="none"&&this.attribute("visibility").value!="hidden"){b.save();this.setContext(b);if(this.attribute("mask").hasValue()){var a=this.attribute("mask").Definition.getDefinition();a!=null&&a.apply(b,this)}else this.style("filter").hasValue()?(a=this.style("filter").Definition.getDefinition(),a!=null&&a.apply(b,this)):this.renderChildren(b);this.clearContext(b);b.restore()}};this.setContext=
function(){};this.clearContext=function(){};this.renderChildren=function(b){for(var a=0;a<this.children.length;a++)this.children[a].render(b)};this.addChild=function(b,d){var c=b;d&&(c=a.CreateElement(b));c.parent=this;this.children.push(c)};if(c!=null&&c.nodeType==1){for(var d=0;d<c.childNodes.length;d++){var b=c.childNodes[d];b.nodeType==1&&this.addChild(b,!0)}for(d=0;d<c.attributes.length;d++)b=c.attributes[d],this.attributes[b.nodeName]=new a.Property(b.nodeName,b.nodeValue);b=a.Styles[c.nodeName];
if(b!=null)for(var k in b)this.styles[k]=b[k];if(this.attribute("class").hasValue())for(var d=a.compressSpaces(this.attribute("class").value).split(" "),e=0;e<d.length;e++){b=a.Styles["."+d[e]];if(b!=null)for(k in b)this.styles[k]=b[k];b=a.Styles[c.nodeName+"."+d[e]];if(b!=null)for(k in b)this.styles[k]=b[k]}if(this.attribute("style").hasValue()){b=this.attribute("style").value.split(";");for(d=0;d<b.length;d++)a.trim(b[d])!=""&&(c=b[d].split(":"),k=a.trim(c[0]),c=a.trim(c[1]),this.styles[k]=new a.Property(k,
c))}this.attribute("id").hasValue()&&a.Definitions[this.attribute("id").value]==null&&(a.Definitions[this.attribute("id").value]=this)}};a.Element.RenderedElementBase=function(c){this.base=a.Element.ElementBase;this.base(c);this.setContext=function(d){if(this.style("fill").Definition.isUrl()){var b=this.style("fill").Definition.getFillStyle(this);if(b!=null)d.fillStyle=b}else if(this.style("fill").hasValue())b=this.style("fill"),this.style("fill-opacity").hasValue()&&(b=b.Color.addOpacity(this.style("fill-opacity").value)),
d.fillStyle=b.value=="none"?"rgba(0,0,0,0)":b.value;if(this.style("stroke").Definition.isUrl()){if(b=this.style("stroke").Definition.getFillStyle(this),b!=null)d.strokeStyle=b}else if(this.style("stroke").hasValue())b=this.style("stroke"),this.style("stroke-opacity").hasValue()&&(b=b.Color.addOpacity(this.style("stroke-opacity").value)),d.strokeStyle=b.value=="none"?"rgba(0,0,0,0)":b.value;if(this.style("stroke-width").hasValue())d.lineWidth=this.style("stroke-width").Length.toPixels();if(this.style("stroke-linecap").hasValue())d.lineCap=
this.style("stroke-linecap").value;if(this.style("stroke-linejoin").hasValue())d.lineJoin=this.style("stroke-linejoin").value;if(this.style("stroke-miterlimit").hasValue())d.miterLimit=this.style("stroke-miterlimit").value;if(typeof d.font!="undefined")d.font=a.Font.CreateFont(this.style("font-style").value,this.style("font-variant").value,this.style("font-weight").value,this.style("font-size").hasValue()?this.style("font-size").Length.toPixels()+"px":"",this.style("font-family").value).toString();
this.attribute("transform").hasValue()&&(new a.Transform(this.attribute("transform").value)).apply(d);this.attribute("clip-path").hasValue()&&(b=this.attribute("clip-path").Definition.getDefinition(),b!=null&&b.apply(d));if(this.style("opacity").hasValue())d.globalAlpha=this.style("opacity").numValue()}};a.Element.RenderedElementBase.prototype=new a.Element.ElementBase;a.Element.PathElementBase=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.path=function(d){d!=null&&d.beginPath();
return new a.BoundingBox};this.renderChildren=function(d){this.path(d);a.Mouse.checkPath(this,d);d.fillStyle!=""&&d.fill();d.strokeStyle!=""&&d.stroke();var b=this.getMarkers();if(b!=null){if(this.style("marker-start").Definition.isUrl()){var c=this.style("marker-start").Definition.getDefinition();c.render(d,b[0][0],b[0][1])}if(this.style("marker-mid").Definition.isUrl())for(var c=this.style("marker-mid").Definition.getDefinition(),e=1;e<b.length-1;e++)c.render(d,b[e][0],b[e][1]);this.style("marker-end").Definition.isUrl()&&
(c=this.style("marker-end").Definition.getDefinition(),c.render(d,b[b.length-1][0],b[b.length-1][1]))}};this.getBoundingBox=function(){return this.path()};this.getMarkers=function(){return null}};a.Element.PathElementBase.prototype=new a.Element.RenderedElementBase;a.Element.svg=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseClearContext=this.clearContext;this.clearContext=function(d){this.baseClearContext(d);a.ViewPort.RemoveCurrent()};this.baseSetContext=this.setContext;
this.setContext=function(d){d.strokeStyle="rgba(0,0,0,0)";d.lineCap="butt";d.lineJoin="miter";d.miterLimit=4;this.baseSetContext(d);this.attribute("x").hasValue()&&this.attribute("y").hasValue()&&d.translate(this.attribute("x").Length.toPixels("x"),this.attribute("y").Length.toPixels("y"));var b=a.ViewPort.width(),c=a.ViewPort.height();if(typeof this.root=="undefined"&&this.attribute("width").hasValue()&&this.attribute("height").hasValue()){var b=this.attribute("width").Length.toPixels("x"),c=this.attribute("height").Length.toPixels("y"),
e=0,f=0;this.attribute("refX").hasValue()&&this.attribute("refY").hasValue()&&(e=-this.attribute("refX").Length.toPixels("x"),f=-this.attribute("refY").Length.toPixels("y"));d.beginPath();d.moveTo(e,f);d.lineTo(b,f);d.lineTo(b,c);d.lineTo(e,c);d.closePath();d.clip()}a.ViewPort.SetCurrent(b,c);if(this.attribute("viewBox").hasValue()){var e=a.ToNumberArray(this.attribute("viewBox").value),f=e[0],g=e[1],b=e[2],c=e[3];a.AspectRatio(d,this.attribute("preserveAspectRatio").value,a.ViewPort.width(),b,a.ViewPort.height(),
c,f,g,this.attribute("refX").value,this.attribute("refY").value);a.ViewPort.RemoveCurrent();a.ViewPort.SetCurrent(e[2],e[3])}}};a.Element.svg.prototype=new a.Element.RenderedElementBase;a.Element.rect=function(c){this.base=a.Element.PathElementBase;this.base(c);this.path=function(d){var b=this.attribute("x").Length.toPixels("x"),c=this.attribute("y").Length.toPixels("y"),e=this.attribute("width").Length.toPixels("x"),f=this.attribute("height").Length.toPixels("y"),g=this.attribute("rx").Length.toPixels("x"),
j=this.attribute("ry").Length.toPixels("y");this.attribute("rx").hasValue()&&!this.attribute("ry").hasValue()&&(j=g);this.attribute("ry").hasValue()&&!this.attribute("rx").hasValue()&&(g=j);d!=null&&(d.beginPath(),d.moveTo(b+g,c),d.lineTo(b+e-g,c),d.quadraticCurveTo(b+e,c,b+e,c+j),d.lineTo(b+e,c+f-j),d.quadraticCurveTo(b+e,c+f,b+e-g,c+f),d.lineTo(b+g,c+f),d.quadraticCurveTo(b,c+f,b,c+f-j),d.lineTo(b,c+j),d.quadraticCurveTo(b,c,b+g,c),d.closePath());return new a.BoundingBox(b,c,b+e,c+f)}};a.Element.rect.prototype=
new a.Element.PathElementBase;a.Element.circle=function(c){this.base=a.Element.PathElementBase;this.base(c);this.path=function(d){var b=this.attribute("cx").Length.toPixels("x"),c=this.attribute("cy").Length.toPixels("y"),e=this.attribute("r").Length.toPixels();d!=null&&(d.beginPath(),d.arc(b,c,e,0,Math.PI*2,!0),d.closePath());return new a.BoundingBox(b-e,c-e,b+e,c+e)}};a.Element.circle.prototype=new a.Element.PathElementBase;a.Element.ellipse=function(c){this.base=a.Element.PathElementBase;this.base(c);
this.path=function(d){var b=4*((Math.sqrt(2)-1)/3),c=this.attribute("rx").Length.toPixels("x"),e=this.attribute("ry").Length.toPixels("y"),f=this.attribute("cx").Length.toPixels("x"),g=this.attribute("cy").Length.toPixels("y");d!=null&&(d.beginPath(),d.moveTo(f,g-e),d.bezierCurveTo(f+b*c,g-e,f+c,g-b*e,f+c,g),d.bezierCurveTo(f+c,g+b*e,f+b*c,g+e,f,g+e),d.bezierCurveTo(f-b*c,g+e,f-c,g+b*e,f-c,g),d.bezierCurveTo(f-c,g-b*e,f-b*c,g-e,f,g-e),d.closePath());return new a.BoundingBox(f-c,g-e,f+c,g+e)}};a.Element.ellipse.prototype=
new a.Element.PathElementBase;a.Element.line=function(c){this.base=a.Element.PathElementBase;this.base(c);this.getPoints=function(){return[new a.Point(this.attribute("x1").Length.toPixels("x"),this.attribute("y1").Length.toPixels("y")),new a.Point(this.attribute("x2").Length.toPixels("x"),this.attribute("y2").Length.toPixels("y"))]};this.path=function(d){var b=this.getPoints();d!=null&&(d.beginPath(),d.moveTo(b[0].x,b[0].y),d.lineTo(b[1].x,b[1].y));return new a.BoundingBox(b[0].x,b[0].y,b[1].x,b[1].y)};
this.getMarkers=function(){var a=this.getPoints(),b=a[0].angleTo(a[1]);return[[a[0],b],[a[1],b]]}};a.Element.line.prototype=new a.Element.PathElementBase;a.Element.polyline=function(c){this.base=a.Element.PathElementBase;this.base(c);this.points=a.CreatePath(this.attribute("points").value);this.path=function(d){var b=new a.BoundingBox(this.points[0].x,this.points[0].y);d!=null&&(d.beginPath(),d.moveTo(this.points[0].x,this.points[0].y));for(var c=1;c<this.points.length;c++)b.addPoint(this.points[c].x,
this.points[c].y),d!=null&&d.lineTo(this.points[c].x,this.points[c].y);return b};this.getMarkers=function(){for(var a=[],b=0;b<this.points.length-1;b++)a.push([this.points[b],this.points[b].angleTo(this.points[b+1])]);a.push([this.points[this.points.length-1],a[a.length-1][1]]);return a}};a.Element.polyline.prototype=new a.Element.PathElementBase;a.Element.polygon=function(c){this.base=a.Element.polyline;this.base(c);this.basePath=this.path;this.path=function(a){var b=this.basePath(a);a!=null&&(a.lineTo(this.points[0].x,
this.points[0].y),a.closePath());return b}};a.Element.polygon.prototype=new a.Element.polyline;a.Element.path=function(c){this.base=a.Element.PathElementBase;this.base(c);c=this.attribute("d").value;c=c.replace(/,/gm," ");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,"$1 $2");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,"$1 $2");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([^\s])/gm,"$1 $2");c=c.replace(/([^\s])([MmZzLlHhVvCcSsQqTtAa])/gm,"$1 $2");c=c.replace(/([0-9])([+\-])/gm,
"$1 $2");c=c.replace(/(\.[0-9]*)(\.)/gm,"$1 $2");c=c.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,"$1 $3 $4 ");c=a.compressSpaces(c);c=a.trim(c);this.PathParser=new function(d){this.tokens=d.split(" ");this.reset=function(){this.i=-1;this.previousCommand=this.command="";this.start=new a.Point(0,0);this.control=new a.Point(0,0);this.current=new a.Point(0,0);this.points=[];this.angles=[]};this.isEnd=function(){return this.i>=this.tokens.length-1};this.isCommandOrEnd=function(){return this.isEnd()?
!0:this.tokens[this.i+1].match(/^[A-Za-z]$/)!=null};this.isRelativeCommand=function(){return this.command==this.command.toLowerCase()};this.getToken=function(){this.i+=1;return this.tokens[this.i]};this.getScalar=function(){return parseFloat(this.getToken())};this.nextCommand=function(){this.previousCommand=this.command;this.command=this.getToken()};this.getPoint=function(){return this.makeAbsolute(new a.Point(this.getScalar(),this.getScalar()))};this.getAsControlPoint=function(){var b=this.getPoint();
return this.control=b};this.getAsCurrentPoint=function(){var b=this.getPoint();return this.current=b};this.getReflectedControlPoint=function(){return this.previousCommand.toLowerCase()!="c"&&this.previousCommand.toLowerCase()!="s"?this.current:new a.Point(2*this.current.x-this.control.x,2*this.current.y-this.control.y)};this.makeAbsolute=function(b){if(this.isRelativeCommand())b.x=this.current.x+b.x,b.y=this.current.y+b.y;return b};this.addMarker=function(b,a,d){d!=null&&this.angles.length>0&&this.angles[this.angles.length-
1]==null&&(this.angles[this.angles.length-1]=this.points[this.points.length-1].angleTo(d));this.addMarkerAngle(b,a==null?null:a.angleTo(b))};this.addMarkerAngle=function(b,a){this.points.push(b);this.angles.push(a)};this.getMarkerPoints=function(){return this.points};this.getMarkerAngles=function(){for(var b=0;b<this.angles.length;b++)if(this.angles[b]==null)for(var a=b+1;a<this.angles.length;a++)if(this.angles[a]!=null){this.angles[b]=this.angles[a];break}return this.angles}}(c);this.path=function(d){var b=
this.PathParser;b.reset();var c=new a.BoundingBox;for(d!=null&&d.beginPath();!b.isEnd();)switch(b.nextCommand(),b.command.toUpperCase()){case "M":var e=b.getAsCurrentPoint();b.addMarker(e);c.addPoint(e.x,e.y);d!=null&&d.moveTo(e.x,e.y);for(b.start=b.current;!b.isCommandOrEnd();)e=b.getAsCurrentPoint(),b.addMarker(e,b.start),c.addPoint(e.x,e.y),d!=null&&d.lineTo(e.x,e.y);break;case "L":for(;!b.isCommandOrEnd();){var f=b.current,e=b.getAsCurrentPoint();b.addMarker(e,f);c.addPoint(e.x,e.y);d!=null&&
d.lineTo(e.x,e.y)}break;case "H":for(;!b.isCommandOrEnd();)e=new a.Point((b.isRelativeCommand()?b.current.x:0)+b.getScalar(),b.current.y),b.addMarker(e,b.current),b.current=e,c.addPoint(b.current.x,b.current.y),d!=null&&d.lineTo(b.current.x,b.current.y);break;case "V":for(;!b.isCommandOrEnd();)e=new a.Point(b.current.x,(b.isRelativeCommand()?b.current.y:0)+b.getScalar()),b.addMarker(e,b.current),b.current=e,c.addPoint(b.current.x,b.current.y),d!=null&&d.lineTo(b.current.x,b.current.y);break;case "C":for(;!b.isCommandOrEnd();){var g=
b.current,f=b.getPoint(),j=b.getAsControlPoint(),e=b.getAsCurrentPoint();b.addMarker(e,j,f);c.addBezierCurve(g.x,g.y,f.x,f.y,j.x,j.y,e.x,e.y);d!=null&&d.bezierCurveTo(f.x,f.y,j.x,j.y,e.x,e.y)}break;case "S":for(;!b.isCommandOrEnd();)g=b.current,f=b.getReflectedControlPoint(),j=b.getAsControlPoint(),e=b.getAsCurrentPoint(),b.addMarker(e,j,f),c.addBezierCurve(g.x,g.y,f.x,f.y,j.x,j.y,e.x,e.y),d!=null&&d.bezierCurveTo(f.x,f.y,j.x,j.y,e.x,e.y);break;case "Q":for(;!b.isCommandOrEnd();)g=b.current,j=b.getAsControlPoint(),
e=b.getAsCurrentPoint(),b.addMarker(e,j,j),c.addQuadraticCurve(g.x,g.y,j.x,j.y,e.x,e.y),d!=null&&d.quadraticCurveTo(j.x,j.y,e.x,e.y);break;case "T":for(;!b.isCommandOrEnd();)g=b.current,j=b.getReflectedControlPoint(),b.control=j,e=b.getAsCurrentPoint(),b.addMarker(e,j,j),c.addQuadraticCurve(g.x,g.y,j.x,j.y,e.x,e.y),d!=null&&d.quadraticCurveTo(j.x,j.y,e.x,e.y);break;case "A":for(;!b.isCommandOrEnd();){var g=b.current,h=b.getScalar(),l=b.getScalar(),f=b.getScalar()*(Math.PI/180),o=b.getScalar(),j=b.getScalar(),
e=b.getAsCurrentPoint(),n=new a.Point(Math.cos(f)*(g.x-e.x)/2+Math.sin(f)*(g.y-e.y)/2,-Math.sin(f)*(g.x-e.x)/2+Math.cos(f)*(g.y-e.y)/2),q=Math.pow(n.x,2)/Math.pow(h,2)+Math.pow(n.y,2)/Math.pow(l,2);q>1&&(h*=Math.sqrt(q),l*=Math.sqrt(q));o=(o==j?-1:1)*Math.sqrt((Math.pow(h,2)*Math.pow(l,2)-Math.pow(h,2)*Math.pow(n.y,2)-Math.pow(l,2)*Math.pow(n.x,2))/(Math.pow(h,2)*Math.pow(n.y,2)+Math.pow(l,2)*Math.pow(n.x,2)));isNaN(o)&&(o=0);var p=new a.Point(o*h*n.y/l,o*-l*n.x/h),g=new a.Point((g.x+e.x)/2+Math.cos(f)*
p.x-Math.sin(f)*p.y,(g.y+e.y)/2+Math.sin(f)*p.x+Math.cos(f)*p.y),m=function(b,a){return(b[0]*a[0]+b[1]*a[1])/(Math.sqrt(Math.pow(b[0],2)+Math.pow(b[1],2))*Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)))},s=function(b,a){return(b[0]*a[1]<b[1]*a[0]?-1:1)*Math.acos(m(b,a))},o=s([1,0],[(n.x-p.x)/h,(n.y-p.y)/l]),q=[(n.x-p.x)/h,(n.y-p.y)/l],p=[(-n.x-p.x)/h,(-n.y-p.y)/l],n=s(q,p);if(m(q,p)<=-1)n=Math.PI;m(q,p)>=1&&(n=0);j==0&&n>0&&(n-=2*Math.PI);j==1&&n<0&&(n+=2*Math.PI);q=new a.Point(g.x-h*Math.cos((o+n)/
2),g.y-l*Math.sin((o+n)/2));b.addMarkerAngle(q,(o+n)/2+(j==0?1:-1)*Math.PI/2);b.addMarkerAngle(e,n+(j==0?1:-1)*Math.PI/2);c.addPoint(e.x,e.y);d!=null&&(m=h>l?h:l,e=h>l?1:h/l,h=h>l?l/h:1,d.translate(g.x,g.y),d.rotate(f),d.scale(e,h),d.arc(0,0,m,o,o+n,1-j),d.scale(1/e,1/h),d.rotate(-f),d.translate(-g.x,-g.y))}break;case "Z":d!=null&&d.closePath(),b.current=b.start}return c};this.getMarkers=function(){for(var a=this.PathParser.getMarkerPoints(),b=this.PathParser.getMarkerAngles(),c=[],e=0;e<a.length;e++)c.push([a[e],
b[e]]);return c}};a.Element.path.prototype=new a.Element.PathElementBase;a.Element.pattern=function(c){this.base=a.Element.ElementBase;this.base(c);this.createPattern=function(d){var b=new a.Element.svg;b.attributes.viewBox=new a.Property("viewBox",this.attribute("viewBox").value);b.attributes.x=new a.Property("x",this.attribute("x").value);b.attributes.y=new a.Property("y",this.attribute("y").value);b.attributes.width=new a.Property("width",this.attribute("width").value);b.attributes.height=new a.Property("height",
this.attribute("height").value);b.children=this.children;var c=document.createElement("canvas");c.width=this.attribute("width").Length.toPixels("x");c.height=this.attribute("height").Length.toPixels("y");b.render(c.getContext("2d"));return d.createPattern(c,"repeat")}};a.Element.pattern.prototype=new a.Element.ElementBase;a.Element.marker=function(c){this.base=a.Element.ElementBase;this.base(c);this.baseRender=this.render;this.render=function(d,b,c){d.translate(b.x,b.y);this.attribute("orient").valueOrDefault("auto")==
"auto"&&d.rotate(c);this.attribute("markerUnits").valueOrDefault("strokeWidth")=="strokeWidth"&&d.scale(d.lineWidth,d.lineWidth);d.save();var e=new a.Element.svg;e.attributes.viewBox=new a.Property("viewBox",this.attribute("viewBox").value);e.attributes.refX=new a.Property("refX",this.attribute("refX").value);e.attributes.refY=new a.Property("refY",this.attribute("refY").value);e.attributes.width=new a.Property("width",this.attribute("markerWidth").value);e.attributes.height=new a.Property("height",
this.attribute("markerHeight").value);e.attributes.fill=new a.Property("fill",this.attribute("fill").valueOrDefault("black"));e.attributes.stroke=new a.Property("stroke",this.attribute("stroke").valueOrDefault("none"));e.children=this.children;e.render(d);d.restore();this.attribute("markerUnits").valueOrDefault("strokeWidth")=="strokeWidth"&&d.scale(1/d.lineWidth,1/d.lineWidth);this.attribute("orient").valueOrDefault("auto")=="auto"&&d.rotate(-c);d.translate(-b.x,-b.y)}};a.Element.marker.prototype=
new a.Element.ElementBase;a.Element.defs=function(c){this.base=a.Element.ElementBase;this.base(c);this.render=function(){}};a.Element.defs.prototype=new a.Element.ElementBase;a.Element.GradientBase=function(c){this.base=a.Element.ElementBase;this.base(c);this.gradientUnits=this.attribute("gradientUnits").valueOrDefault("objectBoundingBox");this.stops=[];for(c=0;c<this.children.length;c++)this.stops.push(this.children[c]);this.getGradient=function(){};this.createGradient=function(d,b){var c=this;this.attribute("xlink:href").hasValue()&&
(c=this.attribute("xlink:href").Definition.getDefinition());for(var e=this.getGradient(d,b),f=0;f<c.stops.length;f++)e.addColorStop(c.stops[f].offset,c.stops[f].color);if(this.attribute("gradientTransform").hasValue()){c=a.ViewPort.viewPorts[0];f=new a.Element.rect;f.attributes.x=new a.Property("x",-a.MAX_VIRTUAL_PIXELS/3);f.attributes.y=new a.Property("y",-a.MAX_VIRTUAL_PIXELS/3);f.attributes.width=new a.Property("width",a.MAX_VIRTUAL_PIXELS);f.attributes.height=new a.Property("height",a.MAX_VIRTUAL_PIXELS);
var g=new a.Element.g;g.attributes.transform=new a.Property("transform",this.attribute("gradientTransform").value);g.children=[f];f=new a.Element.svg;f.attributes.x=new a.Property("x",0);f.attributes.y=new a.Property("y",0);f.attributes.width=new a.Property("width",c.width);f.attributes.height=new a.Property("height",c.height);f.children=[g];g=document.createElement("canvas");g.width=c.width;g.height=c.height;c=g.getContext("2d");c.fillStyle=e;f.render(c);return c.createPattern(g,"no-repeat")}return e}};
a.Element.GradientBase.prototype=new a.Element.ElementBase;a.Element.linearGradient=function(c){this.base=a.Element.GradientBase;this.base(c);this.getGradient=function(a,b){var c=b.getBoundingBox(),e=this.gradientUnits=="objectBoundingBox"?c.x()+c.width()*this.attribute("x1").numValue():this.attribute("x1").Length.toPixels("x"),f=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("y1").numValue():this.attribute("y1").Length.toPixels("y"),g=this.gradientUnits=="objectBoundingBox"?
c.x()+c.width()*this.attribute("x2").numValue():this.attribute("x2").Length.toPixels("x"),c=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("y2").numValue():this.attribute("y2").Length.toPixels("y");return a.createLinearGradient(e,f,g,c)}};a.Element.linearGradient.prototype=new a.Element.GradientBase;a.Element.radialGradient=function(c){this.base=a.Element.GradientBase;this.base(c);this.getGradient=function(a,b){var c=b.getBoundingBox(),e=this.gradientUnits=="objectBoundingBox"?
c.x()+c.width()*this.attribute("cx").numValue():this.attribute("cx").Length.toPixels("x"),f=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("cy").numValue():this.attribute("cy").Length.toPixels("y"),g=e,j=f;this.attribute("fx").hasValue()&&(g=this.gradientUnits=="objectBoundingBox"?c.x()+c.width()*this.attribute("fx").numValue():this.attribute("fx").Length.toPixels("x"));this.attribute("fy").hasValue()&&(j=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("fy").numValue():
this.attribute("fy").Length.toPixels("y"));c=this.gradientUnits=="objectBoundingBox"?(c.width()+c.height())/2*this.attribute("r").numValue():this.attribute("r").Length.toPixels();return a.createRadialGradient(g,j,0,e,f,c)}};a.Element.radialGradient.prototype=new a.Element.GradientBase;a.Element.stop=function(c){this.base=a.Element.ElementBase;this.base(c);this.offset=this.attribute("offset").numValue();c=this.style("stop-color");this.style("stop-opacity").hasValue()&&(c=c.Color.addOpacity(this.style("stop-opacity").value));
this.color=c.value};a.Element.stop.prototype=new a.Element.ElementBase;a.Element.AnimateBase=function(c){this.base=a.Element.ElementBase;this.base(c);a.Animations.push(this);this.duration=0;this.begin=this.attribute("begin").Time.toMilliseconds();this.maxDuration=this.begin+this.attribute("dur").Time.toMilliseconds();this.getProperty=function(){var a=this.attribute("attributeType").value,b=this.attribute("attributeName").value;return a=="CSS"?this.parent.style(b,!0):this.parent.attribute(b,!0)};this.initialValue=
null;this.removed=!1;this.calcValue=function(){return""};this.update=function(a){if(this.initialValue==null)this.initialValue=this.getProperty().value;if(this.duration>this.maxDuration)if(this.attribute("repeatCount").value=="indefinite")this.duration=0;else return this.attribute("fill").valueOrDefault("remove")=="remove"&&!this.removed?(this.removed=!0,this.getProperty().value=this.initialValue,!0):!1;this.duration+=a;a=!1;if(this.begin<this.duration)a=this.calcValue(),this.attribute("type").hasValue()&&
(a=this.attribute("type").value+"("+a+")"),this.getProperty().value=a,a=!0;return a};this.progress=function(){return(this.duration-this.begin)/(this.maxDuration-this.begin)}};a.Element.AnimateBase.prototype=new a.Element.ElementBase;a.Element.animate=function(c){this.base=a.Element.AnimateBase;this.base(c);this.calcValue=function(){var a=this.attribute("from").numValue(),b=this.attribute("to").numValue();return a+(b-a)*this.progress()}};a.Element.animate.prototype=new a.Element.AnimateBase;a.Element.animateColor=
function(c){this.base=a.Element.AnimateBase;this.base(c);this.calcValue=function(){var a=new RGBColor(this.attribute("from").value),b=new RGBColor(this.attribute("to").value);if(a.ok&&b.ok){var c=a.r+(b.r-a.r)*this.progress(),e=a.g+(b.g-a.g)*this.progress(),a=a.b+(b.b-a.b)*this.progress();return"rgb("+parseInt(c,10)+","+parseInt(e,10)+","+parseInt(a,10)+")"}return this.attribute("from").value}};a.Element.animateColor.prototype=new a.Element.AnimateBase;a.Element.animateTransform=function(c){this.base=
a.Element.animate;this.base(c)};a.Element.animateTransform.prototype=new a.Element.animate;a.Element.font=function(c){this.base=a.Element.ElementBase;this.base(c);this.horizAdvX=this.attribute("horiz-adv-x").numValue();this.isArabic=this.isRTL=!1;this.missingGlyph=this.fontFace=null;this.glyphs=[];for(c=0;c<this.children.length;c++){var d=this.children[c];if(d.type=="font-face")this.fontFace=d,d.style("font-family").hasValue()&&(a.Definitions[d.style("font-family").value]=this);else if(d.type=="missing-glyph")this.missingGlyph=
d;else if(d.type=="glyph")d.arabicForm!=""?(this.isArabic=this.isRTL=!0,typeof this.glyphs[d.unicode]=="undefined"&&(this.glyphs[d.unicode]=[]),this.glyphs[d.unicode][d.arabicForm]=d):this.glyphs[d.unicode]=d}};a.Element.font.prototype=new a.Element.ElementBase;a.Element.fontface=function(c){this.base=a.Element.ElementBase;this.base(c);this.ascent=this.attribute("ascent").value;this.descent=this.attribute("descent").value;this.unitsPerEm=this.attribute("units-per-em").numValue()};a.Element.fontface.prototype=
new a.Element.ElementBase;a.Element.missingglyph=function(c){this.base=a.Element.path;this.base(c);this.horizAdvX=0};a.Element.missingglyph.prototype=new a.Element.path;a.Element.glyph=function(c){this.base=a.Element.path;this.base(c);this.horizAdvX=this.attribute("horiz-adv-x").numValue();this.unicode=this.attribute("unicode").value;this.arabicForm=this.attribute("arabic-form").value};a.Element.glyph.prototype=new a.Element.path;a.Element.text=function(c){this.base=a.Element.RenderedElementBase;
this.base(c);if(c!=null){this.children=[];for(var d=0;d<c.childNodes.length;d++){var b=c.childNodes[d];b.nodeType==1?this.addChild(b,!0):b.nodeType==3&&this.addChild(new a.Element.tspan(b),!1)}}this.baseSetContext=this.setContext;this.setContext=function(b){this.baseSetContext(b);if(this.style("dominant-baseline").hasValue())b.textBaseline=this.style("dominant-baseline").value;if(this.style("alignment-baseline").hasValue())b.textBaseline=this.style("alignment-baseline").value};this.renderChildren=
function(b){for(var a=this.style("text-anchor").valueOrDefault("start"),c=this.attribute("x").Length.toPixels("x"),d=this.attribute("y").Length.toPixels("y"),j=0;j<this.children.length;j++){var h=this.children[j];h.attribute("x").hasValue()?h.x=h.attribute("x").Length.toPixels("x"):(h.attribute("dx").hasValue()&&(c+=h.attribute("dx").Length.toPixels("x")),h.x=c);c=h.measureText(b);if(a!="start"&&(j==0||h.attribute("x").hasValue())){for(var l=c,o=j+1;o<this.children.length;o++){var n=this.children[o];
if(n.attribute("x").hasValue())break;l+=n.measureText(b)}h.x-=a=="end"?l:l/2}c=h.x+c;h.attribute("y").hasValue()?h.y=h.attribute("y").Length.toPixels("y"):(h.attribute("dy").hasValue()&&(d+=h.attribute("dy").Length.toPixels("y")),h.y=d);d=h.y;h.render(b)}}};a.Element.text.prototype=new a.Element.RenderedElementBase;a.Element.TextElementBase=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.getGlyph=function(a,b,c){var e=b[c],f=null;if(a.isArabic){var g="isolated";if((c==0||b[c-
1]==" ")&&c<b.length-2&&b[c+1]!=" ")g="terminal";c>0&&b[c-1]!=" "&&c<b.length-2&&b[c+1]!=" "&&(g="medial");if(c>0&&b[c-1]!=" "&&(c==b.length-1||b[c+1]==" "))g="initial";typeof a.glyphs[e]!="undefined"&&(f=a.glyphs[e][g],f==null&&a.glyphs[e].type=="glyph"&&(f=a.glyphs[e]))}else f=a.glyphs[e];if(f==null)f=a.missingGlyph;return f};this.renderChildren=function(c){var b=this.parent.style("font-family").Definition.getDefinition();if(b!=null){var k=this.parent.style("font-size").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize),
e=this.parent.style("font-style").valueOrDefault(a.Font.Parse(a.ctx.font).fontStyle),f=this.getText();b.isRTL&&(f=f.split("").reverse().join(""));for(var g=a.ToNumberArray(this.parent.attribute("dx").value),j=0;j<f.length;j++){var h=this.getGlyph(b,f,j),l=k/b.fontFace.unitsPerEm;c.translate(this.x,this.y);c.scale(l,-l);var o=c.lineWidth;c.lineWidth=c.lineWidth*b.fontFace.unitsPerEm/k;e=="italic"&&c.transform(1,0,0.4,1,0,0);h.render(c);e=="italic"&&c.transform(1,0,-0.4,1,0,0);c.lineWidth=o;c.scale(1/
l,-1/l);c.translate(-this.x,-this.y);this.x+=k*(h.horizAdvX||b.horizAdvX)/b.fontFace.unitsPerEm;typeof g[j]!="undefined"&&!isNaN(g[j])&&(this.x+=g[j])}}else c.strokeStyle!=""&&c.strokeText(a.compressSpaces(this.getText()),this.x,this.y),c.fillStyle!=""&&c.fillText(a.compressSpaces(this.getText()),this.x,this.y)};this.getText=function(){};this.measureText=function(c){var b=this.parent.style("font-family").Definition.getDefinition();if(b!=null){var c=this.parent.style("font-size").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize),
k=0,e=this.getText();b.isRTL&&(e=e.split("").reverse().join(""));for(var f=a.ToNumberArray(this.parent.attribute("dx").value),g=0;g<e.length;g++){var j=this.getGlyph(b,e,g);k+=(j.horizAdvX||b.horizAdvX)*c/b.fontFace.unitsPerEm;typeof f[g]!="undefined"&&!isNaN(f[g])&&(k+=f[g])}return k}b=a.compressSpaces(this.getText());if(!c.measureText)return b.length*10;c.save();this.setContext(c);b=c.measureText(b).width;c.restore();return b}};a.Element.TextElementBase.prototype=new a.Element.RenderedElementBase;
a.Element.tspan=function(c){this.base=a.Element.TextElementBase;this.base(c);this.text=c.nodeType==3?c.nodeValue:c.childNodes.length>0?c.childNodes[0].nodeValue:c.text;this.getText=function(){return this.text}};a.Element.tspan.prototype=new a.Element.TextElementBase;a.Element.tref=function(c){this.base=a.Element.TextElementBase;this.base(c);this.getText=function(){var a=this.attribute("xlink:href").Definition.getDefinition();if(a!=null)return a.children[0].getText()}};a.Element.tref.prototype=new a.Element.TextElementBase;
a.Element.a=function(c){this.base=a.Element.TextElementBase;this.base(c);this.hasText=!0;for(var d=0;d<c.childNodes.length;d++)if(c.childNodes[d].nodeType!=3)this.hasText=!1;this.text=this.hasText?c.childNodes[0].nodeValue:"";this.getText=function(){return this.text};this.baseRenderChildren=this.renderChildren;this.renderChildren=function(b){if(this.hasText){this.baseRenderChildren(b);var c=new a.Property("fontSize",a.Font.Parse(a.ctx.font).fontSize);a.Mouse.checkBoundingBox(this,new a.BoundingBox(this.x,
this.y-c.Length.toPixels("y"),this.x+this.measureText(b),this.y))}else c=new a.Element.g,c.children=this.children,c.parent=this,c.render(b)};this.onclick=function(){window.open(this.attribute("xlink:href").value)};this.onmousemove=function(){a.ctx.canvas.style.cursor="pointer"}};a.Element.a.prototype=new a.Element.TextElementBase;a.Element.image=function(c){this.base=a.Element.RenderedElementBase;this.base(c);a.Images.push(this);this.img=document.createElement("img");this.loaded=!1;var d=this;this.img.onload=
function(){d.loaded=!0};this.img.src=this.attribute("xlink:href").value;this.renderChildren=function(b){var c=this.attribute("x").Length.toPixels("x"),d=this.attribute("y").Length.toPixels("y"),f=this.attribute("width").Length.toPixels("x"),g=this.attribute("height").Length.toPixels("y");f==0||g==0||(b.save(),b.translate(c,d),a.AspectRatio(b,this.attribute("preserveAspectRatio").value,f,this.img.width,g,this.img.height,0,0),b.drawImage(this.img,0,0),b.restore())}};a.Element.image.prototype=new a.Element.RenderedElementBase;
a.Element.g=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.getBoundingBox=function(){for(var c=new a.BoundingBox,b=0;b<this.children.length;b++)c.addBoundingBox(this.children[b].getBoundingBox());return c}};a.Element.g.prototype=new a.Element.RenderedElementBase;a.Element.symbol=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseSetContext=this.setContext;this.setContext=function(c){this.baseSetContext(c);if(this.attribute("viewBox").hasValue()){var b=
a.ToNumberArray(this.attribute("viewBox").value),k=b[0],e=b[1];width=b[2];height=b[3];a.AspectRatio(c,this.attribute("preserveAspectRatio").value,this.attribute("width").Length.toPixels("x"),width,this.attribute("height").Length.toPixels("y"),height,k,e);a.ViewPort.SetCurrent(b[2],b[3])}}};a.Element.symbol.prototype=new a.Element.RenderedElementBase;a.Element.style=function(c){this.base=a.Element.ElementBase;this.base(c);for(var c=c.childNodes[0].nodeValue+(c.childNodes.length>1?c.childNodes[1].nodeValue:
""),c=c.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm,""),c=a.compressSpaces(c),c=c.split("}"),d=0;d<c.length;d++)if(a.trim(c[d])!="")for(var b=c[d].split("{"),k=b[0].split(","),b=b[1].split(";"),e=0;e<k.length;e++){var f=a.trim(k[e]);if(f!=""){for(var g={},j=0;j<b.length;j++){var h=b[j].indexOf(":"),l=b[j].substr(0,h),h=b[j].substr(h+1,b[j].length-h);l!=null&&h!=null&&(g[a.trim(l)]=new a.Property(a.trim(l),a.trim(h)))}a.Styles[f]=g;if(f=="@font-face"){f=g["font-family"].value.replace(/"/g,
"");g=g.src.value.split(",");for(j=0;j<g.length;j++)if(g[j].indexOf('format("svg")')>0){l=g[j].indexOf("url");h=g[j].indexOf(")",l);l=g[j].substr(l+5,h-l-6);l=a.parseXml(a.ajax(l)).getElementsByTagName("font");for(h=0;h<l.length;h++){var o=a.CreateElement(l[h]);a.Definitions[f]=o}}}}}};a.Element.style.prototype=new a.Element.ElementBase;a.Element.use=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseSetContext=this.setContext;this.setContext=function(a){this.baseSetContext(a);
this.attribute("x").hasValue()&&a.translate(this.attribute("x").Length.toPixels("x"),0);this.attribute("y").hasValue()&&a.translate(0,this.attribute("y").Length.toPixels("y"))};this.getDefinition=function(){var a=this.attribute("xlink:href").Definition.getDefinition();if(this.attribute("width").hasValue())a.attribute("width",!0).value=this.attribute("width").value;if(this.attribute("height").hasValue())a.attribute("height",!0).value=this.attribute("height").value;return a};this.path=function(a){var b=
this.getDefinition();b!=null&&b.path(a)};this.renderChildren=function(a){var b=this.getDefinition();b!=null&&b.render(a)}};a.Element.use.prototype=new a.Element.RenderedElementBase;a.Element.mask=function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,b){var c=this.attribute("x").Length.toPixels("x"),e=this.attribute("y").Length.toPixels("y"),f=this.attribute("width").Length.toPixels("x"),g=this.attribute("height").Length.toPixels("y"),j=b.attribute("mask").value;b.attribute("mask").value=
"";var h=document.createElement("canvas");h.width=c+f;h.height=e+g;var l=h.getContext("2d");this.renderChildren(l);var o=document.createElement("canvas");o.width=c+f;o.height=e+g;var n=o.getContext("2d");b.render(n);n.globalCompositeOperation="destination-in";n.fillStyle=l.createPattern(h,"no-repeat");n.fillRect(0,0,c+f,e+g);a.fillStyle=n.createPattern(o,"no-repeat");a.fillRect(0,0,c+f,e+g);b.attribute("mask").value=j};this.render=function(){}};a.Element.mask.prototype=new a.Element.ElementBase;a.Element.clipPath=
function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a){for(var b=0;b<this.children.length;b++)this.children[b].path&&(this.children[b].path(a),a.clip())};this.render=function(){}};a.Element.clipPath.prototype=new a.Element.ElementBase;a.Element.filter=function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,b){var c=b.getBoundingBox(),e=this.attribute("x").Length.toPixels("x"),f=this.attribute("y").Length.toPixels("y");if(e==0||f==0)e=c.x1,f=c.y1;var g=
this.attribute("width").Length.toPixels("x"),j=this.attribute("height").Length.toPixels("y");if(g==0||j==0)g=c.width(),j=c.height();c=b.style("filter").value;b.style("filter").value="";var h=0.2*g,l=0.2*j,o=document.createElement("canvas");o.width=g+2*h;o.height=j+2*l;var n=o.getContext("2d");n.translate(-e+h,-f+l);b.render(n);for(var q=0;q<this.children.length;q++)this.children[q].apply(n,0,0,g+2*h,j+2*l);a.drawImage(o,0,0,g+2*h,j+2*l,e-h,f-l,g+2*h,j+2*l);b.style("filter",!0).value=c};this.render=
function(){}};a.Element.filter.prototype=new a.Element.ElementBase;a.Element.feGaussianBlur=function(c){function d(a,c,d,f,g){for(var j=0;j<g;j++)for(var h=0;h<f;h++)for(var l=a[j*f*4+h*4+3]/255,o=0;o<4;o++){for(var n=d[0]*(l==0?255:a[j*f*4+h*4+o])*(l==0||o==3?1:l),q=1;q<d.length;q++){var p=Math.max(h-q,0),m=a[j*f*4+p*4+3]/255,p=Math.min(h+q,f-1),p=a[j*f*4+p*4+3]/255,s=d[q],r;m==0?r=255:(r=Math.max(h-q,0),r=a[j*f*4+r*4+o]);m=r*(m==0||o==3?1:m);p==0?r=255:(r=Math.min(h+q,f-1),r=a[j*f*4+r*4+o]);n+=
s*(m+r*(p==0||o==3?1:p))}c[h*g*4+j*4+o]=n}}this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,c,e,f,g){var e=this.attribute("stdDeviation").numValue(),c=a.getImageData(0,0,f,g),e=Math.max(e,0.01),j=Math.ceil(e*4)+1;mask=[];for(var h=0;h<j;h++)mask[h]=Math.exp(-0.5*(h/e)*(h/e));e=mask;j=0;for(h=1;h<e.length;h++)j+=Math.abs(e[h]);j=2*j+Math.abs(e[0]);for(h=0;h<e.length;h++)e[h]/=j;tmp=[];d(c.data,tmp,e,f,g);d(tmp,c.data,e,g,f);a.clearRect(0,0,f,g);a.putImageData(c,0,0)}};a.Element.filter.prototype=
new a.Element.feGaussianBlur;a.Element.title=function(){};a.Element.title.prototype=new a.Element.ElementBase;a.Element.desc=function(){};a.Element.desc.prototype=new a.Element.ElementBase;a.Element.MISSING=function(a){console.log("ERROR: Element '"+a.nodeName+"' not yet implemented.")};a.Element.MISSING.prototype=new a.Element.ElementBase;a.CreateElement=function(c){var d=c.nodeName.replace(/^[^:]+:/,""),d=d.replace(/\-/g,""),b=null,b=typeof a.Element[d]!="undefined"?new a.Element[d](c):new a.Element.MISSING(c);
b.type=c.nodeName;return b};a.load=function(c,d){a.loadXml(c,a.ajax(d))};a.loadXml=function(c,d){a.loadXmlDoc(c,a.parseXml(d))};a.loadXmlDoc=function(c,d){a.init(c);var b=function(a){for(var b=c.canvas;b;)a.x-=b.offsetLeft,a.y-=b.offsetTop,b=b.offsetParent;window.scrollX&&(a.x+=window.scrollX);window.scrollY&&(a.y+=window.scrollY);return a};if(a.opts.ignoreMouse!=!0)c.canvas.onclick=function(c){c=b(new a.Point(c!=null?c.clientX:event.clientX,c!=null?c.clientY:event.clientY));a.Mouse.onclick(c.x,c.y)},
c.canvas.onmousemove=function(c){c=b(new a.Point(c!=null?c.clientX:event.clientX,c!=null?c.clientY:event.clientY));a.Mouse.onmousemove(c.x,c.y)};var k=a.CreateElement(d.documentElement),e=k.root=!0,f=function(){a.ViewPort.Clear();c.canvas.parentNode&&a.ViewPort.SetCurrent(c.canvas.parentNode.clientWidth,c.canvas.parentNode.clientHeight);if(a.opts.ignoreDimensions!=!0){if(k.style("width").hasValue())c.canvas.width=k.style("width").Length.toPixels("x"),c.canvas.style.width=c.canvas.width+"px";if(k.style("height").hasValue())c.canvas.height=
k.style("height").Length.toPixels("y"),c.canvas.style.height=c.canvas.height+"px"}var b=c.canvas.clientWidth||c.canvas.width,d=c.canvas.clientHeight||c.canvas.height;a.ViewPort.SetCurrent(b,d);if(a.opts!=null&&a.opts.offsetX!=null)k.attribute("x",!0).value=a.opts.offsetX;if(a.opts!=null&&a.opts.offsetY!=null)k.attribute("y",!0).value=a.opts.offsetY;if(a.opts!=null&&a.opts.scaleWidth!=null&&a.opts.scaleHeight!=null){var f=1,g=1;k.attribute("width").hasValue()&&(f=k.attribute("width").Length.toPixels("x")/
a.opts.scaleWidth);k.attribute("height").hasValue()&&(g=k.attribute("height").Length.toPixels("y")/a.opts.scaleHeight);k.attribute("width",!0).value=a.opts.scaleWidth;k.attribute("height",!0).value=a.opts.scaleHeight;k.attribute("viewBox",!0).value="0 0 "+b*f+" "+d*g;k.attribute("preserveAspectRatio",!0).value="none"}a.opts.ignoreClear!=!0&&c.clearRect(0,0,b,d);k.render(c);e&&(e=!1,a.opts!=null&&typeof a.opts.renderCallback=="function"&&a.opts.renderCallback())},g=!0;a.ImagesLoaded()&&(g=!1,f());
a.intervalID=setInterval(function(){var b=!1;g&&a.ImagesLoaded()&&(g=!1,b=!0);a.opts.ignoreMouse!=!0&&(b|=a.Mouse.hasEvents());if(a.opts.ignoreAnimation!=!0)for(var c=0;c<a.Animations.length;c++)b|=a.Animations[c].update(1E3/a.FRAMERATE);a.opts!=null&&typeof a.opts.forceRedraw=="function"&&a.opts.forceRedraw()==!0&&(b=!0);b&&(f(),a.Mouse.runEvents())},1E3/a.FRAMERATE)};a.stop=function(){a.intervalID&&clearInterval(a.intervalID)};a.Mouse=new function(){this.events=[];this.hasEvents=function(){return this.events.length!=
0};this.onclick=function(a,d){this.events.push({type:"onclick",x:a,y:d,run:function(a){if(a.onclick)a.onclick()}})};this.onmousemove=function(a,d){this.events.push({type:"onmousemove",x:a,y:d,run:function(a){if(a.onmousemove)a.onmousemove()}})};this.eventElements=[];this.checkPath=function(a,d){for(var b=0;b<this.events.length;b++){var k=this.events[b];d.isPointInPath&&d.isPointInPath(k.x,k.y)&&(this.eventElements[b]=a)}};this.checkBoundingBox=function(a,d){for(var b=0;b<this.events.length;b++){var k=
this.events[b];d.isPointInBox(k.x,k.y)&&(this.eventElements[b]=a)}};this.runEvents=function(){a.ctx.canvas.style.cursor="";for(var c=0;c<this.events.length;c++)for(var d=this.events[c],b=this.eventElements[c];b;)d.run(b),b=b.parent;this.events=[];this.eventElements=[]}};return a}this.canvg=function(a,c,d){if(a==null&&c==null&&d==null)for(var c=document.getElementsByTagName("svg"),b=0;b<c.length;b++){a=c[b];d=document.createElement("canvas");d.width=a.clientWidth;d.height=a.clientHeight;a.parentNode.insertBefore(d,
a);a.parentNode.removeChild(a);var k=document.createElement("div");k.appendChild(a);canvg(d,k.innerHTML)}else d=d||{},typeof a=="string"&&(a=document.getElementById(a)),a.svg==null?(b=m(),a.svg=b):(b=a.svg,b.stop()),b.opts=d,a=a.getContext("2d"),typeof c.documentElement!="undefined"?b.loadXmlDoc(a,c):c.substr(0,1)=="<"?b.loadXml(a,c):b.load(a,c)}})();
if(CanvasRenderingContext2D)CanvasRenderingContext2D.prototype.drawSvg=function(m,a,c,d,b){canvg(this.canvas,m,{ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0,ignoreClear:!0,offsetX:a,offsetY:c,scaleWidth:d,scaleHeight:b})};
(function(m){var a=m.css,c=m.CanVGRenderer,d=m.SVGRenderer,b=m.extend,k=m.merge,e=m.addEvent,f=m.createElement,g=m.discardElement;b(c.prototype,d.prototype);b(c.prototype,{create:function(a,b,c,d){this.setContainer(b,c,d);this.configure(a)},setContainer:function(a,b,c){var d=a.style,e=a.parentNode,g=d.left,d=d.top,k=a.offsetWidth,m=a.offsetHeight,s={visibility:"hidden",position:"absolute"};this.init.apply(this,[a,b,c]);this.canvas=f("canvas",{width:k,height:m},{position:"relative",left:g,top:d},a);
this.ttLine=f("div",null,s,e);this.ttDiv=f("div",null,s,e);this.ttTimer=void 0;this.hiddenSvg=a=f("div",{width:k,height:m},{visibility:"hidden",left:g,top:d},e);a.appendChild(this.box)},configure:function(b){var c=this,d=b.options.tooltip,f=d.borderWidth,g=c.ttDiv,m=d.style,p=c.ttLine,t=parseInt(m.padding,10),m=k(m,{padding:t+"px","background-color":d.backgroundColor,"border-style":"solid","border-width":f+"px","border-radius":d.borderRadius+"px"});d.shadow&&(m=k(m,{"box-shadow":"1px 1px 3px gray",
"-webkit-box-shadow":"1px 1px 3px gray"}));a(g,m);a(p,{"border-left":"1px solid darkgray"});e(b,"tooltipRefresh",function(d){var e=b.container,f=e.offsetLeft,e=e.offsetTop,k;g.innerHTML=d.text;k=b.tooltip.getPosition(g.offsetWidth,g.offsetHeight,{plotX:d.x,plotY:d.y});a(g,{visibility:"visible",left:k.x+"px",top:k.y+"px","border-color":d.borderColor});a(p,{visibility:"visible",left:f+d.x+"px",top:e+b.plotTop+"px",height:b.plotHeight+"px"});c.ttTimer!==void 0&&clearTimeout(c.ttTimer);c.ttTimer=setTimeout(function(){a(g,
{visibility:"hidden"});a(p,{visibility:"hidden"})},3E3)})},destroy:function(){g(this.canvas);this.ttTimer!==void 0&&clearTimeout(this.ttTimer);g(this.ttLine);g(this.ttDiv);g(this.hiddenSvg);return d.prototype.destroy.apply(this)},color:function(a,b,c){a&&a.linearGradient&&(a=a.stops[a.stops.length-1][1]);return d.prototype.color.call(this,a,b,c)},draw:function(){window.canvg(this.canvas,this.hiddenSvg.innerHTML)}})})(Highcharts);
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/canvas-tools.src.js
New file
@@ -0,0 +1,3113 @@
/**
 * @license A class to parse color values
 * @author Stoyan Stefanov <sstoo@gmail.com>
 * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
 * Use it if you like it
 *
 */
function RGBColor(color_string)
{
    this.ok = false;
    // strip any leading #
    if (color_string.charAt(0) == '#') { // remove # if any
        color_string = color_string.substr(1,6);
    }
    color_string = color_string.replace(/ /g,'');
    color_string = color_string.toLowerCase();
    // before getting into regexps, try simple matches
    // and overwrite the input
    var simple_colors = {
        aliceblue: 'f0f8ff',
        antiquewhite: 'faebd7',
        aqua: '00ffff',
        aquamarine: '7fffd4',
        azure: 'f0ffff',
        beige: 'f5f5dc',
        bisque: 'ffe4c4',
        black: '000000',
        blanchedalmond: 'ffebcd',
        blue: '0000ff',
        blueviolet: '8a2be2',
        brown: 'a52a2a',
        burlywood: 'deb887',
        cadetblue: '5f9ea0',
        chartreuse: '7fff00',
        chocolate: 'd2691e',
        coral: 'ff7f50',
        cornflowerblue: '6495ed',
        cornsilk: 'fff8dc',
        crimson: 'dc143c',
        cyan: '00ffff',
        darkblue: '00008b',
        darkcyan: '008b8b',
        darkgoldenrod: 'b8860b',
        darkgray: 'a9a9a9',
        darkgreen: '006400',
        darkkhaki: 'bdb76b',
        darkmagenta: '8b008b',
        darkolivegreen: '556b2f',
        darkorange: 'ff8c00',
        darkorchid: '9932cc',
        darkred: '8b0000',
        darksalmon: 'e9967a',
        darkseagreen: '8fbc8f',
        darkslateblue: '483d8b',
        darkslategray: '2f4f4f',
        darkturquoise: '00ced1',
        darkviolet: '9400d3',
        deeppink: 'ff1493',
        deepskyblue: '00bfff',
        dimgray: '696969',
        dodgerblue: '1e90ff',
        feldspar: 'd19275',
        firebrick: 'b22222',
        floralwhite: 'fffaf0',
        forestgreen: '228b22',
        fuchsia: 'ff00ff',
        gainsboro: 'dcdcdc',
        ghostwhite: 'f8f8ff',
        gold: 'ffd700',
        goldenrod: 'daa520',
        gray: '808080',
        green: '008000',
        greenyellow: 'adff2f',
        honeydew: 'f0fff0',
        hotpink: 'ff69b4',
        indianred : 'cd5c5c',
        indigo : '4b0082',
        ivory: 'fffff0',
        khaki: 'f0e68c',
        lavender: 'e6e6fa',
        lavenderblush: 'fff0f5',
        lawngreen: '7cfc00',
        lemonchiffon: 'fffacd',
        lightblue: 'add8e6',
        lightcoral: 'f08080',
        lightcyan: 'e0ffff',
        lightgoldenrodyellow: 'fafad2',
        lightgrey: 'd3d3d3',
        lightgreen: '90ee90',
        lightpink: 'ffb6c1',
        lightsalmon: 'ffa07a',
        lightseagreen: '20b2aa',
        lightskyblue: '87cefa',
        lightslateblue: '8470ff',
        lightslategray: '778899',
        lightsteelblue: 'b0c4de',
        lightyellow: 'ffffe0',
        lime: '00ff00',
        limegreen: '32cd32',
        linen: 'faf0e6',
        magenta: 'ff00ff',
        maroon: '800000',
        mediumaquamarine: '66cdaa',
        mediumblue: '0000cd',
        mediumorchid: 'ba55d3',
        mediumpurple: '9370d8',
        mediumseagreen: '3cb371',
        mediumslateblue: '7b68ee',
        mediumspringgreen: '00fa9a',
        mediumturquoise: '48d1cc',
        mediumvioletred: 'c71585',
        midnightblue: '191970',
        mintcream: 'f5fffa',
        mistyrose: 'ffe4e1',
        moccasin: 'ffe4b5',
        navajowhite: 'ffdead',
        navy: '000080',
        oldlace: 'fdf5e6',
        olive: '808000',
        olivedrab: '6b8e23',
        orange: 'ffa500',
        orangered: 'ff4500',
        orchid: 'da70d6',
        palegoldenrod: 'eee8aa',
        palegreen: '98fb98',
        paleturquoise: 'afeeee',
        palevioletred: 'd87093',
        papayawhip: 'ffefd5',
        peachpuff: 'ffdab9',
        peru: 'cd853f',
        pink: 'ffc0cb',
        plum: 'dda0dd',
        powderblue: 'b0e0e6',
        purple: '800080',
        red: 'ff0000',
        rosybrown: 'bc8f8f',
        royalblue: '4169e1',
        saddlebrown: '8b4513',
        salmon: 'fa8072',
        sandybrown: 'f4a460',
        seagreen: '2e8b57',
        seashell: 'fff5ee',
        sienna: 'a0522d',
        silver: 'c0c0c0',
        skyblue: '87ceeb',
        slateblue: '6a5acd',
        slategray: '708090',
        snow: 'fffafa',
        springgreen: '00ff7f',
        steelblue: '4682b4',
        tan: 'd2b48c',
        teal: '008080',
        thistle: 'd8bfd8',
        tomato: 'ff6347',
        turquoise: '40e0d0',
        violet: 'ee82ee',
        violetred: 'd02090',
        wheat: 'f5deb3',
        white: 'ffffff',
        whitesmoke: 'f5f5f5',
        yellow: 'ffff00',
        yellowgreen: '9acd32'
    };
    for (var key in simple_colors) {
        if (color_string == key) {
            color_string = simple_colors[key];
        }
    }
    // emd of simple type-in colors
    // array of color definition objects
    var color_defs = [
        {
            re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
            example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
            process: function (bits){
                return [
                    parseInt(bits[1]),
                    parseInt(bits[2]),
                    parseInt(bits[3])
                ];
            }
        },
        {
            re: /^(\w{2})(\w{2})(\w{2})$/,
            example: ['#00ff00', '336699'],
            process: function (bits){
                return [
                    parseInt(bits[1], 16),
                    parseInt(bits[2], 16),
                    parseInt(bits[3], 16)
                ];
            }
        },
        {
            re: /^(\w{1})(\w{1})(\w{1})$/,
            example: ['#fb0', 'f0f'],
            process: function (bits){
                return [
                    parseInt(bits[1] + bits[1], 16),
                    parseInt(bits[2] + bits[2], 16),
                    parseInt(bits[3] + bits[3], 16)
                ];
            }
        }
    ];
    // search through the definitions to find a match
    for (var i = 0; i < color_defs.length; i++) {
        var re = color_defs[i].re;
        var processor = color_defs[i].process;
        var bits = re.exec(color_string);
        if (bits) {
            channels = processor(bits);
            this.r = channels[0];
            this.g = channels[1];
            this.b = channels[2];
            this.ok = true;
        }
    }
    // validate/cleanup values
    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
    this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
    this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
    // some getters
    this.toRGB = function () {
        return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
    }
    this.toHex = function () {
        var r = this.r.toString(16);
        var g = this.g.toString(16);
        var b = this.b.toString(16);
        if (r.length == 1) r = '0' + r;
        if (g.length == 1) g = '0' + g;
        if (b.length == 1) b = '0' + b;
        return '#' + r + g + b;
    }
    // help
    this.getHelpXML = function () {
        var examples = new Array();
        // add regexps
        for (var i = 0; i < color_defs.length; i++) {
            var example = color_defs[i].example;
            for (var j = 0; j < example.length; j++) {
                examples[examples.length] = example[j];
            }
        }
        // add type-in colors
        for (var sc in simple_colors) {
            examples[examples.length] = sc;
        }
        var xml = document.createElement('ul');
        xml.setAttribute('id', 'rgbcolor-examples');
        for (var i = 0; i < examples.length; i++) {
            try {
                var list_item = document.createElement('li');
                var list_color = new RGBColor(examples[i]);
                var example_div = document.createElement('div');
                example_div.style.cssText =
                        'margin: 3px; '
                        + 'border: 1px solid black; '
                        + 'background:' + list_color.toHex() + '; '
                        + 'color:' + list_color.toHex()
                ;
                example_div.appendChild(document.createTextNode('test'));
                var list_item_value = document.createTextNode(
                    ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
                );
                list_item.appendChild(example_div);
                list_item.appendChild(list_item_value);
                xml.appendChild(list_item);
            } catch(e){}
        }
        return xml;
    }
}
/**
 * @license canvg.js - Javascript SVG parser and renderer on Canvas
 * MIT Licensed
 * Gabe Lerner (gabelerner@gmail.com)
 * http://code.google.com/p/canvg/
 *
 * Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/
 *
 */
if(!window.console) {
    window.console = {};
    window.console.log = function(str) {};
    window.console.dir = function(str) {};
}
if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}
(function(){
    // canvg(target, s)
    // empty parameters: replace all 'svg' elements on page with 'canvas' elements
    // target: canvas element or the id of a canvas element
    // s: svg string, url to svg file, or xml document
    // opts: optional hash of options
    //         ignoreMouse: true => ignore mouse events
    //         ignoreAnimation: true => ignore animations
    //         ignoreDimensions: true => does not try to resize canvas
    //         ignoreClear: true => does not clear canvas
    //         offsetX: int => draws at a x offset
    //         offsetY: int => draws at a y offset
    //         scaleWidth: int => scales horizontally to width
    //         scaleHeight: int => scales vertically to height
    //         renderCallback: function => will call the function after the first render is completed
    //         forceRedraw: function => will call the function on every frame, if it returns true, will redraw
    this.canvg = function (target, s, opts) {
        // no parameters
        if (target == null && s == null && opts == null) {
            var svgTags = document.getElementsByTagName('svg');
            for (var i=0; i<svgTags.length; i++) {
                var svgTag = svgTags[i];
                var c = document.createElement('canvas');
                c.width = svgTag.clientWidth;
                c.height = svgTag.clientHeight;
                svgTag.parentNode.insertBefore(c, svgTag);
                svgTag.parentNode.removeChild(svgTag);
                var div = document.createElement('div');
                div.appendChild(svgTag);
                canvg(c, div.innerHTML);
            }
            return;
        }
        opts = opts || {};
        if (typeof target == 'string') {
            target = document.getElementById(target);
        }
        // reuse class per canvas
        var svg;
        if (target.svg == null) {
            svg = build();
            target.svg = svg;
        }
        else {
            svg = target.svg;
            svg.stop();
        }
        svg.opts = opts;
        var ctx = target.getContext('2d');
        if (typeof(s.documentElement) != 'undefined') {
            // load from xml doc
            svg.loadXmlDoc(ctx, s);
        }
        else if (s.substr(0,1) == '<') {
            // load from xml string
            svg.loadXml(ctx, s);
        }
        else {
            // load from url
            svg.load(ctx, s);
        }
    }
    function build() {
        var svg = { };
        svg.FRAMERATE = 30;
        svg.MAX_VIRTUAL_PIXELS = 30000;
        // globals
        svg.init = function(ctx) {
            svg.Definitions = {};
            svg.Styles = {};
            svg.Animations = [];
            svg.Images = [];
            svg.ctx = ctx;
            svg.ViewPort = new (function () {
                this.viewPorts = [];
                this.Clear = function() { this.viewPorts = []; }
                this.SetCurrent = function(width, height) { this.viewPorts.push({ width: width, height: height }); }
                this.RemoveCurrent = function() { this.viewPorts.pop(); }
                this.Current = function() { return this.viewPorts[this.viewPorts.length - 1]; }
                this.width = function() { return this.Current().width; }
                this.height = function() { return this.Current().height; }
                this.ComputeSize = function(d) {
                    if (d != null && typeof(d) == 'number') return d;
                    if (d == 'x') return this.width();
                    if (d == 'y') return this.height();
                    return Math.sqrt(Math.pow(this.width(), 2) + Math.pow(this.height(), 2)) / Math.sqrt(2);
                }
            });
        }
        svg.init();
        // images loaded
        svg.ImagesLoaded = function() {
            for (var i=0; i<svg.Images.length; i++) {
                if (!svg.Images[i].loaded) return false;
            }
            return true;
        }
        // trim
        svg.trim = function(s) { return s.replace(/^\s+|\s+$/g, ''); }
        // compress spaces
        svg.compressSpaces = function(s) { return s.replace(/[\s\r\t\n]+/gm,' '); }
        // ajax
        svg.ajax = function(url) {
            var AJAX;
            if(window.XMLHttpRequest){AJAX=new XMLHttpRequest();}
            else{AJAX=new ActiveXObject('Microsoft.XMLHTTP');}
            if(AJAX){
               AJAX.open('GET',url,false);
               AJAX.send(null);
               return AJAX.responseText;
            }
            return null;
        }
        // parse xml
        svg.parseXml = function(xml) {
            if (window.DOMParser)
            {
                var parser = new DOMParser();
                return parser.parseFromString(xml, 'text/xml');
            }
            else
            {
                xml = xml.replace(/<!DOCTYPE svg[^>]*>/, '');
                var xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
                xmlDoc.async = 'false';
                xmlDoc.loadXML(xml);
                return xmlDoc;
            }
        }
        svg.Property = function(name, value) {
            this.name = name;
            this.value = value;
            this.hasValue = function() {
                return (this.value != null && this.value !== '');
            }
            // return the numerical value of the property
            this.numValue = function() {
                if (!this.hasValue()) return 0;
                var n = parseFloat(this.value);
                if ((this.value + '').match(/%$/)) {
                    n = n / 100.0;
                }
                return n;
            }
            this.valueOrDefault = function(def) {
                if (this.hasValue()) return this.value;
                return def;
            }
            this.numValueOrDefault = function(def) {
                if (this.hasValue()) return this.numValue();
                return def;
            }
            /* EXTENSIONS */
            var that = this;
            // color extensions
            this.Color = {
                // augment the current color value with the opacity
                addOpacity: function(opacity) {
                    var newValue = that.value;
                    if (opacity != null && opacity != '') {
                        var color = new RGBColor(that.value);
                        if (color.ok) {
                            newValue = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + opacity + ')';
                        }
                    }
                    return new svg.Property(that.name, newValue);
                }
            }
            // definition extensions
            this.Definition = {
                // get the definition from the definitions table
                getDefinition: function() {
                    var name = that.value.replace(/^(url\()?#([^\)]+)\)?$/, '$2');
                    return svg.Definitions[name];
                },
                isUrl: function() {
                    return that.value.indexOf('url(') == 0
                },
                getFillStyle: function(e) {
                    var def = this.getDefinition();
                    // gradient
                    if (def != null && def.createGradient) {
                        return def.createGradient(svg.ctx, e);
                    }
                    // pattern
                    if (def != null && def.createPattern) {
                        return def.createPattern(svg.ctx, e);
                    }
                    return null;
                }
            }
            // length extensions
            this.Length = {
                DPI: function(viewPort) {
                    return 96.0; // TODO: compute?
                },
                EM: function(viewPort) {
                    var em = 12;
                    var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize);
                    if (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort);
                    return em;
                },
                // get the length as pixels
                toPixels: function(viewPort) {
                    if (!that.hasValue()) return 0;
                    var s = that.value+'';
                    if (s.match(/em$/)) return that.numValue() * this.EM(viewPort);
                    if (s.match(/ex$/)) return that.numValue() * this.EM(viewPort) / 2.0;
                    if (s.match(/px$/)) return that.numValue();
                    if (s.match(/pt$/)) return that.numValue() * 1.25;
                    if (s.match(/pc$/)) return that.numValue() * 15;
                    if (s.match(/cm$/)) return that.numValue() * this.DPI(viewPort) / 2.54;
                    if (s.match(/mm$/)) return that.numValue() * this.DPI(viewPort) / 25.4;
                    if (s.match(/in$/)) return that.numValue() * this.DPI(viewPort);
                    if (s.match(/%$/)) return that.numValue() * svg.ViewPort.ComputeSize(viewPort);
                    return that.numValue();
                }
            }
            // time extensions
            this.Time = {
                // get the time as milliseconds
                toMilliseconds: function() {
                    if (!that.hasValue()) return 0;
                    var s = that.value+'';
                    if (s.match(/s$/)) return that.numValue() * 1000;
                    if (s.match(/ms$/)) return that.numValue();
                    return that.numValue();
                }
            }
            // angle extensions
            this.Angle = {
                // get the angle as radians
                toRadians: function() {
                    if (!that.hasValue()) return 0;
                    var s = that.value+'';
                    if (s.match(/deg$/)) return that.numValue() * (Math.PI / 180.0);
                    if (s.match(/grad$/)) return that.numValue() * (Math.PI / 200.0);
                    if (s.match(/rad$/)) return that.numValue();
                    return that.numValue() * (Math.PI / 180.0);
                }
            }
        }
        // fonts
        svg.Font = new (function() {
            this.Styles = ['normal','italic','oblique','inherit'];
            this.Variants = ['normal','small-caps','inherit'];
            this.Weights = ['normal','bold','bolder','lighter','100','200','300','400','500','600','700','800','900','inherit'];
            this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) {
                var f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font);
                return {
                    fontFamily: fontFamily || f.fontFamily,
                    fontSize: fontSize || f.fontSize,
                    fontStyle: fontStyle || f.fontStyle,
                    fontWeight: fontWeight || f.fontWeight,
                    fontVariant: fontVariant || f.fontVariant,
                    toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') }
                }
            }
            var that = this;
            this.Parse = function(s) {
                var f = {};
                var d = svg.trim(svg.compressSpaces(s || '')).split(' ');
                var set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false }
                var ff = '';
                for (var i=0; i<d.length; i++) {
                    if (!set.fontStyle && that.Styles.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontStyle = d[i]; set.fontStyle = true; }
                    else if (!set.fontVariant && that.Variants.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontVariant = d[i]; set.fontStyle = set.fontVariant = true;    }
                    else if (!set.fontWeight && that.Weights.indexOf(d[i]) != -1) {    if (d[i] != 'inherit') f.fontWeight = d[i]; set.fontStyle = set.fontVariant = set.fontWeight = true; }
                    else if (!set.fontSize) { if (d[i] != 'inherit') f.fontSize = d[i].split('/')[0]; set.fontStyle = set.fontVariant = set.fontWeight = set.fontSize = true; }
                    else { if (d[i] != 'inherit') ff += d[i]; }
                } if (ff != '') f.fontFamily = ff;
                return f;
            }
        });
        // points and paths
        svg.ToNumberArray = function(s) {
            var a = svg.trim(svg.compressSpaces((s || '').replace(/,/g, ' '))).split(' ');
            for (var i=0; i<a.length; i++) {
                a[i] = parseFloat(a[i]);
            }
            return a;
        }
        svg.Point = function(x, y) {
            this.x = x;
            this.y = y;
            this.angleTo = function(p) {
                return Math.atan2(p.y - this.y, p.x - this.x);
            }
            this.applyTransform = function(v) {
                var xp = this.x * v[0] + this.y * v[2] + v[4];
                var yp = this.x * v[1] + this.y * v[3] + v[5];
                this.x = xp;
                this.y = yp;
            }
        }
        svg.CreatePoint = function(s) {
            var a = svg.ToNumberArray(s);
            return new svg.Point(a[0], a[1]);
        }
        svg.CreatePath = function(s) {
            var a = svg.ToNumberArray(s);
            var path = [];
            for (var i=0; i<a.length; i+=2) {
                path.push(new svg.Point(a[i], a[i+1]));
            }
            return path;
        }
        // bounding box
        svg.BoundingBox = function(x1, y1, x2, y2) { // pass in initial points if you want
            this.x1 = Number.NaN;
            this.y1 = Number.NaN;
            this.x2 = Number.NaN;
            this.y2 = Number.NaN;
            this.x = function() { return this.x1; }
            this.y = function() { return this.y1; }
            this.width = function() { return this.x2 - this.x1; }
            this.height = function() { return this.y2 - this.y1; }
            this.addPoint = function(x, y) {
                if (x != null) {
                    if (isNaN(this.x1) || isNaN(this.x2)) {
                        this.x1 = x;
                        this.x2 = x;
                    }
                    if (x < this.x1) this.x1 = x;
                    if (x > this.x2) this.x2 = x;
                }
                if (y != null) {
                    if (isNaN(this.y1) || isNaN(this.y2)) {
                        this.y1 = y;
                        this.y2 = y;
                    }
                    if (y < this.y1) this.y1 = y;
                    if (y > this.y2) this.y2 = y;
                }
            }
            this.addX = function(x) { this.addPoint(x, null); }
            this.addY = function(y) { this.addPoint(null, y); }
            this.addBoundingBox = function(bb) {
                this.addPoint(bb.x1, bb.y1);
                this.addPoint(bb.x2, bb.y2);
            }
            this.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) {
                var cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0)
                var cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0)
                var cp2x = cp1x + 1/3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0)
                var cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0)
                this.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y,    cp2y, p2x, p2y);
            }
            this.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {
                // from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
                var p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y];
                this.addPoint(p0[0], p0[1]);
                this.addPoint(p3[0], p3[1]);
                for (i=0; i<=1; i++) {
                    var f = function(t) {
                        return Math.pow(1-t, 3) * p0[i]
                        + 3 * Math.pow(1-t, 2) * t * p1[i]
                        + 3 * (1-t) * Math.pow(t, 2) * p2[i]
                        + Math.pow(t, 3) * p3[i];
                    }
                    var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
                    var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
                    var c = 3 * p1[i] - 3 * p0[i];
                    if (a == 0) {
                        if (b == 0) continue;
                        var t = -c / b;
                        if (0 < t && t < 1) {
                            if (i == 0) this.addX(f(t));
                            if (i == 1) this.addY(f(t));
                        }
                        continue;
                    }
                    var b2ac = Math.pow(b, 2) - 4 * c * a;
                    if (b2ac < 0) continue;
                    var t1 = (-b + Math.sqrt(b2ac)) / (2 * a);
                    if (0 < t1 && t1 < 1) {
                        if (i == 0) this.addX(f(t1));
                        if (i == 1) this.addY(f(t1));
                    }
                    var t2 = (-b - Math.sqrt(b2ac)) / (2 * a);
                    if (0 < t2 && t2 < 1) {
                        if (i == 0) this.addX(f(t2));
                        if (i == 1) this.addY(f(t2));
                    }
                }
            }
            this.isPointInBox = function(x, y) {
                return (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2);
            }
            this.addPoint(x1, y1);
            this.addPoint(x2, y2);
        }
        // transforms
        svg.Transform = function(v) {
            var that = this;
            this.Type = {}
            // translate
            this.Type.translate = function(s) {
                this.p = svg.CreatePoint(s);
                this.apply = function(ctx) {
                    ctx.translate(this.p.x || 0.0, this.p.y || 0.0);
                }
                this.applyToPoint = function(p) {
                    p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);
                }
            }
            // rotate
            this.Type.rotate = function(s) {
                var a = svg.ToNumberArray(s);
                this.angle = new svg.Property('angle', a[0]);
                this.cx = a[1] || 0;
                this.cy = a[2] || 0;
                this.apply = function(ctx) {
                    ctx.translate(this.cx, this.cy);
                    ctx.rotate(this.angle.Angle.toRadians());
                    ctx.translate(-this.cx, -this.cy);
                }
                this.applyToPoint = function(p) {
                    var a = this.angle.Angle.toRadians();
                    p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);
                    p.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]);
                    p.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]);
                }
            }
            this.Type.scale = function(s) {
                this.p = svg.CreatePoint(s);
                this.apply = function(ctx) {
                    ctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0);
                }
                this.applyToPoint = function(p) {
                    p.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]);
                }
            }
            this.Type.matrix = function(s) {
                this.m = svg.ToNumberArray(s);
                this.apply = function(ctx) {
                    ctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]);
                }
                this.applyToPoint = function(p) {
                    p.applyTransform(this.m);
                }
            }
            this.Type.SkewBase = function(s) {
                this.base = that.Type.matrix;
                this.base(s);
                this.angle = new svg.Property('angle', s);
            }
            this.Type.SkewBase.prototype = new this.Type.matrix;
            this.Type.skewX = function(s) {
                this.base = that.Type.SkewBase;
                this.base(s);
                this.m = [1, 0, Math.tan(this.angle.Angle.toRadians()), 1, 0, 0];
            }
            this.Type.skewX.prototype = new this.Type.SkewBase;
            this.Type.skewY = function(s) {
                this.base = that.Type.SkewBase;
                this.base(s);
                this.m = [1, Math.tan(this.angle.Angle.toRadians()), 0, 1, 0, 0];
            }
            this.Type.skewY.prototype = new this.Type.SkewBase;
            this.transforms = [];
            this.apply = function(ctx) {
                for (var i=0; i<this.transforms.length; i++) {
                    this.transforms[i].apply(ctx);
                }
            }
            this.applyToPoint = function(p) {
                for (var i=0; i<this.transforms.length; i++) {
                    this.transforms[i].applyToPoint(p);
                }
            }
            var data = svg.trim(svg.compressSpaces(v)).split(/\s(?=[a-z])/);
            for (var i=0; i<data.length; i++) {
                var type = data[i].split('(')[0];
                var s = data[i].split('(')[1].replace(')','');
                var transform = new this.Type[type](s);
                this.transforms.push(transform);
            }
        }
        // aspect ratio
        svg.AspectRatio = function(ctx, aspectRatio, width, desiredWidth, height, desiredHeight, minX, minY, refX, refY) {
            // aspect ratio - http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
            aspectRatio = svg.compressSpaces(aspectRatio);
            aspectRatio = aspectRatio.replace(/^defer\s/,''); // ignore defer
            var align = aspectRatio.split(' ')[0] || 'xMidYMid';
            var meetOrSlice = aspectRatio.split(' ')[1] || 'meet';
            // calculate scale
            var scaleX = width / desiredWidth;
            var scaleY = height / desiredHeight;
            var scaleMin = Math.min(scaleX, scaleY);
            var scaleMax = Math.max(scaleX, scaleY);
            if (meetOrSlice == 'meet') { desiredWidth *= scaleMin; desiredHeight *= scaleMin; }
            if (meetOrSlice == 'slice') { desiredWidth *= scaleMax; desiredHeight *= scaleMax; }
            refX = new svg.Property('refX', refX);
            refY = new svg.Property('refY', refY);
            if (refX.hasValue() && refY.hasValue()) {
                ctx.translate(-scaleMin * refX.Length.toPixels('x'), -scaleMin * refY.Length.toPixels('y'));
            }
            else {
                // align
                if (align.match(/^xMid/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(width / 2.0 - desiredWidth / 2.0, 0);
                if (align.match(/YMid$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, height / 2.0 - desiredHeight / 2.0);
                if (align.match(/^xMax/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(width - desiredWidth, 0);
                if (align.match(/YMax$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, height - desiredHeight);
            }
            // scale
            if (align == 'none') ctx.scale(scaleX, scaleY);
            else if (meetOrSlice == 'meet') ctx.scale(scaleMin, scaleMin);
            else if (meetOrSlice == 'slice') ctx.scale(scaleMax, scaleMax);
            // translate
            ctx.translate(minX == null ? 0 : -minX, minY == null ? 0 : -minY);
        }
        // elements
        svg.Element = {}
        svg.Element.ElementBase = function(node) {
            this.attributes = {};
            this.styles = {};
            this.children = [];
            // get or create attribute
            this.attribute = function(name, createIfNotExists) {
                var a = this.attributes[name];
                if (a != null) return a;
                a = new svg.Property(name, '');
                if (createIfNotExists == true) this.attributes[name] = a;
                return a;
            }
            // get or create style, crawls up node tree
            this.style = function(name, createIfNotExists) {
                var s = this.styles[name];
                if (s != null) return s;
                var a = this.attribute(name);
                if (a != null && a.hasValue()) {
                    return a;
                }
                var p = this.parent;
                if (p != null) {
                    var ps = p.style(name);
                    if (ps != null && ps.hasValue()) {
                        return ps;
                    }
                }
                s = new svg.Property(name, '');
                if (createIfNotExists == true) this.styles[name] = s;
                return s;
            }
            // base render
            this.render = function(ctx) {
                // don't render display=none
                if (this.style('display').value == 'none') return;
                // don't render visibility=hidden
                if (this.attribute('visibility').value == 'hidden') return;
                ctx.save();
                    this.setContext(ctx);
                        // mask
                        if (this.attribute('mask').hasValue()) {
                            var mask = this.attribute('mask').Definition.getDefinition();
                            if (mask != null) mask.apply(ctx, this);
                        }
                        else if (this.style('filter').hasValue()) {
                            var filter = this.style('filter').Definition.getDefinition();
                            if (filter != null) filter.apply(ctx, this);
                        }
                        else this.renderChildren(ctx);
                    this.clearContext(ctx);
                ctx.restore();
            }
            // base set context
            this.setContext = function(ctx) {
                // OVERRIDE ME!
            }
            // base clear context
            this.clearContext = function(ctx) {
                // OVERRIDE ME!
            }
            // base render children
            this.renderChildren = function(ctx) {
                for (var i=0; i<this.children.length; i++) {
                    this.children[i].render(ctx);
                }
            }
            this.addChild = function(childNode, create) {
                var child = childNode;
                if (create) child = svg.CreateElement(childNode);
                child.parent = this;
                this.children.push(child);
            }
            if (node != null && node.nodeType == 1) { //ELEMENT_NODE
                // add children
                for (var i=0; i<node.childNodes.length; i++) {
                    var childNode = node.childNodes[i];
                    if (childNode.nodeType == 1) this.addChild(childNode, true); //ELEMENT_NODE
                }
                // add attributes
                for (var i=0; i<node.attributes.length; i++) {
                    var attribute = node.attributes[i];
                    this.attributes[attribute.nodeName] = new svg.Property(attribute.nodeName, attribute.nodeValue);
                }
                // add tag styles
                var styles = svg.Styles[node.nodeName];
                if (styles != null) {
                    for (var name in styles) {
                        this.styles[name] = styles[name];
                    }
                }
                // add class styles
                if (this.attribute('class').hasValue()) {
                    var classes = svg.compressSpaces(this.attribute('class').value).split(' ');
                    for (var j=0; j<classes.length; j++) {
                        styles = svg.Styles['.'+classes[j]];
                        if (styles != null) {
                            for (var name in styles) {
                                this.styles[name] = styles[name];
                            }
                        }
                        styles = svg.Styles[node.nodeName+'.'+classes[j]];
                        if (styles != null) {
                            for (var name in styles) {
                                this.styles[name] = styles[name];
                            }
                        }
                    }
                }
                // add inline styles
                if (this.attribute('style').hasValue()) {
                    var styles = this.attribute('style').value.split(';');
                    for (var i=0; i<styles.length; i++) {
                        if (svg.trim(styles[i]) != '') {
                            var style = styles[i].split(':');
                            var name = svg.trim(style[0]);
                            var value = svg.trim(style[1]);
                            this.styles[name] = new svg.Property(name, value);
                        }
                    }
                }
                // add id
                if (this.attribute('id').hasValue()) {
                    if (svg.Definitions[this.attribute('id').value] == null) {
                        svg.Definitions[this.attribute('id').value] = this;
                    }
                }
            }
        }
        svg.Element.RenderedElementBase = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.setContext = function(ctx) {
                // fill
                if (this.style('fill').Definition.isUrl()) {
                    var fs = this.style('fill').Definition.getFillStyle(this);
                    if (fs != null) ctx.fillStyle = fs;
                }
                else if (this.style('fill').hasValue()) {
                    var fillStyle = this.style('fill');
                    if (this.style('fill-opacity').hasValue()) fillStyle = fillStyle.Color.addOpacity(this.style('fill-opacity').value);
                    ctx.fillStyle = (fillStyle.value == 'none' ? 'rgba(0,0,0,0)' : fillStyle.value);
                }
                // stroke
                if (this.style('stroke').Definition.isUrl()) {
                    var fs = this.style('stroke').Definition.getFillStyle(this);
                    if (fs != null) ctx.strokeStyle = fs;
                }
                else if (this.style('stroke').hasValue()) {
                    var strokeStyle = this.style('stroke');
                    if (this.style('stroke-opacity').hasValue()) strokeStyle = strokeStyle.Color.addOpacity(this.style('stroke-opacity').value);
                    ctx.strokeStyle = (strokeStyle.value == 'none' ? 'rgba(0,0,0,0)' : strokeStyle.value);
                }
                if (this.style('stroke-width').hasValue()) ctx.lineWidth = this.style('stroke-width').Length.toPixels();
                if (this.style('stroke-linecap').hasValue()) ctx.lineCap = this.style('stroke-linecap').value;
                if (this.style('stroke-linejoin').hasValue()) ctx.lineJoin = this.style('stroke-linejoin').value;
                if (this.style('stroke-miterlimit').hasValue()) ctx.miterLimit = this.style('stroke-miterlimit').value;
                // font
                if (typeof(ctx.font) != 'undefined') {
                    ctx.font = svg.Font.CreateFont(
                        this.style('font-style').value,
                        this.style('font-variant').value,
                        this.style('font-weight').value,
                        this.style('font-size').hasValue() ? this.style('font-size').Length.toPixels() + 'px' : '',
                        this.style('font-family').value).toString();
                }
                // transform
                if (this.attribute('transform').hasValue()) {
                    var transform = new svg.Transform(this.attribute('transform').value);
                    transform.apply(ctx);
                }
                // clip
                if (this.attribute('clip-path').hasValue()) {
                    var clip = this.attribute('clip-path').Definition.getDefinition();
                    if (clip != null) clip.apply(ctx);
                }
                // opacity
                if (this.style('opacity').hasValue()) {
                    ctx.globalAlpha = this.style('opacity').numValue();
                }
            }
        }
        svg.Element.RenderedElementBase.prototype = new svg.Element.ElementBase;
        svg.Element.PathElementBase = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            this.path = function(ctx) {
                if (ctx != null) ctx.beginPath();
                return new svg.BoundingBox();
            }
            this.renderChildren = function(ctx) {
                this.path(ctx);
                svg.Mouse.checkPath(this, ctx);
                if (ctx.fillStyle != '') ctx.fill();
                if (ctx.strokeStyle != '') ctx.stroke();
                var markers = this.getMarkers();
                if (markers != null) {
                    if (this.style('marker-start').Definition.isUrl()) {
                        var marker = this.style('marker-start').Definition.getDefinition();
                        marker.render(ctx, markers[0][0], markers[0][1]);
                    }
                    if (this.style('marker-mid').Definition.isUrl()) {
                        var marker = this.style('marker-mid').Definition.getDefinition();
                        for (var i=1;i<markers.length-1;i++) {
                            marker.render(ctx, markers[i][0], markers[i][1]);
                        }
                    }
                    if (this.style('marker-end').Definition.isUrl()) {
                        var marker = this.style('marker-end').Definition.getDefinition();
                        marker.render(ctx, markers[markers.length-1][0], markers[markers.length-1][1]);
                    }
                }
            }
            this.getBoundingBox = function() {
                return this.path();
            }
            this.getMarkers = function() {
                return null;
            }
        }
        svg.Element.PathElementBase.prototype = new svg.Element.RenderedElementBase;
        // svg element
        svg.Element.svg = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            this.baseClearContext = this.clearContext;
            this.clearContext = function(ctx) {
                this.baseClearContext(ctx);
                svg.ViewPort.RemoveCurrent();
            }
            this.baseSetContext = this.setContext;
            this.setContext = function(ctx) {
                // initial values
                ctx.strokeStyle = 'rgba(0,0,0,0)';
                ctx.lineCap = 'butt';
                ctx.lineJoin = 'miter';
                ctx.miterLimit = 4;
                this.baseSetContext(ctx);
                // create new view port
                if (this.attribute('x').hasValue() && this.attribute('y').hasValue()) {
                    ctx.translate(this.attribute('x').Length.toPixels('x'), this.attribute('y').Length.toPixels('y'));
                }
                var width = svg.ViewPort.width();
                var height = svg.ViewPort.height();
                if (typeof(this.root) == 'undefined' && this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
                    width = this.attribute('width').Length.toPixels('x');
                    height = this.attribute('height').Length.toPixels('y');
                    var x = 0;
                    var y = 0;
                    if (this.attribute('refX').hasValue() && this.attribute('refY').hasValue()) {
                        x = -this.attribute('refX').Length.toPixels('x');
                        y = -this.attribute('refY').Length.toPixels('y');
                    }
                    ctx.beginPath();
                    ctx.moveTo(x, y);
                    ctx.lineTo(width, y);
                    ctx.lineTo(width, height);
                    ctx.lineTo(x, height);
                    ctx.closePath();
                    ctx.clip();
                }
                svg.ViewPort.SetCurrent(width, height);
                // viewbox
                if (this.attribute('viewBox').hasValue()) {
                    var viewBox = svg.ToNumberArray(this.attribute('viewBox').value);
                    var minX = viewBox[0];
                    var minY = viewBox[1];
                    width = viewBox[2];
                    height = viewBox[3];
                    svg.AspectRatio(ctx,
                                    this.attribute('preserveAspectRatio').value,
                                    svg.ViewPort.width(),
                                    width,
                                    svg.ViewPort.height(),
                                    height,
                                    minX,
                                    minY,
                                    this.attribute('refX').value,
                                    this.attribute('refY').value);
                    svg.ViewPort.RemoveCurrent();
                    svg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);
                }
            }
        }
        svg.Element.svg.prototype = new svg.Element.RenderedElementBase;
        // rect element
        svg.Element.rect = function(node) {
            this.base = svg.Element.PathElementBase;
            this.base(node);
            this.path = function(ctx) {
                var x = this.attribute('x').Length.toPixels('x');
                var y = this.attribute('y').Length.toPixels('y');
                var width = this.attribute('width').Length.toPixels('x');
                var height = this.attribute('height').Length.toPixels('y');
                var rx = this.attribute('rx').Length.toPixels('x');
                var ry = this.attribute('ry').Length.toPixels('y');
                if (this.attribute('rx').hasValue() && !this.attribute('ry').hasValue()) ry = rx;
                if (this.attribute('ry').hasValue() && !this.attribute('rx').hasValue()) rx = ry;
                if (ctx != null) {
                    ctx.beginPath();
                    ctx.moveTo(x + rx, y);
                    ctx.lineTo(x + width - rx, y);
                    ctx.quadraticCurveTo(x + width, y, x + width, y + ry)
                    ctx.lineTo(x + width, y + height - ry);
                    ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height)
                    ctx.lineTo(x + rx, y + height);
                    ctx.quadraticCurveTo(x, y + height, x, y + height - ry)
                    ctx.lineTo(x, y + ry);
                    ctx.quadraticCurveTo(x, y, x + rx, y)
                    ctx.closePath();
                }
                return new svg.BoundingBox(x, y, x + width, y + height);
            }
        }
        svg.Element.rect.prototype = new svg.Element.PathElementBase;
        // circle element
        svg.Element.circle = function(node) {
            this.base = svg.Element.PathElementBase;
            this.base(node);
            this.path = function(ctx) {
                var cx = this.attribute('cx').Length.toPixels('x');
                var cy = this.attribute('cy').Length.toPixels('y');
                var r = this.attribute('r').Length.toPixels();
                if (ctx != null) {
                    ctx.beginPath();
                    ctx.arc(cx, cy, r, 0, Math.PI * 2, true);
                    ctx.closePath();
                }
                return new svg.BoundingBox(cx - r, cy - r, cx + r, cy + r);
            }
        }
        svg.Element.circle.prototype = new svg.Element.PathElementBase;
        // ellipse element
        svg.Element.ellipse = function(node) {
            this.base = svg.Element.PathElementBase;
            this.base(node);
            this.path = function(ctx) {
                var KAPPA = 4 * ((Math.sqrt(2) - 1) / 3);
                var rx = this.attribute('rx').Length.toPixels('x');
                var ry = this.attribute('ry').Length.toPixels('y');
                var cx = this.attribute('cx').Length.toPixels('x');
                var cy = this.attribute('cy').Length.toPixels('y');
                if (ctx != null) {
                    ctx.beginPath();
                    ctx.moveTo(cx, cy - ry);
                    ctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,  cx + rx, cy - (KAPPA * ry), cx + rx, cy);
                    ctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry), cx + (KAPPA * rx), cy + ry, cx, cy + ry);
                    ctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry, cx - rx, cy + (KAPPA * ry), cx - rx, cy);
                    ctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry), cx - (KAPPA * rx), cy - ry, cx, cy - ry);
                    ctx.closePath();
                }
                return new svg.BoundingBox(cx - rx, cy - ry, cx + rx, cy + ry);
            }
        }
        svg.Element.ellipse.prototype = new svg.Element.PathElementBase;
        // line element
        svg.Element.line = function(node) {
            this.base = svg.Element.PathElementBase;
            this.base(node);
            this.getPoints = function() {
                return [
                    new svg.Point(this.attribute('x1').Length.toPixels('x'), this.attribute('y1').Length.toPixels('y')),
                    new svg.Point(this.attribute('x2').Length.toPixels('x'), this.attribute('y2').Length.toPixels('y'))];
            }
            this.path = function(ctx) {
                var points = this.getPoints();
                if (ctx != null) {
                    ctx.beginPath();
                    ctx.moveTo(points[0].x, points[0].y);
                    ctx.lineTo(points[1].x, points[1].y);
                }
                return new svg.BoundingBox(points[0].x, points[0].y, points[1].x, points[1].y);
            }
            this.getMarkers = function() {
                var points = this.getPoints();
                var a = points[0].angleTo(points[1]);
                return [[points[0], a], [points[1], a]];
            }
        }
        svg.Element.line.prototype = new svg.Element.PathElementBase;
        // polyline element
        svg.Element.polyline = function(node) {
            this.base = svg.Element.PathElementBase;
            this.base(node);
            this.points = svg.CreatePath(this.attribute('points').value);
            this.path = function(ctx) {
                var bb = new svg.BoundingBox(this.points[0].x, this.points[0].y);
                if (ctx != null) {
                    ctx.beginPath();
                    ctx.moveTo(this.points[0].x, this.points[0].y);
                }
                for (var i=1; i<this.points.length; i++) {
                    bb.addPoint(this.points[i].x, this.points[i].y);
                    if (ctx != null) ctx.lineTo(this.points[i].x, this.points[i].y);
                }
                return bb;
            }
            this.getMarkers = function() {
                var markers = [];
                for (var i=0; i<this.points.length - 1; i++) {
                    markers.push([this.points[i], this.points[i].angleTo(this.points[i+1])]);
                }
                markers.push([this.points[this.points.length-1], markers[markers.length-1][1]]);
                return markers;
            }
        }
        svg.Element.polyline.prototype = new svg.Element.PathElementBase;
        // polygon element
        svg.Element.polygon = function(node) {
            this.base = svg.Element.polyline;
            this.base(node);
            this.basePath = this.path;
            this.path = function(ctx) {
                var bb = this.basePath(ctx);
                if (ctx != null) {
                    ctx.lineTo(this.points[0].x, this.points[0].y);
                    ctx.closePath();
                }
                return bb;
            }
        }
        svg.Element.polygon.prototype = new svg.Element.polyline;
        // path element
        svg.Element.path = function(node) {
            this.base = svg.Element.PathElementBase;
            this.base(node);
            var d = this.attribute('d').value;
            // TODO: convert to real lexer based on http://www.w3.org/TR/SVG11/paths.html#PathDataBNF
            d = d.replace(/,/gm,' '); // get rid of all commas
            d = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,'$1 $2'); // separate commands from commands
            d = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,'$1 $2'); // separate commands from commands
            d = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([^\s])/gm,'$1 $2'); // separate commands from points
            d = d.replace(/([^\s])([MmZzLlHhVvCcSsQqTtAa])/gm,'$1 $2'); // separate commands from points
            d = d.replace(/([0-9])([+\-])/gm,'$1 $2'); // separate digits when no comma
            d = d.replace(/(\.[0-9]*)(\.)/gm,'$1 $2'); // separate digits when no comma
            d = d.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,'$1 $3 $4 '); // shorthand elliptical arc path syntax
            d = svg.compressSpaces(d); // compress multiple spaces
            d = svg.trim(d);
            this.PathParser = new (function(d) {
                this.tokens = d.split(' ');
                this.reset = function() {
                    this.i = -1;
                    this.command = '';
                    this.previousCommand = '';
                    this.start = new svg.Point(0, 0);
                    this.control = new svg.Point(0, 0);
                    this.current = new svg.Point(0, 0);
                    this.points = [];
                    this.angles = [];
                }
                this.isEnd = function() {
                    return this.i >= this.tokens.length - 1;
                }
                this.isCommandOrEnd = function() {
                    if (this.isEnd()) return true;
                    return this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null;
                }
                this.isRelativeCommand = function() {
                    return this.command == this.command.toLowerCase();
                }
                this.getToken = function() {
                    this.i = this.i + 1;
                    return this.tokens[this.i];
                }
                this.getScalar = function() {
                    return parseFloat(this.getToken());
                }
                this.nextCommand = function() {
                    this.previousCommand = this.command;
                    this.command = this.getToken();
                }
                this.getPoint = function() {
                    var p = new svg.Point(this.getScalar(), this.getScalar());
                    return this.makeAbsolute(p);
                }
                this.getAsControlPoint = function() {
                    var p = this.getPoint();
                    this.control = p;
                    return p;
                }
                this.getAsCurrentPoint = function() {
                    var p = this.getPoint();
                    this.current = p;
                    return p;
                }
                this.getReflectedControlPoint = function() {
                    if (this.previousCommand.toLowerCase() != 'c' && this.previousCommand.toLowerCase() != 's') {
                        return this.current;
                    }
                    // reflect point
                    var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y);
                    return p;
                }
                this.makeAbsolute = function(p) {
                    if (this.isRelativeCommand()) {
                        p.x = this.current.x + p.x;
                        p.y = this.current.y + p.y;
                    }
                    return p;
                }
                this.addMarker = function(p, from, priorTo) {
                    // if the last angle isn't filled in because we didn't have this point yet ...
                    if (priorTo != null && this.angles.length > 0 && this.angles[this.angles.length-1] == null) {
                        this.angles[this.angles.length-1] = this.points[this.points.length-1].angleTo(priorTo);
                    }
                    this.addMarkerAngle(p, from == null ? null : from.angleTo(p));
                }
                this.addMarkerAngle = function(p, a) {
                    this.points.push(p);
                    this.angles.push(a);
                }
                this.getMarkerPoints = function() { return this.points; }
                this.getMarkerAngles = function() {
                    for (var i=0; i<this.angles.length; i++) {
                        if (this.angles[i] == null) {
                            for (var j=i+1; j<this.angles.length; j++) {
                                if (this.angles[j] != null) {
                                    this.angles[i] = this.angles[j];
                                    break;
                                }
                            }
                        }
                    }
                    return this.angles;
                }
            })(d);
            this.path = function(ctx) {
                var pp = this.PathParser;
                pp.reset();
                var bb = new svg.BoundingBox();
                if (ctx != null) ctx.beginPath();
                while (!pp.isEnd()) {
                    pp.nextCommand();
                    switch (pp.command.toUpperCase()) {
                    case 'M':
                        var p = pp.getAsCurrentPoint();
                        pp.addMarker(p);
                        bb.addPoint(p.x, p.y);
                        if (ctx != null) ctx.moveTo(p.x, p.y);
                        pp.start = pp.current;
                        while (!pp.isCommandOrEnd()) {
                            var p = pp.getAsCurrentPoint();
                            pp.addMarker(p, pp.start);
                            bb.addPoint(p.x, p.y);
                            if (ctx != null) ctx.lineTo(p.x, p.y);
                        }
                        break;
                    case 'L':
                        while (!pp.isCommandOrEnd()) {
                            var c = pp.current;
                            var p = pp.getAsCurrentPoint();
                            pp.addMarker(p, c);
                            bb.addPoint(p.x, p.y);
                            if (ctx != null) ctx.lineTo(p.x, p.y);
                        }
                        break;
                    case 'H':
                        while (!pp.isCommandOrEnd()) {
                            var newP = new svg.Point((pp.isRelativeCommand() ? pp.current.x : 0) + pp.getScalar(), pp.current.y);
                            pp.addMarker(newP, pp.current);
                            pp.current = newP;
                            bb.addPoint(pp.current.x, pp.current.y);
                            if (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);
                        }
                        break;
                    case 'V':
                        while (!pp.isCommandOrEnd()) {
                            var newP = new svg.Point(pp.current.x, (pp.isRelativeCommand() ? pp.current.y : 0) + pp.getScalar());
                            pp.addMarker(newP, pp.current);
                            pp.current = newP;
                            bb.addPoint(pp.current.x, pp.current.y);
                            if (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);
                        }
                        break;
                    case 'C':
                        while (!pp.isCommandOrEnd()) {
                            var curr = pp.current;
                            var p1 = pp.getPoint();
                            var cntrl = pp.getAsControlPoint();
                            var cp = pp.getAsCurrentPoint();
                            pp.addMarker(cp, cntrl, p1);
                            bb.addBezierCurve(curr.x, curr.y, p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);
                            if (ctx != null) ctx.bezierCurveTo(p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);
                        }
                        break;
                    case 'S':
                        while (!pp.isCommandOrEnd()) {
                            var curr = pp.current;
                            var p1 = pp.getReflectedControlPoint();
                            var cntrl = pp.getAsControlPoint();
                            var cp = pp.getAsCurrentPoint();
                            pp.addMarker(cp, cntrl, p1);
                            bb.addBezierCurve(curr.x, curr.y, p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);
                            if (ctx != null) ctx.bezierCurveTo(p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);
                        }
                        break;
                    case 'Q':
                        while (!pp.isCommandOrEnd()) {
                            var curr = pp.current;
                            var cntrl = pp.getAsControlPoint();
                            var cp = pp.getAsCurrentPoint();
                            pp.addMarker(cp, cntrl, cntrl);
                            bb.addQuadraticCurve(curr.x, curr.y, cntrl.x, cntrl.y, cp.x, cp.y);
                            if (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);
                        }
                        break;
                    case 'T':
                        while (!pp.isCommandOrEnd()) {
                            var curr = pp.current;
                            var cntrl = pp.getReflectedControlPoint();
                            pp.control = cntrl;
                            var cp = pp.getAsCurrentPoint();
                            pp.addMarker(cp, cntrl, cntrl);
                            bb.addQuadraticCurve(curr.x, curr.y, cntrl.x, cntrl.y, cp.x, cp.y);
                            if (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);
                        }
                        break;
                    case 'A':
                        while (!pp.isCommandOrEnd()) {
                            var curr = pp.current;
                            var rx = pp.getScalar();
                            var ry = pp.getScalar();
                            var xAxisRotation = pp.getScalar() * (Math.PI / 180.0);
                            var largeArcFlag = pp.getScalar();
                            var sweepFlag = pp.getScalar();
                            var cp = pp.getAsCurrentPoint();
                            // Conversion from endpoint to center parameterization
                            // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
                            // x1', y1'
                            var currp = new svg.Point(
                                Math.cos(xAxisRotation) * (curr.x - cp.x) / 2.0 + Math.sin(xAxisRotation) * (curr.y - cp.y) / 2.0,
                                -Math.sin(xAxisRotation) * (curr.x - cp.x) / 2.0 + Math.cos(xAxisRotation) * (curr.y - cp.y) / 2.0
                            );
                            // adjust radii
                            var l = Math.pow(currp.x,2)/Math.pow(rx,2)+Math.pow(currp.y,2)/Math.pow(ry,2);
                            if (l > 1) {
                                rx *= Math.sqrt(l);
                                ry *= Math.sqrt(l);
                            }
                            // cx', cy'
                            var s = (largeArcFlag == sweepFlag ? -1 : 1) * Math.sqrt(
                                ((Math.pow(rx,2)*Math.pow(ry,2))-(Math.pow(rx,2)*Math.pow(currp.y,2))-(Math.pow(ry,2)*Math.pow(currp.x,2))) /
                                (Math.pow(rx,2)*Math.pow(currp.y,2)+Math.pow(ry,2)*Math.pow(currp.x,2))
                            );
                            if (isNaN(s)) s = 0;
                            var cpp = new svg.Point(s * rx * currp.y / ry, s * -ry * currp.x / rx);
                            // cx, cy
                            var centp = new svg.Point(
                                (curr.x + cp.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y,
                                (curr.y + cp.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y
                            );
                            // vector magnitude
                            var m = function(v) { return Math.sqrt(Math.pow(v[0],2) + Math.pow(v[1],2)); }
                            // ratio between two vectors
                            var r = function(u, v) { return (u[0]*v[0]+u[1]*v[1]) / (m(u)*m(v)) }
                            // angle between two vectors
                            var a = function(u, v) { return (u[0]*v[1] < u[1]*v[0] ? -1 : 1) * Math.acos(r(u,v)); }
                            // initial angle
                            var a1 = a([1,0], [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]);
                            // angle delta
                            var u = [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry];
                            var v = [(-currp.x-cpp.x)/rx,(-currp.y-cpp.y)/ry];
                            var ad = a(u, v);
                            if (r(u,v) <= -1) ad = Math.PI;
                            if (r(u,v) >= 1) ad = 0;
                            if (sweepFlag == 0 && ad > 0) ad = ad - 2 * Math.PI;
                            if (sweepFlag == 1 && ad < 0) ad = ad + 2 * Math.PI;
                            // for markers
                            var halfWay = new svg.Point(
                                centp.x - rx * Math.cos((a1 + ad) / 2),
                                centp.y - ry * Math.sin((a1 + ad) / 2)
                            );
                            pp.addMarkerAngle(halfWay, (a1 + ad) / 2 + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2);
                            pp.addMarkerAngle(cp, ad + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2);
                            bb.addPoint(cp.x, cp.y); // TODO: this is too naive, make it better
                            if (ctx != null) {
                                var r = rx > ry ? rx : ry;
                                var sx = rx > ry ? 1 : rx / ry;
                                var sy = rx > ry ? ry / rx : 1;
                                ctx.translate(centp.x, centp.y);
                                ctx.rotate(xAxisRotation);
                                ctx.scale(sx, sy);
                                ctx.arc(0, 0, r, a1, a1 + ad, 1 - sweepFlag);
                                ctx.scale(1/sx, 1/sy);
                                ctx.rotate(-xAxisRotation);
                                ctx.translate(-centp.x, -centp.y);
                            }
                        }
                        break;
                    case 'Z':
                        if (ctx != null) ctx.closePath();
                        pp.current = pp.start;
                    }
                }
                return bb;
            }
            this.getMarkers = function() {
                var points = this.PathParser.getMarkerPoints();
                var angles = this.PathParser.getMarkerAngles();
                var markers = [];
                for (var i=0; i<points.length; i++) {
                    markers.push([points[i], angles[i]]);
                }
                return markers;
            }
        }
        svg.Element.path.prototype = new svg.Element.PathElementBase;
        // pattern element
        svg.Element.pattern = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.createPattern = function(ctx, element) {
                // render me using a temporary svg element
                var tempSvg = new svg.Element.svg();
                tempSvg.attributes['viewBox'] = new svg.Property('viewBox', this.attribute('viewBox').value);
                tempSvg.attributes['x'] = new svg.Property('x', this.attribute('x').value);
                tempSvg.attributes['y'] = new svg.Property('y', this.attribute('y').value);
                tempSvg.attributes['width'] = new svg.Property('width', this.attribute('width').value);
                tempSvg.attributes['height'] = new svg.Property('height', this.attribute('height').value);
                tempSvg.children = this.children;
                var c = document.createElement('canvas');
                c.width = this.attribute('width').Length.toPixels('x');
                c.height = this.attribute('height').Length.toPixels('y');
                tempSvg.render(c.getContext('2d'));
                return ctx.createPattern(c, 'repeat');
            }
        }
        svg.Element.pattern.prototype = new svg.Element.ElementBase;
        // marker element
        svg.Element.marker = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.baseRender = this.render;
            this.render = function(ctx, point, angle) {
                ctx.translate(point.x, point.y);
                if (this.attribute('orient').valueOrDefault('auto') == 'auto') ctx.rotate(angle);
                if (this.attribute('markerUnits').valueOrDefault('strokeWidth') == 'strokeWidth') ctx.scale(ctx.lineWidth, ctx.lineWidth);
                ctx.save();
                // render me using a temporary svg element
                var tempSvg = new svg.Element.svg();
                tempSvg.attributes['viewBox'] = new svg.Property('viewBox', this.attribute('viewBox').value);
                tempSvg.attributes['refX'] = new svg.Property('refX', this.attribute('refX').value);
                tempSvg.attributes['refY'] = new svg.Property('refY', this.attribute('refY').value);
                tempSvg.attributes['width'] = new svg.Property('width', this.attribute('markerWidth').value);
                tempSvg.attributes['height'] = new svg.Property('height', this.attribute('markerHeight').value);
                tempSvg.attributes['fill'] = new svg.Property('fill', this.attribute('fill').valueOrDefault('black'));
                tempSvg.attributes['stroke'] = new svg.Property('stroke', this.attribute('stroke').valueOrDefault('none'));
                tempSvg.children = this.children;
                tempSvg.render(ctx);
                ctx.restore();
                if (this.attribute('markerUnits').valueOrDefault('strokeWidth') == 'strokeWidth') ctx.scale(1/ctx.lineWidth, 1/ctx.lineWidth);
                if (this.attribute('orient').valueOrDefault('auto') == 'auto') ctx.rotate(-angle);
                ctx.translate(-point.x, -point.y);
            }
        }
        svg.Element.marker.prototype = new svg.Element.ElementBase;
        // definitions element
        svg.Element.defs = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.render = function(ctx) {
                // NOOP
            }
        }
        svg.Element.defs.prototype = new svg.Element.ElementBase;
        // base for gradients
        svg.Element.GradientBase = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.gradientUnits = this.attribute('gradientUnits').valueOrDefault('objectBoundingBox');
            this.stops = [];
            for (var i=0; i<this.children.length; i++) {
                var child = this.children[i];
                this.stops.push(child);
            }
            this.getGradient = function() {
                // OVERRIDE ME!
            }
            this.createGradient = function(ctx, element) {
                var stopsContainer = this;
                if (this.attribute('xlink:href').hasValue()) {
                    stopsContainer = this.attribute('xlink:href').Definition.getDefinition();
                }
                var g = this.getGradient(ctx, element);
                for (var i=0; i<stopsContainer.stops.length; i++) {
                    g.addColorStop(stopsContainer.stops[i].offset, stopsContainer.stops[i].color);
                }
                if (this.attribute('gradientTransform').hasValue()) {
                    // render as transformed pattern on temporary canvas
                    var rootView = svg.ViewPort.viewPorts[0];
                    var rect = new svg.Element.rect();
                    rect.attributes['x'] = new svg.Property('x', -svg.MAX_VIRTUAL_PIXELS/3.0);
                    rect.attributes['y'] = new svg.Property('y', -svg.MAX_VIRTUAL_PIXELS/3.0);
                    rect.attributes['width'] = new svg.Property('width', svg.MAX_VIRTUAL_PIXELS);
                    rect.attributes['height'] = new svg.Property('height', svg.MAX_VIRTUAL_PIXELS);
                    var group = new svg.Element.g();
                    group.attributes['transform'] = new svg.Property('transform', this.attribute('gradientTransform').value);
                    group.children = [ rect ];
                    var tempSvg = new svg.Element.svg();
                    tempSvg.attributes['x'] = new svg.Property('x', 0);
                    tempSvg.attributes['y'] = new svg.Property('y', 0);
                    tempSvg.attributes['width'] = new svg.Property('width', rootView.width);
                    tempSvg.attributes['height'] = new svg.Property('height', rootView.height);
                    tempSvg.children = [ group ];
                    var c = document.createElement('canvas');
                    c.width = rootView.width;
                    c.height = rootView.height;
                    var tempCtx = c.getContext('2d');
                    tempCtx.fillStyle = g;
                    tempSvg.render(tempCtx);
                    return tempCtx.createPattern(c, 'no-repeat');
                }
                return g;
            }
        }
        svg.Element.GradientBase.prototype = new svg.Element.ElementBase;
        // linear gradient element
        svg.Element.linearGradient = function(node) {
            this.base = svg.Element.GradientBase;
            this.base(node);
            this.getGradient = function(ctx, element) {
                var bb = element.getBoundingBox();
                var x1 = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.x() + bb.width() * this.attribute('x1').numValue()
                    : this.attribute('x1').Length.toPixels('x'));
                var y1 = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.y() + bb.height() * this.attribute('y1').numValue()
                    : this.attribute('y1').Length.toPixels('y'));
                var x2 = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.x() + bb.width() * this.attribute('x2').numValue()
                    : this.attribute('x2').Length.toPixels('x'));
                var y2 = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.y() + bb.height() * this.attribute('y2').numValue()
                    : this.attribute('y2').Length.toPixels('y'));
                return ctx.createLinearGradient(x1, y1, x2, y2);
            }
        }
        svg.Element.linearGradient.prototype = new svg.Element.GradientBase;
        // radial gradient element
        svg.Element.radialGradient = function(node) {
            this.base = svg.Element.GradientBase;
            this.base(node);
            this.getGradient = function(ctx, element) {
                var bb = element.getBoundingBox();
                var cx = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.x() + bb.width() * this.attribute('cx').numValue()
                    : this.attribute('cx').Length.toPixels('x'));
                var cy = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.y() + bb.height() * this.attribute('cy').numValue()
                    : this.attribute('cy').Length.toPixels('y'));
                var fx = cx;
                var fy = cy;
                if (this.attribute('fx').hasValue()) {
                    fx = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.x() + bb.width() * this.attribute('fx').numValue()
                    : this.attribute('fx').Length.toPixels('x'));
                }
                if (this.attribute('fy').hasValue()) {
                    fy = (this.gradientUnits == 'objectBoundingBox'
                    ? bb.y() + bb.height() * this.attribute('fy').numValue()
                    : this.attribute('fy').Length.toPixels('y'));
                }
                var r = (this.gradientUnits == 'objectBoundingBox'
                    ? (bb.width() + bb.height()) / 2.0 * this.attribute('r').numValue()
                    : this.attribute('r').Length.toPixels());
                return ctx.createRadialGradient(fx, fy, 0, cx, cy, r);
            }
        }
        svg.Element.radialGradient.prototype = new svg.Element.GradientBase;
        // gradient stop element
        svg.Element.stop = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.offset = this.attribute('offset').numValue();
            var stopColor = this.style('stop-color');
            if (this.style('stop-opacity').hasValue()) stopColor = stopColor.Color.addOpacity(this.style('stop-opacity').value);
            this.color = stopColor.value;
        }
        svg.Element.stop.prototype = new svg.Element.ElementBase;
        // animation base element
        svg.Element.AnimateBase = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            svg.Animations.push(this);
            this.duration = 0.0;
            this.begin = this.attribute('begin').Time.toMilliseconds();
            this.maxDuration = this.begin + this.attribute('dur').Time.toMilliseconds();
            this.getProperty = function() {
                var attributeType = this.attribute('attributeType').value;
                var attributeName = this.attribute('attributeName').value;
                if (attributeType == 'CSS') {
                    return this.parent.style(attributeName, true);
                }
                return this.parent.attribute(attributeName, true);
            };
            this.initialValue = null;
            this.removed = false;
            this.calcValue = function() {
                // OVERRIDE ME!
                return '';
            }
            this.update = function(delta) {
                // set initial value
                if (this.initialValue == null) {
                    this.initialValue = this.getProperty().value;
                }
                // if we're past the end time
                if (this.duration > this.maxDuration) {
                    // loop for indefinitely repeating animations
                    if (this.attribute('repeatCount').value == 'indefinite') {
                        this.duration = 0.0
                    }
                    else if (this.attribute('fill').valueOrDefault('remove') == 'remove' && !this.removed) {
                        this.removed = true;
                        this.getProperty().value = this.initialValue;
                        return true;
                    }
                    else {
                        return false; // no updates made
                    }
                }
                this.duration = this.duration + delta;
                // if we're past the begin time
                var updated = false;
                if (this.begin < this.duration) {
                    var newValue = this.calcValue(); // tween
                    if (this.attribute('type').hasValue()) {
                        // for transform, etc.
                        var type = this.attribute('type').value;
                        newValue = type + '(' + newValue + ')';
                    }
                    this.getProperty().value = newValue;
                    updated = true;
                }
                return updated;
            }
            // fraction of duration we've covered
            this.progress = function() {
                return ((this.duration - this.begin) / (this.maxDuration - this.begin));
            }
        }
        svg.Element.AnimateBase.prototype = new svg.Element.ElementBase;
        // animate element
        svg.Element.animate = function(node) {
            this.base = svg.Element.AnimateBase;
            this.base(node);
            this.calcValue = function() {
                var from = this.attribute('from').numValue();
                var to = this.attribute('to').numValue();
                // tween value linearly
                return from + (to - from) * this.progress();
            };
        }
        svg.Element.animate.prototype = new svg.Element.AnimateBase;
        // animate color element
        svg.Element.animateColor = function(node) {
            this.base = svg.Element.AnimateBase;
            this.base(node);
            this.calcValue = function() {
                var from = new RGBColor(this.attribute('from').value);
                var to = new RGBColor(this.attribute('to').value);
                if (from.ok && to.ok) {
                    // tween color linearly
                    var r = from.r + (to.r - from.r) * this.progress();
                    var g = from.g + (to.g - from.g) * this.progress();
                    var b = from.b + (to.b - from.b) * this.progress();
                    return 'rgb('+parseInt(r,10)+','+parseInt(g,10)+','+parseInt(b,10)+')';
                }
                return this.attribute('from').value;
            };
        }
        svg.Element.animateColor.prototype = new svg.Element.AnimateBase;
        // animate transform element
        svg.Element.animateTransform = function(node) {
            this.base = svg.Element.animate;
            this.base(node);
        }
        svg.Element.animateTransform.prototype = new svg.Element.animate;
        // font element
        svg.Element.font = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.horizAdvX = this.attribute('horiz-adv-x').numValue();
            this.isRTL = false;
            this.isArabic = false;
            this.fontFace = null;
            this.missingGlyph = null;
            this.glyphs = [];
            for (var i=0; i<this.children.length; i++) {
                var child = this.children[i];
                if (child.type == 'font-face') {
                    this.fontFace = child;
                    if (child.style('font-family').hasValue()) {
                        svg.Definitions[child.style('font-family').value] = this;
                    }
                }
                else if (child.type == 'missing-glyph') this.missingGlyph = child;
                else if (child.type == 'glyph') {
                    if (child.arabicForm != '') {
                        this.isRTL = true;
                        this.isArabic = true;
                        if (typeof(this.glyphs[child.unicode]) == 'undefined') this.glyphs[child.unicode] = [];
                        this.glyphs[child.unicode][child.arabicForm] = child;
                    }
                    else {
                        this.glyphs[child.unicode] = child;
                    }
                }
            }
        }
        svg.Element.font.prototype = new svg.Element.ElementBase;
        // font-face element
        svg.Element.fontface = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.ascent = this.attribute('ascent').value;
            this.descent = this.attribute('descent').value;
            this.unitsPerEm = this.attribute('units-per-em').numValue();
        }
        svg.Element.fontface.prototype = new svg.Element.ElementBase;
        // missing-glyph element
        svg.Element.missingglyph = function(node) {
            this.base = svg.Element.path;
            this.base(node);
            this.horizAdvX = 0;
        }
        svg.Element.missingglyph.prototype = new svg.Element.path;
        // glyph element
        svg.Element.glyph = function(node) {
            this.base = svg.Element.path;
            this.base(node);
            this.horizAdvX = this.attribute('horiz-adv-x').numValue();
            this.unicode = this.attribute('unicode').value;
            this.arabicForm = this.attribute('arabic-form').value;
        }
        svg.Element.glyph.prototype = new svg.Element.path;
        // text element
        svg.Element.text = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            if (node != null) {
                // add children
                this.children = [];
                for (var i=0; i<node.childNodes.length; i++) {
                    var childNode = node.childNodes[i];
                    if (childNode.nodeType == 1) { // capture tspan and tref nodes
                        this.addChild(childNode, true);
                    }
                    else if (childNode.nodeType == 3) { // capture text
                        this.addChild(new svg.Element.tspan(childNode), false);
                    }
                }
            }
            this.baseSetContext = this.setContext;
            this.setContext = function(ctx) {
                this.baseSetContext(ctx);
                if (this.style('dominant-baseline').hasValue()) ctx.textBaseline = this.style('dominant-baseline').value;
                if (this.style('alignment-baseline').hasValue()) ctx.textBaseline = this.style('alignment-baseline').value;
            }
            this.renderChildren = function(ctx) {
                var textAnchor = this.style('text-anchor').valueOrDefault('start');
                var x = this.attribute('x').Length.toPixels('x');
                var y = this.attribute('y').Length.toPixels('y');
                for (var i=0; i<this.children.length; i++) {
                    var child = this.children[i];
                    if (child.attribute('x').hasValue()) {
                        child.x = child.attribute('x').Length.toPixels('x');
                    }
                    else {
                        if (child.attribute('dx').hasValue()) x += child.attribute('dx').Length.toPixels('x');
                        child.x = x;
                    }
                    var childLength = child.measureText(ctx);
                    if (textAnchor != 'start' && (i==0 || child.attribute('x').hasValue())) { // new group?
                        // loop through rest of children
                        var groupLength = childLength;
                        for (var j=i+1; j<this.children.length; j++) {
                            var childInGroup = this.children[j];
                            if (childInGroup.attribute('x').hasValue()) break; // new group
                            groupLength += childInGroup.measureText(ctx);
                        }
                        child.x -= (textAnchor == 'end' ? groupLength : groupLength / 2.0);
                    }
                    x = child.x + childLength;
                    if (child.attribute('y').hasValue()) {
                        child.y = child.attribute('y').Length.toPixels('y');
                    }
                    else {
                        if (child.attribute('dy').hasValue()) y += child.attribute('dy').Length.toPixels('y');
                        child.y = y;
                    }
                    y = child.y;
                    child.render(ctx);
                }
            }
        }
        svg.Element.text.prototype = new svg.Element.RenderedElementBase;
        // text base
        svg.Element.TextElementBase = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            this.getGlyph = function(font, text, i) {
                var c = text[i];
                var glyph = null;
                if (font.isArabic) {
                    var arabicForm = 'isolated';
                    if ((i==0 || text[i-1]==' ') && i<text.length-2 && text[i+1]!=' ') arabicForm = 'terminal';
                    if (i>0 && text[i-1]!=' ' && i<text.length-2 && text[i+1]!=' ') arabicForm = 'medial';
                    if (i>0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial';
                    if (typeof(font.glyphs[c]) != 'undefined') {
                        glyph = font.glyphs[c][arabicForm];
                        if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c];
                    }
                }
                else {
                    glyph = font.glyphs[c];
                }
                if (glyph == null) glyph = font.missingGlyph;
                return glyph;
            }
            this.renderChildren = function(ctx) {
                var customFont = this.parent.style('font-family').Definition.getDefinition();
                if (customFont != null) {
                    var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);
                    var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle);
                    var text = this.getText();
                    if (customFont.isRTL) text = text.split("").reverse().join("");
                    var dx = svg.ToNumberArray(this.parent.attribute('dx').value);
                    for (var i=0; i<text.length; i++) {
                        var glyph = this.getGlyph(customFont, text, i);
                        var scale = fontSize / customFont.fontFace.unitsPerEm;
                        ctx.translate(this.x, this.y);
                        ctx.scale(scale, -scale);
                        var lw = ctx.lineWidth;
                        ctx.lineWidth = ctx.lineWidth * customFont.fontFace.unitsPerEm / fontSize;
                        if (fontStyle == 'italic') ctx.transform(1, 0, .4, 1, 0, 0);
                        glyph.render(ctx);
                        if (fontStyle == 'italic') ctx.transform(1, 0, -.4, 1, 0, 0);
                        ctx.lineWidth = lw;
                        ctx.scale(1/scale, -1/scale);
                        ctx.translate(-this.x, -this.y);
                        this.x += fontSize * (glyph.horizAdvX || customFont.horizAdvX) / customFont.fontFace.unitsPerEm;
                        if (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {
                            this.x += dx[i];
                        }
                    }
                    return;
                }
                if (ctx.strokeStyle != '') ctx.strokeText(svg.compressSpaces(this.getText()), this.x, this.y);
                if (ctx.fillStyle != '') ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);
            }
            this.getText = function() {
                // OVERRIDE ME
            }
            this.measureText = function(ctx) {
                var customFont = this.parent.style('font-family').Definition.getDefinition();
                if (customFont != null) {
                    var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);
                    var measure = 0;
                    var text = this.getText();
                    if (customFont.isRTL) text = text.split("").reverse().join("");
                    var dx = svg.ToNumberArray(this.parent.attribute('dx').value);
                    for (var i=0; i<text.length; i++) {
                        var glyph = this.getGlyph(customFont, text, i);
                        measure += (glyph.horizAdvX || customFont.horizAdvX) * fontSize / customFont.fontFace.unitsPerEm;
                        if (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {
                            measure += dx[i];
                        }
                    }
                    return measure;
                }
                var textToMeasure = svg.compressSpaces(this.getText());
                if (!ctx.measureText) return textToMeasure.length * 10;
                ctx.save();
                this.setContext(ctx);
                var width = ctx.measureText(textToMeasure).width;
                ctx.restore();
                return width;
            }
        }
        svg.Element.TextElementBase.prototype = new svg.Element.RenderedElementBase;
        // tspan
        svg.Element.tspan = function(node) {
            this.base = svg.Element.TextElementBase;
            this.base(node);
            this.text = node.nodeType == 3 ? node.nodeValue : // text
                        node.childNodes.length > 0 ? node.childNodes[0].nodeValue : // element
                        node.text;
            this.getText = function() {
                return this.text;
            }
        }
        svg.Element.tspan.prototype = new svg.Element.TextElementBase;
        // tref
        svg.Element.tref = function(node) {
            this.base = svg.Element.TextElementBase;
            this.base(node);
            this.getText = function() {
                var element = this.attribute('xlink:href').Definition.getDefinition();
                if (element != null) return element.children[0].getText();
            }
        }
        svg.Element.tref.prototype = new svg.Element.TextElementBase;
        // a element
        svg.Element.a = function(node) {
            this.base = svg.Element.TextElementBase;
            this.base(node);
            this.hasText = true;
            for (var i=0; i<node.childNodes.length; i++) {
                if (node.childNodes[i].nodeType != 3) this.hasText = false;
            }
            // this might contain text
            this.text = this.hasText ? node.childNodes[0].nodeValue : '';
            this.getText = function() {
                return this.text;
            }
            this.baseRenderChildren = this.renderChildren;
            this.renderChildren = function(ctx) {
                if (this.hasText) {
                    // render as text element
                    this.baseRenderChildren(ctx);
                    var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize);
                    svg.Mouse.checkBoundingBox(this, new svg.BoundingBox(this.x, this.y - fontSize.Length.toPixels('y'), this.x + this.measureText(ctx), this.y));
                }
                else {
                    // render as temporary group
                    var g = new svg.Element.g();
                    g.children = this.children;
                    g.parent = this;
                    g.render(ctx);
                }
            }
            this.onclick = function() {
                window.open(this.attribute('xlink:href').value);
            }
            this.onmousemove = function() {
                svg.ctx.canvas.style.cursor = 'pointer';
            }
        }
        svg.Element.a.prototype = new svg.Element.TextElementBase;
        // image element
        svg.Element.image = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            svg.Images.push(this);
            this.img = document.createElement('img');
            this.loaded = false;
            var that = this;
            this.img.onload = function() { that.loaded = true; }
            this.img.src = this.attribute('xlink:href').value;
            this.renderChildren = function(ctx) {
                var x = this.attribute('x').Length.toPixels('x');
                var y = this.attribute('y').Length.toPixels('y');
                var width = this.attribute('width').Length.toPixels('x');
                var height = this.attribute('height').Length.toPixels('y');
                if (width == 0 || height == 0) return;
                ctx.save();
                ctx.translate(x, y);
                svg.AspectRatio(ctx,
                                this.attribute('preserveAspectRatio').value,
                                width,
                                this.img.width,
                                height,
                                this.img.height,
                                0,
                                0);
                ctx.drawImage(this.img, 0, 0);
                ctx.restore();
            }
        }
        svg.Element.image.prototype = new svg.Element.RenderedElementBase;
        // group element
        svg.Element.g = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            this.getBoundingBox = function() {
                var bb = new svg.BoundingBox();
                for (var i=0; i<this.children.length; i++) {
                    bb.addBoundingBox(this.children[i].getBoundingBox());
                }
                return bb;
            };
        }
        svg.Element.g.prototype = new svg.Element.RenderedElementBase;
        // symbol element
        svg.Element.symbol = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            this.baseSetContext = this.setContext;
            this.setContext = function(ctx) {
                this.baseSetContext(ctx);
                // viewbox
                if (this.attribute('viewBox').hasValue()) {
                    var viewBox = svg.ToNumberArray(this.attribute('viewBox').value);
                    var minX = viewBox[0];
                    var minY = viewBox[1];
                    width = viewBox[2];
                    height = viewBox[3];
                    svg.AspectRatio(ctx,
                                    this.attribute('preserveAspectRatio').value,
                                    this.attribute('width').Length.toPixels('x'),
                                    width,
                                    this.attribute('height').Length.toPixels('y'),
                                    height,
                                    minX,
                                    minY);
                    svg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);
                }
            }
        }
        svg.Element.symbol.prototype = new svg.Element.RenderedElementBase;
        // style element
        svg.Element.style = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            // text, or spaces then CDATA
            var css = node.childNodes[0].nodeValue + (node.childNodes.length > 1 ? node.childNodes[1].nodeValue : '');
            css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments
            css = svg.compressSpaces(css); // replace whitespace
            var cssDefs = css.split('}');
            for (var i=0; i<cssDefs.length; i++) {
                if (svg.trim(cssDefs[i]) != '') {
                    var cssDef = cssDefs[i].split('{');
                    var cssClasses = cssDef[0].split(',');
                    var cssProps = cssDef[1].split(';');
                    for (var j=0; j<cssClasses.length; j++) {
                        var cssClass = svg.trim(cssClasses[j]);
                        if (cssClass != '') {
                            var props = {};
                            for (var k=0; k<cssProps.length; k++) {
                                var prop = cssProps[k].indexOf(':');
                                var name = cssProps[k].substr(0, prop);
                                var value = cssProps[k].substr(prop + 1, cssProps[k].length - prop);
                                if (name != null && value != null) {
                                    props[svg.trim(name)] = new svg.Property(svg.trim(name), svg.trim(value));
                                }
                            }
                            svg.Styles[cssClass] = props;
                            if (cssClass == '@font-face') {
                                var fontFamily = props['font-family'].value.replace(/"/g,'');
                                var srcs = props['src'].value.split(',');
                                for (var s=0; s<srcs.length; s++) {
                                    if (srcs[s].indexOf('format("svg")') > 0) {
                                        var urlStart = srcs[s].indexOf('url');
                                        var urlEnd = srcs[s].indexOf(')', urlStart);
                                        var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6);
                                        var doc = svg.parseXml(svg.ajax(url));
                                        var fonts = doc.getElementsByTagName('font');
                                        for (var f=0; f<fonts.length; f++) {
                                            var font = svg.CreateElement(fonts[f]);
                                            svg.Definitions[fontFamily] = font;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        svg.Element.style.prototype = new svg.Element.ElementBase;
        // use element
        svg.Element.use = function(node) {
            this.base = svg.Element.RenderedElementBase;
            this.base(node);
            this.baseSetContext = this.setContext;
            this.setContext = function(ctx) {
                this.baseSetContext(ctx);
                if (this.attribute('x').hasValue()) ctx.translate(this.attribute('x').Length.toPixels('x'), 0);
                if (this.attribute('y').hasValue()) ctx.translate(0, this.attribute('y').Length.toPixels('y'));
            }
            this.getDefinition = function() {
                var element = this.attribute('xlink:href').Definition.getDefinition();
                if (this.attribute('width').hasValue()) element.attribute('width', true).value = this.attribute('width').value;
                if (this.attribute('height').hasValue()) element.attribute('height', true).value = this.attribute('height').value;
                return element;
            }
            this.path = function(ctx) {
                var element = this.getDefinition();
                if (element != null) element.path(ctx);
            }
            this.renderChildren = function(ctx) {
                var element = this.getDefinition();
                if (element != null) element.render(ctx);
            }
        }
        svg.Element.use.prototype = new svg.Element.RenderedElementBase;
        // mask element
        svg.Element.mask = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.apply = function(ctx, element) {
                // render as temp svg
                var x = this.attribute('x').Length.toPixels('x');
                var y = this.attribute('y').Length.toPixels('y');
                var width = this.attribute('width').Length.toPixels('x');
                var height = this.attribute('height').Length.toPixels('y');
                // temporarily remove mask to avoid recursion
                var mask = element.attribute('mask').value;
                element.attribute('mask').value = '';
                    var cMask = document.createElement('canvas');
                    cMask.width = x + width;
                    cMask.height = y + height;
                    var maskCtx = cMask.getContext('2d');
                    this.renderChildren(maskCtx);
                    var c = document.createElement('canvas');
                    c.width = x + width;
                    c.height = y + height;
                    var tempCtx = c.getContext('2d');
                    element.render(tempCtx);
                    tempCtx.globalCompositeOperation = 'destination-in';
                    tempCtx.fillStyle = maskCtx.createPattern(cMask, 'no-repeat');
                    tempCtx.fillRect(0, 0, x + width, y + height);
                    ctx.fillStyle = tempCtx.createPattern(c, 'no-repeat');
                    ctx.fillRect(0, 0, x + width, y + height);
                // reassign mask
                element.attribute('mask').value = mask;
            }
            this.render = function(ctx) {
                // NO RENDER
            }
        }
        svg.Element.mask.prototype = new svg.Element.ElementBase;
        // clip element
        svg.Element.clipPath = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.apply = function(ctx) {
                for (var i=0; i<this.children.length; i++) {
                    if (this.children[i].path) {
                        this.children[i].path(ctx);
                        ctx.clip();
                    }
                }
            }
            this.render = function(ctx) {
                // NO RENDER
            }
        }
        svg.Element.clipPath.prototype = new svg.Element.ElementBase;
        // filters
        svg.Element.filter = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            this.apply = function(ctx, element) {
                // render as temp svg
                var bb = element.getBoundingBox();
                var x = this.attribute('x').Length.toPixels('x');
                var y = this.attribute('y').Length.toPixels('y');
                if (x == 0 || y == 0) {
                    x = bb.x1;
                    y = bb.y1;
                }
                var width = this.attribute('width').Length.toPixels('x');
                var height = this.attribute('height').Length.toPixels('y');
                if (width == 0 || height == 0) {
                    width = bb.width();
                    height = bb.height();
                }
                // temporarily remove filter to avoid recursion
                var filter = element.style('filter').value;
                element.style('filter').value = '';
                // max filter distance
                var extraPercent = .20;
                var px = extraPercent * width;
                var py = extraPercent * height;
                var c = document.createElement('canvas');
                c.width = width + 2*px;
                c.height = height + 2*py;
                var tempCtx = c.getContext('2d');
                tempCtx.translate(-x + px, -y + py);
                element.render(tempCtx);
                // apply filters
                for (var i=0; i<this.children.length; i++) {
                    this.children[i].apply(tempCtx, 0, 0, width + 2*px, height + 2*py);
                }
                // render on me
                ctx.drawImage(c, 0, 0, width + 2*px, height + 2*py, x - px, y - py, width + 2*px, height + 2*py);
                // reassign filter
                element.style('filter', true).value = filter;
            }
            this.render = function(ctx) {
                // NO RENDER
            }
        }
        svg.Element.filter.prototype = new svg.Element.ElementBase;
        svg.Element.feGaussianBlur = function(node) {
            this.base = svg.Element.ElementBase;
            this.base(node);
            function make_fgauss(sigma) {
                sigma = Math.max(sigma, 0.01);
                var len = Math.ceil(sigma * 4.0) + 1;
                mask = [];
                for (var i = 0; i < len; i++) {
                    mask[i] = Math.exp(-0.5 * (i / sigma) * (i / sigma));
                }
                return mask;
            }
            function normalize(mask) {
                var sum = 0;
                for (var i = 1; i < mask.length; i++) {
                    sum += Math.abs(mask[i]);
                }
                sum = 2 * sum + Math.abs(mask[0]);
                for (var i = 0; i < mask.length; i++) {
                    mask[i] /= sum;
                }
                return mask;
            }
            function convolve_even(src, dst, mask, width, height) {
              for (var y = 0; y < height; y++) {
                for (var x = 0; x < width; x++) {
                  var a = imGet(src, x, y, width, height, 3)/255;
                  for (var rgba = 0; rgba < 4; rgba++) {
                      var sum = mask[0] * (a==0?255:imGet(src, x, y, width, height, rgba)) * (a==0||rgba==3?1:a);
                      for (var i = 1; i < mask.length; i++) {
                        var a1 = imGet(src, Math.max(x-i,0), y, width, height, 3)/255;
                        var a2 = imGet(src, Math.min(x+i, width-1), y, width, height, 3)/255;
                        sum += mask[i] *
                          ((a1==0?255:imGet(src, Math.max(x-i,0), y, width, height, rgba)) * (a1==0||rgba==3?1:a1) +
                           (a2==0?255:imGet(src, Math.min(x+i, width-1), y, width, height, rgba)) * (a2==0||rgba==3?1:a2));
                      }
                      imSet(dst, y, x, height, width, rgba, sum);
                  }
                }
              }
            }
            function imGet(img, x, y, width, height, rgba) {
                return img[y*width*4 + x*4 + rgba];
            }
            function imSet(img, x, y, width, height, rgba, val) {
                img[y*width*4 + x*4 + rgba] = val;
            }
            function blur(ctx, width, height, sigma)
            {
                var srcData = ctx.getImageData(0, 0, width, height);
                var mask = make_fgauss(sigma);
                mask = normalize(mask);
                tmp = [];
                convolve_even(srcData.data, tmp, mask, width, height);
                convolve_even(tmp, srcData.data, mask, height, width);
                ctx.clearRect(0, 0, width, height);
                ctx.putImageData(srcData, 0, 0);
            }
            this.apply = function(ctx, x, y, width, height) {
                // assuming x==0 && y==0 for now
                blur(ctx, width, height, this.attribute('stdDeviation').numValue());
            }
        }
        svg.Element.filter.prototype = new svg.Element.feGaussianBlur;
        // title element, do nothing
        svg.Element.title = function(node) {
        }
        svg.Element.title.prototype = new svg.Element.ElementBase;
        // desc element, do nothing
        svg.Element.desc = function(node) {
        }
        svg.Element.desc.prototype = new svg.Element.ElementBase;
        svg.Element.MISSING = function(node) {
            console.log('ERROR: Element \'' + node.nodeName + '\' not yet implemented.');
        }
        svg.Element.MISSING.prototype = new svg.Element.ElementBase;
        // element factory
        svg.CreateElement = function(node) {
            var className = node.nodeName.replace(/^[^:]+:/,''); // remove namespace
            className = className.replace(/\-/g,''); // remove dashes
            var e = null;
            if (typeof(svg.Element[className]) != 'undefined') {
                e = new svg.Element[className](node);
            }
            else {
                e = new svg.Element.MISSING(node);
            }
            e.type = node.nodeName;
            return e;
        }
        // load from url
        svg.load = function(ctx, url) {
            svg.loadXml(ctx, svg.ajax(url));
        }
        // load from xml
        svg.loadXml = function(ctx, xml) {
            svg.loadXmlDoc(ctx, svg.parseXml(xml));
        }
        svg.loadXmlDoc = function(ctx, dom) {
            svg.init(ctx);
            var mapXY = function(p) {
                var e = ctx.canvas;
                while (e) {
                    p.x -= e.offsetLeft;
                    p.y -= e.offsetTop;
                    e = e.offsetParent;
                }
                if (window.scrollX) p.x += window.scrollX;
                if (window.scrollY) p.y += window.scrollY;
                return p;
            }
            // bind mouse
            if (svg.opts['ignoreMouse'] != true) {
                ctx.canvas.onclick = function(e) {
                    var p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));
                    svg.Mouse.onclick(p.x, p.y);
                };
                ctx.canvas.onmousemove = function(e) {
                    var p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));
                    svg.Mouse.onmousemove(p.x, p.y);
                };
            }
            var e = svg.CreateElement(dom.documentElement);
            e.root = true;
            // render loop
            var isFirstRender = true;
            var draw = function() {
                svg.ViewPort.Clear();
                if (ctx.canvas.parentNode) svg.ViewPort.SetCurrent(ctx.canvas.parentNode.clientWidth, ctx.canvas.parentNode.clientHeight);
                if (svg.opts['ignoreDimensions'] != true) {
                    // set canvas size
                    if (e.style('width').hasValue()) {
                        ctx.canvas.width = e.style('width').Length.toPixels('x');
                        ctx.canvas.style.width = ctx.canvas.width + 'px';
                    }
                    if (e.style('height').hasValue()) {
                        ctx.canvas.height = e.style('height').Length.toPixels('y');
                        ctx.canvas.style.height = ctx.canvas.height + 'px';
                    }
                }
                var cWidth = ctx.canvas.clientWidth || ctx.canvas.width;
                var cHeight = ctx.canvas.clientHeight || ctx.canvas.height;
                svg.ViewPort.SetCurrent(cWidth, cHeight);
                if (svg.opts != null && svg.opts['offsetX'] != null) e.attribute('x', true).value = svg.opts['offsetX'];
                if (svg.opts != null && svg.opts['offsetY'] != null) e.attribute('y', true).value = svg.opts['offsetY'];
                if (svg.opts != null && svg.opts['scaleWidth'] != null && svg.opts['scaleHeight'] != null) {
                    var xRatio = 1, yRatio = 1;
                    if (e.attribute('width').hasValue()) xRatio = e.attribute('width').Length.toPixels('x') / svg.opts['scaleWidth'];
                    if (e.attribute('height').hasValue()) yRatio = e.attribute('height').Length.toPixels('y') / svg.opts['scaleHeight'];
                    e.attribute('width', true).value = svg.opts['scaleWidth'];
                    e.attribute('height', true).value = svg.opts['scaleHeight'];
                    e.attribute('viewBox', true).value = '0 0 ' + (cWidth * xRatio) + ' ' + (cHeight * yRatio);
                    e.attribute('preserveAspectRatio', true).value = 'none';
                }
                // clear and render
                if (svg.opts['ignoreClear'] != true) {
                    ctx.clearRect(0, 0, cWidth, cHeight);
                }
                e.render(ctx);
                if (isFirstRender) {
                    isFirstRender = false;
                    if (svg.opts != null && typeof(svg.opts['renderCallback']) == 'function') svg.opts['renderCallback']();
                }
            }
            var waitingForImages = true;
            if (svg.ImagesLoaded()) {
                waitingForImages = false;
                draw();
            }
            svg.intervalID = setInterval(function() {
                var needUpdate = false;
                if (waitingForImages && svg.ImagesLoaded()) {
                    waitingForImages = false;
                    needUpdate = true;
                }
                // need update from mouse events?
                if (svg.opts['ignoreMouse'] != true) {
                    needUpdate = needUpdate | svg.Mouse.hasEvents();
                }
                // need update from animations?
                if (svg.opts['ignoreAnimation'] != true) {
                    for (var i=0; i<svg.Animations.length; i++) {
                        needUpdate = needUpdate | svg.Animations[i].update(1000 / svg.FRAMERATE);
                    }
                }
                // need update from redraw?
                if (svg.opts != null && typeof(svg.opts['forceRedraw']) == 'function') {
                    if (svg.opts['forceRedraw']() == true) needUpdate = true;
                }
                // render if needed
                if (needUpdate) {
                    draw();
                    svg.Mouse.runEvents(); // run and clear our events
                }
            }, 1000 / svg.FRAMERATE);
        }
        svg.stop = function() {
            if (svg.intervalID) {
                clearInterval(svg.intervalID);
            }
        }
        svg.Mouse = new (function() {
            this.events = [];
            this.hasEvents = function() { return this.events.length != 0; }
            this.onclick = function(x, y) {
                this.events.push({ type: 'onclick', x: x, y: y,
                    run: function(e) { if (e.onclick) e.onclick(); }
                });
            }
            this.onmousemove = function(x, y) {
                this.events.push({ type: 'onmousemove', x: x, y: y,
                    run: function(e) { if (e.onmousemove) e.onmousemove(); }
                });
            }
            this.eventElements = [];
            this.checkPath = function(element, ctx) {
                for (var i=0; i<this.events.length; i++) {
                    var e = this.events[i];
                    if (ctx.isPointInPath && ctx.isPointInPath(e.x, e.y)) this.eventElements[i] = element;
                }
            }
            this.checkBoundingBox = function(element, bb) {
                for (var i=0; i<this.events.length; i++) {
                    var e = this.events[i];
                    if (bb.isPointInBox(e.x, e.y)) this.eventElements[i] = element;
                }
            }
            this.runEvents = function() {
                svg.ctx.canvas.style.cursor = '';
                for (var i=0; i<this.events.length; i++) {
                    var e = this.events[i];
                    var element = this.eventElements[i];
                    while (element) {
                        e.run(element);
                        element = element.parent;
                    }
                }
                // done running, clear
                this.events = [];
                this.eventElements = [];
            }
        });
        return svg;
    }
})();
if (CanvasRenderingContext2D) {
    CanvasRenderingContext2D.prototype.drawSvg = function(s, dx, dy, dw, dh) {
        canvg(this.canvas, s, {
            ignoreMouse: true,
            ignoreAnimation: true,
            ignoreDimensions: true,
            ignoreClear: true,
            offsetX: dx,
            offsetY: dy,
            scaleWidth: dw,
            scaleHeight: dh
        });
    }
}/**
 * @license Highcharts JS v3.0.6 (2013-10-04)
 * CanVGRenderer Extension module
 *
 * (c) 2011-2012 Torstein Hønsi, Erik Olsson
 *
 * License: www.highcharts.com/license
 */
// JSLint options:
/*global Highcharts */
(function (Highcharts) { // encapsulate
    var UNDEFINED,
        DIV = 'div',
        ABSOLUTE = 'absolute',
        RELATIVE = 'relative',
        HIDDEN = 'hidden',
        VISIBLE = 'visible',
        PX = 'px',
        css = Highcharts.css,
        CanVGRenderer = Highcharts.CanVGRenderer,
        SVGRenderer = Highcharts.SVGRenderer,
        extend = Highcharts.extend,
        merge = Highcharts.merge,
        addEvent = Highcharts.addEvent,
        createElement = Highcharts.createElement,
        discardElement = Highcharts.discardElement;
    // Extend CanVG renderer on demand, inherit from SVGRenderer
    extend(CanVGRenderer.prototype, SVGRenderer.prototype);
    // Add additional functionality:
    extend(CanVGRenderer.prototype, {
        create: function (chart, container, chartWidth, chartHeight) {
            this.setContainer(container, chartWidth, chartHeight);
            this.configure(chart);
        },
        setContainer: function (container, chartWidth, chartHeight) {
            var containerStyle = container.style,
                containerParent = container.parentNode,
                containerLeft = containerStyle.left,
                containerTop = containerStyle.top,
                containerOffsetWidth = container.offsetWidth,
                containerOffsetHeight = container.offsetHeight,
                canvas,
                initialHiddenStyle = { visibility: HIDDEN, position: ABSOLUTE };
            this.init.apply(this, [container, chartWidth, chartHeight]);
            // add the canvas above it
            canvas = createElement('canvas', {
                width: containerOffsetWidth,
                height: containerOffsetHeight
            }, {
                position: RELATIVE,
                left: containerLeft,
                top: containerTop
            }, container);
            this.canvas = canvas;
            // Create the tooltip line and div, they are placed as siblings to
            // the container (and as direct childs to the div specified in the html page)
            this.ttLine = createElement(DIV, null, initialHiddenStyle, containerParent);
            this.ttDiv = createElement(DIV, null, initialHiddenStyle, containerParent);
            this.ttTimer = UNDEFINED;
            // Move away the svg node to a new div inside the container's parent so we can hide it.
            var hiddenSvg = createElement(DIV, {
                width: containerOffsetWidth,
                height: containerOffsetHeight
            }, {
                visibility: HIDDEN,
                left: containerLeft,
                top: containerTop
            }, containerParent);
            this.hiddenSvg = hiddenSvg;
            hiddenSvg.appendChild(this.box);
        },
        /**
         * Configures the renderer with the chart. Attach a listener to the event tooltipRefresh.
         **/
        configure: function (chart) {
            var renderer = this,
                options = chart.options.tooltip,
                borderWidth = options.borderWidth,
                tooltipDiv = renderer.ttDiv,
                tooltipDivStyle = options.style,
                tooltipLine = renderer.ttLine,
                padding = parseInt(tooltipDivStyle.padding, 10);
            // Add border styling from options to the style
            tooltipDivStyle = merge(tooltipDivStyle, {
                padding: padding + PX,
                'background-color': options.backgroundColor,
                'border-style': 'solid',
                'border-width': borderWidth + PX,
                'border-radius': options.borderRadius + PX
            });
            // Optionally add shadow
            if (options.shadow) {
                tooltipDivStyle = merge(tooltipDivStyle, {
                    'box-shadow': '1px 1px 3px gray', // w3c
                    '-webkit-box-shadow': '1px 1px 3px gray' // webkit
                });
            }
            css(tooltipDiv, tooltipDivStyle);
            // Set simple style on the line
            css(tooltipLine, {
                'border-left': '1px solid darkgray'
            });
            // This event is triggered when a new tooltip should be shown
            addEvent(chart, 'tooltipRefresh', function (args) {
                var chartContainer = chart.container,
                    offsetLeft = chartContainer.offsetLeft,
                    offsetTop = chartContainer.offsetTop,
                    position;
                // Set the content of the tooltip
                tooltipDiv.innerHTML = args.text;
                // Compute the best position for the tooltip based on the divs size and container size.
                position = chart.tooltip.getPosition(tooltipDiv.offsetWidth, tooltipDiv.offsetHeight, {plotX: args.x, plotY: args.y});
                css(tooltipDiv, {
                    visibility: VISIBLE,
                    left: position.x + PX,
                    top: position.y + PX,
                    'border-color': args.borderColor
                });
                // Position the tooltip line
                css(tooltipLine, {
                    visibility: VISIBLE,
                    left: offsetLeft + args.x + PX,
                    top: offsetTop + chart.plotTop + PX,
                    height: chart.plotHeight  + PX
                });
                // This timeout hides the tooltip after 3 seconds
                // First clear any existing timer
                if (renderer.ttTimer !== UNDEFINED) {
                    clearTimeout(renderer.ttTimer);
                }
                // Start a new timer that hides tooltip and line
                renderer.ttTimer = setTimeout(function () {
                    css(tooltipDiv, { visibility: HIDDEN });
                    css(tooltipLine, { visibility: HIDDEN });
                }, 3000);
            });
        },
        /**
         * Extend SVGRenderer.destroy to also destroy the elements added by CanVGRenderer.
         */
        destroy: function () {
            var renderer = this;
            // Remove the canvas
            discardElement(renderer.canvas);
            // Kill the timer
            if (renderer.ttTimer !== UNDEFINED) {
                clearTimeout(renderer.ttTimer);
            }
            // Remove the divs for tooltip and line
            discardElement(renderer.ttLine);
            discardElement(renderer.ttDiv);
            discardElement(renderer.hiddenSvg);
            // Continue with base class
            return SVGRenderer.prototype.destroy.apply(renderer);
        },
        /**
         * Take a color and return it if it's a string, do not make it a gradient even if it is a
         * gradient. Currently canvg cannot render gradients (turns out black),
         * see: http://code.google.com/p/canvg/issues/detail?id=104
         *
         * @param {Object} color The color or config object
         */
        color: function (color, elem, prop) {
            if (color && color.linearGradient) {
                // Pick the end color and forward to base implementation
                color = color.stops[color.stops.length - 1][1];
            }
            return SVGRenderer.prototype.color.call(this, color, elem, prop);
        },
        /**
         * Draws the SVG on the canvas or adds a draw invokation to the deferred list.
         */
        draw: function () {
            var renderer = this;
            window.canvg(renderer.canvas, renderer.hiddenSvg.innerHTML);
        }
    });
}(Highcharts));
Diff truncated after the above file
ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/data.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/data.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/drilldown.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/drilldown.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/exporting.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/exporting.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/funnel.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/funnel.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/heatmap.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/heatmap.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/map.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/map.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/no-data-to-display.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/modules/no-data-to-display.src.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/dark-blue.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/dark-green.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/gray.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/grid.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/highcharts/themes/skies.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/jquery-1.10.2.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/jquery-1.10.2.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/jquery-1.10.2.min.map ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/snapscreen/UEditorSnapscreen.exe ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.eot ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.svg ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.ttf ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/font/vjs.woff ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video-js.css ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video-js.min.css ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video-js.swf ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video.dev.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/video-js/video.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/Uploader.swf ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.css ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.custom.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.custom.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.flashonly.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.flashonly.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.html5only.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.html5only.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.withoutimage.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/webuploader/webuploader.withoutimage.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/zeroclipboard/ZeroClipboard.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/zeroclipboard/ZeroClipboard.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/third-party/zeroclipboard/ZeroClipboard.swf ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.all.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.all.min.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.config.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.parse.js ManagementNTTravel/guns-admin/src/main/webapp/static/js/ueditor/1.4.3/ueditor.parse.min.js