dever 6 years ago
parent
commit
0ca616a563
100 changed files with 17601 additions and 0 deletions
  1. 110 0
      assets/dever/config.js
  2. 760 0
      assets/dever/core.js
  3. 202 0
      assets/dever/share.js
  4. 3 0
      assets/dever/template.js
  5. 1 0
      assets/lib/attach/jquery.inline-attachment.min.js
  6. 4 0
      assets/lib/bootstrap/css/bootstrap.min.css
  7. BIN
      assets/lib/bootstrap/fonts/glyphicons-halflings-regular.eot
  8. 288 0
      assets/lib/bootstrap/fonts/glyphicons-halflings-regular.svg
  9. BIN
      assets/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf
  10. BIN
      assets/lib/bootstrap/fonts/glyphicons-halflings-regular.woff
  11. BIN
      assets/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2
  12. 5 0
      assets/lib/bootstrap/js/bootstrap.min.js
  13. 0 0
      assets/lib/datetime/jquery.datetimepicker.css
  14. 9 0
      assets/lib/datetime/jquery.datetimepicker.full.js
  15. 0 0
      assets/lib/datetime/jquery.datetimepicker.min.js
  16. 5 0
      assets/lib/doc/doc.min.css
  17. 16 0
      assets/lib/doc/doc.min.js
  18. 55 0
      assets/lib/doc/main.js
  19. 0 0
      assets/lib/echarts/echarts.common.min.js
  20. 7 0
      assets/lib/fancybox/.gitattributes
  21. BIN
      assets/lib/fancybox/blank.gif
  22. BIN
      assets/lib/fancybox/fancybox_loading.gif
  23. BIN
      assets/lib/fancybox/fancybox_loading@2x.gif
  24. BIN
      assets/lib/fancybox/fancybox_overlay.png
  25. BIN
      assets/lib/fancybox/fancybox_sprite.png
  26. BIN
      assets/lib/fancybox/fancybox_sprite@2x.png
  27. BIN
      assets/lib/fancybox/helpers/fancybox_buttons.png
  28. 97 0
      assets/lib/fancybox/helpers/jquery.fancybox-buttons.css
  29. 122 0
      assets/lib/fancybox/helpers/jquery.fancybox-buttons.js
  30. 199 0
      assets/lib/fancybox/helpers/jquery.fancybox-media.js
  31. 55 0
      assets/lib/fancybox/helpers/jquery.fancybox-thumbs.css
  32. 162 0
      assets/lib/fancybox/helpers/jquery.fancybox-thumbs.js
  33. 274 0
      assets/lib/fancybox/jquery.fancybox.css
  34. 2020 0
      assets/lib/fancybox/jquery.fancybox.js
  35. 46 0
      assets/lib/fancybox/jquery.fancybox.pack.js
  36. 1 0
      assets/lib/highlight/highlight.min.css
  37. 1 0
      assets/lib/highlight/highlight.min.js
  38. 3 0
      assets/lib/jquery/jquery.min.js
  39. 139 0
      assets/lib/jquery/store.js
  40. 1 0
      assets/lib/kindeditor/kindeditor-all-min.js
  41. 9849 0
      assets/lib/kindeditor/kindeditor-all.js
  42. 242 0
      assets/lib/kindeditor/lang/ar.js
  43. 241 0
      assets/lib/kindeditor/lang/en.js
  44. 246 0
      assets/lib/kindeditor/lang/ko.js
  45. 242 0
      assets/lib/kindeditor/lang/ru.js
  46. 238 0
      assets/lib/kindeditor/lang/zh-CN.js
  47. 243 0
      assets/lib/kindeditor/lang/zh-TW.js
  48. 806 0
      assets/lib/kindeditor/php/JSON.php
  49. 53 0
      assets/lib/kindeditor/php/demo.php
  50. 137 0
      assets/lib/kindeditor/php/file_manager_json.php
  51. 139 0
      assets/lib/kindeditor/php/upload_json.php
  52. 46 0
      assets/lib/kindeditor/plugins/anchor/anchor.js
  53. 54 0
      assets/lib/kindeditor/plugins/autoheight/autoheight.js
  54. 93 0
      assets/lib/kindeditor/plugins/baidumap/baidumap.js
  55. 83 0
      assets/lib/kindeditor/plugins/baidumap/index.html
  56. 43 0
      assets/lib/kindeditor/plugins/baidumap/map.html
  57. 29 0
      assets/lib/kindeditor/plugins/clearhtml/clearhtml.js
  58. 62 0
      assets/lib/kindeditor/plugins/code/code.js
  59. 13 0
      assets/lib/kindeditor/plugins/code/prettify.css
  60. 28 0
      assets/lib/kindeditor/plugins/code/prettify.js
  61. 129 0
      assets/lib/kindeditor/plugins/emoticons/emoticons.js
  62. BIN
      assets/lib/kindeditor/plugins/emoticons/images/0.gif
  63. BIN
      assets/lib/kindeditor/plugins/emoticons/images/1.gif
  64. BIN
      assets/lib/kindeditor/plugins/emoticons/images/10.gif
  65. BIN
      assets/lib/kindeditor/plugins/emoticons/images/100.gif
  66. BIN
      assets/lib/kindeditor/plugins/emoticons/images/101.gif
  67. BIN
      assets/lib/kindeditor/plugins/emoticons/images/102.gif
  68. BIN
      assets/lib/kindeditor/plugins/emoticons/images/103.gif
  69. BIN
      assets/lib/kindeditor/plugins/emoticons/images/104.gif
  70. BIN
      assets/lib/kindeditor/plugins/emoticons/images/105.gif
  71. BIN
      assets/lib/kindeditor/plugins/emoticons/images/106.gif
  72. BIN
      assets/lib/kindeditor/plugins/emoticons/images/107.gif
  73. BIN
      assets/lib/kindeditor/plugins/emoticons/images/108.gif
  74. BIN
      assets/lib/kindeditor/plugins/emoticons/images/109.gif
  75. BIN
      assets/lib/kindeditor/plugins/emoticons/images/11.gif
  76. BIN
      assets/lib/kindeditor/plugins/emoticons/images/110.gif
  77. BIN
      assets/lib/kindeditor/plugins/emoticons/images/111.gif
  78. BIN
      assets/lib/kindeditor/plugins/emoticons/images/112.gif
  79. BIN
      assets/lib/kindeditor/plugins/emoticons/images/113.gif
  80. BIN
      assets/lib/kindeditor/plugins/emoticons/images/114.gif
  81. BIN
      assets/lib/kindeditor/plugins/emoticons/images/115.gif
  82. BIN
      assets/lib/kindeditor/plugins/emoticons/images/116.gif
  83. BIN
      assets/lib/kindeditor/plugins/emoticons/images/117.gif
  84. BIN
      assets/lib/kindeditor/plugins/emoticons/images/118.gif
  85. BIN
      assets/lib/kindeditor/plugins/emoticons/images/119.gif
  86. BIN
      assets/lib/kindeditor/plugins/emoticons/images/12.gif
  87. BIN
      assets/lib/kindeditor/plugins/emoticons/images/120.gif
  88. BIN
      assets/lib/kindeditor/plugins/emoticons/images/121.gif
  89. BIN
      assets/lib/kindeditor/plugins/emoticons/images/122.gif
  90. BIN
      assets/lib/kindeditor/plugins/emoticons/images/123.gif
  91. BIN
      assets/lib/kindeditor/plugins/emoticons/images/124.gif
  92. BIN
      assets/lib/kindeditor/plugins/emoticons/images/125.gif
  93. BIN
      assets/lib/kindeditor/plugins/emoticons/images/126.gif
  94. BIN
      assets/lib/kindeditor/plugins/emoticons/images/127.gif
  95. BIN
      assets/lib/kindeditor/plugins/emoticons/images/128.gif
  96. BIN
      assets/lib/kindeditor/plugins/emoticons/images/129.gif
  97. BIN
      assets/lib/kindeditor/plugins/emoticons/images/13.gif
  98. BIN
      assets/lib/kindeditor/plugins/emoticons/images/130.gif
  99. BIN
      assets/lib/kindeditor/plugins/emoticons/images/131.gif
  100. BIN
      assets/lib/kindeditor/plugins/emoticons/images/132.gif

+ 110 - 0
assets/dever/config.js

@@ -0,0 +1,110 @@
+//demo
+
+//定义瀑布流
+Dever.Page().name = '#page';
+
+//定义用户相关的一些信息
+Dever.User().config = 
+{
+	//初始化,绑定click
+	'click' : 
+	{
+		//登录
+		0 : '#login'
+		//注册
+		,1 : '#reg'
+		//发表主题
+		,2 : '#dever_create_post'
+		//发表评论
+		,3 : '#dever_create_comment'
+		//用户点赞
+		,4 : '.dever_up'
+	}
+
+	//登录信息
+	,0 :
+	{
+		'input' :
+		{
+			'email' : '#email'
+			,'password' : '#password'
+			,'refer' : '#refer'
+		}
+		//错误提示的div
+		,'status' : '.alert'
+		//错误提示
+		,'error' : '您的邮箱或密码错误'
+		//登录要提交的url
+		,'url' : Dever.Host('passport', 'login.action')
+	}
+
+	//注册信息
+	,1 :
+	{
+		'input' :
+		{
+			'email' : '#email'
+			,'username' : '#username'
+			,'password' : '#password'
+			,'cpassword' : '#cpassword'
+			,'refer' : '#refer'
+		}
+		//错误提示的div
+		,'status' : '.alert'
+		//错误提示
+		,'error' : '您填写的信息有误'
+		//登录要提交的url
+		,'url' : Dever.Host('passport', 'reg.action')
+	}
+	
+	//发表信息
+	,2 :
+	{
+		'input' :
+		{
+			'cate' : '#cate'
+			,'name' : '#dever_post_title'
+			,'content' : '#dever_post_content'
+			,'refer' : '#refer|'//增加|为选填
+		}
+		//错误提示的div
+		,'status' : '#dever_alert'
+		//错误提示
+		,'error' : '您填写的信息有误'
+	}
+
+	//发表信息
+	,3 :
+	{
+		'input' :
+		{
+			'content' : '#dever_comment_content'
+		}
+		//错误提示的div
+		,'status' : '#dever_alert'
+		//错误提示
+		,'error' : '您填写的信息有误'
+		//发表成功后,调用的callback
+		,'callback' : function(e, msg)
+		{
+			$("#dever_comment_content").val('');
+			Dever.LoadPage();
+		}
+	}
+	
+	//点赞
+	,4 :
+	{
+		'input' : 'click'
+		//错误提示
+		,'error' : '您填写的信息有误'
+		,'url' : Dever.Host('forum', 'vote.save')
+		//发表成功后,调用的callback
+		,'callback' : function(e, msg, t)
+		{
+			var num = parseInt(e.find('span').html());
+			e.find('span').html((t.msg == 1 ? num+1 : num-1));
+		}
+	}
+
+};

+ 760 - 0
assets/dever/core.js

@@ -0,0 +1,760 @@
+/* ================================================================================
+ * dever.js v1.0
+ * http://git.shemic.com/dever/script
+ * ================================================================================
+ * Copyright 2017-2018 Dever(dever.cc)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ================================================================================
+ */
+
+ //<filter><script src="../js/lib/jquery.min.js"></script><script src="../js/dever.js"></script></filter>
+
+$(function()
+{
+    Dever.Init();
+});
+
+//公共类库
+var Dever = 
+{
+    Init : function()
+    {
+        this.Import();
+        this.Page().Init();
+        this.User().Init();
+        this.Editor().Init();
+        this.Change();
+        this.Upload();
+        this.LoadPage();
+        this.Extend();
+        //this.Target();
+        //this.Pjax();
+    }
+    
+    ,Pjax : function()
+    {
+		$(document).pjax('a', '.container');
+		//$.pjax.reload('.container');
+	}
+
+    ,Page : function()
+    {
+        return _Dever_Page;
+    }
+
+    ,Template : function()
+    {
+        return _Dever_Template;
+    }
+    
+    ,Editor : function()
+    {
+        return _Dever_Editor;
+    }
+
+    ,User : function()
+    {
+        return _Dever_User;
+    }
+    
+    ,Modal : function()
+    {
+        return _Dever_Modal;
+    }
+    
+    ,Proxy : function(uri)
+    {
+        return config.proxy + 'proxy_method=' + encodeURIComponent(uri);
+    }
+
+    ,Jump : function(url)
+    {
+        location.href = url;
+    }
+    
+    ,BackRun : function(url)
+    {
+        $.post(url);
+    }
+
+    ,Reload : function(e)
+    {
+        e.attr('src', e.attr('src'));
+    }
+    
+    ,Target : function()
+    {
+		var link = config.host;
+		$("a").each(function() {
+			if (!$(this).attr('onclick')) {
+				var url = $(this).attr('href');
+				
+				if (url && url.indexOf(link) == -1) {
+					//$(this).attr('target', '_blank');
+				}
+			}
+		})
+	}
+    
+    ,Import : function()
+	{
+        var self = this;
+        var include = $("include");
+        var count = include.length-1;
+        if (include.length) {
+            include.each(function(i){
+                var dom = $(this);
+                var system  = dom.attr('system');
+                var path    = dom.attr('path');
+                var name    = dom.attr('file');
+
+                var file = '';
+                if(path) file = path;
+                if(system) file = file + '/' + system;
+                
+                file += name + '.html';
+                dom.load(file, function(){
+                    $("html").find("include").eq(i).get(0).outerHTML = dom.html();
+
+                    if (i == count) {
+                        self.Template().Init();
+                    }
+                });
+            })
+        } else {
+            self.Template().Init();
+        }
+	}
+    
+    ,LoadPage : function()
+    {
+		if ($('.dever-loadpage').length) {
+            $('.dever-loadpage').each(function() {
+				var url = $(this).attr('dever-url');
+				var self = $(this);
+                $.getJSON(Dever.CallUrl(url), function(t) {
+					self.html(t.msg);
+					_Dever_Page.Ajax(self);
+				});
+            });
+        }
+    }
+    
+    ,CallUrl : function(url)
+    {
+		if (url.indexOf('callback') == -1) {
+			if (url.indexOf('=') != -1) {
+				url += '&json=1&callback=?';
+			} else {
+				url += '?json=1&callback=?';
+			}
+		}
+		
+		return url;
+	}
+
+    ,Change : function()
+    {
+        if ($('.dever-change').length) {
+            $('.dever-change').change(function() {
+                Dever.Jump($(this).attr('dever-change')+$(this).val());
+            });
+
+            //$('.dever-change').val($('.dever-change').attr('dever-value'));
+        }
+    }
+
+    ,Host : function(host, uri)
+    {
+        var result = '';
+        
+        uri = uri ? uri : '';
+    
+        result = config.host.replace('www', host);
+        result = result.replace('main', host);
+
+        result = result + config.type;
+        
+        result = result.replace('??', '?');
+        
+        if (config.proxy) {
+			return this.Proxy(host + '/' + uri);
+		}
+
+        return result + uri;
+    }
+
+    // 输出数据,提示框
+    ,Out : function(content, callback, ele, title)
+    {
+        if (content && content.indexOf('登录') != -1 && $("#login_url").length) {
+            var href = $("#login_url").val();
+            location.href = href;
+            return;
+        } else {
+            alert(content);
+
+            if (ele && callback) {
+                ele.unbind('click').bind('click', callback);
+            } else if (callback) {
+                callback();
+            }
+        }
+    }
+
+    // 将数据解析,并进行下一步操作
+    ,Msg : function(result, error_callback, success_callback)
+    {
+        if (result.status == 2) {
+            if (error_callback) {
+                return error_callback(result.msg);
+            }
+            this.Out(result.msg);
+        } else {
+            if (success_callback) {
+                return success_callback(result.msg);
+            }
+            if (result.msg.indexOf('http://') != -1) {
+                this.Jump(result.msg);
+            } else if (parseInt(result.msg) > 0) {
+                this.Out('操作成功', function() {
+                    location.reload();
+                });
+            } else {
+                this.Out(result.msg);
+            }
+        }
+    }
+
+    ,Confirm : function(callback)
+    {
+        if (confirm('确定进行此项操作吗?')) {
+            callback();
+        }
+    }
+
+    //上传组件加载
+    ,Upload : function()
+    {
+        if ($(".dever-upload-drag").length) {
+            $(".dever-upload-drag").each(function() {
+                var key = $(this).attr('key');
+                
+                if (config.proxy) {
+					var url = Dever.Proxy('upload/save.drag') + '&key=' + key;
+				} else {
+					var url = config.upload + '.drag?key='+ key;
+				}
+                $(this).inlineattachment({
+                    uploadUrl: url,
+                    progressText: '![文件上传中...]()',
+                    urlText: "![文件描述]({filename})\n",
+                    errorText: '上传失败'
+                });
+            });
+        }
+
+        if ($(".dever-upload").length) {
+            $(".dever-upload").each(function(i) {
+                loadUpload(i,$(this),$(this).attr('key'),config.upload + '.start', config.assets + 'image/');//三个参数说明1:第几个上传框2:文件对象3:图片的基本配置标题
+            })
+        }
+    }
+
+    ,Load : function(filename,filetype)
+    {
+        if (filetype == "js") {
+            var fileref = document.createElement('script');
+            fileref.setAttribute("type","text/javascript");
+            fileref.setAttribute("src",filename + '.' + filetype);
+        } else if (filetype == "css") {
+            var fileref = document.createElement('link');
+            fileref.setAttribute("rel","stylesheet");
+            fileref.setAttribute("type","text/css");
+            fileref.setAttribute("href",filename + '.' + filetype);
+        }
+        if (typeof fileref != "undefined") {
+            document.getElementsByTagName("head")[0].appendChild(fileref);
+        }
+    }
+    
+    ,Extend : function()
+	{
+		Array.prototype.indexIn = function(val) {
+			for (var i = 0; i < this.length; i++) {
+				if (this[i] == val) return i;
+			}
+			return -1;
+		};
+		Array.prototype.remove = function(val) {
+			var index = this.indexIn(val);
+			if (index > -1) {
+				this.splice(index, 1);
+			}
+		};
+
+        $("select option").each(function() {
+            if ($(this).attr('select') && $(this).attr('select') == 'true') {
+                $(this).attr('selected', 'true');
+            } else {
+                $(this).removeAttr('selected');
+            }
+        });
+	}
+
+    ,Ucfirst : function(str)
+    {
+        var str = str.toLowerCase();
+        var strarr = str.split(' ');
+        var result = '';
+        for (var i in strarr){
+            result += strarr[i].substring(0,1).toUpperCase()+strarr[i].substring(1)+' ';
+        }
+        return result;
+    }
+};
+
+//瀑布流分页
+var _Dever_Page = 
+{
+    name : '',
+    Init : function()
+    {
+        if ($(this.name).length) {
+            var self = this;
+            $(window).scroll(function() {  
+                if ($(window).scrollTop() >= $(document).height() - $(window).height()) {
+                    self.Start(self.name);
+                }
+            });  
+        }
+    }
+
+    ,Start : function(page)
+    {
+        page = page ? page : this.name;
+        if ($(page).length) {
+            $(page).hide();
+            var url = $(page).attr('link');
+            if (url) {
+                var key = $(page).attr('dever-list');
+                $.get(url, function(t) {
+                    t = '<div>' + t + '</div>';
+                    var c = $(t).find(key).html();
+                    if (c) {
+                        $(key).append(c);
+
+                        var l = $(t).find(page).attr('link');
+                        $(page).attr('link', l);
+                    }
+                });
+            }
+        }
+    }
+    
+    ,Ajax : function(e)
+    {
+		var self = this;
+		e.find('a').each(function() {
+			var url = $(this).attr('href');
+			
+			$(this).attr('href', 'javascript:;');
+			
+			$(this).unbind('click').bind('click', function() {
+				$.get(url.replace('callback', ''), function(t) {
+					e.html(t);
+					self.Ajax(e);
+				});
+			});
+		});
+	}
+}
+
+//模态框
+var _Dever_Modal =
+{
+    state : false,
+    html : '',
+    box : '',
+    title : '',
+    content : '',
+    yes : '',
+    no : '',
+    setting : '',
+    confirm : '',
+    
+    Init : function()
+    {
+        this.state = false;
+        if (this.html) {
+            $('body').append(this.html);
+            if(this.box) this.box = $(this.box);
+            if(this.title) this.title = $(this.title);
+            if(this.content) this.content = $(this.content);
+            if(this.yes) this.yes = $(this.yes);
+            if(this.no) this.no = $(this.no);
+            if(this.setting) this.setting = $(this.setting);
+            if(this.confirm) this.confirm = $(this.confirm);
+
+            this.state = true;
+        }
+    }
+    
+    ,Alert : function(content, callback)
+    {
+        if (this.state == false) {
+            alert(content);
+            return;
+        } else {
+            if (this.setting.length && this.setting.html()) {
+                this.confirm.hide();
+                this.setting.show();
+            } else {
+                this.setting.hide();
+                this.confirm.show();
+            }
+            this.title.html(content);
+            this.box.show();
+            if (callback) {
+                this.Bind(callback);
+            }
+        }
+    }
+    
+    ,Confirm : function(content, callback)
+    {
+        if (this.state == false) {
+            alert(content);
+            return;
+        } else {
+            this.confirm.show();
+            this.setting.hide();
+            
+            this.title.html(content);
+            this.box.show();
+            if(callback)
+            {
+                this.Bind(callback);
+            }
+        }
+    }
+    
+    ,Bind : function(callback)
+    {
+        if (this.yes.length && callback.yes) {
+            this.yes.unbind('click').bind('click', callback.yes);
+        }
+        
+        if (this.no.length) {
+            if (callback.no) {
+                this.no.unbind('click').bind('click', callback.no);
+            } else {
+                var self = this;
+                this.no.unbind('click').bind('click', function()
+                {
+                    self.Close();
+                });
+            }
+        }
+    }
+    
+    ,Close : function()
+    {
+        this.box.hide();
+    }
+}
+
+//用户相关
+var _Dever_User = 
+{
+    config : [],
+    uid : -1,
+    name : '匿名用户',
+
+    Init : function()
+    {
+        var self = this;
+        if (this.config.click) {
+            for (var i in this.config.click) {
+                var e = self.config.click[i];
+                var c = 1;
+                if (e.indexOf('|') != -1) {
+                    var t = e.split('|');
+                    e = t[0];
+                    c = 2;
+                }
+                if ($(e).length) {
+                    $(e).attr('data-i', i);
+                    $(e).attr('data-c', c);
+                    
+                    $(e).unbind('click').bind('click', function() {
+                        if ($(this).attr('data-c') == 2) {
+                            var t1 = $(this);
+                            Dever.Confirm(function() {
+                                self.Save($(this).attr('data-i'), t1, config);
+                            });
+                        } else {
+                            self.Save($(this).attr('data-i'), $(this), config);
+                        }
+                    });
+                }
+            }
+        }
+    }
+
+    //通用的保存数据功能
+    ,Save : function(key, e, setting)
+    {
+        var self = this;
+        var config = self.config[key];
+        if (config.start) {
+            config.start.call();
+        }
+        var send = {};
+        var callback = function(msg,state) {
+            if (config.status && $(config.status).length) {
+                //$(config.status).html(msg).css('visibility','initial');
+                state ? $(config.status).html(msg).hide() : $(config.status).html(msg).show();
+            } else if(!state) {
+                Dever.Out(msg);
+            }
+        }
+
+        if (typeof(config.input) != 'undefined') {
+            if (typeof(config.input) == 'string' && config.input == 'parent') {
+                if (e.attr('dever-send')) {
+                    send[e.attr('dever-send')] = e.attr('dever-' + e.attr('dever-send'));
+                }
+                send.id = e.attr('dever-id');
+                send.value = e.parent().find('input').val();
+
+                if (!send.id || !send.value) {
+                    callback(config.error);
+                    return;
+                }
+            } else if (typeof(config.input) == 'string' && config.input == 'click') {
+                if (e.attr('dever-send')) {
+					var a = e.attr('dever-send').split('&');
+					for (var i in a) {
+						if (typeof(a[i]) == 'string') {
+							var b = a[i].split('=');
+							send[b[0]] = b[1];
+						}
+					}
+                }
+            } else if (typeof(config.input) == 'object') {
+                for (var i in config.input) {
+                    var option = false;
+                    var input = config.input[i];
+                    if (input.indexOf('|') != -1) {
+                        var t = input.split('|');
+                        input = t[0];
+                        option = true;
+                    }
+                    var m = true;
+                    var el = $(input);
+                    //e.get(0).tagName == 'TEXTAREA'
+                    send[i] = el.val();
+
+                    if (option == false) {
+                        if (send[i] && el.attr('dever-match')) {
+                            var r = new RegExp(el.attr('dever-match'));
+                            m = r.test(send[i]);
+                        }
+
+                        if (send[i] && el.attr('dever-value')) {
+                            m = $(el.attr('dever-value')).val() == send[i];
+                        }
+
+                        if (!send[i] || m != true) {
+                            var error = el.attr('dever-error') ? el.attr('dever-error') : config.error;
+                            callback(error);
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!send) {
+            callback(config.error);
+            return;
+        }
+        
+        if (!config.url) {
+			config.url = e.attr('dever-send');
+		}
+		
+		callback(1,1);
+		
+		config.url = Dever.CallUrl(config.url);
+
+		if (setting.proxy) {
+			$.post(config.url, send, function(t) {
+				t = eval('(' + t + ')');
+				Dever.Msg(t, callback, (config.callback ? function(msg){config.callback(e,msg,t)} : false));
+			});
+		} else {
+			$.getJSON(config.url, send, function(t) {
+				Dever.Msg(t, callback, (config.callback ? function(msg){config.callback(e,msg,t)} : false));
+			});
+		}
+    }
+};
+
+//编辑器相关
+var _Dever_Editor = 
+{
+	state : false,
+    editors : [],
+    Init : function()
+    {
+		if (typeof marked == 'function') {
+			this.state = true;
+		} else {
+			this.state = false;
+		}
+		this.SetMark();
+        var self = this;
+		
+		if ($('.dever-note').length) {
+			$('.dever-note').each(function() {
+				self.InitEditor($(this));
+			})
+        }
+	}
+
+    ,InitEditor : function(e)
+    {
+        var id = e.attr('id');
+        var key = e.attr('key');
+        if (config.uid && config.uid > 0) {
+            var toolbar = [
+              'title'
+              ,'bold'
+              ,'italic'
+              ,'underline'
+              ,'strikethrough'
+              ,'fontScale'
+              ,'color'
+              ,'ol'
+              ,'ul'
+              ,'blockquote'
+              ,'code'
+              ,'table'
+              ,'link'
+              ,'image'
+              ,'hr'
+              ,'indent'
+              ,'outdent'
+              ,'alignment'
+              //,'emoji'
+            ];
+        } else {
+            var toolbar = [
+              'title'
+              ,'bold'
+              ,'fontScale'
+              ,'color'
+              ,'ol'
+              ,'ul'
+              ,'blockquote'
+              ,'indent'
+              ,'outdent'
+              ,'alignment'
+            ];
+        }
+        
+        if (typeof(this.editors[id]) == "undefined")  {
+            this.editors[id] = new Simditor({
+                textarea: e,
+                upload:
+                {
+                    url: config.upload + '.simditor',
+                    params: {key:key},
+                    fileKey: 'file',
+                    connectionCount: 10,
+                    leaveConfirm: 'Uploading is in progress, are you sure to leave this page?'
+                },
+                toolbar : toolbar
+                /*
+                ,emoji: 
+                {
+                    imagePath: config.lib + 'simditor/plugins/emoji/images/emoji/'
+                }
+                */
+            });
+        }
+    }
+	
+	,SetMark : function()
+	{
+        return;
+	}
+	
+	,GetMark : function(content)
+	{
+		if (this.state == true) {
+			return marked(content);
+		}
+		
+		return content;
+	}
+};
+
+//模板
+var _Dever_Template = 
+{
+    state : false,
+    method : '',
+    element : '',
+    data : '',
+    param : '',
+    attr : '',
+    Init : function()
+    {
+        if (this.Check()) {
+            var url = config.proxyTemplateUrl;
+            var send = {};
+            var parsing = [];
+            $("dever").each(function(){
+                parsing.push($(this).html());
+                $(this).remove();
+            });
+            send.url = location.href;
+            send.parsing = parsing.join('');
+            send.html = $("html").html();
+            //$("html").html('dever template loading...');
+            $.ajax({
+                type: "POST",
+                url: url,
+                data: send,
+                dataType: "json",
+                success: function(result){
+                    $("html").html(result.data);
+                }
+            });
+        }
+    }
+
+    ,Check : function()
+    {
+        if ($("dever").length) {
+            this.state = true;
+        } else {
+            this.state = false;
+        }
+        return this.state;
+    }
+}

+ 202 - 0
assets/dever/share.js

@@ -0,0 +1,202 @@
+/* ================================================================================
+ * dever.js v1.0
+ * http://git.shemic.com/dever/script
+ * ================================================================================
+ * Copyright 2017-2018 Dever(dever.cc)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ================================================================================
+ */
+
+ //<filter><script src="../js/lib/jquery.min.js"></script><script src="../js/dever.js"></script></filter>
+
+
+//分享 暂时只支持手机版微信分享 请同时安装wechat组件
+var Dever_Share = 
+{
+    wechat : false,
+    url : '',
+    project : '',
+    uid : '-1',
+    param : {
+        title : '',
+        img : '',
+        desc : '',
+        url : '',
+        timelineCallback: function() {},
+        sendMessageCallback: function() {},
+        shareQQCallback: function() {}
+    },
+    Init : function(uid, project, url, param, button)
+    {
+        var self = this;
+        self.wechat = self.CheckWechat();
+        self.project = project;
+        self.url = url;
+        self.uid = uid;
+        //self.param = param;
+        $.extend(true, self.param, param)
+
+        if (button) {
+            $(button).on('click', function() {
+                if (self.wechat == 1) {
+                    self.WechatGuide();
+                } else {
+                    self.WeiboShare($(this));
+                }
+            })
+        }
+        if (self.wechat == 1) {
+            self.WechatInit();
+        }
+        self.Reflux();
+    }
+
+    ,CheckWechat : function()
+    {
+        var state = navigator.userAgent.toLowerCase().indexOf("micromessenger") > -1;
+        if (state) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    ,WechatGuide : function()
+    {
+        var param = this.param;
+        var tpl = '<div id="weixin_guide" style="position: fixed;background:url(../img/background.png) repeat;left:0;top:0;right:0;bottom:0;z-index:1000;"><img src="../img/weixin-guide.png" style="position: absolute;z-index:100;" width="295" height="273"/></div>';
+        $('#weixin_guide').remove();
+        $(tpl).attr('id', 'weixin_guide').appendTo($('body'));
+
+        $('#weixin_guide img').css(weixinCfg.style || {})
+        setTimeout(function() {
+            $('#weixin_guide').click(function() {
+                $(this).remove();
+            })
+        }, 300)
+    }
+
+    ,WechatInit: function()
+    {
+        var self = this;
+        var url = this.url + 'init?callback=?';
+        var param = this.param;
+        var project = this.project;
+        $.ajax({
+            type:'post',
+            dataType:'jsonp',
+            jsonp: 'jsonp_cb',
+            url: url,
+            data: {
+                'project' : project,
+                'url' : location.href.split('#')[0]
+            },
+            success:function(result) {
+                var data = result.data;
+                wx.config({
+                    //debug:true,
+                    appId: data.appId,
+                    timestamp: data.timestamp,
+                    nonceStr: data.nonceStr,
+                    signature: data.signature,
+                    jsApiList: [
+                        'onMenuShareTimeline',
+                        'onMenuShareAppMessage',
+                        'onMenuShareQQ'
+                    ]
+                });
+
+                wx.ready(function() {
+                    wx.onMenuShareAppMessage({
+                        title: param.title,
+                        desc: param.desc,
+                        link: param.url,
+                        imgUrl: param.img,
+                        success: function(res) {
+                            param.sendMessageCallback('success', res)
+                            self.ShareLog(1, 1);
+                        },
+                        cancel: function(res) {
+                            param.sendMessageCallback('cancel', res)
+                            self.ShareLog(1, 2);
+                        },
+                        fail: function(res) {
+                            param.sendMessageCallback('fail', res)
+                            self.ShareLog(1, 3);
+                        }
+                    });
+                    wx.onMenuShareTimeline({
+                        title: param.title,
+                        link: param.url,
+                        imgUrl: param.img,
+                        success: function(res) {
+                            param.timelineCallback('success', res)
+                            self.ShareLog(2, 1);
+                        },
+                        cancel: function(res) {
+                            param.timelineCallback('cancel', res)
+                            self.ShareLog(2, 2);
+                        },
+                        fail: function(res) {
+                            param.timelineCallback('fail', res)
+                            self.ShareLog(2, 3);
+                        }
+                    });
+                    wx.onMenuShareQQ({
+                        title: param.title,
+                        link: param.url,
+                        imgUrl: param.img,
+                        success: function(res) {
+                            param.shareQQCallback('success', res)
+                            self.ShareLog(3, 1);
+                        },
+                        cancel: function(res) {
+                            param.shareQQCallback('cancel', res)
+                            self.ShareLog(3, 2);
+                        },
+                        fail: function(res) {
+                            param.shareQQCallback('fail', res)
+                            self.ShareLog(3, 3);
+                        }
+                    });
+                });
+            },
+            async:'true',
+            timeout: 3000            
+        });
+    }
+
+    ,Reflux: function() {
+        var refer = document.referrer,
+            url = encodeURIComponent(document.location.href),
+            param = location.search.substr(1),
+            ua = encodeURIComponent(navigator.userAgent),
+            project = this.project,
+            uid = this.uid,
+            wechat = this.wechat;
+
+        if (param.indexOf("tsina-") > -1 || param.indexOf("timeline") > -1 || param.indexOf("singlemessage") > -1 || param.indexOf("groupmessage") > -1) {
+            $.getJSON(this.url + 'reflux?callback=?' + '&project='+project+'&url=' + url + '&ua=' + ua + '&param=' + encodeURIComponent(param) + '&uid=' + uid + '&type=' + wechat);
+        }
+    }
+
+    ,ShareLog: function(actType, actResult) {
+        var project = this.project;
+        var uid = this.uid;
+        var wechat = this.wechat;
+        var ua = encodeURIComponent(navigator.userAgent);
+        var url = encodeURIComponent(document.location.href);
+        $.getJSON(this.url + 'collect?callback=?' + '&project='+project+'&url=' + url + '&actType=' + actType + '&actResult=' + actResult + '&ua=' + ua + '&uid=' + uid + '&type=' + wechat);
+    }
+}

+ 3 - 0
assets/dever/template.js

@@ -0,0 +1,3 @@
+// 待续...
+var config = {};
+config.proxyTemplateUrl = 'http://192.168.15.10/dever/package/ai/?src/proxy.template?';

File diff suppressed because it is too large
+ 1 - 0
assets/lib/attach/jquery.inline-attachment.min.js


File diff suppressed because it is too large
+ 4 - 0
assets/lib/bootstrap/css/bootstrap.min.css


BIN
assets/lib/bootstrap/fonts/glyphicons-halflings-regular.eot


+ 288 - 0
assets/lib/bootstrap/fonts/glyphicons-halflings-regular.svg

@@ -0,0 +1,288 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="400" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
+<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
+<glyph unicode="&#x2000;" horiz-adv-x="650" />
+<glyph unicode="&#x2001;" horiz-adv-x="1300" />
+<glyph unicode="&#x2002;" horiz-adv-x="650" />
+<glyph unicode="&#x2003;" horiz-adv-x="1300" />
+<glyph unicode="&#x2004;" horiz-adv-x="433" />
+<glyph unicode="&#x2005;" horiz-adv-x="325" />
+<glyph unicode="&#x2006;" horiz-adv-x="216" />
+<glyph unicode="&#x2007;" horiz-adv-x="216" />
+<glyph unicode="&#x2008;" horiz-adv-x="162" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="325" />
+<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
+<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
+<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
+<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
+<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
+<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
+<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
+<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
+<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
+<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
+<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
+<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
+<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
+<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
+<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
+<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
+<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
+<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
+<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
+<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
+<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
+<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
+<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
+<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
+<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
+<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
+<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
+<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
+<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
+<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
+<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
+<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
+<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
+<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
+<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
+<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
+<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
+<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
+<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
+<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
+<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
+<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
+<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
+<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
+<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
+<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
+<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
+<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
+<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
+<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
+<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
+<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
+<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
+<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
+<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
+<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
+<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
+<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
+<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
+<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
+<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
+<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
+<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
+<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
+<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
+<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
+<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
+<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
+<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
+<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
+<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
+<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
+<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
+<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
+<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
+<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
+<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
+<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
+<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
+<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
+<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
+<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
+<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
+<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
+<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
+<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
+<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
+<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
+<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
+<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
+<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
+<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
+<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
+<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
+<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
+<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
+<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
+<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
+<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
+<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
+<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
+<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
+<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
+<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
+<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
+<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
+<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
+<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
+<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
+<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
+<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
+<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
+<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
+<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
+<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
+<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
+<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
+<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
+<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
+<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
+<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
+<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
+<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
+<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
+<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
+<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
+<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
+<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
+<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
+<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
+<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
+<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
+<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
+<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
+<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
+<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
+<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
+<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
+<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
+<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
+<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
+<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
+<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
+<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
+<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
+<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
+<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
+<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
+<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
+<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
+<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
+<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
+<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
+<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
+<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
+<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
+<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
+<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
+<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
+<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
+<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
+<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
+<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
+<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
+<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
+<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
+<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
+<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
+<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
+</font>
+</defs></svg> 

BIN
assets/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf


BIN
assets/lib/bootstrap/fonts/glyphicons-halflings-regular.woff


BIN
assets/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2


File diff suppressed because it is too large
+ 5 - 0
assets/lib/bootstrap/js/bootstrap.min.js


File diff suppressed because it is too large
+ 0 - 0
assets/lib/datetime/jquery.datetimepicker.css


File diff suppressed because it is too large
+ 9 - 0
assets/lib/datetime/jquery.datetimepicker.full.js


File diff suppressed because it is too large
+ 0 - 0
assets/lib/datetime/jquery.datetimepicker.min.js


File diff suppressed because it is too large
+ 5 - 0
assets/lib/doc/doc.min.css


File diff suppressed because it is too large
+ 16 - 0
assets/lib/doc/doc.min.js


+ 55 - 0
assets/lib/doc/main.js

@@ -0,0 +1,55 @@
+/**
+ *  处理双击编辑
+ */
+function edit()
+{
+	if($(".edit").length)
+	{
+		$(".edit").each(function()
+		{
+			$(this).bind('dblclick', function()
+			{
+				var col = $(this).attr('data-col');
+				var url = $(this).attr('data-url');
+				var id = $(this).attr('data-id');
+				var type = $(this).attr('data-type');
+				var html = $(this).text();
+				if(html.indexOf('input') == -1)
+				{
+					$(this).html('<input type="text" name="edit" id="edit" value="'+html+'">');
+					var self = $(this);
+					self.find("#edit").blur(function()
+					{
+						var value = self.find("#edit").val();
+						if(!value)
+						{
+							alert('不能为空');
+							return;
+						}
+						
+						if($(this).find(".edit-content").length)
+						{
+							$(this).find(".edit-content").html(value);
+						}
+						else
+						{
+							self.attr('data-content', value);
+						}
+						
+						self.html(value);
+						
+						$.post(url, {value:value,id:id,type:type,col:col}, function(t)
+						{
+							//notify('修改成功');
+						})
+					})
+				}
+			});
+		})
+	}
+}
+
+$(function()
+{
+	edit();
+});

File diff suppressed because it is too large
+ 0 - 0
assets/lib/echarts/echarts.common.min.js


+ 7 - 0
assets/lib/fancybox/.gitattributes

@@ -0,0 +1,7 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+*.gif binary

BIN
assets/lib/fancybox/blank.gif


BIN
assets/lib/fancybox/fancybox_loading.gif


BIN
assets/lib/fancybox/fancybox_loading@2x.gif


BIN
assets/lib/fancybox/fancybox_overlay.png


BIN
assets/lib/fancybox/fancybox_sprite.png


BIN
assets/lib/fancybox/fancybox_sprite@2x.png


BIN
assets/lib/fancybox/helpers/fancybox_buttons.png


+ 97 - 0
assets/lib/fancybox/helpers/jquery.fancybox-buttons.css

@@ -0,0 +1,97 @@
+#fancybox-buttons {
+	position: fixed;
+	left: 0;
+	width: 100%;
+	z-index: 8050;
+}
+
+#fancybox-buttons.top {
+	top: 10px;
+}
+
+#fancybox-buttons.bottom {
+	bottom: 10px;
+}
+
+#fancybox-buttons ul {
+	display: block;
+	width: 166px;
+	height: 30px;
+	margin: 0 auto;
+	padding: 0;
+	list-style: none;
+	border: 1px solid #111;
+	border-radius: 3px;
+	-webkit-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
+	   -moz-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
+	        box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
+	background: rgb(50,50,50);
+	background: -moz-linear-gradient(top, rgb(68,68,68) 0%, rgb(52,52,52) 50%, rgb(41,41,41) 50%, rgb(51,51,51) 100%);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(68,68,68)), color-stop(50%,rgb(52,52,52)), color-stop(50%,rgb(41,41,41)), color-stop(100%,rgb(51,51,51)));
+	background: -webkit-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
+	background: -o-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
+	background: -ms-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
+	background: linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 );
+}
+
+#fancybox-buttons ul li {
+	float: left;
+	margin: 0;
+	padding: 0;
+}
+
+#fancybox-buttons a {
+	display: block;
+	width: 30px;
+	height: 30px;
+	text-indent: -9999px;
+	background-color: transparent;
+	background-image: url('fancybox_buttons.png');
+	background-repeat: no-repeat;
+	outline: none;
+	opacity: 0.8;
+}
+
+#fancybox-buttons a:hover {
+	opacity: 1;
+}
+
+#fancybox-buttons a.btnPrev {
+	background-position: 5px 0;
+}
+
+#fancybox-buttons a.btnNext {
+	background-position: -33px 0;
+	border-right: 1px solid #3e3e3e;
+}
+
+#fancybox-buttons a.btnPlay {
+	background-position: 0 -30px;
+}
+
+#fancybox-buttons a.btnPlayOn {
+	background-position: -30px -30px;
+}
+
+#fancybox-buttons a.btnToggle {
+	background-position: 3px -60px;
+	border-left: 1px solid #111;
+	border-right: 1px solid #3e3e3e;
+	width: 35px
+}
+
+#fancybox-buttons a.btnToggleOn {
+	background-position: -27px -60px;
+}
+
+#fancybox-buttons a.btnClose {
+	border-left: 1px solid #111;
+	width: 35px;
+	background-position: -56px 0px;
+}
+
+#fancybox-buttons a.btnDisabled {
+	opacity : 0.4;
+	cursor: default;
+}

+ 122 - 0
assets/lib/fancybox/helpers/jquery.fancybox-buttons.js

@@ -0,0 +1,122 @@
+ /*!
+ * Buttons helper for fancyBox
+ * version: 1.0.5 (Mon, 15 Oct 2012)
+ * @requires fancyBox v2.0 or later
+ *
+ * Usage:
+ *     $(".fancybox").fancybox({
+ *         helpers : {
+ *             buttons: {
+ *                 position : 'top'
+ *             }
+ *         }
+ *     });
+ *
+ */
+(function ($) {
+	//Shortcut for fancyBox object
+	var F = $.fancybox;
+
+	//Add helper object
+	F.helpers.buttons = {
+		defaults : {
+			skipSingle : false, // disables if gallery contains single image
+			position   : 'top', // 'top' or 'bottom'
+			tpl        : '<div id="fancybox-buttons"><ul><li><a class="btnPrev" title="Previous" href="javascript:;"></a></li><li><a class="btnPlay" title="Start slideshow" href="javascript:;"></a></li><li><a class="btnNext" title="Next" href="javascript:;"></a></li><li><a class="btnToggle" title="Toggle size" href="javascript:;"></a></li><li><a class="btnClose" title="Close" href="javascript:;"></a></li></ul></div>'
+		},
+
+		list : null,
+		buttons: null,
+
+		beforeLoad: function (opts, obj) {
+			//Remove self if gallery do not have at least two items
+
+			if (opts.skipSingle && obj.group.length < 2) {
+				obj.helpers.buttons = false;
+				obj.closeBtn = true;
+
+				return;
+			}
+
+			//Increase top margin to give space for buttons
+			obj.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30;
+		},
+
+		onPlayStart: function () {
+			if (this.buttons) {
+				this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn');
+			}
+		},
+
+		onPlayEnd: function () {
+			if (this.buttons) {
+				this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn');
+			}
+		},
+
+		afterShow: function (opts, obj) {
+			var buttons = this.buttons;
+
+			if (!buttons) {
+				this.list = $(opts.tpl).addClass(opts.position).appendTo('body');
+
+				buttons = {
+					prev   : this.list.find('.btnPrev').click( F.prev ),
+					next   : this.list.find('.btnNext').click( F.next ),
+					play   : this.list.find('.btnPlay').click( F.play ),
+					toggle : this.list.find('.btnToggle').click( F.toggle ),
+					close  : this.list.find('.btnClose').click( F.close )
+				}
+			}
+
+			//Prev
+			if (obj.index > 0 || obj.loop) {
+				buttons.prev.removeClass('btnDisabled');
+			} else {
+				buttons.prev.addClass('btnDisabled');
+			}
+
+			//Next / Play
+			if (obj.loop || obj.index < obj.group.length - 1) {
+				buttons.next.removeClass('btnDisabled');
+				buttons.play.removeClass('btnDisabled');
+
+			} else {
+				buttons.next.addClass('btnDisabled');
+				buttons.play.addClass('btnDisabled');
+			}
+
+			this.buttons = buttons;
+
+			this.onUpdate(opts, obj);
+		},
+
+		onUpdate: function (opts, obj) {
+			var toggle;
+
+			if (!this.buttons) {
+				return;
+			}
+
+			toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn');
+
+			//Size toggle button
+			if (obj.canShrink) {
+				toggle.addClass('btnToggleOn');
+
+			} else if (!obj.canExpand) {
+				toggle.addClass('btnDisabled');
+			}
+		},
+
+		beforeClose: function () {
+			if (this.list) {
+				this.list.remove();
+			}
+
+			this.list    = null;
+			this.buttons = null;
+		}
+	};
+
+}(jQuery));

+ 199 - 0
assets/lib/fancybox/helpers/jquery.fancybox-media.js

@@ -0,0 +1,199 @@
+/*!
+ * Media helper for fancyBox
+ * version: 1.0.6 (Fri, 14 Jun 2013)
+ * @requires fancyBox v2.0 or later
+ *
+ * Usage:
+ *     $(".fancybox").fancybox({
+ *         helpers : {
+ *             media: true
+ *         }
+ *     });
+ *
+ * Set custom URL parameters:
+ *     $(".fancybox").fancybox({
+ *         helpers : {
+ *             media: {
+ *                 youtube : {
+ *                     params : {
+ *                         autoplay : 0
+ *                     }
+ *                 }
+ *             }
+ *         }
+ *     });
+ *
+ * Or:
+ *     $(".fancybox").fancybox({,
+ *         helpers : {
+ *             media: true
+ *         },
+ *         youtube : {
+ *             autoplay: 0
+ *         }
+ *     });
+ *
+ *  Supports:
+ *
+ *      Youtube
+ *          http://www.youtube.com/watch?v=opj24KnzrWo
+ *          http://www.youtube.com/embed/opj24KnzrWo
+ *          http://youtu.be/opj24KnzrWo
+ *			http://www.youtube-nocookie.com/embed/opj24KnzrWo
+ *      Vimeo
+ *          http://vimeo.com/40648169
+ *          http://vimeo.com/channels/staffpicks/38843628
+ *          http://vimeo.com/groups/surrealism/videos/36516384
+ *          http://player.vimeo.com/video/45074303
+ *      Metacafe
+ *          http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/
+ *          http://www.metacafe.com/watch/7635964/
+ *      Dailymotion
+ *          http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people
+ *      Twitvid
+ *          http://twitvid.com/QY7MD
+ *      Twitpic
+ *          http://twitpic.com/7p93st
+ *      Instagram
+ *          http://instagr.am/p/IejkuUGxQn/
+ *          http://instagram.com/p/IejkuUGxQn/
+ *      Google maps
+ *          http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17
+ *          http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
+ *          http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56
+ */
+(function ($) {
+	"use strict";
+
+	//Shortcut for fancyBox object
+	var F = $.fancybox,
+		format = function( url, rez, params ) {
+			params = params || '';
+
+			if ( $.type( params ) === "object" ) {
+				params = $.param(params, true);
+			}
+
+			$.each(rez, function(key, value) {
+				url = url.replace( '$' + key, value || '' );
+			});
+
+			if (params.length) {
+				url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params;
+			}
+
+			return url;
+		};
+
+	//Add helper object
+	F.helpers.media = {
+		defaults : {
+			youtube : {
+				matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i,
+				params  : {
+					autoplay    : 1,
+					autohide    : 1,
+					fs          : 1,
+					rel         : 0,
+					hd          : 1,
+					wmode       : 'opaque',
+					enablejsapi : 1
+				},
+				type : 'iframe',
+				url  : '//www.youtube.com/embed/$3'
+			},
+			vimeo : {
+				matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/,
+				params  : {
+					autoplay      : 1,
+					hd            : 1,
+					show_title    : 1,
+					show_byline   : 1,
+					show_portrait : 0,
+					fullscreen    : 1
+				},
+				type : 'iframe',
+				url  : '//player.vimeo.com/video/$1'
+			},
+			metacafe : {
+				matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/,
+				params  : {
+					autoPlay : 'yes'
+				},
+				type : 'swf',
+				url  : function( rez, params, obj ) {
+					obj.swf.flashVars = 'playerVars=' + $.param( params, true );
+
+					return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf';
+				}
+			},
+			dailymotion : {
+				matcher : /dailymotion.com\/video\/(.*)\/?(.*)/,
+				params  : {
+					additionalInfos : 0,
+					autoStart : 1
+				},
+				type : 'swf',
+				url  : '//www.dailymotion.com/swf/video/$1'
+			},
+			twitvid : {
+				matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i,
+				params  : {
+					autoplay : 0
+				},
+				type : 'iframe',
+				url  : '//www.twitvid.com/embed.php?guid=$1'
+			},
+			twitpic : {
+				matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i,
+				type : 'image',
+				url  : '//twitpic.com/show/full/$1/'
+			},
+			instagram : {
+				matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
+				type : 'image',
+				url  : '//$1/p/$2/media/?size=l'
+			},
+			google_maps : {
+				matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i,
+				type : 'iframe',
+				url  : function( rez ) {
+					return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed');
+				}
+			}
+		},
+
+		beforeLoad : function(opts, obj) {
+			var url   = obj.href || '',
+				type  = false,
+				what,
+				item,
+				rez,
+				params;
+
+			for (what in opts) {
+				if (opts.hasOwnProperty(what)) {
+					item = opts[ what ];
+					rez  = url.match( item.matcher );
+
+					if (rez) {
+						type   = item.type;
+						params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null));
+
+						url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params );
+
+						break;
+					}
+				}
+			}
+
+			if (type) {
+				obj.href = url;
+				obj.type = type;
+
+				obj.autoHeight = false;
+			}
+		}
+	};
+
+}(jQuery));

+ 55 - 0
assets/lib/fancybox/helpers/jquery.fancybox-thumbs.css

@@ -0,0 +1,55 @@
+#fancybox-thumbs {
+	position: fixed;
+	left: 0;
+	width: 100%;
+	overflow: hidden;
+	z-index: 8050;
+}
+
+#fancybox-thumbs.bottom {
+	bottom: 2px;
+}
+
+#fancybox-thumbs.top {
+	top: 2px;
+}
+
+#fancybox-thumbs ul {
+	position: relative;
+	list-style: none;
+	margin: 0;
+	padding: 0;
+}
+
+#fancybox-thumbs ul li {
+	float: left;
+	padding: 1px;
+	opacity: 0.5;
+}
+
+#fancybox-thumbs ul li.active {
+	opacity: 0.75;
+	padding: 0;
+	border: 1px solid #fff;
+}
+
+#fancybox-thumbs ul li:hover {
+	opacity: 1;
+}
+
+#fancybox-thumbs ul li a {
+	display: block;
+	position: relative;
+	overflow: hidden;
+	border: 1px solid #222;
+	background: #111;
+	outline: none;
+}
+
+#fancybox-thumbs ul li img {
+	display: block;
+	position: relative;
+	border: 0;
+	padding: 0;
+	max-width: none;
+}

+ 162 - 0
assets/lib/fancybox/helpers/jquery.fancybox-thumbs.js

@@ -0,0 +1,162 @@
+ /*!
+ * Thumbnail helper for fancyBox
+ * version: 1.0.7 (Mon, 01 Oct 2012)
+ * @requires fancyBox v2.0 or later
+ *
+ * Usage:
+ *     $(".fancybox").fancybox({
+ *         helpers : {
+ *             thumbs: {
+ *                 width  : 50,
+ *                 height : 50
+ *             }
+ *         }
+ *     });
+ *
+ */
+(function ($) {
+	//Shortcut for fancyBox object
+	var F = $.fancybox;
+
+	//Add helper object
+	F.helpers.thumbs = {
+		defaults : {
+			width    : 50,       // thumbnail width
+			height   : 50,       // thumbnail height
+			position : 'bottom', // 'top' or 'bottom'
+			source   : function ( item ) {  // function to obtain the URL of the thumbnail image
+				var href;
+
+				if (item.element) {
+					href = $(item.element).find('img').attr('src');
+				}
+
+				if (!href && item.type === 'image' && item.href) {
+					href = item.href;
+				}
+
+				return href;
+			}
+		},
+
+		wrap  : null,
+		list  : null,
+		width : 0,
+
+		init: function (opts, obj) {
+			var that = this,
+				list,
+				thumbWidth  = opts.width,
+				thumbHeight = opts.height,
+				thumbSource = opts.source;
+
+			//Build list structure
+			list = '';
+
+			for (var n = 0; n < obj.group.length; n++) {
+				list += '<li><a style="width:' + thumbWidth + 'px;height:' + thumbHeight + 'px;" href="javascript:jQuery.fancybox.jumpto(' + n + ');"></a></li>';
+			}
+
+			this.wrap = $('<div id="fancybox-thumbs"></div>').addClass(opts.position).appendTo('body');
+			this.list = $('<ul>' + list + '</ul>').appendTo(this.wrap);
+
+			//Load each thumbnail
+			$.each(obj.group, function (i) {
+				var href = thumbSource( obj.group[ i ] );
+
+				if (!href) {
+					return;
+				}
+
+				$("<img />").load(function () {
+					var width  = this.width,
+						height = this.height,
+						widthRatio, heightRatio, parent;
+
+					if (!that.list || !width || !height) {
+						return;
+					}
+
+					//Calculate thumbnail width/height and center it
+					widthRatio  = width / thumbWidth;
+					heightRatio = height / thumbHeight;
+
+					parent = that.list.children().eq(i).find('a');
+
+					if (widthRatio >= 1 && heightRatio >= 1) {
+						if (widthRatio > heightRatio) {
+							width  = Math.floor(width / heightRatio);
+							height = thumbHeight;
+
+						} else {
+							width  = thumbWidth;
+							height = Math.floor(height / widthRatio);
+						}
+					}
+
+					$(this).css({
+						width  : width,
+						height : height,
+						top    : Math.floor(thumbHeight / 2 - height / 2),
+						left   : Math.floor(thumbWidth / 2 - width / 2)
+					});
+
+					parent.width(thumbWidth).height(thumbHeight);
+
+					$(this).hide().appendTo(parent).fadeIn(300);
+
+				}).attr('src', href);
+			});
+
+			//Set initial width
+			this.width = this.list.children().eq(0).outerWidth(true);
+
+			this.list.width(this.width * (obj.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5)));
+		},
+
+		beforeLoad: function (opts, obj) {
+			//Remove self if gallery do not have at least two items
+			if (obj.group.length < 2) {
+				obj.helpers.thumbs = false;
+
+				return;
+			}
+
+			//Increase bottom margin to give space for thumbs
+			obj.margin[ opts.position === 'top' ? 0 : 2 ] += ((opts.height) + 15);
+		},
+
+		afterShow: function (opts, obj) {
+			//Check if exists and create or update list
+			if (this.list) {
+				this.onUpdate(opts, obj);
+
+			} else {
+				this.init(opts, obj);
+			}
+
+			//Set active element
+			this.list.children().removeClass('active').eq(obj.index).addClass('active');
+		},
+
+		//Center list
+		onUpdate: function (opts, obj) {
+			if (this.list) {
+				this.list.stop(true).animate({
+					'left': Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5))
+				}, 150);
+			}
+		},
+
+		beforeClose: function () {
+			if (this.wrap) {
+				this.wrap.remove();
+			}
+
+			this.wrap  = null;
+			this.list  = null;
+			this.width = 0;
+		}
+	}
+
+}(jQuery));

+ 274 - 0
assets/lib/fancybox/jquery.fancybox.css

@@ -0,0 +1,274 @@
+/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
+.fancybox-wrap,
+.fancybox-skin,
+.fancybox-outer,
+.fancybox-inner,
+.fancybox-image,
+.fancybox-wrap iframe,
+.fancybox-wrap object,
+.fancybox-nav,
+.fancybox-nav span,
+.fancybox-tmp
+{
+	padding: 0;
+	margin: 0;
+	border: 0;
+	outline: none;
+	vertical-align: top;
+}
+
+.fancybox-wrap {
+	position: absolute;
+	top: 0;
+	left: 0;
+	z-index: 8020;
+}
+
+.fancybox-skin {
+	position: relative;
+	background: #f9f9f9;
+	color: #444;
+	text-shadow: none;
+	-webkit-border-radius: 4px;
+	   -moz-border-radius: 4px;
+	        border-radius: 4px;
+}
+
+.fancybox-opened {
+	z-index: 8030;
+}
+
+.fancybox-opened .fancybox-skin {
+	-webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+	   -moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+	        box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+}
+
+.fancybox-outer, .fancybox-inner {
+	position: relative;
+}
+
+.fancybox-inner {
+	overflow: hidden;
+}
+
+.fancybox-type-iframe .fancybox-inner {
+	-webkit-overflow-scrolling: touch;
+}
+
+.fancybox-error {
+	color: #444;
+	font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
+	margin: 0;
+	padding: 15px;
+	white-space: nowrap;
+}
+
+.fancybox-image, .fancybox-iframe {
+	display: block;
+	width: 100%;
+	height: 100%;
+}
+
+.fancybox-image {
+	max-width: 100%;
+	max-height: 100%;
+}
+
+#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span {
+	background-image: url('fancybox_sprite.png');
+}
+
+#fancybox-loading {
+	position: fixed;
+	top: 50%;
+	left: 50%;
+	margin-top: -22px;
+	margin-left: -22px;
+	background-position: 0 -108px;
+	opacity: 0.8;
+	cursor: pointer;
+	z-index: 8060;
+}
+
+#fancybox-loading div {
+	width: 44px;
+	height: 44px;
+	background: url('fancybox_loading.gif') center center no-repeat;
+}
+
+.fancybox-close {
+	position: absolute;
+	top: -18px;
+	right: -18px;
+	width: 36px;
+	height: 36px;
+	cursor: pointer;
+	z-index: 8040;
+}
+
+.fancybox-nav {
+	position: absolute;
+	top: 0;
+	width: 40%;
+	height: 100%;
+	cursor: pointer;
+	text-decoration: none;
+	background: transparent url('blank.gif'); /* helps IE */
+	-webkit-tap-highlight-color: rgba(0,0,0,0);
+	z-index: 8040;
+}
+
+.fancybox-prev {
+	left: 0;
+}
+
+.fancybox-next {
+	right: 0;
+}
+
+.fancybox-nav span {
+	position: absolute;
+	top: 50%;
+	width: 36px;
+	height: 34px;
+	margin-top: -18px;
+	cursor: pointer;
+	z-index: 8040;
+	visibility: hidden;
+}
+
+.fancybox-prev span {
+	left: 10px;
+	background-position: 0 -36px;
+}
+
+.fancybox-next span {
+	right: 10px;
+	background-position: 0 -72px;
+}
+
+.fancybox-nav:hover span {
+	visibility: visible;
+}
+
+.fancybox-tmp {
+	position: absolute;
+	top: -99999px;
+	left: -99999px;
+	visibility: hidden;
+	max-width: 99999px;
+	max-height: 99999px;
+	overflow: visible !important;
+}
+
+/* Overlay helper */
+
+.fancybox-lock {
+    overflow: hidden !important;
+    width: auto;
+}
+
+.fancybox-lock body {
+    overflow: hidden !important;
+}
+
+.fancybox-lock-test {
+    overflow-y: hidden !important;
+}
+
+.fancybox-overlay {
+	position: absolute;
+	top: 0;
+	left: 0;
+	overflow: hidden;
+	display: none;
+	z-index: 8010;
+	background: url('fancybox_overlay.png');
+}
+
+.fancybox-overlay-fixed {
+	position: fixed;
+	bottom: 0;
+	right: 0;
+}
+
+.fancybox-lock .fancybox-overlay {
+	overflow: auto;
+	overflow-y: scroll;
+}
+
+/* Title helper */
+
+.fancybox-title {
+	visibility: hidden;
+	font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
+	position: relative;
+	text-shadow: none;
+	z-index: 8050;
+}
+
+.fancybox-opened .fancybox-title {
+	visibility: visible;
+}
+
+.fancybox-title-float-wrap {
+	position: absolute;
+	bottom: 0;
+	right: 50%;
+	margin-bottom: -35px;
+	z-index: 8050;
+	text-align: center;
+}
+
+.fancybox-title-float-wrap .child {
+	display: inline-block;
+	margin-right: -100%;
+	padding: 2px 20px;
+	background: transparent; /* Fallback for web browsers that doesn't support RGBa */
+	background: rgba(0, 0, 0, 0.8);
+	-webkit-border-radius: 15px;
+	   -moz-border-radius: 15px;
+	        border-radius: 15px;
+	text-shadow: 0 1px 2px #222;
+	color: #FFF;
+	font-weight: bold;
+	line-height: 24px;
+	white-space: nowrap;
+}
+
+.fancybox-title-outside-wrap {
+	position: relative;
+	margin-top: 10px;
+	color: #fff;
+}
+
+.fancybox-title-inside-wrap {
+	padding-top: 10px;
+}
+
+.fancybox-title-over-wrap {
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	color: #fff;
+	padding: 10px;
+	background: #000;
+	background: rgba(0, 0, 0, .8);
+}
+
+/*Retina graphics!*/
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
+	   only screen and (min--moz-device-pixel-ratio: 1.5),
+	   only screen and (min-device-pixel-ratio: 1.5){
+
+	#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span {
+		background-image: url('fancybox_sprite@2x.png');
+		background-size: 44px 152px; /*The size of the normal image, half the size of the hi-res image*/
+	}
+
+	#fancybox-loading div {
+		background-image: url('fancybox_loading@2x.gif');
+		background-size: 24px 24px; /*The size of the normal image, half the size of the hi-res image*/
+	}
+}

+ 2020 - 0
assets/lib/fancybox/jquery.fancybox.js

@@ -0,0 +1,2020 @@
+/*!
+ * fancyBox - jQuery Plugin
+ * version: 2.1.5 (Fri, 14 Jun 2013)
+ * @requires jQuery v1.6 or later
+ *
+ * Examples at http://fancyapps.com/fancybox/
+ * License: www.fancyapps.com/fancybox/#license
+ *
+ * Copyright 2012 Janis Skarnelis - janis@fancyapps.com
+ *
+ */
+
+(function (window, document, $, undefined) {
+	"use strict";
+
+	var H = $("html"),
+		W = $(window),
+		D = $(document),
+		F = $.fancybox = function () {
+			F.open.apply( this, arguments );
+		},
+		IE =  navigator.userAgent.match(/msie/i),
+		didUpdate	= null,
+		isTouch		= document.createTouch !== undefined,
+
+		isQuery	= function(obj) {
+			return obj && obj.hasOwnProperty && obj instanceof $;
+		},
+		isString = function(str) {
+			return str && $.type(str) === "string";
+		},
+		isPercentage = function(str) {
+			return isString(str) && str.indexOf('%') > 0;
+		},
+		isScrollable = function(el) {
+			return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
+		},
+		getScalar = function(orig, dim) {
+			var value = parseInt(orig, 10) || 0;
+
+			if (dim && isPercentage(orig)) {
+				value = F.getViewport()[ dim ] / 100 * value;
+			}
+
+			return Math.ceil(value);
+		},
+		getValue = function(value, dim) {
+			return getScalar(value, dim) + 'px';
+		};
+
+	$.extend(F, {
+		// The current version of fancyBox
+		version: '2.1.5',
+
+		defaults: {
+			padding : 15,
+			margin  : 20,
+
+			width     : 800,
+			height    : 600,
+			minWidth  : 100,
+			minHeight : 100,
+			maxWidth  : 9999,
+			maxHeight : 9999,
+			pixelRatio: 1, // Set to 2 for retina display support
+
+			autoSize   : true,
+			autoHeight : false,
+			autoWidth  : false,
+
+			autoResize  : true,
+			autoCenter  : !isTouch,
+			fitToView   : true,
+			aspectRatio : false,
+			topRatio    : 0.5,
+			leftRatio   : 0.5,
+
+			scrolling : 'auto', // 'auto', 'yes' or 'no'
+			wrapCSS   : '',
+
+			arrows     : true,
+			closeBtn   : true,
+			closeClick : false,
+			nextClick  : false,
+			mouseWheel : true,
+			autoPlay   : false,
+			playSpeed  : 3000,
+			preload    : 3,
+			modal      : false,
+			loop       : true,
+
+			ajax  : {
+				dataType : 'html',
+				headers  : { 'X-fancyBox': true }
+			},
+			iframe : {
+				scrolling : 'auto',
+				preload   : true
+			},
+			swf : {
+				wmode: 'transparent',
+				allowfullscreen   : 'true',
+				allowscriptaccess : 'always'
+			},
+
+			keys  : {
+				next : {
+					13 : 'left', // enter
+					34 : 'up',   // page down
+					39 : 'left', // right arrow
+					40 : 'up'    // down arrow
+				},
+				prev : {
+					8  : 'right',  // backspace
+					33 : 'down',   // page up
+					37 : 'right',  // left arrow
+					38 : 'down'    // up arrow
+				},
+				close  : [27], // escape key
+				play   : [32], // space - start/stop slideshow
+				toggle : [70]  // letter "f" - toggle fullscreen
+			},
+
+			direction : {
+				next : 'left',
+				prev : 'right'
+			},
+
+			scrollOutside  : true,
+
+			// Override some properties
+			index   : 0,
+			type    : null,
+			href    : null,
+			content : null,
+			title   : null,
+
+			// HTML templates
+			tpl: {
+				wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
+				image    : '<img class="fancybox-image" src="{href}" alt="" />',
+				iframe   : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
+				error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
+				closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
+				next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
+				prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
+			},
+
+			// Properties for each animation type
+			// Opening fancyBox
+			openEffect  : 'fade', // 'elastic', 'fade' or 'none'
+			openSpeed   : 250,
+			openEasing  : 'swing',
+			openOpacity : true,
+			openMethod  : 'zoomIn',
+
+			// Closing fancyBox
+			closeEffect  : 'fade', // 'elastic', 'fade' or 'none'
+			closeSpeed   : 250,
+			closeEasing  : 'swing',
+			closeOpacity : true,
+			closeMethod  : 'zoomOut',
+
+			// Changing next gallery item
+			nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
+			nextSpeed  : 250,
+			nextEasing : 'swing',
+			nextMethod : 'changeIn',
+
+			// Changing previous gallery item
+			prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
+			prevSpeed  : 250,
+			prevEasing : 'swing',
+			prevMethod : 'changeOut',
+
+			// Enable default helpers
+			helpers : {
+				overlay : true,
+				title   : true
+			},
+
+			// Callbacks
+			onCancel     : $.noop, // If canceling
+			beforeLoad   : $.noop, // Before loading
+			afterLoad    : $.noop, // After loading
+			beforeShow   : $.noop, // Before changing in current item
+			afterShow    : $.noop, // After opening
+			beforeChange : $.noop, // Before changing gallery item
+			beforeClose  : $.noop, // Before closing
+			afterClose   : $.noop  // After closing
+		},
+
+		//Current state
+		group    : {}, // Selected group
+		opts     : {}, // Group options
+		previous : null,  // Previous element
+		coming   : null,  // Element being loaded
+		current  : null,  // Currently loaded element
+		isActive : false, // Is activated
+		isOpen   : false, // Is currently open
+		isOpened : false, // Have been fully opened at least once
+
+		wrap  : null,
+		skin  : null,
+		outer : null,
+		inner : null,
+
+		player : {
+			timer    : null,
+			isActive : false
+		},
+
+		// Loaders
+		ajaxLoad   : null,
+		imgPreload : null,
+
+		// Some collections
+		transitions : {},
+		helpers     : {},
+
+		/*
+		 *	Static methods
+		 */
+
+		open: function (group, opts) {
+			if (!group) {
+				return;
+			}
+
+			if (!$.isPlainObject(opts)) {
+				opts = {};
+			}
+
+			// Close if already active
+			if (false === F.close(true)) {
+				return;
+			}
+
+			// Normalize group
+			if (!$.isArray(group)) {
+				group = isQuery(group) ? $(group).get() : [group];
+			}
+
+			// Recheck if the type of each element is `object` and set content type (image, ajax, etc)
+			$.each(group, function(i, element) {
+				var obj = {},
+					href,
+					title,
+					content,
+					type,
+					rez,
+					hrefParts,
+					selector;
+
+				if ($.type(element) === "object") {
+					// Check if is DOM element
+					if (element.nodeType) {
+						element = $(element);
+					}
+
+					if (isQuery(element)) {
+						obj = {
+							href    : element.data('fancybox-href') || element.attr('href'),
+							title   : element.data('fancybox-title') || element.attr('title'),
+							isDom   : true,
+							element : element
+						};
+
+						if ($.metadata) {
+							$.extend(true, obj, element.metadata());
+						}
+
+					} else {
+						obj = element;
+					}
+				}
+
+				href  = opts.href  || obj.href || (isString(element) ? element : null);
+				title = opts.title !== undefined ? opts.title : obj.title || '';
+
+				content = opts.content || obj.content;
+				type    = content ? 'html' : (opts.type  || obj.type);
+
+				if (!type && obj.isDom) {
+					type = element.data('fancybox-type');
+
+					if (!type) {
+						rez  = element.prop('class').match(/fancybox\.(\w+)/);
+						type = rez ? rez[1] : null;
+					}
+				}
+
+				if (isString(href)) {
+					// Try to guess the content type
+					if (!type) {
+						if (F.isImage(href)) {
+							type = 'image';
+
+						} else if (F.isSWF(href)) {
+							type = 'swf';
+
+						} else if (href.charAt(0) === '#') {
+							type = 'inline';
+
+						} else if (isString(element)) {
+							type    = 'html';
+							content = element;
+						}
+					}
+
+					// Split url into two pieces with source url and content selector, e.g,
+					// "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
+					if (type === 'ajax') {
+						hrefParts = href.split(/\s+/, 2);
+						href      = hrefParts.shift();
+						selector  = hrefParts.shift();
+					}
+				}
+
+				if (!content) {
+					if (type === 'inline') {
+						if (href) {
+							content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
+
+						} else if (obj.isDom) {
+							content = element;
+						}
+
+					} else if (type === 'html') {
+						content = href;
+
+					} else if (!type && !href && obj.isDom) {
+						type    = 'inline';
+						content = element;
+					}
+				}
+
+				$.extend(obj, {
+					href     : href,
+					type     : type,
+					content  : content,
+					title    : title,
+					selector : selector
+				});
+
+				group[ i ] = obj;
+			});
+
+			// Extend the defaults
+			F.opts = $.extend(true, {}, F.defaults, opts);
+
+			// All options are merged recursive except keys
+			if (opts.keys !== undefined) {
+				F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
+			}
+
+			F.group = group;
+
+			return F._start(F.opts.index);
+		},
+
+		// Cancel image loading or abort ajax request
+		cancel: function () {
+			var coming = F.coming;
+
+			if (!coming || false === F.trigger('onCancel')) {
+				return;
+			}
+
+			F.hideLoading();
+
+			if (F.ajaxLoad) {
+				F.ajaxLoad.abort();
+			}
+
+			F.ajaxLoad = null;
+
+			if (F.imgPreload) {
+				F.imgPreload.onload = F.imgPreload.onerror = null;
+			}
+
+			if (coming.wrap) {
+				coming.wrap.stop(true, true).trigger('onReset').remove();
+			}
+
+			F.coming = null;
+
+			// If the first item has been canceled, then clear everything
+			if (!F.current) {
+				F._afterZoomOut( coming );
+			}
+		},
+
+		// Start closing animation if is open; remove immediately if opening/closing
+		close: function (event) {
+			F.cancel();
+
+			if (false === F.trigger('beforeClose')) {
+				return;
+			}
+
+			F.unbindEvents();
+
+			if (!F.isActive) {
+				return;
+			}
+
+			if (!F.isOpen || event === true) {
+				$('.fancybox-wrap').stop(true).trigger('onReset').remove();
+
+				F._afterZoomOut();
+
+			} else {
+				F.isOpen = F.isOpened = false;
+				F.isClosing = true;
+
+				$('.fancybox-item, .fancybox-nav').remove();
+
+				F.wrap.stop(true, true).removeClass('fancybox-opened');
+
+				F.transitions[ F.current.closeMethod ]();
+			}
+		},
+
+		// Manage slideshow:
+		//   $.fancybox.play(); - toggle slideshow
+		//   $.fancybox.play( true ); - start
+		//   $.fancybox.play( false ); - stop
+		play: function ( action ) {
+			var clear = function () {
+					clearTimeout(F.player.timer);
+				},
+				set = function () {
+					clear();
+
+					if (F.current && F.player.isActive) {
+						F.player.timer = setTimeout(F.next, F.current.playSpeed);
+					}
+				},
+				stop = function () {
+					clear();
+
+					D.unbind('.player');
+
+					F.player.isActive = false;
+
+					F.trigger('onPlayEnd');
+				},
+				start = function () {
+					if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
+						F.player.isActive = true;
+
+						D.bind({
+							'onCancel.player beforeClose.player' : stop,
+							'onUpdate.player'   : set,
+							'beforeLoad.player' : clear
+						});
+
+						set();
+
+						F.trigger('onPlayStart');
+					}
+				};
+
+			if (action === true || (!F.player.isActive && action !== false)) {
+				start();
+			} else {
+				stop();
+			}
+		},
+
+		// Navigate to next gallery item
+		next: function ( direction ) {
+			var current = F.current;
+
+			if (current) {
+				if (!isString(direction)) {
+					direction = current.direction.next;
+				}
+
+				F.jumpto(current.index + 1, direction, 'next');
+			}
+		},
+
+		// Navigate to previous gallery item
+		prev: function ( direction ) {
+			var current = F.current;
+
+			if (current) {
+				if (!isString(direction)) {
+					direction = current.direction.prev;
+				}
+
+				F.jumpto(current.index - 1, direction, 'prev');
+			}
+		},
+
+		// Navigate to gallery item by index
+		jumpto: function ( index, direction, router ) {
+			var current = F.current;
+
+			if (!current) {
+				return;
+			}
+
+			index = getScalar(index);
+
+			F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
+			F.router    = router || 'jumpto';
+
+			if (current.loop) {
+				if (index < 0) {
+					index = current.group.length + (index % current.group.length);
+				}
+
+				index = index % current.group.length;
+			}
+
+			if (current.group[ index ] !== undefined) {
+				F.cancel();
+
+				F._start(index);
+			}
+		},
+
+		// Center inside viewport and toggle position type to fixed or absolute if needed
+		reposition: function (e, onlyAbsolute) {
+			var current = F.current,
+				wrap    = current ? current.wrap : null,
+				pos;
+
+			if (wrap) {
+				pos = F._getPosition(onlyAbsolute);
+
+				if (e && e.type === 'scroll') {
+					delete pos.position;
+
+					wrap.stop(true, true).animate(pos, 200);
+
+				} else {
+					wrap.css(pos);
+
+					current.pos = $.extend({}, current.dim, pos);
+				}
+			}
+		},
+
+		update: function (e) {
+			var type = (e && e.type),
+				anyway = !type || type === 'orientationchange';
+
+			if (anyway) {
+				clearTimeout(didUpdate);
+
+				didUpdate = null;
+			}
+
+			if (!F.isOpen || didUpdate) {
+				return;
+			}
+
+			didUpdate = setTimeout(function() {
+				var current = F.current;
+
+				if (!current || F.isClosing) {
+					return;
+				}
+
+				F.wrap.removeClass('fancybox-tmp');
+
+				if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
+					F._setDimension();
+				}
+
+				if (!(type === 'scroll' && current.canShrink)) {
+					F.reposition(e);
+				}
+
+				F.trigger('onUpdate');
+
+				didUpdate = null;
+
+			}, (anyway && !isTouch ? 0 : 300));
+		},
+
+		// Shrink content to fit inside viewport or restore if resized
+		toggle: function ( action ) {
+			if (F.isOpen) {
+				F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
+
+				// Help browser to restore document dimensions
+				if (isTouch) {
+					F.wrap.removeAttr('style').addClass('fancybox-tmp');
+
+					F.trigger('onUpdate');
+				}
+
+				F.update();
+			}
+		},
+
+		hideLoading: function () {
+			D.unbind('.loading');
+
+			$('#fancybox-loading').remove();
+		},
+
+		showLoading: function () {
+			var el, viewport;
+
+			F.hideLoading();
+
+			el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
+
+			// If user will press the escape-button, the request will be canceled
+			D.bind('keydown.loading', function(e) {
+				if ((e.which || e.keyCode) === 27) {
+					e.preventDefault();
+
+					F.cancel();
+				}
+			});
+
+			if (!F.defaults.fixed) {
+				viewport = F.getViewport();
+
+				el.css({
+					position : 'absolute',
+					top  : (viewport.h * 0.5) + viewport.y,
+					left : (viewport.w * 0.5) + viewport.x
+				});
+			}
+		},
+
+		getViewport: function () {
+			var locked = (F.current && F.current.locked) || false,
+				rez    = {
+					x: W.scrollLeft(),
+					y: W.scrollTop()
+				};
+
+			if (locked) {
+				rez.w = locked[0].clientWidth;
+				rez.h = locked[0].clientHeight;
+
+			} else {
+				// See http://bugs.jquery.com/ticket/6724
+				rez.w = isTouch && window.innerWidth  ? window.innerWidth  : W.width();
+				rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
+			}
+
+			return rez;
+		},
+
+		// Unbind the keyboard / clicking actions
+		unbindEvents: function () {
+			if (F.wrap && isQuery(F.wrap)) {
+				F.wrap.unbind('.fb');
+			}
+
+			D.unbind('.fb');
+			W.unbind('.fb');
+		},
+
+		bindEvents: function () {
+			var current = F.current,
+				keys;
+
+			if (!current) {
+				return;
+			}
+
+			// Changing document height on iOS devices triggers a 'resize' event,
+			// that can change document height... repeating infinitely
+			W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
+
+			keys = current.keys;
+
+			if (keys) {
+				D.bind('keydown.fb', function (e) {
+					var code   = e.which || e.keyCode,
+						target = e.target || e.srcElement;
+
+					// Skip esc key if loading, because showLoading will cancel preloading
+					if (code === 27 && F.coming) {
+						return false;
+					}
+
+					// Ignore key combinations and key events within form elements
+					if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
+						$.each(keys, function(i, val) {
+							if (current.group.length > 1 && val[ code ] !== undefined) {
+								F[ i ]( val[ code ] );
+
+								e.preventDefault();
+								return false;
+							}
+
+							if ($.inArray(code, val) > -1) {
+								F[ i ] ();
+
+								e.preventDefault();
+								return false;
+							}
+						});
+					}
+				});
+			}
+
+			if ($.fn.mousewheel && current.mouseWheel) {
+				F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
+					var target = e.target || null,
+						parent = $(target),
+						canScroll = false;
+
+					while (parent.length) {
+						if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {
+							break;
+						}
+
+						canScroll = isScrollable( parent[0] );
+						parent    = $(parent).parent();
+					}
+
+					if (delta !== 0 && !canScroll) {
+						if (F.group.length > 1 && !current.canShrink) {
+							if (deltaY > 0 || deltaX > 0) {
+								F.prev( deltaY > 0 ? 'down' : 'left' );
+
+							} else if (deltaY < 0 || deltaX < 0) {
+								F.next( deltaY < 0 ? 'up' : 'right' );
+							}
+
+							e.preventDefault();
+						}
+					}
+				});
+			}
+		},
+
+		trigger: function (event, o) {
+			var ret, obj = o || F.coming || F.current;
+
+			if (!obj) {
+				return;
+			}
+
+			if ($.isFunction( obj[event] )) {
+				ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
+			}
+
+			if (ret === false) {
+				return false;
+			}
+
+			if (obj.helpers) {
+				$.each(obj.helpers, function (helper, opts) {
+					if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
+						F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);
+					}
+				});
+			}
+
+			D.trigger(event);
+		},
+
+		isImage: function (str) {
+			return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
+		},
+
+		isSWF: function (str) {
+			return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
+		},
+
+		_start: function (index) {
+			var coming = {},
+				obj,
+				href,
+				type,
+				margin,
+				padding;
+
+			index = getScalar( index );
+			obj   = F.group[ index ] || null;
+
+			if (!obj) {
+				return false;
+			}
+
+			coming = $.extend(true, {}, F.opts, obj);
+
+			// Convert margin and padding properties to array - top, right, bottom, left
+			margin  = coming.margin;
+			padding = coming.padding;
+
+			if ($.type(margin) === 'number') {
+				coming.margin = [margin, margin, margin, margin];
+			}
+
+			if ($.type(padding) === 'number') {
+				coming.padding = [padding, padding, padding, padding];
+			}
+
+			// 'modal' propery is just a shortcut
+			if (coming.modal) {
+				$.extend(true, coming, {
+					closeBtn   : false,
+					closeClick : false,
+					nextClick  : false,
+					arrows     : false,
+					mouseWheel : false,
+					keys       : null,
+					helpers: {
+						overlay : {
+							closeClick : false
+						}
+					}
+				});
+			}
+
+			// 'autoSize' property is a shortcut, too
+			if (coming.autoSize) {
+				coming.autoWidth = coming.autoHeight = true;
+			}
+
+			if (coming.width === 'auto') {
+				coming.autoWidth = true;
+			}
+
+			if (coming.height === 'auto') {
+				coming.autoHeight = true;
+			}
+
+			/*
+			 * Add reference to the group, so it`s possible to access from callbacks, example:
+			 * afterLoad : function() {
+			 *     this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
+			 * }
+			 */
+
+			coming.group  = F.group;
+			coming.index  = index;
+
+			// Give a chance for callback or helpers to update coming item (type, title, etc)
+			F.coming = coming;
+
+			if (false === F.trigger('beforeLoad')) {
+				F.coming = null;
+
+				return;
+			}
+
+			type = coming.type;
+			href = coming.href;
+
+			if (!type) {
+				F.coming = null;
+
+				//If we can not determine content type then drop silently or display next/prev item if looping through gallery
+				if (F.current && F.router && F.router !== 'jumpto') {
+					F.current.index = index;
+
+					return F[ F.router ]( F.direction );
+				}
+
+				return false;
+			}
+
+			F.isActive = true;
+
+			if (type === 'image' || type === 'swf') {
+				coming.autoHeight = coming.autoWidth = false;
+				coming.scrolling  = 'visible';
+			}
+
+			if (type === 'image') {
+				coming.aspectRatio = true;
+			}
+
+			if (type === 'iframe' && isTouch) {
+				coming.scrolling = 'scroll';
+			}
+
+			// Build the neccessary markup
+			coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
+
+			$.extend(coming, {
+				skin  : $('.fancybox-skin',  coming.wrap),
+				outer : $('.fancybox-outer', coming.wrap),
+				inner : $('.fancybox-inner', coming.wrap)
+			});
+
+			$.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
+				coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
+			});
+
+			F.trigger('onReady');
+
+			// Check before try to load; 'inline' and 'html' types need content, others - href
+			if (type === 'inline' || type === 'html') {
+				if (!coming.content || !coming.content.length) {
+					return F._error( 'content' );
+				}
+
+			} else if (!href) {
+				return F._error( 'href' );
+			}
+
+			if (type === 'image') {
+				F._loadImage();
+
+			} else if (type === 'ajax') {
+				F._loadAjax();
+
+			} else if (type === 'iframe') {
+				F._loadIframe();
+
+			} else {
+				F._afterLoad();
+			}
+		},
+
+		_error: function ( type ) {
+			$.extend(F.coming, {
+				type       : 'html',
+				autoWidth  : true,
+				autoHeight : true,
+				minWidth   : 0,
+				minHeight  : 0,
+				scrolling  : 'no',
+				hasError   : type,
+				content    : F.coming.tpl.error
+			});
+
+			F._afterLoad();
+		},
+
+		_loadImage: function () {
+			// Reset preload image so it is later possible to check "complete" property
+			var img = F.imgPreload = new Image();
+
+			img.onload = function () {
+				this.onload = this.onerror = null;
+
+				F.coming.width  = this.width / F.opts.pixelRatio;
+				F.coming.height = this.height / F.opts.pixelRatio;
+
+				F._afterLoad();
+			};
+
+			img.onerror = function () {
+				this.onload = this.onerror = null;
+
+				F._error( 'image' );
+			};
+
+			img.src = F.coming.href;
+
+			if (img.complete !== true) {
+				F.showLoading();
+			}
+		},
+
+		_loadAjax: function () {
+			var coming = F.coming;
+
+			F.showLoading();
+
+			F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
+				url: coming.href,
+				error: function (jqXHR, textStatus) {
+					if (F.coming && textStatus !== 'abort') {
+						F._error( 'ajax', jqXHR );
+
+					} else {
+						F.hideLoading();
+					}
+				},
+				success: function (data, textStatus) {
+					if (textStatus === 'success') {
+						coming.content = data;
+
+						F._afterLoad();
+					}
+				}
+			}));
+		},
+
+		_loadIframe: function() {
+			var coming = F.coming,
+				iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
+					.attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
+					.attr('src', coming.href);
+
+			// This helps IE
+			$(coming.wrap).bind('onReset', function () {
+				try {
+					$(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
+				} catch (e) {}
+			});
+
+			if (coming.iframe.preload) {
+				F.showLoading();
+
+				iframe.one('load', function() {
+					$(this).data('ready', 1);
+
+					// iOS will lose scrolling if we resize
+					if (!isTouch) {
+						$(this).bind('load.fb', F.update);
+					}
+
+					// Without this trick:
+					//   - iframe won't scroll on iOS devices
+					//   - IE7 sometimes displays empty iframe
+					$(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();
+
+					F._afterLoad();
+				});
+			}
+
+			coming.content = iframe.appendTo( coming.inner );
+
+			if (!coming.iframe.preload) {
+				F._afterLoad();
+			}
+		},
+
+		_preloadImages: function() {
+			var group   = F.group,
+				current = F.current,
+				len     = group.length,
+				cnt     = current.preload ? Math.min(current.preload, len - 1) : 0,
+				item,
+				i;
+
+			for (i = 1; i <= cnt; i += 1) {
+				item = group[ (current.index + i ) % len ];
+
+				if (item.type === 'image' && item.href) {
+					new Image().src = item.href;
+				}
+			}
+		},
+
+		_afterLoad: function () {
+			var coming   = F.coming,
+				previous = F.current,
+				placeholder = 'fancybox-placeholder',
+				current,
+				content,
+				type,
+				scrolling,
+				href,
+				embed;
+
+			F.hideLoading();
+
+			if (!coming || F.isActive === false) {
+				return;
+			}
+
+			if (false === F.trigger('afterLoad', coming, previous)) {
+				coming.wrap.stop(true).trigger('onReset').remove();
+
+				F.coming = null;
+
+				return;
+			}
+
+			if (previous) {
+				F.trigger('beforeChange', previous);
+
+				previous.wrap.stop(true).removeClass('fancybox-opened')
+					.find('.fancybox-item, .fancybox-nav')
+					.remove();
+			}
+
+			F.unbindEvents();
+
+			current   = coming;
+			content   = coming.content;
+			type      = coming.type;
+			scrolling = coming.scrolling;
+
+			$.extend(F, {
+				wrap  : current.wrap,
+				skin  : current.skin,
+				outer : current.outer,
+				inner : current.inner,
+				current  : current,
+				previous : previous
+			});
+
+			href = current.href;
+
+			switch (type) {
+				case 'inline':
+				case 'ajax':
+				case 'html':
+					if (current.selector) {
+						content = $('<div>').html(content).find(current.selector);
+
+					} else if (isQuery(content)) {
+						if (!content.data(placeholder)) {
+							content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
+						}
+
+						content = content.show().detach();
+
+						current.wrap.bind('onReset', function () {
+							if ($(this).find(content).length) {
+								content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
+							}
+						});
+					}
+				break;
+
+				case 'image':
+					content = current.tpl.image.replace('{href}', href);
+				break;
+
+				case 'swf':
+					content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
+					embed   = '';
+
+					$.each(current.swf, function(name, val) {
+						content += '<param name="' + name + '" value="' + val + '"></param>';
+						embed   += ' ' + name + '="' + val + '"';
+					});
+
+					content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
+				break;
+			}
+
+			if (!(isQuery(content) && content.parent().is(current.inner))) {
+				current.inner.append( content );
+			}
+
+			// Give a chance for helpers or callbacks to update elements
+			F.trigger('beforeShow');
+
+			// Set scrolling before calculating dimensions
+			current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
+
+			// Set initial dimensions and start position
+			F._setDimension();
+
+			F.reposition();
+
+			F.isOpen = false;
+			F.coming = null;
+
+			F.bindEvents();
+
+			if (!F.isOpened) {
+				$('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
+
+			} else if (previous.prevMethod) {
+				F.transitions[ previous.prevMethod ]();
+			}
+
+			F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
+
+			F._preloadImages();
+		},
+
+		_setDimension: function () {
+			var viewport   = F.getViewport(),
+				steps      = 0,
+				canShrink  = false,
+				canExpand  = false,
+				wrap       = F.wrap,
+				skin       = F.skin,
+				inner      = F.inner,
+				current    = F.current,
+				width      = current.width,
+				height     = current.height,
+				minWidth   = current.minWidth,
+				minHeight  = current.minHeight,
+				maxWidth   = current.maxWidth,
+				maxHeight  = current.maxHeight,
+				scrolling  = current.scrolling,
+				scrollOut  = current.scrollOutside ? current.scrollbarWidth : 0,
+				margin     = current.margin,
+				wMargin    = getScalar(margin[1] + margin[3]),
+				hMargin    = getScalar(margin[0] + margin[2]),
+				wPadding,
+				hPadding,
+				wSpace,
+				hSpace,
+				origWidth,
+				origHeight,
+				origMaxWidth,
+				origMaxHeight,
+				ratio,
+				width_,
+				height_,
+				maxWidth_,
+				maxHeight_,
+				iframe,
+				body;
+
+			// Reset dimensions so we could re-check actual size
+			wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
+
+			wPadding = getScalar(skin.outerWidth(true)  - skin.width());
+			hPadding = getScalar(skin.outerHeight(true) - skin.height());
+
+			// Any space between content and viewport (margin, padding, border, title)
+			wSpace = wMargin + wPadding;
+			hSpace = hMargin + hPadding;
+
+			origWidth  = isPercentage(width)  ? (viewport.w - wSpace) * getScalar(width)  / 100 : width;
+			origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
+
+			if (current.type === 'iframe') {
+				iframe = current.content;
+
+				if (current.autoHeight && iframe.data('ready') === 1) {
+					try {
+						if (iframe[0].contentWindow.document.location) {
+							inner.width( origWidth ).height(9999);
+
+							body = iframe.contents().find('body');
+
+							if (scrollOut) {
+								body.css('overflow-x', 'hidden');
+							}
+
+							origHeight = body.outerHeight(true);
+						}
+
+					} catch (e) {}
+				}
+
+			} else if (current.autoWidth || current.autoHeight) {
+				inner.addClass( 'fancybox-tmp' );
+
+				// Set width or height in case we need to calculate only one dimension
+				if (!current.autoWidth) {
+					inner.width( origWidth );
+				}
+
+				if (!current.autoHeight) {
+					inner.height( origHeight );
+				}
+
+				if (current.autoWidth) {
+					origWidth = inner.width();
+				}
+
+				if (current.autoHeight) {
+					origHeight = inner.height();
+				}
+
+				inner.removeClass( 'fancybox-tmp' );
+			}
+
+			width  = getScalar( origWidth );
+			height = getScalar( origHeight );
+
+			ratio  = origWidth / origHeight;
+
+			// Calculations for the content
+			minWidth  = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
+			maxWidth  = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
+
+			minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
+			maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
+
+			// These will be used to determine if wrap can fit in the viewport
+			origMaxWidth  = maxWidth;
+			origMaxHeight = maxHeight;
+
+			if (current.fitToView) {
+				maxWidth  = Math.min(viewport.w - wSpace, maxWidth);
+				maxHeight = Math.min(viewport.h - hSpace, maxHeight);
+			}
+
+			maxWidth_  = viewport.w - wMargin;
+			maxHeight_ = viewport.h - hMargin;
+
+			if (current.aspectRatio) {
+				if (width > maxWidth) {
+					width  = maxWidth;
+					height = getScalar(width / ratio);
+				}
+
+				if (height > maxHeight) {
+					height = maxHeight;
+					width  = getScalar(height * ratio);
+				}
+
+				if (width < minWidth) {
+					width  = minWidth;
+					height = getScalar(width / ratio);
+				}
+
+				if (height < minHeight) {
+					height = minHeight;
+					width  = getScalar(height * ratio);
+				}
+
+			} else {
+				width = Math.max(minWidth, Math.min(width, maxWidth));
+
+				if (current.autoHeight && current.type !== 'iframe') {
+					inner.width( width );
+
+					height = inner.height();
+				}
+
+				height = Math.max(minHeight, Math.min(height, maxHeight));
+			}
+
+			// Try to fit inside viewport (including the title)
+			if (current.fitToView) {
+				inner.width( width ).height( height );
+
+				wrap.width( width + wPadding );
+
+				// Real wrap dimensions
+				width_  = wrap.width();
+				height_ = wrap.height();
+
+				if (current.aspectRatio) {
+					while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
+						if (steps++ > 19) {
+							break;
+						}
+
+						height = Math.max(minHeight, Math.min(maxHeight, height - 10));
+						width  = getScalar(height * ratio);
+
+						if (width < minWidth) {
+							width  = minWidth;
+							height = getScalar(width / ratio);
+						}
+
+						if (width > maxWidth) {
+							width  = maxWidth;
+							height = getScalar(width / ratio);
+						}
+
+						inner.width( width ).height( height );
+
+						wrap.width( width + wPadding );
+
+						width_  = wrap.width();
+						height_ = wrap.height();
+					}
+
+				} else {
+					width  = Math.max(minWidth,  Math.min(width,  width  - (width_  - maxWidth_)));
+					height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
+				}
+			}
+
+			if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
+				width += scrollOut;
+			}
+
+			inner.width( width ).height( height );
+
+			wrap.width( width + wPadding );
+
+			width_  = wrap.width();
+			height_ = wrap.height();
+
+			canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
+			canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
+
+			$.extend(current, {
+				dim : {
+					width	: getValue( width_ ),
+					height	: getValue( height_ )
+				},
+				origWidth  : origWidth,
+				origHeight : origHeight,
+				canShrink  : canShrink,
+				canExpand  : canExpand,
+				wPadding   : wPadding,
+				hPadding   : hPadding,
+				wrapSpace  : height_ - skin.outerHeight(true),
+				skinSpace  : skin.height() - height
+			});
+
+			if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
+				inner.height('auto');
+			}
+		},
+
+		_getPosition: function (onlyAbsolute) {
+			var current  = F.current,
+				viewport = F.getViewport(),
+				margin   = current.margin,
+				width    = F.wrap.width()  + margin[1] + margin[3],
+				height   = F.wrap.height() + margin[0] + margin[2],
+				rez      = {
+					position: 'absolute',
+					top  : margin[0],
+					left : margin[3]
+				};
+
+			if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
+				rez.position = 'fixed';
+
+			} else if (!current.locked) {
+				rez.top  += viewport.y;
+				rez.left += viewport.x;
+			}
+
+			rez.top  = getValue(Math.max(rez.top,  rez.top  + ((viewport.h - height) * current.topRatio)));
+			rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width)  * current.leftRatio)));
+
+			return rez;
+		},
+
+		_afterZoomIn: function () {
+			var current = F.current;
+
+			if (!current) {
+				return;
+			}
+
+			F.isOpen = F.isOpened = true;
+
+			F.wrap.css('overflow', 'visible').addClass('fancybox-opened');
+
+			F.update();
+
+			// Assign a click event
+			if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
+				F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
+					if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
+						e.preventDefault();
+
+						F[ current.closeClick ? 'close' : 'next' ]();
+					}
+				});
+			}
+
+			// Create a close button
+			if (current.closeBtn) {
+				$(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
+					e.preventDefault();
+
+					F.close();
+				});
+			}
+
+			// Create navigation arrows
+			if (current.arrows && F.group.length > 1) {
+				if (current.loop || current.index > 0) {
+					$(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
+				}
+
+				if (current.loop || current.index < F.group.length - 1) {
+					$(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
+				}
+			}
+
+			F.trigger('afterShow');
+
+			// Stop the slideshow if this is the last item
+			if (!current.loop && current.index === current.group.length - 1) {
+				F.play( false );
+
+			} else if (F.opts.autoPlay && !F.player.isActive) {
+				F.opts.autoPlay = false;
+
+				F.play();
+			}
+		},
+
+		_afterZoomOut: function ( obj ) {
+			obj = obj || F.current;
+
+			$('.fancybox-wrap').trigger('onReset').remove();
+
+			$.extend(F, {
+				group  : {},
+				opts   : {},
+				router : false,
+				current   : null,
+				isActive  : false,
+				isOpened  : false,
+				isOpen    : false,
+				isClosing : false,
+				wrap   : null,
+				skin   : null,
+				outer  : null,
+				inner  : null
+			});
+
+			F.trigger('afterClose', obj);
+		}
+	});
+
+	/*
+	 *	Default transitions
+	 */
+
+	F.transitions = {
+		getOrigPosition: function () {
+			var current  = F.current,
+				element  = current.element,
+				orig     = current.orig,
+				pos      = {},
+				width    = 50,
+				height   = 50,
+				hPadding = current.hPadding,
+				wPadding = current.wPadding,
+				viewport = F.getViewport();
+
+			if (!orig && current.isDom && element.is(':visible')) {
+				orig = element.find('img:first');
+
+				if (!orig.length) {
+					orig = element;
+				}
+			}
+
+			if (isQuery(orig)) {
+				pos = orig.offset();
+
+				if (orig.is('img')) {
+					width  = orig.outerWidth();
+					height = orig.outerHeight();
+				}
+
+			} else {
+				pos.top  = viewport.y + (viewport.h - height) * current.topRatio;
+				pos.left = viewport.x + (viewport.w - width)  * current.leftRatio;
+			}
+
+			if (F.wrap.css('position') === 'fixed' || current.locked) {
+				pos.top  -= viewport.y;
+				pos.left -= viewport.x;
+			}
+
+			pos = {
+				top     : getValue(pos.top  - hPadding * current.topRatio),
+				left    : getValue(pos.left - wPadding * current.leftRatio),
+				width   : getValue(width  + wPadding),
+				height  : getValue(height + hPadding)
+			};
+
+			return pos;
+		},
+
+		step: function (now, fx) {
+			var ratio,
+				padding,
+				value,
+				prop       = fx.prop,
+				current    = F.current,
+				wrapSpace  = current.wrapSpace,
+				skinSpace  = current.skinSpace;
+
+			if (prop === 'width' || prop === 'height') {
+				ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
+
+				if (F.isClosing) {
+					ratio = 1 - ratio;
+				}
+
+				padding = prop === 'width' ? current.wPadding : current.hPadding;
+				value   = now - padding;
+
+				F.skin[ prop ](  getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) ) );
+				F.inner[ prop ]( getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
+			}
+		},
+
+		zoomIn: function () {
+			var current  = F.current,
+				startPos = current.pos,
+				effect   = current.openEffect,
+				elastic  = effect === 'elastic',
+				endPos   = $.extend({opacity : 1}, startPos);
+
+			// Remove "position" property that breaks older IE
+			delete endPos.position;
+
+			if (elastic) {
+				startPos = this.getOrigPosition();
+
+				if (current.openOpacity) {
+					startPos.opacity = 0.1;
+				}
+
+			} else if (effect === 'fade') {
+				startPos.opacity = 0.1;
+			}
+
+			F.wrap.css(startPos).animate(endPos, {
+				duration : effect === 'none' ? 0 : current.openSpeed,
+				easing   : current.openEasing,
+				step     : elastic ? this.step : null,
+				complete : F._afterZoomIn
+			});
+		},
+
+		zoomOut: function () {
+			var current  = F.current,
+				effect   = current.closeEffect,
+				elastic  = effect === 'elastic',
+				endPos   = {opacity : 0.1};
+
+			if (elastic) {
+				endPos = this.getOrigPosition();
+
+				if (current.closeOpacity) {
+					endPos.opacity = 0.1;
+				}
+			}
+
+			F.wrap.animate(endPos, {
+				duration : effect === 'none' ? 0 : current.closeSpeed,
+				easing   : current.closeEasing,
+				step     : elastic ? this.step : null,
+				complete : F._afterZoomOut
+			});
+		},
+
+		changeIn: function () {
+			var current   = F.current,
+				effect    = current.nextEffect,
+				startPos  = current.pos,
+				endPos    = { opacity : 1 },
+				direction = F.direction,
+				distance  = 200,
+				field;
+
+			startPos.opacity = 0.1;
+
+			if (effect === 'elastic') {
+				field = direction === 'down' || direction === 'up' ? 'top' : 'left';
+
+				if (direction === 'down' || direction === 'right') {
+					startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
+					endPos[ field ]   = '+=' + distance + 'px';
+
+				} else {
+					startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
+					endPos[ field ]   = '-=' + distance + 'px';
+				}
+			}
+
+			// Workaround for http://bugs.jquery.com/ticket/12273
+			if (effect === 'none') {
+				F._afterZoomIn();
+
+			} else {
+				F.wrap.css(startPos).animate(endPos, {
+					duration : current.nextSpeed,
+					easing   : current.nextEasing,
+					complete : F._afterZoomIn
+				});
+			}
+		},
+
+		changeOut: function () {
+			var previous  = F.previous,
+				effect    = previous.prevEffect,
+				endPos    = { opacity : 0.1 },
+				direction = F.direction,
+				distance  = 200;
+
+			if (effect === 'elastic') {
+				endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
+			}
+
+			previous.wrap.animate(endPos, {
+				duration : effect === 'none' ? 0 : previous.prevSpeed,
+				easing   : previous.prevEasing,
+				complete : function () {
+					$(this).trigger('onReset').remove();
+				}
+			});
+		}
+	};
+
+	/*
+	 *	Overlay helper
+	 */
+
+	F.helpers.overlay = {
+		defaults : {
+			closeClick : true,      // if true, fancyBox will be closed when user clicks on the overlay
+			speedOut   : 200,       // duration of fadeOut animation
+			showEarly  : true,      // indicates if should be opened immediately or wait until the content is ready
+			css        : {},        // custom CSS properties
+			locked     : !isTouch,  // if true, the content will be locked into overlay
+			fixed      : true       // if false, the overlay CSS position property will not be set to "fixed"
+		},
+
+		overlay : null,      // current handle
+		fixed   : false,     // indicates if the overlay has position "fixed"
+		el      : $('html'), // element that contains "the lock"
+
+		// Public methods
+		create : function(opts) {
+			opts = $.extend({}, this.defaults, opts);
+
+			if (this.overlay) {
+				this.close();
+			}
+
+			this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent );
+			this.fixed   = false;
+
+			if (opts.fixed && F.defaults.fixed) {
+				this.overlay.addClass('fancybox-overlay-fixed');
+
+				this.fixed = true;
+			}
+		},
+
+		open : function(opts) {
+			var that = this;
+
+			opts = $.extend({}, this.defaults, opts);
+
+			if (this.overlay) {
+				this.overlay.unbind('.overlay').width('auto').height('auto');
+
+			} else {
+				this.create(opts);
+			}
+
+			if (!this.fixed) {
+				W.bind('resize.overlay', $.proxy( this.update, this) );
+
+				this.update();
+			}
+
+			if (opts.closeClick) {
+				this.overlay.bind('click.overlay', function(e) {
+					if ($(e.target).hasClass('fancybox-overlay')) {
+						if (F.isActive) {
+							F.close();
+						} else {
+							that.close();
+						}
+
+						return false;
+					}
+				});
+			}
+
+			this.overlay.css( opts.css ).show();
+		},
+
+		close : function() {
+			var scrollV, scrollH;
+
+			W.unbind('resize.overlay');
+
+			if (this.el.hasClass('fancybox-lock')) {
+				$('.fancybox-margin').removeClass('fancybox-margin');
+
+				scrollV = W.scrollTop();
+				scrollH = W.scrollLeft();
+
+				this.el.removeClass('fancybox-lock');
+
+				W.scrollTop( scrollV ).scrollLeft( scrollH );
+			}
+
+			$('.fancybox-overlay').remove().hide();
+
+			$.extend(this, {
+				overlay : null,
+				fixed   : false
+			});
+		},
+
+		// Private, callbacks
+
+		update : function () {
+			var width = '100%', offsetWidth;
+
+			// Reset width/height so it will not mess
+			this.overlay.width(width).height('100%');
+
+			// jQuery does not return reliable result for IE
+			if (IE) {
+				offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
+
+				if (D.width() > offsetWidth) {
+					width = D.width();
+				}
+
+			} else if (D.width() > W.width()) {
+				width = D.width();
+			}
+
+			this.overlay.width(width).height(D.height());
+		},
+
+		// This is where we can manipulate DOM, because later it would cause iframes to reload
+		onReady : function (opts, obj) {
+			var overlay = this.overlay;
+
+			$('.fancybox-overlay').stop(true, true);
+
+			if (!overlay) {
+				this.create(opts);
+			}
+
+			if (opts.locked && this.fixed && obj.fixed) {
+				if (!overlay) {
+					this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false;
+				}
+
+				obj.locked = this.overlay.append( obj.wrap );
+				obj.fixed  = false;
+			}
+
+			if (opts.showEarly === true) {
+				this.beforeShow.apply(this, arguments);
+			}
+		},
+
+		beforeShow : function(opts, obj) {
+			var scrollV, scrollH;
+
+			if (obj.locked) {
+				if (this.margin !== false) {
+					$('*').filter(function(){
+						return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );
+					}).addClass('fancybox-margin');
+
+					this.el.addClass('fancybox-margin');
+				}
+
+				scrollV = W.scrollTop();
+				scrollH = W.scrollLeft();
+
+				this.el.addClass('fancybox-lock');
+
+				W.scrollTop( scrollV ).scrollLeft( scrollH );
+			}
+
+			this.open(opts);
+		},
+
+		onUpdate : function() {
+			if (!this.fixed) {
+				this.update();
+			}
+		},
+
+		afterClose: function (opts) {
+			// Remove overlay if exists and fancyBox is not opening
+			// (e.g., it is not being open using afterClose callback)
+			//if (this.overlay && !F.isActive) {
+			if (this.overlay && !F.coming) {
+				this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
+			}
+		}
+	};
+
+	/*
+	 *	Title helper
+	 */
+
+	F.helpers.title = {
+		defaults : {
+			type     : 'float', // 'float', 'inside', 'outside' or 'over',
+			position : 'bottom' // 'top' or 'bottom'
+		},
+
+		beforeShow: function (opts) {
+			var current = F.current,
+				text    = current.title,
+				type    = opts.type,
+				title,
+				target;
+
+			if ($.isFunction(text)) {
+				text = text.call(current.element, current);
+			}
+
+			if (!isString(text) || $.trim(text) === '') {
+				return;
+			}
+
+			title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + '</div>');
+
+			switch (type) {
+				case 'inside':
+					target = F.skin;
+				break;
+
+				case 'outside':
+					target = F.wrap;
+				break;
+
+				case 'over':
+					target = F.inner;
+				break;
+
+				default: // 'float'
+					target = F.skin;
+
+					title.appendTo('body');
+
+					if (IE) {
+						title.width( title.width() );
+					}
+
+					title.wrapInner('<span class="child"></span>');
+
+					//Increase bottom margin so this title will also fit into viewport
+					F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
+				break;
+			}
+
+			title[ (opts.position === 'top' ? 'prependTo'  : 'appendTo') ](target);
+		}
+	};
+
+	// jQuery plugin initialization
+	$.fn.fancybox = function (options) {
+		var index,
+			that     = $(this),
+			selector = this.selector || '',
+			run      = function(e) {
+				var what = $(this).blur(), idx = index, relType, relVal;
+
+				if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
+					relType = options.groupAttr || 'data-fancybox-group';
+					relVal  = what.attr(relType);
+
+					if (!relVal) {
+						relType = 'rel';
+						relVal  = what.get(0)[ relType ];
+					}
+
+					if (relVal && relVal !== '' && relVal !== 'nofollow') {
+						what = selector.length ? $(selector) : that;
+						what = what.filter('[' + relType + '="' + relVal + '"]');
+						idx  = what.index(this);
+					}
+
+					options.index = idx;
+
+					// Stop an event from bubbling if everything is fine
+					if (F.open(what, options) !== false) {
+						e.preventDefault();
+					}
+				}
+			};
+
+		options = options || {};
+		index   = options.index || 0;
+
+		if (!selector || options.live === false) {
+			that.unbind('click.fb-start').bind('click.fb-start', run);
+
+		} else {
+			D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
+		}
+
+		this.filter('[data-fancybox-start=1]').trigger('click');
+
+		return this;
+	};
+
+	// Tests that need a body at doc ready
+	D.ready(function() {
+		var w1, w2;
+
+		if ( $.scrollbarWidth === undefined ) {
+			// http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
+			$.scrollbarWidth = function() {
+				var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
+					child  = parent.children(),
+					width  = child.innerWidth() - child.height( 99 ).innerWidth();
+
+				parent.remove();
+
+				return width;
+			};
+		}
+
+		if ( $.support.fixedPosition === undefined ) {
+			$.support.fixedPosition = (function() {
+				var elem  = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
+					fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
+
+				elem.remove();
+
+				return fixed;
+			}());
+		}
+
+		$.extend(F.defaults, {
+			scrollbarWidth : $.scrollbarWidth(),
+			fixed  : $.support.fixedPosition,
+			parent : $('body')
+		});
+
+		//Get real width of page scroll-bar
+		w1 = $(window).width();
+
+		H.addClass('fancybox-lock-test');
+
+		w2 = $(window).width();
+
+		H.removeClass('fancybox-lock-test');
+
+		$("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
+	});
+
+}(window, document, jQuery));

+ 46 - 0
assets/lib/fancybox/jquery.fancybox.pack.js

@@ -0,0 +1,46 @@
+/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
+(function(r,G,f,v){var J=f("html"),n=f(r),p=f(G),b=f.fancybox=function(){b.open.apply(this,arguments)},I=navigator.userAgent.match(/msie/i),B=null,s=G.createTouch!==v,t=function(a){return a&&a.hasOwnProperty&&a instanceof f},q=function(a){return a&&"string"===f.type(a)},E=function(a){return q(a)&&0<a.indexOf("%")},l=function(a,d){var e=parseInt(a,10)||0;d&&E(a)&&(e*=b.getViewport()[d]/100);return Math.ceil(e)},w=function(a,b){return l(a,b)+"px"};f.extend(b,{version:"2.1.5",defaults:{padding:15,margin:20,
+width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,pixelRatio:1,autoSize:!0,autoHeight:!1,autoWidth:!1,autoResize:!0,autoCenter:!s,fitToView:!0,aspectRatio:!1,topRatio:0.5,leftRatio:0.5,scrolling:"auto",wrapCSS:"",arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,playSpeed:3E3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-fancyBox":!0}},iframe:{scrolling:"auto",preload:!0},swf:{wmode:"transparent",allowfullscreen:"true",allowscriptaccess:"always"},
+keys:{next:{13:"left",34:"up",39:"left",40:"up"},prev:{8:"right",33:"down",37:"right",38:"down"},close:[27],play:[32],toggle:[70]},direction:{next:"left",prev:"right"},scrollOutside:!0,index:0,type:null,href:null,content:null,title:null,tpl:{wrap:'<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',image:'<img class="fancybox-image" src="{href}" alt="" />',iframe:'<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen'+
+(I?' allowtransparency="true"':"")+"></iframe>",error:'<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',closeBtn:'<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',next:'<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',prev:'<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,
+openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:f.noop,beforeLoad:f.noop,afterLoad:f.noop,beforeShow:f.noop,afterShow:f.noop,beforeChange:f.noop,beforeClose:f.noop,afterClose:f.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1,
+isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(a,d){if(a&&(f.isPlainObject(d)||(d={}),!1!==b.close(!0)))return f.isArray(a)||(a=t(a)?f(a).get():[a]),f.each(a,function(e,c){var k={},g,h,j,m,l;"object"===f.type(c)&&(c.nodeType&&(c=f(c)),t(c)?(k={href:c.data("fancybox-href")||c.attr("href"),title:c.data("fancybox-title")||c.attr("title"),isDom:!0,element:c},f.metadata&&f.extend(!0,k,
+c.metadata())):k=c);g=d.href||k.href||(q(c)?c:null);h=d.title!==v?d.title:k.title||"";m=(j=d.content||k.content)?"html":d.type||k.type;!m&&k.isDom&&(m=c.data("fancybox-type"),m||(m=(m=c.prop("class").match(/fancybox\.(\w+)/))?m[1]:null));q(g)&&(m||(b.isImage(g)?m="image":b.isSWF(g)?m="swf":"#"===g.charAt(0)?m="inline":q(c)&&(m="html",j=c)),"ajax"===m&&(l=g.split(/\s+/,2),g=l.shift(),l=l.shift()));j||("inline"===m?g?j=f(q(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):k.isDom&&(j=c):"html"===m?j=g:!m&&(!g&&
+k.isDom)&&(m="inline",j=c));f.extend(k,{href:g,type:m,content:j,title:h,selector:l});a[e]=k}),b.opts=f.extend(!0,{},b.defaults,d),d.keys!==v&&(b.opts.keys=d.keys?f.extend({},b.defaults.keys,d.keys):!1),b.group=a,b._start(b.opts.index)},cancel:function(){var a=b.coming;a&&!1!==b.trigger("onCancel")&&(b.hideLoading(),b.ajaxLoad&&b.ajaxLoad.abort(),b.ajaxLoad=null,b.imgPreload&&(b.imgPreload.onload=b.imgPreload.onerror=null),a.wrap&&a.wrap.stop(!0,!0).trigger("onReset").remove(),b.coming=null,b.current||
+b._afterZoomOut(a))},close:function(a){b.cancel();!1!==b.trigger("beforeClose")&&(b.unbindEvents(),b.isActive&&(!b.isOpen||!0===a?(f(".fancybox-wrap").stop(!0).trigger("onReset").remove(),b._afterZoomOut()):(b.isOpen=b.isOpened=!1,b.isClosing=!0,f(".fancybox-item, .fancybox-nav").remove(),b.wrap.stop(!0,!0).removeClass("fancybox-opened"),b.transitions[b.current.closeMethod]())))},play:function(a){var d=function(){clearTimeout(b.player.timer)},e=function(){d();b.current&&b.player.isActive&&(b.player.timer=
+setTimeout(b.next,b.current.playSpeed))},c=function(){d();p.unbind(".player");b.player.isActive=!1;b.trigger("onPlayEnd")};if(!0===a||!b.player.isActive&&!1!==a){if(b.current&&(b.current.loop||b.current.index<b.group.length-1))b.player.isActive=!0,p.bind({"onCancel.player beforeClose.player":c,"onUpdate.player":e,"beforeLoad.player":d}),e(),b.trigger("onPlayStart")}else c()},next:function(a){var d=b.current;d&&(q(a)||(a=d.direction.next),b.jumpto(d.index+1,a,"next"))},prev:function(a){var d=b.current;
+d&&(q(a)||(a=d.direction.prev),b.jumpto(d.index-1,a,"prev"))},jumpto:function(a,d,e){var c=b.current;c&&(a=l(a),b.direction=d||c.direction[a>=c.index?"next":"prev"],b.router=e||"jumpto",c.loop&&(0>a&&(a=c.group.length+a%c.group.length),a%=c.group.length),c.group[a]!==v&&(b.cancel(),b._start(a)))},reposition:function(a,d){var e=b.current,c=e?e.wrap:null,k;c&&(k=b._getPosition(d),a&&"scroll"===a.type?(delete k.position,c.stop(!0,!0).animate(k,200)):(c.css(k),e.pos=f.extend({},e.dim,k)))},update:function(a){var d=
+a&&a.type,e=!d||"orientationchange"===d;e&&(clearTimeout(B),B=null);b.isOpen&&!B&&(B=setTimeout(function(){var c=b.current;c&&!b.isClosing&&(b.wrap.removeClass("fancybox-tmp"),(e||"load"===d||"resize"===d&&c.autoResize)&&b._setDimension(),"scroll"===d&&c.canShrink||b.reposition(a),b.trigger("onUpdate"),B=null)},e&&!s?0:300))},toggle:function(a){b.isOpen&&(b.current.fitToView="boolean"===f.type(a)?a:!b.current.fitToView,s&&(b.wrap.removeAttr("style").addClass("fancybox-tmp"),b.trigger("onUpdate")),
+b.update())},hideLoading:function(){p.unbind(".loading");f("#fancybox-loading").remove()},showLoading:function(){var a,d;b.hideLoading();a=f('<div id="fancybox-loading"><div></div></div>').click(b.cancel).appendTo("body");p.bind("keydown.loading",function(a){if(27===(a.which||a.keyCode))a.preventDefault(),b.cancel()});b.defaults.fixed||(d=b.getViewport(),a.css({position:"absolute",top:0.5*d.h+d.y,left:0.5*d.w+d.x}))},getViewport:function(){var a=b.current&&b.current.locked||!1,d={x:n.scrollLeft(),
+y:n.scrollTop()};a?(d.w=a[0].clientWidth,d.h=a[0].clientHeight):(d.w=s&&r.innerWidth?r.innerWidth:n.width(),d.h=s&&r.innerHeight?r.innerHeight:n.height());return d},unbindEvents:function(){b.wrap&&t(b.wrap)&&b.wrap.unbind(".fb");p.unbind(".fb");n.unbind(".fb")},bindEvents:function(){var a=b.current,d;a&&(n.bind("orientationchange.fb"+(s?"":" resize.fb")+(a.autoCenter&&!a.locked?" scroll.fb":""),b.update),(d=a.keys)&&p.bind("keydown.fb",function(e){var c=e.which||e.keyCode,k=e.target||e.srcElement;
+if(27===c&&b.coming)return!1;!e.ctrlKey&&(!e.altKey&&!e.shiftKey&&!e.metaKey&&(!k||!k.type&&!f(k).is("[contenteditable]")))&&f.each(d,function(d,k){if(1<a.group.length&&k[c]!==v)return b[d](k[c]),e.preventDefault(),!1;if(-1<f.inArray(c,k))return b[d](),e.preventDefault(),!1})}),f.fn.mousewheel&&a.mouseWheel&&b.wrap.bind("mousewheel.fb",function(d,c,k,g){for(var h=f(d.target||null),j=!1;h.length&&!j&&!h.is(".fancybox-skin")&&!h.is(".fancybox-wrap");)j=h[0]&&!(h[0].style.overflow&&"hidden"===h[0].style.overflow)&&
+(h[0].clientWidth&&h[0].scrollWidth>h[0].clientWidth||h[0].clientHeight&&h[0].scrollHeight>h[0].clientHeight),h=f(h).parent();if(0!==c&&!j&&1<b.group.length&&!a.canShrink){if(0<g||0<k)b.prev(0<g?"down":"left");else if(0>g||0>k)b.next(0>g?"up":"right");d.preventDefault()}}))},trigger:function(a,d){var e,c=d||b.coming||b.current;if(c){f.isFunction(c[a])&&(e=c[a].apply(c,Array.prototype.slice.call(arguments,1)));if(!1===e)return!1;c.helpers&&f.each(c.helpers,function(d,e){if(e&&b.helpers[d]&&f.isFunction(b.helpers[d][a]))b.helpers[d][a](f.extend(!0,
+{},b.helpers[d].defaults,e),c)});p.trigger(a)}},isImage:function(a){return q(a)&&a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(a){return q(a)&&a.match(/\.(swf)((\?|#).*)?$/i)},_start:function(a){var d={},e,c;a=l(a);e=b.group[a]||null;if(!e)return!1;d=f.extend(!0,{},b.opts,e);e=d.margin;c=d.padding;"number"===f.type(e)&&(d.margin=[e,e,e,e]);"number"===f.type(c)&&(d.padding=[c,c,c,c]);d.modal&&f.extend(!0,d,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,
+mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}});d.autoSize&&(d.autoWidth=d.autoHeight=!0);"auto"===d.width&&(d.autoWidth=!0);"auto"===d.height&&(d.autoHeight=!0);d.group=b.group;d.index=a;b.coming=d;if(!1===b.trigger("beforeLoad"))b.coming=null;else{c=d.type;e=d.href;if(!c)return b.coming=null,b.current&&b.router&&"jumpto"!==b.router?(b.current.index=a,b[b.router](b.direction)):!1;b.isActive=!0;if("image"===c||"swf"===c)d.autoHeight=d.autoWidth=!1,d.scrolling="visible";"image"===c&&(d.aspectRatio=
+!0);"iframe"===c&&s&&(d.scrolling="scroll");d.wrap=f(d.tpl.wrap).addClass("fancybox-"+(s?"mobile":"desktop")+" fancybox-type-"+c+" fancybox-tmp "+d.wrapCSS).appendTo(d.parent||"body");f.extend(d,{skin:f(".fancybox-skin",d.wrap),outer:f(".fancybox-outer",d.wrap),inner:f(".fancybox-inner",d.wrap)});f.each(["Top","Right","Bottom","Left"],function(a,b){d.skin.css("padding"+b,w(d.padding[a]))});b.trigger("onReady");if("inline"===c||"html"===c){if(!d.content||!d.content.length)return b._error("content")}else if(!e)return b._error("href");
+"image"===c?b._loadImage():"ajax"===c?b._loadAjax():"iframe"===c?b._loadIframe():b._afterLoad()}},_error:function(a){f.extend(b.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:a,content:b.coming.tpl.error});b._afterLoad()},_loadImage:function(){var a=b.imgPreload=new Image;a.onload=function(){this.onload=this.onerror=null;b.coming.width=this.width/b.opts.pixelRatio;b.coming.height=this.height/b.opts.pixelRatio;b._afterLoad()};a.onerror=function(){this.onload=
+this.onerror=null;b._error("image")};a.src=b.coming.href;!0!==a.complete&&b.showLoading()},_loadAjax:function(){var a=b.coming;b.showLoading();b.ajaxLoad=f.ajax(f.extend({},a.ajax,{url:a.href,error:function(a,e){b.coming&&"abort"!==e?b._error("ajax",a):b.hideLoading()},success:function(d,e){"success"===e&&(a.content=d,b._afterLoad())}}))},_loadIframe:function(){var a=b.coming,d=f(a.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",s?"auto":a.iframe.scrolling).attr("src",a.href);
+f(a.wrap).bind("onReset",function(){try{f(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(a){}});a.iframe.preload&&(b.showLoading(),d.one("load",function(){f(this).data("ready",1);s||f(this).bind("load.fb",b.update);f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();b._afterLoad()}));a.content=d.appendTo(a.inner);a.iframe.preload||b._afterLoad()},_preloadImages:function(){var a=b.group,d=b.current,e=a.length,c=d.preload?Math.min(d.preload,
+e-1):0,f,g;for(g=1;g<=c;g+=1)f=a[(d.index+g)%e],"image"===f.type&&f.href&&((new Image).src=f.href)},_afterLoad:function(){var a=b.coming,d=b.current,e,c,k,g,h;b.hideLoading();if(a&&!1!==b.isActive)if(!1===b.trigger("afterLoad",a,d))a.wrap.stop(!0).trigger("onReset").remove(),b.coming=null;else{d&&(b.trigger("beforeChange",d),d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());b.unbindEvents();e=a.content;c=a.type;k=a.scrolling;f.extend(b,{wrap:a.wrap,skin:a.skin,
+outer:a.outer,inner:a.inner,current:a,previous:d});g=a.href;switch(c){case "inline":case "ajax":case "html":a.selector?e=f("<div>").html(e).find(a.selector):t(e)&&(e.data("fancybox-placeholder")||e.data("fancybox-placeholder",f('<div class="fancybox-placeholder"></div>').insertAfter(e).hide()),e=e.show().detach(),a.wrap.bind("onReset",function(){f(this).find(e).length&&e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder",!1)}));break;case "image":e=a.tpl.image.replace("{href}",
+g);break;case "swf":e='<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="'+g+'"></param>',h="",f.each(a.swf,function(a,b){e+='<param name="'+a+'" value="'+b+'"></param>';h+=" "+a+'="'+b+'"'}),e+='<embed src="'+g+'" type="application/x-shockwave-flash" width="100%" height="100%"'+h+"></embed></object>"}(!t(e)||!e.parent().is(a.inner))&&a.inner.append(e);b.trigger("beforeShow");a.inner.css("overflow","yes"===k?"scroll":
+"no"===k?"hidden":k);b._setDimension();b.reposition();b.isOpen=!1;b.coming=null;b.bindEvents();if(b.isOpened){if(d.prevMethod)b.transitions[d.prevMethod]()}else f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();b.transitions[b.isOpened?a.nextMethod:a.openMethod]();b._preloadImages()}},_setDimension:function(){var a=b.getViewport(),d=0,e=!1,c=!1,e=b.wrap,k=b.skin,g=b.inner,h=b.current,c=h.width,j=h.height,m=h.minWidth,u=h.minHeight,n=h.maxWidth,p=h.maxHeight,s=h.scrolling,q=h.scrollOutside?
+h.scrollbarWidth:0,x=h.margin,y=l(x[1]+x[3]),r=l(x[0]+x[2]),v,z,t,C,A,F,B,D,H;e.add(k).add(g).width("auto").height("auto").removeClass("fancybox-tmp");x=l(k.outerWidth(!0)-k.width());v=l(k.outerHeight(!0)-k.height());z=y+x;t=r+v;C=E(c)?(a.w-z)*l(c)/100:c;A=E(j)?(a.h-t)*l(j)/100:j;if("iframe"===h.type){if(H=h.content,h.autoHeight&&1===H.data("ready"))try{H[0].contentWindow.document.location&&(g.width(C).height(9999),F=H.contents().find("body"),q&&F.css("overflow-x","hidden"),A=F.outerHeight(!0))}catch(G){}}else if(h.autoWidth||
+h.autoHeight)g.addClass("fancybox-tmp"),h.autoWidth||g.width(C),h.autoHeight||g.height(A),h.autoWidth&&(C=g.width()),h.autoHeight&&(A=g.height()),g.removeClass("fancybox-tmp");c=l(C);j=l(A);D=C/A;m=l(E(m)?l(m,"w")-z:m);n=l(E(n)?l(n,"w")-z:n);u=l(E(u)?l(u,"h")-t:u);p=l(E(p)?l(p,"h")-t:p);F=n;B=p;h.fitToView&&(n=Math.min(a.w-z,n),p=Math.min(a.h-t,p));z=a.w-y;r=a.h-r;h.aspectRatio?(c>n&&(c=n,j=l(c/D)),j>p&&(j=p,c=l(j*D)),c<m&&(c=m,j=l(c/D)),j<u&&(j=u,c=l(j*D))):(c=Math.max(m,Math.min(c,n)),h.autoHeight&&
+"iframe"!==h.type&&(g.width(c),j=g.height()),j=Math.max(u,Math.min(j,p)));if(h.fitToView)if(g.width(c).height(j),e.width(c+x),a=e.width(),y=e.height(),h.aspectRatio)for(;(a>z||y>r)&&(c>m&&j>u)&&!(19<d++);)j=Math.max(u,Math.min(p,j-10)),c=l(j*D),c<m&&(c=m,j=l(c/D)),c>n&&(c=n,j=l(c/D)),g.width(c).height(j),e.width(c+x),a=e.width(),y=e.height();else c=Math.max(m,Math.min(c,c-(a-z))),j=Math.max(u,Math.min(j,j-(y-r)));q&&("auto"===s&&j<A&&c+x+q<z)&&(c+=q);g.width(c).height(j);e.width(c+x);a=e.width();
+y=e.height();e=(a>z||y>r)&&c>m&&j>u;c=h.aspectRatio?c<F&&j<B&&c<C&&j<A:(c<F||j<B)&&(c<C||j<A);f.extend(h,{dim:{width:w(a),height:w(y)},origWidth:C,origHeight:A,canShrink:e,canExpand:c,wPadding:x,hPadding:v,wrapSpace:y-k.outerHeight(!0),skinSpace:k.height()-j});!H&&(h.autoHeight&&j>u&&j<p&&!c)&&g.height("auto")},_getPosition:function(a){var d=b.current,e=b.getViewport(),c=d.margin,f=b.wrap.width()+c[1]+c[3],g=b.wrap.height()+c[0]+c[2],c={position:"absolute",top:c[0],left:c[3]};d.autoCenter&&d.fixed&&
+!a&&g<=e.h&&f<=e.w?c.position="fixed":d.locked||(c.top+=e.y,c.left+=e.x);c.top=w(Math.max(c.top,c.top+(e.h-g)*d.topRatio));c.left=w(Math.max(c.left,c.left+(e.w-f)*d.leftRatio));return c},_afterZoomIn:function(){var a=b.current;a&&(b.isOpen=b.isOpened=!0,b.wrap.css("overflow","visible").addClass("fancybox-opened"),b.update(),(a.closeClick||a.nextClick&&1<b.group.length)&&b.inner.css("cursor","pointer").bind("click.fb",function(d){!f(d.target).is("a")&&!f(d.target).parent().is("a")&&(d.preventDefault(),
+b[a.closeClick?"close":"next"]())}),a.closeBtn&&f(a.tpl.closeBtn).appendTo(b.skin).bind("click.fb",function(a){a.preventDefault();b.close()}),a.arrows&&1<b.group.length&&((a.loop||0<a.index)&&f(a.tpl.prev).appendTo(b.outer).bind("click.fb",b.prev),(a.loop||a.index<b.group.length-1)&&f(a.tpl.next).appendTo(b.outer).bind("click.fb",b.next)),b.trigger("afterShow"),!a.loop&&a.index===a.group.length-1?b.play(!1):b.opts.autoPlay&&!b.player.isActive&&(b.opts.autoPlay=!1,b.play()))},_afterZoomOut:function(a){a=
+a||b.current;f(".fancybox-wrap").trigger("onReset").remove();f.extend(b,{group:{},opts:{},router:!1,current:null,isActive:!1,isOpened:!1,isOpen:!1,isClosing:!1,wrap:null,skin:null,outer:null,inner:null});b.trigger("afterClose",a)}});b.transitions={getOrigPosition:function(){var a=b.current,d=a.element,e=a.orig,c={},f=50,g=50,h=a.hPadding,j=a.wPadding,m=b.getViewport();!e&&(a.isDom&&d.is(":visible"))&&(e=d.find("img:first"),e.length||(e=d));t(e)?(c=e.offset(),e.is("img")&&(f=e.outerWidth(),g=e.outerHeight())):
+(c.top=m.y+(m.h-g)*a.topRatio,c.left=m.x+(m.w-f)*a.leftRatio);if("fixed"===b.wrap.css("position")||a.locked)c.top-=m.y,c.left-=m.x;return c={top:w(c.top-h*a.topRatio),left:w(c.left-j*a.leftRatio),width:w(f+j),height:w(g+h)}},step:function(a,d){var e,c,f=d.prop;c=b.current;var g=c.wrapSpace,h=c.skinSpace;if("width"===f||"height"===f)e=d.end===d.start?1:(a-d.start)/(d.end-d.start),b.isClosing&&(e=1-e),c="width"===f?c.wPadding:c.hPadding,c=a-c,b.skin[f](l("width"===f?c:c-g*e)),b.inner[f](l("width"===
+f?c:c-g*e-h*e))},zoomIn:function(){var a=b.current,d=a.pos,e=a.openEffect,c="elastic"===e,k=f.extend({opacity:1},d);delete k.position;c?(d=this.getOrigPosition(),a.openOpacity&&(d.opacity=0.1)):"fade"===e&&(d.opacity=0.1);b.wrap.css(d).animate(k,{duration:"none"===e?0:a.openSpeed,easing:a.openEasing,step:c?this.step:null,complete:b._afterZoomIn})},zoomOut:function(){var a=b.current,d=a.closeEffect,e="elastic"===d,c={opacity:0.1};e&&(c=this.getOrigPosition(),a.closeOpacity&&(c.opacity=0.1));b.wrap.animate(c,
+{duration:"none"===d?0:a.closeSpeed,easing:a.closeEasing,step:e?this.step:null,complete:b._afterZoomOut})},changeIn:function(){var a=b.current,d=a.nextEffect,e=a.pos,c={opacity:1},f=b.direction,g;e.opacity=0.1;"elastic"===d&&(g="down"===f||"up"===f?"top":"left","down"===f||"right"===f?(e[g]=w(l(e[g])-200),c[g]="+=200px"):(e[g]=w(l(e[g])+200),c[g]="-=200px"));"none"===d?b._afterZoomIn():b.wrap.css(e).animate(c,{duration:a.nextSpeed,easing:a.nextEasing,complete:b._afterZoomIn})},changeOut:function(){var a=
+b.previous,d=a.prevEffect,e={opacity:0.1},c=b.direction;"elastic"===d&&(e["down"===c||"up"===c?"top":"left"]=("up"===c||"left"===c?"-":"+")+"=200px");a.wrap.animate(e,{duration:"none"===d?0:a.prevSpeed,easing:a.prevEasing,complete:function(){f(this).trigger("onReset").remove()}})}};b.helpers.overlay={defaults:{closeClick:!0,speedOut:200,showEarly:!0,css:{},locked:!s,fixed:!0},overlay:null,fixed:!1,el:f("html"),create:function(a){a=f.extend({},this.defaults,a);this.overlay&&this.close();this.overlay=
+f('<div class="fancybox-overlay"></div>').appendTo(b.coming?b.coming.parent:a.parent);this.fixed=!1;a.fixed&&b.defaults.fixed&&(this.overlay.addClass("fancybox-overlay-fixed"),this.fixed=!0)},open:function(a){var d=this;a=f.extend({},this.defaults,a);this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(a);this.fixed||(n.bind("resize.overlay",f.proxy(this.update,this)),this.update());a.closeClick&&this.overlay.bind("click.overlay",function(a){if(f(a.target).hasClass("fancybox-overlay"))return b.isActive?
+b.close():d.close(),!1});this.overlay.css(a.css).show()},close:function(){var a,b;n.unbind("resize.overlay");this.el.hasClass("fancybox-lock")&&(f(".fancybox-margin").removeClass("fancybox-margin"),a=n.scrollTop(),b=n.scrollLeft(),this.el.removeClass("fancybox-lock"),n.scrollTop(a).scrollLeft(b));f(".fancybox-overlay").remove().hide();f.extend(this,{overlay:null,fixed:!1})},update:function(){var a="100%",b;this.overlay.width(a).height("100%");I?(b=Math.max(G.documentElement.offsetWidth,G.body.offsetWidth),
+p.width()>b&&(a=p.width())):p.width()>n.width()&&(a=p.width());this.overlay.width(a).height(p.height())},onReady:function(a,b){var e=this.overlay;f(".fancybox-overlay").stop(!0,!0);e||this.create(a);a.locked&&(this.fixed&&b.fixed)&&(e||(this.margin=p.height()>n.height()?f("html").css("margin-right").replace("px",""):!1),b.locked=this.overlay.append(b.wrap),b.fixed=!1);!0===a.showEarly&&this.beforeShow.apply(this,arguments)},beforeShow:function(a,b){var e,c;b.locked&&(!1!==this.margin&&(f("*").filter(function(){return"fixed"===
+f(this).css("position")&&!f(this).hasClass("fancybox-overlay")&&!f(this).hasClass("fancybox-wrap")}).addClass("fancybox-margin"),this.el.addClass("fancybox-margin")),e=n.scrollTop(),c=n.scrollLeft(),this.el.addClass("fancybox-lock"),n.scrollTop(e).scrollLeft(c));this.open(a)},onUpdate:function(){this.fixed||this.update()},afterClose:function(a){this.overlay&&!b.coming&&this.overlay.fadeOut(a.speedOut,f.proxy(this.close,this))}};b.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(a){var d=
+b.current,e=d.title,c=a.type;f.isFunction(e)&&(e=e.call(d.element,d));if(q(e)&&""!==f.trim(e)){d=f('<div class="fancybox-title fancybox-title-'+c+'-wrap">'+e+"</div>");switch(c){case "inside":c=b.skin;break;case "outside":c=b.wrap;break;case "over":c=b.inner;break;default:c=b.skin,d.appendTo("body"),I&&d.width(d.width()),d.wrapInner('<span class="child"></span>'),b.current.margin[2]+=Math.abs(l(d.css("margin-bottom")))}d["top"===a.position?"prependTo":"appendTo"](c)}}};f.fn.fancybox=function(a){var d,
+e=f(this),c=this.selector||"",k=function(g){var h=f(this).blur(),j=d,k,l;!g.ctrlKey&&(!g.altKey&&!g.shiftKey&&!g.metaKey)&&!h.is(".fancybox-wrap")&&(k=a.groupAttr||"data-fancybox-group",l=h.attr(k),l||(k="rel",l=h.get(0)[k]),l&&(""!==l&&"nofollow"!==l)&&(h=c.length?f(c):e,h=h.filter("["+k+'="'+l+'"]'),j=h.index(this)),a.index=j,!1!==b.open(h,a)&&g.preventDefault())};a=a||{};d=a.index||0;!c||!1===a.live?e.unbind("click.fb-start").bind("click.fb-start",k):p.undelegate(c,"click.fb-start").delegate(c+
+":not('.fancybox-item, .fancybox-nav')","click.fb-start",k);this.filter("[data-fancybox-start=1]").trigger("click");return this};p.ready(function(){var a,d;f.scrollbarWidth===v&&(f.scrollbarWidth=function(){var a=f('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),b=a.children(),b=b.innerWidth()-b.height(99).innerWidth();a.remove();return b});if(f.support.fixedPosition===v){a=f.support;d=f('<div style="position:fixed;top:20px;"></div>').appendTo("body");var e=20===
+d[0].offsetTop||15===d[0].offsetTop;d.remove();a.fixedPosition=e}f.extend(b.defaults,{scrollbarWidth:f.scrollbarWidth(),fixed:f.support.fixedPosition,parent:f("body")});a=f(r).width();J.addClass("fancybox-lock-test");d=f(r).width();J.removeClass("fancybox-lock-test");f("<style type='text/css'>.fancybox-margin{margin-right:"+(d-a)+"px;}</style>").appendTo("head")})})(window,document,jQuery);

+ 1 - 0
assets/lib/highlight/highlight.min.css

@@ -0,0 +1 @@
+.hljs{overflow-x:auto;background:#f5f5f5}.hljs,.hljs-subst{color:#444}.hljs-comment{color:#888888}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}

File diff suppressed because it is too large
+ 1 - 0
assets/lib/highlight/highlight.min.js


File diff suppressed because it is too large
+ 3 - 0
assets/lib/jquery/jquery.min.js


+ 139 - 0
assets/lib/jquery/store.js

@@ -0,0 +1,139 @@
+/* Copyright (c) 2010 Marcus Westin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.  
+ */
+var store=function(){var b={},e=window,g=e.document,c;b.set=function(){};b.get=function(){};b.remove=function(){};b.clear=function(){};b.transact=function(a,d){var f=b.get(a);if(typeof f=="undefined")f={};d(f);b.set(a,f)};b.serialize=function(a){return JSON.stringify(a)};b.deserialize=function(a){if(typeof a=="string")return JSON.parse(a)};var h;try{h="localStorage"in e&&e.localStorage}catch(k){h=false}if(h){c=e.localStorage;b.set=function(a,d){c.setItem(a,b.serialize(d))};b.get=function(a){return b.deserialize(c.getItem(a))};
+b.remove=function(a){c.removeItem(a)};b.clear=function(){c.clear()}}else{var i;try{i="globalStorage"in e&&e.globalStorage&&e.globalStorage[e.location.hostname]}catch(l){i=false}if(i){c=e.globalStorage[e.location.hostname];b.set=function(a,d){c[a]=b.serialize(d)};b.get=function(a){return b.deserialize(c[a]&&c[a].value)};b.remove=function(a){delete c[a]};b.clear=function(){for(var a in c)delete c[a]}}else if(g.documentElement.addBehavior){c=g.createElement("div");e=function(a){return function(){var d=
+Array.prototype.slice.call(arguments,0);d.unshift(c);g.body.appendChild(c);c.addBehavior("#default#userData");c.load("localStorage");d=a.apply(b,d);g.body.removeChild(c);return d}};b.set=e(function(a,d,f){a.setAttribute(d,b.serialize(f));a.save("localStorage")});b.get=e(function(a,d){return b.deserialize(a.getAttribute(d))});b.remove=e(function(a,d){a.removeAttribute(d);a.save("localStorage")});b.clear=e(function(a){var d=a.XMLDocument.documentElement.attributes;a.load("localStorage");for(var f=0,
+j;j=d[f];f++)a.removeAttribute(j.name);a.save("localStorage")})}}return b}();
+
+/*!
+ * jQuery Cookie Plugin v1.4.1
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2006, 2014 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+	if (typeof define === 'function' && define.amd) {
+		// AMD (Register as an anonymous module)
+		define(['jquery'], factory);
+	} else if (typeof exports === 'object') {
+		// Node/CommonJS
+		module.exports = factory(require('jquery'));
+	} else {
+		// Browser globals
+		factory(jQuery);
+	}
+}(function ($) {
+
+	var pluses = /\+/g;
+
+	function encode(s) {
+		return config.raw ? s : encodeURIComponent(s);
+	}
+
+	function decode(s) {
+		return config.raw ? s : decodeURIComponent(s);
+	}
+
+	function stringifyCookieValue(value) {
+		return encode(config.json ? JSON.stringify(value) : String(value));
+	}
+
+	function parseCookieValue(s) {
+		if (s.indexOf('"') === 0) {
+			// This is a quoted cookie as according to RFC2068, unescape...
+			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+		}
+
+		try {
+			// Replace server-side written pluses with spaces.
+			// If we can't decode the cookie, ignore it, it's unusable.
+			// If we can't parse the cookie, ignore it, it's unusable.
+			s = decodeURIComponent(s.replace(pluses, ' '));
+			return config.json ? JSON.parse(s) : s;
+		} catch(e) {}
+	}
+
+	function read(s, converter) {
+		var value = config.raw ? s : parseCookieValue(s);
+		return $.isFunction(converter) ? converter(value) : value;
+	}
+
+	var config = $.cookie = function (key, value, options) {
+
+		// Write
+
+		if (arguments.length > 1 && !$.isFunction(value)) {
+			options = $.extend({}, config.defaults, options);
+
+			if (typeof options.expires === 'number') {
+				var days = options.expires, t = options.expires = new Date();
+				t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
+			}
+
+			return (document.cookie = [
+				encode(key), '=', stringifyCookieValue(value),
+				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+				options.path    ? '; path=' + options.path : '',
+				options.domain  ? '; domain=' + options.domain : '',
+				options.secure  ? '; secure' : ''
+			].join(''));
+		}
+
+		// Read
+
+		var result = key ? undefined : {},
+			// To prevent the for loop in the first place assign an empty array
+			// in case there are no cookies at all. Also prevents odd result when
+			// calling $.cookie().
+			cookies = document.cookie ? document.cookie.split('; ') : [],
+			i = 0,
+			l = cookies.length;
+
+		for (; i < l; i++) {
+			var parts = cookies[i].split('='),
+				name = decode(parts.shift()),
+				cookie = parts.join('=');
+
+			if (key === name) {
+				// If second argument (value) is a function it's a converter...
+				result = read(cookie, value);
+				break;
+			}
+
+			// Prevent storing a cookie that we couldn't decode.
+			if (!key && (cookie = read(cookie)) !== undefined) {
+				result[name] = cookie;
+			}
+		}
+
+		return result;
+	};
+
+	config.defaults = {};
+
+	$.removeCookie = function (key, options) {
+		// Must not alter options, thus extending a fresh object...
+		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
+		return !$.cookie(key);
+	};
+
+}));

File diff suppressed because it is too large
+ 1 - 0
assets/lib/kindeditor/kindeditor-all-min.js


+ 9849 - 0
assets/lib/kindeditor/kindeditor-all.js

@@ -0,0 +1,9849 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2016 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @website http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+* @version 4.1.11 (2016-03-31)
+*******************************************************************************/
+(function (window, undefined) {
+	if (window.KindEditor) {
+		return;
+	}
+
+
+if (!window.console) {
+	window.console = {};
+}
+if (!console.log) {
+	console.log = function () {};
+}
+var _VERSION = '4.1.11 (2016-03-31)',
+	_ua = navigator.userAgent.toLowerCase(),
+	_IE = _ua.indexOf('msie') > -1 && _ua.indexOf('opera') == -1,
+	_NEWIE = _ua.indexOf('msie') == -1 && _ua.indexOf('trident') > -1,
+	_GECKO = _ua.indexOf('gecko') > -1 && _ua.indexOf('khtml') == -1,
+	_WEBKIT = _ua.indexOf('applewebkit') > -1,
+	_OPERA = _ua.indexOf('opera') > -1,
+	_MOBILE = _ua.indexOf('mobile') > -1,
+	_IOS = /ipad|iphone|ipod/.test(_ua),
+	_QUIRKS = document.compatMode != 'CSS1Compat',
+	_IERANGE = !window.getSelection,
+	_matches = /(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua),
+	_V = _matches ? _matches[1] : '0',
+	_TIME = new Date().getTime();
+function _isArray(val) {
+	if (!val) {
+		return false;
+	}
+	return Object.prototype.toString.call(val) === '[object Array]';
+}
+function _isFunction(val) {
+	if (!val) {
+		return false;
+	}
+	return Object.prototype.toString.call(val) === '[object Function]';
+}
+function _inArray(val, arr) {
+	for (var i = 0, len = arr.length; i < len; i++) {
+		if (val === arr[i]) {
+			return i;
+		}
+	}
+	return -1;
+}
+function _each(obj, fn) {
+	if (_isArray(obj)) {
+		for (var i = 0, len = obj.length; i < len; i++) {
+			if (fn.call(obj[i], i, obj[i]) === false) {
+				break;
+			}
+		}
+	} else {
+		for (var key in obj) {
+			if (obj.hasOwnProperty(key)) {
+				if (fn.call(obj[key], key, obj[key]) === false) {
+					break;
+				}
+			}
+		}
+	}
+}
+function _trim(str) {
+	return str.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, '');
+}
+function _inString(val, str, delimiter) {
+	delimiter = delimiter === undefined ? ',' : delimiter;
+	return (delimiter + str + delimiter).indexOf(delimiter + val + delimiter) >= 0;
+}
+function _addUnit(val, unit) {
+	unit = unit || 'px';
+	return val && /^-?\d+(?:\.\d+)?$/.test(val) ? val + unit : val;
+}
+function _removeUnit(val) {
+	var match;
+	return val && (match = /(\d+)/.exec(val)) ? parseInt(match[1], 10) : 0;
+}
+function _escape(val) {
+	return val.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
+}
+function _unescape(val) {
+	return val.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&amp;/g, '&');
+}
+function _toCamel(str) {
+	var arr = str.split('-');
+	str = '';
+	_each(arr, function(key, val) {
+		str += (key > 0) ? val.charAt(0).toUpperCase() + val.substr(1) : val;
+	});
+	return str;
+}
+function _toHex(val) {
+	function hex(d) {
+		var s = parseInt(d, 10).toString(16).toUpperCase();
+		return s.length > 1 ? s : '0' + s;
+	}
+	return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ig,
+		function($0, $1, $2, $3) {
+			return '#' + hex($1) + hex($2) + hex($3);
+		}
+	);
+}
+function _toMap(val, delimiter) {
+	delimiter = delimiter === undefined ? ',' : delimiter;
+	var map = {}, arr = _isArray(val) ? val : val.split(delimiter), match;
+	_each(arr, function(key, val) {
+		if ((match = /^(\d+)\.\.(\d+)$/.exec(val))) {
+			for (var i = parseInt(match[1], 10); i <= parseInt(match[2], 10); i++) {
+				map[i.toString()] = true;
+			}
+		} else {
+			map[val] = true;
+		}
+	});
+	return map;
+}
+function _toArray(obj, offset) {
+	return Array.prototype.slice.call(obj, offset || 0);
+}
+function _undef(val, defaultVal) {
+	return val === undefined ? defaultVal : val;
+}
+function _invalidUrl(url) {
+	return !url || /[<>"]/.test(url);
+}
+function _addParam(url, param) {
+	return url.indexOf('?') >= 0 ? url + '&' + param : url + '?' + param;
+}
+function _extend(child, parent, proto) {
+	if (!proto) {
+		proto = parent;
+		parent = null;
+	}
+	var childProto;
+	if (parent) {
+		var fn = function () {};
+		fn.prototype = parent.prototype;
+		childProto = new fn();
+		_each(proto, function(key, val) {
+			childProto[key] = val;
+		});
+	} else {
+		childProto = proto;
+	}
+	childProto.constructor = child;
+	child.prototype = childProto;
+	child.parent = parent ? parent.prototype : null;
+}
+

+function _json(text) {
+	var match;
+	if ((match = /\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))) {
+		text = match[0];
+	}
+	var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+	cx.lastIndex = 0;
+	if (cx.test(text)) {
+		text = text.replace(cx, function (a) {
+			return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+		});
+	}
+	if (/^[\],:{}\s]*$/.
+	test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+	replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+	replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+		return eval('(' + text + ')');
+	}
+	throw 'JSON parse error';
+}
+var _round = Math.round;
+var K = {
+	DEBUG : false,
+	VERSION : _VERSION,
+	IE : _IE,
+	GECKO : _GECKO,
+	WEBKIT : _WEBKIT,
+	OPERA : _OPERA,
+	V : _V,
+	TIME : _TIME,
+	each : _each,
+	isArray : _isArray,
+	isFunction : _isFunction,
+	inArray : _inArray,
+	inString : _inString,
+	trim : _trim,
+	addUnit : _addUnit,
+	removeUnit : _removeUnit,
+	escape : _escape,
+	unescape : _unescape,
+	toCamel : _toCamel,
+	toHex : _toHex,
+	toMap : _toMap,
+	toArray : _toArray,
+	undef : _undef,
+	invalidUrl : _invalidUrl,
+	addParam : _addParam,
+	extend : _extend,
+	json : _json
+};
+var _INLINE_TAG_MAP = _toMap('a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'),
+	_BLOCK_TAG_MAP = _toMap('address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul'),
+	_SINGLE_TAG_MAP = _toMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'),
+	_STYLE_TAG_MAP = _toMap('b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u'),
+	_CONTROL_TAG_MAP = _toMap('img,table,input,textarea,button'),
+	_PRE_TAG_MAP = _toMap('pre,style,script'),
+	_NOSPLIT_TAG_MAP = _toMap('html,head,body,td,tr,table,ol,ul,li'),
+	_AUTOCLOSE_TAG_MAP = _toMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'),
+	_FILL_ATTR_MAP = _toMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'),
+	_VALUE_TAG_MAP = _toMap('input,button,textarea,select');
+
+
+function _getBasePath() {
+	var els = document.getElementsByTagName('script'), src;
+	for (var i = 0, len = els.length; i < len; i++) {
+		src = els[i].src || '';
+		if (/kindeditor[\w\-\.]*\.js/.test(src)) {
+			return src.substring(0, src.lastIndexOf('/') + 1);
+		}
+	}
+	return '';
+}
+K.basePath = _getBasePath();
+K.options = {
+	designMode : true,
+	fullscreenMode : false,
+	filterMode : true,
+	wellFormatMode : true,
+	shadowMode : true,
+	loadStyleMode : true,
+	basePath : K.basePath,
+	themesPath : K.basePath + 'themes/',
+	langPath : K.basePath + 'lang/',
+	pluginsPath : K.basePath + 'plugins/',
+	themeType : 'default',
+	langType : 'zh-CN',
+	urlType : '',
+	newlineTag : 'p',
+	resizeType : 2,
+	syncType : 'form',
+	pasteType : 2,
+	dialogAlignType : 'page',
+	useContextmenu : true,
+	fullscreenShortcut : false,
+	bodyClass : 'ke-content',
+	indentChar : '\t',
+	cssPath : '',
+	cssData : '',
+	minWidth : 650,
+	minHeight : 100,
+	minChangeSize : 50,
+	zIndex : 811213,
+	items : [
+		'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
+		'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',
+		'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
+		'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
+		'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
+		'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
+		'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
+		'anchor', 'link', 'unlink', '|', 'about'
+	],
+	noDisableItems : ['source', 'fullscreen'],
+	colorTable : [
+		['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'],
+		['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'],
+		['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'],
+		['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000']
+	],
+	fontSizeTable : ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'],
+	htmlTags : {
+		font : ['id', 'class', 'color', 'size', 'face', '.background-color'],
+		span : [
+			'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background',
+			'.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height'
+		],
+		div : [
+			'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color',
+			'.background-color', '.font-size', '.font-family', '.font-weight', '.background',
+			'.font-style', '.text-decoration', '.vertical-align', '.margin-left'
+		],
+		table: [
+			'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor',
+			'.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color',
+			'.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background',
+			'.width', '.height', '.border-collapse'
+		],
+		'td,th': [
+			'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor',
+			'.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight',
+			'.font-style', '.text-decoration', '.vertical-align', '.background', '.border'
+		],
+		a : ['id', 'class', 'href', 'target', 'name'],
+		embed : ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess', 'wmode'],
+		img : ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'],
+		'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [
+			'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background',
+			'.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left'
+		],
+		pre : ['id', 'class'],
+		hr : ['id', 'class', '.page-break-after'],
+		'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : ['id', 'class'],
+		iframe : ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height']
+	},
+	layout : '<div class="container"><div class="toolbar"></div><div class="edit"></div><div class="statusbar"></div></div>'
+};
+
+
+var _useCapture = false;
+

+var _INPUT_KEY_MAP = _toMap('8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222');

+var _CURSORMOVE_KEY_MAP = _toMap('33..40');

+var _CHANGE_KEY_MAP = {};
+_each(_INPUT_KEY_MAP, function(key, val) {
+	_CHANGE_KEY_MAP[key] = val;
+});
+_each(_CURSORMOVE_KEY_MAP, function(key, val) {
+	_CHANGE_KEY_MAP[key] = val;
+});
+

+function _bindEvent(el, type, fn) {
+	if (el.addEventListener){
+		el.addEventListener(type, fn, _useCapture);
+	} else if (el.attachEvent){
+		el.attachEvent('on' + type, fn);
+	}
+}

+function _unbindEvent(el, type, fn) {
+	if (el.removeEventListener){
+		el.removeEventListener(type, fn, _useCapture);
+	} else if (el.detachEvent){
+		el.detachEvent('on' + type, fn);
+	}
+}
+var _EVENT_PROPS = ('altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,' +
+	'data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,' +
+	'pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which').split(',');
+

+function KEvent(el, event) {
+	this.init(el, event);
+}
+_extend(KEvent, {
+	init : function(el, event) {
+		var self = this, doc = el.ownerDocument || el.document || el;
+		self.event = event;
+		_each(_EVENT_PROPS, function(key, val) {
+			self[val] = event[val];
+		});
+		if (!self.target) {
+			self.target = self.srcElement || doc;
+		}
+		if (self.target.nodeType === 3) {
+			self.target = self.target.parentNode;
+		}
+		if (!self.relatedTarget && self.fromElement) {
+			self.relatedTarget = self.fromElement === self.target ? self.toElement : self.fromElement;
+		}
+		if (self.pageX == null && self.clientX != null) {
+			var d = doc.documentElement, body = doc.body;
+			self.pageX = self.clientX + (d && d.scrollLeft || body && body.scrollLeft || 0) - (d && d.clientLeft || body && body.clientLeft || 0);
+			self.pageY = self.clientY + (d && d.scrollTop  || body && body.scrollTop  || 0) - (d && d.clientTop  || body && body.clientTop  || 0);
+		}
+		if (!self.which && ((self.charCode || self.charCode === 0) ? self.charCode : self.keyCode)) {
+			self.which = self.charCode || self.keyCode;
+		}
+		if (!self.metaKey && self.ctrlKey) {
+			self.metaKey = self.ctrlKey;
+		}
+		if (!self.which && self.button !== undefined) {
+			self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : (self.button & 4 ? 2 : 0)));
+		}
+		switch (self.which) {
+		case 186 :
+			self.which = 59;
+			break;
+		case 187 :
+		case 107 :
+		case 43 :
+			self.which = 61;
+			break;
+		case 189 :
+		case 45 :
+			self.which = 109;
+			break;
+		case 42 :
+			self.which = 106;
+			break;
+		case 47 :
+			self.which = 111;
+			break;
+		case 78 :
+			self.which = 110;
+			break;
+		}
+		if (self.which >= 96 && self.which <= 105) {
+			self.which -= 48;
+		}
+	},
+	preventDefault : function() {
+		var ev = this.event;
+		if (ev.preventDefault) {
+			ev.preventDefault();
+		} else {
+			ev.returnValue = false;
+		}
+	},
+	stopPropagation : function() {
+		var ev = this.event;
+		if (ev.stopPropagation) {
+			ev.stopPropagation();
+		} else {
+			ev.cancelBubble = true;
+		}
+	},
+	stop : function() {
+		this.preventDefault();
+		this.stopPropagation();
+	}
+});
+var _eventExpendo = 'kindeditor_' + _TIME, _eventId = 0, _eventData = {};
+function _getId(el) {
+	return el[_eventExpendo] || null;
+}
+function _setId(el) {
+	el[_eventExpendo] = ++_eventId;
+	return _eventId;
+}
+function _removeId(el) {
+	try {
+		delete el[_eventExpendo];
+	} catch(e) {
+		if (el.removeAttribute) {
+			el.removeAttribute(_eventExpendo);
+		}
+	}
+}
+function _bind(el, type, fn) {
+	if (type.indexOf(',') >= 0) {
+		_each(type.split(','), function() {
+			_bind(el, this, fn);
+		});
+		return;
+	}
+	var id = _getId(el);
+	if (!id) {
+		id = _setId(el);
+	}
+	if (_eventData[id] === undefined) {
+		_eventData[id] = {};
+	}
+	var events = _eventData[id][type];
+	if (events && events.length > 0) {
+		_unbindEvent(el, type, events[0]);
+	} else {
+		_eventData[id][type] = [];
+		_eventData[id].el = el;
+	}
+	events = _eventData[id][type];
+	if (events.length === 0) {
+		events[0] = function(e) {
+			var kevent = e ? new KEvent(el, e) : undefined;
+			_each(events, function(i, event) {
+				if (i > 0 && event) {
+					event.call(el, kevent);
+				}
+			});
+		};
+	}
+	if (_inArray(fn, events) < 0) {
+		events.push(fn);
+	}
+	_bindEvent(el, type, events[0]);
+}
+function _unbind(el, type, fn) {
+	if (type && type.indexOf(',') >= 0) {
+		_each(type.split(','), function() {
+			_unbind(el, this, fn);
+		});
+		return;
+	}
+	var id = _getId(el);
+	if (!id) {
+		return;
+	}
+	if (type === undefined) {
+		if (id in _eventData) {
+			_each(_eventData[id], function(key, events) {
+				if (key != 'el' && events.length > 0) {
+					_unbindEvent(el, key, events[0]);
+				}
+			});
+			delete _eventData[id];
+			_removeId(el);
+		}
+		return;
+	}
+	if (!_eventData[id]) {
+		return;
+	}
+	var events = _eventData[id][type];
+	if (events && events.length > 0) {
+		if (fn === undefined) {
+			_unbindEvent(el, type, events[0]);
+			delete _eventData[id][type];
+		} else {
+			_each(events, function(i, event) {
+				if (i > 0 && event === fn) {
+					events.splice(i, 1);
+				}
+			});
+			if (events.length == 1) {
+				_unbindEvent(el, type, events[0]);
+				delete _eventData[id][type];
+			}
+		}
+		var count = 0;
+		_each(_eventData[id], function() {
+			count++;
+		});
+		if (count < 2) {
+			delete _eventData[id];
+			_removeId(el);
+		}
+	}
+}
+function _fire(el, type) {
+	if (type.indexOf(',') >= 0) {
+		_each(type.split(','), function() {
+			_fire(el, this);
+		});
+		return;
+	}
+	var id = _getId(el);
+	if (!id) {
+		return;
+	}
+	var events = _eventData[id][type];
+	if (_eventData[id] && events && events.length > 0) {
+		events[0]();
+	}
+}
+function _ctrl(el, key, fn) {
+	var self = this;
+	key = /^\d{2,}$/.test(key) ? key : key.toUpperCase().charCodeAt(0);
+	_bind(el, 'keydown', function(e) {
+		if (e.ctrlKey && e.which == key && !e.shiftKey && !e.altKey) {
+			fn.call(el);
+			e.stop();
+		}
+	});
+}
+var _readyFinished = false;
+function _ready(fn) {
+	if (_readyFinished) {
+		fn(KindEditor);
+		return;
+	}
+	var loaded = false;
+	function readyFunc() {
+		if (!loaded) {
+			loaded = true;
+			fn(KindEditor);
+			_readyFinished = true;
+		}
+	}
+	function ieReadyFunc() {
+		if (!loaded) {
+			try {
+				document.documentElement.doScroll('left');
+			} catch(e) {
+				setTimeout(ieReadyFunc, 100);
+				return;
+			}
+			readyFunc();
+		}
+	}
+	function ieReadyStateFunc() {
+		if (document.readyState === 'complete') {
+			readyFunc();
+		}
+	}
+	if (document.addEventListener) {
+		_bind(document, 'DOMContentLoaded', readyFunc);
+	} else if (document.attachEvent) {
+		_bind(document, 'readystatechange', ieReadyStateFunc);
+		var toplevel = false;
+		try {
+			toplevel = window.frameElement == null;
+		} catch(e) {}
+		if (document.documentElement.doScroll && toplevel) {
+			ieReadyFunc();
+		}
+	}
+	_bind(window, 'load', readyFunc);
+}
+if (window.attachEvent) {
+	window.attachEvent('onunload', function() {
+		_each(_eventData, function(key, events) {
+			if (events.el) {
+				_unbind(events.el);
+			}
+		});
+	});
+}
+K.ctrl = _ctrl;
+K.ready = _ready;
+
+function _getCssList(css) {
+	var list = {},
+		reg = /\s*([\w\-]+)\s*:([^;]*)(;|$)/g,
+		match;
+	while ((match = reg.exec(css))) {
+		var key = _trim(match[1].toLowerCase()),
+			val = _trim(_toHex(match[2]));
+		list[key] = val;
+	}
+	return list;
+}
+function _getAttrList(tag) {
+	var list = {},
+		reg = /\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g,
+		match;
+	while ((match = reg.exec(tag))) {
+		var key = (match[1] || match[2] || match[4] || match[6]).toLowerCase(),
+			val = (match[2] ? match[3] : (match[4] ? match[5] : match[7])) || '';
+		list[key] = val;
+	}
+	return list;
+}
+function _addClassToTag(tag, className) {
+	if (/\s+class\s*=/.test(tag)) {
+		tag = tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/, function($0, $1, $2, $3) {
+			if ((' ' + $2 + ' ').indexOf(' ' + className + ' ') < 0) {
+				return $2 === '' ? $1 + className + $3 : $1 + $2 + ' ' + className + $3;
+			} else {
+				return $0;
+			}
+		});
+	} else {
+		tag = tag.substr(0, tag.length - 1) + ' class="' + className + '">';
+	}
+	return tag;
+}
+function _formatCss(css) {
+	var str = '';
+	_each(_getCssList(css), function(key, val) {
+		str += key + ':' + val + ';';
+	});
+	return str;
+}
+function _formatUrl(url, mode, host, pathname) {
+	mode = _undef(mode, '').toLowerCase();
+	if (url.substr(0, 5) != 'data:') {
+		url = url.replace(/([^:])\/\//g, '$1/');
+	}
+	if (_inArray(mode, ['absolute', 'relative', 'domain']) < 0) {
+		return url;
+	}
+	host = host || location.protocol + '//' + location.host;
+	if (pathname === undefined) {
+		var m = location.pathname.match(/^(\/.*)\//);
+		pathname = m ? m[1] : '';
+	}
+	var match;
+	if ((match = /^(\w+:\/\/[^\/]*)/.exec(url))) {
+		if (match[1] !== host) {
+			return url;
+		}
+	} else if (/^\w+:/.test(url)) {
+		return url;
+	}
+	function getRealPath(path) {
+		var parts = path.split('/'), paths = [];
+		for (var i = 0, len = parts.length; i < len; i++) {
+			var part = parts[i];
+			if (part == '..') {
+				if (paths.length > 0) {
+					paths.pop();
+				}
+			} else if (part !== '' && part != '.') {
+				paths.push(part);
+			}
+		}
+		return '/' + paths.join('/');
+	}
+	if (/^\//.test(url)) {
+		url = host + getRealPath(url.substr(1));
+	} else if (!/^\w+:\/\//.test(url)) {
+		url = host + getRealPath(pathname + '/' + url);
+	}
+	function getRelativePath(path, depth) {
+		if (url.substr(0, path.length) === path) {
+			var arr = [];
+			for (var i = 0; i < depth; i++) {
+				arr.push('..');
+			}
+			var prefix = '.';
+			if (arr.length > 0) {
+				prefix += '/' + arr.join('/');
+			}
+			if (pathname == '/') {
+				prefix += '/';
+			}
+			return prefix + url.substr(path.length);
+		} else {
+			if ((match = /^(.*)\//.exec(path))) {
+				return getRelativePath(match[1], ++depth);
+			}
+		}
+	}
+	if (mode === 'relative') {
+		url = getRelativePath(host + pathname, 0).substr(2);
+	} else if (mode === 'absolute') {
+		if (url.substr(0, host.length) === host) {
+			url = url.substr(host.length);
+		}
+	}
+	return url;
+}
+function _formatHtml(html, htmlTags, urlType, wellFormatted, indentChar) {
+	if (html == null) {
+		html = '';
+	}
+	urlType = urlType || '';
+	wellFormatted = _undef(wellFormatted, false);
+	indentChar = _undef(indentChar, '\t');
+	var fontSizeList = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(',');
+	html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) {
+		return $1 + $2.replace(/<(?:br|br\s[^>]*)>/ig, '\n') + $3;
+	});
+	html = html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/ig, '</p>');
+	html = html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/ig, '$1<br />$2');
+	html = html.replace(/\u200B/g, '');
+	html = html.replace(/\u00A9/g, '&copy;');
+	html = html.replace(/\u00AE/g, '&reg;');
+	html = html.replace(/\u2003/g, '&emsp;');
+	html = html.replace(/\u3000/g, '&emsp;');
+	html = html.replace(/<[^>]+/g, function($0) {
+		return $0.replace(/\s+/g, ' ');
+	});
+	var htmlTagMap = {};
+	if (htmlTags) {
+		_each(htmlTags, function(key, val) {
+			var arr = key.split(',');
+			for (var i = 0, len = arr.length; i < len; i++) {
+				htmlTagMap[arr[i]] = _toMap(val);
+			}
+		});
+		if (!htmlTagMap.script) {
+			html = html.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/ig, '');
+		}
+		if (!htmlTagMap.style) {
+			html = html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/ig, '');
+		}
+	}
+	var re = /(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g;
+	var tagStack = [];
+	html = html.replace(re, function($0, $1, $2, $3, $4, $5, $6) {
+		var full = $0,
+			startNewline = $1 || '',
+			startSlash = $2 || '',
+			tagName = $3.toLowerCase(),
+			attr = $4 || '',
+			endSlash = $5 ? ' ' + $5 : '',
+			endNewline = $6 || '';
+		if (htmlTags && !htmlTagMap[tagName]) {
+			return '';
+		}
+		if (endSlash === '' && _SINGLE_TAG_MAP[tagName]) {
+			endSlash = ' /';
+		}
+		if (_INLINE_TAG_MAP[tagName]) {
+			if (startNewline) {
+				startNewline = ' ';
+			}
+			if (endNewline) {
+				endNewline = ' ';
+			}
+		}
+		if (_PRE_TAG_MAP[tagName]) {
+			if (startSlash) {
+				endNewline = '\n';
+			} else {
+				startNewline = '\n';
+			}
+		}
+		if (wellFormatted && tagName == 'br') {
+			endNewline = '\n';
+		}
+		if (_BLOCK_TAG_MAP[tagName] && !_PRE_TAG_MAP[tagName]) {
+			if (wellFormatted) {
+				if (startSlash && tagStack.length > 0 && tagStack[tagStack.length - 1] === tagName) {
+					tagStack.pop();
+				} else {
+					tagStack.push(tagName);
+				}
+				startNewline = '\n';
+				endNewline = '\n';
+				for (var i = 0, len = startSlash ? tagStack.length : tagStack.length - 1; i < len; i++) {
+					startNewline += indentChar;
+					if (!startSlash) {
+						endNewline += indentChar;
+					}
+				}
+				if (endSlash) {
+					tagStack.pop();
+				} else if (!startSlash) {
+					endNewline += indentChar;
+				}
+			} else {
+				startNewline = endNewline = '';
+			}
+		}
+		if (attr !== '') {
+			var attrMap = _getAttrList(full);
+			if (tagName === 'font') {
+				var fontStyleMap = {}, fontStyle = '';
+				_each(attrMap, function(key, val) {
+					if (key === 'color') {
+						fontStyleMap.color = val;
+						delete attrMap[key];
+					}
+					if (key === 'size') {
+						fontStyleMap['font-size'] = fontSizeList[parseInt(val, 10) - 1] || '';
+						delete attrMap[key];
+					}
+					if (key === 'face') {
+						fontStyleMap['font-family'] = val;
+						delete attrMap[key];
+					}
+					if (key === 'style') {
+						fontStyle = val;
+					}
+				});
+				if (fontStyle && !/;$/.test(fontStyle)) {
+					fontStyle += ';';
+				}
+				_each(fontStyleMap, function(key, val) {
+					if (val === '') {
+						return;
+					}
+					if (/\s/.test(val)) {
+						val = "'" + val + "'";
+					}
+					fontStyle += key + ':' + val + ';';
+				});
+				attrMap.style = fontStyle;
+			}
+			_each(attrMap, function(key, val) {
+				if (_FILL_ATTR_MAP[key]) {
+					attrMap[key] = key;
+				}
+				if (_inArray(key, ['src', 'href']) >= 0) {
+					attrMap[key] = _formatUrl(val, urlType);
+				}
+				if (htmlTags && key !== 'style' && !htmlTagMap[tagName]['*'] && !htmlTagMap[tagName][key] ||
+					tagName === 'body' && key === 'contenteditable' ||
+					/^kindeditor_\d+$/.test(key)) {
+					delete attrMap[key];
+				}
+				if (key === 'style' && val !== '') {
+					var styleMap = _getCssList(val);
+					_each(styleMap, function(k, v) {
+						if (htmlTags && !htmlTagMap[tagName].style && !htmlTagMap[tagName]['.' + k]) {
+							delete styleMap[k];
+						}
+					});
+					var style = '';
+					_each(styleMap, function(k, v) {
+						style += k + ':' + v + ';';
+					});
+					attrMap.style = style;
+				}
+			});
+			attr = '';
+			_each(attrMap, function(key, val) {
+				if (key === 'style' && val === '') {
+					return;
+				}
+				val = val.replace(/"/g, '&quot;');
+				attr += ' ' + key + '="' + val + '"';
+			});
+		}
+		if (tagName === 'font') {
+			tagName = 'span';
+		}
+		return startNewline + '<' + startSlash + tagName + attr + endSlash + '>' + endNewline;
+	});
+	html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) {
+		return $1 + $2.replace(/\n/g, '<span id="__kindeditor_pre_newline__">\n') + $3;
+	});
+	html = html.replace(/\n\s*\n/g, '\n');
+	html = html.replace(/<span id="__kindeditor_pre_newline__">\n/g, '\n');
+	return _trim(html);
+}

+function _clearMsWord(html, htmlTags) {
+	html = html.replace(/<meta[\s\S]*?>/ig, '')
+		.replace(/<![\s\S]*?>/ig, '')
+		.replace(/<style[^>]*>[\s\S]*?<\/style>/ig, '')
+		.replace(/<script[^>]*>[\s\S]*?<\/script>/ig, '')
+		.replace(/<w:[^>]+>[\s\S]*?<\/w:[^>]+>/ig, '')
+		.replace(/<o:[^>]+>[\s\S]*?<\/o:[^>]+>/ig, '')
+		.replace(/<xml>[\s\S]*?<\/xml>/ig, '')
+		.replace(/<(?:table|td)[^>]*>/ig, function(full) {
+			return full.replace(/border-bottom:([#\w\s]+)/ig, 'border:$1');
+		});
+	return _formatHtml(html, htmlTags);
+}

+function _mediaType(src) {
+	if (/\.(rm|rmvb)(\?|$)/i.test(src)) {
+		return 'audio/x-pn-realaudio-plugin';
+	}
+	if (/\.(swf|flv)(\?|$)/i.test(src)) {
+		return 'application/x-shockwave-flash';
+	}
+	return 'video/x-ms-asf-plugin';
+}

+function _mediaClass(type) {
+	if (/realaudio/i.test(type)) {
+		return 'ke-rm';
+	}
+	if (/flash/i.test(type)) {
+		return 'ke-flash';
+	}
+	return 'ke-media';
+}
+function _mediaAttrs(srcTag) {
+	return _getAttrList(unescape(srcTag));
+}
+function _mediaEmbed(attrs) {
+	var html = '<embed ';
+	_each(attrs, function(key, val) {
+		html += key + '="' + val + '" ';
+	});
+	html += '/>';
+	return html;
+}
+function _mediaImg(blankPath, attrs) {
+	var width = attrs.width,
+		height = attrs.height,
+		type = attrs.type || _mediaType(attrs.src),
+		srcTag = _mediaEmbed(attrs),
+		style = '';
+	if (/\D/.test(width)) {
+		style += 'width:' + width + ';';
+	} else if (width > 0) {
+		style += 'width:' + width + 'px;';
+	}
+	if (/\D/.test(height)) {
+		style += 'height:' + height + ';';
+	} else if (height > 0) {
+		style += 'height:' + height + 'px;';
+	}
+	var html = '<img class="' + _mediaClass(type) + '" src="' + blankPath + '" ';
+	if (style !== '') {
+		html += 'style="' + style + '" ';
+	}
+	html += 'data-ke-tag="' + escape(srcTag) + '" alt="" />';
+	return html;
+}
+



+function _tmpl(str, data) {
+	var fn = new Function("obj",
+		"var p=[],print=function(){p.push.apply(p,arguments);};" +
+		"with(obj){p.push('" +
+		str.replace(/[\r\t\n]/g, " ")
+			.split("<%").join("\t")
+			.replace(/((^|%>)[^\t]*)'/g, "$1\r")
+			.replace(/\t=(.*?)%>/g, "',$1,'")
+			.split("\t").join("');")
+			.split("%>").join("p.push('")
+			.split("\r").join("\\'") + "');}return p.join('');");
+	return data ? fn(data) : fn;
+}
+K.formatUrl = _formatUrl;
+K.formatHtml = _formatHtml;
+K.getCssList = _getCssList;
+K.getAttrList = _getAttrList;
+K.mediaType = _mediaType;
+K.mediaAttrs = _mediaAttrs;
+K.mediaEmbed = _mediaEmbed;
+K.mediaImg = _mediaImg;
+K.clearMsWord = _clearMsWord;
+K.tmpl = _tmpl;
+
+
+function _contains(nodeA, nodeB) {
+	if (nodeA.nodeType == 9 && nodeB.nodeType != 9) {
+		return true;
+	}
+	while ((nodeB = nodeB.parentNode)) {
+		if (nodeB == nodeA) {
+			return true;
+		}
+	}
+	return false;
+}
+var _getSetAttrDiv = document.createElement('div');
+_getSetAttrDiv.setAttribute('className', 't');
+var _GET_SET_ATTRIBUTE = _getSetAttrDiv.className !== 't';
+function _getAttr(el, key) {
+	key = key.toLowerCase();
+	var val = null;
+	if (!_GET_SET_ATTRIBUTE && el.nodeName.toLowerCase() != 'script') {
+		var div = el.ownerDocument.createElement('div');
+		div.appendChild(el.cloneNode(false));
+		var list = _getAttrList(_unescape(div.innerHTML));
+		if (key in list) {
+			val = list[key];
+		}
+	} else {
+		try {
+			val = el.getAttribute(key, 2);
+		} catch(e) {
+			val = el.getAttribute(key, 1);
+		}
+	}
+	if (key === 'style' && val !== null) {
+		val = _formatCss(val);
+	}
+	return val;
+}
+function _queryAll(expr, root) {
+	var exprList = expr.split(',');
+	if (exprList.length > 1) {
+		var mergedResults = [];
+		_each(exprList, function() {
+			_each(_queryAll(this, root), function() {
+				if (_inArray(this, mergedResults) < 0) {
+					mergedResults.push(this);
+				}
+			});
+		});
+		return mergedResults;
+	}
+	root = root || document;
+	function escape(str) {
+		if (typeof str != 'string') {
+			return str;
+		}
+		return str.replace(/([^\w\-])/g, '\\$1');
+	}
+	function stripslashes(str) {
+		return str.replace(/\\/g, '');
+	}
+	function cmpTag(tagA, tagB) {
+		return tagA === '*' || tagA.toLowerCase() === escape(tagB.toLowerCase());
+	}
+	function byId(id, tag, root) {
+		var arr = [],
+			doc = root.ownerDocument || root,
+			el = doc.getElementById(stripslashes(id));
+		if (el) {
+			if (cmpTag(tag, el.nodeName) && _contains(root, el)) {
+				arr.push(el);
+			}
+		}
+		return arr;
+	}
+	function byClass(className, tag, root) {
+		var doc = root.ownerDocument || root, arr = [], els, i, len, el;
+		if (root.getElementsByClassName) {
+			els = root.getElementsByClassName(stripslashes(className));
+			for (i = 0, len = els.length; i < len; i++) {
+				el = els[i];
+				if (cmpTag(tag, el.nodeName)) {
+					arr.push(el);
+				}
+			}
+		} else if (doc.querySelectorAll) {
+			els = doc.querySelectorAll((root.nodeName !== '#document' ? root.nodeName + ' ' : '') + tag + '.' + className);
+			for (i = 0, len = els.length; i < len; i++) {
+				el = els[i];
+				if (_contains(root, el)) {
+					arr.push(el);
+				}
+			}
+		} else {
+			els = root.getElementsByTagName(tag);
+			className = ' ' + className + ' ';
+			for (i = 0, len = els.length; i < len; i++) {
+				el = els[i];
+				if (el.nodeType == 1) {
+					var cls = el.className;
+					if (cls && (' ' + cls + ' ').indexOf(className) > -1) {
+						arr.push(el);
+					}
+				}
+			}
+		}
+		return arr;
+	}
+	function byName(name, tag, root) {
+		var arr = [], doc = root.ownerDocument || root,
+			els = doc.getElementsByName(stripslashes(name)), el;
+		for (var i = 0, len = els.length; i < len; i++) {
+			el = els[i];
+			if (cmpTag(tag, el.nodeName) && _contains(root, el)) {
+				if (el.getAttribute('name') !== null) {
+					arr.push(el);
+				}
+			}
+		}
+		return arr;
+	}
+	function byAttr(key, val, tag, root) {
+		var arr = [], els = root.getElementsByTagName(tag), el;
+		for (var i = 0, len = els.length; i < len; i++) {
+			el = els[i];
+			if (el.nodeType == 1) {
+				if (val === null) {
+					if (_getAttr(el, key) !== null) {
+						arr.push(el);
+					}
+				} else {
+					if (val === escape(_getAttr(el, key))) {
+						arr.push(el);
+					}
+				}
+			}
+		}
+		return arr;
+	}
+	function select(expr, root) {
+		var arr = [], matches;
+		matches = /^((?:\\.|[^.#\s\[<>])+)/.exec(expr);
+		var tag = matches ? matches[1] : '*';
+		if ((matches = /#((?:[\w\-]|\\.)+)$/.exec(expr))) {
+			arr = byId(matches[1], tag, root);
+		} else if ((matches = /\.((?:[\w\-]|\\.)+)$/.exec(expr))) {
+			arr = byClass(matches[1], tag, root);
+		} else if ((matches = /\[((?:[\w\-]|\\.)+)\]/.exec(expr))) {
+			arr = byAttr(matches[1].toLowerCase(), null, tag, root);
+		} else if ((matches = /\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr))) {
+			var key = matches[1].toLowerCase(), val = matches[2];
+			if (key === 'id') {
+				arr = byId(val, tag, root);
+			} else if (key === 'class') {
+				arr = byClass(val, tag, root);
+			} else if (key === 'name') {
+				arr = byName(val, tag, root);
+			} else {
+				arr = byAttr(key, val, tag, root);
+			}
+		} else {
+			var els = root.getElementsByTagName(tag), el;
+			for (var i = 0, len = els.length; i < len; i++) {
+				el = els[i];
+				if (el.nodeType == 1) {
+					arr.push(el);
+				}
+			}
+		}
+		return arr;
+	}
+	var parts = [], arr, re = /((?:\\.|[^\s>])+|[\s>])/g;
+	while ((arr = re.exec(expr))) {
+		if (arr[1] !== ' ') {
+			parts.push(arr[1]);
+		}
+	}
+	var results = [];
+	if (parts.length == 1) {
+		return select(parts[0], root);
+	}
+	var isChild = false, part, els, subResults, val, v, i, j, k, length, len, l;
+	for (i = 0, lenth = parts.length; i < lenth; i++) {
+		part = parts[i];
+		if (part === '>') {
+			isChild = true;
+			continue;
+		}
+		if (i > 0) {
+			els = [];
+			for (j = 0, len = results.length; j < len; j++) {
+				val = results[j];
+				subResults = select(part, val);
+				for (k = 0, l = subResults.length; k < l; k++) {
+					v = subResults[k];
+					if (isChild) {
+						if (val === v.parentNode) {
+							els.push(v);
+						}
+					} else {
+						els.push(v);
+					}
+				}
+			}
+			results = els;
+		} else {
+			results = select(part, root);
+		}
+		if (results.length === 0) {
+			return [];
+		}
+	}
+	return results;
+}
+function _query(expr, root) {
+	var arr = _queryAll(expr, root);
+	return arr.length > 0 ? arr[0] : null;
+}
+K.query = _query;
+K.queryAll = _queryAll;
+
+
+function _get(val) {
+	return K(val)[0];
+}
+function _getDoc(node) {
+	if (!node) {
+		return document;
+	}
+	return node.ownerDocument || node.document || node;
+}
+function _getWin(node) {
+	if (!node) {
+		return window;
+	}
+	var doc = _getDoc(node);
+	return doc.parentWindow || doc.defaultView;
+}
+function _setHtml(el, html) {
+	if (el.nodeType != 1) {
+		return;
+	}
+	var doc = _getDoc(el);
+	try {
+		el.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + html;
+		var temp = doc.getElementById('__kindeditor_temp_tag__');
+		temp.parentNode.removeChild(temp);
+	} catch(e) {
+		K(el).empty();
+		K('@' + html, doc).each(function() {
+			el.appendChild(this);
+		});
+	}
+}
+function _hasClass(el, cls) {
+	return _inString(cls, el.className, ' ');
+}
+function _setAttr(el, key, val) {
+	if (_IE && _V < 8 && key.toLowerCase() == 'class') {
+		key = 'className';
+	}
+	el.setAttribute(key, '' + val);
+}
+function _removeAttr(el, key) {
+	if (_IE && _V < 8 && key.toLowerCase() == 'class') {
+		key = 'className';
+	}
+	_setAttr(el, key, '');
+	el.removeAttribute(key);
+}
+function _getNodeName(node) {
+	if (!node || !node.nodeName) {
+		return '';
+	}
+	return node.nodeName.toLowerCase();
+}
+function _computedCss(el, key) {
+	var self = this, win = _getWin(el), camelKey = _toCamel(key), val = '';
+	if (win.getComputedStyle) {
+		var style = win.getComputedStyle(el, null);
+		val = style[camelKey] || style.getPropertyValue(key) || el.style[camelKey];
+	} else if (el.currentStyle) {
+		val = el.currentStyle[camelKey] || el.style[camelKey];
+	}
+	return val;
+}
+function _hasVal(node) {
+	return !!_VALUE_TAG_MAP[_getNodeName(node)];
+}
+function _docElement(doc) {
+	doc = doc || document;
+	return _QUIRKS ? doc.body : doc.documentElement;
+}
+function _docHeight(doc) {
+	var el = _docElement(doc);
+	return Math.max(el.scrollHeight, el.clientHeight);
+}
+function _docWidth(doc) {
+	var el = _docElement(doc);
+	return Math.max(el.scrollWidth, el.clientWidth);
+}
+function _getScrollPos(doc) {
+	doc = doc || document;
+	var x, y;
+	if (_IE || _NEWIE || _OPERA) {
+		x = _docElement(doc).scrollLeft;
+		y = _docElement(doc).scrollTop;
+	} else {
+		x = _getWin(doc).scrollX;
+		y = _getWin(doc).scrollY;
+	}
+	return {x : x, y : y};
+}
+

+function KNode(node) {
+	this.init(node);
+}
+_extend(KNode, {
+	init : function(node) {
+		var self = this;
+		node = _isArray(node) ? node : [node];
+		var length = 0;
+		for (var i = 0, len = node.length; i < len; i++) {
+			if (node[i]) {
+				self[i] = node[i].constructor === KNode ? node[i][0] : node[i];
+				length++;
+			}
+		}
+		self.length = length;
+		self.doc = _getDoc(self[0]);
+		self.name = _getNodeName(self[0]);
+		self.type = self.length > 0 ? self[0].nodeType : null;
+		self.win = _getWin(self[0]);
+	},
+	each : function(fn) {
+		var self = this;
+		for (var i = 0; i < self.length; i++) {
+			if (fn.call(self[i], i, self[i]) === false) {
+				return self;
+			}
+		}
+		return self;
+	},
+	bind : function(type, fn) {
+		this.each(function() {
+			_bind(this, type, fn);
+		});
+		return this;
+	},
+	unbind : function(type, fn) {
+		this.each(function() {
+			_unbind(this, type, fn);
+		});
+		return this;
+	},
+	fire : function(type) {
+		if (this.length < 1) {
+			return this;
+		}
+		_fire(this[0], type);
+		return this;
+	},
+	hasAttr : function(key) {
+		if (this.length < 1) {
+			return false;
+		}
+		return !!_getAttr(this[0], key);
+	},
+	attr : function(key, val) {
+		var self = this;
+		if (key === undefined) {
+			return _getAttrList(self.outer());
+		}
+		if (typeof key === 'object') {
+			_each(key, function(k, v) {
+				self.attr(k, v);
+			});
+			return self;
+		}
+		if (val === undefined) {
+			val = self.length < 1 ? null : _getAttr(self[0], key);
+			return val === null ? '' : val;
+		}
+		self.each(function() {
+			_setAttr(this, key, val);
+		});
+		return self;
+	},
+	removeAttr : function(key) {
+		this.each(function() {
+			_removeAttr(this, key);
+		});
+		return this;
+	},
+	get : function(i) {
+		if (this.length < 1) {
+			return null;
+		}
+		return this[i || 0];
+	},
+	eq : function(i) {
+		if (this.length < 1) {
+			return null;
+		}
+		return this[i] ? new KNode(this[i]) : null;
+	},
+	hasClass : function(cls) {
+		if (this.length < 1) {
+			return false;
+		}
+		return _hasClass(this[0], cls);
+	},
+	addClass : function(cls) {
+		this.each(function() {
+			if (!_hasClass(this, cls)) {
+				this.className = _trim(this.className + ' ' + cls);
+			}
+		});
+		return this;
+	},
+	removeClass : function(cls) {
+		this.each(function() {
+			if (_hasClass(this, cls)) {
+				this.className = _trim(this.className.replace(new RegExp('(^|\\s)' + cls + '(\\s|$)'), ' '));
+			}
+		});
+		return this;
+	},
+	html : function(val) {
+		var self = this;
+		if (val === undefined) {
+			if (self.length < 1 || self.type != 1) {
+				return '';
+			}
+			return _formatHtml(self[0].innerHTML);
+		}
+		self.each(function() {
+			_setHtml(this, val);
+		});
+		return self;
+	},
+	text : function() {
+		var self = this;
+		if (self.length < 1) {
+			return '';
+		}
+		return _IE ? self[0].innerText : self[0].textContent;
+	},
+	hasVal : function() {
+		if (this.length < 1) {
+			return false;
+		}
+		return _hasVal(this[0]);
+	},
+	val : function(val) {
+		var self = this;
+		if (val === undefined) {
+			if (self.length < 1) {
+				return '';
+			}
+			return self.hasVal() ? self[0].value : self.attr('value');
+		} else {
+			self.each(function() {
+				if (_hasVal(this)) {
+					this.value = val;
+				} else {
+					_setAttr(this, 'value' , val);
+				}
+			});
+			return self;
+		}
+	},
+	css : function(key, val) {
+		var self = this;
+		if (key === undefined) {
+			return _getCssList(self.attr('style'));
+		}
+		if (typeof key === 'object') {
+			_each(key, function(k, v) {
+				self.css(k, v);
+			});
+			return self;
+		}
+		if (val === undefined) {
+			if (self.length < 1) {
+				return '';
+			}
+			return self[0].style[_toCamel(key)] || _computedCss(self[0], key) || '';
+		}
+		self.each(function() {
+			this.style[_toCamel(key)] = val;
+		});
+		return self;
+	},
+	width : function(val) {
+		var self = this;
+		if (val === undefined) {
+			if (self.length < 1) {
+				return 0;
+			}
+			return self[0].offsetWidth;
+		}
+		return self.css('width', _addUnit(val));
+	},
+	height : function(val) {
+		var self = this;
+		if (val === undefined) {
+			if (self.length < 1) {
+				return 0;
+			}
+			return self[0].offsetHeight;
+		}
+		return self.css('height', _addUnit(val));
+	},
+	opacity : function(val) {
+		this.each(function() {
+			if (this.style.opacity === undefined) {
+				this.style.filter = val == 1 ? '' : 'alpha(opacity=' + (val * 100) + ')';
+			} else {
+				this.style.opacity = val == 1 ? '' : val;
+			}
+		});
+		return this;
+	},
+	data : function(key, val) {
+		var self = this;
+		key = 'kindeditor_data_' + key;
+		if (val === undefined) {
+			if (self.length < 1) {
+				return null;
+			}
+			return self[0][key];
+		}
+		this.each(function() {
+			this[key] = val;
+		});
+		return self;
+	},
+	pos : function() {
+		var self = this, node = self[0], x = 0, y = 0;
+		if (node) {
+			if (node.getBoundingClientRect) {
+				var box = node.getBoundingClientRect(),
+					pos = _getScrollPos(self.doc);
+				x = box.left + pos.x;
+				y = box.top + pos.y;
+			} else {
+				while (node) {
+					x += node.offsetLeft;
+					y += node.offsetTop;
+					node = node.offsetParent;
+				}
+			}
+		}
+		return {x : _round(x), y : _round(y)};
+	},
+	clone : function(bool) {
+		if (this.length < 1) {
+			return new KNode([]);
+		}
+		return new KNode(this[0].cloneNode(bool));
+	},
+	append : function(expr) {
+		this.each(function() {
+			if (this.appendChild) {
+				this.appendChild(_get(expr));
+			}
+		});
+		return this;
+	},
+	appendTo : function(expr) {
+		this.each(function() {
+			_get(expr).appendChild(this);
+		});
+		return this;
+	},
+	before : function(expr) {
+		this.each(function() {
+			this.parentNode.insertBefore(_get(expr), this);
+		});
+		return this;
+	},
+	after : function(expr) {
+		this.each(function() {
+			if (this.nextSibling) {
+				this.parentNode.insertBefore(_get(expr), this.nextSibling);
+			} else {
+				this.parentNode.appendChild(_get(expr));
+			}
+		});
+		return this;
+	},
+	replaceWith : function(expr) {
+		var nodes = [];
+		this.each(function(i, node) {
+			_unbind(node);
+			var newNode = _get(expr);
+			node.parentNode.replaceChild(newNode, node);
+			nodes.push(newNode);
+		});
+		return K(nodes);
+	},
+	empty : function() {
+		var self = this;
+		self.each(function(i, node) {
+			var child = node.firstChild;
+			while (child) {
+				if (!node.parentNode) {
+					return;
+				}
+				var next = child.nextSibling;
+				child.parentNode.removeChild(child);
+				child = next;
+			}
+		});
+		return self;
+	},
+	remove : function(keepChilds) {
+		var self = this;
+		self.each(function(i, node) {
+			if (!node.parentNode) {
+				return;
+			}
+			_unbind(node);
+			if (keepChilds) {
+				var child = node.firstChild;
+				while (child) {
+					var next = child.nextSibling;
+					node.parentNode.insertBefore(child, node);
+					child = next;
+				}
+			}
+			node.parentNode.removeChild(node);
+			delete self[i];
+		});
+		self.length = 0;
+		return self;
+	},
+	show : function(val) {
+		var self = this;
+		if (val === undefined) {
+			val = self._originDisplay || '';
+		}
+		if (self.css('display') != 'none') {
+			return self;
+		}
+		return self.css('display', val);
+	},
+	hide : function() {
+		var self = this;
+		if (self.length < 1) {
+			return self;
+		}
+		self._originDisplay = self[0].style.display;
+		return self.css('display', 'none');
+	},
+	outer : function() {
+		var self = this;
+		if (self.length < 1) {
+			return '';
+		}
+		var div = self.doc.createElement('div'), html;
+		div.appendChild(self[0].cloneNode(true));
+		html = _formatHtml(div.innerHTML);
+		div = null;
+		return html;
+	},
+	isSingle : function() {
+		return !!_SINGLE_TAG_MAP[this.name];
+	},
+	isInline : function() {
+		return !!_INLINE_TAG_MAP[this.name];
+	},
+	isBlock : function() {
+		return !!_BLOCK_TAG_MAP[this.name];
+	},
+	isStyle : function() {
+		return !!_STYLE_TAG_MAP[this.name];
+	},
+	isControl : function() {
+		return !!_CONTROL_TAG_MAP[this.name];
+	},
+	contains : function(otherNode) {
+		if (this.length < 1) {
+			return false;
+		}
+		return _contains(this[0], _get(otherNode));
+	},
+	parent : function() {
+		if (this.length < 1) {
+			return null;
+		}
+		var node = this[0].parentNode;
+		return node ? new KNode(node) : null;
+	},
+	children : function() {
+		if (this.length < 1) {
+			return new KNode([]);
+		}
+		var list = [], child = this[0].firstChild;
+		while (child) {
+			if (child.nodeType != 3 || _trim(child.nodeValue) !== '') {
+				list.push(child);
+			}
+			child = child.nextSibling;
+		}
+		return new KNode(list);
+	},
+	first : function() {
+		var list = this.children();
+		return list.length > 0 ? list.eq(0) : null;
+	},
+	last : function() {
+		var list = this.children();
+		return list.length > 0 ? list.eq(list.length - 1) : null;
+	},
+	index : function() {
+		if (this.length < 1) {
+			return -1;
+		}
+		var i = -1, sibling = this[0];
+		while (sibling) {
+			i++;
+			sibling = sibling.previousSibling;
+		}
+		return i;
+	},
+	prev : function() {
+		if (this.length < 1) {
+			return null;
+		}
+		var node = this[0].previousSibling;
+		return node ? new KNode(node) : null;
+	},
+	next : function() {
+		if (this.length < 1) {
+			return null;
+		}
+		var node = this[0].nextSibling;
+		return node ? new KNode(node) : null;
+	},
+	scan : function(fn, order) {
+		if (this.length < 1) {
+			return;
+		}
+		order = (order === undefined) ? true : order;
+		function walk(node) {
+			var n = order ? node.firstChild : node.lastChild;
+			while (n) {
+				var next = order ? n.nextSibling : n.previousSibling;
+				if (fn(n) === false) {
+					return false;
+				}
+				if (walk(n) === false) {
+					return false;
+				}
+				n = next;
+			}
+		}
+		walk(this[0]);
+		return this;
+	}
+});
+_each(('blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,' +
+	'mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,' +
+	'change,select,submit,keydown,keypress,keyup,error,contextmenu').split(','), function(i, type) {
+	KNode.prototype[type] = function(fn) {
+		return fn ? this.bind(type, fn) : this.fire(type);
+	};
+});
+var _K = K;
+K = function(expr, root) {
+	if (expr === undefined || expr === null) {
+		return;
+	}
+	function newNode(node) {
+		if (!node[0]) {
+			node = [];
+		}
+		return new KNode(node);
+	}
+	if (typeof expr === 'string') {
+		if (root) {
+			root = _get(root);
+		}
+		var length = expr.length;
+		if (expr.charAt(0) === '@') {
+			expr = expr.substr(1);
+		}
+		if (expr.length !== length || /<.+>/.test(expr)) {
+			var doc = root ? root.ownerDocument || root : document,
+				div = doc.createElement('div'), list = [];
+			div.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + expr;
+			for (var i = 0, len = div.childNodes.length; i < len; i++) {
+				var child = div.childNodes[i];
+				if (child.id == '__kindeditor_temp_tag__') {
+					continue;
+				}
+				list.push(child);
+			}
+			return newNode(list);
+		}
+		return newNode(_queryAll(expr, root));
+	}
+	if (expr && expr.constructor === KNode) {
+		return expr;
+	}
+	if (expr.toArray) {
+		expr = expr.toArray();
+	}
+	if (_isArray(expr)) {
+		return newNode(expr);
+	}
+	return newNode(_toArray(arguments));
+};
+_each(_K, function(key, val) {
+	K[key] = val;
+});
+K.NodeClass = KNode;
+window.KindEditor = K;
+
+
+var _START_TO_START = 0,
+	_START_TO_END = 1,
+	_END_TO_END = 2,
+	_END_TO_START = 3,
+	_BOOKMARK_ID = 0;
+function _updateCollapsed(range) {
+	range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);
+	return range;
+}
+function _copyAndDelete(range, isCopy, isDelete) {
+	var doc = range.doc, nodeList = [];
+	function splitTextNode(node, startOffset, endOffset) {
+		var length = node.nodeValue.length, centerNode;
+		if (isCopy) {
+			var cloneNode = node.cloneNode(true);
+			if (startOffset > 0) {
+				centerNode = cloneNode.splitText(startOffset);
+			} else {
+				centerNode = cloneNode;
+			}
+			if (endOffset < length) {
+				centerNode.splitText(endOffset - startOffset);
+			}
+		}
+		if (isDelete) {
+			var center = node;
+			if (startOffset > 0) {
+				center = node.splitText(startOffset);
+				range.setStart(node, startOffset);
+			}
+			if (endOffset < length) {
+				var right = center.splitText(endOffset - startOffset);
+				range.setEnd(right, 0);
+			}
+			nodeList.push(center);
+		}
+		return centerNode;
+	}
+	function removeNodes() {
+		if (isDelete) {
+			range.up().collapse(true);
+		}
+		for (var i = 0, len = nodeList.length; i < len; i++) {
+			var node = nodeList[i];
+			if (node.parentNode) {
+				node.parentNode.removeChild(node);
+			}
+		}
+	}
+	var copyRange = range.cloneRange().down();
+	var start = -1, incStart = -1, incEnd = -1, end = -1,
+		ancestor = range.commonAncestor(), frag = doc.createDocumentFragment();
+	if (ancestor.nodeType == 3) {
+		var textNode = splitTextNode(ancestor, range.startOffset, range.endOffset);
+		if (isCopy) {
+			frag.appendChild(textNode);
+		}
+		removeNodes();
+		return isCopy ? frag : range;
+	}
+	function extractNodes(parent, frag) {
+		var node = parent.firstChild, nextNode;
+		while (node) {
+			var testRange = new KRange(doc).selectNode(node);
+			start = testRange.compareBoundaryPoints(_START_TO_END, range);
+			if (start >= 0 && incStart <= 0) {
+				incStart = testRange.compareBoundaryPoints(_START_TO_START, range);
+			}
+			if (incStart >= 0 && incEnd <= 0) {
+				incEnd = testRange.compareBoundaryPoints(_END_TO_END, range);
+			}
+			if (incEnd >= 0 && end <= 0) {
+				end = testRange.compareBoundaryPoints(_END_TO_START, range);
+			}
+			if (end >= 0) {
+				return false;
+			}
+			nextNode = node.nextSibling;
+			if (start > 0) {
+				if (node.nodeType == 1) {
+					if (incStart >= 0 && incEnd <= 0) {
+						if (isCopy) {
+							frag.appendChild(node.cloneNode(true));
+						}
+						if (isDelete) {
+							nodeList.push(node);
+						}
+					} else {
+						var childFlag;
+						if (isCopy) {
+							childFlag = node.cloneNode(false);
+							frag.appendChild(childFlag);
+						}
+						if (extractNodes(node, childFlag) === false) {
+							return false;
+						}
+					}
+				} else if (node.nodeType == 3) {
+					var textNode;
+					if (node == copyRange.startContainer) {
+						textNode = splitTextNode(node, copyRange.startOffset, node.nodeValue.length);
+					} else if (node == copyRange.endContainer) {
+						textNode = splitTextNode(node, 0, copyRange.endOffset);
+					} else {
+						textNode = splitTextNode(node, 0, node.nodeValue.length);
+					}
+					if (isCopy) {
+						try {
+							frag.appendChild(textNode);
+						} catch(e) {}
+					}
+				}
+			}
+			node = nextNode;
+		}
+	}
+	extractNodes(ancestor, frag);
+	if (isDelete) {
+		range.up().collapse(true);
+	}
+	for (var i = 0, len = nodeList.length; i < len; i++) {
+		var node = nodeList[i];
+		if (node.parentNode) {
+			node.parentNode.removeChild(node);
+		}
+	}
+	return isCopy ? frag : range;
+}

+function _moveToElementText(range, el) {
+	var node = el;
+	while (node) {
+		var knode = K(node);
+		if (knode.name == 'marquee' || knode.name == 'select') {
+			return;
+		}
+		node = node.parentNode;
+	}
+	try {
+		range.moveToElementText(el);
+	} catch(e) {}
+}

+function _getStartEnd(rng, isStart) {
+	var doc = rng.parentElement().ownerDocument,
+		pointRange = rng.duplicate();
+	pointRange.collapse(isStart);
+	var parent = pointRange.parentElement(),
+		nodes = parent.childNodes;
+	if (nodes.length === 0) {
+		return {node: parent.parentNode, offset: K(parent).index()};
+	}
+	var startNode = doc, startPos = 0, cmp = -1;
+	var testRange = rng.duplicate();
+	_moveToElementText(testRange, parent);
+	for (var i = 0, len = nodes.length; i < len; i++) {
+		var node = nodes[i];
+		cmp = testRange.compareEndPoints('StartToStart', pointRange);
+		if (cmp === 0) {
+			return {node: node.parentNode, offset: i};
+		}
+		if (node.nodeType == 1) {
+			var nodeRange = rng.duplicate(), dummy, knode = K(node), newNode = node;
+			if (knode.isControl()) {
+				dummy = doc.createElement('span');
+				knode.after(dummy);
+				newNode = dummy;
+				startPos += knode.text().replace(/\r\n|\n|\r/g, '').length;
+			}
+			_moveToElementText(nodeRange, newNode);
+			testRange.setEndPoint('StartToEnd', nodeRange);
+			if (cmp > 0) {
+				startPos += nodeRange.text.replace(/\r\n|\n|\r/g, '').length;
+			} else {
+				startPos = 0;
+			}
+			if (dummy) {
+				K(dummy).remove();
+			}
+		} else if (node.nodeType == 3) {
+			testRange.moveStart('character', node.nodeValue.length);
+			startPos += node.nodeValue.length;
+		}
+		if (cmp < 0) {
+			startNode = node;
+		}
+	}
+	if (cmp < 0 && startNode.nodeType == 1) {
+		return {node: parent, offset: K(parent.lastChild).index() + 1};
+	}
+	if (cmp > 0) {
+		while (startNode.nextSibling && startNode.nodeType == 1) {
+			startNode = startNode.nextSibling;
+		}
+	}
+	testRange = rng.duplicate();
+	_moveToElementText(testRange, parent);
+	testRange.setEndPoint('StartToEnd', pointRange);
+	startPos -= testRange.text.replace(/\r\n|\n|\r/g, '').length;
+	if (cmp > 0 && startNode.nodeType == 3) {
+		var prevNode = startNode.previousSibling;
+		while (prevNode && prevNode.nodeType == 3) {
+			startPos -= prevNode.nodeValue.length;
+			prevNode = prevNode.previousSibling;
+		}
+	}
+	return {node: startNode, offset: startPos};
+}

+function _getEndRange(node, offset) {
+	var doc = node.ownerDocument || node,
+		range = doc.body.createTextRange();
+	if (doc == node) {
+		range.collapse(true);
+		return range;
+	}
+	if (node.nodeType == 1 && node.childNodes.length > 0) {
+		var children = node.childNodes, isStart, child;
+		if (offset === 0) {
+			child = children[0];
+			isStart = true;
+		} else {
+			child = children[offset - 1];
+			isStart = false;
+		}
+		if (!child) {
+			return range;
+		}
+		if (K(child).name === 'head') {
+			if (offset === 1) {
+				isStart = true;
+			}
+			if (offset === 2) {
+				isStart = false;
+			}
+			range.collapse(isStart);
+			return range;
+		}
+		if (child.nodeType == 1) {
+			var kchild = K(child), span;
+			if (kchild.isControl()) {
+				span = doc.createElement('span');
+				if (isStart) {
+					kchild.before(span);
+				} else {
+					kchild.after(span);
+				}
+				child = span;
+			}
+			_moveToElementText(range, child);
+			range.collapse(isStart);
+			if (span) {
+				K(span).remove();
+			}
+			return range;
+		}
+		node = child;
+		offset = isStart ? 0 : child.nodeValue.length;
+	}
+	var dummy = doc.createElement('span');
+	K(node).before(dummy);
+	_moveToElementText(range, dummy);
+	range.moveStart('character', offset);
+	K(dummy).remove();
+	return range;
+}

+function _toRange(rng) {
+	var doc, range;
+	function tr2td(start) {
+		if (K(start.node).name == 'tr') {
+			start.node = start.node.cells[start.offset];
+			start.offset = 0;
+		}
+	}
+	if (_IERANGE) {
+		if (rng.item) {
+			doc = _getDoc(rng.item(0));
+			range = new KRange(doc);
+			range.selectNode(rng.item(0));
+			return range;
+		}
+		doc = rng.parentElement().ownerDocument;
+		var start = _getStartEnd(rng, true),
+			end = _getStartEnd(rng, false);
+		tr2td(start);
+		tr2td(end);
+		range = new KRange(doc);
+		range.setStart(start.node, start.offset);
+		range.setEnd(end.node, end.offset);
+		return range;
+	}
+	var startContainer = rng.startContainer;
+	doc = startContainer.ownerDocument || startContainer;
+	range = new KRange(doc);
+	range.setStart(startContainer, rng.startOffset);
+	range.setEnd(rng.endContainer, rng.endOffset);
+	return range;
+}
+

+function KRange(doc) {
+	this.init(doc);
+}
+_extend(KRange, {
+	init : function(doc) {
+		var self = this;
+		self.startContainer = doc;
+		self.startOffset = 0;
+		self.endContainer = doc;
+		self.endOffset = 0;
+		self.collapsed = true;
+		self.doc = doc;
+	},
+	commonAncestor : function() {
+		function getParents(node) {
+			var parents = [];
+			while (node) {
+				parents.push(node);
+				node = node.parentNode;
+			}
+			return parents;
+		}
+		var parentsA = getParents(this.startContainer),
+			parentsB = getParents(this.endContainer),
+			i = 0, lenA = parentsA.length, lenB = parentsB.length, parentA, parentB;
+		while (++i) {
+			parentA = parentsA[lenA - i];
+			parentB = parentsB[lenB - i];
+			if (!parentA || !parentB || parentA !== parentB) {
+				break;
+			}
+		}
+		return parentsA[lenA - i + 1];
+	},
+	setStart : function(node, offset) {
+		var self = this, doc = self.doc;
+		self.startContainer = node;
+		self.startOffset = offset;
+		if (self.endContainer === doc) {
+			self.endContainer = node;
+			self.endOffset = offset;
+		}
+		return _updateCollapsed(this);
+	},
+	setEnd : function(node, offset) {
+		var self = this, doc = self.doc;
+		self.endContainer = node;
+		self.endOffset = offset;
+		if (self.startContainer === doc) {
+			self.startContainer = node;
+			self.startOffset = offset;
+		}
+		return _updateCollapsed(this);
+	},
+	setStartBefore : function(node) {
+		return this.setStart(node.parentNode || this.doc, K(node).index());
+	},
+	setStartAfter : function(node) {
+		return this.setStart(node.parentNode || this.doc, K(node).index() + 1);
+	},
+	setEndBefore : function(node) {
+		return this.setEnd(node.parentNode || this.doc, K(node).index());
+	},
+	setEndAfter : function(node) {
+		return this.setEnd(node.parentNode || this.doc, K(node).index() + 1);
+	},
+	selectNode : function(node) {
+		return this.setStartBefore(node).setEndAfter(node);
+	},
+	selectNodeContents : function(node) {
+		var knode = K(node);
+		if (knode.type == 3 || knode.isSingle()) {
+			return this.selectNode(node);
+		}
+		var children = knode.children();
+		if (children.length > 0) {
+			return this.setStartBefore(children[0]).setEndAfter(children[children.length - 1]);
+		}
+		return this.setStart(node, 0).setEnd(node, 0);
+	},
+	collapse : function(toStart) {
+		if (toStart) {
+			return this.setEnd(this.startContainer, this.startOffset);
+		}
+		return this.setStart(this.endContainer, this.endOffset);
+	},
+	compareBoundaryPoints : function(how, range) {
+		var rangeA = this.get(), rangeB = range.get();
+		if (_IERANGE) {
+			var arr = {};
+			arr[_START_TO_START] = 'StartToStart';
+			arr[_START_TO_END] = 'EndToStart';
+			arr[_END_TO_END] = 'EndToEnd';
+			arr[_END_TO_START] = 'StartToEnd';
+			var cmp = rangeA.compareEndPoints(arr[how], rangeB);
+			if (cmp !== 0) {
+				return cmp;
+			}
+			var nodeA, nodeB, nodeC, posA, posB;
+			if (how === _START_TO_START || how === _END_TO_START) {
+				nodeA = this.startContainer;
+				posA = this.startOffset;
+			}
+			if (how === _START_TO_END || how === _END_TO_END) {
+				nodeA = this.endContainer;
+				posA = this.endOffset;
+			}
+			if (how === _START_TO_START || how === _START_TO_END) {
+				nodeB = range.startContainer;
+				posB = range.startOffset;
+			}
+			if (how === _END_TO_END || how === _END_TO_START) {
+				nodeB = range.endContainer;
+				posB = range.endOffset;
+			}
+			if (nodeA === nodeB) {
+				var diff = posA - posB;
+				return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
+			}
+			nodeC = nodeB;
+			while (nodeC && nodeC.parentNode !== nodeA) {
+				nodeC = nodeC.parentNode;
+			}
+			if (nodeC) {
+				return K(nodeC).index() >= posA ? -1 : 1;
+			}
+			nodeC = nodeA;
+			while (nodeC && nodeC.parentNode !== nodeB) {
+				nodeC = nodeC.parentNode;
+			}
+			if (nodeC) {
+				return K(nodeC).index() >= posB ? 1 : -1;
+			}
+			nodeC = K(nodeB).next();
+			if (nodeC && nodeC.contains(nodeA)) {
+				return 1;
+			}
+			nodeC = K(nodeA).next();
+			if (nodeC && nodeC.contains(nodeB)) {
+				return -1;
+			}
+		} else {
+			return rangeA.compareBoundaryPoints(how, rangeB);
+		}
+	},
+	cloneRange : function() {
+		return new KRange(this.doc).setStart(this.startContainer, this.startOffset).setEnd(this.endContainer, this.endOffset);
+	},
+	toString : function() {
+		var rng = this.get(), str = _IERANGE ? rng.text : rng.toString();
+		return str.replace(/\r\n|\n|\r/g, '');
+	},
+	cloneContents : function() {
+		return _copyAndDelete(this, true, false);
+	},
+	deleteContents : function() {
+		return _copyAndDelete(this, false, true);
+	},
+	extractContents : function() {
+		return _copyAndDelete(this, true, true);
+	},
+	insertNode : function(node) {
+		var self = this,
+			sc = self.startContainer, so = self.startOffset,
+			ec = self.endContainer, eo = self.endOffset,
+			firstChild, lastChild, c, nodeCount = 1;
+		if (node.nodeName.toLowerCase() === '#document-fragment') {
+			firstChild = node.firstChild;
+			lastChild = node.lastChild;
+			nodeCount = node.childNodes.length;
+		}
+		if (sc.nodeType == 1) {
+			c = sc.childNodes[so];
+			if (c) {
+				sc.insertBefore(node, c);
+				if (sc === ec) {
+					eo += nodeCount;
+				}
+			} else {
+				sc.appendChild(node);
+			}
+		} else if (sc.nodeType == 3) {
+			if (so === 0) {
+				sc.parentNode.insertBefore(node, sc);
+				if (sc.parentNode === ec) {
+					eo += nodeCount;
+				}
+			} else if (so >= sc.nodeValue.length) {
+				if (sc.nextSibling) {
+					sc.parentNode.insertBefore(node, sc.nextSibling);
+				} else {
+					sc.parentNode.appendChild(node);
+				}
+			} else {
+				if (so > 0) {
+					c = sc.splitText(so);
+				} else {
+					c = sc;
+				}
+				sc.parentNode.insertBefore(node, c);
+				if (sc === ec) {
+					ec = c;
+					eo -= so;
+				}
+			}
+		}
+		if (firstChild) {
+			self.setStartBefore(firstChild).setEndAfter(lastChild);
+		} else {
+			self.selectNode(node);
+		}
+		if (self.compareBoundaryPoints(_END_TO_END, self.cloneRange().setEnd(ec, eo)) >= 1) {
+			return self;
+		}
+		return self.setEnd(ec, eo);
+	},
+	surroundContents : function(node) {
+		node.appendChild(this.extractContents());
+		return this.insertNode(node).selectNode(node);
+	},
+	isControl : function() {
+		var self = this,
+			sc = self.startContainer, so = self.startOffset,
+			ec = self.endContainer, eo = self.endOffset, rng;
+		return sc.nodeType == 1 && sc === ec && so + 1 === eo && K(sc.childNodes[so]).isControl();
+	},
+	get : function(hasControlRange) {
+		var self = this, doc = self.doc, node, rng;
+		if (!_IERANGE) {
+			rng = doc.createRange();
+			try {
+				rng.setStart(self.startContainer, self.startOffset);
+				rng.setEnd(self.endContainer, self.endOffset);
+			} catch (e) {}
+			return rng;
+		}
+		if (hasControlRange && self.isControl()) {
+			rng = doc.body.createControlRange();
+			rng.addElement(self.startContainer.childNodes[self.startOffset]);
+			return rng;
+		}
+		var range = self.cloneRange().down();
+		rng = doc.body.createTextRange();
+		rng.setEndPoint('StartToStart', _getEndRange(range.startContainer, range.startOffset));
+		rng.setEndPoint('EndToStart', _getEndRange(range.endContainer, range.endOffset));
+		return rng;
+	},
+	html : function() {
+		return K(this.cloneContents()).outer();
+	},
+	down : function() {
+		var self = this;
+		function downPos(node, pos, isStart) {
+			if (node.nodeType != 1) {
+				return;
+			}
+			var children = K(node).children();
+			if (children.length === 0) {
+				return;
+			}
+			var left, right, child, offset;
+			if (pos > 0) {
+				left = children.eq(pos - 1);
+			}
+			if (pos < children.length) {
+				right = children.eq(pos);
+			}
+			if (left && left.type == 3) {
+				child = left[0];
+				offset = child.nodeValue.length;
+			}
+			if (right && right.type == 3) {
+				child = right[0];
+				offset = 0;
+			}
+			if (!child) {
+				return;
+			}
+			if (isStart) {
+				self.setStart(child, offset);
+			} else {
+				self.setEnd(child, offset);
+			}
+		}
+		downPos(self.startContainer, self.startOffset, true);
+		downPos(self.endContainer, self.endOffset, false);
+		return self;
+	},
+	up : function() {
+		var self = this;
+		function upPos(node, pos, isStart) {
+			if (node.nodeType != 3) {
+				return;
+			}
+			if (pos === 0) {
+				if (isStart) {
+					self.setStartBefore(node);
+				} else {
+					self.setEndBefore(node);
+				}
+			} else if (pos == node.nodeValue.length) {
+				if (isStart) {
+					self.setStartAfter(node);
+				} else {
+					self.setEndAfter(node);
+				}
+			}
+		}
+		upPos(self.startContainer, self.startOffset, true);
+		upPos(self.endContainer, self.endOffset, false);
+		return self;
+	},
+	enlarge : function(toBlock) {
+		var self = this;
+		self.up();
+		function enlargePos(node, pos, isStart) {
+			var knode = K(node), parent;
+			if (knode.type == 3 || _NOSPLIT_TAG_MAP[knode.name] || !toBlock && knode.isBlock()) {
+				return;
+			}
+			if (pos === 0) {
+				while (!knode.prev()) {
+					parent = knode.parent();
+					if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) {
+						break;
+					}
+					knode = parent;
+				}
+				if (isStart) {
+					self.setStartBefore(knode[0]);
+				} else {
+					self.setEndBefore(knode[0]);
+				}
+			} else if (pos == knode.children().length) {
+				while (!knode.next()) {
+					parent = knode.parent();
+					if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) {
+						break;
+					}
+					knode = parent;
+				}
+				if (isStart) {
+					self.setStartAfter(knode[0]);
+				} else {
+					self.setEndAfter(knode[0]);
+				}
+			}
+		}
+		enlargePos(self.startContainer, self.startOffset, true);
+		enlargePos(self.endContainer, self.endOffset, false);
+		return self;
+	},
+	shrink : function() {
+		var self = this, child, collapsed = self.collapsed;
+		while (self.startContainer.nodeType == 1 && (child = self.startContainer.childNodes[self.startOffset]) && child.nodeType == 1 && !K(child).isSingle()) {
+			self.setStart(child, 0);
+		}
+		if (collapsed) {
+			return self.collapse(collapsed);
+		}
+		while (self.endContainer.nodeType == 1 && self.endOffset > 0 && (child = self.endContainer.childNodes[self.endOffset - 1]) && child.nodeType == 1 && !K(child).isSingle()) {
+			self.setEnd(child, child.childNodes.length);
+		}
+		return self;
+	},
+	createBookmark : function(serialize) {
+		var self = this, doc = self.doc, endNode,
+			startNode = K('<span style="display:none;"></span>', doc)[0];
+		startNode.id = '__kindeditor_bookmark_start_' + (_BOOKMARK_ID++) + '__';
+		if (!self.collapsed) {
+			endNode = startNode.cloneNode(true);
+			endNode.id = '__kindeditor_bookmark_end_' + (_BOOKMARK_ID++) + '__';
+		}
+		if (endNode) {
+			self.cloneRange().collapse(false).insertNode(endNode).setEndBefore(endNode);
+		}
+		self.insertNode(startNode).setStartAfter(startNode);
+		return {
+			start : serialize ? '#' + startNode.id : startNode,
+			end : endNode ? (serialize ? '#' + endNode.id : endNode) : null
+		};
+	},
+	moveToBookmark : function(bookmark) {
+		var self = this, doc = self.doc,
+			start = K(bookmark.start, doc), end = bookmark.end ? K(bookmark.end, doc) : null;
+		if (!start || start.length < 1) {
+			return self;
+		}
+		self.setStartBefore(start[0]);
+		start.remove();
+		if (end && end.length > 0) {
+			self.setEndBefore(end[0]);
+			end.remove();
+		} else {
+			self.collapse(true);
+		}
+		return self;
+	},
+	dump : function() {
+		console.log('--------------------');
+		console.log(this.startContainer.nodeType == 3 ? this.startContainer.nodeValue : this.startContainer, this.startOffset);
+		console.log(this.endContainer.nodeType == 3 ? this.endContainer.nodeValue : this.endContainer, this.endOffset);
+	}
+});
+function _range(mixed) {
+	if (!mixed.nodeName) {
+		return mixed.constructor === KRange ? mixed : _toRange(mixed);
+	}
+	return new KRange(mixed);
+}
+K.RangeClass = KRange;
+K.range = _range;
+K.START_TO_START = _START_TO_START;
+K.START_TO_END = _START_TO_END;
+K.END_TO_END = _END_TO_END;
+K.END_TO_START = _END_TO_START;
+
+

+function _nativeCommand(doc, key, val) {
+	try {
+		doc.execCommand(key, false, val);
+	} catch(e) {}
+}

+function _nativeCommandValue(doc, key) {
+	var val = '';
+	try {
+		val = doc.queryCommandValue(key);
+	} catch (e) {}
+	if (typeof val !== 'string') {
+		val = '';
+	}
+	return val;
+}

+function _getSel(doc) {
+	var win = _getWin(doc);
+	return _IERANGE ? doc.selection : win.getSelection();
+}

+function _getRng(doc) {
+	var sel = _getSel(doc), rng;
+	try {
+		if (sel.rangeCount > 0) {
+			rng = sel.getRangeAt(0);
+		} else {
+			rng = sel.createRange();
+		}
+	} catch(e) {}
+	if (_IERANGE && (!rng || (!rng.item && rng.parentElement().ownerDocument !== doc))) {
+		return null;
+	}
+	return rng;
+}

+function _singleKeyMap(map) {
+	var newMap = {}, arr, v;
+	_each(map, function(key, val) {
+		arr = key.split(',');
+		for (var i = 0, len = arr.length; i < len; i++) {
+			v = arr[i];
+			newMap[v] = val;
+		}
+	});
+	return newMap;
+}

+function _hasAttrOrCss(knode, map) {
+	return _hasAttrOrCssByKey(knode, map, '*') || _hasAttrOrCssByKey(knode, map);
+}
+function _hasAttrOrCssByKey(knode, map, mapKey) {
+	mapKey = mapKey || knode.name;
+	if (knode.type !== 1) {
+		return false;
+	}
+	var newMap = _singleKeyMap(map);
+	if (!newMap[mapKey]) {
+		return false;
+	}
+	var arr = newMap[mapKey].split(',');
+	for (var i = 0, len = arr.length; i < len; i++) {
+		var key = arr[i];
+		if (key === '*') {
+			return true;
+		}
+		var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key);
+		var method = match[1] ? 'css' : 'attr';
+		key = match[2];
+		var val = match[3] || '';
+		if (val === '' && knode[method](key) !== '') {
+			return true;
+		}
+		if (val !== '' && knode[method](key) === val) {
+			return true;
+		}
+	}
+	return false;
+}

+function _removeAttrOrCss(knode, map) {
+	if (knode.type != 1) {
+		return;
+	}
+	_removeAttrOrCssByKey(knode, map, '*');
+	_removeAttrOrCssByKey(knode, map);
+}
+function _removeAttrOrCssByKey(knode, map, mapKey) {
+	mapKey = mapKey || knode.name;
+	if (knode.type !== 1) {
+		return;
+	}
+	var newMap = _singleKeyMap(map);
+	if (!newMap[mapKey]) {
+		return;
+	}
+	var arr = newMap[mapKey].split(','), allFlag = false;
+	for (var i = 0, len = arr.length; i < len; i++) {
+		var key = arr[i];
+		if (key === '*') {
+			allFlag = true;
+			break;
+		}
+		var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key);
+		key = match[2];
+		if (match[1]) {
+			key = _toCamel(key);
+			if (knode[0].style[key]) {
+				knode[0].style[key] = '';
+			}
+		} else {
+			knode.removeAttr(key);
+		}
+	}
+	if (allFlag) {
+		knode.remove(true);
+	}
+}

+function _getInnerNode(knode) {
+	var inner = knode;
+	while (inner.first()) {
+		inner = inner.first();
+	}
+	return inner;
+}

+function _isEmptyNode(knode) {
+	if (knode.type != 1 || knode.isSingle()) {
+		return false;
+	}
+	return knode.html().replace(/<[^>]+>/g, '') === '';
+}




+function _mergeWrapper(a, b) {
+	a = a.clone(true);
+	var lastA = _getInnerNode(a), childA = a, merged = false;
+	while (b) {
+		while (childA) {
+			if (childA.name === b.name) {
+				_mergeAttrs(childA, b.attr(), b.css());
+				merged = true;
+			}
+			childA = childA.first();
+		}
+		if (!merged) {
+			lastA.append(b.clone(false));
+		}
+		merged = false;
+		b = b.first();
+	}
+	return a;
+}

+function _wrapNode(knode, wrapper) {
+	wrapper = wrapper.clone(true);
+	if (knode.type == 3) {
+		_getInnerNode(wrapper).append(knode.clone(false));
+		knode.replaceWith(wrapper);
+		return wrapper;
+	}
+	var nodeWrapper = knode, child;
+	while ((child = knode.first()) && child.children().length == 1) {
+		knode = child;
+	}
+	child = knode.first();
+	var frag = knode.doc.createDocumentFragment();
+	while (child) {
+		frag.appendChild(child[0]);
+		child = child.next();
+	}
+	wrapper = _mergeWrapper(nodeWrapper, wrapper);
+	if (frag.firstChild) {
+		_getInnerNode(wrapper).append(frag);
+	}
+	nodeWrapper.replaceWith(wrapper);
+	return wrapper;
+}

+function _mergeAttrs(knode, attrs, styles) {
+	_each(attrs, function(key, val) {
+		if (key !== 'style') {
+			knode.attr(key, val);
+		}
+	});
+	_each(styles, function(key, val) {
+		knode.css(key, val);
+	});
+}

+function _inPreElement(knode) {
+	while (knode && knode.name != 'body') {
+		if (_PRE_TAG_MAP[knode.name] || knode.name == 'div' && knode.hasClass('ke-script')) {
+			return true;
+		}
+		knode = knode.parent();
+	}
+	return false;
+}

+function KCmd(range) {
+	this.init(range);
+}
+_extend(KCmd, {
+	init : function(range) {
+		var self = this, doc = range.doc;
+		self.doc = doc;
+		self.win = _getWin(doc);
+		self.sel = _getSel(doc);
+		self.range = range;
+	},
+	selection : function(forceReset) {
+		var self = this, doc = self.doc, rng = _getRng(doc);
+		self.sel = _getSel(doc);
+		if (rng) {
+			self.range = _range(rng);
+			if (K(self.range.startContainer).name == 'html') {
+				self.range.selectNodeContents(doc.body).collapse(false);
+			}
+			return self;
+		}
+		if (forceReset) {
+			self.range.selectNodeContents(doc.body).collapse(false);
+		}
+		return self;
+	},
+	select : function(hasDummy) {
+		hasDummy = _undef(hasDummy, true);
+		var self = this, sel = self.sel, range = self.range.cloneRange().shrink(),
+			sc = range.startContainer, so = range.startOffset,
+			ec = range.endContainer, eo = range.endOffset,
+			doc = _getDoc(sc), win = self.win, rng, hasU200b = false;
+		if (hasDummy && sc.nodeType == 1 && range.collapsed) {
+			if (_IERANGE) {
+				var dummy = K('<span>&nbsp;</span>', doc);
+				range.insertNode(dummy[0]);
+				rng = doc.body.createTextRange();
+				try {
+					rng.moveToElementText(dummy[0]);
+				} catch(ex) {}
+				rng.collapse(false);
+				rng.select();
+				dummy.remove();
+				win.focus();
+				return self;
+			}
+			if (_WEBKIT) {
+				var children = sc.childNodes;
+				if (K(sc).isInline() || so > 0 && K(children[so - 1]).isInline() || children[so] && K(children[so]).isInline()) {
+					range.insertNode(doc.createTextNode('\u200B'));
+					hasU200b = true;
+				}
+			}
+		}
+		if (_IERANGE) {
+			try {
+				rng = range.get(true);
+				rng.select();
+			} catch(e) {}
+		} else {
+			if (hasU200b) {
+				range.collapse(false);
+			}
+			rng = range.get(true);
+			sel.removeAllRanges();
+			sel.addRange(rng);
+			if (doc !== document) {
+				var pos = K(rng.endContainer).pos();
+				win.scrollTo(pos.x, pos.y);
+			}
+		}
+		win.focus();
+		return self;
+	},
+	wrap : function(val) {
+		var self = this, doc = self.doc, range = self.range, wrapper;
+		wrapper = K(val, doc);
+		if (range.collapsed) {
+			range.shrink();
+			range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]);
+			return self;
+		}
+		if (wrapper.isBlock()) {
+			var copyWrapper = wrapper.clone(true), child = copyWrapper;
+			while (child.first()) {
+				child = child.first();
+			}
+			child.append(range.extractContents());
+			range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]);
+			return self;
+		}
+		range.enlarge();
+		var bookmark = range.createBookmark(), ancestor = range.commonAncestor(), isStart = false;
+		K(ancestor).scan(function(node) {
+			if (!isStart && node == bookmark.start) {
+				isStart = true;
+				return;
+			}
+			if (isStart) {
+				if (node == bookmark.end) {
+					return false;
+				}
+				var knode = K(node);
+				if (_inPreElement(knode)) {
+					return;
+				}
+				if (knode.type == 3 && _trim(node.nodeValue).length > 0) {
+					var parent;
+					while ((parent = knode.parent()) && parent.isStyle() && parent.children().length == 1) {
+						knode = parent;
+					}
+					_wrapNode(knode, wrapper);
+				}
+			}
+		});
+		range.moveToBookmark(bookmark);
+		return self;
+	},
+	split : function(isStart, map) {
+		var range = this.range, doc = range.doc;
+		var tempRange = range.cloneRange().collapse(isStart);
+		var node = tempRange.startContainer, pos = tempRange.startOffset,
+			parent = node.nodeType == 3 ? node.parentNode : node,
+			needSplit = false, knode;
+		while (parent && parent.parentNode) {
+			knode = K(parent);
+			if (map) {
+				if (!knode.isStyle()) {
+					break;
+				}
+				if (!_hasAttrOrCss(knode, map)) {
+					break;
+				}
+			} else {
+				if (_NOSPLIT_TAG_MAP[knode.name]) {
+					break;
+				}
+			}
+			needSplit = true;
+			parent = parent.parentNode;
+		}
+		if (needSplit) {
+			var dummy = doc.createElement('span');
+			range.cloneRange().collapse(!isStart).insertNode(dummy);
+			if (isStart) {
+				tempRange.setStartBefore(parent.firstChild).setEnd(node, pos);
+			} else {
+				tempRange.setStart(node, pos).setEndAfter(parent.lastChild);
+			}
+			var frag = tempRange.extractContents(),
+				first = frag.firstChild, last = frag.lastChild;
+			if (isStart) {
+				tempRange.insertNode(frag);
+				range.setStartAfter(last).setEndBefore(dummy);
+			} else {
+				parent.appendChild(frag);
+				range.setStartBefore(dummy).setEndBefore(first);
+			}
+			var dummyParent = dummy.parentNode;
+			if (dummyParent == range.endContainer) {
+				var prev = K(dummy).prev(), next = K(dummy).next();
+				if (prev && next && prev.type == 3 && next.type == 3) {
+					range.setEnd(prev[0], prev[0].nodeValue.length);
+				} else if (!isStart) {
+					range.setEnd(range.endContainer, range.endOffset - 1);
+				}
+			}
+			dummyParent.removeChild(dummy);
+		}
+		return this;
+	},
+	remove : function(map) {
+		var self = this, doc = self.doc, range = self.range;
+		range.enlarge();
+		if (range.startOffset === 0) {
+			var ksc = K(range.startContainer), parent;
+			while ((parent = ksc.parent()) && parent.isStyle() && parent.children().length == 1) {
+				ksc = parent;
+			}
+			range.setStart(ksc[0], 0);
+			ksc = K(range.startContainer);
+			if (ksc.isBlock()) {
+				_removeAttrOrCss(ksc, map);
+			}
+			var kscp = ksc.parent();
+			if (kscp && kscp.isBlock()) {
+				_removeAttrOrCss(kscp, map);
+			}
+		}
+		var sc, so;
+		if (range.collapsed) {
+			self.split(true, map);
+			sc = range.startContainer;
+			so = range.startOffset;
+			if (so > 0) {
+				var sb = K(sc.childNodes[so - 1]);
+				if (sb && _isEmptyNode(sb)) {
+					sb.remove();
+					range.setStart(sc, so - 1);
+				}
+			}
+			var sa = K(sc.childNodes[so]);
+			if (sa && _isEmptyNode(sa)) {
+				sa.remove();
+			}
+			if (_isEmptyNode(sc)) {
+				range.startBefore(sc);
+				sc.remove();
+			}
+			range.collapse(true);
+			return self;
+		}
+		self.split(true, map);
+		self.split(false, map);
+		var startDummy = doc.createElement('span'), endDummy = doc.createElement('span');
+		range.cloneRange().collapse(false).insertNode(endDummy);
+		range.cloneRange().collapse(true).insertNode(startDummy);
+		var nodeList = [], cmpStart = false;
+		K(range.commonAncestor()).scan(function(node) {
+			if (!cmpStart && node == startDummy) {
+				cmpStart = true;
+				return;
+			}
+			if (node == endDummy) {
+				return false;
+			}
+			if (cmpStart) {
+				nodeList.push(node);
+			}
+		});
+		K(startDummy).remove();
+		K(endDummy).remove();
+		sc = range.startContainer;
+		so = range.startOffset;
+		var ec = range.endContainer, eo = range.endOffset;
+		if (so > 0) {
+			var startBefore = K(sc.childNodes[so - 1]);
+			if (startBefore && _isEmptyNode(startBefore)) {
+				startBefore.remove();
+				range.setStart(sc, so - 1);
+				if (sc == ec) {
+					range.setEnd(ec, eo - 1);
+				}
+			}
+			var startAfter = K(sc.childNodes[so]);
+			if (startAfter && _isEmptyNode(startAfter)) {
+				startAfter.remove();
+				if (sc == ec) {
+					range.setEnd(ec, eo - 1);
+				}
+			}
+		}
+		var endAfter = K(ec.childNodes[range.endOffset]);
+		if (endAfter && _isEmptyNode(endAfter)) {
+			endAfter.remove();
+		}
+		var bookmark = range.createBookmark(true);
+		_each(nodeList, function(i, node) {
+			_removeAttrOrCss(K(node), map);
+		});
+		range.moveToBookmark(bookmark);
+		return self;
+	},
+	commonNode : function(map) {
+		var range = this.range;
+		var ec = range.endContainer, eo = range.endOffset,
+			node = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1];
+		function find(node) {
+			var child = node, parent = node;
+			while (parent) {
+				if (_hasAttrOrCss(K(parent), map)) {
+					return K(parent);
+				}
+				parent = parent.parentNode;
+			}
+			while (child && (child = child.lastChild)) {
+				if (_hasAttrOrCss(K(child), map)) {
+					return K(child);
+				}
+			}
+			return null;
+		}
+		var cNode = find(node);
+		if (cNode) {
+			return cNode;
+		}
+		if (node.nodeType == 1 || (ec.nodeType == 3 && eo === 0)) {
+			var prev = K(node).prev();
+			if (prev) {
+				return find(prev);
+			}
+		}
+		return null;
+	},
+	commonAncestor : function(tagName) {
+		var range = this.range,
+			sc = range.startContainer, so = range.startOffset,
+			ec = range.endContainer, eo = range.endOffset,
+			startNode = (sc.nodeType == 3 || so === 0) ? sc : sc.childNodes[so - 1],
+			endNode = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1];
+		function find(node) {
+			while (node) {
+				if (node.nodeType == 1) {
+					if (node.tagName.toLowerCase() === tagName) {
+						return node;
+					}
+				}
+				node = node.parentNode;
+			}
+			return null;
+		}
+		var start = find(startNode), end = find(endNode);
+		if (start && end && start === end) {
+			return K(start);
+		}
+		return null;
+	},
+	state : function(key) {
+		var self = this, doc = self.doc, bool = false;
+		try {
+			bool = doc.queryCommandState(key);
+		} catch (e) {}
+		return bool;
+	},
+	val : function(key) {
+		var self = this, doc = self.doc, range = self.range;
+		function lc(val) {
+			return val.toLowerCase();
+		}
+		key = lc(key);
+		var val = '', knode;
+		if (key === 'fontfamily' || key === 'fontname') {
+			val = _nativeCommandValue(doc, 'fontname');
+			val = val.replace(/['"]/g, '');
+			return lc(val);
+		}
+		if (key === 'formatblock') {
+			val = _nativeCommandValue(doc, key);
+			if (val === '') {
+				knode = self.commonNode({'h1,h2,h3,h4,h5,h6,p,div,pre,address' : '*'});
+				if (knode) {
+					val = knode.name;
+				}
+			}
+			if (val === 'Normal') {
+				val = 'p';
+			}
+			return lc(val);
+		}
+		if (key === 'fontsize') {
+			knode = self.commonNode({'*' : '.font-size'});
+			if (knode) {
+				val = knode.css('font-size');
+			}
+			return lc(val);
+		}
+		if (key === 'forecolor') {
+			knode = self.commonNode({'*' : '.color'});
+			if (knode) {
+				val = knode.css('color');
+			}
+			val = _toHex(val);
+			if (val === '') {
+				val = 'default';
+			}
+			return lc(val);
+		}
+		if (key === 'hilitecolor') {
+			knode = self.commonNode({'*' : '.background-color'});
+			if (knode) {
+				val = knode.css('background-color');
+			}
+			val = _toHex(val);
+			if (val === '') {
+				val = 'default';
+			}
+			return lc(val);
+		}
+		return val;
+	},
+	toggle : function(wrapper, map) {
+		var self = this;
+		if (self.commonNode(map)) {
+			self.remove(map);
+		} else {
+			self.wrap(wrapper);
+		}
+		return self.select();
+	},
+	bold : function() {
+		return this.toggle('<strong></strong>', {
+			span : '.font-weight=bold',
+			strong : '*',
+			b : '*'
+		});
+	},
+	italic : function() {
+		return this.toggle('<em></em>', {
+			span : '.font-style=italic',
+			em : '*',
+			i : '*'
+		});
+	},
+	underline : function() {
+		return this.toggle('<u></u>', {
+			span : '.text-decoration=underline',
+			u : '*'
+		});
+	},
+	strikethrough : function() {
+		return this.toggle('<s></s>', {
+			span : '.text-decoration=line-through',
+			s : '*'
+		});
+	},
+	forecolor : function(val) {
+		return this.wrap('<span style="color:' + val + ';"></span>').select();
+	},
+	hilitecolor : function(val) {
+		return this.wrap('<span style="background-color:' + val + ';"></span>').select();
+	},
+	fontsize : function(val) {
+		return this.wrap('<span style="font-size:' + val + ';"></span>').select();
+	},
+	fontname : function(val) {
+		return this.fontfamily(val);
+	},
+	fontfamily : function(val) {
+		return this.wrap('<span style="font-family:' + val + ';"></span>').select();
+	},
+	removeformat : function() {
+		var map = {
+			'*' : '.font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent'
+		},
+		tags = _STYLE_TAG_MAP;
+		_each(tags, function(key, val) {
+			map[key] = '*';
+		});
+		this.remove(map);
+		return this.select();
+	},
+	inserthtml : function(val, quickMode) {
+		var self = this, range = self.range;
+		if (val === '') {
+			return self;
+		}
+		function pasteHtml(range, val) {
+			val = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + val;
+			var rng = range.get();
+			if (rng.item) {
+				rng.item(0).outerHTML = val;
+			} else {
+				rng.pasteHTML(val);
+			}
+			var temp = range.doc.getElementById('__kindeditor_temp_tag__');
+			temp.parentNode.removeChild(temp);
+			var newRange = _toRange(rng);
+			range.setEnd(newRange.endContainer, newRange.endOffset);
+			range.collapse(false);
+			self.select(false);
+		}
+		function insertHtml(range, val) {
+			var doc = range.doc,
+				frag = doc.createDocumentFragment();
+			K('@' + val, doc).each(function() {
+				frag.appendChild(this);
+			});
+			range.deleteContents();
+			range.insertNode(frag);
+			range.collapse(false);
+			self.select(false);
+		}
+		if (_IERANGE && quickMode) {
+			try {
+				pasteHtml(range, val);
+			} catch(e) {
+				insertHtml(range, val);
+			}
+			return self;
+		}
+		insertHtml(range, val);
+		return self;
+	},
+	hr : function() {
+		return this.inserthtml('<hr />');
+	},
+	print : function() {
+		this.win.print();
+		return this;
+	},
+	insertimage : function(url, title, width, height, border, align) {
+		title = _undef(title, '');
+		border = _undef(border, 0);
+		var html = '<img src="' + _escape(url) + '" data-ke-src="' + _escape(url) + '" ';
+		if (width) {
+			html += 'width="' + _escape(width) + '" ';
+		}
+		if (height) {
+			html += 'height="' + _escape(height) + '" ';
+		}
+		if (title) {
+			html += 'title="' + _escape(title) + '" ';
+		}
+		if (align) {
+			html += 'align="' + _escape(align) + '" ';
+		}
+		html += 'alt="' + _escape(title) + '" ';
+		html += '/>';
+		return this.inserthtml(html);
+	},
+	createlink : function(url, type) {
+		var self = this, doc = self.doc, range = self.range;
+		self.select();
+		var a = self.commonNode({ a : '*' });
+		if (a && !range.isControl()) {
+			range.selectNode(a.get());
+			self.select();
+		}
+		var html = '<a href="' + _escape(url) + '" data-ke-src="' + _escape(url) + '" ';
+		if (type) {
+			html += ' target="' + _escape(type) + '"';
+		}
+		if (range.collapsed) {
+			html += '>' + _escape(url) + '</a>';
+			return self.inserthtml(html);
+		}
+		if (range.isControl()) {
+			var node = K(range.startContainer.childNodes[range.startOffset]);
+			html += '></a>';
+			node.after(K(html, doc));
+			node.next().append(node);
+			range.selectNode(node[0]);
+			return self.select();
+		}
+		function setAttr(node, url, type) {
+			K(node).attr('href', url).attr('data-ke-src', url);
+			if (type) {
+				K(node).attr('target', type);
+			} else {
+				K(node).removeAttr('target');
+			}
+		}
+		var sc = range.startContainer, so = range.startOffset,
+			ec = range.endContainer, eo = range.endOffset;
+		if (sc.nodeType == 1 && sc === ec && so + 1 === eo) {
+			var child = sc.childNodes[so];
+			if (child.nodeName.toLowerCase() == 'a') {
+				setAttr(child, url, type);
+				return self;
+			}
+		}
+		_nativeCommand(doc, 'createlink', '__kindeditor_temp_url__');
+		K('a[href="__kindeditor_temp_url__"]', doc).each(function() {
+			setAttr(this, url, type);
+		});
+		return self;
+	},
+	unlink : function() {
+		var self = this, doc = self.doc, range = self.range;
+		self.select();
+		if (range.collapsed) {
+			var a = self.commonNode({ a : '*' });
+			if (a) {
+				range.selectNode(a.get());
+				self.select();
+			}
+			_nativeCommand(doc, 'unlink', null);
+			if (_WEBKIT && K(range.startContainer).name === 'img') {
+				var parent = K(range.startContainer).parent();
+				if (parent.name === 'a') {
+					parent.remove(true);
+				}
+			}
+		} else {
+			_nativeCommand(doc, 'unlink', null);
+		}
+		return self;
+	}
+});
+_each(('formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' +
+	'insertunorderedlist,indent,outdent,subscript,superscript').split(','), function(i, name) {
+	KCmd.prototype[name] = function(val) {
+		var self = this;
+		self.select();
+		_nativeCommand(self.doc, name, val);
+		if (_IERANGE && _inArray(name, 'justifyleft,justifycenter,justifyright,justifyfull'.split(',')) >= 0) {
+			self.selection();
+		}
+		if (!_IERANGE || _inArray(name, 'formatblock,selectall,insertorderedlist,insertunorderedlist'.split(',')) >= 0) {
+			self.selection();
+		}
+		return self;
+	};
+});
+_each('cut,copy,paste'.split(','), function(i, name) {
+	KCmd.prototype[name] = function() {
+		var self = this;
+		if (!self.doc.queryCommandSupported(name)) {
+			throw 'not supported';
+		}
+		self.select();
+		_nativeCommand(self.doc, name, null);
+		return self;
+	};
+});
+function _cmd(mixed) {
+	if (mixed.nodeName) {
+		var doc = _getDoc(mixed);
+		mixed = _range(doc).selectNodeContents(doc.body).collapse(false);
+	}
+	return new KCmd(mixed);
+}
+K.CmdClass = KCmd;
+K.cmd = _cmd;
+
+
+function _drag(options) {
+	var moveEl = options.moveEl,
+		moveFn = options.moveFn,
+		clickEl = options.clickEl || moveEl,
+		beforeDrag = options.beforeDrag,
+		iframeFix = options.iframeFix === undefined ? true : options.iframeFix;
+	var docs = [document];
+	if (iframeFix) {
+		K('iframe').each(function() {
+			var src = _formatUrl(this.src || '', 'absolute');
+			if (/^https?:\/\//.test(src)) {
+				return;
+			}
+			var doc;
+			try {
+				doc = _iframeDoc(this);
+			} catch(e) {}
+			if (doc) {
+				var pos = K(this).pos();
+				K(doc).data('pos-x', pos.x);
+				K(doc).data('pos-y', pos.y);
+				docs.push(doc);
+			}
+		});
+	}
+	clickEl.mousedown(function(e) {
+		if(e.button !== 0 && e.button !== 1) {
+			return;
+		}
+		e.stopPropagation();
+		var self = clickEl.get(),
+			x = _removeUnit(moveEl.css('left')),
+			y = _removeUnit(moveEl.css('top')),
+			width = moveEl.width(),
+			height = moveEl.height(),
+			pageX = e.pageX,
+			pageY = e.pageY;
+		if (beforeDrag) {
+			beforeDrag();
+		}
+		function moveListener(e) {
+			e.preventDefault();
+			var kdoc = K(_getDoc(e.target));
+			var diffX = _round((kdoc.data('pos-x') || 0) + e.pageX - pageX);
+			var diffY = _round((kdoc.data('pos-y') || 0) + e.pageY - pageY);
+			moveFn.call(clickEl, x, y, width, height, diffX, diffY);
+		}
+		function selectListener(e) {
+			e.preventDefault();
+		}
+		function upListener(e) {
+			e.preventDefault();
+			K(docs).unbind('mousemove', moveListener)
+				.unbind('mouseup', upListener)
+				.unbind('selectstart', selectListener);
+			if (self.releaseCapture) {
+				self.releaseCapture();
+			}
+		}
+		K(docs).mousemove(moveListener)
+			.mouseup(upListener)
+			.bind('selectstart', selectListener);
+		if (self.setCapture) {
+			self.setCapture();
+		}
+	});
+}
+

+function KWidget(options) {
+	this.init(options);
+}
+_extend(KWidget, {
+	init : function(options) {
+		var self = this;
+		self.name = options.name || '';
+		self.doc = options.doc || document;
+		self.win = _getWin(self.doc);
+		self.x = _addUnit(options.x);
+		self.y = _addUnit(options.y);
+		self.z = options.z;
+		self.width = _addUnit(options.width);
+		self.height = _addUnit(options.height);
+		self.div = K('<div style="display:block;"></div>');
+		self.options = options;
+		self._alignEl = options.alignEl;
+		if (self.width) {
+			self.div.css('width', self.width);
+		}
+		if (self.height) {
+			self.div.css('height', self.height);
+		}
+		if (self.z) {
+			self.div.css({
+				position : 'absolute',
+				left : self.x,
+				top : self.y,
+				'z-index' : self.z
+			});
+		}
+		if (self.z && (self.x === undefined || self.y === undefined)) {
+			self.autoPos(self.width, self.height);
+		}
+		if (options.cls) {
+			self.div.addClass(options.cls);
+		}
+		if (options.shadowMode) {
+			self.div.addClass('ke-shadow');
+		}
+		if (options.css) {
+			self.div.css(options.css);
+		}
+		if (options.src) {
+			K(options.src).replaceWith(self.div);
+		} else {
+			K(self.doc.body).append(self.div);
+		}
+		if (options.html) {
+			self.div.html(options.html);
+		}
+		if (options.autoScroll) {
+			if (_IE && _V < 7 || _QUIRKS) {
+				var scrollPos = _getScrollPos();
+				K(self.win).bind('scroll', function(e) {
+					var pos = _getScrollPos(),
+						diffX = pos.x - scrollPos.x,
+						diffY = pos.y - scrollPos.y;
+					self.pos(_removeUnit(self.x) + diffX, _removeUnit(self.y) + diffY, false);
+				});
+			} else {
+				self.div.css('position', 'fixed');
+			}
+		}
+	},
+	pos : function(x, y, updateProp) {
+		var self = this;
+		updateProp = _undef(updateProp, true);
+		if (x !== null) {
+			x = x < 0 ? 0 : _addUnit(x);
+			self.div.css('left', x);
+			if (updateProp) {
+				self.x = x;
+			}
+		}
+		if (y !== null) {
+			y = y < 0 ? 0 : _addUnit(y);
+			self.div.css('top', y);
+			if (updateProp) {
+				self.y = y;
+			}
+		}
+		return self;
+	},
+	autoPos : function(width, height) {
+		var self = this,
+			w = _removeUnit(width) || 0,
+			h = _removeUnit(height) || 0,
+			scrollPos = _getScrollPos();
+		if (self._alignEl) {
+			var knode = K(self._alignEl),
+				pos = knode.pos(),
+				diffX = _round(knode[0].clientWidth / 2 - w / 2),
+				diffY = _round(knode[0].clientHeight / 2 - h / 2);
+			x = diffX < 0 ? pos.x : pos.x + diffX;
+			y = diffY < 0 ? pos.y : pos.y + diffY;
+		} else {
+			var docEl = _docElement(self.doc);
+			x = _round(scrollPos.x + (docEl.clientWidth - w) / 2);
+			y = _round(scrollPos.y + (docEl.clientHeight - h) / 2);
+		}
+		if (!(_IE && _V < 7 || _QUIRKS)) {
+			x -= scrollPos.x;
+			y -= scrollPos.y;
+		}
+		return self.pos(x, y);
+	},
+	remove : function() {
+		var self = this;
+		if (_IE && _V < 7 || _QUIRKS) {
+			K(self.win).unbind('scroll');
+		}
+		self.div.remove();
+		_each(self, function(i) {
+			self[i] = null;
+		});
+		return this;
+	},
+	show : function() {
+		this.div.show();
+		return this;
+	},
+	hide : function() {
+		this.div.hide();
+		return this;
+	},
+	draggable : function(options) {
+		var self = this;
+		options = options || {};
+		options.moveEl = self.div;
+		options.moveFn = function(x, y, width, height, diffX, diffY) {
+			if ((x = x + diffX) < 0) {
+				x = 0;
+			}
+			if ((y = y + diffY) < 0) {
+				y = 0;
+			}
+			self.pos(x, y);
+		};
+		_drag(options);
+		return self;
+	}
+});
+function _widget(options) {
+	return new KWidget(options);
+}
+K.WidgetClass = KWidget;
+K.widget = _widget;
+
+
+function _iframeDoc(iframe) {
+	iframe = _get(iframe);
+	return iframe.contentDocument || iframe.contentWindow.document;
+}
+var html, _direction = '';
+if ((html = document.getElementsByTagName('html'))) {
+	_direction = html[0].dir;
+}
+function _getInitHtml(themesPath, bodyClass, cssPath, cssData) {
+	var arr = [
+		(_direction === '' ? '<html>' : '<html dir="' + _direction + '">'),
+		'<head><meta charset="utf-8" /><title></title>',
+		'<style>',
+		'html {margin:0;padding:0;}',
+		'body {margin:0;padding:5px;}',
+		'body, td {font:12px/1.5 "sans serif",tahoma,verdana,helvetica;}',
+		'body, p, div {word-wrap: break-word;}',
+		'p {margin:5px 0;}',
+		'table {border-collapse:collapse;}',
+		'img {border:0;}',
+		'noscript {display:none;}',
+		'table.ke-zeroborder td {border:1px dotted #AAA;}',
+		'img.ke-flash {',
+		'	border:1px solid #AAA;',
+		'	background-image:url(' + themesPath + 'common/flash.gif);',
+		'	background-position:center center;',
+		'	background-repeat:no-repeat;',
+		'	width:100px;',
+		'	height:100px;',
+		'}',
+		'img.ke-rm {',
+		'	border:1px solid #AAA;',
+		'	background-image:url(' + themesPath + 'common/rm.gif);',
+		'	background-position:center center;',
+		'	background-repeat:no-repeat;',
+		'	width:100px;',
+		'	height:100px;',
+		'}',
+		'img.ke-media {',
+		'	border:1px solid #AAA;',
+		'	background-image:url(' + themesPath + 'common/media.gif);',
+		'	background-position:center center;',
+		'	background-repeat:no-repeat;',
+		'	width:100px;',
+		'	height:100px;',
+		'}',
+		'img.ke-anchor {',
+		'	border:1px dashed #666;',
+		'	width:16px;',
+		'	height:16px;',
+		'}',
+		'.ke-script, .ke-noscript, .ke-display-none {',
+		'	display:none;',
+		'	font-size:0;',
+		'	width:0;',
+		'	height:0;',
+		'}',
+		'.ke-pagebreak {',
+		'	border:1px dotted #AAA;',
+		'	font-size:0;',
+		'	height:2px;',
+		'}',
+		'</style>'
+	];
+	if (!_isArray(cssPath)) {
+		cssPath = [cssPath];
+	}
+	_each(cssPath, function(i, path) {
+		if (path) {
+			arr.push('<link href="' + path + '" rel="stylesheet" />');
+		}
+	});
+	if (cssData) {
+		arr.push('<style>' + cssData + '</style>');
+	}
+	arr.push('</head><body ' + (bodyClass ? 'class="' + bodyClass + '"' : '') + '></body></html>');
+	return arr.join('\n');
+}
+function _elementVal(knode, val) {
+	if (knode.hasVal()) {
+		if (val === undefined) {
+			var html = knode.val();
+			html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, '');
+			return html;
+		}
+		return knode.val(val);
+	}
+	return knode.html(val);
+}
+

+function KEdit(options) {
+	this.init(options);
+}
+_extend(KEdit, KWidget, {
+	init : function(options) {
+		var self = this;
+		KEdit.parent.init.call(self, options);
+		self.srcElement = K(options.srcElement);
+		self.div.addClass('ke-edit');
+		self.designMode = _undef(options.designMode, true);
+		self.beforeGetHtml = options.beforeGetHtml;
+		self.beforeSetHtml = options.beforeSetHtml;
+		self.afterSetHtml = options.afterSetHtml;
+		var themesPath = _undef(options.themesPath, ''),
+			bodyClass = options.bodyClass,
+			cssPath = options.cssPath,
+			cssData = options.cssData,
+			isDocumentDomain = location.protocol != 'res:' && location.host.replace(/:\d+/, '') !== document.domain,
+			srcScript = ('document.open();' +
+				(isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') +
+				'document.close();'),
+			iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : '';
+		self.iframe = K('<iframe class="ke-edit-iframe" hidefocus="true" frameborder="0"' + iframeSrc + '></iframe>').css('width', '100%');
+		self.textarea = K('<textarea class="ke-edit-textarea" hidefocus="true"></textarea>').css('width', '100%');
+		self.tabIndex = isNaN(parseInt(options.tabIndex, 10)) ? self.srcElement.attr('tabindex') : parseInt(options.tabIndex, 10);
+		self.iframe.attr('tabindex', self.tabIndex);
+		self.textarea.attr('tabindex', self.tabIndex);
+		if (self.width) {
+			self.setWidth(self.width);
+		}
+		if (self.height) {
+			self.setHeight(self.height);
+		}
+		if (self.designMode) {
+			self.textarea.hide();
+		} else {
+			self.iframe.hide();
+		}
+		function ready() {
+			var doc = _iframeDoc(self.iframe);
+			doc.open();
+			if (isDocumentDomain) {
+				doc.domain = document.domain;
+			}
+			doc.write(_getInitHtml(themesPath, bodyClass, cssPath, cssData));
+			doc.close();
+			self.win = self.iframe[0].contentWindow;
+			self.doc = doc;
+			var cmd = _cmd(doc);
+			self.afterChange(function(e) {
+				cmd.selection();
+			});
+			if (_WEBKIT) {
+				K(doc).click(function(e) {
+					if (K(e.target).name === 'img') {
+						cmd.selection(true);
+						cmd.range.selectNode(e.target);
+						cmd.select();
+					}
+				});
+			}
+			if (_IE) {
+				self._mousedownHandler = function() {
+					var newRange = cmd.range.cloneRange();
+					newRange.shrink();
+					if (newRange.isControl()) {
+						self.blur();
+					}
+				};
+				K(document).mousedown(self._mousedownHandler);
+				K(doc).keydown(function(e) {
+					if (e.which == 8) {
+						cmd.selection();
+						var rng = cmd.range;
+						if (rng.isControl()) {
+							rng.collapse(true);
+							K(rng.startContainer.childNodes[rng.startOffset]).remove();
+							e.preventDefault();
+						}
+					}
+				});
+			}
+			self.cmd = cmd;
+			self.html(_elementVal(self.srcElement));
+			if (_IE) {
+				doc.body.disabled = true;
+				doc.body.contentEditable = true;
+				doc.body.removeAttribute('disabled');
+			} else {
+				doc.designMode = 'on';
+			}
+			if (options.afterCreate) {
+				options.afterCreate.call(self);
+			}
+		}
+		if (isDocumentDomain) {
+			self.iframe.bind('load', function(e) {
+				self.iframe.unbind('load');
+				if (_IE) {
+					ready();
+				} else {
+					setTimeout(ready, 0);
+				}
+			});
+		}
+		self.div.append(self.iframe);
+		self.div.append(self.textarea);
+		self.srcElement.hide();
+		!isDocumentDomain && ready();
+	},
+	setWidth : function(val) {
+		var self = this;
+		val = _addUnit(val);
+		self.width = val;
+		self.div.css('width', val);
+		return self;
+	},
+	setHeight : function(val) {
+		var self = this;
+		val = _addUnit(val);
+		self.height = val;
+		self.div.css('height', val);
+		self.iframe.css('height', val);
+		if ((_IE && _V < 8) || _QUIRKS) {
+			val = _addUnit(_removeUnit(val) - 2);
+		}
+		self.textarea.css('height', val);
+		return self;
+	},
+	remove : function() {
+		var self = this, doc = self.doc;
+		K(doc.body).unbind();
+		K(doc).unbind();
+		K(self.win).unbind();
+		if (self._mousedownHandler) {
+			K(document).unbind('mousedown', self._mousedownHandler);
+		}
+		_elementVal(self.srcElement, self.html());
+		self.srcElement.show();
+		self.iframe.unbind();
+		self.textarea.unbind();
+		KEdit.parent.remove.call(self);
+	},
+	html : function(val, isFull) {
+		var self = this, doc = self.doc;
+		if (self.designMode) {
+			var body = doc.body;
+			if (val === undefined) {
+				if (isFull) {
+					val = '<!doctype html><html>' + body.parentNode.innerHTML + '</html>';
+				} else {
+					val = body.innerHTML;
+				}
+				if (self.beforeGetHtml) {
+					val = self.beforeGetHtml(val);
+				}
+				if (_GECKO && val == '<br />') {
+					val = '';
+				}
+				return val;
+			}
+			if (self.beforeSetHtml) {
+				val = self.beforeSetHtml(val);
+			}
+			if (_IE && _V >= 9) {
+				val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2');
+			}
+			K(body).html(val);
+			if (self.afterSetHtml) {
+				self.afterSetHtml();
+			}
+			return self;
+		}
+		if (val === undefined) {
+			return self.textarea.val();
+		}
+		self.textarea.val(val);
+		return self;
+	},
+	design : function(bool) {
+		var self = this, val;
+		if (bool === undefined ? !self.designMode : bool) {
+			if (!self.designMode) {
+				val = self.html();
+				self.designMode = true;
+				self.textarea.hide();
+				self.html(val);
+				var iframe = self.iframe;
+				var height = _removeUnit(self.height);
+				iframe.height(height - 2);
+				iframe.show();
+				setTimeout(function() {
+					iframe.height(height);
+				}, 0);
+			}
+		} else {
+			if (self.designMode) {
+				val = self.html();
+				self.designMode = false;
+				self.html(val);
+				self.iframe.hide();
+				self.textarea.show();
+			}
+		}
+		return self.focus();
+	},
+	focus : function() {
+		var self = this;
+		self.designMode ? self.win.focus() : self.textarea[0].focus();
+		return self;
+	},
+	blur : function() {
+		var self = this;
+		if (_IE) {
+			var input = K('<input type="text" style="float:left;width:0;height:0;padding:0;margin:0;border:0;" value="" />', self.div);
+			self.div.append(input);
+			input[0].focus();
+			input.remove();
+		} else {
+			self.designMode ? self.win.blur() : self.textarea[0].blur();
+		}
+		return self;
+	},
+	afterChange : function(fn) {
+		var self = this, doc = self.doc, body = doc.body;
+		K(doc).keyup(function(e) {
+			if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) {
+				fn(e);
+			}
+		});
+		K(doc).mouseup(fn).contextmenu(fn);
+		K(self.win).blur(fn);
+		function timeoutHandler(e) {
+			setTimeout(function() {
+				fn(e);
+			}, 1);
+		}
+		K(body).bind('paste', timeoutHandler);
+		K(body).bind('cut', timeoutHandler);
+		return self;
+	}
+});
+function _edit(options) {
+	return new KEdit(options);
+}
+K.EditClass = KEdit;
+K.edit = _edit;
+K.iframeDoc = _iframeDoc;
+
+
+function _selectToolbar(name, fn) {
+	var self = this,
+		knode = self.get(name);
+	if (knode) {
+		if (knode.hasClass('ke-disabled')) {
+			return;
+		}
+		fn(knode);
+	}
+}
+

+function KToolbar(options) {
+	this.init(options);
+}
+_extend(KToolbar, KWidget, {
+	init : function(options) {
+		var self = this;
+		KToolbar.parent.init.call(self, options);
+		self.disableMode = _undef(options.disableMode, false);
+		self.noDisableItemMap = _toMap(_undef(options.noDisableItems, []));
+		self._itemMap = {};
+		self.div.addClass('ke-toolbar').bind('contextmenu,mousedown,mousemove', function(e) {
+			e.preventDefault();
+		}).attr('unselectable', 'on');
+		function find(target) {
+			var knode = K(target);
+			if (knode.hasClass('ke-outline')) {
+				return knode;
+			}
+			if (knode.hasClass('ke-toolbar-icon')) {
+				return knode.parent();
+			}
+		}
+		function hover(e, method) {
+			var knode = find(e.target);
+			if (knode) {
+				if (knode.hasClass('ke-disabled')) {
+					return;
+				}
+				if (knode.hasClass('ke-selected')) {
+					return;
+				}
+				knode[method]('ke-on');
+			}
+		}
+		self.div.mouseover(function(e) {
+			hover(e, 'addClass');
+		})
+		.mouseout(function(e) {
+			hover(e, 'removeClass');
+		})
+		.click(function(e) {
+			var knode = find(e.target);
+			if (knode) {
+				if (knode.hasClass('ke-disabled')) {
+					return;
+				}
+				self.options.click.call(this, e, knode.attr('data-name'));
+			}
+		});
+	},
+	get : function(name) {
+		if (this._itemMap[name]) {
+			return this._itemMap[name];
+		}
+		return (this._itemMap[name] = K('span.ke-icon-' + name, this.div).parent());
+	},
+	select : function(name) {
+		_selectToolbar.call(this, name, function(knode) {
+			knode.addClass('ke-selected');
+		});
+		return self;
+	},
+	unselect : function(name) {
+		_selectToolbar.call(this, name, function(knode) {
+			knode.removeClass('ke-selected').removeClass('ke-on');
+		});
+		return self;
+	},
+	enable : function(name) {
+		var self = this,
+			knode = name.get ? name : self.get(name);
+		if (knode) {
+			knode.removeClass('ke-disabled');
+			knode.opacity(1);
+		}
+		return self;
+	},
+	disable : function(name) {
+		var self = this,
+			knode = name.get ? name : self.get(name);
+		if (knode) {
+			knode.removeClass('ke-selected').addClass('ke-disabled');
+			knode.opacity(0.5);
+		}
+		return self;
+	},
+	disableAll : function(bool, noDisableItems) {
+		var self = this, map = self.noDisableItemMap, item;
+		if (noDisableItems) {
+			map = _toMap(noDisableItems);
+		}
+		if (bool === undefined ? !self.disableMode : bool) {
+			K('span.ke-outline', self.div).each(function() {
+				var knode = K(this),
+					name = knode[0].getAttribute('data-name', 2);
+				if (!map[name]) {
+					self.disable(knode);
+				}
+			});
+			self.disableMode = true;
+		} else {
+			K('span.ke-outline', self.div).each(function() {
+				var knode = K(this),
+					name = knode[0].getAttribute('data-name', 2);
+				if (!map[name]) {
+					self.enable(knode);
+				}
+			});
+			self.disableMode = false;
+		}
+		return self;
+	}
+});
+function _toolbar(options) {
+	return new KToolbar(options);
+}
+K.ToolbarClass = KToolbar;
+K.toolbar = _toolbar;
+
+

+function KMenu(options) {
+	this.init(options);
+}
+_extend(KMenu, KWidget, {
+	init : function(options) {
+		var self = this;
+		options.z = options.z || 811213;
+		KMenu.parent.init.call(self, options);
+		self.centerLineMode = _undef(options.centerLineMode, true);
+		self.div.addClass('ke-menu').bind('click,mousedown', function(e){
+			e.stopPropagation();
+		}).attr('unselectable', 'on');
+	},
+	addItem : function(item) {
+		var self = this;
+		if (item.title === '-') {
+			self.div.append(K('<div class="ke-menu-separator"></div>'));
+			return;
+		}
+		var itemDiv = K('<div class="ke-menu-item" unselectable="on"></div>'),
+			leftDiv = K('<div class="ke-inline-block ke-menu-item-left"></div>'),
+			rightDiv = K('<div class="ke-inline-block ke-menu-item-right"></div>'),
+			height = _addUnit(item.height),
+			iconClass = _undef(item.iconClass, '');
+		self.div.append(itemDiv);
+		if (height) {
+			itemDiv.css('height', height);
+			rightDiv.css('line-height', height);
+		}
+		var centerDiv;
+		if (self.centerLineMode) {
+			centerDiv = K('<div class="ke-inline-block ke-menu-item-center"></div>');
+			if (height) {
+				centerDiv.css('height', height);
+			}
+		}
+		itemDiv.mouseover(function(e) {
+			K(this).addClass('ke-menu-item-on');
+			if (centerDiv) {
+				centerDiv.addClass('ke-menu-item-center-on');
+			}
+		})
+		.mouseout(function(e) {
+			K(this).removeClass('ke-menu-item-on');
+			if (centerDiv) {
+				centerDiv.removeClass('ke-menu-item-center-on');
+			}
+		})
+		.click(function(e) {
+			item.click.call(K(this));
+			e.stopPropagation();
+		})
+		.append(leftDiv);
+		if (centerDiv) {
+			itemDiv.append(centerDiv);
+		}
+		itemDiv.append(rightDiv);
+		if (item.checked) {
+			iconClass = 'ke-icon-checked';
+		}
+		if (iconClass !== '') {
+			leftDiv.html('<span class="ke-inline-block ke-toolbar-icon ke-toolbar-icon-url ' + iconClass + '"></span>');
+		}
+		rightDiv.html(item.title);
+		return self;
+	},
+	remove : function() {
+		var self = this;
+		if (self.options.beforeRemove) {
+			self.options.beforeRemove.call(self);
+		}
+		K('.ke-menu-item', self.div[0]).unbind();
+		KMenu.parent.remove.call(self);
+		return self;
+	}
+});
+function _menu(options) {
+	return new KMenu(options);
+}
+K.MenuClass = KMenu;
+K.menu = _menu;
+
+

+function KColorPicker(options) {
+	this.init(options);
+}
+_extend(KColorPicker, KWidget, {
+	init : function(options) {
+		var self = this;
+		options.z = options.z || 811213;
+		KColorPicker.parent.init.call(self, options);
+		var colors = options.colors || [
+			['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'],
+			['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'],
+			['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'],
+			['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000']
+		];
+		self.selectedColor = (options.selectedColor || '').toLowerCase();
+		self._cells = [];
+		self.div.addClass('ke-colorpicker').bind('click,mousedown', function(e){
+			e.stopPropagation();
+		}).attr('unselectable', 'on');
+		var table = self.doc.createElement('table');
+		self.div.append(table);
+		table.className = 'ke-colorpicker-table';
+		table.cellPadding = 0;
+		table.cellSpacing = 0;
+		table.border = 0;
+		var row = table.insertRow(0), cell = row.insertCell(0);
+		cell.colSpan = colors[0].length;
+		self._addAttr(cell, '', 'ke-colorpicker-cell-top');
+		for (var i = 0; i < colors.length; i++) {
+			row = table.insertRow(i + 1);
+			for (var j = 0; j < colors[i].length; j++) {
+				cell = row.insertCell(j);
+				self._addAttr(cell, colors[i][j], 'ke-colorpicker-cell');
+			}
+		}
+	},
+	_addAttr : function(cell, color, cls) {
+		var self = this;
+		cell = K(cell).addClass(cls);
+		if (self.selectedColor === color.toLowerCase()) {
+			cell.addClass('ke-colorpicker-cell-selected');
+		}
+		cell.attr('title', color || self.options.noColor);
+		cell.mouseover(function(e) {
+			K(this).addClass('ke-colorpicker-cell-on');
+		});
+		cell.mouseout(function(e) {
+			K(this).removeClass('ke-colorpicker-cell-on');
+		});
+		cell.click(function(e) {
+			e.stop();
+			self.options.click.call(K(this), color);
+		});
+		if (color) {
+			cell.append(K('<div class="ke-colorpicker-cell-color" unselectable="on"></div>').css('background-color', color));
+		} else {
+			cell.html(self.options.noColor);
+		}
+		K(cell).attr('unselectable', 'on');
+		self._cells.push(cell);
+	},
+	remove : function() {
+		var self = this;
+		_each(self._cells, function() {
+			this.unbind();
+		});
+		KColorPicker.parent.remove.call(self);
+		return self;
+	}
+});
+function _colorpicker(options) {
+	return new KColorPicker(options);
+}
+K.ColorPickerClass = KColorPicker;
+K.colorpicker = _colorpicker;
+
+
+function KUploadButton(options) {
+	this.init(options);
+}
+_extend(KUploadButton, {
+	init : function(options) {
+		var self = this,
+			button = K(options.button),
+			fieldName = options.fieldName || 'file',
+			url = options.url || '',
+			title = button.val(),
+			extraParams = options.extraParams || {},
+			cls = button[0].className || '',
+			target = options.target || 'kindeditor_upload_iframe_' + new Date().getTime();
+		options.afterError = options.afterError || function(str) {
+			alert(str);
+		};
+		var hiddenElements = [];
+		for(var k in extraParams){
+			hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />');
+		}
+		var html = [
+			'<div class="ke-inline-block ' + cls + '">',
+			(options.target ? '' : '<iframe name="' + target + '" style="display:none;"></iframe>'),
+			(options.form ? '<div class="ke-upload-area">' : '<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + url + '">'),
+			'<span class="ke-button-common">',
+			hiddenElements.join(''),
+			'<input type="button" class="ke-button-common ke-button" value="' + title + '" />',
+			'</span>',
+			'<input type="file" class="ke-upload-file" name="' + fieldName + '" tabindex="-1" />',
+			(options.form ? '</div>' : '</form>'),
+			'</div>'].join('');
+		var div = K(html, button.doc);
+		button.hide();
+		button.before(div);
+		self.div = div;
+		self.button = button;
+		self.iframe = options.target ? K('iframe[name="' + target + '"]') : K('iframe', div);
+		self.form = options.form ? K(options.form) : K('form', div);
+		self.fileBox = K('.ke-upload-file', div);
+		var width = options.width || K('.ke-button-common', div).width();
+		K('.ke-upload-area', div).width(width);
+		self.options = options;
+	},
+	submit : function() {
+		var self = this,
+			iframe = self.iframe;
+		iframe.bind('load', function() {
+			iframe.unbind();
+			var tempForm = document.createElement('form');
+			self.fileBox.before(tempForm);
+			K(tempForm).append(self.fileBox);
+			tempForm.reset();
+			K(tempForm).remove(true);
+			var doc = K.iframeDoc(iframe),
+				pre = doc.getElementsByTagName('pre')[0],
+				str = '', data;
+			if (pre) {
+				str = pre.innerHTML;
+			} else {
+				str = doc.body.innerHTML;
+			}
+			str = _unescape(str);
+			iframe[0].src = 'javascript:false';
+			try {
+				data = K.json(str);
+			} catch (e) {
+				self.options.afterError.call(self, '<!doctype html><html>' + doc.body.parentNode.innerHTML + '</html>');
+			}
+			if (data) {
+				self.options.afterUpload.call(self, data);
+			}
+		});
+		self.form[0].submit();
+		return self;
+	},
+	remove : function() {
+		var self = this;
+		if (self.fileBox) {
+			self.fileBox.unbind();
+		}
+		self.iframe.remove();
+		self.div.remove();
+		self.button.show();
+		return self;
+	}
+});
+function _uploadbutton(options) {
+	return new KUploadButton(options);
+}
+K.UploadButtonClass = KUploadButton;
+K.uploadbutton = _uploadbutton;
+
+
+function _createButton(arg) {
+	arg = arg || {};
+	var name = arg.name || '',
+		span = K('<span class="ke-button-common ke-button-outer" title="' + name + '"></span>'),
+		btn = K('<input class="ke-button-common ke-button" type="button" value="' + name + '" />');
+	if (arg.click) {
+		btn.click(arg.click);
+	}
+	span.append(btn);
+	return span;
+}
+

+function KDialog(options) {
+	this.init(options);
+}
+_extend(KDialog, KWidget, {
+	init : function(options) {
+		var self = this;
+		var shadowMode = _undef(options.shadowMode, true);
+		options.z = options.z || 811213;
+		options.shadowMode = false;
+		options.autoScroll = _undef(options.autoScroll, true);
+		KDialog.parent.init.call(self, options);
+		var title = options.title,
+			body = K(options.body, self.doc),
+			previewBtn = options.previewBtn,
+			yesBtn = options.yesBtn,
+			noBtn = options.noBtn,
+			closeBtn = options.closeBtn,
+			showMask = _undef(options.showMask, true);
+		self.div.addClass('ke-dialog').bind('click,mousedown', function(e){
+			e.stopPropagation();
+		});
+		var contentDiv = K('<div class="ke-dialog-content"></div>').appendTo(self.div);
+		if (_IE && _V < 7) {
+			self.iframeMask = K('<iframe src="about:blank" class="ke-dialog-shadow"></iframe>').appendTo(self.div);
+		} else if (shadowMode) {
+			K('<div class="ke-dialog-shadow"></div>').appendTo(self.div);
+		}
+		var headerDiv = K('<div class="ke-dialog-header"></div>');
+		contentDiv.append(headerDiv);
+		headerDiv.html(title);
+		self.closeIcon = K('<span class="ke-dialog-icon-close" title="' + closeBtn.name + '"></span>').click(closeBtn.click);
+		headerDiv.append(self.closeIcon);
+		self.draggable({
+			clickEl : headerDiv,
+			beforeDrag : options.beforeDrag
+		});
+		var bodyDiv = K('<div class="ke-dialog-body"></div>');
+		contentDiv.append(bodyDiv);
+		bodyDiv.append(body);
+		var footerDiv = K('<div class="ke-dialog-footer"></div>');
+		if (previewBtn || yesBtn || noBtn) {
+			contentDiv.append(footerDiv);
+		}
+		_each([
+			{ btn : previewBtn, name : 'preview' },
+			{ btn : yesBtn, name : 'yes' },
+			{ btn : noBtn, name : 'no' }
+		], function() {
+			if (this.btn) {
+				var button = _createButton(this.btn);
+				button.addClass('ke-dialog-' + this.name);
+				footerDiv.append(button);
+			}
+		});
+		if (self.height) {
+			bodyDiv.height(_removeUnit(self.height) - headerDiv.height() - footerDiv.height());
+		}
+		self.div.width(self.div.width());
+		self.div.height(self.div.height());
+		self.mask = null;
+		if (showMask) {
+			var docEl = _docElement(self.doc),
+				docWidth = Math.max(docEl.scrollWidth, docEl.clientWidth),
+				docHeight = Math.max(docEl.scrollHeight, docEl.clientHeight);
+			self.mask = _widget({
+				x : 0,
+				y : 0,
+				z : self.z - 1,
+				cls : 'ke-dialog-mask',
+				width : docWidth,
+				height : docHeight
+			});
+		}
+		self.autoPos(self.div.width(), self.div.height());
+		self.footerDiv = footerDiv;
+		self.bodyDiv = bodyDiv;
+		self.headerDiv = headerDiv;
+		self.isLoading = false;
+	},
+	setMaskIndex : function(z) {
+		var self = this;
+		self.mask.div.css('z-index', z);
+	},
+	showLoading : function(msg) {
+		msg = _undef(msg, '');
+		var self = this, body = self.bodyDiv;
+		self.loading = K('<div class="ke-dialog-loading"><div class="ke-inline-block ke-dialog-loading-content" style="margin-top:' + Math.round(body.height() / 3) + 'px;">' + msg + '</div></div>')
+			.width(body.width()).height(body.height())
+			.css('top', self.headerDiv.height() + 'px');
+		body.css('visibility', 'hidden').after(self.loading);
+		self.isLoading = true;
+		return self;
+	},
+	hideLoading : function() {
+		this.loading && this.loading.remove();
+		this.bodyDiv.css('visibility', 'visible');
+		this.isLoading = false;
+		return this;
+	},
+	remove : function() {
+		var self = this;
+		if (self.options.beforeRemove) {
+			self.options.beforeRemove.call(self);
+		}
+		self.mask && self.mask.remove();
+		self.iframeMask && self.iframeMask.remove();
+		self.closeIcon.unbind();
+		K('input', self.div).unbind();
+		K('button', self.div).unbind();
+		self.footerDiv.unbind();
+		self.bodyDiv.unbind();
+		self.headerDiv.unbind();
+		K('iframe', self.div).each(function() {
+			K(this).remove();
+		});
+		KDialog.parent.remove.call(self);
+		return self;
+	}
+});
+function _dialog(options) {
+	return new KDialog(options);
+}
+K.DialogClass = KDialog;
+K.dialog = _dialog;
+
+
+function _tabs(options) {
+	var self = _widget(options),
+		remove = self.remove,
+		afterSelect = options.afterSelect,
+		div = self.div,
+		liList = [];
+	div.addClass('ke-tabs')
+		.bind('contextmenu,mousedown,mousemove', function(e) {
+			e.preventDefault();
+		});
+	var ul = K('<ul class="ke-tabs-ul ke-clearfix"></ul>');
+	div.append(ul);
+	self.add = function(tab) {
+		var li = K('<li class="ke-tabs-li">' + tab.title + '</li>');
+		li.data('tab', tab);
+		liList.push(li);
+		ul.append(li);
+	};
+	self.selectedIndex = 0;
+	self.select = function(index) {
+		self.selectedIndex = index;
+		_each(liList, function(i, li) {
+			li.unbind();
+			if (i === index) {
+				li.addClass('ke-tabs-li-selected');
+				K(li.data('tab').panel).show('');
+			} else {
+				li.removeClass('ke-tabs-li-selected').removeClass('ke-tabs-li-on')
+				.mouseover(function() {
+					K(this).addClass('ke-tabs-li-on');
+				})
+				.mouseout(function() {
+					K(this).removeClass('ke-tabs-li-on');
+				})
+				.click(function() {
+					self.select(i);
+				});
+				K(li.data('tab').panel).hide();
+			}
+		});
+		if (afterSelect) {
+			afterSelect.call(self, index);
+		}
+	};
+	self.remove = function() {
+		_each(liList, function() {
+			this.remove();
+		});
+		ul.remove();
+		remove.call(self);
+	};
+	return self;
+}
+K.tabs = _tabs;
+
+
+function _loadScript(url, fn) {
+	var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement),
+		script = document.createElement('script');
+	head.appendChild(script);
+	script.src = url;
+	script.charset = 'utf-8';
+	script.onload = script.onreadystatechange = function() {
+		if (!this.readyState || this.readyState === 'loaded') {
+			if (fn) {
+				fn();
+			}
+			script.onload = script.onreadystatechange = null;
+			head.removeChild(script);
+		}
+	};
+}
+

+function _chopQuery(url) {
+	var index = url.indexOf('?');
+	return index > 0 ? url.substr(0, index) : url;
+}
+function _loadStyle(url) {
+	var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement),
+		link = document.createElement('link'),
+		absoluteUrl = _chopQuery(_formatUrl(url, 'absolute'));
+	var links = K('link[rel="stylesheet"]', head);
+	for (var i = 0, len = links.length; i < len; i++) {
+		if (_chopQuery(_formatUrl(links[i].href, 'absolute')) === absoluteUrl) {
+			return;
+		}
+	}
+	head.appendChild(link);
+	link.href = url;
+	link.rel = 'stylesheet';
+}
+function _ajax(url, fn, method, param, dataType) {
+	method = method || 'GET';
+	dataType = dataType || 'json';
+	var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
+	xhr.open(method, url, true);
+	xhr.onreadystatechange = function () {
+		if (xhr.readyState == 4 && xhr.status == 200) {
+			if (fn) {
+				var data = _trim(xhr.responseText);
+				if (dataType == 'json') {
+					data = _json(data);
+				}
+				fn(data);
+			}
+		}
+	};
+	if (method == 'POST') {
+		var params = [];
+		_each(param, function(key, val) {
+			params.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
+		});
+		try {
+			xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+		} catch (e) {}
+		xhr.send(params.join('&'));
+	} else {
+		xhr.send(null);
+	}
+}
+K.loadScript = _loadScript;
+K.loadStyle = _loadStyle;
+K.ajax = _ajax;
+
+
+var _plugins = {};
+function _plugin(name, fn) {
+	if (name === undefined) {
+		return _plugins;
+	}
+	if (!fn) {
+		return _plugins[name];
+	}
+	_plugins[name] = fn;
+}
+var _language = {};
+function _parseLangKey(key) {
+	var match, ns = 'core';
+	if ((match = /^(\w+)\.(\w+)$/.exec(key))) {
+		ns = match[1];
+		key = match[2];
+	}
+	return { ns : ns, key : key };
+}
+function _lang(mixed, langType) {
+	langType = langType === undefined ? K.options.langType : langType;
+	if (typeof mixed === 'string') {
+		if (!_language[langType]) {
+			return 'no language';
+		}
+		var pos = mixed.length - 1;
+		if (mixed.substr(pos) === '.') {
+			return _language[langType][mixed.substr(0, pos)];
+		}
+		var obj = _parseLangKey(mixed);
+		return _language[langType][obj.ns][obj.key];
+	}
+	_each(mixed, function(key, val) {
+		var obj = _parseLangKey(key);
+		if (!_language[langType]) {
+			_language[langType] = {};
+		}
+		if (!_language[langType][obj.ns]) {
+			_language[langType][obj.ns] = {};
+		}
+		_language[langType][obj.ns][obj.key] = val;
+	});
+}
+

+function _getImageFromRange(range, fn) {
+	if (range.collapsed) {
+		return;
+	}
+	range = range.cloneRange().up();
+	var sc = range.startContainer, so = range.startOffset;
+	if (!_WEBKIT && !range.isControl()) {
+		return;
+	}
+	var img = K(sc.childNodes[so]);
+	if (!img || img.name != 'img') {
+		return;
+	}
+	if (fn(img)) {
+		return img;
+	}
+}
+function _bindContextmenuEvent() {
+	var self = this, doc = self.edit.doc;
+	K(doc).contextmenu(function(e) {
+		if (self.menu) {
+			self.hideMenu();
+		}
+		if (!self.useContextmenu) {
+			e.preventDefault();
+			return;
+		}
+		if (self._contextmenus.length === 0) {
+			return;
+		}
+		var maxWidth = 0, items = [];
+		_each(self._contextmenus, function() {
+			if (this.title == '-') {
+				items.push(this);
+				return;
+			}
+			if (this.cond && this.cond()) {
+				items.push(this);
+				if (this.width && this.width > maxWidth) {
+					maxWidth = this.width;
+				}
+			}
+		});
+		while (items.length > 0 && items[0].title == '-') {
+			items.shift();
+		}
+		while (items.length > 0 && items[items.length - 1].title == '-') {
+			items.pop();
+		}
+		var prevItem = null;
+		_each(items, function(i) {
+			if (this.title == '-' && prevItem.title == '-') {
+				delete items[i];
+			}
+			prevItem = this;
+		});
+		if (items.length > 0) {
+			e.preventDefault();
+			var pos = K(self.edit.iframe).pos(),
+				menu = _menu({
+					x : pos.x + e.clientX,
+					y : pos.y + e.clientY,
+					width : maxWidth,
+					css : { visibility: 'hidden' },
+					shadowMode : self.shadowMode
+				});
+			_each(items, function() {
+				if (this.title) {
+					menu.addItem(this);
+				}
+			});
+			var docEl = _docElement(menu.doc),
+				menuHeight = menu.div.height();
+			if (e.clientY + menuHeight >= docEl.clientHeight - 100) {
+				menu.pos(menu.x, _removeUnit(menu.y) - menuHeight);
+			}
+			menu.div.css('visibility', 'visible');
+			self.menu = menu;
+		}
+	});
+}
+function _bindNewlineEvent() {
+	var self = this, doc = self.edit.doc, newlineTag = self.newlineTag;
+	if (_IE && newlineTag !== 'br') {
+		return;
+	}
+	if (_GECKO && _V < 3 && newlineTag !== 'p') {
+		return;
+	}
+	if (_OPERA && _V < 9) {
+		return;
+	}
+	var brSkipTagMap = _toMap('h1,h2,h3,h4,h5,h6,pre,li'),
+		pSkipTagMap = _toMap('p,h1,h2,h3,h4,h5,h6,pre,li,blockquote');
+	function getAncestorTagName(range) {
+		var ancestor = K(range.commonAncestor());
+		while (ancestor) {
+			if (ancestor.type == 1 && !ancestor.isStyle()) {
+				break;
+			}
+			ancestor = ancestor.parent();
+		}
+		return ancestor.name;
+	}
+	K(doc).keydown(function(e) {
+		if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
+			return;
+		}
+		self.cmd.selection();
+		var tagName = getAncestorTagName(self.cmd.range);
+		if (tagName == 'marquee' || tagName == 'select') {
+			return;
+		}
+		if (newlineTag === 'br' && !brSkipTagMap[tagName]) {
+			e.preventDefault();
+			self.insertHtml('<br />' + (_IE && _V < 9 ? '' : '\u200B'));
+			return;
+		}
+		if (!pSkipTagMap[tagName]) {
+			_nativeCommand(doc, 'formatblock', '<p>');
+		}
+	});
+	K(doc).keyup(function(e) {
+		if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
+			return;
+		}
+		if (newlineTag == 'br') {
+			return;
+		}
+		if (_GECKO) {
+			var root = self.cmd.commonAncestor('p');
+			var a = self.cmd.commonAncestor('a');
+			if (a && a.text() == '') {
+				a.remove(true);
+				self.cmd.range.selectNodeContents(root[0]).collapse(true);
+				self.cmd.select();
+			}
+			return;
+		}
+		self.cmd.selection();
+		var tagName = getAncestorTagName(self.cmd.range);
+		if (tagName == 'marquee' || tagName == 'select') {
+			return;
+		}
+		if (!pSkipTagMap[tagName]) {
+			_nativeCommand(doc, 'formatblock', '<p>');
+		}
+		var div = self.cmd.commonAncestor('div');
+		if (div) {
+			var p = K('<p></p>'),
+				child = div[0].firstChild;
+			while (child) {
+				var next = child.nextSibling;
+				p.append(child);
+				child = next;
+			}
+			div.before(p);
+			div.remove();
+			self.cmd.range.selectNodeContents(p[0]);
+			self.cmd.select();
+		}
+	});
+}
+function _bindTabEvent() {
+	var self = this, doc = self.edit.doc;
+	K(doc).keydown(function(e) {
+		if (e.which == 9) {
+			e.preventDefault();
+			if (self.afterTab) {
+				self.afterTab.call(self, e);
+				return;
+			}
+			var cmd = self.cmd, range = cmd.range;
+			range.shrink();
+			if (range.collapsed && range.startContainer.nodeType == 1) {
+				range.insertNode(K('@&nbsp;', doc)[0]);
+				cmd.select();
+			}
+			self.insertHtml('&nbsp;&nbsp;&nbsp;&nbsp;');
+		}
+	});
+}
+function _bindFocusEvent() {
+	var self = this;
+	K(self.edit.textarea[0], self.edit.win).focus(function(e) {
+		if (self.afterFocus) {
+			self.afterFocus.call(self, e);
+		}
+	}).blur(function(e) {
+		if (self.afterBlur) {
+			self.afterBlur.call(self, e);
+		}
+	});
+}
+function _removeBookmarkTag(html) {
+	return _trim(html.replace(/<span [^>]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/ig, ''));
+}
+function _removeTempTag(html) {
+	return html.replace(/<div[^>]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/ig, '');
+}
+function _addBookmarkToStack(stack, bookmark) {
+	if (stack.length === 0) {
+		stack.push(bookmark);
+		return;
+	}
+	var prev = stack[stack.length - 1];
+	if (_removeBookmarkTag(bookmark.html) !== _removeBookmarkTag(prev.html)) {
+		stack.push(bookmark);
+	}
+}
+


+function _undoToRedo(fromStack, toStack) {
+	var self = this, edit = self.edit,
+		body = edit.doc.body,
+		range, bookmark;
+	if (fromStack.length === 0) {
+		return self;
+	}
+	if (edit.designMode) {
+		range = self.cmd.range;
+		bookmark = range.createBookmark(true);
+		bookmark.html = body.innerHTML;
+	} else {
+		bookmark = {
+			html : body.innerHTML
+		};
+	}
+	_addBookmarkToStack(toStack, bookmark);
+	var prev = fromStack.pop();
+	if (_removeBookmarkTag(bookmark.html) === _removeBookmarkTag(prev.html) && fromStack.length > 0) {
+		prev = fromStack.pop();
+	}
+	if (edit.designMode) {
+		edit.html(prev.html);
+		if (prev.start) {
+			range.moveToBookmark(prev);
+			self.select();
+		}
+	} else {
+		K(body).html(_removeBookmarkTag(prev.html));
+	}
+	return self;
+}
+function KEditor(options) {
+	var self = this;
+	self.options = {};
+	function setOption(key, val) {
+		if (KEditor.prototype[key] === undefined) {
+			self[key] = val;
+		}
+		self.options[key] = val;
+	}
+	_each(options, function(key, val) {
+		setOption(key, options[key]);
+	});
+	_each(K.options, function(key, val) {
+		if (self[key] === undefined) {
+			setOption(key, val);
+		}
+	});
+	var se = K(self.srcElement || '<textarea/>');
+	if (!self.width) {
+		self.width = se[0].style.width || se.width();
+	}
+	if (!self.height) {
+		self.height = se[0].style.height || se.height();
+	}
+	setOption('width', _undef(self.width, self.minWidth));
+	setOption('height', _undef(self.height, self.minHeight));
+	setOption('width', _addUnit(self.width));
+	setOption('height', _addUnit(self.height));
+	if (_MOBILE && (!_IOS || _V < 534)) {
+		self.designMode = false;
+	}
+	self.srcElement = se;
+	self.initContent = '';
+	self.plugin = {};
+	self.isCreated = false;
+	self._handlers = {};
+	self._contextmenus = [];
+	self._undoStack = [];
+	self._redoStack = [];
+	self._firstAddBookmark = true;
+	self.menu = self.contextmenu = null;
+	self.dialogs = [];
+}
+KEditor.prototype = {
+	lang : function(mixed) {
+		return _lang(mixed, this.langType);
+	},
+	loadPlugin : function(name, fn) {
+		var self = this;
+		var _pluginStatus = this._pluginStatus;
+		if (!_pluginStatus) {
+			_pluginStatus = this._pluginStatus = {};
+		}
+		if (_plugins[name]) {
+			if (!_isFunction(_plugins[name])) {
+				setTimeout(function() {
+					self.loadPlugin(name, fn);
+				}, 100);
+				return self;
+			}
+			if(!_pluginStatus[name]) {
+				_plugins[name].call(self, KindEditor);
+				_pluginStatus[name] = 'inited';
+			}
+			if (fn) {
+				fn.call(self);
+			}
+			return self;
+		}
+		_plugins[name] = 'loading';
+		_loadScript(self.pluginsPath + name + '/' + name + '.js?ver=' + encodeURIComponent(K.DEBUG ? _TIME : _VERSION), function() {
+			setTimeout(function() {
+				if (_plugins[name]) {
+					self.loadPlugin(name, fn);
+				}
+			}, 0);
+		});
+		return self;
+	},
+	handler : function(key, fn) {
+		var self = this;
+		if (!self._handlers[key]) {
+			self._handlers[key] = [];
+		}
+		if (_isFunction(fn)) {
+			self._handlers[key].push(fn);
+			return self;
+		}
+		_each(self._handlers[key], function() {
+			fn = this.call(self, fn);
+		});
+		return fn;
+	},
+	clickToolbar : function(name, fn) {
+		var self = this, key = 'clickToolbar' + name;
+		if (fn === undefined) {
+			if (self._handlers[key]) {
+				return self.handler(key);
+			}
+			self.loadPlugin(name, function() {
+				self.handler(key);
+			});
+			return self;
+		}
+		return self.handler(key, fn);
+	},
+	updateState : function() {
+		var self = this;
+		_each(('justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,' +
+			'subscript,superscript,bold,italic,underline,strikethrough').split(','), function(i, name) {
+			self.cmd.state(name) ? self.toolbar.select(name) : self.toolbar.unselect(name);
+		});
+		return self;
+	},
+	addContextmenu : function(item) {
+		this._contextmenus.push(item);
+		return this;
+	},
+	afterCreate : function(fn) {
+		return this.handler('afterCreate', fn);
+	},
+	beforeRemove : function(fn) {
+		return this.handler('beforeRemove', fn);
+	},
+	beforeGetHtml : function(fn) {
+		return this.handler('beforeGetHtml', fn);
+	},
+	beforeSetHtml : function(fn) {
+		return this.handler('beforeSetHtml', fn);
+	},
+	afterSetHtml : function(fn) {
+		return this.handler('afterSetHtml', fn);
+	},
+	create : function() {
+		var self = this, fullscreenMode = self.fullscreenMode;
+		if (self.isCreated) {
+			return self;
+		}
+		if (self.srcElement.data('kindeditor')) {
+			return self;
+		}
+		self.srcElement.data('kindeditor', 'true');
+		if (fullscreenMode) {
+			_docElement().style.overflow = 'hidden';
+		} else {
+			_docElement().style.overflow = '';
+		}
+		var width = fullscreenMode ? _docElement().clientWidth + 'px' : self.width,
+			height = fullscreenMode ? _docElement().clientHeight + 'px' : self.height;
+		if ((_IE && _V < 8) || _QUIRKS) {
+			height = _addUnit(_removeUnit(height) + 2);
+		}
+		var container = self.container = K(self.layout);
+		if (fullscreenMode) {
+			K(document.body).append(container);
+		} else {
+			self.srcElement.before(container);
+		}
+		var toolbarDiv = K('.toolbar', container),
+			editDiv = K('.edit', container),
+			statusbar = self.statusbar = K('.statusbar', container);
+		container.removeClass('container')
+			.addClass('ke-container ke-container-' + self.themeType).css('width', width);
+		if (fullscreenMode) {
+			container.css({
+				position : 'absolute',
+				left : 0,
+				top : 0,
+				'z-index' : 811211
+			});
+			if (!_GECKO) {
+				self._scrollPos = _getScrollPos();
+			}
+			window.scrollTo(0, 0);
+			K(document.body).css({
+				'height' : '1px',
+				'overflow' : 'hidden'
+			});
+			K(document.body.parentNode).css('overflow', 'hidden');
+			self._fullscreenExecuted = true;
+		} else {
+			if (self._fullscreenExecuted) {
+				K(document.body).css({
+					'height' : '',
+					'overflow' : ''
+				});
+				K(document.body.parentNode).css('overflow', '');
+			}
+			if (self._scrollPos) {
+				window.scrollTo(self._scrollPos.x, self._scrollPos.y);
+			}
+		}
+		var htmlList = [];
+		K.each(self.items, function(i, name) {
+			if (name == '|') {
+				htmlList.push('<span class="ke-inline-block ke-separator"></span>');
+			} else if (name == '/') {
+				htmlList.push('<div class="ke-hr"></div>');
+			} else {
+				htmlList.push('<span class="ke-outline" data-name="' + name + '" title="' + self.lang(name) + '" unselectable="on">');
+				htmlList.push('<span class="ke-toolbar-icon ke-toolbar-icon-url ke-icon-' + name + '" unselectable="on"></span></span>');
+			}
+		});
+		var toolbar = self.toolbar = _toolbar({
+			src : toolbarDiv,
+			html : htmlList.join(''),
+			noDisableItems : self.noDisableItems,
+			click : function(e, name) {
+				e.stop();
+				if (self.menu) {
+					var menuName = self.menu.name;
+					self.hideMenu();
+					if (menuName === name) {
+						return;
+					}
+				}
+				self.clickToolbar(name);
+			}
+		});
+		var editHeight = _removeUnit(height) - toolbar.div.height();
+		var edit = self.edit = _edit({
+			height : editHeight > 0 && _removeUnit(height) > self.minHeight ? editHeight : self.minHeight,
+			src : editDiv,
+			srcElement : self.srcElement,
+			designMode : self.designMode,
+			themesPath : self.themesPath,
+			bodyClass : self.bodyClass,
+			cssPath : self.cssPath,
+			cssData : self.cssData,
+			beforeGetHtml : function(html) {
+				html = self.beforeGetHtml(html);
+				html = _removeBookmarkTag(_removeTempTag(html));
+				return _formatHtml(html, self.filterMode ? self.htmlTags : null, self.urlType, self.wellFormatMode, self.indentChar);
+			},
+			beforeSetHtml : function(html) {
+				html = _formatHtml(html, self.filterMode ? self.htmlTags : null, '', false);
+				return self.beforeSetHtml(html);
+			},
+			afterSetHtml : function() {
+				self.edit = edit = this;
+				self.afterSetHtml();
+			},
+			afterCreate : function() {
+				self.edit = edit = this;
+				self.cmd = edit.cmd;
+				self._docMousedownFn = function(e) {
+					if (self.menu) {
+						self.hideMenu();
+					}
+				};
+				K(edit.doc, document).mousedown(self._docMousedownFn);
+				_bindContextmenuEvent.call(self);
+				_bindNewlineEvent.call(self);
+				_bindTabEvent.call(self);
+				_bindFocusEvent.call(self);
+				edit.afterChange(function(e) {
+					if (!edit.designMode) {
+						return;
+					}
+					self.updateState();
+					self.addBookmark();
+					if (self.options.afterChange) {
+						self.options.afterChange.call(self);
+					}
+				});
+				edit.textarea.keyup(function(e) {
+					if (!e.ctrlKey && !e.altKey && _INPUT_KEY_MAP[e.which]) {
+						if (self.options.afterChange) {
+							self.options.afterChange.call(self);
+						}
+					}
+				});
+				if (self.readonlyMode) {
+					self.readonly();
+				}
+				self.isCreated = true;
+				if (self.initContent === '') {
+					self.initContent = self.html();
+				}
+				if (self._undoStack.length > 0) {
+					var prev = self._undoStack.pop();
+					if (prev.start) {
+						self.html(prev.html);
+						edit.cmd.range.moveToBookmark(prev);
+						self.select();
+					}
+				}
+				self.afterCreate();
+				if (self.options.afterCreate) {
+					self.options.afterCreate.call(self);
+				}
+			}
+		});
+		statusbar.removeClass('statusbar').addClass('ke-statusbar')
+			.append('<span class="ke-inline-block ke-statusbar-center-icon"></span>')
+			.append('<span class="ke-inline-block ke-statusbar-right-icon"></span>');
+		if (self._fullscreenResizeHandler) {
+			K(window).unbind('resize', self._fullscreenResizeHandler);
+			self._fullscreenResizeHandler = null;
+		}
+		function initResize() {
+			if (statusbar.height() === 0) {
+				setTimeout(initResize, 100);
+				return;
+			}
+			self.resize(width, height, false);
+		}
+		initResize();
+		if (fullscreenMode) {
+			self._fullscreenResizeHandler = function(e) {
+				if (self.isCreated) {
+					self.resize(_docElement().clientWidth, _docElement().clientHeight, false);
+				}
+			};
+			K(window).bind('resize', self._fullscreenResizeHandler);
+			toolbar.select('fullscreen');
+			statusbar.first().css('visibility', 'hidden');
+			statusbar.last().css('visibility', 'hidden');
+		} else {
+			if (_GECKO) {
+				K(window).bind('scroll', function(e) {
+					self._scrollPos = _getScrollPos();
+				});
+			}
+			if (self.resizeType > 0) {
+				_drag({
+					moveEl : container,
+					clickEl : statusbar,
+					moveFn : function(x, y, width, height, diffX, diffY) {
+						height += diffY;
+						self.resize(null, height);
+					}
+				});
+			} else {
+				statusbar.first().css('visibility', 'hidden');
+			}
+			if (self.resizeType === 2) {
+				_drag({
+					moveEl : container,
+					clickEl : statusbar.last(),
+					moveFn : function(x, y, width, height, diffX, diffY) {
+						width += diffX;
+						height += diffY;
+						self.resize(width, height);
+					}
+				});
+			} else {
+				statusbar.last().css('visibility', 'hidden');
+			}
+		}
+		return self;
+	},
+	remove : function() {
+		var self = this;
+		if (!self.isCreated) {
+			return self;
+		}
+		self.beforeRemove();
+		self.srcElement.data('kindeditor', '');
+		if (self.menu) {
+			self.hideMenu();
+		}
+		_each(self.dialogs, function() {
+			self.hideDialog();
+		});
+		K(document).unbind('mousedown', self._docMousedownFn);
+		self.toolbar.remove();
+		self.edit.remove();
+		self.statusbar.last().unbind();
+		self.statusbar.unbind();
+		self.container.remove();
+		self.container = self.toolbar = self.edit = self.menu = null;
+		self.dialogs = [];
+		self.isCreated = false;
+		return self;
+	},
+	resize : function(width, height, updateProp) {
+		var self = this;
+		updateProp = _undef(updateProp, true);
+		if (width) {
+			if (!/%/.test(width)) {
+				width = _removeUnit(width);
+				width = width < self.minWidth ? self.minWidth : width;
+			}
+			self.container.css('width', _addUnit(width));
+			if (updateProp) {
+				self.width = _addUnit(width);
+			}
+		}
+		if (height) {
+			height = _removeUnit(height);
+			editHeight = _removeUnit(height) - self.toolbar.div.height() - self.statusbar.height();
+			editHeight = editHeight < self.minHeight ? self.minHeight : editHeight;
+			self.edit.setHeight(editHeight);
+			if (updateProp) {
+				self.height = _addUnit(height);
+			}
+		}
+		return self;
+	},
+	select : function() {
+		this.isCreated && this.cmd.select();
+		return this;
+	},
+	html : function(val) {
+		var self = this;
+		if (val === undefined) {
+			return self.isCreated ? self.edit.html() : _elementVal(self.srcElement);
+		}
+		self.isCreated ? self.edit.html(val) : _elementVal(self.srcElement, val);
+		if (self.isCreated) {
+			self.cmd.selection();
+		}
+		return self;
+	},
+	fullHtml : function() {
+		return this.isCreated ? this.edit.html(undefined, true) : '';
+	},
+	text : function(val) {
+		var self = this;
+		if (val === undefined) {
+			return _trim(self.html().replace(/<(?!img|embed).*?>/ig, '').replace(/&nbsp;/ig, ' '));
+		} else {
+			return self.html(_escape(val));
+		}
+	},
+	isEmpty : function() {
+		return _trim(this.text().replace(/\r\n|\n|\r/, '')) === '';
+	},
+	isDirty : function() {
+		return _trim(this.initContent.replace(/\r\n|\n|\r|t/g, '')) !== _trim(this.html().replace(/\r\n|\n|\r|t/g, ''));
+	},
+	selectedHtml : function() {
+		var val = this.isCreated ? this.cmd.range.html() : '';
+		val = _removeBookmarkTag(_removeTempTag(val));
+		return val;
+	},
+	count : function(mode) {
+		var self = this;
+		mode = (mode || 'html').toLowerCase();
+		if (mode === 'html') {
+			return self.html().length;
+		}
+		if (mode === 'text') {
+			return self.text().replace(/<(?:img|embed).*?>/ig, 'K').replace(/\r\n|\n|\r/g, '').length;
+		}
+		return 0;
+	},
+	exec : function(key) {
+		key = key.toLowerCase();
+		var self = this, cmd = self.cmd,
+			changeFlag = _inArray(key, 'selectall,copy,paste,print'.split(',')) < 0;
+		if (changeFlag) {
+			self.addBookmark(false);
+		}
+		cmd[key].apply(cmd, _toArray(arguments, 1));
+		if (changeFlag) {
+			self.updateState();
+			self.addBookmark(false);
+			if (self.options.afterChange) {
+				self.options.afterChange.call(self);
+			}
+		}
+		return self;
+	},
+	insertHtml : function(val, quickMode) {
+		if (!this.isCreated) {
+			return this;
+		}
+		val = this.beforeSetHtml(val);
+		this.exec('inserthtml', val, quickMode);
+		return this;
+	},
+	appendHtml : function(val) {
+		this.html(this.html() + val);
+		if (this.isCreated) {
+			var cmd = this.cmd;
+			cmd.range.selectNodeContents(cmd.doc.body).collapse(false);
+			cmd.select();
+		}
+		return this;
+	},
+	sync : function() {
+		_elementVal(this.srcElement, this.html());
+		return this;
+	},
+	focus : function() {
+		this.isCreated ? this.edit.focus() : this.srcElement[0].focus();
+		return this;
+	},
+	blur : function() {
+		this.isCreated ? this.edit.blur() : this.srcElement[0].blur();
+		return this;
+	},
+	addBookmark : function(checkSize) {
+		checkSize = _undef(checkSize, true);
+		var self = this, edit = self.edit,
+			body = edit.doc.body,
+			html = _removeTempTag(body.innerHTML), bookmark;
+		if (checkSize && self._undoStack.length > 0) {
+			var prev = self._undoStack[self._undoStack.length - 1];
+			if (Math.abs(html.length - _removeBookmarkTag(prev.html).length) < self.minChangeSize) {
+				return self;
+			}
+		}
+		if (edit.designMode && !self._firstAddBookmark) {
+			var range = self.cmd.range;
+			bookmark = range.createBookmark(true);
+			bookmark.html = _removeTempTag(body.innerHTML);
+			range.moveToBookmark(bookmark);
+		} else {
+			bookmark = {
+				html : html
+			};
+		}
+		self._firstAddBookmark = false;
+		_addBookmarkToStack(self._undoStack, bookmark);
+		return self;
+	},
+	undo : function() {
+		return _undoToRedo.call(this, this._undoStack, this._redoStack);
+	},
+	redo : function() {
+		return _undoToRedo.call(this, this._redoStack, this._undoStack);
+	},
+	fullscreen : function(bool) {
+		this.fullscreenMode = (bool === undefined ? !this.fullscreenMode : bool);
+		this.addBookmark(false);
+		return this.remove().create();
+	},
+	readonly : function(isReadonly) {
+		isReadonly = _undef(isReadonly, true);
+		var self = this, edit = self.edit, doc = edit.doc;
+		if (self.designMode) {
+			self.toolbar.disableAll(isReadonly, []);
+		} else {
+			_each(self.noDisableItems, function() {
+				self.toolbar[isReadonly ? 'disable' : 'enable'](this);
+			});
+		}
+		if (_IE) {
+			doc.body.contentEditable = !isReadonly;
+		} else {
+			doc.designMode = isReadonly ? 'off' : 'on';
+		}
+		edit.textarea[0].disabled = isReadonly;
+	},
+	createMenu : function(options) {
+		var self = this,
+			name = options.name,
+			knode = self.toolbar.get(name),
+			pos = knode.pos();
+		options.x = pos.x;
+		options.y = pos.y + knode.height();
+		options.z = self.options.zIndex;
+		options.shadowMode = _undef(options.shadowMode, self.shadowMode);
+		if (options.selectedColor !== undefined) {
+			options.cls = 'ke-colorpicker-' + self.themeType;
+			options.noColor = self.lang('noColor');
+			self.menu = _colorpicker(options);
+		} else {
+			options.cls = 'ke-menu-' + self.themeType;
+			options.centerLineMode = false;
+			self.menu = _menu(options);
+		}
+		return self.menu;
+	},
+	hideMenu : function() {
+		this.menu.remove();
+		this.menu = null;
+		return this;
+	},
+	hideContextmenu : function() {
+		this.contextmenu.remove();
+		this.contextmenu = null;
+		return this;
+	},
+	createDialog : function(options) {
+		var self = this, name = options.name;
+		options.z = self.options.zIndex;
+		options.shadowMode = _undef(options.shadowMode, self.shadowMode);
+		options.closeBtn = _undef(options.closeBtn, {
+			name : self.lang('close'),
+			click : function(e) {
+				self.hideDialog();
+				if (_IE && self.cmd) {
+					self.cmd.select();
+				}
+			}
+		});
+		options.noBtn = _undef(options.noBtn, {
+			name : self.lang(options.yesBtn ? 'no' : 'close'),
+			click : function(e) {
+				self.hideDialog();
+				if (_IE && self.cmd) {
+					self.cmd.select();
+				}
+			}
+		});
+		if (self.dialogAlignType != 'page') {
+			options.alignEl = self.container;
+		}
+		options.cls = 'ke-dialog-' + self.themeType;
+		if (self.dialogs.length > 0) {
+			var firstDialog = self.dialogs[0],
+				parentDialog = self.dialogs[self.dialogs.length - 1];
+			firstDialog.setMaskIndex(parentDialog.z + 2);
+			options.z = parentDialog.z + 3;
+			options.showMask = false;
+		}
+		var dialog = _dialog(options);
+		self.dialogs.push(dialog);
+		return dialog;
+	},
+	hideDialog : function() {
+		var self = this;
+		if (self.dialogs.length > 0) {
+			self.dialogs.pop().remove();
+		}
+		if (self.dialogs.length > 0) {
+			var firstDialog = self.dialogs[0],
+				parentDialog = self.dialogs[self.dialogs.length - 1];
+			firstDialog.setMaskIndex(parentDialog.z - 1);
+		}
+		return self;
+	},
+	errorDialog : function(html) {
+		var self = this;
+		var dialog = self.createDialog({
+			width : 750,
+			title : self.lang('uploadError'),
+			body : '<div style="padding:10px 20px;"><iframe frameborder="0" style="width:708px;height:400px;"></iframe></div>'
+		});
+		var iframe = K('iframe', dialog.div), doc = K.iframeDoc(iframe);
+		doc.open();
+		doc.write(html);
+		doc.close();
+		K(doc.body).css('background-color', '#FFF');
+		iframe[0].contentWindow.focus();
+		return self;
+	}
+};
+function _editor(options) {
+	return new KEditor(options);
+}
+_instances = [];
+function _create(expr, options) {
+	options = options || {};
+	options.basePath = _undef(options.basePath, K.basePath);
+	options.themesPath = _undef(options.themesPath, options.basePath + 'themes/');
+	options.langPath = _undef(options.langPath, options.basePath + 'lang/');
+	options.pluginsPath = _undef(options.pluginsPath, options.basePath + 'plugins/');
+	if (_undef(options.loadStyleMode, K.options.loadStyleMode)) {
+		var themeType = _undef(options.themeType, K.options.themeType);
+		_loadStyle(options.themesPath + 'default/default.css');
+		_loadStyle(options.themesPath + themeType + '/' + themeType + '.css');
+	}
+	function create(editor) {
+		_each(_plugins, function(name, fn) {
+			if (_isFunction(fn)) {
+				fn.call(editor, KindEditor);
+				if (!editor._pluginStatus) {
+					editor._pluginStatus = {};
+				}
+				editor._pluginStatus[name] = 'inited';
+			}
+		});
+		return editor.create();
+	}
+	var knode = K(expr);
+	if (!knode || knode.length === 0) {
+		return;
+	}
+	if (knode.length > 1) {
+		knode.each(function() {
+			_create(this, options);
+		});
+		return _instances[0];
+	}
+	options.srcElement = knode[0];
+	var editor = new KEditor(options);
+	_instances.push(editor);
+	if (_language[editor.langType]) {
+		return create(editor);
+	}
+	_loadScript(editor.langPath + editor.langType + '.js?ver=' + encodeURIComponent(K.DEBUG ? _TIME : _VERSION), function() {
+		create(editor);
+	});
+	return editor;
+}
+function _eachEditor(expr, fn) {
+	K(expr).each(function(i, el) {
+		K.each(_instances, function(j, editor) {
+			if (editor && editor.srcElement[0] == el) {
+				fn.call(editor, j);
+				return false;
+			}
+		});
+	});
+}
+K.remove = function(expr) {
+	_eachEditor(expr, function(i) {
+		this.remove();
+		_instances.splice(i, 1);
+	});
+};
+K.sync = function(expr) {
+	_eachEditor(expr, function() {
+		this.sync();
+	});
+};
+K.html = function(expr, val) {
+	_eachEditor(expr, function() {
+		this.html(val);
+	});
+};
+K.insertHtml = function(expr, val) {
+	_eachEditor(expr, function() {
+		this.insertHtml(val);
+	});
+};
+K.appendHtml = function(expr, val) {
+	_eachEditor(expr, function() {
+		this.appendHtml(val);
+	});
+};
+

+if (_IE && _V < 7) {
+	_nativeCommand(document, 'BackgroundImageCache', true);
+}
+K.EditorClass = KEditor;
+K.editor = _editor;
+K.create = _create;
+K.instances = _instances;
+K.plugin = _plugin;
+K.lang = _lang;
+

+_plugin('core', function(K) {
+	var self = this,
+		shortcutKeys = {
+			undo : 'Z', redo : 'Y', bold : 'B', italic : 'I', underline : 'U', print : 'P', selectall : 'A'
+		};
+	self.afterSetHtml(function() {
+		if (self.options.afterChange) {
+			self.options.afterChange.call(self);
+		}
+	});
+	self.afterCreate(function() {
+		if (self.syncType != 'form') {
+			return;
+		}
+		var el = K(self.srcElement), hasForm = false;
+		while ((el = el.parent())) {
+			if (el.name == 'form') {
+				hasForm = true;
+				break;
+			}
+		}
+		if (hasForm) {
+			el.bind('submit', function(e) {
+				self.sync();
+				K(window).bind('unload', function() {
+					self.edit.textarea.remove();
+				});
+			});
+			var resetBtn = K('[type="reset"]', el);
+			resetBtn.click(function() {
+				self.html(self.initContent);
+				self.cmd.selection();
+			});
+			self.beforeRemove(function() {
+				el.unbind();
+				resetBtn.unbind();
+			});
+		}
+	});
+	self.clickToolbar('source', function() {
+		if (self.edit.designMode) {
+			self.toolbar.disableAll(true);
+			self.edit.design(false);
+			self.toolbar.select('source');
+		} else {
+			self.toolbar.disableAll(false);
+			self.edit.design(true);
+			self.toolbar.unselect('source');
+			if (_GECKO) {
+				setTimeout(function() {
+					self.cmd.selection();
+				}, 0);
+			} else {
+				self.cmd.selection();
+			}
+		}
+		self.designMode = self.edit.designMode;
+	});
+	self.afterCreate(function() {
+		if (!self.designMode) {
+			self.toolbar.disableAll(true).select('source');
+		}
+	});
+	self.clickToolbar('fullscreen', function() {
+		self.fullscreen();
+	});
+	if (self.fullscreenShortcut) {
+		var loaded = false;
+		self.afterCreate(function() {
+			K(self.edit.doc, self.edit.textarea).keyup(function(e) {
+				if (e.which == 27) {
+					setTimeout(function() {
+						self.fullscreen();
+					}, 0);
+				}
+			});
+			if (loaded) {
+				if (_IE && !self.designMode) {
+					return;
+				}
+				self.focus();
+			}
+			if (!loaded) {
+				loaded = true;
+			}
+		});
+	}
+	_each('undo,redo'.split(','), function(i, name) {
+		if (shortcutKeys[name]) {
+			self.afterCreate(function() {
+				_ctrl(this.edit.doc, shortcutKeys[name], function() {
+					self.clickToolbar(name);
+				});
+			});
+		}
+		self.clickToolbar(name, function() {
+			self[name]();
+		});
+	});
+	self.clickToolbar('formatblock', function() {
+		var blocks = self.lang('formatblock.formatBlock'),
+			heights = {
+				h1 : 28,
+				h2 : 24,
+				h3 : 18,
+				H4 : 14,
+				p : 12
+			},
+			curVal = self.cmd.val('formatblock'),
+			menu = self.createMenu({
+				name : 'formatblock',
+				width : self.langType == 'en' ? 200 : 150
+			});
+		_each(blocks, function(key, val) {
+			var style = 'font-size:' + heights[key] + 'px;';
+			if (key.charAt(0) === 'h') {
+				style += 'font-weight:bold;';
+			}
+			menu.addItem({
+				title : '<span style="' + style + '" unselectable="on">' + val + '</span>',
+				height : heights[key] + 12,
+				checked : (curVal === key || curVal === val),
+				click : function() {
+					self.select().exec('formatblock', '<' + key + '>').hideMenu();
+				}
+			});
+		});
+	});
+	self.clickToolbar('fontname', function() {
+		var curVal = self.cmd.val('fontname'),
+			menu = self.createMenu({
+				name : 'fontname',
+				width : 150
+			});
+		_each(self.lang('fontname.fontName'), function(key, val) {
+			menu.addItem({
+				title : '<span style="font-family: ' + key + ';" unselectable="on">' + val + '</span>',
+				checked : (curVal === key.toLowerCase() || curVal === val.toLowerCase()),
+				click : function() {
+					self.exec('fontname', key).hideMenu();
+				}
+			});
+		});
+	});
+	self.clickToolbar('fontsize', function() {
+		var curVal = self.cmd.val('fontsize'),
+			menu = self.createMenu({
+				name : 'fontsize',
+				width : 150
+			});
+		_each(self.fontSizeTable, function(i, val) {
+			menu.addItem({
+				title : '<span style="font-size:' + val + ';" unselectable="on">' + val + '</span>',
+				height : _removeUnit(val) + 12,
+				checked : curVal === val,
+				click : function() {
+					self.exec('fontsize', val).hideMenu();
+				}
+			});
+		});
+	});
+	_each('forecolor,hilitecolor'.split(','), function(i, name) {
+		self.clickToolbar(name, function() {
+			self.createMenu({
+				name : name,
+				selectedColor : self.cmd.val(name) || 'default',
+				colors : self.colorTable,
+				click : function(color) {
+					self.exec(name, color).hideMenu();
+				}
+			});
+		});
+	});
+	_each(('cut,copy,paste').split(','), function(i, name) {
+		self.clickToolbar(name, function() {
+			self.focus();
+			try {
+				self.exec(name, null);
+			} catch(e) {
+				alert(self.lang(name + 'Error'));
+			}
+		});
+	});
+	self.clickToolbar('about', function() {
+		var html = '<div style="margin:20px;">' +
+			'<div>KindEditor ' + _VERSION + '</div>' +
+			'<div>Copyright &copy; <a href="http://www.kindsoft.net/" target="_blank">kindsoft.net</a> All rights reserved.</div>' +
+			'</div>';
+		self.createDialog({
+			name : 'about',
+			width : 350,
+			title : self.lang('about'),
+			body : html
+		});
+	});
+	self.plugin.getSelectedLink = function() {
+		return self.cmd.commonAncestor('a');
+	};
+	self.plugin.getSelectedImage = function() {
+		return _getImageFromRange(self.edit.cmd.range, function(img) {
+			return !/^ke-\w+$/i.test(img[0].className);
+		});
+	};
+	self.plugin.getSelectedFlash = function() {
+		return _getImageFromRange(self.edit.cmd.range, function(img) {
+			return img[0].className == 'ke-flash';
+		});
+	};
+	self.plugin.getSelectedMedia = function() {
+		return _getImageFromRange(self.edit.cmd.range, function(img) {
+			return img[0].className == 'ke-media' || img[0].className == 'ke-rm';
+		});
+	};
+	self.plugin.getSelectedAnchor = function() {
+		return _getImageFromRange(self.edit.cmd.range, function(img) {
+			return img[0].className == 'ke-anchor';
+		});
+	};
+	_each('link,image,flash,media,anchor'.split(','), function(i, name) {
+		var uName = name.charAt(0).toUpperCase() + name.substr(1);
+		_each('edit,delete'.split(','), function(j, val) {
+			self.addContextmenu({
+				title : self.lang(val + uName),
+				click : function() {
+					self.loadPlugin(name, function() {
+						self.plugin[name][val]();
+						self.hideMenu();
+					});
+				},
+				cond : self.plugin['getSelected' + uName],
+				width : 150,
+				iconClass : val == 'edit' ? 'ke-icon-' + name : undefined
+			});
+		});
+		self.addContextmenu({ title : '-' });
+	});
+	self.plugin.getSelectedTable = function() {
+		return self.cmd.commonAncestor('table');
+	};
+	self.plugin.getSelectedRow = function() {
+		return self.cmd.commonAncestor('tr');
+	};
+	self.plugin.getSelectedCell = function() {
+		return self.cmd.commonAncestor('td');
+	};
+	_each(('prop,cellprop,colinsertleft,colinsertright,rowinsertabove,rowinsertbelow,rowmerge,colmerge,' +
+	'rowsplit,colsplit,coldelete,rowdelete,insert,delete').split(','), function(i, val) {
+		var cond = _inArray(val, ['prop', 'delete']) < 0 ? self.plugin.getSelectedCell : self.plugin.getSelectedTable;
+		self.addContextmenu({
+			title : self.lang('table' + val),
+			click : function() {
+				self.loadPlugin('table', function() {
+					self.plugin.table[val]();
+					self.hideMenu();
+				});
+			},
+			cond : cond,
+			width : 170,
+			iconClass : 'ke-icon-table' + val
+		});
+	});
+	self.addContextmenu({ title : '-' });
+	_each(('selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' +
+		'insertunorderedlist,indent,outdent,subscript,superscript,hr,print,' +
+		'bold,italic,underline,strikethrough,removeformat,unlink').split(','), function(i, name) {
+		if (shortcutKeys[name]) {
+			self.afterCreate(function() {
+				_ctrl(this.edit.doc, shortcutKeys[name], function() {
+					self.cmd.selection();
+					self.clickToolbar(name);
+				});
+			});
+		}
+		self.clickToolbar(name, function() {
+			self.focus().exec(name, null);
+		});
+	});
+	self.afterCreate(function() {
+		var doc = self.edit.doc, cmd, bookmark, div,
+			cls = '__kindeditor_paste__', pasting = false;
+		function movePastedData() {
+			cmd.range.moveToBookmark(bookmark);
+			cmd.select();
+			if (_WEBKIT) {
+				K('div.' + cls, div).each(function() {
+					K(this).after('<br />').remove(true);
+				});
+				K('span.Apple-style-span', div).remove(true);
+				K('span.Apple-tab-span', div).remove(true);
+				K('span[style]', div).each(function() {
+					if (K(this).css('white-space') == 'nowrap') {
+						K(this).remove(true);
+					}
+				});
+				K('meta', div).remove();
+			}
+			var html = div[0].innerHTML;
+			div.remove();
+			if (html === '') {
+				return;
+			}
+			if (_WEBKIT) {
+				html = html.replace(/(<br>)\1/ig, '$1');
+			}
+			if (self.pasteType === 2) {
+				html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, '');
+				if (/schemas-microsoft-com|worddocument|mso-\w+/i.test(html)) {
+					html = _clearMsWord(html, self.filterMode ? self.htmlTags : K.options.htmlTags);
+				} else {
+					html = _formatHtml(html, self.filterMode ? self.htmlTags : null);
+					html = self.beforeSetHtml(html);
+				}
+			}
+			if (self.pasteType === 1) {
+				html = html.replace(/&nbsp;/ig, ' ');
+				html = html.replace(/\n\s*\n/g, '\n');
+				html = html.replace(/<br[^>]*>/ig, '\n');
+				html = html.replace(/<\/p><p[^>]*>/ig, '\n');
+				html = html.replace(/<[^>]+>/g, '');
+				html = html.replace(/ {2}/g, ' &nbsp;');
+				if (self.newlineTag == 'p') {
+					if (/\n/.test(html)) {
+						html = html.replace(/^/, '<p>').replace(/$/, '<br /></p>').replace(/\n/g, '<br /></p><p>');
+					}
+				} else {
+					html = html.replace(/\n/g, '<br />$&');
+				}
+			}
+			self.insertHtml(html, true);
+		}
+		K(doc.body).bind('paste', function(e){
+			if (self.pasteType === 0) {
+				e.stop();
+				return;
+			}
+			if (pasting) {
+				return;
+			}
+			pasting = true;
+			K('div.' + cls, doc).remove();
+			cmd = self.cmd.selection();
+			bookmark = cmd.range.createBookmark();
+			div = K('<div class="' + cls + '"></div>', doc).css({
+				position : 'absolute',
+				width : '1px',
+				height : '1px',
+				overflow : 'hidden',
+				left : '-1981px',
+				top : K(bookmark.start).pos().y + 'px',
+				'white-space' : 'nowrap'
+			});
+			K(doc.body).append(div);
+			if (_IE) {
+				var rng = cmd.range.get(true);
+				rng.moveToElementText(div[0]);
+				rng.select();
+				rng.execCommand('paste');
+				e.preventDefault();
+			} else {
+				cmd.range.selectNodeContents(div[0]);
+				cmd.select();
+				div[0].tabIndex = -1;
+				div[0].focus();
+			}
+			setTimeout(function() {
+				movePastedData();
+				pasting = false;
+			}, 0);
+		});
+	});
+	self.beforeGetHtml(function(html) {
+		if (_IE && _V <= 8) {
+			html = html.replace(/<div\s+[^>]*data-ke-input-tag="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, tag) {
+				return unescape(tag);
+			});
+			html = html.replace(/(<input)((?:\s+[^>]*)?>)/ig, function($0, $1, $2) {
+				if (!/\s+type="[^"]+"/i.test($0)) {
+					return $1 + ' type="text"' + $2;
+				}
+				return $0;
+			});
+		}
+		return html.replace(/(<(?:noscript|noscript\s[^>]*)>)([\s\S]*?)(<\/noscript>)/ig, function($0, $1, $2, $3) {
+			return $1 + _unescape($2).replace(/\s+/g, ' ') + $3;
+		})
+		.replace(/<img[^>]*class="?ke-(flash|rm|media)"?[^>]*>/ig, function(full) {
+			var imgAttrs = _getAttrList(full);
+			var styles = _getCssList(imgAttrs.style || '');
+			var attrs = _mediaAttrs(imgAttrs['data-ke-tag']);
+			var width = _undef(styles.width, '');
+			var height = _undef(styles.height, '');
+			if (/px/i.test(width)) {
+				width = _removeUnit(width);
+			}
+			if (/px/i.test(height)) {
+				height = _removeUnit(height);
+			}
+			attrs.width = _undef(imgAttrs.width, width);
+			attrs.height = _undef(imgAttrs.height, height);
+			return _mediaEmbed(attrs);
+		})
+		.replace(/<img[^>]*class="?ke-anchor"?[^>]*>/ig, function(full) {
+			var imgAttrs = _getAttrList(full);
+			return '<a name="' + unescape(imgAttrs['data-ke-name']) + '"></a>';
+		})
+		.replace(/<div\s+[^>]*data-ke-script-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, attr, code) {
+			return '<script' + unescape(attr) + '>' + unescape(code) + '</script>';
+		})
+		.replace(/<div\s+[^>]*data-ke-noscript-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, attr, code) {
+			return '<noscript' + unescape(attr) + '>' + unescape(code) + '</noscript>';
+		})
+		.replace(/(<[^>]*)data-ke-src="([^"]*)"([^>]*>)/ig, function(full, start, src, end) {
+			full = full.replace(/(\s+(?:href|src)=")[^"]*(")/i, function($0, $1, $2) {
+				return $1 + _unescape(src) + $2;
+			});
+			full = full.replace(/\s+data-ke-src="[^"]*"/i, '');
+			return full;
+		})
+		.replace(/(<[^>]+\s)data-ke-(on\w+="[^"]*"[^>]*>)/ig, function(full, start, end) {
+			return start + end;
+		});
+	});
+	self.beforeSetHtml(function(html) {
+		if (_IE && _V <= 8) {
+			html = html.replace(/<input[^>]*>|<(select|button)[^>]*>[\s\S]*?<\/\1>/ig, function(full) {
+				var attrs = _getAttrList(full);
+				var styles = _getCssList(attrs.style || '');
+				if (styles.display == 'none') {
+					return '<div class="ke-display-none" data-ke-input-tag="' + escape(full) + '"></div>';
+				}
+				return full;
+			});
+		}
+		return html.replace(/<embed[^>]*type="([^"]+)"[^>]*>(?:<\/embed>)?/ig, function(full) {
+			var attrs = _getAttrList(full);
+			attrs.src = _undef(attrs.src, '');
+			attrs.width = _undef(attrs.width, 0);
+			attrs.height = _undef(attrs.height, 0);
+			return _mediaImg(self.themesPath + 'common/blank.gif', attrs);
+		})
+		.replace(/<a[^>]*name="([^"]+)"[^>]*>(?:<\/a>)?/ig, function(full) {
+			var attrs = _getAttrList(full);
+			if (attrs.href !== undefined) {
+				return full;
+			}
+			return '<img class="ke-anchor" src="' + self.themesPath + 'common/anchor.gif" data-ke-name="' + escape(attrs.name) + '" />';
+		})
+		.replace(/<script([^>]*)>([\s\S]*?)<\/script>/ig, function(full, attr, code) {
+			return '<div class="ke-script" data-ke-script-attr="' + escape(attr) + '">' + escape(code) + '</div>';
+		})
+		.replace(/<noscript([^>]*)>([\s\S]*?)<\/noscript>/ig, function(full, attr, code) {
+			return '<div class="ke-noscript" data-ke-noscript-attr="' + escape(attr) + '">' + escape(code) + '</div>';
+		})
+		.replace(/(<[^>]*)(href|src)="([^"]*)"([^>]*>)/ig, function(full, start, key, src, end) {
+			if (full.match(/\sdata-ke-src="[^"]*"/i)) {
+				return full;
+			}
+			full = start + key + '="' + src + '"' + ' data-ke-src="' + _escape(src) + '"' + end;
+			return full;
+		})
+		.replace(/(<[^>]+\s)(on\w+="[^"]*"[^>]*>)/ig, function(full, start, end) {
+			return start + 'data-ke-' + end;
+		})
+		.replace(/<table[^>]*\s+border="0"[^>]*>/ig, function(full) {
+			if (full.indexOf('ke-zeroborder') >= 0) {
+				return full;
+			}
+			return _addClassToTag(full, 'ke-zeroborder');
+		});
+	});
+});
+
+
+})(window);
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.lang({
+	source : 'HTML代码',
+	preview : '预览',
+	undo : '后退(Ctrl+Z)',
+	redo : '前进(Ctrl+Y)',
+	cut : '剪切(Ctrl+X)',
+	copy : '复制(Ctrl+C)',
+	paste : '粘贴(Ctrl+V)',
+	plainpaste : '粘贴为无格式文本',
+	wordpaste : '从Word粘贴',
+	selectall : '全选(Ctrl+A)',
+	justifyleft : '左对齐',
+	justifycenter : '居中',
+	justifyright : '右对齐',
+	justifyfull : '两端对齐',
+	insertorderedlist : '编号',
+	insertunorderedlist : '项目符号',
+	indent : '增加缩进',
+	outdent : '减少缩进',
+	subscript : '下标',
+	superscript : '上标',
+	formatblock : '段落',
+	fontname : '字体',
+	fontsize : '文字大小',
+	forecolor : '文字颜色',
+	hilitecolor : '文字背景',
+	bold : '粗体(Ctrl+B)',
+	italic : '斜体(Ctrl+I)',
+	underline : '下划线(Ctrl+U)',
+	strikethrough : '删除线',
+	removeformat : '删除格式',
+	image : '图片',
+	multiimage : '批量图片上传',
+	flash : 'Flash',
+	media : '视音频',
+	table : '表格',
+	tablecell : '单元格',
+	hr : '插入横线',
+	emoticons : '插入表情',
+	link : '超级链接',
+	unlink : '取消超级链接',
+	fullscreen : '全屏显示',
+	about : '关于',
+	print : '打印(Ctrl+P)',
+	filemanager : '文件空间',
+	code : '插入程序代码',
+	map : 'Google地图',
+	baidumap : '百度地图',
+	lineheight : '行距',
+	clearhtml : '清理HTML代码',
+	pagebreak : '插入分页符',
+	quickformat : '一键排版',
+	insertfile : '插入文件',
+	template : '插入模板',
+	anchor : '锚点',
+	yes : '确定',
+	no : '取消',
+	close : '关闭',
+	editImage : '图片属性',
+	deleteImage : '删除图片',
+	editFlash : 'Flash属性',
+	deleteFlash : '删除Flash',
+	editMedia : '视音频属性',
+	deleteMedia : '删除视音频',
+	editLink : '超级链接属性',
+	deleteLink : '取消超级链接',
+	editAnchor : '锚点属性',
+	deleteAnchor : '删除锚点',
+	tableprop : '表格属性',
+	tablecellprop : '单元格属性',
+	tableinsert : '插入表格',
+	tabledelete : '删除表格',
+	tablecolinsertleft : '左侧插入列',
+	tablecolinsertright : '右侧插入列',
+	tablerowinsertabove : '上方插入行',
+	tablerowinsertbelow : '下方插入行',
+	tablerowmerge : '向下合并单元格',
+	tablecolmerge : '向右合并单元格',
+	tablerowsplit : '拆分行',
+	tablecolsplit : '拆分列',
+	tablecoldelete : '删除列',
+	tablerowdelete : '删除行',
+	noColor : '无颜色',
+	pleaseSelectFile : '请选择文件。',
+	invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",
+	invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
+	invalidWidth : "宽度必须为数字。",
+	invalidHeight : "高度必须为数字。",
+	invalidBorder : "边框必须为数字。",
+	invalidUrl : "请输入有效的URL地址。",
+	invalidRows : '行数为必选项,只允许输入大于0的数字。',
+	invalidCols : '列数为必选项,只允许输入大于0的数字。',
+	invalidPadding : '边距必须为数字。',
+	invalidSpacing : '间距必须为数字。',
+	invalidJson : '服务器发生故障。',
+	uploadSuccess : '上传成功。',
+	cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。',
+	copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。',
+	pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。',
+	ajaxLoading : '加载中,请稍候 ...',
+	uploadLoading : '上传中,请稍候 ...',
+	uploadError : '上传错误',
+	'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
+	'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
+	'code.pleaseInput' : '请输入程序代码。',
+	'link.url' : 'URL',
+	'link.linkType' : '打开类型',
+	'link.newWindow' : '新窗口',
+	'link.selfWindow' : '当前窗口',
+	'flash.url' : 'URL',
+	'flash.width' : '宽度',
+	'flash.height' : '高度',
+	'flash.upload' : '上传',
+	'flash.viewServer' : '文件空间',
+	'media.url' : 'URL',
+	'media.width' : '宽度',
+	'media.height' : '高度',
+	'media.autostart' : '自动播放',
+	'media.upload' : '上传',
+	'media.viewServer' : '文件空间',
+	'image.remoteImage' : '网络图片',
+	'image.localImage' : '本地上传',
+	'image.remoteUrl' : '图片地址',
+	'image.localUrl' : '上传文件',
+	'image.size' : '图片大小',
+	'image.width' : '宽',
+	'image.height' : '高',
+	'image.resetSize' : '重置大小',
+	'image.align' : '对齐方式',
+	'image.defaultAlign' : '默认方式',
+	'image.leftAlign' : '左对齐',
+	'image.rightAlign' : '右对齐',
+	'image.imgTitle' : '图片说明',
+	'image.upload' : '浏览...',
+	'image.viewServer' : '图片空间',
+	'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>',
+	'multiimage.startUpload' : '开始上传',
+	'multiimage.clearAll' : '全部清空',
+	'multiimage.insertAll' : '全部插入',
+	'multiimage.queueLimitExceeded' : '文件数量超过限制。',
+	'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。',
+	'multiimage.zeroByteFile' : '无法上传空文件。',
+	'multiimage.invalidFiletype' : '文件类型不正确。',
+	'multiimage.unknownError' : '发生异常,无法上传。',
+	'multiimage.pending' : '等待上传',
+	'multiimage.uploadError' : '上传失败',
+	'filemanager.emptyFolder' : '空文件夹',
+	'filemanager.moveup' : '移到上一级文件夹',
+	'filemanager.viewType' : '显示方式:',
+	'filemanager.viewImage' : '缩略图',
+	'filemanager.listImage' : '详细信息',
+	'filemanager.orderType' : '排序方式:',
+	'filemanager.fileName' : '名称',
+	'filemanager.fileSize' : '大小',
+	'filemanager.fileType' : '类型',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : '文件说明',
+	'insertfile.upload' : '上传',
+	'insertfile.viewServer' : '文件空间',
+	'table.cells' : '单元格数',
+	'table.rows' : '行数',
+	'table.cols' : '列数',
+	'table.size' : '大小',
+	'table.width' : '宽度',
+	'table.height' : '高度',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '边距间距',
+	'table.padding' : '边距',
+	'table.spacing' : '间距',
+	'table.align' : '对齐方式',
+	'table.textAlign' : '水平对齐',
+	'table.verticalAlign' : '垂直对齐',
+	'table.alignDefault' : '默认',
+	'table.alignLeft' : '左对齐',
+	'table.alignCenter' : '居中',
+	'table.alignRight' : '右对齐',
+	'table.alignTop' : '顶部',
+	'table.alignMiddle' : '中部',
+	'table.alignBottom' : '底部',
+	'table.alignBaseline' : '基线',
+	'table.border' : '边框',
+	'table.borderWidth' : '边框',
+	'table.borderColor' : '颜色',
+	'table.backgroundColor' : '背景颜色',
+	'map.address' : '地址: ',
+	'map.search' : '搜索',
+	'baidumap.address' : '地址: ',
+	'baidumap.search' : '搜索',
+	'baidumap.insertDynamicMap' : '插入动态地图',
+	'anchor.name' : '锚点名称',
+	'formatblock.formatBlock' : {
+		h1 : '标题 1',
+		h2 : '标题 2',
+		h3 : '标题 3',
+		h4 : '标题 4',
+		p : '正 文'
+	},
+	'fontname.fontName' : {
+		'SimSun' : '宋体',
+		'NSimSun' : '新宋体',
+		'FangSong_GB2312' : '仿宋_GB2312',
+		'KaiTi_GB2312' : '楷体_GB2312',
+		'SimHei' : '黑体',
+		'Microsoft YaHei' : '微软雅黑',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Times New Roman' : 'Times New Roman',
+		'Courier New' : 'Courier New',
+		'Tahoma' : 'Tahoma',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '单倍行距'},
+		{'1.5' : '1.5倍行距'},
+		{'2' : '2倍行距'},
+		{'2.5' : '2.5倍行距'},
+		{'3' : '3倍行距'}
+	],
+	'template.selectTemplate' : '可选模板',
+	'template.replaceContent' : '替换当前内容',
+	'template.fileList' : {
+		'1.html' : '图片和文字',
+		'2.html' : '表格',
+		'3.html' : '项目编号'
+	}
+}, 'zh-CN');
+KindEditor.options.langType = 'zh-CN';
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('anchor', function(K) {
+	var self = this, name = 'anchor', lang = self.lang(name + '.');
+	self.plugin.anchor = {
+		edit : function() {
+			var html = ['<div style="padding:20px;">',
+					'<div class="ke-dialog-row">',
+					'<label for="keName">' + lang.name + '</label>',
+					'<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />',
+					'</div>',
+					'</div>'].join('');
+			var dialog = self.createDialog({
+				name : name,
+				width : 300,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus();
+					}
+				}
+			});
+			var div = dialog.div,
+				nameBox = K('input[name="name"]', div);
+			var img = self.plugin.getSelectedAnchor();
+			if (img) {
+				nameBox.val(unescape(img.attr('data-ke-name')));
+			}
+			nameBox[0].focus();
+			nameBox[0].select();
+		},
+		'delete' : function() {
+			self.plugin.getSelectedAnchor().remove();
+		}
+	};
+	self.clickToolbar(name, self.plugin.anchor.edit);
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('autoheight', function(K) {
+	var self = this;
+	if (!self.autoHeightMode) {
+		return;
+	}
+	var minHeight;
+	function hideScroll() {
+		var edit = self.edit;
+		var body = edit.doc.body;
+		edit.iframe[0].scroll = 'no';
+		body.style.overflowY = 'hidden';
+	}
+	function resetHeight() {
+		var edit = self.edit;
+		var body = edit.doc.body;
+		edit.iframe.height(minHeight);
+		self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight));
+	}
+	function init() {
+		minHeight = K.removeUnit(self.height);
+		self.edit.afterChange(resetHeight);
+		hideScroll();
+		resetHeight();
+	}
+	if (self.isCreated) {
+		init();
+	} else {
+		self.afterCreate(init);
+	}
+});
+/*
+* 如何实现真正的自动高度?
+* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。
+* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。
+* 由此就实现了真正的自动高度
+* 测试:chrome、firefox、IE9、IE8
+* */
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('baidumap', function(K) {
+	var self = this, name = 'baidumap', lang = self.lang(name + '.');
+	var mapWidth = K.undef(self.mapWidth, 558);
+	var mapHeight = K.undef(self.mapHeight, 360);
+	self.clickToolbar(name, function() {
+		var html = ['<div style="padding:10px 20px;">',
+			'<div class="ke-header">',
+			'<div class="ke-left">',
+			lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ',
+			'<span class="ke-button-common ke-button-outer">',
+			'<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />',
+			'</span>',
+			'</div>',
+			'<div class="ke-right">',
+			'<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>',
+			'</div>',
+			'<div class="ke-clearfix"></div>',
+			'</div>',
+			'<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>',
+			'</div>'].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : mapWidth + 42,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					var map = win.map;
+					var centerObj = map.getCenter();
+					var center = centerObj.lng + ',' + centerObj.lat;
+					var zoom = map.getZoom();
+					var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage',
+						'?center=' + encodeURIComponent(center),
+						'&zoom=' + encodeURIComponent(zoom),
+						'&width=' + mapWidth,
+						'&height=' + mapHeight,
+						'&markers=' + encodeURIComponent(center),
+						'&markerStyles=' + encodeURIComponent('l,A')].join('');
+					if (checkbox[0].checked) {
+						self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>');
+					} else {
+						self.exec('insertimage', url);
+					}
+					self.hideDialog().focus();
+				}
+			},
+			beforeRemove : function() {
+				searchBtn.remove();
+				if (doc) {
+					doc.write('');
+				}
+				iframe.remove();
+			}
+		});
+		var div = dialog.div,
+			addressBox = K('[name="address"]', div),
+			searchBtn = K('[name="searchBtn"]', div),
+			checkbox = K('[name="insertDynamicMap"]', dialog.div),
+			win, doc;
+		var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>');
+		function ready() {
+			win = iframe[0].contentWindow;
+			doc = K.iframeDoc(iframe);
+		}
+		iframe.bind('load', function() {
+			iframe.unbind('load');
+			if (K.IE) {
+				ready();
+			} else {
+				setTimeout(ready, 0);
+			}
+		});
+		K('.ke-map', div).replaceWith(iframe);
+		searchBtn.click(function() {
+			win.search(addressBox.val());
+		});
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+

+KindEditor.plugin('map', function(K) {
+	var self = this, name = 'map', lang = self.lang(name + '.');
+	self.clickToolbar(name, function() {
+		var html = ['<div style="padding:10px 20px;">',
+			'<div class="ke-dialog-row">',
+			lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ',
+			'<span class="ke-button-common ke-button-outer">',
+			'<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />',
+			'</span>',
+			'</div>',
+			'<div class="ke-map" style="width:558px;height:360px;"></div>',
+			'</div>'].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : 600,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					var geocoder = win.geocoder,
+						map = win.map,
+						center = map.getCenter().lat() + ',' + map.getCenter().lng(),
+						zoom = map.getZoom(),
+						maptype = map.getMapTypeId(),
+						url = 'http://maps.googleapis.com/maps/api/staticmap';
+						url += '?center=' + encodeURIComponent(center);
+						url += '&zoom=' + encodeURIComponent(zoom);
+						url += '&size=558x360';
+						url += '&maptype=' + encodeURIComponent(maptype);
+						url += '&markers=' + encodeURIComponent(center);
+						url += '&language=' + self.langType;
+						url += '&sensor=false';
+					self.exec('insertimage', url).hideDialog().focus();
+				}
+			},
+			beforeRemove : function() {
+				searchBtn.remove();
+				if (doc) {
+					doc.write('');
+				}
+				iframe.remove();
+			}
+		});
+		var div = dialog.div,
+			addressBox = K('[name="address"]', div),
+			searchBtn = K('[name="searchBtn"]', div),
+			win, doc;
+		var iframeHtml = ['<!doctype html><html><head>',
+			'<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />',
+			'<style>',
+			'	html { height: 100% }',
+			'	body { height: 100%; margin: 0; padding: 0; background-color: #FFF }',
+			'	#map_canvas { height: 100% }',
+			'</style>',
+			'<script src="http://maps.googleapis.com/maps/api/js?sensor=false&language=' + self.langType + '"></script>',
+			'<script>',
+			'var map, geocoder;',
+			'function initialize() {',
+			'	var latlng = new google.maps.LatLng(31.230393, 121.473704);',
+			'	var options = {',
+			'		zoom: 11,',
+			'		center: latlng,',
+			'		disableDefaultUI: true,',
+			'		panControl: true,',
+			'		zoomControl: true,',
+			'		mapTypeControl: true,',
+			'		scaleControl: true,',
+			'		streetViewControl: false,',
+			'		overviewMapControl: true,',
+			'		mapTypeId: google.maps.MapTypeId.ROADMAP',
+			'	};',
+			'	map = new google.maps.Map(document.getElementById("map_canvas"), options);',
+			'	geocoder = new google.maps.Geocoder();',
+			'	geocoder.geocode({latLng: latlng}, function(results, status) {',
+			'		if (status == google.maps.GeocoderStatus.OK) {',
+			'			if (results[3]) {',
+			'				parent.document.getElementById("kindeditor_plugin_map_address").value = results[3].formatted_address;',
+			'			}',
+			'		}',
+			'	});',
+			'}',
+			'function search(address) {',
+			'	if (!map) return;',
+			'	geocoder.geocode({address : address}, function(results, status) {',
+			'		if (status == google.maps.GeocoderStatus.OK) {',
+			'			map.setZoom(11);',
+			'			map.setCenter(results[0].geometry.location);',
+			'			var marker = new google.maps.Marker({',
+			'				map: map,',
+			'				position: results[0].geometry.location',
+			'			});',
+			'		} else {',
+			'			alert("Invalid address: " + address);',
+			'		}',
+			'	});',
+			'}',
+			'</script>',
+			'</head>',
+			'<body onload="initialize();">',
+			'<div id="map_canvas" style="width:100%; height:100%"></div>',
+			'</body></html>'].join('\n');
+		var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'map/map.html" style="width:558px;height:360px;"></iframe>');
+		function ready() {
+			win = iframe[0].contentWindow;
+			doc = K.iframeDoc(iframe);
+		}
+		iframe.bind('load', function() {
+			iframe.unbind('load');
+			if (K.IE) {
+				ready();
+			} else {
+				setTimeout(ready, 0);
+			}
+		});
+		K('.ke-map', div).replaceWith(iframe);
+		searchBtn.click(function() {
+			win.search(addressBox.val());
+		});
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('clearhtml', function(K) {
+	var self = this, name = 'clearhtml';
+	self.clickToolbar(name, function() {
+		self.focus();
+		var html = self.html();
+		html = html.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/ig, '');
+		html = html.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/ig, '');
+		html = K.formatHtml(html, {
+			a : ['href', 'target'],
+			embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'],
+			img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'],
+			table : ['border'],
+			'td,th' : ['rowspan', 'colspan'],
+			'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : []
+		});
+		self.html(html);
+		self.cmd.selection(true);
+		self.addBookmark();
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+


+KindEditor.plugin('code', function(K) {
+	var self = this, name = 'code';
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			html = ['<div style="padding:10px 20px;">',
+				'<div class="ke-dialog-row">',
+				'<select class="ke-code-type">',
+				'<option value="js">JavaScript</option>',
+				'<option value="html">HTML</option>',
+				'<option value="css">CSS</option>',
+				'<option value="php">PHP</option>',
+				'<option value="pl">Perl</option>',
+				'<option value="py">Python</option>',
+				'<option value="rb">Ruby</option>',
+				'<option value="java">Java</option>',
+				'<option value="vb">ASP/VB</option>',
+				'<option value="cpp">C/C++</option>',
+				'<option value="cs">C#</option>',
+				'<option value="xml">XML</option>',
+				'<option value="bsh">Shell</option>',
+				'<option value="">Other</option>',
+				'</select>',
+				'</div>',
+				'<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>',
+				'</div>'].join(''),
+			dialog = self.createDialog({
+				name : name,
+				width : 450,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var type = K('.ke-code-type', dialog.div).val(),
+							code = textarea.val(),
+							cls = type === '' ? '' :  ' lang-' + type,
+							html = '<pre class="prettyprint' + cls + '">\n' + K.escape(code) + '</pre> ';
+						if (K.trim(code) === '') {
+							alert(lang.pleaseInput);
+							textarea[0].focus();
+							return;
+						}
+						self.insertHtml(html).hideDialog().focus();
+					}
+				}
+			}),
+			textarea = K('textarea', dialog.div);
+		textarea[0].focus();
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('emoticons', function(K) {
+	var self = this, name = 'emoticons',
+		path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'),
+		allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons,
+		currentPageNum = 1;
+	self.clickToolbar(name, function() {
+		var rows = 5, cols = 9, total = 135, startNum = 0,
+			cells = rows * cols, pages = Math.ceil(total / cells),
+			colsHalf = Math.floor(cols / 2),
+			wrapperDiv = K('<div class="ke-plugin-emoticons"></div>'),
+			elements = [],
+			menu = self.createMenu({
+				name : name,
+				beforeRemove : function() {
+					removeEvent();
+				}
+			});
+		menu.div.append(wrapperDiv);
+		var previewDiv, previewImg;
+		if (allowPreview) {
+			previewDiv = K('<div class="ke-preview"></div>').css('right', 0);
+			previewImg = K('<img class="ke-preview-img" src="' + path + startNum + '.gif" />');
+			wrapperDiv.append(previewDiv);
+			previewDiv.append(previewImg);
+		}
+		function bindCellEvent(cell, j, num) {
+			if (previewDiv) {
+				cell.mouseover(function() {
+					if (j > colsHalf) {
+						previewDiv.css('left', 0);
+						previewDiv.css('right', '');
+					} else {
+						previewDiv.css('left', '');
+						previewDiv.css('right', 0);
+					}
+					previewImg.attr('src', path + num + '.gif');
+					K(this).addClass('ke-on');
+				});
+			} else {
+				cell.mouseover(function() {
+					K(this).addClass('ke-on');
+				});
+			}
+			cell.mouseout(function() {
+				K(this).removeClass('ke-on');
+			});
+			cell.click(function(e) {
+				self.insertHtml('<img src="' + path + num + '.gif" border="0" alt="" />').hideMenu().focus();
+				e.stop();
+			});
+		}
+		function createEmoticonsTable(pageNum, parentDiv) {
+			var table = document.createElement('table');
+			parentDiv.append(table);
+			if (previewDiv) {
+				K(table).mouseover(function() {
+					previewDiv.show('block');
+				});
+				K(table).mouseout(function() {
+					previewDiv.hide();
+				});
+				elements.push(K(table));
+			}
+			table.className = 'ke-table';
+			table.cellPadding = 0;
+			table.cellSpacing = 0;
+			table.border = 0;
+			var num = (pageNum - 1) * cells + startNum;
+			for (var i = 0; i < rows; i++) {
+				var row = table.insertRow(i);
+				for (var j = 0; j < cols; j++) {
+					var cell = K(row.insertCell(j));
+					cell.addClass('ke-cell');
+					bindCellEvent(cell, j, num);
+					var span = K('<span class="ke-img"></span>')
+						.css('background-position', '-' + (24 * num) + 'px 0px')
+						.css('background-image', 'url(' + path + 'static.gif)');
+					cell.append(span);
+					elements.push(cell);
+					num++;
+				}
+			}
+			return table;
+		}
+		var table = createEmoticonsTable(currentPageNum, wrapperDiv);
+		function removeEvent() {
+			K.each(elements, function() {
+				this.unbind();
+			});
+		}
+		var pageDiv;
+		function bindPageEvent(el, pageNum) {
+			el.click(function(e) {
+				removeEvent();
+				table.parentNode.removeChild(table);
+				pageDiv.remove();
+				table = createEmoticonsTable(pageNum, wrapperDiv);
+				createPageTable(pageNum);
+				currentPageNum = pageNum;
+				e.stop();
+			});
+		}
+		function createPageTable(currentPageNum) {
+			pageDiv = K('<div class="ke-page"></div>');
+			wrapperDiv.append(pageDiv);
+			for (var pageNum = 1; pageNum <= pages; pageNum++) {
+				if (currentPageNum !== pageNum) {
+					var a = K('<a href="javascript:;">[' + pageNum + ']</a>');
+					bindPageEvent(a, pageNum);
+					pageDiv.append(a);
+					elements.push(a);
+				} else {
+					pageDiv.append(K('@[' + pageNum + ']'));
+				}
+				pageDiv.append(K('@&nbsp;'));
+			}
+		}
+		createPageTable(currentPageNum);
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('filemanager', function(K) {
+	var self = this, name = 'filemanager',
+		fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'),
+		imgPath = self.pluginsPath + name + '/images/',
+		lang = self.lang(name + '.');
+	function makeFileTitle(filename, filesize, datetime) {
+		return filename + ' (' + Math.ceil(filesize / 1024) + 'KB, ' + datetime + ')';
+	}
+	function bindTitle(el, data) {
+		if (data.is_dir) {
+			el.attr('title', data.filename);
+		} else {
+			el.attr('title', makeFileTitle(data.filename, data.filesize, data.datetime));
+		}
+	}
+	self.plugin.filemanagerDialog = function(options) {
+		var width = K.undef(options.width, 650),
+			height = K.undef(options.height, 510),
+			dirName = K.undef(options.dirName, ''),
+			viewType = K.undef(options.viewType, 'VIEW').toUpperCase(),
+			clickFn = options.clickFn;
+		var html = [
+			'<div style="padding:10px 20px;">',
+			'<div class="ke-plugin-filemanager-header">',
+			'<div class="ke-left">',
+			'<img class="ke-inline-block" name="moveupImg" src="' + imgPath + 'go-up.gif" width="16" height="16" border="0" alt="" /> ',
+			'<a class="ke-inline-block" name="moveupLink" href="javascript:;">' + lang.moveup + '</a>',
+			'</div>',
+			'<div class="ke-right">',
+			lang.viewType + ' <select class="ke-inline-block" name="viewType">',
+			'<option value="VIEW">' + lang.viewImage + '</option>',
+			'<option value="LIST">' + lang.listImage + '</option>',
+			'</select> ',
+			lang.orderType + ' <select class="ke-inline-block" name="orderType">',
+			'<option value="NAME">' + lang.fileName + '</option>',
+			'<option value="SIZE">' + lang.fileSize + '</option>',
+			'<option value="TYPE">' + lang.fileType + '</option>',
+			'</select>',
+			'</div>',
+			'<div class="ke-clearfix"></div>',
+			'</div>',
+			'<div class="ke-plugin-filemanager-body"></div>',
+			'</div>'
+		].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : width,
+			height : height,
+			title : self.lang(name),
+			body : html
+		}),
+		div = dialog.div,
+		bodyDiv = K('.ke-plugin-filemanager-body', div),
+		moveupImg = K('[name="moveupImg"]', div),
+		moveupLink = K('[name="moveupLink"]', div),
+		viewServerBtn = K('[name="viewServer"]', div),
+		viewTypeBox = K('[name="viewType"]', div),
+		orderTypeBox = K('[name="orderType"]', div);
+		function reloadPage(path, order, func) {
+			var param = 'path=' + path + '&order=' + order + '&dir=' + dirName;
+			dialog.showLoading(self.lang('ajaxLoading'));
+			K.ajax(K.addParam(fileManagerJson, param + '&' + new Date().getTime()), function(data) {
+				dialog.hideLoading();
+				func(data);
+			});
+		}
+		var elList = [];
+		function bindEvent(el, result, data, createFunc) {
+			var fileUrl = K.formatUrl(result.current_url + data.filename, 'absolute'),
+				dirPath = encodeURIComponent(result.current_dir_path + data.filename + '/');
+			if (data.is_dir) {
+				el.click(function(e) {
+					reloadPage(dirPath, orderTypeBox.val(), createFunc);
+				});
+			} else if (data.is_photo) {
+				el.click(function(e) {
+					clickFn.call(this, fileUrl, data.filename);
+				});
+			} else {
+				el.click(function(e) {
+					clickFn.call(this, fileUrl, data.filename);
+				});
+			}
+			elList.push(el);
+		}
+		function createCommon(result, createFunc) {
+			K.each(elList, function() {
+				this.unbind();
+			});
+			moveupLink.unbind();
+			viewTypeBox.unbind();
+			orderTypeBox.unbind();
+			if (result.current_dir_path) {
+				moveupLink.click(function(e) {
+					reloadPage(result.moveup_dir_path, orderTypeBox.val(), createFunc);
+				});
+			}
+			function changeFunc() {
+				if (viewTypeBox.val() == 'VIEW') {
+					reloadPage(result.current_dir_path, orderTypeBox.val(), createView);
+				} else {
+					reloadPage(result.current_dir_path, orderTypeBox.val(), createList);
+				}
+			}
+			viewTypeBox.change(changeFunc);
+			orderTypeBox.change(changeFunc);
+			bodyDiv.html('');
+		}
+		function createList(result) {
+			createCommon(result, createList);
+			var table = document.createElement('table');
+			table.className = 'ke-table';
+			table.cellPadding = 0;
+			table.cellSpacing = 0;
+			table.border = 0;
+			bodyDiv.append(table);
+			var fileList = result.file_list;
+			for (var i = 0, len = fileList.length; i < len; i++) {
+				var data = fileList[i], row = K(table.insertRow(i));
+				row.mouseover(function(e) {
+					K(this).addClass('ke-on');
+				})
+				.mouseout(function(e) {
+					K(this).removeClass('ke-on');
+				});
+				var iconUrl = imgPath + (data.is_dir ? 'folder-16.gif' : 'file-16.gif'),
+					img = K('<img src="' + iconUrl + '" width="16" height="16" alt="' + data.filename + '" align="absmiddle" />'),
+					cell0 = K(row[0].insertCell(0)).addClass('ke-cell ke-name').append(img).append(document.createTextNode(' ' + data.filename));
+				if (!data.is_dir || data.has_file) {
+					row.css('cursor', 'pointer');
+					cell0.attr('title', data.filename);
+					bindEvent(cell0, result, data, createList);
+				} else {
+					cell0.attr('title', lang.emptyFolder);
+				}
+				K(row[0].insertCell(1)).addClass('ke-cell ke-size').html(data.is_dir ? '-' : Math.ceil(data.filesize / 1024) + 'KB');
+				K(row[0].insertCell(2)).addClass('ke-cell ke-datetime').html(data.datetime);
+			}
+		}
+		function createView(result) {
+			createCommon(result, createView);
+			var fileList = result.file_list;
+			for (var i = 0, len = fileList.length; i < len; i++) {
+				var data = fileList[i],
+					div = K('<div class="ke-inline-block ke-item"></div>');
+				bodyDiv.append(div);
+				var photoDiv = K('<div class="ke-inline-block ke-photo"></div>')
+					.mouseover(function(e) {
+						K(this).addClass('ke-on');
+					})
+					.mouseout(function(e) {
+						K(this).removeClass('ke-on');
+					});
+				div.append(photoDiv);
+				var fileUrl = result.current_url + data.filename,
+					iconUrl = data.is_dir ? imgPath + 'folder-64.gif' : (data.is_photo ? fileUrl : imgPath + 'file-64.gif');
+				var img = K('<img src="' + iconUrl + '" width="80" height="80" alt="' + data.filename + '" />');
+				if (!data.is_dir || data.has_file) {
+					photoDiv.css('cursor', 'pointer');
+					bindTitle(photoDiv, data);
+					bindEvent(photoDiv, result, data, createView);
+				} else {
+					photoDiv.attr('title', lang.emptyFolder);
+				}
+				photoDiv.append(img);
+				div.append('<div class="ke-name" title="' + data.filename + '">' + data.filename + '</div>');
+			}
+		}
+		viewTypeBox.val(viewType);
+		reloadPage('', orderTypeBox.val(), viewType == 'VIEW' ? createView : createList);
+		return dialog;
+	}
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('flash', function(K) {
+	var self = this, name = 'flash', lang = self.lang(name + '.'),
+		allowFlashUpload = K.undef(self.allowFlashUpload, true),
+		allowFileManager = K.undef(self.allowFileManager, false),
+		formatUploadUrl = K.undef(self.formatUploadUrl, true),
+		extraParams = K.undef(self.extraFileUploadParams, {}),
+		filePostName = K.undef(self.filePostName, 'imgFile'),
+		uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php');
+	self.plugin.flash = {
+		edit : function() {
+			var html = [
+				'<div style="padding:20px;">',
+				'<div class="ke-dialog-row">',
+				'<label for="keUrl" style="width:60px;">' + lang.url + '</label>',
+				'<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;',
+				'<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;',
+				'<span class="ke-button-common ke-button-outer">',
+				'<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />',
+				'</span>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keWidth" style="width:60px;">' + lang.width + '</label>',
+				'<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" /> ',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keHeight" style="width:60px;">' + lang.height + '</label>',
+				'<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" /> ',
+				'</div>',
+				'</div>'
+			].join('');
+			var dialog = self.createDialog({
+				name : name,
+				width : 450,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var url = K.trim(urlBox.val()),
+							width = widthBox.val(),
+							height = heightBox.val();
+						if (url == 'http://' || K.invalidUrl(url)) {
+							alert(self.lang('invalidUrl'));
+							urlBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(width)) {
+							alert(self.lang('invalidWidth'));
+							widthBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(height)) {
+							alert(self.lang('invalidHeight'));
+							heightBox[0].focus();
+							return;
+						}
+						var html = K.mediaImg(self.themesPath + 'common/blank.gif', {
+								src : url,
+								type : K.mediaType('.swf'),
+								width : width,
+								height : height,
+								quality : 'high'
+							});
+						self.insertHtml(html).hideDialog().focus();
+					}
+				}
+			}),
+			div = dialog.div,
+			urlBox = K('[name="url"]', div),
+			viewServerBtn = K('[name="viewServer"]', div),
+			widthBox = K('[name="width"]', div),
+			heightBox = K('[name="height"]', div);
+			urlBox.val('http://');
+			if (allowFlashUpload) {
+				var uploadbutton = K.uploadbutton({
+					button : K('.ke-upload-button', div)[0],
+					fieldName : filePostName,
+					extraParams : extraParams,
+					url : K.addParam(uploadJson, 'dir=flash'),
+					afterUpload : function(data) {
+						dialog.hideLoading();
+						if (data.error === 0) {
+							var url = data.url;
+							if (formatUploadUrl) {
+								url = K.formatUrl(url, 'absolute');
+							}
+							urlBox.val(url);
+							if (self.afterUpload) {
+								self.afterUpload.call(self, url, data, name);
+							}
+							alert(self.lang('uploadSuccess'));
+						} else {
+							alert(data.message);
+						}
+					},
+					afterError : function(html) {
+						dialog.hideLoading();
+						self.errorDialog(html);
+					}
+				});
+				uploadbutton.fileBox.change(function(e) {
+					dialog.showLoading(self.lang('uploadLoading'));
+					uploadbutton.submit();
+				});
+			} else {
+				K('.ke-upload-button', div).hide();
+			}
+			if (allowFileManager) {
+				viewServerBtn.click(function(e) {
+					self.loadPlugin('filemanager', function() {
+						self.plugin.filemanagerDialog({
+							viewType : 'LIST',
+							dirName : 'flash',
+							clickFn : function(url, title) {
+								if (self.dialogs.length > 1) {
+									K('[name="url"]', div).val(url);
+									if (self.afterSelectFile) {
+										self.afterSelectFile.call(self, url);
+									}
+									self.hideDialog();
+								}
+							}
+						});
+					});
+				});
+			} else {
+				viewServerBtn.hide();
+			}
+			var img = self.plugin.getSelectedFlash();
+			if (img) {
+				var attrs = K.mediaAttrs(img.attr('data-ke-tag'));
+				urlBox.val(attrs.src);
+				widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0);
+				heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0);
+			}
+			urlBox[0].focus();
+			urlBox[0].select();
+		},
+		'delete' : function() {
+			self.plugin.getSelectedFlash().remove();
+			self.addBookmark();
+		}
+	};
+	self.clickToolbar(name, self.plugin.flash.edit);
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('image', function(K) {
+	var self = this, name = 'image',
+		allowImageUpload = K.undef(self.allowImageUpload, true),
+		allowImageRemote = K.undef(self.allowImageRemote, true),
+		formatUploadUrl = K.undef(self.formatUploadUrl, true),
+		allowFileManager = K.undef(self.allowFileManager, false),
+		uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'),
+		imageTabIndex = K.undef(self.imageTabIndex, 0),
+		imgPath = self.pluginsPath + 'image/images/',
+		extraParams = K.undef(self.extraFileUploadParams, {}),
+		filePostName = K.undef(self.filePostName, 'imgFile'),
+		fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false),
+		lang = self.lang(name + '.');
+	self.plugin.imageDialog = function(options) {
+		var imageUrl = options.imageUrl,
+			imageWidth = K.undef(options.imageWidth, ''),
+			imageHeight = K.undef(options.imageHeight, ''),
+			imageTitle = K.undef(options.imageTitle, ''),
+			imageAlign = K.undef(options.imageAlign, ''),
+			showRemote = K.undef(options.showRemote, true),
+			showLocal = K.undef(options.showLocal, true),
+			tabIndex = K.undef(options.tabIndex, 0),
+			clickFn = options.clickFn;
+		var target = 'kindeditor_upload_iframe_' + new Date().getTime();
+		var hiddenElements = [];
+		for(var k in extraParams){
+			hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />');
+		}
+		var html = [
+			'<div style="padding:20px;">',
+			'<div class="tabs"></div>',
+			'<div class="tab1" style="display:none;">',
+			'<div class="ke-dialog-row">',
+			'<label for="remoteUrl" style="width:60px;">' + lang.remoteUrl + '</label>',
+			'<input type="text" id="remoteUrl" class="ke-input-text" name="url" value="" style="width:200px;" /> &nbsp;',
+			'<span class="ke-button-common ke-button-outer">',
+			'<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />',
+			'</span>',
+			'</div>',
+			'<div class="ke-dialog-row">',
+			'<label for="remoteWidth" style="width:60px;">' + lang.size + '</label>',
+			lang.width + ' <input type="text" id="remoteWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> ',
+			lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> ',
+			'<img class="ke-refresh-btn" src="' + imgPath + 'refresh.png" width="16" height="16" alt="" style="cursor:pointer;" title="' + lang.resetSize + '" />',
+			'</div>',
+			'<div class="ke-dialog-row">',
+			'<label style="width:60px;">' + lang.align + '</label>',
+			'<input type="radio" name="align" class="ke-inline-block" value="" checked="checked" /> <img name="defaultImg" src="' + imgPath + 'align_top.gif" width="23" height="25" alt="" />',
+			' <input type="radio" name="align" class="ke-inline-block" value="left" /> <img name="leftImg" src="' + imgPath + 'align_left.gif" width="23" height="25" alt="" />',
+			' <input type="radio" name="align" class="ke-inline-block" value="right" /> <img name="rightImg" src="' + imgPath + 'align_right.gif" width="23" height="25" alt="" />',
+			'</div>',
+			'<div class="ke-dialog-row">',
+			'<label for="remoteTitle" style="width:60px;">' + lang.imgTitle + '</label>',
+			'<input type="text" id="remoteTitle" class="ke-input-text" name="title" value="" style="width:200px;" />',
+			'</div>',
+			'</div>',
+			'<div class="tab2" style="display:none;">',
+			'<iframe name="' + target + '" style="display:none;"></iframe>',
+			'<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + K.addParam(uploadJson, 'dir=image') + '">',
+			'<div class="ke-dialog-row">',
+			hiddenElements.join(''),
+			'<label style="width:60px;">' + lang.localUrl + '</label>',
+			'<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;',
+			'<input type="button" class="ke-upload-button" value="' + lang.upload + '" />',
+			'</div>',
+			'</form>',
+			'</div>',
+			'</div>'
+		].join('');
+		var dialogWidth = showLocal || allowFileManager ? 450 : 400,
+			dialogHeight = showLocal && showRemote ? 300 : 250;
+		var dialog = self.createDialog({
+			name : name,
+			width : dialogWidth,
+			height : dialogHeight,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					if (dialog.isLoading) {
+						return;
+					}
+					if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) {
+						if (uploadbutton.fileBox.val() == '') {
+							alert(self.lang('pleaseSelectFile'));
+							return;
+						}
+						dialog.showLoading(self.lang('uploadLoading'));
+						uploadbutton.submit();
+						localUrlBox.val('');
+						return;
+					}
+					var url = K.trim(urlBox.val()),
+						width = widthBox.val(),
+						height = heightBox.val(),
+						title = titleBox.val(),
+						align = '';
+					alignBox.each(function() {
+						if (this.checked) {
+							align = this.value;
+							return false;
+						}
+					});
+					if (url == 'http://' || K.invalidUrl(url)) {
+						alert(self.lang('invalidUrl'));
+						urlBox[0].focus();
+						return;
+					}
+					if (!/^\d*$/.test(width)) {
+						alert(self.lang('invalidWidth'));
+						widthBox[0].focus();
+						return;
+					}
+					if (!/^\d*$/.test(height)) {
+						alert(self.lang('invalidHeight'));
+						heightBox[0].focus();
+						return;
+					}
+					clickFn.call(self, url, title, width, height, 0, align);
+				}
+			},
+			beforeRemove : function() {
+				viewServerBtn.unbind();
+				widthBox.unbind();
+				heightBox.unbind();
+				refreshBtn.unbind();
+			}
+		}),
+		div = dialog.div;
+		var urlBox = K('[name="url"]', div),
+			localUrlBox = K('[name="localUrl"]', div),
+			viewServerBtn = K('[name="viewServer"]', div),
+			widthBox = K('.tab1 [name="width"]', div),
+			heightBox = K('.tab1 [name="height"]', div),
+			refreshBtn = K('.ke-refresh-btn', div),
+			titleBox = K('.tab1 [name="title"]', div),
+			alignBox = K('.tab1 [name="align"]', div);
+		var tabs;
+		if (showRemote && showLocal) {
+			tabs = K.tabs({
+				src : K('.tabs', div),
+				afterSelect : function(i) {}
+			});
+			tabs.add({
+				title : lang.remoteImage,
+				panel : K('.tab1', div)
+			});
+			tabs.add({
+				title : lang.localImage,
+				panel : K('.tab2', div)
+			});
+			tabs.select(tabIndex);
+		} else if (showRemote) {
+			K('.tab1', div).show();
+		} else if (showLocal) {
+			K('.tab2', div).show();
+		}
+		var uploadbutton = K.uploadbutton({
+			button : K('.ke-upload-button', div)[0],
+			fieldName : filePostName,
+			form : K('.ke-form', div),
+			target : target,
+			width: 60,
+			afterUpload : function(data) {
+				dialog.hideLoading();
+				if (data.error === 0) {
+					var url = data.url;
+					if (formatUploadUrl) {
+						url = K.formatUrl(url, 'absolute');
+					}
+					if (self.afterUpload) {
+						self.afterUpload.call(self, url, data, name);
+					}
+					if (!fillDescAfterUploadImage) {
+						clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align);
+					} else {
+						K(".ke-dialog-row #remoteUrl", div).val(url);
+						K(".ke-tabs-li", div)[0].click();
+						K(".ke-refresh-btn", div).click();
+					}
+				} else {
+					alert(data.message);
+				}
+			},
+			afterError : function(html) {
+				dialog.hideLoading();
+				self.errorDialog(html);
+			}
+		});
+		uploadbutton.fileBox.change(function(e) {
+			localUrlBox.val(uploadbutton.fileBox.val());
+		});
+		if (allowFileManager) {
+			viewServerBtn.click(function(e) {
+				self.loadPlugin('filemanager', function() {
+					self.plugin.filemanagerDialog({
+						viewType : 'VIEW',
+						dirName : 'image',
+						clickFn : function(url, title) {
+							if (self.dialogs.length > 1) {
+								K('[name="url"]', div).val(url);
+								if (self.afterSelectFile) {
+									self.afterSelectFile.call(self, url);
+								}
+								self.hideDialog();
+							}
+						}
+					});
+				});
+			});
+		} else {
+			viewServerBtn.hide();
+		}
+		var originalWidth = 0, originalHeight = 0;
+		function setSize(width, height) {
+			widthBox.val(width);
+			heightBox.val(height);
+			originalWidth = width;
+			originalHeight = height;
+		}
+		refreshBtn.click(function(e) {
+			var tempImg = K('<img src="' + urlBox.val() + '" />', document).css({
+				position : 'absolute',
+				visibility : 'hidden',
+				top : 0,
+				left : '-1000px'
+			});
+			tempImg.bind('load', function() {
+				setSize(tempImg.width(), tempImg.height());
+				tempImg.remove();
+			});
+			K(document.body).append(tempImg);
+		});
+		widthBox.change(function(e) {
+			if (originalWidth > 0) {
+				heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10)));
+			}
+		});
+		heightBox.change(function(e) {
+			if (originalHeight > 0) {
+				widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10)));
+			}
+		});
+		urlBox.val(options.imageUrl);
+		setSize(options.imageWidth, options.imageHeight);
+		titleBox.val(options.imageTitle);
+		alignBox.each(function() {
+			if (this.value === options.imageAlign) {
+				this.checked = true;
+				return false;
+			}
+		});
+		if (showRemote && tabIndex === 0) {
+			urlBox[0].focus();
+			urlBox[0].select();
+		}
+		return dialog;
+	};
+	self.plugin.image = {
+		edit : function() {
+			var img = self.plugin.getSelectedImage();
+			self.plugin.imageDialog({
+				imageUrl : img ? img.attr('data-ke-src') : 'http://',
+				imageWidth : img ? img.width() : '',
+				imageHeight : img ? img.height() : '',
+				imageTitle : img ? img.attr('title') : '',
+				imageAlign : img ? img.attr('align') : '',
+				showRemote : allowImageRemote,
+				showLocal : allowImageUpload,
+				tabIndex: img ? 0 : imageTabIndex,
+				clickFn : function(url, title, width, height, border, align) {
+					if (img) {
+						img.attr('src', url);
+						img.attr('data-ke-src', url);
+						img.attr('width', width);
+						img.attr('height', height);
+						img.attr('title', title);
+						img.attr('align', align);
+						img.attr('alt', title);
+					} else {
+						self.exec('insertimage', url, title, width, height, border, align);
+					}
+					setTimeout(function() {
+						self.hideDialog().focus();
+					}, 0);
+				}
+			});
+		},
+		'delete' : function() {
+			var target = self.plugin.getSelectedImage();
+			if (target.parent().name == 'a') {
+				target = target.parent();
+			}
+			target.remove();
+			self.addBookmark();
+		}
+	};
+	self.clickToolbar(name, self.plugin.image.edit);
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('insertfile', function(K) {
+	var self = this, name = 'insertfile',
+		allowFileUpload = K.undef(self.allowFileUpload, true),
+		allowFileManager = K.undef(self.allowFileManager, false),
+		formatUploadUrl = K.undef(self.formatUploadUrl, true),
+		uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'),
+		extraParams = K.undef(self.extraFileUploadParams, {}),
+		filePostName = K.undef(self.filePostName, 'imgFile'),
+		lang = self.lang(name + '.');
+	self.plugin.fileDialog = function(options) {
+		var fileUrl = K.undef(options.fileUrl, 'http://'),
+			fileTitle = K.undef(options.fileTitle, ''),
+			clickFn = options.clickFn;
+		var html = [
+			'<div style="padding:20px;">',
+			'<div class="ke-dialog-row">',
+			'<label for="keUrl" style="width:60px;">' + lang.url + '</label>',
+			'<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;',
+			'<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;',
+			'<span class="ke-button-common ke-button-outer">',
+			'<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />',
+			'</span>',
+			'</div>',
+			'<div class="ke-dialog-row">',
+			'<label for="keTitle" style="width:60px;">' + lang.title + '</label>',
+			'<input type="text" id="keTitle" class="ke-input-text" name="title" value="" style="width:160px;" /></div>',
+			'</div>',
+			'</form>',
+			'</div>'
+			].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : 450,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					var url = K.trim(urlBox.val()),
+						title = titleBox.val();
+					if (url == 'http://' || K.invalidUrl(url)) {
+						alert(self.lang('invalidUrl'));
+						urlBox[0].focus();
+						return;
+					}
+					if (K.trim(title) === '') {
+						title = url;
+					}
+					clickFn.call(self, url, title);
+				}
+			}
+		}),
+		div = dialog.div;
+		var urlBox = K('[name="url"]', div),
+			viewServerBtn = K('[name="viewServer"]', div),
+			titleBox = K('[name="title"]', div);
+		if (allowFileUpload) {
+			var uploadbutton = K.uploadbutton({
+				button : K('.ke-upload-button', div)[0],
+				fieldName : filePostName,
+				url : K.addParam(uploadJson, 'dir=file'),
+				extraParams : extraParams,
+				afterUpload : function(data) {
+					dialog.hideLoading();
+					if (data.error === 0) {
+						var url = data.url;
+						if (formatUploadUrl) {
+							url = K.formatUrl(url, 'absolute');
+						}
+						urlBox.val(url);
+						if (self.afterUpload) {
+							self.afterUpload.call(self, url, data, name);
+						}
+						alert(self.lang('uploadSuccess'));
+					} else {
+						alert(data.message);
+					}
+				},
+				afterError : function(html) {
+					dialog.hideLoading();
+					self.errorDialog(html);
+				}
+			});
+			uploadbutton.fileBox.change(function(e) {
+				dialog.showLoading(self.lang('uploadLoading'));
+				uploadbutton.submit();
+			});
+		} else {
+			K('.ke-upload-button', div).hide();
+		}
+		if (allowFileManager) {
+			viewServerBtn.click(function(e) {
+				self.loadPlugin('filemanager', function() {
+					self.plugin.filemanagerDialog({
+						viewType : 'LIST',
+						dirName : 'file',
+						clickFn : function(url, title) {
+							if (self.dialogs.length > 1) {
+								K('[name="url"]', div).val(url);
+								if (self.afterSelectFile) {
+									self.afterSelectFile.call(self, url);
+								}
+								self.hideDialog();
+							}
+						}
+					});
+				});
+			});
+		} else {
+			viewServerBtn.hide();
+		}
+		urlBox.val(fileUrl);
+		titleBox.val(fileTitle);
+		urlBox[0].focus();
+		urlBox[0].select();
+	};
+	self.clickToolbar(name, function() {
+		self.plugin.fileDialog({
+			clickFn : function(url, title) {
+				var html = '<a class="ke-insertfile" href="' + url + '" data-ke-src="' + url + '" target="_blank">' + title + '</a>';
+				self.insertHtml(html).hideDialog().focus();
+			}
+		});
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('lineheight', function(K) {
+	var self = this, name = 'lineheight', lang = self.lang(name + '.');
+	self.clickToolbar(name, function() {
+		var curVal = '', commonNode = self.cmd.commonNode({'*' : '.line-height'});
+		if (commonNode) {
+			curVal = commonNode.css('line-height');
+		}
+		var menu = self.createMenu({
+			name : name,
+			width : 150
+		});
+		K.each(lang.lineHeight, function(i, row) {
+			K.each(row, function(key, val) {
+				menu.addItem({
+					title : val,
+					checked : curVal === key,
+					click : function() {
+						self.cmd.toggle('<span style="line-height:' + key + ';"></span>', {
+							span : '.line-height=' + key
+						});
+						self.updateState();
+						self.addBookmark();
+						self.hideMenu();
+					}
+				});
+			});
+		});
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('link', function(K) {
+	var self = this, name = 'link';
+	self.plugin.link = {
+		edit : function() {
+			var lang = self.lang(name + '.'),
+				html = '<div style="padding:20px;">' +
+					'<div class="ke-dialog-row">' +
+					'<label for="keUrl" style="width:60px;">' + lang.url + '</label>' +
+					'<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:260px;" /></div>' +
+					'<div class="ke-dialog-row"">' +
+					'<label for="keType" style="width:60px;">' + lang.linkType + '</label>' +
+					'<select id="keType" name="type"></select>' +
+					'</div>' +
+					'</div>',
+				dialog = self.createDialog({
+					name : name,
+					width : 450,
+					title : self.lang(name),
+					body : html,
+					yesBtn : {
+						name : self.lang('yes'),
+						click : function(e) {
+							var url = K.trim(urlBox.val());
+							if (url == 'http://' || K.invalidUrl(url)) {
+								alert(self.lang('invalidUrl'));
+								urlBox[0].focus();
+								return;
+							}
+							self.exec('createlink', url, typeBox.val()).hideDialog().focus();
+						}
+					}
+				}),
+				div = dialog.div,
+				urlBox = K('input[name="url"]', div),
+				typeBox = K('select[name="type"]', div);
+			urlBox.val('http://');
+			typeBox[0].options[0] = new Option(lang.newWindow, '_blank');
+			typeBox[0].options[1] = new Option(lang.selfWindow, '');
+			self.cmd.selection();
+			var a = self.plugin.getSelectedLink();
+			if (a) {
+				self.cmd.range.selectNode(a[0]);
+				self.cmd.select();
+				urlBox.val(a.attr('data-ke-src'));
+				typeBox.val(a.attr('target'));
+			}
+			urlBox[0].focus();
+			urlBox[0].select();
+		},
+		'delete' : function() {
+			self.exec('unlink', null);
+		}
+	};
+	self.clickToolbar(name, self.plugin.link.edit);
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('media', function(K) {
+	var self = this, name = 'media', lang = self.lang(name + '.'),
+		allowMediaUpload = K.undef(self.allowMediaUpload, true),
+		allowFileManager = K.undef(self.allowFileManager, false),
+		formatUploadUrl = K.undef(self.formatUploadUrl, true),
+		extraParams = K.undef(self.extraFileUploadParams, {}),
+		filePostName = K.undef(self.filePostName, 'imgFile'),
+		uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php');
+	self.plugin.media = {
+		edit : function() {
+			var html = [
+				'<div style="padding:20px;">',
+				'<div class="ke-dialog-row">',
+				'<label for="keUrl" style="width:60px;">' + lang.url + '</label>',
+				'<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;',
+				'<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;',
+				'<span class="ke-button-common ke-button-outer">',
+				'<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />',
+				'</span>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keWidth" style="width:60px;">' + lang.width + '</label>',
+				'<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" />',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keHeight" style="width:60px;">' + lang.height + '</label>',
+				'<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" />',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keAutostart">' + lang.autostart + '</label>',
+				'<input type="checkbox" id="keAutostart" name="autostart" value="" /> ',
+				'</div>',
+				'</div>'
+			].join('');
+			var dialog = self.createDialog({
+				name : name,
+				width : 450,
+				height : 230,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var url = K.trim(urlBox.val()),
+							width = widthBox.val(),
+							height = heightBox.val();
+						if (url == 'http://' || K.invalidUrl(url)) {
+							alert(self.lang('invalidUrl'));
+							urlBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(width)) {
+							alert(self.lang('invalidWidth'));
+							widthBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(height)) {
+							alert(self.lang('invalidHeight'));
+							heightBox[0].focus();
+							return;
+						}
+						var html = K.mediaImg(self.themesPath + 'common/blank.gif', {
+								src : url,
+								type : K.mediaType(url),
+								width : width,
+								height : height,
+								autostart : autostartBox[0].checked ? 'true' : 'false',
+								loop : 'true'
+							});
+						self.insertHtml(html).hideDialog().focus();
+					}
+				}
+			}),
+			div = dialog.div,
+			urlBox = K('[name="url"]', div),
+			viewServerBtn = K('[name="viewServer"]', div),
+			widthBox = K('[name="width"]', div),
+			heightBox = K('[name="height"]', div),
+			autostartBox = K('[name="autostart"]', div);
+			urlBox.val('http://');
+			if (allowMediaUpload) {
+				var uploadbutton = K.uploadbutton({
+					button : K('.ke-upload-button', div)[0],
+					fieldName : filePostName,
+					extraParams : extraParams,
+					url : K.addParam(uploadJson, 'dir=media'),
+					afterUpload : function(data) {
+						dialog.hideLoading();
+						if (data.error === 0) {
+							var url = data.url;
+							if (formatUploadUrl) {
+								url = K.formatUrl(url, 'absolute');
+							}
+							urlBox.val(url);
+							if (self.afterUpload) {
+								self.afterUpload.call(self, url, data, name);
+							}
+							alert(self.lang('uploadSuccess'));
+						} else {
+							alert(data.message);
+						}
+					},
+					afterError : function(html) {
+						dialog.hideLoading();
+						self.errorDialog(html);
+					}
+				});
+				uploadbutton.fileBox.change(function(e) {
+					dialog.showLoading(self.lang('uploadLoading'));
+					uploadbutton.submit();
+				});
+			} else {
+				K('.ke-upload-button', div).hide();
+			}
+			if (allowFileManager) {
+				viewServerBtn.click(function(e) {
+					self.loadPlugin('filemanager', function() {
+						self.plugin.filemanagerDialog({
+							viewType : 'LIST',
+							dirName : 'media',
+							clickFn : function(url, title) {
+								if (self.dialogs.length > 1) {
+									K('[name="url"]', div).val(url);
+									if (self.afterSelectFile) {
+										self.afterSelectFile.call(self, url);
+									}
+									self.hideDialog();
+								}
+							}
+						});
+					});
+				});
+			} else {
+				viewServerBtn.hide();
+			}
+			var img = self.plugin.getSelectedMedia();
+			if (img) {
+				var attrs = K.mediaAttrs(img.attr('data-ke-tag'));
+				urlBox.val(attrs.src);
+				widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0);
+				heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0);
+				autostartBox[0].checked = (attrs.autostart === 'true');
+			}
+			urlBox[0].focus();
+			urlBox[0].select();
+		},
+		'delete' : function() {
+			self.plugin.getSelectedMedia().remove();
+			self.addBookmark();
+		}
+	};
+	self.clickToolbar(name, self.plugin.media.edit);
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+(function(K) {
+function KSWFUpload(options) {
+	this.init(options);
+}
+K.extend(KSWFUpload, {
+	init : function(options) {
+		var self = this;
+		options.afterError = options.afterError || function(str) {
+			alert(str);
+		};
+		self.options = options;
+		self.progressbars = {};
+		self.div = K(options.container).html([
+			'<div class="ke-swfupload">',
+			'<div class="ke-swfupload-top">',
+			'<div class="ke-inline-block ke-swfupload-button">',
+			'<input type="button" value="Browse" />',
+			'</div>',
+			'<div class="ke-inline-block ke-swfupload-desc">' + options.uploadDesc + '</div>',
+			'<span class="ke-button-common ke-button-outer ke-swfupload-startupload">',
+			'<input type="button" class="ke-button-common ke-button" value="' + options.startButtonValue + '" />',
+			'</span>',
+			'</div>',
+			'<div class="ke-swfupload-body"></div>',
+			'</div>'
+		].join(''));
+		self.bodyDiv = K('.ke-swfupload-body', self.div);
+		function showError(itemDiv, msg) {
+			K('.ke-status > div', itemDiv).hide();
+			K('.ke-message', itemDiv).addClass('ke-error').show().html(K.escape(msg));
+		}
+		var settings = {
+			debug : false,
+			upload_url : options.uploadUrl,
+			flash_url : options.flashUrl,
+			file_post_name : options.filePostName,
+			button_placeholder : K('.ke-swfupload-button > input', self.div)[0],
+			button_image_url: options.buttonImageUrl,
+			button_width: options.buttonWidth,
+			button_height: options.buttonHeight,
+			button_cursor : SWFUpload.CURSOR.HAND,
+			file_types : options.fileTypes,
+			file_types_description : options.fileTypesDesc,
+			file_upload_limit : options.fileUploadLimit,
+			file_size_limit : options.fileSizeLimit,
+			post_params : options.postParams,
+			file_queued_handler : function(file) {
+				file.url = self.options.fileIconUrl;
+				self.appendFile(file);
+			},
+			file_queue_error_handler : function(file, errorCode, message) {
+				var errorName = '';
+				switch (errorCode) {
+					case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
+						errorName = options.queueLimitExceeded;
+						break;
+					case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
+						errorName = options.fileExceedsSizeLimit;
+						break;
+					case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
+						errorName = options.zeroByteFile;
+						break;
+					case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
+						errorName = options.invalidFiletype;
+						break;
+					default:
+						errorName = options.unknownError;
+						break;
+				}
+				K.DEBUG && alert(errorName);
+			},
+			upload_start_handler : function(file) {
+				var self = this;
+				var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv);
+				K('.ke-status > div', itemDiv).hide();
+				K('.ke-progressbar', itemDiv).show();
+			},
+			upload_progress_handler : function(file, bytesLoaded, bytesTotal) {
+				var percent = Math.round(bytesLoaded * 100 / bytesTotal);
+				var progressbar = self.progressbars[file.id];
+				progressbar.bar.css('width', Math.round(percent * 80 / 100) + 'px');
+				progressbar.percent.html(percent + '%');
+			},
+			upload_error_handler : function(file, errorCode, message) {
+				if (file && file.filestatus == SWFUpload.FILE_STATUS.ERROR) {
+					var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0);
+					showError(itemDiv, self.options.errorMessage);
+				}
+			},
+			upload_success_handler : function(file, serverData) {
+				var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0);
+				var data = {};
+				try {
+					data = K.json(serverData);
+				} catch (e) {
+					self.options.afterError.call(this, '<!doctype html><html>' + serverData + '</html>');
+				}
+				if (data.error !== 0) {
+					showError(itemDiv, K.DEBUG ? data.message : self.options.errorMessage);
+					return;
+				}
+				file.url = data.url;
+				K('.ke-img', itemDiv).attr('src', file.url).attr('data-status', file.filestatus).data('data', data);
+				K('.ke-status > div', itemDiv).hide();
+			}
+		};
+		self.swfu = new SWFUpload(settings);
+		K('.ke-swfupload-startupload input', self.div).click(function() {
+			self.swfu.startUpload();
+		});
+	},
+	getUrlList : function() {
+		var list = [];
+		K('.ke-img', self.bodyDiv).each(function() {
+			var img = K(this);
+			var status = img.attr('data-status');
+			if (status == SWFUpload.FILE_STATUS.COMPLETE) {
+				list.push(img.data('data'));
+			}
+		});
+		return list;
+	},
+	removeFile : function(fileId) {
+		var self = this;
+		self.swfu.cancelUpload(fileId);
+		var itemDiv = K('div[data-id="' + fileId + '"]', self.bodyDiv);
+		K('.ke-photo', itemDiv).unbind();
+		K('.ke-delete', itemDiv).unbind();
+		itemDiv.remove();
+	},
+	removeFiles : function() {
+		var self = this;
+		K('.ke-item', self.bodyDiv).each(function() {
+			self.removeFile(K(this).attr('data-id'));
+		});
+	},
+	appendFile : function(file) {
+		var self = this;
+		var itemDiv = K('<div class="ke-inline-block ke-item" data-id="' + file.id + '"></div>');
+		self.bodyDiv.append(itemDiv);
+		var photoDiv = K('<div class="ke-inline-block ke-photo"></div>')
+			.mouseover(function(e) {
+				K(this).addClass('ke-on');
+			})
+			.mouseout(function(e) {
+				K(this).removeClass('ke-on');
+			});
+		itemDiv.append(photoDiv);
+		var img = K('<img src="' + file.url + '" class="ke-img" data-status="' + file.filestatus + '" width="80" height="80" alt="' + file.name + '" />');
+		photoDiv.append(img);
+		K('<span class="ke-delete"></span>').appendTo(photoDiv).click(function() {
+			self.removeFile(file.id);
+		});
+		var statusDiv = K('<div class="ke-status"></div>').appendTo(photoDiv);
+		K(['<div class="ke-progressbar">',
+			'<div class="ke-progressbar-bar"><div class="ke-progressbar-bar-inner"></div></div>',
+			'<div class="ke-progressbar-percent">0%</div></div>'].join('')).hide().appendTo(statusDiv);
+		K('<div class="ke-message">' + self.options.pendingMessage + '</div>').appendTo(statusDiv);
+		itemDiv.append('<div class="ke-name">' + file.name + '</div>');
+		self.progressbars[file.id] = {
+			bar : K('.ke-progressbar-bar-inner', photoDiv),
+			percent : K('.ke-progressbar-percent', photoDiv)
+		};
+	},
+	remove : function() {
+		this.removeFiles();
+		this.swfu.destroy();
+		this.div.html('');
+	}
+});
+K.swfupload = function(element, options) {
+	return new KSWFUpload(element, options);
+};
+})(KindEditor);
+KindEditor.plugin('multiimage', function(K) {
+	var self = this, name = 'multiimage',
+		formatUploadUrl = K.undef(self.formatUploadUrl, true),
+		uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'),
+		imgPath = self.pluginsPath + 'multiimage/images/',
+		imageSizeLimit = K.undef(self.imageSizeLimit, '1MB'),
+		imageFileTypes = K.undef(self.imageFileTypes, '*.jpg;*.gif;*.png'),
+		imageUploadLimit = K.undef(self.imageUploadLimit, 20),
+		filePostName = K.undef(self.filePostName, 'imgFile'),
+		lang = self.lang(name + '.');
+	self.plugin.multiImageDialog = function(options) {
+		var clickFn = options.clickFn,
+			uploadDesc = K.tmpl(lang.uploadDesc, {uploadLimit : imageUploadLimit, sizeLimit : imageSizeLimit});
+		var html = [
+			'<div style="padding:20px;">',
+			'<div class="swfupload">',
+			'</div>',
+			'</div>'
+		].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : 650,
+			height : 510,
+			title : self.lang(name),
+			body : html,
+			previewBtn : {
+				name : lang.insertAll,
+				click : function(e) {
+					clickFn.call(self, swfupload.getUrlList());
+				}
+			},
+			yesBtn : {
+				name : lang.clearAll,
+				click : function(e) {
+					swfupload.removeFiles();
+				}
+			},
+			beforeRemove : function() {
+				if (!K.IE || K.V <= 8) {
+					swfupload.remove();
+				}
+			}
+		}),
+		div = dialog.div;
+		var swfupload = K.swfupload({
+			container : K('.swfupload', div),
+			buttonImageUrl : imgPath + (self.langType == 'zh-CN' ? 'select-files-zh-CN.png' : 'select-files-en.png'),
+			buttonWidth : self.langType == 'zh-CN' ? 72 : 88,
+			buttonHeight : 23,
+			fileIconUrl : imgPath + 'image.png',
+			uploadDesc : uploadDesc,
+			startButtonValue : lang.startUpload,
+			uploadUrl : K.addParam(uploadJson, 'dir=image'),
+			flashUrl : imgPath + 'swfupload.swf',
+			filePostName : filePostName,
+			fileTypes : '*.jpg;*.jpeg;*.gif;*.png;*.bmp',
+			fileTypesDesc : 'Image Files',
+			fileUploadLimit : imageUploadLimit,
+			fileSizeLimit : imageSizeLimit,
+			postParams :  K.undef(self.extraFileUploadParams, {}),
+			queueLimitExceeded : lang.queueLimitExceeded,
+			fileExceedsSizeLimit : lang.fileExceedsSizeLimit,
+			zeroByteFile : lang.zeroByteFile,
+			invalidFiletype : lang.invalidFiletype,
+			unknownError : lang.unknownError,
+			pendingMessage : lang.pending,
+			errorMessage : lang.uploadError,
+			afterError : function(html) {
+				self.errorDialog(html);
+			}
+		});
+		return dialog;
+	};
+	self.clickToolbar(name, function() {
+		self.plugin.multiImageDialog({
+			clickFn : function (urlList) {
+				if (urlList.length === 0) {
+					return;
+				}
+				K.each(urlList, function(i, data) {
+					if (self.afterUpload) {
+						self.afterUpload.call(self, data.url, data, 'multiimage');
+					}
+					self.exec('insertimage', data.url, data.title, data.width, data.height, data.border, data.align);
+				});
+				setTimeout(function() {
+					self.hideDialog().focus();
+				}, 0);
+			}
+		});
+	});
+});
+/* ******************* */
+/* Constructor & Init  */
+/* ******************* */
+(function() {
+window.SWFUpload = function (settings) {
+	this.initSWFUpload(settings);
+};
+SWFUpload.prototype.initSWFUpload = function (settings) {
+	try {
+		this.customSettings = {};
+		this.settings = settings;
+		this.eventQueue = [];
+		this.movieName = "KindEditor_SWFUpload_" + SWFUpload.movieCount++;
+		this.movieElement = null;
+		SWFUpload.instances[this.movieName] = this;
+		this.initSettings();
+		this.loadFlash();
+		this.displayDebugInfo();
+	} catch (ex) {
+		delete SWFUpload.instances[this.movieName];
+		throw ex;
+	}
+};
+/* *************** */
+/* Static Members  */
+/* *************** */
+SWFUpload.instances = {};
+SWFUpload.movieCount = 0;
+SWFUpload.version = "2.2.0 2009-03-25";
+SWFUpload.QUEUE_ERROR = {
+	QUEUE_LIMIT_EXCEEDED	  		: -100,
+	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
+	ZERO_BYTE_FILE			  		: -120,
+	INVALID_FILETYPE		  		: -130
+};
+SWFUpload.UPLOAD_ERROR = {
+	HTTP_ERROR				  		: -200,
+	MISSING_UPLOAD_URL	      		: -210,
+	IO_ERROR				  		: -220,
+	SECURITY_ERROR			  		: -230,
+	UPLOAD_LIMIT_EXCEEDED	  		: -240,
+	UPLOAD_FAILED			  		: -250,
+	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
+	FILE_VALIDATION_FAILED	  		: -270,
+	FILE_CANCELLED			  		: -280,
+	UPLOAD_STOPPED					: -290
+};
+SWFUpload.FILE_STATUS = {
+	QUEUED		 : -1,
+	IN_PROGRESS	 : -2,
+	ERROR		 : -3,
+	COMPLETE	 : -4,
+	CANCELLED	 : -5
+};
+SWFUpload.BUTTON_ACTION = {
+	SELECT_FILE  : -100,
+	SELECT_FILES : -110,
+	START_UPLOAD : -120
+};
+SWFUpload.CURSOR = {
+	ARROW : -1,
+	HAND : -2
+};
+SWFUpload.WINDOW_MODE = {
+	WINDOW : "window",
+	TRANSPARENT : "transparent",
+	OPAQUE : "opaque"
+};
+SWFUpload.completeURL = function(url) {
+	if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
+		return url;
+	}
+	var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
+	var indexSlash = window.location.pathname.lastIndexOf("/");
+	if (indexSlash <= 0) {
+		path = "/";
+	} else {
+		path = window.location.pathname.substr(0, indexSlash) + "/";
+	}
+	return /*currentURL +*/ path + url;
+};
+/* ******************** */
+/* Instance Members  */
+/* ******************** */
+SWFUpload.prototype.initSettings = function () {
+	this.ensureDefault = function (settingName, defaultValue) {
+		this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
+	};
+	this.ensureDefault("upload_url", "");
+	this.ensureDefault("preserve_relative_urls", false);
+	this.ensureDefault("file_post_name", "Filedata");
+	this.ensureDefault("post_params", {});
+	this.ensureDefault("use_query_string", false);
+	this.ensureDefault("requeue_on_error", false);
+	this.ensureDefault("http_success", []);
+	this.ensureDefault("assume_success_timeout", 0);
+	this.ensureDefault("file_types", "*.*");
+	this.ensureDefault("file_types_description", "All Files");
+	this.ensureDefault("file_size_limit", 0);
+	this.ensureDefault("file_upload_limit", 0);
+	this.ensureDefault("file_queue_limit", 0);
+	this.ensureDefault("flash_url", "swfupload.swf");
+	this.ensureDefault("prevent_swf_caching", true);
+	this.ensureDefault("button_image_url", "");
+	this.ensureDefault("button_width", 1);
+	this.ensureDefault("button_height", 1);
+	this.ensureDefault("button_text", "");
+	this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
+	this.ensureDefault("button_text_top_padding", 0);
+	this.ensureDefault("button_text_left_padding", 0);
+	this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
+	this.ensureDefault("button_disabled", false);
+	this.ensureDefault("button_placeholder_id", "");
+	this.ensureDefault("button_placeholder", null);
+	this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
+	this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
+	this.ensureDefault("debug", false);
+	this.settings.debug_enabled = this.settings.debug;
+	this.settings.return_upload_start_handler = this.returnUploadStart;
+	this.ensureDefault("swfupload_loaded_handler", null);
+	this.ensureDefault("file_dialog_start_handler", null);
+	this.ensureDefault("file_queued_handler", null);
+	this.ensureDefault("file_queue_error_handler", null);
+	this.ensureDefault("file_dialog_complete_handler", null);
+	this.ensureDefault("upload_start_handler", null);
+	this.ensureDefault("upload_progress_handler", null);
+	this.ensureDefault("upload_error_handler", null);
+	this.ensureDefault("upload_success_handler", null);
+	this.ensureDefault("upload_complete_handler", null);
+	this.ensureDefault("debug_handler", this.debugMessage);
+	this.ensureDefault("custom_settings", {});
+	this.customSettings = this.settings.custom_settings;
+	if (!!this.settings.prevent_swf_caching) {
+		this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
+	}
+	if (!this.settings.preserve_relative_urls) {
+		this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
+		this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
+	}
+	delete this.ensureDefault;
+};
+SWFUpload.prototype.loadFlash = function () {
+	var targetElement, tempParent;
+	if (document.getElementById(this.movieName) !== null) {
+		throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
+	}
+	targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
+	if (targetElement == undefined) {
+		throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
+	}
+	tempParent = document.createElement("div");
+	tempParent.innerHTML = this.getFlashHTML();
+	targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
+	if (window[this.movieName] == undefined) {
+		window[this.movieName] = this.getMovieElement();
+	}
+};
+SWFUpload.prototype.getFlashHTML = function () {
+	var classid = '';
+	if (KindEditor.IE && KindEditor.V > 8) {
+		classid = ' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"';
+	}
+	return ['<object id="', this.movieName, '"' + classid + ' type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
+				'<param name="wmode" value="', this.settings.button_window_mode, '" />',
+				'<param name="movie" value="', this.settings.flash_url, '" />',
+				'<param name="quality" value="high" />',
+				'<param name="menu" value="false" />',
+				'<param name="allowScriptAccess" value="always" />',
+				'<param name="flashvars" value="' + this.getFlashVars() + '" />',
+				'</object>'].join("");
+};
+SWFUpload.prototype.getFlashVars = function () {
+	var paramString = this.buildParamString();
+	var httpSuccessString = this.settings.http_success.join(",");
+	return ["movieName=", encodeURIComponent(this.movieName),
+			"&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
+			"&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
+			"&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
+			"&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
+			"&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
+			"&amp;params=", encodeURIComponent(paramString),
+			"&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
+			"&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
+			"&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
+			"&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
+			"&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
+			"&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
+			"&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
+			"&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
+			"&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
+			"&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
+			"&amp;buttonText=", encodeURIComponent(this.settings.button_text),
+			"&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
+			"&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
+			"&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
+			"&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
+			"&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
+			"&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
+		].join("");
+};
+SWFUpload.prototype.getMovieElement = function () {
+	if (this.movieElement == undefined) {
+		this.movieElement = document.getElementById(this.movieName);
+	}
+	if (this.movieElement === null) {
+		throw "Could not find Flash element";
+	}
+	return this.movieElement;
+};
+SWFUpload.prototype.buildParamString = function () {
+	var postParams = this.settings.post_params;
+	var paramStringPairs = [];
+	if (typeof(postParams) === "object") {
+		for (var name in postParams) {
+			if (postParams.hasOwnProperty(name)) {
+				paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
+			}
+		}
+	}
+	return paramStringPairs.join("&amp;");
+};
+SWFUpload.prototype.destroy = function () {
+	try {
+		this.cancelUpload(null, false);
+		var movieElement = null;
+		movieElement = this.getMovieElement();
+		if (movieElement && typeof(movieElement.CallFunction) === "unknown") {
+			for (var i in movieElement) {
+				try {
+					if (typeof(movieElement[i]) === "function") {
+						movieElement[i] = null;
+					}
+				} catch (ex1) {}
+			}
+			try {
+				movieElement.parentNode.removeChild(movieElement);
+			} catch (ex) {}
+		}
+		window[this.movieName] = null;
+		SWFUpload.instances[this.movieName] = null;
+		delete SWFUpload.instances[this.movieName];
+		this.movieElement = null;
+		this.settings = null;
+		this.customSettings = null;
+		this.eventQueue = null;
+		this.movieName = null;
+		return true;
+	} catch (ex2) {
+		return false;
+	}
+};
+SWFUpload.prototype.displayDebugInfo = function () {
+	this.debug(
+		[
+			"---SWFUpload Instance Info---\n",
+			"Version: ", SWFUpload.version, "\n",
+			"Movie Name: ", this.movieName, "\n",
+			"Settings:\n",
+			"\t", "upload_url:               ", this.settings.upload_url, "\n",
+			"\t", "flash_url:                ", this.settings.flash_url, "\n",
+			"\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
+			"\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
+			"\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
+			"\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
+			"\t", "file_post_name:           ", this.settings.file_post_name, "\n",
+			"\t", "post_params:              ", this.settings.post_params.toString(), "\n",
+			"\t", "file_types:               ", this.settings.file_types, "\n",
+			"\t", "file_types_description:   ", this.settings.file_types_description, "\n",
+			"\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
+			"\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
+			"\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
+			"\t", "debug:                    ", this.settings.debug.toString(), "\n",
+			"\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",
+			"\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
+			"\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
+			"\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
+			"\t", "button_width:             ", this.settings.button_width.toString(), "\n",
+			"\t", "button_height:            ", this.settings.button_height.toString(), "\n",
+			"\t", "button_text:              ", this.settings.button_text.toString(), "\n",
+			"\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
+			"\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
+			"\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
+			"\t", "button_action:            ", this.settings.button_action.toString(), "\n",
+			"\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",
+			"\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
+			"Event Handlers:\n",
+			"\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
+			"\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
+			"\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
+			"\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
+			"\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
+			"\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
+			"\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
+			"\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
+			"\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
+			"\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
+		].join("")
+	);
+};
+/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
+	the maintain v2 API compatibility
+*/
+SWFUpload.prototype.addSetting = function (name, value, default_value) {
+    if (value == undefined) {
+        return (this.settings[name] = default_value);
+    } else {
+        return (this.settings[name] = value);
+	}
+};
+SWFUpload.prototype.getSetting = function (name) {
+    if (this.settings[name] != undefined) {
+        return this.settings[name];
+	}
+    return "";
+};
+SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
+	argumentArray = argumentArray || [];
+	var movieElement = this.getMovieElement();
+	var returnValue, returnString;
+	try {
+		returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
+		returnValue = eval(returnString);
+	} catch (ex) {
+		throw "Call to " + functionName + " failed";
+	}
+	if (returnValue != undefined && typeof returnValue.post === "object") {
+		returnValue = this.unescapeFilePostParams(returnValue);
+	}
+	return returnValue;
+};
+/* *****************************
+	-- Flash control methods --
+	Your UI should use these
+	to operate SWFUpload
+   ***************************** */
+SWFUpload.prototype.selectFile = function () {
+	this.callFlash("SelectFile");
+};
+SWFUpload.prototype.selectFiles = function () {
+	this.callFlash("SelectFiles");
+};
+SWFUpload.prototype.startUpload = function (fileID) {
+	this.callFlash("StartUpload", [fileID]);
+};
+SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
+	if (triggerErrorEvent !== false) {
+		triggerErrorEvent = true;
+	}
+	this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
+};
+SWFUpload.prototype.stopUpload = function () {
+	this.callFlash("StopUpload");
+};
+/* ************************
+ * Settings methods
+ *   These methods change the SWFUpload settings.
+ *   SWFUpload settings should not be changed directly on the settings object
+ *   since many of the settings need to be passed to Flash in order to take
+ *   effect.
+ * *********************** */
+SWFUpload.prototype.getStats = function () {
+	return this.callFlash("GetStats");
+};
+SWFUpload.prototype.setStats = function (statsObject) {
+	this.callFlash("SetStats", [statsObject]);
+};
+SWFUpload.prototype.getFile = function (fileID) {
+	if (typeof(fileID) === "number") {
+		return this.callFlash("GetFileByIndex", [fileID]);
+	} else {
+		return this.callFlash("GetFile", [fileID]);
+	}
+};
+SWFUpload.prototype.addFileParam = function (fileID, name, value) {
+	return this.callFlash("AddFileParam", [fileID, name, value]);
+};
+SWFUpload.prototype.removeFileParam = function (fileID, name) {
+	this.callFlash("RemoveFileParam", [fileID, name]);
+};
+SWFUpload.prototype.setUploadURL = function (url) {
+	this.settings.upload_url = url.toString();
+	this.callFlash("SetUploadURL", [url]);
+};
+SWFUpload.prototype.setPostParams = function (paramsObject) {
+	this.settings.post_params = paramsObject;
+	this.callFlash("SetPostParams", [paramsObject]);
+};
+SWFUpload.prototype.addPostParam = function (name, value) {
+	this.settings.post_params[name] = value;
+	this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+SWFUpload.prototype.removePostParam = function (name) {
+	delete this.settings.post_params[name];
+	this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+SWFUpload.prototype.setFileTypes = function (types, description) {
+	this.settings.file_types = types;
+	this.settings.file_types_description = description;
+	this.callFlash("SetFileTypes", [types, description]);
+};
+SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
+	this.settings.file_size_limit = fileSizeLimit;
+	this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
+};
+SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
+	this.settings.file_upload_limit = fileUploadLimit;
+	this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
+};
+SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
+	this.settings.file_queue_limit = fileQueueLimit;
+	this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
+};
+SWFUpload.prototype.setFilePostName = function (filePostName) {
+	this.settings.file_post_name = filePostName;
+	this.callFlash("SetFilePostName", [filePostName]);
+};
+SWFUpload.prototype.setUseQueryString = function (useQueryString) {
+	this.settings.use_query_string = useQueryString;
+	this.callFlash("SetUseQueryString", [useQueryString]);
+};
+SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
+	this.settings.requeue_on_error = requeueOnError;
+	this.callFlash("SetRequeueOnError", [requeueOnError]);
+};
+SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
+	if (typeof http_status_codes === "string") {
+		http_status_codes = http_status_codes.replace(" ", "").split(",");
+	}
+	this.settings.http_success = http_status_codes;
+	this.callFlash("SetHTTPSuccess", [http_status_codes]);
+};
+SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
+	this.settings.assume_success_timeout = timeout_seconds;
+	this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
+};
+SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
+	this.settings.debug_enabled = debugEnabled;
+	this.callFlash("SetDebugEnabled", [debugEnabled]);
+};
+SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
+	if (buttonImageURL == undefined) {
+		buttonImageURL = "";
+	}
+	this.settings.button_image_url = buttonImageURL;
+	this.callFlash("SetButtonImageURL", [buttonImageURL]);
+};
+SWFUpload.prototype.setButtonDimensions = function (width, height) {
+	this.settings.button_width = width;
+	this.settings.button_height = height;
+	var movie = this.getMovieElement();
+	if (movie != undefined) {
+		movie.style.width = width + "px";
+		movie.style.height = height + "px";
+	}
+	this.callFlash("SetButtonDimensions", [width, height]);
+};
+SWFUpload.prototype.setButtonText = function (html) {
+	this.settings.button_text = html;
+	this.callFlash("SetButtonText", [html]);
+};
+SWFUpload.prototype.setButtonTextPadding = function (left, top) {
+	this.settings.button_text_top_padding = top;
+	this.settings.button_text_left_padding = left;
+	this.callFlash("SetButtonTextPadding", [left, top]);
+};
+SWFUpload.prototype.setButtonTextStyle = function (css) {
+	this.settings.button_text_style = css;
+	this.callFlash("SetButtonTextStyle", [css]);
+};
+SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
+	this.settings.button_disabled = isDisabled;
+	this.callFlash("SetButtonDisabled", [isDisabled]);
+};
+SWFUpload.prototype.setButtonAction = function (buttonAction) {
+	this.settings.button_action = buttonAction;
+	this.callFlash("SetButtonAction", [buttonAction]);
+};
+SWFUpload.prototype.setButtonCursor = function (cursor) {
+	this.settings.button_cursor = cursor;
+	this.callFlash("SetButtonCursor", [cursor]);
+};
+/* *******************************
+	Flash Event Interfaces
+	These functions are used by Flash to trigger the various
+	events.
+	All these functions a Private.
+	Because the ExternalInterface library is buggy the event calls
+	are added to a queue and the queue then executed by a setTimeout.
+	This ensures that events are executed in a determinate order and that
+	the ExternalInterface bugs are avoided.
+******************************* */
+SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
+	if (argumentArray == undefined) {
+		argumentArray = [];
+	} else if (!(argumentArray instanceof Array)) {
+		argumentArray = [argumentArray];
+	}
+	var self = this;
+	if (typeof this.settings[handlerName] === "function") {
+		this.eventQueue.push(function () {
+			this.settings[handlerName].apply(this, argumentArray);
+		});
+		setTimeout(function () {
+			self.executeNextEvent();
+		}, 0);
+	} else if (this.settings[handlerName] !== null) {
+		throw "Event handler " + handlerName + " is unknown or is not a function";
+	}
+};
+SWFUpload.prototype.executeNextEvent = function () {
+	var  f = this.eventQueue ? this.eventQueue.shift() : null;
+	if (typeof(f) === "function") {
+		f.apply(this);
+	}
+};
+SWFUpload.prototype.unescapeFilePostParams = function (file) {
+	var reg = /[$]([0-9a-f]{4})/i;
+	var unescapedPost = {};
+	var uk;
+	if (file != undefined) {
+		for (var k in file.post) {
+			if (file.post.hasOwnProperty(k)) {
+				uk = k;
+				var match;
+				while ((match = reg.exec(uk)) !== null) {
+					uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
+				}
+				unescapedPost[uk] = file.post[k];
+			}
+		}
+		file.post = unescapedPost;
+	}
+	return file;
+};
+SWFUpload.prototype.testExternalInterface = function () {
+	try {
+		return this.callFlash("TestExternalInterface");
+	} catch (ex) {
+		return false;
+	}
+};
+SWFUpload.prototype.flashReady = function () {
+	var movieElement = this.getMovieElement();
+	if (!movieElement) {
+		this.debug("Flash called back ready but the flash movie can't be found.");
+		return;
+	}
+	this.cleanUp(movieElement);
+	this.queueEvent("swfupload_loaded_handler");
+};
+SWFUpload.prototype.cleanUp = function (movieElement) {
+	try {
+		if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") {
+			this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
+			for (var key in movieElement) {
+				try {
+					if (typeof(movieElement[key]) === "function") {
+						movieElement[key] = null;
+					}
+				} catch (ex) {
+				}
+			}
+		}
+	} catch (ex1) {
+	}
+	window["__flash__removeCallback"] = function (instance, name) {
+		try {
+			if (instance) {
+				instance[name] = null;
+			}
+		} catch (flashEx) {
+		}
+	};
+};
+/* This is a chance to do something before the browse window opens */
+SWFUpload.prototype.fileDialogStart = function () {
+	this.queueEvent("file_dialog_start_handler");
+};
+/* Called when a file is successfully added to the queue. */
+SWFUpload.prototype.fileQueued = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("file_queued_handler", file);
+};
+/* Handle errors that occur when an attempt to queue a file fails. */
+SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
+};
+/* Called after the file dialog has closed and the selected files have been queued.
+	You could call startUpload here if you want the queued files to begin uploading immediately. */
+SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
+	this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
+};
+SWFUpload.prototype.uploadStart = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("return_upload_start_handler", file);
+};
+SWFUpload.prototype.returnUploadStart = function (file) {
+	var returnValue;
+	if (typeof this.settings.upload_start_handler === "function") {
+		file = this.unescapeFilePostParams(file);
+		returnValue = this.settings.upload_start_handler.call(this, file);
+	} else if (this.settings.upload_start_handler != undefined) {
+		throw "upload_start_handler must be a function";
+	}
+	if (returnValue === undefined) {
+		returnValue = true;
+	}
+	returnValue = !!returnValue;
+	this.callFlash("ReturnUploadStart", [returnValue]);
+};
+SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
+};
+SWFUpload.prototype.uploadError = function (file, errorCode, message) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_error_handler", [file, errorCode, message]);
+};
+SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
+};
+SWFUpload.prototype.uploadComplete = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_complete_handler", file);
+};
+/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
+   internal debug console.  You can override this event and have messages written where you want. */
+SWFUpload.prototype.debug = function (message) {
+	this.queueEvent("debug_handler", message);
+};
+/* **********************************
+	Debug Console
+	The debug console is a self contained, in page location
+	for debug message to be sent.  The Debug Console adds
+	itself to the body if necessary.
+	The console is automatically scrolled as messages appear.
+	If you are using your own debug handler or when you deploy to production and
+	have debug disabled you can remove these functions to reduce the file size
+	and complexity.
+********************************** */
+SWFUpload.prototype.debugMessage = function (message) {
+	if (this.settings.debug) {
+		var exceptionMessage, exceptionValues = [];
+		if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
+			for (var key in message) {
+				if (message.hasOwnProperty(key)) {
+					exceptionValues.push(key + ": " + message[key]);
+				}
+			}
+			exceptionMessage = exceptionValues.join("\n") || "";
+			exceptionValues = exceptionMessage.split("\n");
+			exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
+			SWFUpload.Console.writeLine(exceptionMessage);
+		} else {
+			SWFUpload.Console.writeLine(message);
+		}
+	}
+};
+SWFUpload.Console = {};
+SWFUpload.Console.writeLine = function (message) {
+	var console, documentForm;
+	try {
+		console = document.getElementById("SWFUpload_Console");
+		if (!console) {
+			documentForm = document.createElement("form");
+			document.getElementsByTagName("body")[0].appendChild(documentForm);
+			console = document.createElement("textarea");
+			console.id = "SWFUpload_Console";
+			console.style.fontFamily = "monospace";
+			console.setAttribute("wrap", "off");
+			console.wrap = "off";
+			console.style.overflow = "auto";
+			console.style.width = "700px";
+			console.style.height = "350px";
+			console.style.margin = "5px";
+			documentForm.appendChild(console);
+		}
+		console.value += message + "\n";
+		console.scrollTop = console.scrollHeight - console.clientHeight;
+	} catch (ex) {
+		alert("Exception: " + ex.name + " Message: " + ex.message);
+	}
+};
+})();
+(function() {
+/*
+	Queue Plug-in
+	Features:
+		*Adds a cancelQueue() method for cancelling the entire queue.
+		*All queued files are uploaded when startUpload() is called.
+		*If false is returned from uploadComplete then the queue upload is stopped.
+		 If false is not returned (strict comparison) then the queue upload is continued.
+		*Adds a QueueComplete event that is fired when all the queued files have finished uploading.
+		 Set the event handler with the queue_complete_handler setting.
+	*/
+if (typeof(SWFUpload) === "function") {
+	SWFUpload.queue = {};
+	SWFUpload.prototype.initSettings = (function (oldInitSettings) {
+		return function () {
+			if (typeof(oldInitSettings) === "function") {
+				oldInitSettings.call(this);
+			}
+			this.queueSettings = {};
+			this.queueSettings.queue_cancelled_flag = false;
+			this.queueSettings.queue_upload_count = 0;
+			this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
+			this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
+			this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
+			this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
+			this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
+		};
+	})(SWFUpload.prototype.initSettings);
+	SWFUpload.prototype.startUpload = function (fileID) {
+		this.queueSettings.queue_cancelled_flag = false;
+		this.callFlash("StartUpload", [fileID]);
+	};
+	SWFUpload.prototype.cancelQueue = function () {
+		this.queueSettings.queue_cancelled_flag = true;
+		this.stopUpload();
+		var stats = this.getStats();
+		while (stats.files_queued > 0) {
+			this.cancelUpload();
+			stats = this.getStats();
+		}
+	};
+	SWFUpload.queue.uploadStartHandler = function (file) {
+		var returnValue;
+		if (typeof(this.queueSettings.user_upload_start_handler) === "function") {
+			returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
+		}
+		returnValue = (returnValue === false) ? false : true;
+		this.queueSettings.queue_cancelled_flag = !returnValue;
+		return returnValue;
+	};
+	SWFUpload.queue.uploadCompleteHandler = function (file) {
+		var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
+		var continueUpload;
+		if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
+			this.queueSettings.queue_upload_count++;
+		}
+		if (typeof(user_upload_complete_handler) === "function") {
+			continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
+		} else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
+			continueUpload = false;
+		} else {
+			continueUpload = true;
+		}
+		if (continueUpload) {
+			var stats = this.getStats();
+			if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
+				this.startUpload();
+			} else if (this.queueSettings.queue_cancelled_flag === false) {
+				this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]);
+				this.queueSettings.queue_upload_count = 0;
+			} else {
+				this.queueSettings.queue_cancelled_flag = false;
+				this.queueSettings.queue_upload_count = 0;
+			}
+		}
+	};
+}
+})();
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('pagebreak', function(K) {
+	var self = this;
+	var name = 'pagebreak';
+	var pagebreakHtml = K.undef(self.pagebreakHtml, '<hr style="page-break-after: always;" class="ke-pagebreak" />');
+	self.clickToolbar(name, function() {
+		var cmd = self.cmd, range = cmd.range;
+		self.focus();
+		var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : '<span id="__kindeditor_tail_tag__"></span>';
+		self.insertHtml(pagebreakHtml + tail);
+		if (tail !== '') {
+			var p = K('#__kindeditor_tail_tag__', self.edit.doc);
+			range.selectNodeContents(p[0]);
+			p.removeAttr('id');
+			cmd.select();
+		}
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('plainpaste', function(K) {
+	var self = this, name = 'plainpaste';
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			html = '<div style="padding:10px 20px;">' +
+				'<div style="margin-bottom:10px;">' + lang.comment + '</div>' +
+				'<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>' +
+				'</div>',
+			dialog = self.createDialog({
+				name : name,
+				width : 450,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var html = textarea.val();
+						html = K.escape(html);
+						html = html.replace(/ {2}/g, ' &nbsp;');
+						if (self.newlineTag == 'p') {
+							html = html.replace(/^/, '<p>').replace(/$/, '</p>').replace(/\n/g, '</p><p>');
+						} else {
+							html = html.replace(/\n/g, '<br />$&');
+						}
+						self.insertHtml(html).hideDialog().focus();
+					}
+				}
+			}),
+			textarea = K('textarea', dialog.div);
+		textarea[0].focus();
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('preview', function(K) {
+	var self = this, name = 'preview', undefined;
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			html = '<div style="padding:10px 20px;">' +
+				'<iframe class="ke-textarea" frameborder="0" style="width:708px;height:400px;"></iframe>' +
+				'</div>',
+			dialog = self.createDialog({
+				name : name,
+				width : 750,
+				title : self.lang(name),
+				body : html
+			}),
+			iframe = K('iframe', dialog.div),
+			doc = K.iframeDoc(iframe);
+		doc.open();
+		doc.write(self.fullHtml());
+		doc.close();
+		K(doc.body).css('background-color', '#FFF');
+		iframe[0].contentWindow.focus();
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('quickformat', function(K) {
+	var self = this, name = 'quickformat',
+		blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p');
+	function getFirstChild(knode) {
+		var child = knode.first();
+		while (child && child.first()) {
+			child = child.first();
+		}
+		return child;
+	}
+	self.clickToolbar(name, function() {
+		self.focus();
+		var doc = self.edit.doc,
+			range = self.cmd.range,
+			child = K(doc.body).first(), next,
+			nodeList = [], subList = [],
+			bookmark = range.createBookmark(true);
+		while(child) {
+			next = child.next();
+			var firstChild = getFirstChild(child);
+			if (!firstChild || firstChild.name != 'img') {
+				if (blockMap[child.name]) {
+					child.html(child.html().replace(/^(\s|&nbsp;| )+/ig, ''));
+					child.css('text-indent', '2em');
+				} else {
+					subList.push(child);
+				}
+				if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) {
+					if (subList.length > 0) {
+						nodeList.push(subList);
+					}
+					subList = [];
+				}
+			}
+			child = next;
+		}
+		K.each(nodeList, function(i, subList) {
+			var wrapper = K('<p style="text-indent:2em;"></p>', doc);
+			subList[0].before(wrapper);
+			K.each(subList, function(i, knode) {
+				wrapper.append(knode);
+			});
+		});
+		range.moveToBookmark(bookmark);
+		self.addBookmark();
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('table', function(K) {
+	var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder';
+	function _setColor(box, color) {
+		color = color.toUpperCase();
+		box.css('background-color', color);
+		box.css('color', color === '#000000' ? '#FFFFFF' : '#000000');
+		box.html(color);
+	}
+	var pickerList = [];
+	function _initColorPicker(dialogDiv, colorBox) {
+		colorBox.bind('click,mousedown', function(e){
+			e.stopPropagation();
+		});
+		function removePicker() {
+			K.each(pickerList, function() {
+				this.remove();
+			});
+			pickerList = [];
+			K(document).unbind('click,mousedown', removePicker);
+			dialogDiv.unbind('click,mousedown', removePicker);
+		}
+		colorBox.click(function(e) {
+			removePicker();
+			var box = K(this),
+				pos = box.pos();
+			var picker = K.colorpicker({
+				x : pos.x,
+				y : pos.y + box.height(),
+				z : 811214,
+				selectedColor : K(this).html(),
+				colors : self.colorTable,
+				noColor : self.lang('noColor'),
+				shadowMode : self.shadowMode,
+				click : function(color) {
+					_setColor(box, color);
+					removePicker();
+				}
+			});
+			pickerList.push(picker);
+			K(document).bind('click,mousedown', removePicker);
+			dialogDiv.bind('click,mousedown', removePicker);
+		});
+	}
+	function _getCellIndex(table, row, cell) {
+		var rowSpanCount = 0;
+		for (var i = 0, len = row.cells.length; i < len; i++) {
+			if (row.cells[i] == cell) {
+				break;
+			}
+			rowSpanCount += row.cells[i].rowSpan - 1;
+		}
+		return cell.cellIndex - rowSpanCount;
+	}
+	self.plugin.table = {
+		prop : function(isInsert) {
+			var html = [
+				'<div style="padding:20px;">',
+				'<div class="ke-dialog-row">',
+				'<label for="keRows" style="width:90px;">' + lang.cells + '</label>',
+				lang.rows + ' <input type="text" id="keRows" class="ke-input-text ke-input-number" name="rows" value="" maxlength="4" /> &nbsp; ',
+				lang.cols + ' <input type="text" class="ke-input-text ke-input-number" name="cols" value="" maxlength="4" />',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keWidth" style="width:90px;">' + lang.size + '</label>',
+				lang.width + ' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ',
+				'<select name="widthType">',
+				'<option value="%">' + lang.percent + '</option>',
+				'<option value="px">' + lang.px + '</option>',
+				'</select> &nbsp; ',
+				lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ',
+				'<select name="heightType">',
+				'<option value="%">' + lang.percent + '</option>',
+				'<option value="px">' + lang.px + '</option>',
+				'</select>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="kePadding" style="width:90px;">' + lang.space + '</label>',
+				lang.padding + ' <input type="text" id="kePadding" class="ke-input-text ke-input-number" name="padding" value="" maxlength="4" /> &nbsp; ',
+				lang.spacing + ' <input type="text" class="ke-input-text ke-input-number" name="spacing" value="" maxlength="4" />',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keAlign" style="width:90px;">' + lang.align + '</label>',
+				'<select id="keAlign" name="align">',
+				'<option value="">' + lang.alignDefault + '</option>',
+				'<option value="left">' + lang.alignLeft + '</option>',
+				'<option value="center">' + lang.alignCenter + '</option>',
+				'<option value="right">' + lang.alignRight + '</option>',
+				'</select>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keBorder" style="width:90px;">' + lang.border + '</label>',
+				lang.borderWidth + ' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ',
+				lang.borderColor + ' <span class="ke-inline-block ke-input-color"></span>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keBgColor" style="width:90px;">' + lang.backgroundColor + '</label>',
+				'<span class="ke-inline-block ke-input-color"></span>',
+				'</div>',
+				'</div>'
+			].join('');
+			var bookmark = self.cmd.range.createBookmark();
+			var dialog = self.createDialog({
+				name : name,
+				width : 500,
+				title : self.lang(name),
+				body : html,
+				beforeRemove : function() {
+					colorBox.unbind();
+				},
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var rows = rowsBox.val(),
+							cols = colsBox.val(),
+							width = widthBox.val(),
+							height = heightBox.val(),
+							widthType = widthTypeBox.val(),
+							heightType = heightTypeBox.val(),
+							padding = paddingBox.val(),
+							spacing = spacingBox.val(),
+							align = alignBox.val(),
+							border = borderBox.val(),
+							borderColor = K(colorBox[0]).html() || '',
+							bgColor = K(colorBox[1]).html() || '';
+						if (rows == 0 || !/^\d+$/.test(rows)) {
+							alert(self.lang('invalidRows'));
+							rowsBox[0].focus();
+							return;
+						}
+						if (cols == 0 || !/^\d+$/.test(cols)) {
+							alert(self.lang('invalidRows'));
+							colsBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(width)) {
+							alert(self.lang('invalidWidth'));
+							widthBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(height)) {
+							alert(self.lang('invalidHeight'));
+							heightBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(padding)) {
+							alert(self.lang('invalidPadding'));
+							paddingBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(spacing)) {
+							alert(self.lang('invalidSpacing'));
+							spacingBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(border)) {
+							alert(self.lang('invalidBorder'));
+							borderBox[0].focus();
+							return;
+						}
+						if (table) {
+							if (width !== '') {
+								table.width(width + widthType);
+							} else {
+								table.css('width', '');
+							}
+							if (table[0].width !== undefined) {
+								table.removeAttr('width');
+							}
+							if (height !== '') {
+								table.height(height + heightType);
+							} else {
+								table.css('height', '');
+							}
+							if (table[0].height !== undefined) {
+								table.removeAttr('height');
+							}
+							table.css('background-color', bgColor);
+							if (table[0].bgColor !== undefined) {
+								table.removeAttr('bgColor');
+							}
+							if (padding !== '') {
+								table[0].cellPadding = padding;
+							} else {
+								table.removeAttr('cellPadding');
+							}
+							if (spacing !== '') {
+								table[0].cellSpacing = spacing;
+							} else {
+								table.removeAttr('cellSpacing');
+							}
+							if (align !== '') {
+								table[0].align = align;
+							} else {
+								table.removeAttr('align');
+							}
+							if (border !== '') {
+								table.attr('border', border);
+							} else {
+								table.removeAttr('border');
+							}
+							if (border === '' || border === '0') {
+								table.addClass(zeroborder);
+							} else {
+								table.removeClass(zeroborder);
+							}
+							if (borderColor !== '') {
+								table.attr('borderColor', borderColor);
+							} else {
+								table.removeAttr('borderColor');
+							}
+							self.hideDialog().focus();
+							self.cmd.range.moveToBookmark(bookmark);
+							self.cmd.select();
+							self.addBookmark();
+							return;
+						}
+						var style = '';
+						if (width !== '') {
+							style += 'width:' + width + widthType + ';';
+						}
+						if (height !== '') {
+							style += 'height:' + height + heightType + ';';
+						}
+						if (bgColor !== '') {
+							style += 'background-color:' + bgColor + ';';
+						}
+						var html = '<table';
+						if (style !== '') {
+							html += ' style="' + style + '"';
+						}
+						if (padding !== '') {
+							html += ' cellpadding="' + padding + '"';
+						}
+						if (spacing !== '') {
+							html += ' cellspacing="' + spacing + '"';
+						}
+						if (align !== '') {
+							html += ' align="' + align + '"';
+						}
+						if (border !== '') {
+							html += ' border="' + border + '"';
+						}
+						if (border === '' || border === '0') {
+							html += ' class="' + zeroborder + '"';
+						}
+						if (borderColor !== '') {
+							html += ' bordercolor="' + borderColor + '"';
+						}
+						html += '>';
+						for (var i = 0; i < rows; i++) {
+							html += '<tr>';
+							for (var j = 0; j < cols; j++) {
+								html += '<td>' + (K.IE ? '&nbsp;' : '<br />') + '</td>';
+							}
+							html += '</tr>';
+						}
+						html += '</table>';
+						if (!K.IE) {
+							html += '<br />';
+						}
+						self.insertHtml(html);
+						self.select().hideDialog().focus();
+						self.addBookmark();
+					}
+				}
+			}),
+			div = dialog.div,
+			rowsBox = K('[name="rows"]', div).val(3),
+			colsBox = K('[name="cols"]', div).val(2),
+			widthBox = K('[name="width"]', div).val(100),
+			heightBox = K('[name="height"]', div),
+			widthTypeBox = K('[name="widthType"]', div),
+			heightTypeBox = K('[name="heightType"]', div),
+			paddingBox = K('[name="padding"]', div).val(2),
+			spacingBox = K('[name="spacing"]', div).val(0),
+			alignBox = K('[name="align"]', div),
+			borderBox = K('[name="border"]', div).val(1),
+			colorBox = K('.ke-input-color', div);
+			_initColorPicker(div, colorBox.eq(0));
+			_initColorPicker(div, colorBox.eq(1));
+			_setColor(colorBox.eq(0), '#000000');
+			_setColor(colorBox.eq(1), '');
+			rowsBox[0].focus();
+			rowsBox[0].select();
+			var table;
+			if (isInsert) {
+				return;
+			}
+			table = self.plugin.getSelectedTable();
+			if (table) {
+				rowsBox.val(table[0].rows.length);
+				colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0);
+				rowsBox.attr('disabled', true);
+				colsBox.attr('disabled', true);
+				var match,
+					tableWidth = table[0].style.width || table[0].width,
+					tableHeight = table[0].style.height || table[0].height;
+				if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) {
+					widthBox.val(match[1]);
+					widthTypeBox.val(match[2]);
+				} else {
+					widthBox.val('');
+				}
+				if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) {
+					heightBox.val(match[1]);
+					heightTypeBox.val(match[2]);
+				}
+				paddingBox.val(table[0].cellPadding || '');
+				spacingBox.val(table[0].cellSpacing || '');
+				alignBox.val(table[0].align || '');
+				borderBox.val(table[0].border === undefined ? '' : table[0].border);
+				_setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || ''));
+				_setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || ''));
+				widthBox[0].focus();
+				widthBox[0].select();
+			}
+		},
+		cellprop : function() {
+			var html = [
+				'<div style="padding:20px;">',
+				'<div class="ke-dialog-row">',
+				'<label for="keWidth" style="width:90px;">' + lang.size + '</label>',
+				lang.width + ' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ',
+				'<select name="widthType">',
+				'<option value="%">' + lang.percent + '</option>',
+				'<option value="px">' + lang.px + '</option>',
+				'</select> &nbsp; ',
+				lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ',
+				'<select name="heightType">',
+				'<option value="%">' + lang.percent + '</option>',
+				'<option value="px">' + lang.px + '</option>',
+				'</select>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keAlign" style="width:90px;">' + lang.align + '</label>',
+				lang.textAlign + ' <select id="keAlign" name="textAlign">',
+				'<option value="">' + lang.alignDefault + '</option>',
+				'<option value="left">' + lang.alignLeft + '</option>',
+				'<option value="center">' + lang.alignCenter + '</option>',
+				'<option value="right">' + lang.alignRight + '</option>',
+				'</select> ',
+				lang.verticalAlign + ' <select name="verticalAlign">',
+				'<option value="">' + lang.alignDefault + '</option>',
+				'<option value="top">' + lang.alignTop + '</option>',
+				'<option value="middle">' + lang.alignMiddle + '</option>',
+				'<option value="bottom">' + lang.alignBottom + '</option>',
+				'<option value="baseline">' + lang.alignBaseline + '</option>',
+				'</select>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keBorder" style="width:90px;">' + lang.border + '</label>',
+				lang.borderWidth + ' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ',
+				lang.borderColor + ' <span class="ke-inline-block ke-input-color"></span>',
+				'</div>',
+				'<div class="ke-dialog-row">',
+				'<label for="keBgColor" style="width:90px;">' + lang.backgroundColor + '</label>',
+				'<span class="ke-inline-block ke-input-color"></span>',
+				'</div>',
+				'</div>'
+			].join('');
+			var bookmark = self.cmd.range.createBookmark();
+			var dialog = self.createDialog({
+				name : name,
+				width : 500,
+				title : self.lang('tablecell'),
+				body : html,
+				beforeRemove : function() {
+					colorBox.unbind();
+				},
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var width = widthBox.val(),
+							height = heightBox.val(),
+							widthType = widthTypeBox.val(),
+							heightType = heightTypeBox.val(),
+							padding = paddingBox.val(),
+							spacing = spacingBox.val(),
+							textAlign = textAlignBox.val(),
+							verticalAlign = verticalAlignBox.val(),
+							border = borderBox.val(),
+							borderColor = K(colorBox[0]).html() || '',
+							bgColor = K(colorBox[1]).html() || '';
+						if (!/^\d*$/.test(width)) {
+							alert(self.lang('invalidWidth'));
+							widthBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(height)) {
+							alert(self.lang('invalidHeight'));
+							heightBox[0].focus();
+							return;
+						}
+						if (!/^\d*$/.test(border)) {
+							alert(self.lang('invalidBorder'));
+							borderBox[0].focus();
+							return;
+						}
+						cell.css({
+							width : width !== '' ? (width + widthType) : '',
+							height : height !== '' ? (height + heightType) : '',
+							'background-color' : bgColor,
+							'text-align' : textAlign,
+							'vertical-align' : verticalAlign,
+							'border-width' : border,
+							'border-style' : border !== '' ? 'solid' : '',
+							'border-color' : borderColor
+						});
+						self.hideDialog().focus();
+						self.cmd.range.moveToBookmark(bookmark);
+						self.cmd.select();
+						self.addBookmark();
+					}
+				}
+			}),
+			div = dialog.div,
+			widthBox = K('[name="width"]', div).val(100),
+			heightBox = K('[name="height"]', div),
+			widthTypeBox = K('[name="widthType"]', div),
+			heightTypeBox = K('[name="heightType"]', div),
+			paddingBox = K('[name="padding"]', div).val(2),
+			spacingBox = K('[name="spacing"]', div).val(0),
+			textAlignBox = K('[name="textAlign"]', div),
+			verticalAlignBox = K('[name="verticalAlign"]', div),
+			borderBox = K('[name="border"]', div).val(1),
+			colorBox = K('.ke-input-color', div);
+			_initColorPicker(div, colorBox.eq(0));
+			_initColorPicker(div, colorBox.eq(1));
+			_setColor(colorBox.eq(0), '#000000');
+			_setColor(colorBox.eq(1), '');
+			widthBox[0].focus();
+			widthBox[0].select();
+			var cell = self.plugin.getSelectedCell();
+			var match,
+				cellWidth = cell[0].style.width || cell[0].width || '',
+				cellHeight = cell[0].style.height || cell[0].height || '';
+			if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) {
+				widthBox.val(match[1]);
+				widthTypeBox.val(match[2]);
+			} else {
+				widthBox.val('');
+			}
+			if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) {
+				heightBox.val(match[1]);
+				heightTypeBox.val(match[2]);
+			}
+			textAlignBox.val(cell[0].style.textAlign || '');
+			verticalAlignBox.val(cell[0].style.verticalAlign || '');
+			var border = cell[0].style.borderWidth || '';
+			if (border) {
+				border = parseInt(border);
+			}
+			borderBox.val(border);
+			_setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || ''));
+			_setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || ''));
+			widthBox[0].focus();
+			widthBox[0].select();
+		},
+		insert : function() {
+			this.prop(true);
+		},
+		'delete' : function() {
+			var table = self.plugin.getSelectedTable();
+			self.cmd.range.setStartBefore(table[0]).collapse(true);
+			self.cmd.select();
+			table.remove();
+			self.addBookmark();
+		},
+		colinsert : function(offset) {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				index = cell.cellIndex + offset;
+			index += table.rows[0].cells.length - row.cells.length;
+			for (var i = 0, len = table.rows.length; i < len; i++) {
+				var newRow = table.rows[i],
+					newCell = newRow.insertCell(index);
+				newCell.innerHTML = K.IE ? '' : '<br />';
+				index = _getCellIndex(table, newRow, newCell);
+			}
+			self.cmd.range.selectNodeContents(cell).collapse(true);
+			self.cmd.select();
+			self.addBookmark();
+		},
+		colinsertleft : function() {
+			this.colinsert(0);
+		},
+		colinsertright : function() {
+			this.colinsert(1);
+		},
+		rowinsert : function(offset) {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0];
+			var rowIndex = row.rowIndex;
+			if (offset === 1) {
+				rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset;
+			}
+			var newRow = table.insertRow(rowIndex);
+			for (var i = 0, len = row.cells.length; i < len; i++) {
+				if (row.cells[i].rowSpan > 1) {
+					len -= row.cells[i].rowSpan - 1;
+				}
+				var newCell = newRow.insertCell(i);
+				if (offset === 1 && row.cells[i].colSpan > 1) {
+					newCell.colSpan = row.cells[i].colSpan;
+				}
+				newCell.innerHTML = K.IE ? '' : '<br />';
+			}
+			for (var j = rowIndex; j >= 0; j--) {
+				var cells = table.rows[j].cells;
+				if (cells.length > i) {
+					for (var k = cell.cellIndex; k >= 0; k--) {
+						if (cells[k].rowSpan > 1) {
+							cells[k].rowSpan += 1;
+						}
+					}
+					break;
+				}
+			}
+			self.cmd.range.selectNodeContents(cell).collapse(true);
+			self.cmd.select();
+			self.addBookmark();
+		},
+		rowinsertabove : function() {
+			this.rowinsert(0);
+		},
+		rowinsertbelow : function() {
+			this.rowinsert(1);
+		},
+		rowmerge : function() {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				rowIndex = row.rowIndex,
+				nextRowIndex = rowIndex + cell.rowSpan,
+				nextRow = table.rows[nextRowIndex];
+			if (table.rows.length <= nextRowIndex) {
+				return;
+			}
+			var cellIndex = cell.cellIndex;
+			if (nextRow.cells.length <= cellIndex) {
+				return;
+			}
+			var nextCell = nextRow.cells[cellIndex];
+			if (cell.colSpan !== nextCell.colSpan) {
+				return;
+			}
+			cell.rowSpan += nextCell.rowSpan;
+			nextRow.deleteCell(cellIndex);
+			self.cmd.range.selectNodeContents(cell).collapse(true);
+			self.cmd.select();
+			self.addBookmark();
+		},
+		colmerge : function() {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				rowIndex = row.rowIndex,
+				cellIndex = cell.cellIndex,
+				nextCellIndex = cellIndex + 1;
+			if (row.cells.length <= nextCellIndex) {
+				return;
+			}
+			var nextCell = row.cells[nextCellIndex];
+			if (cell.rowSpan !== nextCell.rowSpan) {
+				return;
+			}
+			cell.colSpan += nextCell.colSpan;
+			row.deleteCell(nextCellIndex);
+			self.cmd.range.selectNodeContents(cell).collapse(true);
+			self.cmd.select();
+			self.addBookmark();
+		},
+		rowsplit : function() {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				rowIndex = row.rowIndex;
+			if (cell.rowSpan === 1) {
+				return;
+			}
+			var cellIndex = _getCellIndex(table, row, cell);
+			for (var i = 1, len = cell.rowSpan; i < len; i++) {
+				var newRow = table.rows[rowIndex + i],
+					newCell = newRow.insertCell(cellIndex);
+				if (cell.colSpan > 1) {
+					newCell.colSpan = cell.colSpan;
+				}
+				newCell.innerHTML = K.IE ? '' : '<br />';
+				cellIndex = _getCellIndex(table, newRow, newCell);
+			}
+			K(cell).removeAttr('rowSpan');
+			self.cmd.range.selectNodeContents(cell).collapse(true);
+			self.cmd.select();
+			self.addBookmark();
+		},
+		colsplit : function() {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				cellIndex = cell.cellIndex;
+			if (cell.colSpan === 1) {
+				return;
+			}
+			for (var i = 1, len = cell.colSpan; i < len; i++) {
+				var newCell = row.insertCell(cellIndex + i);
+				if (cell.rowSpan > 1) {
+					newCell.rowSpan = cell.rowSpan;
+				}
+				newCell.innerHTML = K.IE ? '' : '<br />';
+			}
+			K(cell).removeAttr('colSpan');
+			self.cmd.range.selectNodeContents(cell).collapse(true);
+			self.cmd.select();
+			self.addBookmark();
+		},
+		coldelete : function() {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				index = cell.cellIndex;
+			for (var i = 0, len = table.rows.length; i < len; i++) {
+				var newRow = table.rows[i],
+					newCell = newRow.cells[index];
+				if (newCell.colSpan > 1) {
+					newCell.colSpan -= 1;
+					if (newCell.colSpan === 1) {
+						K(newCell).removeAttr('colSpan');
+					}
+				} else {
+					newRow.deleteCell(index);
+				}
+				if (newCell.rowSpan > 1) {
+					i += newCell.rowSpan - 1;
+				}
+			}
+			if (row.cells.length === 0) {
+				self.cmd.range.setStartBefore(table).collapse(true);
+				self.cmd.select();
+				K(table).remove();
+			} else {
+				self.cmd.selection(true);
+			}
+			self.addBookmark();
+		},
+		rowdelete : function() {
+			var table = self.plugin.getSelectedTable()[0],
+				row = self.plugin.getSelectedRow()[0],
+				cell = self.plugin.getSelectedCell()[0],
+				rowIndex = row.rowIndex;
+			for (var i = cell.rowSpan - 1; i >= 0; i--) {
+				table.deleteRow(rowIndex + i);
+			}
+			if (table.rows.length === 0) {
+				self.cmd.range.setStartBefore(table).collapse(true);
+				self.cmd.select();
+				K(table).remove();
+			} else {
+				self.cmd.selection(true);
+			}
+			self.addBookmark();
+		}
+	};
+	self.clickToolbar(name, self.plugin.table.prop);
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('template', function(K) {
+	var self = this, name = 'template', lang = self.lang(name + '.'),
+		htmlPath = self.pluginsPath + name + '/html/';
+	function getFilePath(fileName) {
+		return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION);
+	}
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			arr = ['<div style="padding:10px 20px;">',
+				'<div class="ke-header">',
+				'<div class="ke-left">',
+				lang. selectTemplate + ' <select>'];
+			K.each(lang.fileList, function(key, val) {
+				arr.push('<option value="' + key + '">' + val + '</option>');
+			});
+			html = [arr.join(''),
+				'</select></div>',
+				'<div class="ke-right">',
+				'<input type="checkbox" id="keReplaceFlag" name="replaceFlag" value="1" /> <label for="keReplaceFlag">' + lang.replaceContent + '</label>',
+				'</div>',
+				'<div class="ke-clearfix"></div>',
+				'</div>',
+				'<iframe class="ke-textarea" frameborder="0" style="width:458px;height:260px;background-color:#FFF;"></iframe>',
+				'</div>'].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : 500,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					var doc = K.iframeDoc(iframe);
+					self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus();
+				}
+			}
+		});
+		var selectBox = K('select', dialog.div),
+			checkbox = K('[name="replaceFlag"]', dialog.div),
+			iframe = K('iframe', dialog.div);
+		checkbox[0].checked = true;
+		iframe.attr('src', getFilePath(selectBox.val()));
+		selectBox.change(function() {
+			iframe.attr('src', getFilePath(this.value));
+		});
+	});
+});
+
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+KindEditor.plugin('wordpaste', function(K) {
+	var self = this, name = 'wordpaste';
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			html = '<div style="padding:10px 20px;">' +
+				'<div style="margin-bottom:10px;">' + lang.comment + '</div>' +
+				'<iframe class="ke-textarea" frameborder="0" style="width:408px;height:260px;"></iframe>' +
+				'</div>',
+			dialog = self.createDialog({
+				name : name,
+				width : 450,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var str = doc.body.innerHTML;
+						str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags);
+						self.insertHtml(str).hideDialog().focus();
+					}
+				}
+			}),
+			div = dialog.div,
+			iframe = K('iframe', div),
+			doc = K.iframeDoc(iframe);
+		if (!K.IE) {
+			doc.designMode = 'on';
+		}
+		doc.open();
+		doc.write('<!doctype html><html><head><title>WordPaste</title></head>');
+		doc.write('<body style="background-color:#FFF;font-size:12px;margin:2px;">');
+		if (!K.IE) {
+			doc.write('<br />');
+		}
+		doc.write('</body></html>');
+		doc.close();
+		if (K.IE) {
+			doc.body.contentEditable = 'true';
+		}
+		iframe[0].contentWindow.focus();
+	});
+});
+
+
+KindEditor.plugin('fixtoolbar', function (K) {
+    var self = this;
+    if (!self.fixToolBar) {
+        return;
+    }
+    function init() {
+        var toolbar = K('.ke-toolbar');
+        var originY = toolbar.pos().y;
+        K(window).bind('scroll', function () {
+            if (toolbar.css('position') == 'fixed') {
+                if(document.body.scrollTop - originY < 0){
+                    toolbar.css('position', 'static');
+                    toolbar.css('top', 'auto');
+                }
+            } else {
+                if (toolbar.pos().y - document.body.scrollTop < 0) {
+                    toolbar.css('position', 'fixed');
+                    toolbar.css('top', 0);
+                }
+            }
+        });
+    }
+    if (self.isCreated) {
+        init();
+    } else {
+        self.afterCreate(init);
+    }
+});

+ 242 - 0
assets/lib/kindeditor/lang/ar.js

@@ -0,0 +1,242 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+* Arabic Translation By daif alotaibi (http://daif.net/)
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'عرض المصدر',
+	preview : 'معاينة الصفحة',
+	undo : 'تراجع(Ctrl+Z)',
+	redo : 'إعادة التراجع(Ctrl+Y)',
+	cut : 'قص(Ctrl+X)',
+	copy : 'نسخ(Ctrl+C)',
+	paste : 'لصق(Ctrl+V)',
+	plainpaste : 'لصق كنص عادي',
+	wordpaste : 'لصق من مايكروسفت ورد',
+	selectall : 'تحديد الكل',
+	justifyleft : 'محاذاه لليسار',
+	justifycenter : 'محاذاه للوسط',
+	justifyright : 'محاذاه لليمين',
+	justifyfull : 'محاذاه تلقائية',
+	insertorderedlist : 'قائمة مرقمه',
+	insertunorderedlist : 'قائمة نقطية',
+	indent : 'إزاحه النص',
+	outdent : 'إلغاء الازاحة',
+	subscript : 'أسفل النص',
+	superscript : 'أعلى النص',
+	formatblock : 'Paragraph format',
+	fontname : 'نوع الخط',
+	fontsize : 'حجم الخط',
+	forecolor : 'لون النص',
+	hilitecolor : 'لون خلفية النص',
+	bold : 'عريض(Ctrl+B)',
+	italic : 'مائل(Ctrl+I)',
+	underline : 'خط تحت النص(Ctrl+U)',
+	strikethrough : 'خط على النص',
+	removeformat : 'إزالة التنسيق',
+	image : 'إدراج صورة',
+	multiimage : 'Multi image',
+	flash : 'إدراج فلاش',
+	media : 'إدراج وسائط متعددة',
+	table : 'إدراج جدول',
+	tablecell : 'خلية',
+	hr : 'إدراج خط أفقي',
+	emoticons : 'إدراج وجه ضاحك',
+	link : 'رابط',
+	unlink : 'إزالة الرابط',
+	fullscreen : 'محرر ملئ الشاشة',
+	about : 'حول',
+	print : 'طباعة',
+	filemanager : 'مدير الملفات',
+	code : 'إدراج نص برمجي',
+	map : 'خرائط قووقل',
+	baidumap : 'خرائط قووقل',
+	lineheight : 'إرتفاع السطر',
+	clearhtml : 'مسح كود HTML',
+	pagebreak : 'إدراج فاصل صفحات',
+	quickformat : 'تنسيق سريع',
+	insertfile : 'إدراج ملف',
+	template : 'إدراج قالب',
+	anchor : 'رابط',
+	yes : 'موافق',
+	no : 'إلغاء',
+	close : 'إغلاق',
+	editImage : 'خصائص الصورة',
+	deleteImage : 'حذفالصورة',
+	editFlash : 'خصائص الفلاش',
+	deleteFlash : 'حذف الفلاش',
+	editMedia : 'خصائص الوسائط',
+	deleteMedia : 'حذف الوسائط',
+	editLink : 'خصائص الرابط',
+	deleteLink : 'إزالة الرابط',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : 'خصائص الجدول',
+	tablecellprop : 'خصائص الخلية',
+	tableinsert : 'إدراج جدول',
+	tabledelete : 'حذف جدول',
+	tablecolinsertleft : 'إدراج عمود لليسار',
+	tablecolinsertright : 'إدراج عمود لليسار',
+	tablerowinsertabove : 'إدراج صف للأعلى',
+	tablerowinsertbelow : 'إدراج صف للأسفل',
+	tablerowmerge : 'دمج للأسفل',
+	tablecolmerge : 'دمج لليمين',
+	tablerowsplit : 'تقسم الصف',
+	tablecolsplit : 'تقسيم العمود',
+	tablecoldelete : 'حذف العمود',
+	tablerowdelete : 'حذف الصف',
+	noColor : 'إفتراضي',
+	pleaseSelectFile : 'Please select file.',
+	invalidImg : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: jpg,gif,bmp,png",
+	invalidMedia : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
+	invalidWidth : "العرض يجب أن يكون رقم.",
+	invalidHeight : "الإرتفاع يجب أن يكون رقم.",
+	invalidBorder : "عرض الحد يجب أن يكون رقم.",
+	invalidUrl : "الرجاء إدخال رابط حيح.",
+	invalidRows : 'صفوف غير صحيح.',
+	invalidCols : 'أعمدة غير صحيحة.',
+	invalidPadding : 'The padding must be number.',
+	invalidSpacing : 'The spacing must be number.',
+	invalidJson : 'Invalid JSON string.',
+	uploadSuccess : 'تم رفع الملف بنجاح.',
+	cutError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+X).',
+	copyError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+C).',
+	pasteError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+V).',
+	ajaxLoading : 'Loading ...',
+	uploadLoading : 'Uploading ...',
+	uploadError : 'Upload Error',
+	'plainpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.',
+	'wordpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : 'الرابط',
+	'link.linkType' : 'الهدف',
+	'link.newWindow' : 'نافذة جديدة',
+	'link.selfWindow' : 'نفس النافذة',
+	'flash.url' : 'الرابط',
+	'flash.width' : 'العرض',
+	'flash.height' : 'الإرتفاع',
+	'flash.upload' : 'رفع',
+	'flash.viewServer' : 'أستعراض',
+	'media.url' : 'الرابط',
+	'media.width' : 'العرض',
+	'media.height' : 'الإرتفاع',
+	'media.autostart' : 'تشغيل تلقائي',
+	'media.upload' : 'رفع',
+	'media.viewServer' : 'أستعراض',
+	'image.remoteImage' : 'إدراج الرابط',
+	'image.localImage' : 'رفع',
+	'image.remoteUrl' : 'الرابط',
+	'image.localUrl' : 'الملف',
+	'image.size' : 'الحجم',
+	'image.width' : 'العرض',
+	'image.height' : 'الإرتفاع',
+	'image.resetSize' : 'إستعادة الأبعاد',
+	'image.align' : 'محاذاة',
+	'image.defaultAlign' : 'الإفتراضي',
+	'image.leftAlign' : 'اليسار',
+	'image.rightAlign' : 'اليمين',
+	'image.imgTitle' : 'العنوان',
+	'image.upload' : 'أستعراض',
+	'image.viewServer' : 'أستعراض',
+	'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Start upload',
+	'multiimage.clearAll' : 'Clear all',
+	'multiimage.insertAll' : 'Insert all',
+	'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
+	'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
+	'multiimage.zeroByteFile' : 'Zero byte file.',
+	'multiimage.invalidFiletype' : 'Invalid file type.',
+	'multiimage.unknownError' : 'Unknown upload error.',
+	'multiimage.pending' : 'Pending ...',
+	'multiimage.uploadError' : 'Upload error',
+	'filemanager.emptyFolder' : 'فارغ',
+	'filemanager.moveup' : 'المجلد الأب',
+	'filemanager.viewType' : 'العرض: ',
+	'filemanager.viewImage' : 'مصغرات',
+	'filemanager.listImage' : 'قائمة',
+	'filemanager.orderType' : 'الترتيب: ',
+	'filemanager.fileName' : 'بالإسم',
+	'filemanager.fileSize' : 'بالحجم',
+	'filemanager.fileType' : 'بالنوع',
+	'insertfile.url' : 'الرابط',
+	'insertfile.title' : 'العنوان',
+	'insertfile.upload' : 'رفع',
+	'insertfile.viewServer' : 'أستعراض',
+	'table.cells' : 'خلايا',
+	'table.rows' : 'صفوف',
+	'table.cols' : 'أعمدة',
+	'table.size' : 'الأبعاد',
+	'table.width' : 'العرض',
+	'table.height' : 'الإرتفاع',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : 'الخارج',
+	'table.padding' : 'الداخل',
+	'table.spacing' : 'الفراغات',
+	'table.align' : 'محاذاه',
+	'table.textAlign' : 'افقى',
+	'table.verticalAlign' : 'رأسي',
+	'table.alignDefault' : 'إفتراضي',
+	'table.alignLeft' : 'يسار',
+	'table.alignCenter' : 'وسط',
+	'table.alignRight' : 'يمين',
+	'table.alignTop' : 'أعلى',
+	'table.alignMiddle' : 'منتصف',
+	'table.alignBottom' : 'أسفل',
+	'table.alignBaseline' : 'Baseline',
+	'table.border' : 'الحدود',
+	'table.borderWidth' : 'العرض',
+	'table.borderColor' : 'اللون',
+	'table.backgroundColor' : 'الخلفية',
+	'map.address' : 'العنوان: ',
+	'map.search' : 'بحث',
+	'baidumap.address' : 'العنوان: ',
+	'baidumap.search' : 'بحث',
+	'baidumap.insertDynamicMap' : 'Dynamic Map',
+	'anchor.name' : 'إسم الرابط',
+	'formatblock.formatBlock' : {
+		h1 : 'عنوان 1',
+		h2 : 'عنوان 2',
+		h3 : 'عنوان 3',
+		h4 : 'عنوان 4',
+		p : 'عادي'
+	},
+	'fontname.fontName' : {
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : 'إرتفاع السطر 1'},
+		{'1.5' : 'إرتفاع السطر 1.5'},
+		{'2' : 'إرتفاع السطر 2'},
+		{'2.5' : 'إرتفاع السطر 2.5'},
+		{'3' : 'إرتفاع السطر 3'}
+	],
+	'template.selectTemplate' : 'قالب',
+	'template.replaceContent' : 'إستبدال المحتوى الحالي',
+	'template.fileList' : {
+		'1.html' : 'صورة ونص',
+		'2.html' : 'جدول',
+		'3.html' : 'قائمة'
+	}
+}, 'ar');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'ar';

+ 241 - 0
assets/lib/kindeditor/lang/en.js

@@ -0,0 +1,241 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'Source',
+	preview : 'Preview',
+	undo : 'Undo(Ctrl+Z)',
+	redo : 'Redo(Ctrl+Y)',
+	cut : 'Cut(Ctrl+X)',
+	copy : 'Copy(Ctrl+C)',
+	paste : 'Paste(Ctrl+V)',
+	plainpaste : 'Paste as plain text',
+	wordpaste : 'Paste from Word',
+	selectall : 'Select all',
+	justifyleft : 'Align left',
+	justifycenter : 'Align center',
+	justifyright : 'Align right',
+	justifyfull : 'Align full',
+	insertorderedlist : 'Ordered list',
+	insertunorderedlist : 'Unordered list',
+	indent : 'Increase indent',
+	outdent : 'Decrease indent',
+	subscript : 'Subscript',
+	superscript : 'Superscript',
+	formatblock : 'Paragraph format',
+	fontname : 'Font family',
+	fontsize : 'Font size',
+	forecolor : 'Text color',
+	hilitecolor : 'Highlight color',
+	bold : 'Bold(Ctrl+B)',
+	italic : 'Italic(Ctrl+I)',
+	underline : 'Underline(Ctrl+U)',
+	strikethrough : 'Strikethrough',
+	removeformat : 'Remove format',
+	image : 'Image',
+	multiimage : 'Multi image',
+	flash : 'Flash',
+	media : 'Embeded media',
+	table : 'Table',
+	tablecell : 'Cell',
+	hr : 'Insert horizontal line',
+	emoticons : 'Insert emoticon',
+	link : 'Link',
+	unlink : 'Unlink',
+	fullscreen : 'Toggle fullscreen mode',
+	about : 'About',
+	print : 'Print',
+	filemanager : 'File Manager',
+	code : 'Insert code',
+	map : 'Google Maps',
+	baidumap : 'Baidu Maps',
+	lineheight : 'Line height',
+	clearhtml : 'Clear HTML code',
+	pagebreak : 'Insert Page Break',
+	quickformat : 'Quick Format',
+	insertfile : 'Insert file',
+	template : 'Insert Template',
+	anchor : 'Anchor',
+	yes : 'OK',
+	no : 'Cancel',
+	close : 'Close',
+	editImage : 'Image properties',
+	deleteImage : 'Delete image',
+	editFlash : 'Flash properties',
+	deleteFlash : 'Delete flash',
+	editMedia : 'Media properties',
+	deleteMedia : 'Delete media',
+	editLink : 'Link properties',
+	deleteLink : 'Unlink',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : 'Table properties',
+	tablecellprop : 'Cell properties',
+	tableinsert : 'Insert table',
+	tabledelete : 'Delete table',
+	tablecolinsertleft : 'Insert column left',
+	tablecolinsertright : 'Insert column right',
+	tablerowinsertabove : 'Insert row above',
+	tablerowinsertbelow : 'Insert row below',
+	tablerowmerge : 'Merge down',
+	tablecolmerge : 'Merge right',
+	tablerowsplit : 'Split row',
+	tablecolsplit : 'Split column',
+	tablecoldelete : 'Delete column',
+	tablerowdelete : 'Delete row',
+	noColor : 'Default',
+	pleaseSelectFile : 'Please select file.',
+	invalidImg : "Please type valid URL.\nAllowed file extension: jpg,gif,bmp,png",
+	invalidMedia : "Please type valid URL.\nAllowed file extension: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
+	invalidWidth : "The width must be number.",
+	invalidHeight : "The height must be number.",
+	invalidBorder : "The border must be number.",
+	invalidUrl : "Please type valid URL.",
+	invalidRows : 'Invalid rows.',
+	invalidCols : 'Invalid columns.',
+	invalidPadding : 'The padding must be number.',
+	invalidSpacing : 'The spacing must be number.',
+	invalidJson : 'Invalid JSON string.',
+	uploadSuccess : 'Upload success.',
+	cutError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+X) instead.',
+	copyError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+C) instead.',
+	pasteError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+V) instead.',
+	ajaxLoading : 'Loading ...',
+	uploadLoading : 'Uploading ...',
+	uploadError : 'Upload Error',
+	'plainpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.',
+	'wordpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : 'URL',
+	'link.linkType' : 'Target',
+	'link.newWindow' : 'New window',
+	'link.selfWindow' : 'Same window',
+	'flash.url' : 'URL',
+	'flash.width' : 'Width',
+	'flash.height' : 'Height',
+	'flash.upload' : 'Upload',
+	'flash.viewServer' : 'Browse',
+	'media.url' : 'URL',
+	'media.width' : 'Width',
+	'media.height' : 'Height',
+	'media.autostart' : 'Auto start',
+	'media.upload' : 'Upload',
+	'media.viewServer' : 'Browse',
+	'image.remoteImage' : 'Insert URL',
+	'image.localImage' : 'Upload',
+	'image.remoteUrl' : 'URL',
+	'image.localUrl' : 'File',
+	'image.size' : 'Size',
+	'image.width' : 'Width',
+	'image.height' : 'Height',
+	'image.resetSize' : 'Reset dimensions',
+	'image.align' : 'Align',
+	'image.defaultAlign' : 'Default',
+	'image.leftAlign' : 'Left',
+	'image.rightAlign' : 'Right',
+	'image.imgTitle' : 'Title',
+	'image.upload' : 'Browse',
+	'image.viewServer' : 'Browse',
+	'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Start upload',
+	'multiimage.clearAll' : 'Clear all',
+	'multiimage.insertAll' : 'Insert all',
+	'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
+	'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
+	'multiimage.zeroByteFile' : 'Zero byte file.',
+	'multiimage.invalidFiletype' : 'Invalid file type.',
+	'multiimage.unknownError' : 'Unknown upload error.',
+	'multiimage.pending' : 'Pending ...',
+	'multiimage.uploadError' : 'Upload error',
+	'filemanager.emptyFolder' : 'Blank',
+	'filemanager.moveup' : 'Parent folder',
+	'filemanager.viewType' : 'Display: ',
+	'filemanager.viewImage' : 'Thumbnails',
+	'filemanager.listImage' : 'List',
+	'filemanager.orderType' : 'Sorting: ',
+	'filemanager.fileName' : 'By name',
+	'filemanager.fileSize' : 'By size',
+	'filemanager.fileType' : 'By type',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : 'Title',
+	'insertfile.upload' : 'Upload',
+	'insertfile.viewServer' : 'Browse',
+	'table.cells' : 'Cells',
+	'table.rows' : 'Rows',
+	'table.cols' : 'Columns',
+	'table.size' : 'Dimensions',
+	'table.width' : 'Width',
+	'table.height' : 'Height',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : 'Space',
+	'table.padding' : 'Padding',
+	'table.spacing' : 'Spacing',
+	'table.align' : 'Align',
+	'table.textAlign' : 'Horizontal',
+	'table.verticalAlign' : 'Vertical',
+	'table.alignDefault' : 'Default',
+	'table.alignLeft' : 'Left',
+	'table.alignCenter' : 'Center',
+	'table.alignRight' : 'Right',
+	'table.alignTop' : 'Top',
+	'table.alignMiddle' : 'Middle',
+	'table.alignBottom' : 'Bottom',
+	'table.alignBaseline' : 'Baseline',
+	'table.border' : 'Border',
+	'table.borderWidth' : 'Width',
+	'table.borderColor' : 'Color',
+	'table.backgroundColor' : 'Background',
+	'map.address' : 'Address: ',
+	'map.search' : 'Search',
+	'baidumap.address' : 'Address: ',
+	'baidumap.search' : 'Search',
+	'baidumap.insertDynamicMap' : 'Dynamic Map',
+	'anchor.name' : 'Anchor name',
+	'formatblock.formatBlock' : {
+		h1 : 'Heading 1',
+		h2 : 'Heading 2',
+		h3 : 'Heading 3',
+		h4 : 'Heading 4',
+		p : 'Normal'
+	},
+	'fontname.fontName' : {
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : 'Line height 1'},
+		{'1.5' : 'Line height 1.5'},
+		{'2' : 'Line height 2'},
+		{'2.5' : 'Line height 2.5'},
+		{'3' : 'Line height 3'}
+	],
+	'template.selectTemplate' : 'Template',
+	'template.replaceContent' : 'Replace current content',
+	'template.fileList' : {
+		'1.html' : 'Image and Text',
+		'2.html' : 'Table',
+		'3.html' : 'List'
+	}
+}, 'en');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'en';

+ 246 - 0
assets/lib/kindeditor/lang/ko.js

@@ -0,0 +1,246 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Composite <ukjinplant@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : '소스',
+	preview : '미리보기',
+	undo : '작업취소(Ctrl+Z)',
+	redo : '작업재개(Ctrl+Y)',
+	cut : '잘라내기(Ctrl+X)',
+	copy : '복사(Ctrl+C)',
+	paste : '붙여넣기(Ctrl+V)',
+	plainpaste : '일반 텍스트로 붙여넣기',
+	wordpaste : '워드 문서로 붙여넣기',
+	selectall : '전체 선택',
+	justifyleft : '왼쪽 정렬',
+	justifycenter : '가운데 정렬',
+	justifyright : '오른쪽 정렬',
+	justifyfull : '양쪽 정렬',
+	insertorderedlist : '순서 목록',
+	insertunorderedlist : '비순서 목록',
+	indent : '들여쓰기',
+	outdent : '내어쓰기',
+	subscript : '아랫첨자',
+	superscript : '윗첨자',
+	formatblock : '문단 형식',
+	fontname : '글꼴',
+	fontsize : '글자 크기',
+	forecolor : '글자색',
+	hilitecolor : '강조색',
+	bold : '굵게(Ctrl+B)',
+	italic : '이텔릭(Ctrl+I)',
+	underline : '빝줄(Ctrl+U)',
+	strikethrough : '취소선',
+	removeformat : '형식 제거',
+	image : '이미지 추가',
+	multiimage : '여러 이미지 추가',
+	flash : '플래시 추가',
+	media : '미디어 추가',
+	table : '표',
+	tablecell : '열',
+	hr : '구분선 추가',
+	emoticons : '이모티콘 추가',
+	link : '링크',
+	unlink : '링크 제거',
+	fullscreen : '전체 화면 모드',
+	about : '이 에디터는...',
+	print : '인쇄',
+	filemanager : '파일 관리자',
+	code : '코드 추가',
+	map : '구글 맵 추가',
+	baidumap : '바이두 맵 추가',
+	lineheight : '행 간격',
+	clearhtml : 'HTML 코드 정리',
+	pagebreak : '페이지 구분 추가',
+	quickformat : '빠른 형식',
+	insertfile : '파일 추가',
+	template : '템플릿 추가',
+	anchor : '책갈피',
+	yes : '확인',
+	no : '취소',
+	close : '닫기',
+	editImage : '이미지 속성',
+	deleteImage : '이미지 삭제',
+	editFlash : '플래시 속성',
+	deleteFlash : '플래시 삭제',
+	editMedia : '미디어 속성',
+	deleteMedia : '미디어 삭제',
+	editLink : '링크 속성',
+	deleteLink : '링크 삭제',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : '표 속성',
+	tablecellprop : '열 속성',
+	tableinsert : '표 추가',
+	tabledelete : '표 삭제',
+	tablecolinsertleft : '왼쪽으로 열 추가',
+	tablecolinsertright : '오른쪽으로 열 추가',
+	tablerowinsertabove : '위쪽으로 열 추가',
+	tablerowinsertbelow : '아래쪽으로 열 추가',
+	tablerowmerge : '아래로 병합',
+	tablecolmerge : '오른쪽으로 병합',
+	tablerowsplit : '행 나누기',
+	tablecolsplit : '열 나누기',
+	tablecoldelete : '열 삭제',
+	tablerowdelete : '행 삭제',
+	noColor : '기본색',
+	pleaseSelectFile : '파일 선택',
+	invalidImg : "올바른 주소를 입력하세요.\njpg,gif,bmp,png 형식이 가능합니다.",
+	invalidMedia : "올바른 주소를 입력하세요.\nswf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb 형식이 가능합니다.",
+	invalidWidth : "넓이 값은 숫자여야 합니다.",
+	invalidHeight : "높이 값은 숫자여야 합니다.",
+	invalidBorder : "굵기 값은 숫자여야 합니다.",
+	invalidUrl : "올바른 주소를 입력하세요.",
+	invalidRows : '올바른 행이 아닙니다.',
+	invalidCols : '올바른 열이 아닙니다.',
+	invalidPadding : '안쪽 여백 값은 숫자여야 합니다.',
+	invalidSpacing : '간격 길이 값은 숫자여야 합니다.',
+	invalidJson : '올바른 JSON 형식이 아닙니다.',
+	uploadSuccess : '업로드가 완료되었습니다.',
+	cutError : '브라우저가 잘라내기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
+	copyError : '브라우저가 복사 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
+	pasteError : '브라우저가 붙여넣기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
+	ajaxLoading : '불러오는 중 ...',
+	uploadLoading : '업로드 중 ...',
+	uploadError : '업로드 오류',
+	'plainpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 텍스트를 붙여넣으세요.',
+	'wordpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 워드 텍스트를 붙여넣으세요.',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : '주소',
+	'link.linkType' : '창',
+	'link.newWindow' : '새 창',
+	'link.selfWindow' : '현재 창',
+	'flash.url' : '주소',
+	'flash.width' : '넓이',
+	'flash.height' : '높이',
+	'flash.upload' : '업로드',
+	'flash.viewServer' : '찾아보기',
+	'media.url' : '주소',
+	'media.width' : '넓이',
+	'media.height' : '높이',
+	'media.autostart' : '자동 시작',
+	'media.upload' : '업로드',
+	'media.viewServer' : '찾아보기',
+	'image.remoteImage' : '외부 이미지',
+	'image.localImage' : '내부 이미지',
+	'image.remoteUrl' : '주소',
+	'image.localUrl' : '파일',
+	'image.size' : '크기',
+	'image.width' : '넓이',
+	'image.height' : '높이',
+	'image.resetSize' : '기본 크기로',
+	'image.align' : '정렬',
+	'image.defaultAlign' : '기본',
+	'image.leftAlign' : '왼쪽',
+	'image.rightAlign' : '오른쪽',
+	'image.imgTitle' : '제목',
+	'image.upload' : '찾아보기',
+	'image.viewServer' : '찾아보기',
+	'multiimage.uploadDesc' : '최대 이미지 개수: <%=uploadLimit%>개, 개당 이미지 크기: <%=sizeLimit%>',
+	'multiimage.startUpload' : '업로드 시작',
+	'multiimage.clearAll' : '모두 삭제',
+	'multiimage.insertAll' : '모두 삽입',
+	'multiimage.queueLimitExceeded' : '업로드 개수가 초과되었습니다.',
+	'multiimage.fileExceedsSizeLimit' : '업로드 크기가 초과되었습니다.',
+	'multiimage.zeroByteFile' : '파일 크기가 없습니다.',
+	'multiimage.invalidFiletype' : '올바른 이미지가 아닙니다.',
+	'multiimage.unknownError' : '알 수 없는 업로드 오류가 발생하였습니다.',
+	'multiimage.pending' : '처리 중 ...',
+	'multiimage.uploadError' : '업로드 오류',
+	'filemanager.emptyFolder' : '빈 폴더',
+	'filemanager.moveup' : '위로',
+	'filemanager.viewType' : '보기 방식: ',
+	'filemanager.viewImage' : '미리 보기',
+	'filemanager.listImage' : '목록',
+	'filemanager.orderType' : '정렬 방식: ',
+	'filemanager.fileName' : '이름별',
+	'filemanager.fileSize' : '크기별',
+	'filemanager.fileType' : '종류별',
+	'insertfile.url' : '주소',
+	'insertfile.title' : '제목',
+	'insertfile.upload' : '업로드',
+	'insertfile.viewServer' : '찾아보기',
+	'table.cells' : '열',
+	'table.rows' : '행',
+	'table.cols' : '열',
+	'table.size' : '표 크기',
+	'table.width' : '넓이',
+	'table.height' : '높이',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '간격',
+	'table.padding' : '안쪽여백',
+	'table.spacing' : '간격',
+	'table.align' : '정렬',
+	'table.textAlign' : '수직',
+	'table.verticalAlign' : '수평',
+	'table.alignDefault' : '기본',
+	'table.alignLeft' : '왼쪽',
+	'table.alignCenter' : '가운데',
+	'table.alignRight' : '오른쪽',
+	'table.alignTop' : '위쪽',
+	'table.alignMiddle' : '중간',
+	'table.alignBottom' : '아래쪽',
+	'table.alignBaseline' : '글자기준',
+	'table.border' : '테두리',
+	'table.borderWidth' : '크기',
+	'table.borderColor' : '색상',
+	'table.backgroundColor' : '배경',
+	'map.address' : '주소: ',
+	'map.search' : '검색',
+	'baidumap.address' : '주소: ',
+	'baidumap.search' : '검색',
+	'baidumap.insertDynamicMap' : '동적 지도',
+	'anchor.name' : '책갈피명',
+	'formatblock.formatBlock' : {
+		h1 : '제목 1',
+		h2 : '제목 2',
+		h3 : '제목 3',
+		h4 : '제목 4',
+		p : '본문'
+	},
+	'fontname.fontName' : {
+		'Gulim' : '굴림',
+		'Dotum' : '돋움',
+		'Batang' : '바탕',
+		'Gungsuh' : '궁서',
+		'Malgun Gothic' : '맑은 고딕',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '행간 1'},
+		{'1.5' : '행간 1.5'},
+		{'2' : '행간 2'},
+		{'2.5' : '행간 2.5'},
+		{'3' : '행간 3'}
+	],
+	'template.selectTemplate' : '템플릿',
+	'template.replaceContent' : '내용 바꾸기',
+	'template.fileList' : {
+		'1.html' : '이미지와 텍스트',
+		'2.html' : '표',
+		'3.html' : '목록'
+	}
+}, 'ko');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'ko';

+ 242 - 0
assets/lib/kindeditor/lang/ru.js

@@ -0,0 +1,242 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+* Translated to Russian by Valery Votintsev (http://codersclub.org/)
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'Source',
+	preview : 'Preview',
+	undo : 'Отмена(Ctrl+Z)',
+	redo : 'Повтор(Ctrl+Y)',
+	cut : 'Вырезать(Ctrl+X)',
+	copy : 'Копировать(Ctrl+C)',
+	paste : 'Вставить(Ctrl+V)',
+	plainpaste : 'Вставить как простой текст',
+	wordpaste : 'Вставить из Word',
+	selectall : 'Выбрать все',
+	justifyleft : 'Выравнивание влево',
+	justifycenter : 'Выравнивание по центру',
+	justifyright : 'Выравнивание вправо',
+	justifyfull : 'Выравнивание по обеим сторонам',
+	insertorderedlist : 'Нумерованый список',
+	insertunorderedlist : 'Ненумерованый список',
+	indent : 'Добавить отступ',
+	outdent : 'Убрать отступ',
+	subscript : 'Надстрочный',
+	superscript : 'Подстрочный',
+	formatblock : 'Формат параграфа',
+	fontname : 'Шрифт',
+	fontsize : 'Размер',
+	forecolor : 'Цвет текста',
+	hilitecolor : 'Цвет фона',
+	bold : 'Жирный(Ctrl+B)',
+	italic : 'Наклонный(Ctrl+I)',
+	underline : 'Подчёркнутый(Ctrl+U)',
+	strikethrough : 'Перечёркнутый',
+	removeformat : 'Удалить формат',
+	image : 'Изображение',
+	multiimage : 'Мульти-загрузка',
+	flash : 'Flash',
+	media : 'Встроенные данные',
+	table : 'Таблица',
+	tablecell : 'Ячейка',
+	hr : 'Горизонтальный разделитель',
+	emoticons : 'Смайл',
+	link : 'Ссылка',
+	unlink : 'Убрать ссылку',
+	fullscreen : 'На весь экран',
+	about : 'О программе',
+	print : 'Печать',
+	filemanager : 'Файлы',
+	code : 'Код',
+	map : 'Карта Google',
+	baidumap : 'Карта Baidu',
+	lineheight : 'Межстрочный интервал',
+	clearhtml : 'Очистить HTML код',
+	pagebreak : 'Разрыв страницы',
+	quickformat : 'Быстрый формат',
+	insertfile : 'Вставить файл',
+	template : 'Вставить шаблон',
+	anchor : 'Якорь',
+	yes : 'OK',
+	no : 'Отмена',
+	close : 'Закрыть',
+	editImage : 'Свойства изображения',
+	deleteImage : 'Удалить изображение',
+	editFlash : 'Свойства Flash',
+	deleteFlash : 'Удалить Flash',
+	editMedia : 'Свойства Media',
+	deleteMedia : 'Удалить Media',
+	editLink : 'Свойства ссылки',
+	deleteLink : 'Удалить ссылку',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : 'Свойства таблицы',
+	tablecellprop : 'Свойства ячейки',
+	tableinsert : 'Вставить таблицу',
+	tabledelete : 'Удалить таблицу',
+	tablecolinsertleft : 'Добавить столбец слева',
+	tablecolinsertright : 'Добавить столбец справа',
+	tablerowinsertabove : 'Добавить строку выше',
+	tablerowinsertbelow : 'Добавить строку ниже',
+	tablerowmerge : 'Объединить вниз',
+	tablecolmerge : 'Объединить вправо',
+	tablerowsplit : 'Разделить строку',
+	tablecolsplit : 'Разделить столбец',
+	tablecoldelete : 'Удалить столбец',
+	tablerowdelete : 'Удалить строку',
+	noColor : 'По умолчанию',
+	pleaseSelectFile : 'Выберите файл.',
+	invalidImg : "Укажите корректный URL изображения.\nРазрешённые форматы: jpg,gif,bmp,png",
+	invalidMedia : "Укажите корректный тип медиа-объекта.\nРазрешённые типы: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
+	invalidWidth : "Ширина должна быть числом.",
+	invalidHeight : "Высота должна быть числом.",
+	invalidBorder : "Ширина рамки должна быть числом.",
+	invalidUrl : "Укажите корректный URL.",
+	invalidRows : 'Неверные строки.',
+	invalidCols : 'Неверные столбцы.',
+	invalidPadding : 'padding должен быть числом.',
+	invalidSpacing : 'spacing должен быть числом.',
+	invalidJson : 'Неверная JSON строка.',
+	uploadSuccess : 'Загрузка завершена.',
+	cutError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+X).',
+	copyError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+C).',
+	pasteError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+V).',
+	ajaxLoading : 'Загрузка ...',
+	uploadLoading : 'Загрузка ...',
+	uploadError : 'Сбой загрузки',
+	'plainpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).',
+	'wordpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).',
+	'code.pleaseInput' : 'Введите код.',
+	'link.url' : 'URL',
+	'link.linkType' : 'Открывать ссылку',
+	'link.newWindow' : 'в новом окне',
+	'link.selfWindow' : 'в том же окне',
+	'flash.url' : 'URL',
+	'flash.width' : 'Ширина',
+	'flash.height' : 'Высота',
+	'flash.upload' : 'Загрузить',
+	'flash.viewServer' : 'Выбрать',
+	'media.url' : 'URL',
+	'media.width' : 'Ширина',
+	'media.height' : 'Высота',
+	'media.autostart' : 'Автостарт',
+	'media.upload' : 'Загрузить',
+	'media.viewServer' : 'Выбрать',
+	'image.remoteImage' : 'Вставить URL изображения',
+	'image.localImage' : 'Загрузить',
+	'image.remoteUrl' : 'URL',
+	'image.localUrl' : 'Файл',
+	'image.size' : 'Размер',
+	'image.width' : 'Ширина',
+	'image.height' : 'Высота',
+	'image.resetSize' : 'Сбросить размеры',
+	'image.align' : 'Выравнивание',
+	'image.defaultAlign' : 'По умолчанию',
+	'image.leftAlign' : 'Влево',
+	'image.rightAlign' : 'Вправо',
+	'image.imgTitle' : 'Название',
+	'image.upload' : 'Загрузить',
+	'image.viewServer' : 'Выбрать',
+	'multiimage.uploadDesc' : 'Максимальное кол-во изображений: <%=uploadLimit%>, Максимальный размер одного изображения: <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Начать загрузку',
+	'multiimage.clearAll' : 'Очистить все',
+	'multiimage.insertAll' : 'Вставить все',
+	'multiimage.queueLimitExceeded' : 'Превышен лимит очереди.',
+	'multiimage.fileExceedsSizeLimit' : 'Превышен максимальный размер файла.',
+	'multiimage.zeroByteFile' : 'Файл нулевой длины.',
+	'multiimage.invalidFiletype' : 'Недопустимый тип файла.',
+	'multiimage.unknownError' : 'Непредвиденная ошибка загрузки.',
+	'multiimage.pending' : 'Ожидает ...',
+	'multiimage.uploadError' : 'Ошибка загрузки',
+	'filemanager.emptyFolder' : 'Папка пуста',
+	'filemanager.moveup' : 'Наверх',
+	'filemanager.viewType' : 'Тип показа: ',
+	'filemanager.viewImage' : 'Превьюшки',
+	'filemanager.listImage' : 'Список',
+	'filemanager.orderType' : 'Сортировка: ',
+	'filemanager.fileName' : 'По имени',
+	'filemanager.fileSize' : 'По размеру',
+	'filemanager.fileType' : 'По типу',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : 'Название',
+	'insertfile.upload' : 'Загрузить',
+	'insertfile.viewServer' : 'Выбрать',
+	'table.cells' : 'Ячейки',
+	'table.rows' : 'Строки',
+	'table.cols' : 'Столбцы',
+	'table.size' : 'Размеры',
+	'table.width' : 'Ширина',
+	'table.height' : 'Высота',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : 'Space',
+	'table.padding' : 'Padding',
+	'table.spacing' : 'Spacing',
+	'table.align' : 'Выравнивание',
+	'table.textAlign' : 'По горизонтали',
+	'table.verticalAlign' : 'По вертикали',
+	'table.alignDefault' : 'По умолчанию',
+	'table.alignLeft' : 'Влево',
+	'table.alignCenter' : 'По центру',
+	'table.alignRight' : 'Вправо',
+	'table.alignTop' : 'Вверх',
+	'table.alignMiddle' : 'Посередине',
+	'table.alignBottom' : 'Вниз',
+	'table.alignBaseline' : 'По базовой линии',
+	'table.border' : 'Рамка',
+	'table.borderWidth' : 'Ширина',
+	'table.borderColor' : 'Цвет',
+	'table.backgroundColor' : 'Цвет фона',
+	'map.address' : 'Адрес: ',
+	'map.search' : 'Поиск',
+	'baidumap.address' : 'Адрес: ',
+	'baidumap.search' : 'Поиск',
+	'baidumap.insertDynamicMap' : 'Динамическая карта',
+	'anchor.name' : 'Имя якоря',
+	'formatblock.formatBlock' : {
+		h1 : 'Заголовок 1',
+		h2 : 'Заголовок 2',
+		h3 : 'Заголовок 3',
+		h4 : 'Заголовок 4',
+		p : 'Обычный текст'
+	},
+	'fontname.fontName' : {
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '1'},
+		{'1.5' : '1.5'},
+		{'2' : '2'},
+		{'2.5' : '2.5'},
+		{'3' : '3'}
+	],
+	'template.selectTemplate' : 'Шаблон',
+	'template.replaceContent' : 'Заменить текущий шаблон',
+	'template.fileList' : {
+		'1.html' : 'Текст и изображения',
+		'2.html' : 'Таблица',
+		'3.html' : 'Список'
+	}
+}, 'en');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'ru';

+ 238 - 0
assets/lib/kindeditor/lang/zh-CN.js

@@ -0,0 +1,238 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'HTML代码',
+	preview : '预览',
+	undo : '后退(Ctrl+Z)',
+	redo : '前进(Ctrl+Y)',
+	cut : '剪切(Ctrl+X)',
+	copy : '复制(Ctrl+C)',
+	paste : '粘贴(Ctrl+V)',
+	plainpaste : '粘贴为无格式文本',
+	wordpaste : '从Word粘贴',
+	selectall : '全选(Ctrl+A)',
+	justifyleft : '左对齐',
+	justifycenter : '居中',
+	justifyright : '右对齐',
+	justifyfull : '两端对齐',
+	insertorderedlist : '编号',
+	insertunorderedlist : '项目符号',
+	indent : '增加缩进',
+	outdent : '减少缩进',
+	subscript : '下标',
+	superscript : '上标',
+	formatblock : '段落',
+	fontname : '字体',
+	fontsize : '文字大小',
+	forecolor : '文字颜色',
+	hilitecolor : '文字背景',
+	bold : '粗体(Ctrl+B)',
+	italic : '斜体(Ctrl+I)',
+	underline : '下划线(Ctrl+U)',
+	strikethrough : '删除线',
+	removeformat : '删除格式',
+	image : '图片',
+	multiimage : '批量图片上传',
+	flash : 'Flash',
+	media : '视音频',
+	table : '表格',
+	tablecell : '单元格',
+	hr : '插入横线',
+	emoticons : '插入表情',
+	link : '超级链接',
+	unlink : '取消超级链接',
+	fullscreen : '全屏显示',
+	about : '关于',
+	print : '打印(Ctrl+P)',
+	filemanager : '文件空间',
+	code : '插入程序代码',
+	map : 'Google地图',
+	baidumap : '百度地图',
+	lineheight : '行距',
+	clearhtml : '清理HTML代码',
+	pagebreak : '插入分页符',
+	quickformat : '一键排版',
+	insertfile : '插入文件',
+	template : '插入模板',
+	anchor : '锚点',
+	yes : '确定',
+	no : '取消',
+	close : '关闭',
+	editImage : '图片属性',
+	deleteImage : '删除图片',
+	editFlash : 'Flash属性',
+	deleteFlash : '删除Flash',
+	editMedia : '视音频属性',
+	deleteMedia : '删除视音频',
+	editLink : '超级链接属性',
+	deleteLink : '取消超级链接',
+	editAnchor : '锚点属性',
+	deleteAnchor : '删除锚点',
+	tableprop : '表格属性',
+	tablecellprop : '单元格属性',
+	tableinsert : '插入表格',
+	tabledelete : '删除表格',
+	tablecolinsertleft : '左侧插入列',
+	tablecolinsertright : '右侧插入列',
+	tablerowinsertabove : '上方插入行',
+	tablerowinsertbelow : '下方插入行',
+	tablerowmerge : '向下合并单元格',
+	tablecolmerge : '向右合并单元格',
+	tablerowsplit : '拆分行',
+	tablecolsplit : '拆分列',
+	tablecoldelete : '删除列',
+	tablerowdelete : '删除行',
+	noColor : '无颜色',
+	pleaseSelectFile : '请选择文件。',
+	invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",
+	invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
+	invalidWidth : "宽度必须为数字。",
+	invalidHeight : "高度必须为数字。",
+	invalidBorder : "边框必须为数字。",
+	invalidUrl : "请输入有效的URL地址。",
+	invalidRows : '行数为必选项,只允许输入大于0的数字。',
+	invalidCols : '列数为必选项,只允许输入大于0的数字。',
+	invalidPadding : '边距必须为数字。',
+	invalidSpacing : '间距必须为数字。',
+	invalidJson : '服务器发生故障。',
+	uploadSuccess : '上传成功。',
+	cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。',
+	copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。',
+	pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。',
+	ajaxLoading : '加载中,请稍候 ...',
+	uploadLoading : '上传中,请稍候 ...',
+	uploadError : '上传错误',
+	'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
+	'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
+	'code.pleaseInput' : '请输入程序代码。',
+	'link.url' : 'URL',
+	'link.linkType' : '打开类型',
+	'link.newWindow' : '新窗口',
+	'link.selfWindow' : '当前窗口',
+	'flash.url' : 'URL',
+	'flash.width' : '宽度',
+	'flash.height' : '高度',
+	'flash.upload' : '上传',
+	'flash.viewServer' : '文件空间',
+	'media.url' : 'URL',
+	'media.width' : '宽度',
+	'media.height' : '高度',
+	'media.autostart' : '自动播放',
+	'media.upload' : '上传',
+	'media.viewServer' : '文件空间',
+	'image.remoteImage' : '网络图片',
+	'image.localImage' : '本地上传',
+	'image.remoteUrl' : '图片地址',
+	'image.localUrl' : '上传文件',
+	'image.size' : '图片大小',
+	'image.width' : '宽',
+	'image.height' : '高',
+	'image.resetSize' : '重置大小',
+	'image.align' : '对齐方式',
+	'image.defaultAlign' : '默认方式',
+	'image.leftAlign' : '左对齐',
+	'image.rightAlign' : '右对齐',
+	'image.imgTitle' : '图片说明',
+	'image.upload' : '浏览...',
+	'image.viewServer' : '图片空间',
+	'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>',
+	'multiimage.startUpload' : '开始上传',
+	'multiimage.clearAll' : '全部清空',
+	'multiimage.insertAll' : '全部插入',
+	'multiimage.queueLimitExceeded' : '文件数量超过限制。',
+	'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。',
+	'multiimage.zeroByteFile' : '无法上传空文件。',
+	'multiimage.invalidFiletype' : '文件类型不正确。',
+	'multiimage.unknownError' : '发生异常,无法上传。',
+	'multiimage.pending' : '等待上传',
+	'multiimage.uploadError' : '上传失败',
+	'filemanager.emptyFolder' : '空文件夹',
+	'filemanager.moveup' : '移到上一级文件夹',
+	'filemanager.viewType' : '显示方式:',
+	'filemanager.viewImage' : '缩略图',
+	'filemanager.listImage' : '详细信息',
+	'filemanager.orderType' : '排序方式:',
+	'filemanager.fileName' : '名称',
+	'filemanager.fileSize' : '大小',
+	'filemanager.fileType' : '类型',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : '文件说明',
+	'insertfile.upload' : '上传',
+	'insertfile.viewServer' : '文件空间',
+	'table.cells' : '单元格数',
+	'table.rows' : '行数',
+	'table.cols' : '列数',
+	'table.size' : '大小',
+	'table.width' : '宽度',
+	'table.height' : '高度',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '边距间距',
+	'table.padding' : '边距',
+	'table.spacing' : '间距',
+	'table.align' : '对齐方式',
+	'table.textAlign' : '水平对齐',
+	'table.verticalAlign' : '垂直对齐',
+	'table.alignDefault' : '默认',
+	'table.alignLeft' : '左对齐',
+	'table.alignCenter' : '居中',
+	'table.alignRight' : '右对齐',
+	'table.alignTop' : '顶部',
+	'table.alignMiddle' : '中部',
+	'table.alignBottom' : '底部',
+	'table.alignBaseline' : '基线',
+	'table.border' : '边框',
+	'table.borderWidth' : '边框',
+	'table.borderColor' : '颜色',
+	'table.backgroundColor' : '背景颜色',
+	'map.address' : '地址: ',
+	'map.search' : '搜索',
+	'baidumap.address' : '地址: ',
+	'baidumap.search' : '搜索',
+	'baidumap.insertDynamicMap' : '插入动态地图',
+	'anchor.name' : '锚点名称',
+	'formatblock.formatBlock' : {
+		h1 : '标题 1',
+		h2 : '标题 2',
+		h3 : '标题 3',
+		h4 : '标题 4',
+		p : '正 文'
+	},
+	'fontname.fontName' : {
+		'SimSun' : '宋体',
+		'NSimSun' : '新宋体',
+		'FangSong_GB2312' : '仿宋_GB2312',
+		'KaiTi_GB2312' : '楷体_GB2312',
+		'SimHei' : '黑体',
+		'Microsoft YaHei' : '微软雅黑',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Times New Roman' : 'Times New Roman',
+		'Courier New' : 'Courier New',
+		'Tahoma' : 'Tahoma',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '单倍行距'},
+		{'1.5' : '1.5倍行距'},
+		{'2' : '2倍行距'},
+		{'2.5' : '2.5倍行距'},
+		{'3' : '3倍行距'}
+	],
+	'template.selectTemplate' : '可选模板',
+	'template.replaceContent' : '替换当前内容',
+	'template.fileList' : {
+		'1.html' : '图片和文字',
+		'2.html' : '表格',
+		'3.html' : '项目编号'
+	}
+}, 'zh-CN');
+
+KindEditor.options.langType = 'zh-CN';

+ 243 - 0
assets/lib/kindeditor/lang/zh-TW.js

@@ -0,0 +1,243 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : '原始碼',
+	preview : '預覽',
+	undo : '復原(Ctrl+Z)',
+	redo : '重複(Ctrl+Y)',
+	cut : '剪下(Ctrl+X)',
+	copy : '複製(Ctrl+C)',
+	paste : '貼上(Ctrl+V)',
+	plainpaste : '貼為純文字格式',
+	wordpaste : '自Word貼上',
+	selectall : '全選(Ctrl+A)',
+	justifyleft : '靠左對齊',
+	justifycenter : '置中',
+	justifyright : '靠右對齊',
+	justifyfull : '左右對齊',
+	insertorderedlist : '編號清單',
+	insertunorderedlist : '項目清單',
+	indent : '增加縮排',
+	outdent : '減少縮排',
+	subscript : '下標',
+	superscript : '上標',
+	formatblock : '標題',
+	fontname : '字體',
+	fontsize : '文字大小',
+	forecolor : '文字顏色',
+	hilitecolor : '背景顏色',
+	bold : '粗體(Ctrl+B)',
+	italic : '斜體(Ctrl+I)',
+	underline : '底線(Ctrl+U)',
+	strikethrough : '刪除線',
+	removeformat : '清除格式',
+	image : '影像',
+	multiimage : '批量影像上傳',
+	flash : 'Flash',
+	media : '多媒體',
+	table : '表格',
+	tablecell : '儲存格',
+	hr : '插入水平線',
+	emoticons : '插入表情',
+	link : '超連結',
+	unlink : '移除超連結',
+	fullscreen : '最大化',
+	about : '關於',
+	print : '列印(Ctrl+P)',
+	filemanager : '瀏覽伺服器',
+	code : '插入程式代碼',
+	map : 'Google地圖',
+	baidumap : 'Baidu地圖',
+	lineheight : '行距',
+	clearhtml : '清理HTML代碼',
+	pagebreak : '插入分頁符號',
+	quickformat : '快速排版',
+	insertfile : '插入文件',
+	template : '插入樣板',
+	anchor : '錨點',
+	yes : '確定',
+	no : '取消',
+	close : '關閉',
+	editImage : '影像屬性',
+	deleteImage : '刪除影像',
+	editFlash : 'Flash屬性',
+	deleteFlash : '删除Flash',
+	editMedia : '多媒體屬性',
+	deleteMedia : '删除多媒體',
+	editLink : '超連結屬性',
+	deleteLink : '移除超連結',
+	editAnchor : '锚点属性',
+	deleteAnchor : '删除锚点',
+	tableprop : '表格屬性',
+	tablecellprop : '儲存格屬性',
+	tableinsert : '插入表格',
+	tabledelete : '刪除表格',
+	tablecolinsertleft : '向左插入列',
+	tablecolinsertright : '向右插入列',
+	tablerowinsertabove : '向上插入欄',
+	tablerowinsertbelow : '下方插入欄',
+	tablerowmerge : '向下合併單元格',
+	tablecolmerge : '向右合併單元格',
+	tablerowsplit : '分割欄',
+	tablecolsplit : '分割列',
+	tablecoldelete : '删除列',
+	tablerowdelete : '删除欄',
+	noColor : '自動',
+	pleaseSelectFile : '請選擇文件。',
+	invalidImg : "請輸入有效的URL。\n只允許jpg,gif,bmp,png格式。",
+	invalidMedia : "請輸入有效的URL。\n只允許swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
+	invalidWidth : "寬度必須是數字。",
+	invalidHeight : "高度必須是數字。",
+	invalidBorder : "邊框必須是數字。",
+	invalidUrl : "請輸入有效的URL。",
+	invalidRows : '欄數是必須輸入項目,只允許輸入大於0的數字。',
+	invalidCols : '列數是必須輸入項目,只允許輸入大於0的數字。',
+	invalidPadding : '內距必須是數字。',
+	invalidSpacing : '間距必須是數字。',
+	invalidJson : '伺服器發生故障。',
+	uploadSuccess : '上傳成功。',
+	cutError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+X)完成。',
+	copyError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+C)完成。',
+	pasteError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+V)完成。',
+	ajaxLoading : '加載中,請稍候 ...',
+	uploadLoading : '上傳中,請稍候 ...',
+	uploadError : '上傳錯誤',
+	'plainpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。',
+	'wordpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : 'URL',
+	'link.linkType' : '打開類型',
+	'link.newWindow' : '新窗口',
+	'link.selfWindow' : '本頁窗口',
+	'flash.url' : 'URL',
+	'flash.width' : '寬度',
+	'flash.height' : '高度',
+	'flash.upload' : '上傳',
+	'flash.viewServer' : '瀏覽',
+	'media.url' : 'URL',
+	'media.width' : '寬度',
+	'media.height' : '高度',
+	'media.autostart' : '自動播放',
+	'media.upload' : '上傳',
+	'media.viewServer' : '瀏覽',
+	'image.remoteImage' : '網絡影像',
+	'image.localImage' : '上傳影像',
+	'image.remoteUrl' : '影像URL',
+	'image.localUrl' : '影像URL',
+	'image.size' : '影像大小',
+	'image.width' : '寬度',
+	'image.height' : '高度',
+	'image.resetSize' : '原始大小',
+	'image.align' : '對齊方式',
+	'image.defaultAlign' : '未設定',
+	'image.leftAlign' : '向左對齊',
+	'image.rightAlign' : '向右對齊',
+	'image.imgTitle' : '影像說明',
+	'image.upload' : '瀏覽...',
+	'image.viewServer' : '瀏覽...',
+	'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Start upload',
+	'multiimage.clearAll' : 'Clear all',
+	'multiimage.insertAll' : 'Insert all',
+	'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
+	'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
+	'multiimage.zeroByteFile' : 'Zero byte file.',
+	'multiimage.invalidFiletype' : 'Invalid file type.',
+	'multiimage.unknownError' : 'Unknown upload error.',
+	'multiimage.pending' : 'Pending ...',
+	'multiimage.uploadError' : 'Upload error',
+	'filemanager.emptyFolder' : '空文件夾',
+	'filemanager.moveup' : '至上一級文件夾',
+	'filemanager.viewType' : '顯示方式:',
+	'filemanager.viewImage' : '縮略圖',
+	'filemanager.listImage' : '詳細信息',
+	'filemanager.orderType' : '排序方式:',
+	'filemanager.fileName' : '名稱',
+	'filemanager.fileSize' : '大小',
+	'filemanager.fileType' : '類型',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : '文件說明',
+	'insertfile.upload' : '上傳',
+	'insertfile.viewServer' : '瀏覽',
+	'table.cells' : '儲存格數',
+	'table.rows' : '欄數',
+	'table.cols' : '列數',
+	'table.size' : '表格大小',
+	'table.width' : '寬度',
+	'table.height' : '高度',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '內距間距',
+	'table.padding' : '內距',
+	'table.spacing' : '間距',
+	'table.align' : '對齊方式',
+	'table.textAlign' : '水平對齊',
+	'table.verticalAlign' : '垂直對齊',
+	'table.alignDefault' : '未設定',
+	'table.alignLeft' : '向左對齊',
+	'table.alignCenter' : '置中',
+	'table.alignRight' : '向右對齊',
+	'table.alignTop' : '靠上',
+	'table.alignMiddle' : '置中',
+	'table.alignBottom' : '靠下',
+	'table.alignBaseline' : '基線',
+	'table.border' : '表格邊框',
+	'table.borderWidth' : '邊框',
+	'table.borderColor' : '顏色',
+	'table.backgroundColor' : '背景顏色',
+	'map.address' : '住所: ',
+	'map.search' : '尋找',
+	'baidumap.address' : '住所: ',
+	'baidumap.search' : '尋找',
+	'baidumap.insertDynamicMap' : '插入動態地圖',
+	'anchor.name' : '錨點名稱',
+	'formatblock.formatBlock' : {
+		h1 : '標題 1',
+		h2 : '標題 2',
+		h3 : '標題 3',
+		h4 : '標題 4',
+		p : '一般'
+	},
+	'fontname.fontName' : {
+		'MingLiU' : '細明體',
+		'PMingLiU' : '新細明體',
+		'DFKai-SB' : '標楷體',
+		'SimSun' : '宋體',
+		'NSimSun' : '新宋體',
+		'FangSong' : '仿宋體',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Times New Roman' : 'Times New Roman',
+		'Courier New' : 'Courier New',
+		'Tahoma' : 'Tahoma',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '单倍行距'},
+		{'1.5' : '1.5倍行距'},
+		{'2' : '2倍行距'},
+		{'2.5' : '2.5倍行距'},
+		{'3' : '3倍行距'}
+	],
+	'template.selectTemplate' : '可選樣板',
+	'template.replaceContent' : '取代當前內容',
+	'template.fileList' : {
+		'1.html' : '影像和文字',
+		'2.html' : '表格',
+		'3.html' : '项目清單'
+	}
+}, 'zh-TW');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'zh-TW';

+ 806 - 0
assets/lib/kindeditor/php/JSON.php

@@ -0,0 +1,806 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Converts to and from JSON format.
+ *
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
+ * format. It is easy for humans to read and write. It is easy for machines
+ * to parse and generate. It is based on a subset of the JavaScript
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+ * This feature can also be found in  Python. JSON is a text format that is
+ * completely language independent but uses conventions that are familiar
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
+ * ideal data-interchange language.
+ *
+ * This package provides a simple encoder and decoder for JSON notation. It
+ * is intended for use with client-side Javascript applications that make
+ * use of HTTPRequest to perform server communication functions - data can
+ * be encoded into JSON notation for use in a client-side javascript, or
+ * decoded from incoming Javascript requests. JSON format is native to
+ * Javascript, and can be directly eval()'ed with no further parsing
+ * overhead
+ *
+ * All strings should be in ASCII or UTF-8 format!
+ *
+ * LICENSE: Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met: Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following
+ * disclaimer. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * @category
+ * @package     Services_JSON
+ * @author      Michal Migurski <mike-json@teczno.com>
+ * @author      Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author      Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright   2005 Michal Migurski
+ * @version     CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
+ * @license     http://www.opensource.org/licenses/bsd-license.php
+ * @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+ */
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_SLICE',   1);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_STR',  2);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_ARR',  3);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_OBJ',  4);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_CMT', 5);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_LOOSE_TYPE', 16);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
+
+/**
+ * Converts to and from JSON format.
+ *
+ * Brief example of use:
+ *
+ * <code>
+ * // create a new instance of Services_JSON
+ * $json = new Services_JSON();
+ *
+ * // convert a complexe value to JSON notation, and send it to the browser
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+ * $output = $json->encode($value);
+ *
+ * print($output);
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+ *
+ * // accept incoming POST data, assumed to be in JSON notation
+ * $input = file_get_contents('php://input', 1000000);
+ * $value = $json->decode($input);
+ * </code>
+ */
+class Services_JSON
+{
+   /**
+    * constructs a new JSON instance
+    *
+    * @param    int     $use    object behavior flags; combine with boolean-OR
+    *
+    *                           possible values:
+    *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
+    *                                   "{...}" syntax creates associative arrays
+    *                                   instead of objects in decode().
+    *                           - SERVICES_JSON_SUPPRESS_ERRORS:  error suppression.
+    *                                   Values which can't be encoded (e.g. resources)
+    *                                   appear as NULL instead of throwing errors.
+    *                                   By default, a deeply-nested resource will
+    *                                   bubble up with an error, so all return values
+    *                                   from encode() should be checked with isError()
+    */
+    function Services_JSON($use = 0)
+    {
+        $this->use = $use;
+    }
+
+   /**
+    * convert a string from one UTF-16 char to one UTF-8 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf16  UTF-16 character
+    * @return   string  UTF-8 character
+    * @access   private
+    */
+    function utf162utf8($utf16)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding')) {
+            return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+        }
+
+        $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+        switch(true) {
+            case ((0x7F & $bytes) == $bytes):
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x7F & $bytes);
+
+            case (0x07FF & $bytes) == $bytes:
+                // return a 2-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xC0 | (($bytes >> 6) & 0x1F))
+                     . chr(0x80 | ($bytes & 0x3F));
+
+            case (0xFFFF & $bytes) == $bytes:
+                // return a 3-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xE0 | (($bytes >> 12) & 0x0F))
+                     . chr(0x80 | (($bytes >> 6) & 0x3F))
+                     . chr(0x80 | ($bytes & 0x3F));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }
+
+   /**
+    * convert a string from one UTF-8 char to one UTF-16 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf8   UTF-8 character
+    * @return   string  UTF-16 character
+    * @access   private
+    */
+    function utf82utf16($utf8)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding')) {
+            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+        }
+
+        switch(strlen($utf8)) {
+            case 1:
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return $utf8;
+
+            case 2:
+                // return a UTF-16 character from a 2-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x07 & (ord($utf8{0}) >> 2))
+                     . chr((0xC0 & (ord($utf8{0}) << 6))
+                         | (0x3F & ord($utf8{1})));
+
+            case 3:
+                // return a UTF-16 character from a 3-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr((0xF0 & (ord($utf8{0}) << 4))
+                         | (0x0F & (ord($utf8{1}) >> 2)))
+                     . chr((0xC0 & (ord($utf8{1}) << 6))
+                         | (0x7F & ord($utf8{2})));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }
+
+   /**
+    * encodes an arbitrary variable into JSON format
+    *
+    * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
+    *                           see argument 1 to Services_JSON() above for array-parsing behavior.
+    *                           if var is a strng, note that encode() always expects it
+    *                           to be in ASCII or UTF-8 format!
+    *
+    * @return   mixed   JSON string representation of input var or an error if a problem occurs
+    * @access   public
+    */
+    function encode($var)
+    {
+        switch (gettype($var)) {
+            case 'boolean':
+                return $var ? 'true' : 'false';
+
+            case 'NULL':
+                return 'null';
+
+            case 'integer':
+                return (int) $var;
+
+            case 'double':
+            case 'float':
+                return (float) $var;
+
+            case 'string':
+                // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+                $ascii = '';
+                $strlen_var = strlen($var);
+
+               /*
+                * Iterate over every character in the string,
+                * escaping with a slash or encoding to UTF-8 where necessary
+                */
+                for ($c = 0; $c < $strlen_var; ++$c) {
+
+                    $ord_var_c = ord($var{$c});
+
+                    switch (true) {
+                        case $ord_var_c == 0x08:
+                            $ascii .= '\b';
+                            break;
+                        case $ord_var_c == 0x09:
+                            $ascii .= '\t';
+                            break;
+                        case $ord_var_c == 0x0A:
+                            $ascii .= '\n';
+                            break;
+                        case $ord_var_c == 0x0C:
+                            $ascii .= '\f';
+                            break;
+                        case $ord_var_c == 0x0D:
+                            $ascii .= '\r';
+                            break;
+
+                        case $ord_var_c == 0x22:
+                        case $ord_var_c == 0x2F:
+                        case $ord_var_c == 0x5C:
+                            // double quote, slash, slosh
+                            $ascii .= '\\'.$var{$c};
+                            break;
+
+                        case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+                            // characters U-00000000 - U-0000007F (same as ASCII)
+                            $ascii .= $var{$c};
+                            break;
+
+                        case (($ord_var_c & 0xE0) == 0xC0):
+                            // characters U-00000080 - U-000007FF, mask 110XXXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+                            $c += 1;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xF0) == 0xE0):
+                            // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}));
+                            $c += 2;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xF8) == 0xF0):
+                            // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}));
+                            $c += 3;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xFC) == 0xF8):
+                            // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}));
+                            $c += 4;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+
+                        case (($ord_var_c & 0xFE) == 0xFC):
+                            // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}),
+                                         ord($var{$c + 5}));
+                            $c += 5;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+                    }
+                }
+
+                return '"'.$ascii.'"';
+
+            case 'array':
+               /*
+                * As per JSON spec if any array key is not an integer
+                * we must treat the the whole array as an object. We
+                * also try to catch a sparsely populated associative
+                * array with numeric keys here because some JS engines
+                * will create an array with empty indexes up to
+                * max_index which can cause memory issues and because
+                * the keys, which may be relevant, will be remapped
+                * otherwise.
+                *
+                * As per the ECMA and JSON specification an object may
+                * have any string as a property. Unfortunately due to
+                * a hole in the ECMA specification if the key is a
+                * ECMA reserved word or starts with a digit the
+                * parameter is only accessible using ECMAScript's
+                * bracket notation.
+                */
+
+                // treat as a JSON object
+                if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+                    $properties = array_map(array($this, 'name_value'),
+                                            array_keys($var),
+                                            array_values($var));
+
+                    foreach($properties as $property) {
+                        if(Services_JSON::isError($property)) {
+                            return $property;
+                        }
+                    }
+
+                    return '{' . join(',', $properties) . '}';
+                }
+
+                // treat it like a regular array
+                $elements = array_map(array($this, 'encode'), $var);
+
+                foreach($elements as $element) {
+                    if(Services_JSON::isError($element)) {
+                        return $element;
+                    }
+                }
+
+                return '[' . join(',', $elements) . ']';
+
+            case 'object':
+                $vars = get_object_vars($var);
+
+                $properties = array_map(array($this, 'name_value'),
+                                        array_keys($vars),
+                                        array_values($vars));
+
+                foreach($properties as $property) {
+                    if(Services_JSON::isError($property)) {
+                        return $property;
+                    }
+                }
+
+                return '{' . join(',', $properties) . '}';
+
+            default:
+                return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
+                    ? 'null'
+                    : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
+        }
+    }
+
+   /**
+    * array-walking function for use in generating JSON-formatted name-value pairs
+    *
+    * @param    string  $name   name of key to use
+    * @param    mixed   $value  reference to an array element to be encoded
+    *
+    * @return   string  JSON-formatted name-value pair, like '"name":value'
+    * @access   private
+    */
+    function name_value($name, $value)
+    {
+        $encoded_value = $this->encode($value);
+
+        if(Services_JSON::isError($encoded_value)) {
+            return $encoded_value;
+        }
+
+        return $this->encode(strval($name)) . ':' . $encoded_value;
+    }
+
+   /**
+    * reduce a string by removing leading and trailing comments and whitespace
+    *
+    * @param    $str    string      string value to strip of comments and whitespace
+    *
+    * @return   string  string value stripped of comments and whitespace
+    * @access   private
+    */
+    function reduce_string($str)
+    {
+        $str = preg_replace(array(
+
+                // eliminate single line comments in '// ...' form
+                '#^\s*//(.+)$#m',
+
+                // eliminate multi-line comments in '/* ... */' form, at start of string
+                '#^\s*/\*(.+)\*/#Us',
+
+                // eliminate multi-line comments in '/* ... */' form, at end of string
+                '#/\*(.+)\*/\s*$#Us'
+
+            ), '', $str);
+
+        // eliminate extraneous space
+        return trim($str);
+    }
+
+   /**
+    * decodes a JSON string into appropriate variable
+    *
+    * @param    string  $str    JSON-formatted string
+    *
+    * @return   mixed   number, boolean, string, array, or object
+    *                   corresponding to given JSON input string.
+    *                   See argument 1 to Services_JSON() above for object-output behavior.
+    *                   Note that decode() always returns strings
+    *                   in ASCII or UTF-8 format!
+    * @access   public
+    */
+    function decode($str)
+    {
+        $str = $this->reduce_string($str);
+
+        switch (strtolower($str)) {
+            case 'true':
+                return true;
+
+            case 'false':
+                return false;
+
+            case 'null':
+                return null;
+
+            default:
+                $m = array();
+
+                if (is_numeric($str)) {
+                    // Lookie-loo, it's a number
+
+                    // This would work on its own, but I'm trying to be
+                    // good about returning integers where appropriate:
+                    // return (float)$str;
+
+                    // Return float or int, as appropriate
+                    return ((float)$str == (integer)$str)
+                        ? (integer)$str
+                        : (float)$str;
+
+                } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+                    // STRINGS RETURNED IN UTF-8 FORMAT
+                    $delim = substr($str, 0, 1);
+                    $chrs = substr($str, 1, -1);
+                    $utf8 = '';
+                    $strlen_chrs = strlen($chrs);
+
+                    for ($c = 0; $c < $strlen_chrs; ++$c) {
+
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                        $ord_chrs_c = ord($chrs{$c});
+
+                        switch (true) {
+                            case $substr_chrs_c_2 == '\b':
+                                $utf8 .= chr(0x08);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\t':
+                                $utf8 .= chr(0x09);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\n':
+                                $utf8 .= chr(0x0A);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\f':
+                                $utf8 .= chr(0x0C);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\r':
+                                $utf8 .= chr(0x0D);
+                                ++$c;
+                                break;
+
+                            case $substr_chrs_c_2 == '\\"':
+                            case $substr_chrs_c_2 == '\\\'':
+                            case $substr_chrs_c_2 == '\\\\':
+                            case $substr_chrs_c_2 == '\\/':
+                                if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+                                   ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+                                    $utf8 .= $chrs{++$c};
+                                }
+                                break;
+
+                            case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+                                // single, escaped unicode character
+                                $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+                                       . chr(hexdec(substr($chrs, ($c + 4), 2)));
+                                $utf8 .= $this->utf162utf8($utf16);
+                                $c += 5;
+                                break;
+
+                            case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+                                $utf8 .= $chrs{$c};
+                                break;
+
+                            case ($ord_chrs_c & 0xE0) == 0xC0:
+                                // characters U-00000080 - U-000007FF, mask 110XXXXX
+                                //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 2);
+                                ++$c;
+                                break;
+
+                            case ($ord_chrs_c & 0xF0) == 0xE0:
+                                // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 3);
+                                $c += 2;
+                                break;
+
+                            case ($ord_chrs_c & 0xF8) == 0xF0:
+                                // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 4);
+                                $c += 3;
+                                break;
+
+                            case ($ord_chrs_c & 0xFC) == 0xF8:
+                                // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 5);
+                                $c += 4;
+                                break;
+
+                            case ($ord_chrs_c & 0xFE) == 0xFC:
+                                // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 6);
+                                $c += 5;
+                                break;
+
+                        }
+
+                    }
+
+                    return $utf8;
+
+                } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+                    // array, or object notation
+
+                    if ($str{0} == '[') {
+                        $stk = array(SERVICES_JSON_IN_ARR);
+                        $arr = array();
+                    } else {
+                        if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = array();
+                        } else {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = new stdClass();
+                        }
+                    }
+
+                    array_push($stk, array('what'  => SERVICES_JSON_SLICE,
+                                           'where' => 0,
+                                           'delim' => false));
+
+                    $chrs = substr($str, 1, -1);
+                    $chrs = $this->reduce_string($chrs);
+
+                    if ($chrs == '') {
+                        if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                            return $arr;
+
+                        } else {
+                            return $obj;
+
+                        }
+                    }
+
+                    //print("\nparsing {$chrs}\n");
+
+                    $strlen_chrs = strlen($chrs);
+
+                    for ($c = 0; $c <= $strlen_chrs; ++$c) {
+
+                        $top = end($stk);
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+
+                        if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+                            // found a comma that is not inside a string, array, etc.,
+                            // OR we've reached the end of the character list
+                            $slice = substr($chrs, $top['where'], ($c - $top['where']));
+                            array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+                            //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                            if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                                // we are in an array, so just push an element onto the stack
+                                array_push($arr, $this->decode($slice));
+
+                            } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                                // we are in an object, so figure
+                                // out the property name and set an
+                                // element in an associative array,
+                                // for now
+                                $parts = array();
+                                
+                                if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // "name":value pair
+                                    $key = $this->decode($parts[1]);
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // name:value pair, where name is unquoted
+                                    $key = $parts[1];
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                }
+
+                            }
+
+                        } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+                            // found a quote, and we are not inside a string
+                            array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+                            //print("Found start of string at {$c}\n");
+
+                        } elseif (($chrs{$c} == $top['delim']) &&
+                                 ($top['what'] == SERVICES_JSON_IN_STR) &&
+                                 ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
+                            // found a quote, we're in a string, and it's not escaped
+                            // we know that it's not escaped becase there is _not_ an
+                            // odd number of backslashes at the end of the string so far
+                            array_pop($stk);
+                            //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '[') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-bracket, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+                            //print("Found start of array at {$c}\n");
+
+                        } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+                            // found a right-bracket, and we're in an array
+                            array_pop($stk);
+                            //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '{') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-brace, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+                            //print("Found start of object at {$c}\n");
+
+                        } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+                            // found a right-brace, and we're in an object
+                            array_pop($stk);
+                            //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($substr_chrs_c_2 == '/*') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a comment start, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+                            $c++;
+                            //print("Found start of comment at {$c}\n");
+
+                        } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+                            // found a comment end, and we're in one now
+                            array_pop($stk);
+                            $c++;
+
+                            for ($i = $top['where']; $i <= $c; ++$i)
+                                $chrs = substr_replace($chrs, ' ', $i, 1);
+
+                            //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        }
+
+                    }
+
+                    if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                        return $arr;
+
+                    } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                        return $obj;
+
+                    }
+
+                }
+        }
+    }
+
+    /**
+     * @todo Ultimately, this should just call PEAR::isError()
+     */
+    function isError($data, $code = null)
+    {
+        if (class_exists('pear')) {
+            return PEAR::isError($data, $code);
+        } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
+                                 is_subclass_of($data, 'services_json_error'))) {
+            return true;
+        }
+
+        return false;
+    }
+}
+
+if (class_exists('PEAR_Error')) {
+
+    class Services_JSON_Error extends PEAR_Error
+    {
+        function Services_JSON_Error($message = 'unknown error', $code = null,
+                                     $mode = null, $options = null, $userinfo = null)
+        {
+            parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+        }
+    }
+
+} else {
+
+    /**
+     * @todo Ultimately, this class shall be descended from PEAR_Error
+     */
+    class Services_JSON_Error
+    {
+        function Services_JSON_Error($message = 'unknown error', $code = null,
+                                     $mode = null, $options = null, $userinfo = null)
+        {
+
+        }
+    }
+
+}
+    
+?>

+ 53 - 0
assets/lib/kindeditor/php/demo.php

@@ -0,0 +1,53 @@
+<?php
+	$htmlData = '';
+	if (!empty($_POST['content1'])) {
+		if (get_magic_quotes_gpc()) {
+			$htmlData = stripslashes($_POST['content1']);
+		} else {
+			$htmlData = $_POST['content1'];
+		}
+	}
+?>
+<!doctype html>
+<html>
+<head>
+	<meta charset="utf-8" />
+	<title>KindEditor PHP</title>
+	<link rel="stylesheet" href="../themes/default/default.css" />
+	<link rel="stylesheet" href="../plugins/code/prettify.css" />
+	<script charset="utf-8" src="../kindeditor.js"></script>
+	<script charset="utf-8" src="../lang/zh-CN.js"></script>
+	<script charset="utf-8" src="../plugins/code/prettify.js"></script>
+	<script>
+		KindEditor.ready(function(K) {
+			var editor1 = K.create('textarea[name="content1"]', {
+				cssPath : '../plugins/code/prettify.css',
+				uploadJson : '../php/upload_json.php',
+				fileManagerJson : '../php/file_manager_json.php',
+				allowFileManager : true,
+				afterCreate : function() {
+					var self = this;
+					K.ctrl(document, 13, function() {
+						self.sync();
+						K('form[name=example]')[0].submit();
+					});
+					K.ctrl(self.edit.doc, 13, function() {
+						self.sync();
+						K('form[name=example]')[0].submit();
+					});
+				}
+			});
+			prettyPrint();
+		});
+	</script>
+</head>
+<body>
+	<?php echo $htmlData; ?>
+	<form name="example" method="post" action="demo.php">
+		<textarea name="content1" style="width:700px;height:200px;visibility:hidden;"><?php echo htmlspecialchars($htmlData); ?></textarea>
+		<br />
+		<input type="submit" name="button" value="提交内容" /> (提交快捷键: Ctrl + Enter)
+	</form>
+</body>
+</html>
+

+ 137 - 0
assets/lib/kindeditor/php/file_manager_json.php

@@ -0,0 +1,137 @@
+<?php
+/**
+ * KindEditor PHP
+ *
+ * 本PHP程序是演示程序,建议不要直接在实际项目中使用。
+ * 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。
+ *
+ */
+
+require_once 'JSON.php';
+
+$php_path = dirname(__FILE__) . '/';
+$php_url = dirname($_SERVER['PHP_SELF']) . '/';
+
+//根目录路径,可以指定绝对路径,比如 /var/www/attached/
+$root_path = $php_path . '../attached/';
+//根目录URL,可以指定绝对路径,比如 http://www.yoursite.com/attached/
+$root_url = $php_url . '../attached/';
+//图片扩展名
+$ext_arr = array('gif', 'jpg', 'jpeg', 'png', 'bmp');
+
+//目录名
+$dir_name = empty($_GET['dir']) ? '' : trim($_GET['dir']);
+if (!in_array($dir_name, array('', 'image', 'flash', 'media', 'file'))) {
+	echo "Invalid Directory name.";
+	exit;
+}
+if ($dir_name !== '') {
+	$root_path .= $dir_name . "/";
+	$root_url .= $dir_name . "/";
+	if (!file_exists($root_path)) {
+		mkdir($root_path);
+	}
+}
+
+//根据path参数,设置各路径和URL
+if (empty($_GET['path'])) {
+	$current_path = realpath($root_path) . '/';
+	$current_url = $root_url;
+	$current_dir_path = '';
+	$moveup_dir_path = '';
+} else {
+	$current_path = realpath($root_path) . '/' . $_GET['path'];
+	$current_url = $root_url . $_GET['path'];
+	$current_dir_path = $_GET['path'];
+	$moveup_dir_path = preg_replace('/(.*?)[^\/]+\/$/', '$1', $current_dir_path);
+}
+//echo realpath($root_path);
+//排序形式,name or size or type
+$order = empty($_GET['order']) ? 'name' : strtolower($_GET['order']);
+
+//不允许使用..移动到上一级目录
+if (preg_match('/\.\./', $current_path)) {
+	echo 'Access is not allowed.';
+	exit;
+}
+//最后一个字符不是/
+if (!preg_match('/\/$/', $current_path)) {
+	echo 'Parameter is not valid.';
+	exit;
+}
+//目录不存在或不是目录
+if (!file_exists($current_path) || !is_dir($current_path)) {
+	echo 'Directory does not exist.';
+	exit;
+}
+
+//遍历目录取得文件信息
+$file_list = array();
+if ($handle = opendir($current_path)) {
+	$i = 0;
+	while (false !== ($filename = readdir($handle))) {
+		if ($filename{0} == '.') continue;
+		$file = $current_path . $filename;
+		if (is_dir($file)) {
+			$file_list[$i]['is_dir'] = true; //是否文件夹
+			$file_list[$i]['has_file'] = (count(scandir($file)) > 2); //文件夹是否包含文件
+			$file_list[$i]['filesize'] = 0; //文件大小
+			$file_list[$i]['is_photo'] = false; //是否图片
+			$file_list[$i]['filetype'] = ''; //文件类别,用扩展名判断
+		} else {
+			$file_list[$i]['is_dir'] = false;
+			$file_list[$i]['has_file'] = false;
+			$file_list[$i]['filesize'] = filesize($file);
+			$file_list[$i]['dir_path'] = '';
+			$file_ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
+			$file_list[$i]['is_photo'] = in_array($file_ext, $ext_arr);
+			$file_list[$i]['filetype'] = $file_ext;
+		}
+		$file_list[$i]['filename'] = $filename; //文件名,包含扩展名
+		$file_list[$i]['datetime'] = date('Y-m-d H:i:s', filemtime($file)); //文件最后修改时间
+		$i++;
+	}
+	closedir($handle);
+}
+
+//排序
+function cmp_func($a, $b) {
+	global $order;
+	if ($a['is_dir'] && !$b['is_dir']) {
+		return -1;
+	} else if (!$a['is_dir'] && $b['is_dir']) {
+		return 1;
+	} else {
+		if ($order == 'size') {
+			if ($a['filesize'] > $b['filesize']) {
+				return 1;
+			} else if ($a['filesize'] < $b['filesize']) {
+				return -1;
+			} else {
+				return 0;
+			}
+		} else if ($order == 'type') {
+			return strcmp($a['filetype'], $b['filetype']);
+		} else {
+			return strcmp($a['filename'], $b['filename']);
+		}
+	}
+}
+usort($file_list, 'cmp_func');
+
+$result = array();
+//相对于根目录的上一级目录
+$result['moveup_dir_path'] = $moveup_dir_path;
+//相对于根目录的当前目录
+$result['current_dir_path'] = $current_dir_path;
+//当前目录的URL
+$result['current_url'] = $current_url;
+//文件数
+$result['total_count'] = count($file_list);
+//文件列表数组
+$result['file_list'] = $file_list;
+
+//输出JSON字符串
+header('Content-type: application/json; charset=UTF-8');
+$json = new Services_JSON();
+echo $json->encode($result);

+ 139 - 0
assets/lib/kindeditor/php/upload_json.php

@@ -0,0 +1,139 @@
+<?php
+/**
+ * KindEditor PHP
+ *
+ * 本PHP程序是演示程序,建议不要直接在实际项目中使用。
+ * 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。
+ *
+ */
+
+require_once 'JSON.php';
+
+$php_path = dirname(__FILE__) . '/';
+$php_url = dirname($_SERVER['PHP_SELF']) . '/';
+
+//文件保存目录路径
+$save_path = $php_path . '../attached/';
+//文件保存目录URL
+$save_url = $php_url . '../attached/';
+//定义允许上传的文件扩展名
+$ext_arr = array(
+	'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'),
+	'flash' => array('swf', 'flv'),
+	'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'),
+	'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2'),
+);
+//最大文件大小
+$max_size = 1000000;
+
+$save_path = realpath($save_path) . '/';
+
+//PHP上传失败
+if (!empty($_FILES['imgFile']['error'])) {
+	switch($_FILES['imgFile']['error']){
+		case '1':
+			$error = '超过php.ini允许的大小。';
+			break;
+		case '2':
+			$error = '超过表单允许的大小。';
+			break;
+		case '3':
+			$error = '图片只有部分被上传。';
+			break;
+		case '4':
+			$error = '请选择图片。';
+			break;
+		case '6':
+			$error = '找不到临时目录。';
+			break;
+		case '7':
+			$error = '写文件到硬盘出错。';
+			break;
+		case '8':
+			$error = 'File upload stopped by extension。';
+			break;
+		case '999':
+		default:
+			$error = '未知错误。';
+	}
+	alert($error);
+}
+
+//有上传文件时
+if (empty($_FILES) === false) {
+	//原文件名
+	$file_name = $_FILES['imgFile']['name'];
+	//服务器上临时文件名
+	$tmp_name = $_FILES['imgFile']['tmp_name'];
+	//文件大小
+	$file_size = $_FILES['imgFile']['size'];
+	//检查文件名
+	if (!$file_name) {
+		alert("请选择文件。");
+	}
+	//检查目录
+	if (@is_dir($save_path) === false) {
+		alert("上传目录不存在。");
+	}
+	//检查目录写权限
+	if (@is_writable($save_path) === false) {
+		alert("上传目录没有写权限。");
+	}
+	//检查是否已上传
+	if (@is_uploaded_file($tmp_name) === false) {
+		alert("上传失败。");
+	}
+	//检查文件大小
+	if ($file_size > $max_size) {
+		alert("上传文件大小超过限制。");
+	}
+	//检查目录名
+	$dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']);
+	if (empty($ext_arr[$dir_name])) {
+		alert("目录名不正确。");
+	}
+	//获得文件扩展名
+	$temp_arr = explode(".", $file_name);
+	$file_ext = array_pop($temp_arr);
+	$file_ext = trim($file_ext);
+	$file_ext = strtolower($file_ext);
+	//检查扩展名
+	if (in_array($file_ext, $ext_arr[$dir_name]) === false) {
+		alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。");
+	}
+	//创建文件夹
+	if ($dir_name !== '') {
+		$save_path .= $dir_name . "/";
+		$save_url .= $dir_name . "/";
+		if (!file_exists($save_path)) {
+			mkdir($save_path);
+		}
+	}
+	$ymd = date("Ymd");
+	$save_path .= $ymd . "/";
+	$save_url .= $ymd . "/";
+	if (!file_exists($save_path)) {
+		mkdir($save_path);
+	}
+	//新文件名
+	$new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext;
+	//移动文件
+	$file_path = $save_path . $new_file_name;
+	if (move_uploaded_file($tmp_name, $file_path) === false) {
+		alert("上传文件失败。");
+	}
+	@chmod($file_path, 0644);
+	$file_url = $save_url . $new_file_name;
+
+	header('Content-type: text/html; charset=UTF-8');
+	$json = new Services_JSON();
+	echo $json->encode(array('error' => 0, 'url' => $file_url));
+	exit;
+}
+
+function alert($msg) {
+	header('Content-type: text/html; charset=UTF-8');
+	$json = new Services_JSON();
+	echo $json->encode(array('error' => 1, 'message' => $msg));
+	exit;
+}

+ 46 - 0
assets/lib/kindeditor/plugins/anchor/anchor.js

@@ -0,0 +1,46 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('anchor', function(K) {
+	var self = this, name = 'anchor', lang = self.lang(name + '.');
+	self.plugin.anchor = {
+		edit : function() {
+			var html = ['<div style="padding:20px;">',
+					'<div class="ke-dialog-row">',
+					'<label for="keName">' + lang.name + '</label>',
+					'<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />',
+					'</div>',
+					'</div>'].join('');
+			var dialog = self.createDialog({
+				name : name,
+				width : 300,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus();
+					}
+				}
+			});
+			var div = dialog.div,
+				nameBox = K('input[name="name"]', div);
+			var img = self.plugin.getSelectedAnchor();
+			if (img) {
+				nameBox.val(unescape(img.attr('data-ke-name')));
+			}
+			nameBox[0].focus();
+			nameBox[0].select();
+		},
+		'delete' : function() {
+			self.plugin.getSelectedAnchor().remove();
+		}
+	};
+	self.clickToolbar(name, self.plugin.anchor.edit);
+});

+ 54 - 0
assets/lib/kindeditor/plugins/autoheight/autoheight.js

@@ -0,0 +1,54 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('autoheight', function(K) {
+	var self = this;
+
+	if (!self.autoHeightMode) {
+		return;
+	}
+
+	var minHeight;
+
+	function hideScroll() {
+		var edit = self.edit;
+		var body = edit.doc.body;
+		edit.iframe[0].scroll = 'no';
+		body.style.overflowY = 'hidden';
+	}
+
+	function resetHeight() {
+		var edit = self.edit;
+		var body = edit.doc.body;
+		edit.iframe.height(minHeight);
+		self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight));
+	}
+
+	function init() {
+		minHeight = K.removeUnit(self.height);
+
+		self.edit.afterChange(resetHeight);
+		hideScroll();
+		resetHeight();
+	}
+
+	if (self.isCreated) {
+		init();
+	} else {
+		self.afterCreate(init);
+	}
+});
+
+/*
+* 如何实现真正的自动高度?
+* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。
+* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。
+* 由此就实现了真正的自动高度
+* 测试:chrome、firefox、IE9、IE8
+* */

+ 93 - 0
assets/lib/kindeditor/plugins/baidumap/baidumap.js

@@ -0,0 +1,93 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+// Baidu Maps: http://dev.baidu.com/wiki/map/index.php?title=%E9%A6%96%E9%A1%B5
+
+KindEditor.plugin('baidumap', function(K) {
+	var self = this, name = 'baidumap', lang = self.lang(name + '.');
+	var mapWidth = K.undef(self.mapWidth, 558);
+	var mapHeight = K.undef(self.mapHeight, 360);
+	self.clickToolbar(name, function() {
+		var html = ['<div style="padding:10px 20px;">',
+			'<div class="ke-header">',
+			// left start
+			'<div class="ke-left">',
+			lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ',
+			'<span class="ke-button-common ke-button-outer">',
+			'<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />',
+			'</span>',
+			'</div>',
+			// right start
+			'<div class="ke-right">',
+			'<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>',
+			'</div>',
+			'<div class="ke-clearfix"></div>',
+			'</div>',
+			'<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>',
+			'</div>'].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : mapWidth + 42,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					var map = win.map;
+					var centerObj = map.getCenter();
+					var center = centerObj.lng + ',' + centerObj.lat;
+					var zoom = map.getZoom();
+					var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage',
+						'?center=' + encodeURIComponent(center),
+						'&zoom=' + encodeURIComponent(zoom),
+						'&width=' + mapWidth,
+						'&height=' + mapHeight,
+						'&markers=' + encodeURIComponent(center),
+						'&markerStyles=' + encodeURIComponent('l,A')].join('');
+					if (checkbox[0].checked) {
+						self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>');
+					} else {
+						self.exec('insertimage', url);
+					}
+					self.hideDialog().focus();
+				}
+			},
+			beforeRemove : function() {
+				searchBtn.remove();
+				if (doc) {
+					doc.write('');
+				}
+				iframe.remove();
+			}
+		});
+		var div = dialog.div,
+			addressBox = K('[name="address"]', div),
+			searchBtn = K('[name="searchBtn"]', div),
+			checkbox = K('[name="insertDynamicMap"]', dialog.div),
+			win, doc;
+		var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>');
+		function ready() {
+			win = iframe[0].contentWindow;
+			doc = K.iframeDoc(iframe);
+		}
+		iframe.bind('load', function() {
+			iframe.unbind('load');
+			if (K.IE) {
+				ready();
+			} else {
+				setTimeout(ready, 0);
+			}
+		});
+		K('.ke-map', div).replaceWith(iframe);
+		// search map
+		searchBtn.click(function() {
+			win.search(addressBox.val());
+		});
+	});
+});

+ 83 - 0
assets/lib/kindeditor/plugins/baidumap/index.html

@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta charset="utf-8" />
+<meta name="keywords" content="百度地图,百度地图API,百度地图自定义工具,百度地图所见即所得工具" />
+<meta name="description" content="百度地图API自定义地图,帮助用户在可视化操作下生成百度地图" />
+<title>百度地图API自定义地图</title>
+<!--引用百度地图API-->
+<style type="text/css">
+	html,body{margin:0;padding:0;}
+	.iw_poi_title {color:#CC5522;font-size:14px;font-weight:bold;overflow:hidden;padding-right:13px;white-space:nowrap}
+	.iw_poi_content {font:12px arial,sans-serif;overflow:visible;padding-top:4px;white-space:-moz-pre-wrap;word-wrap:break-word}
+</style>
+<script type="text/javascript" src="http://api.map.baidu.com/api?key=&v=1.1&services=true"></script>
+</head>
+
+<body onload="initMap();">
+  <!--百度地图容器-->
+  <div style="width:697px;height:550px;border:#ccc solid 1px;" id="dituContent"></div>
+</body>
+<script type="text/javascript">
+	function getParam(name) {
+		return location.href.match(new RegExp('[?&]' + name + '=([^?&]+)', 'i')) ? decodeURIComponent(RegExp.$1) : '';
+	}
+	var centerParam = getParam('center');
+	var zoomParam = getParam('zoom');
+	var widthParam = getParam('width');
+	var heightParam = getParam('height');
+	var markersParam = getParam('markers');
+	var markerStylesParam = getParam('markerStyles');
+
+	//创建和初始化地图函数:
+	function initMap(){
+		// [FF]切换模式后报错
+		if (!window.BMap) {
+			return;
+		}
+		var dituContent = document.getElementById('dituContent');
+		dituContent.style.width = widthParam + 'px';
+		dituContent.style.height = heightParam + 'px';
+
+		createMap();//创建地图
+		setMapEvent();//设置地图事件
+		addMapControl();//向地图添加控件
+
+		// 创建标注
+		var markersArr = markersParam.split(',');
+		var point = new BMap.Point(markersArr[0], markersArr[1]);
+		var marker = new BMap.Marker(point);
+		map.addOverlay(marker); // 将标注添加到地图中
+	}
+
+	//创建地图函数:
+	function createMap(){
+		var map = new BMap.Map("dituContent");//在百度地图容器中创建一个地图
+		var centerArr = centerParam.split(',');
+		var point = new BMap.Point(centerArr[0], centerArr[1]);//定义一个中心点坐标
+		map.centerAndZoom(point, zoomParam);//设定地图的中心点和坐标并将地图显示在地图容器中
+		window.map = map;//将map变量存储在全局
+	}
+
+	//地图事件设置函数:
+	function setMapEvent(){
+		map.enableDragging();//启用地图拖拽事件,默认启用(可不写)
+		map.enableScrollWheelZoom();//启用地图滚轮放大缩小
+		map.enableDoubleClickZoom();//启用鼠标双击放大,默认启用(可不写)
+		map.enableKeyboard();//启用键盘上下左右键移动地图
+	}
+
+	//地图控件添加函数:
+	function addMapControl(){
+		//向地图中添加缩放控件
+	var ctrl_nav = new BMap.NavigationControl({anchor:BMAP_ANCHOR_TOP_LEFT,type:BMAP_NAVIGATION_CONTROL_LARGE});
+	map.addControl(ctrl_nav);
+		//向地图中添加缩略图控件
+	var ctrl_ove = new BMap.OverviewMapControl({anchor:BMAP_ANCHOR_BOTTOM_RIGHT,isOpen:1});
+	map.addControl(ctrl_ove);
+		//向地图中添加比例尺控件
+	var ctrl_sca = new BMap.ScaleControl({anchor:BMAP_ANCHOR_BOTTOM_LEFT});
+	map.addControl(ctrl_sca);
+	}
+</script>
+</html>

+ 43 - 0
assets/lib/kindeditor/plugins/baidumap/map.html

@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+	<head>
+		<meta charset="utf-8" />
+		<title>Baidu Maps</title>
+		<style>
+			html { height: 100% }
+			body { height: 100%; margin: 0; padding: 0; background-color: #FFF }
+		</style>
+		<script charset="utf-8" src="http://api.map.baidu.com/api?v=1.3"></script>
+		<script>
+			var map, geocoder;
+			function initialize() {
+				map = new BMap.Map('map_canvas');
+				var point = new BMap.Point(121.473704, 31.230393);
+				map.centerAndZoom(point, 11);
+				map.addControl(new BMap.NavigationControl());
+				map.enableScrollWheelZoom();
+
+				var gc = new BMap.Geocoder();
+				gc.getLocation(point, function(rs){
+					var addComp = rs.addressComponents;
+					var address = [addComp.city].join('');
+					parent.document.getElementById("kindeditor_plugin_map_address").value = address;
+				});
+			}
+			function search(address) {
+				if (!map) return;
+				var local = new BMap.LocalSearch(map, {
+					renderOptions: {
+						map: map,
+						autoViewport: true,
+						selectFirstResult: false
+					}
+				});
+				local.search(address);
+			}
+		</script>
+	</head>
+	<body onload="initialize();">
+		<div id="map_canvas" style="width:100%; height:100%"></div>
+	</body>
+</html>

+ 29 - 0
assets/lib/kindeditor/plugins/clearhtml/clearhtml.js

@@ -0,0 +1,29 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('clearhtml', function(K) {
+	var self = this, name = 'clearhtml';
+	self.clickToolbar(name, function() {
+		self.focus();
+		var html = self.html();
+		html = html.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/ig, '');
+		html = html.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/ig, '');
+		html = K.formatHtml(html, {
+			a : ['href', 'target'],
+			embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'],
+			img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'],
+			table : ['border'],
+			'td,th' : ['rowspan', 'colspan'],
+			'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : []
+		});
+		self.html(html);
+		self.cmd.selection(true);
+		self.addBookmark();
+	});
+});

+ 62 - 0
assets/lib/kindeditor/plugins/code/code.js

@@ -0,0 +1,62 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+// google code prettify: http://google-code-prettify.googlecode.com/
+// http://google-code-prettify.googlecode.com/
+
+KindEditor.plugin('code', function(K) {
+	var self = this, name = 'code';
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			html = ['<div style="padding:10px 20px;">',
+				'<div class="ke-dialog-row">',
+				'<select class="ke-code-type">',
+				'<option value="js">JavaScript</option>',
+				'<option value="html">HTML</option>',
+				'<option value="css">CSS</option>',
+				'<option value="php">PHP</option>',
+				'<option value="pl">Perl</option>',
+				'<option value="py">Python</option>',
+				'<option value="rb">Ruby</option>',
+				'<option value="java">Java</option>',
+				'<option value="vb">ASP/VB</option>',
+				'<option value="cpp">C/C++</option>',
+				'<option value="cs">C#</option>',
+				'<option value="xml">XML</option>',
+				'<option value="bsh">Shell</option>',
+				'<option value="">Other</option>',
+				'</select>',
+				'</div>',
+				'<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>',
+				'</div>'].join(''),
+			dialog = self.createDialog({
+				name : name,
+				width : 450,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var type = K('.ke-code-type', dialog.div).val(),
+							code = textarea.val(),
+							cls = type === '' ? '' :  ' lang-' + type,
+							html = '<pre class="prettyprint' + cls + '">\n' + K.escape(code) + '</pre> ';
+						if (K.trim(code) === '') {
+							alert(lang.pleaseInput);
+							textarea[0].focus();
+							return;
+						}
+						self.insertHtml(html).hideDialog().focus();
+					}
+				}
+			}),
+			textarea = K('textarea', dialog.div);
+		textarea[0].focus();
+	});
+});

+ 13 - 0
assets/lib/kindeditor/plugins/code/prettify.css

@@ -0,0 +1,13 @@
+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
+
+pre.prettyprint {
+	border: 0;
+	border-left: 3px solid rgb(204, 204, 204);
+	margin-left: 2em;
+	padding: 0.5em;
+	font-size: 110%;
+	display: block;
+	font-family: "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
+	margin: 1em 0px;
+	white-space: pre;
+}

+ 28 - 0
assets/lib/kindeditor/plugins/code/prettify.js

@@ -0,0 +1,28 @@
+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
+f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
+(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
+{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
+t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
+"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
+l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
+m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
+a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
+j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
+I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
+250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
+PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();

+ 129 - 0
assets/lib/kindeditor/plugins/emoticons/emoticons.js

@@ -0,0 +1,129 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('emoticons', function(K) {
+	var self = this, name = 'emoticons',
+		path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'),
+		allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons,
+		currentPageNum = 1;
+	self.clickToolbar(name, function() {
+		var rows = 5, cols = 9, total = 135, startNum = 0,
+			cells = rows * cols, pages = Math.ceil(total / cells),
+			colsHalf = Math.floor(cols / 2),
+			wrapperDiv = K('<div class="ke-plugin-emoticons"></div>'),
+			elements = [],
+			menu = self.createMenu({
+				name : name,
+				beforeRemove : function() {
+					removeEvent();
+				}
+			});
+		menu.div.append(wrapperDiv);
+		var previewDiv, previewImg;
+		if (allowPreview) {
+			previewDiv = K('<div class="ke-preview"></div>').css('right', 0);
+			previewImg = K('<img class="ke-preview-img" src="' + path + startNum + '.gif" />');
+			wrapperDiv.append(previewDiv);
+			previewDiv.append(previewImg);
+		}
+		function bindCellEvent(cell, j, num) {
+			if (previewDiv) {
+				cell.mouseover(function() {
+					if (j > colsHalf) {
+						previewDiv.css('left', 0);
+						previewDiv.css('right', '');
+					} else {
+						previewDiv.css('left', '');
+						previewDiv.css('right', 0);
+					}
+					previewImg.attr('src', path + num + '.gif');
+					K(this).addClass('ke-on');
+				});
+			} else {
+				cell.mouseover(function() {
+					K(this).addClass('ke-on');
+				});
+			}
+			cell.mouseout(function() {
+				K(this).removeClass('ke-on');
+			});
+			cell.click(function(e) {
+				self.insertHtml('<img src="' + path + num + '.gif" border="0" alt="" />').hideMenu().focus();
+				e.stop();
+			});
+		}
+		function createEmoticonsTable(pageNum, parentDiv) {
+			var table = document.createElement('table');
+			parentDiv.append(table);
+			if (previewDiv) {
+				K(table).mouseover(function() {
+					previewDiv.show('block');
+				});
+				K(table).mouseout(function() {
+					previewDiv.hide();
+				});
+				elements.push(K(table));
+			}
+			table.className = 'ke-table';
+			table.cellPadding = 0;
+			table.cellSpacing = 0;
+			table.border = 0;
+			var num = (pageNum - 1) * cells + startNum;
+			for (var i = 0; i < rows; i++) {
+				var row = table.insertRow(i);
+				for (var j = 0; j < cols; j++) {
+					var cell = K(row.insertCell(j));
+					cell.addClass('ke-cell');
+					bindCellEvent(cell, j, num);
+					var span = K('<span class="ke-img"></span>')
+						.css('background-position', '-' + (24 * num) + 'px 0px')
+						.css('background-image', 'url(' + path + 'static.gif)');
+					cell.append(span);
+					elements.push(cell);
+					num++;
+				}
+			}
+			return table;
+		}
+		var table = createEmoticonsTable(currentPageNum, wrapperDiv);
+		function removeEvent() {
+			K.each(elements, function() {
+				this.unbind();
+			});
+		}
+		var pageDiv;
+		function bindPageEvent(el, pageNum) {
+			el.click(function(e) {
+				removeEvent();
+				table.parentNode.removeChild(table);
+				pageDiv.remove();
+				table = createEmoticonsTable(pageNum, wrapperDiv);
+				createPageTable(pageNum);
+				currentPageNum = pageNum;
+				e.stop();
+			});
+		}
+		function createPageTable(currentPageNum) {
+			pageDiv = K('<div class="ke-page"></div>');
+			wrapperDiv.append(pageDiv);
+			for (var pageNum = 1; pageNum <= pages; pageNum++) {
+				if (currentPageNum !== pageNum) {
+					var a = K('<a href="javascript:;">[' + pageNum + ']</a>');
+					bindPageEvent(a, pageNum);
+					pageDiv.append(a);
+					elements.push(a);
+				} else {
+					pageDiv.append(K('@[' + pageNum + ']'));
+				}
+				pageDiv.append(K('@&nbsp;'));
+			}
+		}
+		createPageTable(currentPageNum);
+	});
+});

BIN
assets/lib/kindeditor/plugins/emoticons/images/0.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/1.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/10.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/100.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/101.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/102.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/103.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/104.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/105.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/106.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/107.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/108.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/109.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/11.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/110.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/111.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/112.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/113.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/114.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/115.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/116.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/117.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/118.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/119.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/12.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/120.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/121.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/122.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/123.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/124.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/125.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/126.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/127.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/128.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/129.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/13.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/130.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/131.gif


BIN
assets/lib/kindeditor/plugins/emoticons/images/132.gif


Some files were not shown because too many files changed in this diff