diff --git a/assets/css/app.css b/assets/css/app.css new file mode 100644 index 0000000..847e38c --- /dev/null +++ b/assets/css/app.css @@ -0,0 +1,233 @@ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +input, button, textarea { + font-family: inherit; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: normal; +} + +em { + font-style: normal !important; +} + +html, body { + height: 100%; + font-family: 'PingFang SC', BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif; +} + +.el-message__icon { + display: none +} + +.container { + height: 100%; + display: flex; + flex-direction: column; +} + +.top { + height: 60px; + padding: 10px 20px; + display: flex; + align-items: center; + margin-right: 20px; +} + +.web-title { + margin: 0 15px 0 5px; +} + +.web-icon { + width: auto; + height: 1.5rem; + vertical-align: middle; +} + +#editor { + height: 100%; + display: block; + border: none; + width: 100%; + padding: 10px; +} + +section { + height: 100%; +} + +.main-body { + display: flex; + flex-direction: column; + padding-top: 0; + padding-bottom: 10px; +} + +.ctrl { + flex-basis: 60px; + flex-grow: 1; + flex-shrink: 1; + display: flex; + align-items: center; +} + +.preview-wrapper { + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); + padding: 0; + align-items: center; + justify-content: center; + display: flex; + overflow: scroll; +} + +.main-section { + display: flex; + height: 100%; +} + +.hint { + opacity: 0.6; + margin: 20px 0; +} + +.preview { + margin: 0 -20px; + width: 375px; + padding: 20px; + font-size: 14px; + box-sizing: border-box; + outline: none; + box-shadow: 0 0 60px rgba(0, 0, 0, 0.1); +} + +.preview table { + margin-bottom: 10px; + border-collapse: collapse; + display: table; + width: 100% !important; +} +/* +.preview table tr:nth-child(even){ + background: rgb(250, 250, 250); +} + */ +.select-item-left { + float: left; +} + +.select-item-right { + float: right; + color: #8492a6; + font-size: 13px; +} + +.CodeMirror { + height: 100% !important; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); + font-size: 14px; + padding: 20px; + width: 100% !important; + font-family: 'PingFang SC', BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif; +} + +/* ele ui */ +.el-form-item { + margin-bottom: 0 !important; +} + +.el-tooltip { + cursor: pointer; +} + +/*wechat code block*/ +.rich_media_content .code-snippet *, .rich_media_content .code-snippet__fix * { + max-width: 1000% !important; +} + +.code-snippet__fix { + word-wrap: break-word !important; + font-size: 14px; + margin: 10px 8px; + color: #333; + position: relative; + background-color: rgba(0, 0, 0, 0.03); + border: 1px solid #f0f0f0; + border-radius: 2px; + display: flex; + line-height: 24px; +} + +.code-snippet__fix .code-snippet__line-index { + counter-reset: line; + flex-shrink: 0; + height: 100%; + padding: 1em; + list-style-type: none; +} + +.code-snippet__fix .code-snippet__line-index li { + list-style-type: none; + text-align: right; +} + +.code-snippet__fix .code-snippet__line-index li::before { + min-width: 1.5em; + text-align: right; + left: -2.5em; + counter-increment: line; + content: counter(line); + display: inline; + color: rgba(0, 0, 0, 0.15); +} + +.code-snippet__fix pre { + overflow-x: auto; + padding: 1em 1em 1em 1em; + white-space: normal; + flex: 1; + -webkit-overflow-scrolling: touch; +} + +.code-snippet__fix code { + text-align: left; + font-size: 14px; + white-space: pre; + display: flex; + position: relative; + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +::-webkit-scrollbar { + width: 6px; + height: 6px; + background-color: #FFF; +} + +::-webkit-scrollbar-track { + border-radius: 6px; + background-color: rgba(200, 200, 200, 0.3); +} + +::-webkit-scrollbar-thumb { + border-radius: 6px; + background-color: rgba(144, 146, 152, 0.5); + transition: background-color .3s; +} + +::-webkit-scrollbar-thumb:hover { + background-color: rgba(144, 146, 152, 0.5); +} + +.CodeMirror-vscrollbar:focus { + outline: none; +} + +.CodeMirror-scroll, .preview-wrapper { + overflow: unset!important; + overflow-y: scroll!important; +} \ No newline at end of file diff --git a/assets/css/loading.css b/assets/css/loading.css new file mode 100644 index 0000000..f91fef5 --- /dev/null +++ b/assets/css/loading.css @@ -0,0 +1,43 @@ +.loading { + text-align: center; + position: fixed; + width: 100%; + height: 100%; + overflow: hidden; + z-index: 99999; + background-color: #f2f2f2; +} + +.loading-wrapper { + position: fixed; + top: 50%; + left: 50%; + -webkit-transform: translateX(-50%) translateY(-50%); + -moz-transform: translateX(-50%) translateY(-50%); + -ms-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); +} + +.loading-text { + line-height: 1.4; + font-size: 1.2rem; + font-weight: bold; + margin-bottom: 1rem; +} + +.loading-anim { + width: 35px; + height: 35px; + border: 5px solid rgba(189, 189, 189, 0.25); + border-left-color: rgba(66, 185, 131, 0.9); + border-top-color: rgba(66, 185, 131, 0.9); + border-radius: 50%; + display: inline-block; + animation: rotate 600ms infinite linear; +} + +@keyframes rotate { + to { + transform: rotate(1turn) + } +} diff --git a/assets/css/style-mirror.css b/assets/css/style-mirror.css new file mode 100644 index 0000000..bf98442 --- /dev/null +++ b/assets/css/style-mirror.css @@ -0,0 +1,104 @@ +/* + + Name: Base16 Default Light + Author: Chris Kempson (http://chriskempson.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-style-mirror.CodeMirror { + background: #f5f5f5; + color: #444; + font-size: 16px; + padding: 20px; + line-height: 25px; + } + .cm-s-style-mirror div.CodeMirror-selected { + background: #e0e0e0; + } + .cm-s-style-mirror .CodeMirror-line::selection, + .cm-s-style-mirror .CodeMirror-line > span::selection, + .cm-s-style-mirror .CodeMirror-line > span > span::selection { + background: #e0e0e0; + } + .cm-s-style-mirror .CodeMirror-line::-moz-selection, + .cm-s-style-mirror .CodeMirror-line > span::-moz-selection, + .cm-s-style-mirror .CodeMirror-line > span > span::-moz-selection { + background: #e0e0e0; + } + .cm-s-style-mirror .CodeMirror-gutters { + background: #f5f5f5; + border-right: 0px; + } + .cm-s-style-mirror .CodeMirror-guttermarker { + color: #ac4142; + } + .cm-s-style-mirror .CodeMirror-guttermarker-subtle { + color: #b0b0b0; + } + .cm-s-style-mirror .CodeMirror-linenumber { + color: #b0b0b0; + } + .cm-s-style-mirror .CodeMirror-cursor { + border-left: 1px solid #505050; + } + + .cm-s-style-mirror span.cm-comment { + color:green; + } + .cm-s-style-mirror span.cm-atom { + color: #aa759f; + } + .cm-s-style-mirror span.cm-number { + color: #aa759f; + } + + .cm-s-style-mirror span.cm-property, + .cm-s-style-mirror span.cm-attribute { + color: #90a959; + } + .cm-s-style-mirror span.cm-keyword { + color: #023a52; + } + .cm-s-style-mirror span.cm-string { + color: #e46918; + } + + .cm-s-style-mirror span.cm-variable { + color: #90a959; + } + .cm-s-style-mirror span.cm-variable-2 { + color: #00695f; + } + .cm-s-style-mirror span.cm-variable-3 { + color: #2e6e8a; + } + .cm-s-style-mirror span.cm-def { + color: #d28445; + } + .cm-s-style-mirror span.cm-bracket { + color: #202020; + } + .cm-s-style-mirror span.cm-tag { + color:#000; + } + .cm-s-style-mirror span.cm-link { + color: #b26a00; + } + .cm-s-style-mirror span.cm-error { + /* background: #ac4142; + color: #f5f5f5; */ + text-decoration: underline; + text-decoration-style: wavy; + text-decoration-color: #df8d8e; + } + .cm-s-style-mirror .CodeMirror-activeline-background { + background: #dddcdc; + } + .cm-s-style-mirror .CodeMirror-matchingbracket { + color: rgb(32,32,32) !important; + background-color: rgba(0,0,0,0.1) !important; + } + \ No newline at end of file diff --git a/assets/images/dfa.png b/assets/images/dfa.png new file mode 100644 index 0000000..248df5a Binary files /dev/null and b/assets/images/dfa.png differ diff --git a/assets/images/doocs-md-copy-and-paste.gif b/assets/images/doocs-md-copy-and-paste.gif new file mode 100644 index 0000000..e20d615 Binary files /dev/null and b/assets/images/doocs-md-copy-and-paste.gif differ diff --git a/assets/images/doocs-md-custom-css.gif b/assets/images/doocs-md-custom-css.gif new file mode 100644 index 0000000..b4cef01 Binary files /dev/null and b/assets/images/doocs-md-custom-css.gif differ diff --git a/assets/images/doocs-md-select-and-change-color-theme.gif b/assets/images/doocs-md-select-and-change-color-theme.gif new file mode 100644 index 0000000..a702a2e Binary files /dev/null and b/assets/images/doocs-md-select-and-change-color-theme.gif differ diff --git a/assets/images/doocs-md-upload-image.gif b/assets/images/doocs-md-upload-image.gif new file mode 100644 index 0000000..24499d2 Binary files /dev/null and b/assets/images/doocs-md-upload-image.gif differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..e151dec Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/images/feedback.gif b/assets/images/feedback.gif new file mode 100644 index 0000000..acfb96d Binary files /dev/null and b/assets/images/feedback.gif differ diff --git a/assets/images/juej.gif b/assets/images/juej.gif new file mode 100644 index 0000000..c4a3343 Binary files /dev/null and b/assets/images/juej.gif differ diff --git a/assets/images/juex.gif b/assets/images/juex.gif new file mode 100644 index 0000000..71821a3 Binary files /dev/null and b/assets/images/juex.gif differ diff --git a/assets/images/logo-2.png b/assets/images/logo-2.png new file mode 100644 index 0000000..4239279 Binary files /dev/null and b/assets/images/logo-2.png differ diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 0000000..54f9eab Binary files /dev/null and b/assets/images/logo.png differ diff --git a/assets/images/prefixtree.png b/assets/images/prefixtree.png new file mode 100644 index 0000000..ca11180 Binary files /dev/null and b/assets/images/prefixtree.png differ diff --git a/assets/images/qrcode-for-doocs.gif b/assets/images/qrcode-for-doocs.gif new file mode 100644 index 0000000..413eddc Binary files /dev/null and b/assets/images/qrcode-for-doocs.gif differ diff --git a/assets/images/qrcode-for-doocs.jpg b/assets/images/qrcode-for-doocs.jpg new file mode 100644 index 0000000..bd1db5d Binary files /dev/null and b/assets/images/qrcode-for-doocs.jpg differ diff --git a/assets/images/qrcode-for-yanglbme.jpg b/assets/images/qrcode-for-yanglbme.jpg new file mode 100644 index 0000000..5bd385b Binary files /dev/null and b/assets/images/qrcode-for-yanglbme.jpg differ diff --git a/assets/scripts/default-content.js b/assets/scripts/default-content.js new file mode 100644 index 0000000..800150a --- /dev/null +++ b/assets/scripts/default-content.js @@ -0,0 +1,99 @@ +const DEFAULT_CONTENT = +`# 示例文章:Google 搜索的即时自动补全功能究竟是如何“工作”的? +> Google 搜索**自动补全功能**的强大,相信不少朋友都能感受到,它帮助我们更快地“补全”我们所要输入的搜索关键字。那么,它怎么知道我们要输入什么内容?它又是如何工作的?在这篇文章里,我们一起来看看。 + +## 使用自动补全 +Google 搜索的自动补全功能可以在 Google 搜索应用的大多数位置使用,包括 [Google](https://www.google.com/) 主页、适用于 IOS 和 Android 的 Google 应用,我们只需要在 Google 搜索框上开始键入关键字,就可以看到联想词了。 + +![](https://imgkr.cn-bj.ufileos.com/17ed83bf-e028-4db2-9503-5a3b4e64deee.gif) + +在上图示例中,我们可以看到,输入关键字 \`juej\`,Google 搜索会联想到“掘金”、“掘金小册”、“绝句”等等,好处就是,我们无须输入完整的关键字即可轻松完成针对这些 topics 的搜索。 + +谷歌搜索的自动补全功能对于使用移动设备的用户来说特别有用,用户可以轻松在难以键入的小屏幕上完成搜索。当然,对于移动设备用户和台式机用户而言,这都节省了大量的时间。根据 Google 官方报告,自动补全功能可以减少大约 25% 的打字,累积起来,预计每天可以节省 200 多年的打字时间。是的,每天! + +> 注意,本文所提到的“**联想词**”与“**预测**”,是同一个意思。 + +## 基于“预测”而非“建议” +Google 官方将自动补全功能称之为“预测”,而不是“建议”,为什么呢?其实是有充分理由的。自动补全功能是为了**帮助用户完成他们打算进行的搜索**,而不是建议用户要执行什么搜索。 + +那么,Google 是如何确定这些“预测”的?其实,Google 会根据趋势搜索 [trends](https://trends.google.com/trends/?geo=US) 给到我们这些“预测”。简单来说,哪个热门、哪个搜索频率高,就更可能推给我们。当然,这也与我们当前所处的位置以及我们的搜索历史相关。 + +另外,这些“预测”也会随着我们键入的关键字的变更而更改。例如,当我们把键入的关键字从 \`juej\` 更改为 \`juex\` 时,与“掘金”相关的预测会“消失”,同时,与“觉醒”、“决心”相关联的词会出现。 + +![](https://imgkr.cn-bj.ufileos.com/5b17dc99-606d-42c1-9f86-e09e88aaa822.gif) + +## 为什么看不到某些联想词? +如果我们在输入某个关键字时看不到联想词,那么表明 Google 的算法可能检测到: + +- 这个关键字不是热门字词; +- 搜索的字词太新了,我们可能需要等待几天或几周才能看到联想词; +- 这是一个侮辱性或敏感字词,这个搜索字词违反了 Google 的相关政策。更加详细的情况,可以了解 [Google 搜索自动补全政策](https://support.google.com/websearch/answer/7368877)。 + +## 为什么会看到某些不当的联想词? +Google 拥有专门设计的系统,可以自动捕获不适当的预测结果而不显示出来。然而,Google 每天需要处理数十亿次搜索,这意味着 Google 每天会显示数十亿甚至上百亿条预测。再好的系统,也可能存在缺陷,不正确的预测也可能随时会出现。 + +我们作为 Google 搜索的用户,如果认定某条预测违反了相关的搜索自动补全政策,可以进行举报反馈,点击右下角“**举报不当的联想查询**”并勾选相关选项即可。 + +![](https://imgkr.cn-bj.ufileos.com/6ca8185d-12c6-4550-bb4e-e49cfbf56db7.gif) + +## 如何实现自动补全算法? +目前,Google 官方似乎并没有公开搜索自动补全的算法实现,但是业界在这方面已经有了不少研究。 + +一个好的自动补全器必须是快速的,并且在用户键入下一个字符后立即更新联想词列表。**自动补全器的核心是一个函数,它接受输入的前缀,并搜索以给定前缀开头的词汇或语句列表**。通常来说,只需要返回少量的数目即可。 + +接下来,我们先从一个简单且低效的实现开始,并在此基础上逐步构建更高效的方法。 + +### 词汇表实现 +一个**简单粗暴的实现方式**是:顺序查找词汇表,依次检查每个词汇,看它是否以给定的前缀开头。 + +但是,此方法需要将前缀与每个词汇进行匹配检查,若词汇量较少,这种方式可能勉强行得通。但是,如果词汇量规模较大,效率就太低了。 + +一个**更好的实现方式是**:让词汇按字典顺序排序。借助二分搜索算法,可以快速搜索有序词汇表中的前缀。由于二分搜索的每一步都会将搜索的范围减半,因此,总的搜索时间与词汇表中单词数量的对数成正比,即时间复杂度是 \`O(log N)\`。二分搜索的性能很好,但有没有更好的实现呢?当然有,往下看。 + +### 前缀树实现 +通常来说,许多词汇都以相同的前缀开头,比如 \`need\`、\`nested\` 都以 \`ne\` 开头,\`seed\`、\`speed\` 都以 \`s\` 开头。要是为每个单词分别存储公共前缀似乎很浪费。 + +![](https://imgkr.cn-bj.ufileos.com/7cc3cf37-040a-420e-8ef9-d05e92c82cfd.png) + +前缀树是一种利用公共前缀来加速补全速度的数据结构。前缀树在节点树中排列一组单词,单词沿着从根节点到叶子节点的路径存储,树的层次对应于前缀的字母位置。 + +前缀的补全是顺着前缀定义的路径来查找的。例如,在上图的前缀树中,前缀 \`ne\` 对应于从子节点取左边缘 \`N\` 和唯一边缘 \`E\` 的路径。然后可以通过继续遍历从 \`E\` 节点可以达到的所有叶节点来生成补全列表。在图中,\`ne\` 的补全可以是两个分支:\`-ed\` 和 \`-sted\`。如果在数中找不到由前缀定义的路径,则说明词汇表中不包含以该前缀开头的单词。 + +### 有限状态自动机(DFA)实现 +前缀树可以有效处理公共前缀,但是,对于其他共享词部分,仍会分别存储在每个分支中。比如,后缀 \`ed\`、\`ing\`、\`tion\` 在英文单词中特别常见。在上一个例子中,\`e\`、\`d\` 分别存放在了每一个分支上。 + +有没有一种方法可以更加节省存储空间呢?有的,那就是 DFA。 + +
[${x[0]}]
: ${x[1]}[${x[0]}]
${x[1]}: ${x[2]}${footnoteArray.join('\n')}
`; + }; + + this.buildAddition = () => { + return ` + + `; + } + + this.setOptions = newOpts => { + this.opts = merge(this.opts, newOpts); + }; + + this.hasFootnotes = () => footnotes.length !== 0; + + this.getRenderer = (status) => { + footnotes = []; + footnoteIndex = 0; + + styleMapping = this.buildTheme(this.opts.theme); + let renderer = new marked.Renderer(); + + renderer.heading = (text, level) => { + switch (level) { + case 1: + return `${text}
`; + + renderer.blockquote = text => { + text = text.replace(/`); + return `
${text}`; + }; + renderer.code = (text, infoString) => { + text = text.replace(//g, ">"); + + let lines = text.split('\n'); + let codeLines = []; + let numbers = []; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + codeLines.push(`
${(line || '
')}
`);
+ numbers.push('');
+ }
+ let lang = infoString || '';
+
+ return `
+ + ${codeLines.join('')} ++
${text}
`;
+ renderer.listitem = text => `<%s/>${text}`;
+
+ renderer.list = (text, ordered, start) => {
+ text = text.replace(/<\/*p.*?>/g, '');
+ let segments = text.split(`<%s/>`);
+ if (!ordered) {
+ text = segments.join('•');
+ return `${text}
`; + } + text = segments[0]; + for (let i = 1; i < segments.length; i++) { + text = text + i + '.' + segments[i]; + } + return `${text}
`; + }; + renderer.image = (href, title, text) => { + let subText = ''; + if (text) { + subText = `${text}
`; + renderer.table = (header, body) => `['.concat(e[0],"]
: ").concat(e[1],"['.concat(e[0],"]
").concat(e[1],": ").concat(e[2],"").concat(e.join("\n"),"
")},this.buildAddition=function(){return'\n \n '},this.setOptions=function(e){t.opts=s(t.opts,e)},this.hasFootnotes=function(){return 0!==o.length},this.getRenderer=function(e){o=[],i=0,r=t.buildTheme(t.opts.theme);var a=new Re.a.Renderer;return a.heading=function(e,t){switch(t){case 1:return"").concat(e,"
")},a.blockquote=function(e){return e=e.replace(/")),"
").concat(e,"")},a.code=function(e,t){e=e.replace(//g,">");for(var n=e.split("\n"),o=[],i=[],r=0;r
\n ').concat(o.join(""),"\n\n
").concat(e,"
")},a.listitem=function(e){return"<%s/>').concat(e,"")},a.list=function(e,t,n){e=e.replace(/<\/*p.*?>/g,"");var o=e.split("<%s/>");if(!t)return e=o.join("•"),"").concat(e,"
");e=o[0];for(var i=1;i").concat(e,"
")},a.table=function(e,t){return'扫码关注我的公众号,原创技术文章第一时间推送!
\n \n[${x[0]}]
: ${x[1]}[${x[0]}]
${x[1]}: ${x[2]}${footnoteArray.join('\\n')}
`\n }\n\n this.buildAddition = () => {\n return `\n \n `\n }\n\n this.setOptions = newOpts => {\n this.opts = merge(this.opts, newOpts)\n }\n\n this.hasFootnotes = () => footnotes.length !== 0\n\n this.getRenderer = (status) => {\n footnotes = []\n footnoteIndex = 0\n\n styleMapping = this.buildTheme(this.opts.theme)\n let renderer = new marked.Renderer()\n\n renderer.heading = (text, level) => {\n switch (level) {\n case 1:\n return `${text}
`\n\n renderer.blockquote = text => {\n text = text.replace(/`)\n return `
${text}`\n }\n renderer.code = (text, infoString) => {\n text = text.replace(//g, '>')\n\n let lines = text.split('\\n')\n let codeLines = []\n let numbers = []\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n codeLines.push(`
${(line || '
')}
`)\n numbers.push('')\n }\n let lang = infoString || ''\n\n return `\n \n ${codeLines.join('')}\n\n
${text}
`\n renderer.listitem = text => `<%s/>${text}`\n\n renderer.list = (text, ordered, start) => {\n text = text.replace(/<\\/*p.*?>/g, '')\n let segments = text.split(`<%s/>`)\n if (!ordered) {\n text = segments.join('•')\n return `${text}
`\n }\n text = segments[0]\n for (let i = 1; i < segments.length; i++) {\n text = text + i + '.' + segments[i]\n }\n return `${text}
`\n }\n renderer.image = (href, title, text) => {\n let subText = ''\n if (text) {\n subText = `${text}
`\n renderer.table = (header, body) => `-1)r&&r.push(o);else if(u=he(o),a=we(h.appendChild(o),"script"),u&&ke(a),n){c=0;while(o=a[c++])xe.test(o.type||"")&&n.push(o)}return h}var Oe=/^key/,Ee=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function De(){return!0}function Ae(){return!1}function je(e,t){return e===$e()===("focus"===t)}function $e(){try{return x.activeElement}catch(e){}}function Le(e,t,n,i,r,o){var a,s;if("object"===typeof t){for(s in"string"!==typeof n&&(i=i||n,n=void 0),t)Le(e,s,n,i,t[s],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"===typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Ae;else if(!r)return e;return 1===o&&(a=r,r=function(e){return S().off(e),a.apply(this,arguments)},r.guid=a.guid||(a.guid=S.guid++)),e.each((function(){S.event.add(this,t,r,i,n)}))}function Ne(e,t,n){n?(te.set(e,t,!1),S.event.add(e,t,{namespace:!1,handler:function(e){var i,r,o=te.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(S.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=l.call(arguments),te.set(this,t,o),i=n(this,t),this[t](),r=te.get(this,t),o!==r||i?te.set(this,t,!1):r={},o!==r)return e.stopImmediatePropagation(),e.preventDefault(),r.value}else o.length&&(te.set(this,t,{value:S.event.trigger(S.extend(o[0],S.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===te.get(e,t)&&S.event.add(e,t,De)}S.event={global:{},add:function(e,t,n,i,r){var o,a,s,l,u,c,h,f,d,p,m,v=te.get(e);if(Q(e)){n.handler&&(o=n,n=o.handler,r=o.selector),r&&S.find.matchesSelector(ce,r),n.guid||(n.guid=S.guid++),(l=v.events)||(l=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(t){return"undefined"!==typeof S&&S.event.triggered!==t.type?S.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(B)||[""],u=t.length;while(u--)s=Te.exec(t[u])||[],d=m=s[1],p=(s[2]||"").split(".").sort(),d&&(h=S.event.special[d]||{},d=(r?h.delegateType:h.bindType)||d,h=S.event.special[d]||{},c=S.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&S.expr.match.needsContext.test(r),namespace:p.join(".")},o),(f=l[d])||(f=l[d]=[],f.delegateCount=0,h.setup&&!1!==h.setup.call(e,i,p,a)||e.addEventListener&&e.addEventListener(d,a)),h.add&&(h.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),r?f.splice(f.delegateCount++,0,c):f.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,i,r){var o,a,s,l,u,c,h,f,d,p,m,v=te.hasData(e)&&te.get(e);if(v&&(l=v.events)){t=(t||"").match(B)||[""],u=t.length;while(u--)if(s=Te.exec(t[u])||[],d=m=s[1],p=(s[2]||"").split(".").sort(),d){h=S.event.special[d]||{},d=(i?h.delegateType:h.bindType)||d,f=l[d]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=f.length;while(o--)c=f[o],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,h.remove&&h.remove.call(e,c));a&&!f.length&&(h.teardown&&!1!==h.teardown.call(e,p,v.handle)||S.removeEvent(e,d,v.handle),delete l[d])}else for(d in l)S.event.remove(e,d+t[u],n,i,!0);S.isEmptyObject(l)&&te.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,o,a,s=new Array(arguments.length),l=S.event.fix(e),u=(te.get(this,"events")||Object.create(null))[l.type]||[],c=S.event.special[l.type]||{};for(s[0]=l,t=1;t