├── .babelrc
├── .editorconfig
├── .gitignore
├── README.md
├── demo
├── index.html
├── ui1.jpg
└── ui2.jpg
├── dist
├── best-editor.css
├── best-editor.js
├── best-editor.min.css
└── fonts
│ ├── iconfont.eot
│ └── iconfont.ttf
├── package.json
├── src
├── assets
│ ├── iconfont.css
│ ├── iconfont.eot
│ ├── iconfont.svg
│ ├── iconfont.ttf
│ └── iconfont.woff
├── core
│ ├── best-editor.js
│ ├── dom.js
│ ├── handle
│ │ ├── image-handle.js
│ │ ├── link-handle.js
│ │ ├── list-handle.js
│ │ ├── paste-handle.js
│ │ └── video-handle.js
│ ├── handler.js
│ ├── request.js
│ ├── selection.js
│ └── toolbar.js
├── main.js
├── scss
│ └── main.scss
└── ui
│ ├── image-dialog.html
│ ├── image-upload.html
│ ├── link-dialog.html
│ ├── toolbar.html
│ └── video-dialog.html
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env"]
3 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = crlf
7 | charset = utf-8
8 |
9 | trim_trailing_whitespace = false
10 | insert_final_newline = false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 概述
2 |
3 | 一款简洁实用的web富文本编辑器,拥有着现代化UI风格的界面。比现有的富文本编辑器多了一些特色功能。图片上传,支持本地和链接,且拥有图片上传状态预览框。文章粘贴做了格式优化,并支持图片上传到自己的服务器。
4 |
5 | [](https://raw.githubusercontent.com/zc9/best-editor/master/demo/ui1.jpg)
6 |
7 | # 文档
8 | - 说明文档参考 [Wiki](https://github.com/zc9/best-editor/wiki)
9 |
10 | # 下载安装
11 | - 直接下载:[https://github.com/zc9/best-editor/releases](https://github.com/zc9/best-editor/releases)
12 | - `npm`下载:`npm install --save best-editor`
13 |
14 |
15 | # 运行环境
16 |
17 | 目前测试的环境:edge、ie10、chrome。建议运行在基于webkit内核的浏览器上,拥有更好的体验。
18 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | best-editor
9 |
10 |
11 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
46 |
47 |
--------------------------------------------------------------------------------
/demo/ui1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/demo/ui1.jpg
--------------------------------------------------------------------------------
/demo/ui2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/demo/ui2.jpg
--------------------------------------------------------------------------------
/dist/best-editor.css:
--------------------------------------------------------------------------------
1 | .best-editor-container {
2 | display: flex;
3 | flex-direction: column; }
4 | .best-editor-container.full-screen {
5 | position: fixed;
6 | z-index: 9999;
7 | top: 0;
8 | left: 0;
9 | right: 0;
10 | bottom: 0;
11 | width: 100% !important;
12 | height: 100% !important;
13 | background-color: #d9d9d9; }
14 | .best-editor-container.full-screen .best-editor {
15 | width: 60%;
16 | margin: 0 auto;
17 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
18 | margin-top: 35px;
19 | margin-bottom: 20px; }
20 | .best-editor-container .best-editor-toolbar {
21 | background-color: #d9d9d9;
22 | border-bottom: 1px solid #ccc;
23 | user-select: none;
24 | box-sizing: border-box; }
25 | .best-editor-container .best-editor-toolbar ul {
26 | zoom: 1;
27 | list-style: none;
28 | word-break: break-all; }
29 | .best-editor-container .best-editor-toolbar ul li {
30 | list-style: none;
31 | float: left; }
32 | .best-editor-container .best-editor-toolbar ul li a {
33 | height: 39px;
34 | line-height: 39px;
35 | color: #595959;
36 | padding: 0 14px;
37 | display: inline-block;
38 | font-size: 16px;
39 | font-weight: bold;
40 | cursor: pointer; }
41 | .best-editor-container .best-editor-toolbar ul li a:hover {
42 | color: #f2f2f2;
43 | background-color: #595959; }
44 | .best-editor-container .best-editor-toolbar ul:after {
45 | content: ".";
46 | display: block;
47 | height: 0;
48 | clear: both;
49 | visibility: hidden; }
50 | .best-editor-container .best-editor {
51 | flex: 1;
52 | outline: none;
53 | padding: 30px;
54 | box-sizing: border-box;
55 | padding-top: 15px;
56 | overflow-y: auto;
57 | background: #fff; }
58 | .best-editor-container .best-editor p {
59 | margin: 15px 0;
60 | word-break: break-word; }
61 | .best-editor-container .best-editor h1, .best-editor-container .best-editor h2, .best-editor-container .best-editor h3, .best-editor-container .best-editor h4, .best-editor-container .best-editor h5, .best-editor-container .best-editor h6 {
62 | margin: 15px 0; }
63 | .best-editor-container .best-editor a {
64 | text-decoration: none;
65 | color: #3194d0; }
66 | .best-editor-container .best-editor blockquote {
67 | padding: 20px;
68 | background-color: #f2f2f2;
69 | border-left: 6px solid #b3b3b3;
70 | word-break: break-word;
71 | font-size: 16px;
72 | font-weight: 400;
73 | line-height: 30px;
74 | margin: 0 0 20px; }
75 | .best-editor-container .best-editor iframe {
76 | display: block;
77 | margin: 0 auto; }
78 | .best-editor-container .best-editor ul, .best-editor-container .best-editor ol {
79 | list-style-position: inside;
80 | margin: 15px 0; }
81 | .best-editor-container .best-editor .image-box {
82 | text-align: center;
83 | font-size: 0;
84 | margin: 15px 0; }
85 | .best-editor-container .best-editor .image-box > img {
86 | max-width: 100%;
87 | width: auto;
88 | height: auto;
89 | vertical-align: middle;
90 | border: 0; }
91 | .best-editor-container .best-editor .image-box .image-upload {
92 | width: 443px;
93 | padding: 5px 16px 5px 5px;
94 | margin: 0 auto;
95 | border: 1px solid #d9d9d9;
96 | overflow: hidden;
97 | font-size: 14px;
98 | -webkit-box-sizing: border-box;
99 | box-sizing: border-box; }
100 | .best-editor-container .best-editor .image-box .image-upload .preview-image {
101 | display: block;
102 | float: left;
103 | width: 90px;
104 | height: 90px;
105 | object-fit: cover;
106 | margin-right: 20px; }
107 | .best-editor-container .best-editor .image-box .image-upload .status-bar {
108 | display: block;
109 | float: right;
110 | width: 305px; }
111 | .best-editor-container .best-editor .image-box .image-upload .status-bar .upload-error-msg {
112 | color: #f50; }
113 | .best-editor-container .best-editor .image-box .image-upload .status-bar .status-area a {
114 | float: right;
115 | margin-left: 20px;
116 | cursor: pointer;
117 | color: #999; }
118 | .best-editor-container .best-editor .image-box .image-upload .status-bar .status-area .upload-btn-retry {
119 | display: none; }
120 | .best-editor-container .best-editor .image-box .image-upload .status-bar .uploading-icon {
121 | height: 3px;
122 | width: 305px;
123 | min-height: 3px;
124 | display: block;
125 | margin: 25px 0 20px;
126 | background: url(data:image/gif;base64,R0lGODlhMgEDAMQfACV79DaH+avH8bDK9rDJ7ajI8qvI7q3K8a/M92Oc7ih776/K9KrL9KbH8KbK8jV/7i9+7xhw8bjT+ICw8pLF+sHW9a3H8ajH8azJ8LPL9q3L9rPL7zB/8SV89zSH/f///yH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2QTdFQzI3OUUyMUQxMUU2OEVGMUVFRTY0NzY1NUJEMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2QTdFQzI3QUUyMUQxMUU2OEVGMUVFRTY0NzY1NUJEMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZBN0VDMjc3RTIxRDExRTY4RUYxRUVFNjQ3NjU1QkQzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjZBN0VDMjc4RTIxRDExRTY4RUYxRUVFNjQ3NjU1QkQzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwv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) 50% no-repeat; }
127 |
128 | .best-editor-dialog {
129 | position: fixed;
130 | top: 0;
131 | left: 0;
132 | right: 0;
133 | bottom: 0;
134 | z-index: 9999999999999;
135 | background-color: rgba(255, 255, 255, 0.7); }
136 | .best-editor-dialog .wrap {
137 | position: absolute;
138 | top: 50%;
139 | left: 50%;
140 | transform: translate(-50%, -50%);
141 | width: 412px;
142 | background-color: #fff;
143 | border-radius: 6px;
144 | -webkit-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
145 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
146 | padding: 16px;
147 | box-sizing: border-box; }
148 | .best-editor-dialog .wrap .head .close {
149 | text-align: right; }
150 | .best-editor-dialog .wrap .head .close a {
151 | cursor: pointer;
152 | font-size: 24px;
153 | color: #999;
154 | transition: color .3s ease; }
155 | .best-editor-dialog .wrap .head .close a:hover {
156 | color: #4d4d4d; }
157 | .best-editor-dialog .wrap .head h3 {
158 | font-size: 22px;
159 | padding-bottom: 26px;
160 | text-align: center; }
161 | .best-editor-dialog .wrap .body {
162 | padding: 15px 30px 30px; }
163 | .best-editor-dialog .wrap .body .upload-btn {
164 | position: relative;
165 | height: 42px;
166 | margin-bottom: 20px;
167 | background: #555;
168 | overflow: hidden;
169 | text-align: center;
170 | line-height: 42px;
171 | color: #fff;
172 | font-size: 14px;
173 | cursor: pointer; }
174 | .best-editor-dialog .wrap .body .upload-btn input {
175 | position: absolute;
176 | top: -12000px;
177 | right: 0;
178 | left: 0; }
179 | .best-editor-dialog .wrap .body .input-box {
180 | display: flex;
181 | margin-bottom: 20px; }
182 | .best-editor-dialog .wrap .body .input-box > div {
183 | height: 42px;
184 | border: 1px solid #ccc;
185 | box-sizing: border-box;
186 | line-height: 42px; }
187 | .best-editor-dialog .wrap .body .input-box .icon-box {
188 | text-align: center;
189 | background-color: #eee;
190 | width: 38px;
191 | color: #595959; }
192 | .best-editor-dialog .wrap .body .input-box .input {
193 | border-left: 0;
194 | flex: 1; }
195 | .best-editor-dialog .wrap .body .input-box .input input {
196 | border: 0;
197 | outline: none;
198 | width: 99%;
199 | border-left: 0;
200 | box-sizing: border-box;
201 | padding: 0 10px;
202 | color: #595959; }
203 | .best-editor-dialog .wrap .body .switch-box {
204 | color: #888;
205 | cursor: pointer;
206 | font-size: 14px;
207 | padding-bottom: 10px;
208 | text-align: center; }
209 | .best-editor-dialog .wrap .body .waring-txt {
210 | height: 20px;
211 | line-height: 20px;
212 | color: #bc6351;
213 | font-size: 14px;
214 | margin-bottom: 5px; }
215 | .best-editor-dialog .wrap .body .btn-box {
216 | font-size: 14px;
217 | text-align: right;
218 | height: 30px;
219 | line-height: 20px;
220 | user-select: none;
221 | color: #595959; }
222 | .best-editor-dialog .wrap .body .btn-box > span {
223 | display: inline-block;
224 | transition: color .3s ease;
225 | cursor: pointer;
226 | padding: 4px 12px;
227 | font-size: 14px;
228 | font-weight: 500; }
229 | .best-editor-dialog .wrap .body .btn-box .cancel:hover {
230 | color: #000; }
231 | .best-editor-dialog .wrap .body .btn-box .confirm {
232 | color: #42c02e;
233 | background-color: #fff;
234 | border: 1px solid #42c02e;
235 | border-radius: 15px;
236 | margin-left: 15px; }
237 |
238 |
239 | @font-face {font-family: "iconfont";
240 | src: url(fonts/iconfont.eot); /* IE9*/
241 | src: url(fonts/iconfont.eot#iefix) format('embedded-opentype'),
242 | url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAA6UAAsAAAAAFggAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8jk7oY21hcAAAAYAAAAD/AAAC+JNZho1nbHlmAAACgAAACUEAAA00tiGakGhlYWQAAAvEAAAAMQAAADYSYKgOaGhlYQAAC/gAAAAgAAAAJAffA5BobXR4AAAMGAAAABsAAABYWAP/92xvY2EAAAw0AAAALgAAAC4nqCSObWF4cAAADGQAAAAfAAAAIAEmAINuYW1lAAAMhAAAAUUAAAJtPlT+fXBvc3QAAA3MAAAAxQAAAQ7t7UAqeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeSbz5xtzwv4EhhrmBoQEozAiSAwDx1wz3eJzlkk1KA0EQhV9Pxvg3/ow64FJMshGvkIMkkEVMcoTkcO5ymTcDGcgu2/hqngiC6AGs4hvoppiurq8BnADoiVeRA6lFQgS1m7r9Hi66/RzvWj8pVcdHDjjilDOuuOGW+zqrq6Zshrtxezgevyomqphz/VPFr5G6kyKflS/q43tGxRnOcYkCV7jGDW5R4g4ZKvX7oHvdo49TdR+36v9x2n+IIj6p+FxVYciEZw6MZgqOjKYLTozmDE5N/Ikzo9mDcyML4JuRD3BhZAZcGjkCV0a2wLWRN3Bjut62Jt4e90ZWUWcm3m1dGZlGUxo5RzM0so/d2MQbbw8G+QdnbWapAHicjVd9bBxHFZ+3c7d7d3tf69uP+77dW9+u72zvne+zcXO2kxDXbpLmg4SQpmoDbQ1CTUAQV21RihUFNW0iJW0EooHyB0HhjyZVIwFFCNdtChWISJVAQkojpLYUUFuCGlS1FfjWvLlz0sQ0EvZ63pvf25l9M/Pe740JR8jSRXqc2kQhaUK8plUGQ+AFM2+1oNmqqRqoPNRsy+YFOvtQlN/p/nEbH/1aMOyBqhD5eoSH2zxht+/3U30hMWxB+K23wiAHaSYMEFp8S1TgwfnKgNVP8Ifit/5D70WhkmFyLyEFtVZt1G3HY+YFWVXwj9coYmNco+5wPZA9CrTG2DMOKBpR2+HK3BjUqvhqlipymApZYAKdNvMRgJ8XjF8pIdMoFzL9YS/wnBBRjGJ7JJmpjhqJAY/X/Qf4JvsoDxSAE7m+lDjAjfxrreiI5toxJx3VSrnkphlzdMt2R/282rhv/1T0J6sMNSv5OG/yK8l8tuAEYNYT0kdLZj0bFhL3J8KNkCa668pc0MdH/FEh7jXgPcUjeMBTAr83lCmNWcnBTCYalO7dUN1cM8PUyxOCz9JlD9AY8RGJGKRERsnthLRkPm/Vm1W1cVXBBfKmkbfaUG/WDOzfzCCt6F+a2D1x7aEFUehM+wIBH/eCIC5e+jT0en33cHfgR87ExF0TE+7be32i6GMNJzpdi/vXfWwEayBzzYpnvbS09DtcV4tESJXcQwhU1Qxc51nBsq0Gyqqmsl9FjkAZEDPzPJ55FxRqCGMsdn/NfNeMY21rHBotNQeqluUwWABDyKL/ZC4v9rMWuGgo/fR30uuscZ73UaHiS2dr69du2vjwwK2G+th7nngopRaHS87kmvIW3e8B/Bn1+0IeKlcni4WddUeGuYCvwObCpiAnbql/6SkRo9GZzIsRzgM79Pq6ammTKaaioRNqdmKVnpaT6UAwpPkFr08YS0mqkuBkRRc9RimeXW9XSlHcApYE3BLnkgrGfjeiW7Fmq+GA3dIwlseBF8Ig8BEIQwT4DC4QdbSyTREgEB/RfAFudYVXylpgz0hlwN5M+WQj4fMIfUNyVHQcEHRlSKnVjLW6wwdFMRkC9c3RUIBydS+lXk31hfyKMrjn5T3TVcXv5xNxDnwAAmW+LX1Iz9MA5iaJZUFrOdBA/6p4DIYkoBNhTL6tkxsabbpwbPKR8qOw9VD71N0LLkzNnB3fUT648dgCrSO87dDYevC6hCzP+UpvTlyTYEuGjXmLs2NHw9kd4Mjdp9qHYNu3yo9MHlvwQLux4bYtOJwGYP3YIfe5R8t1/N7Gg+Ud42dnFlziwTl/S39BbyFeImLGaJgrNaUmGTFTMSQTao1aw4g1TMloTM0fcF+dn4fRA/DwgXn31QMHYPTb2MUejC4en0eYoaQ751/oMzTzyZwxNoFJu7NBd2aqsM9cnAXr3OzsOfd17pVzYM2eOzcLAff1WXjm3GynjUaubxbxXl7PYfx/E1l1FZkmnyMz5EFCNMyAvN3Cw2426oLNImBEUMxGTUEKiykmpsQYreN5C3aX4JDVOKHW8K5MfjakZfI4Q01ZaVxJAK+PO6stPW1I8dWRWFgWW+2FVsaE12jSslJSOCmPhJtGaZVdtmGafuFGflhoA3jjxTva9Is3o4jscMOqJqVov0dPxDQRsjtra4RBuH23LGYqmUQiHTHyGb1cTFeSuYj5wjWOgH+vWvVUQBmc/vufexTiC9xIId168RJ9ma7BU5FJuxdDGDzdwKE99pP5GIJhDvMF2R93D7MKqwfuYBiWASwSyJEcLHS83s7Ci6x9SU4mB5LJvf5U3h/0ch4+hTsTl/uiASOZzcRSETW/ZrDYztM1V0e8uNDp3J8qJpPFFAzGkro/JPJyVo7FzVQsGpWDmq5PaKH0Lf3ZRi7B0hx9P09/TCdxFVj8WgbGkKFEQJK7Zy+VodHrMrdtzDVE7qLjiy/DzKa+ex64b1ffFkhtlH5wdvfjdjYhbRbW00NNPuo+8tU99++Hh2JCsynE3APfP1IeMu/8LByM8t1v4qa9xJ3HCC7jbpksf5t1C1NXkHDfaqx6OlD4FMzGd+nEHPfAtlR/f+rwzyhMN+ea0wDTbmAl0sTX4ODWvVyh2Q+enx5eIq0pgKnWXHPq/P9C3Na9zC1P17cHKeBZasRk/sXYCbIAxT0Quq3RRbw30c/gHmvcCdbuY4073QUKrO3s/URfxk8Yw7o+bOzLOYbh5C7pTi7n6JcMJoxezn9Aj9Lgdf4YWSxQguFg3mj/h36WO40find2x7GFX8f1XMJdzXTuNGs7d67AaRD0ig6seRNyI6jlqrmVGqdXcsv7hdz5I+TOPpLFCvoZrBh5jJNWs9bvrWpZLBOCwWOFUFFiXWy2IG8yr5hZ7dnzJnS9LbIa4iB911pVoFos6ufFERgGR+mLirw46F74LvymHPTnjc7aoVBAz8OZJx7PGEYaYiAHVF/Ez4eKR4+AktKNpLvodgKyP+wPpuUPjlwUA0afBcBEAe9SI2BliwBmdgjc5yE7ksPiwqPN5Nyz2M1i1ysa+RhcXeNR+gHd343XcTKBa+RZma+Pg4WVj5exxlfZpc/GGphnZVFrNasI4mVBbY5Dsw6aWsV7ah0H5QUcoMF2panskeUrxV3mmYGB46UHSmcMUYPHrmpXrrd3tsejA1GIRiJMuu9HIrIs78E3rmiicQZHHB8YOGPuKsILy8qVG8zuHfFIBKI4FKX7Psrumv7mITSJ954cGcB7LsFD0CRMNwwaW8J0KxjLuWdgR3LAG4Yel1FDBJuexMODrLZ4oSdpffHC4CheUAZpvSs701CZGhmZqrxI737n3VPcu5DTOic13Omcxs2grMDoUOfkEHt3iJsZGn2tUKlMVyqdj+FD9+nvLXPTEv0l0iurTV1WRXcwE5GXkBlMVveRpLB+WGbXV+QsNDJfrxkZaZj0y4efoyAFYXNQkoIf0f0b60zpvI1wDwW0fki/sanWUymhzx92d4UkKQR3IHTrpll88daQdBOYXZc+XnrT46M5/P8kjr46oLNLksazGNebWEDtpgWSl/4wfdn90+V0ewhgqJ2+DKVlvTMPLRrwBYO+xBtPPvlG4prWOQ1/eKd3J6OEm0MeIKAJNpZUvI21NG7HszuevfrA3HWd/wKFUW9TAAAAeJxjYGRgYADixO7ginh+m68M3CwMIHB9wSZuGP3/x/8GFg7maiCXg4EJJAoAPjYL2gAAAHicY2BkYGBu+N/AEMPC+P/H/x8sHAxAERQgBgCgPwZ2eJxjYWBgYEHGjP//I9hockTh/z9ANACl8QRQAAAAAAAANgDAASwBtgIEAi4CWAKCAqwDTgOsA+YENAR8BMwFPgWoBfoGUAaABpoAAHicY2BkYGAQYyhnYGMAASYg5gJCBob/YD4DABbFAaoAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbYzBUsJAEES3cZNAAoKg+BU5WB78HAs2k2Rkahd2Zy35e1OViwffqburu83CzNTmf45Y4AEWBUpUWGKFGg3W2OARW+zwhD0OeMYLjng1tg9e7TlIVwknbbNskka+kI4x5GEsWU/Czkbqgs2+C7s+i7TJRSLf0g9r8yeYP4LYkeS6muoUhT0dPt7ez3zyX3zjzzv7e/DDerodfOvIK8V6NkK9NrOMPIxqp/GlurLTHKm85aCUim/uKBROQiJjfgH+xEYRAAAA') format('woff'),
243 | url(fonts/iconfont.ttf) format('truetype')
244 | }
245 |
246 | .iconfont {
247 | font-family:"iconfont" !important;
248 | font-style:normal;
249 | -webkit-font-smoothing: antialiased;
250 | -moz-osx-font-smoothing: grayscale;
251 | }
252 |
253 | .icon-font:before { content: "\E618"; }
254 |
255 | .icon-bold:before { content: "\E675"; }
256 |
257 | .icon-list-ul:before { content: "\EB3D"; }
258 |
259 | .icon-strikethrough:before { content: "\ECF6"; }
260 |
261 | .icon-italic:before { content: "\E702"; }
262 |
263 | .icon-redo:before { content: "\E811"; }
264 |
265 | .icon-undo:before { content: "\E824"; }
266 |
267 | .icon-full-screen-exit:before { content: "\E623"; }
268 |
269 | .icon-full-screen:before { content: "\E625"; }
270 |
271 | .icon-list-ol:before { content: "\E6C1"; }
272 |
273 | .icon-help:before { content: "\E659"; }
274 |
275 | .icon-underline:before { content: "\E65A"; }
276 |
277 | .icon-713bianjiqi_yinyong:before { content: "\E65D"; }
278 |
279 | .icon-align-center:before { content: "\E661"; }
280 |
281 | .icon-align-left:before { content: "\E662"; }
282 |
283 | .icon-align-right:before { content: "\E663"; }
284 |
285 | .icon-link:before { content: "\E664"; }
286 |
287 | .icon-picture:before { content: "\E665"; }
288 |
289 | .icon-quotes:before { content: "\E715"; }
290 |
291 | .icon-video:before { content: "\E6EF"; }
292 |
293 | .icon-close:before { content: "\E676"; }
294 |
295 |
296 |
297 | /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9CZXN0RWRpdG9yLy4vc3JjL3Njc3MvbWFpbi5zY3NzIiwid2VicGFjazovL0Jlc3RFZGl0b3IvLi9zcmMvYXNzZXRzL2ljb25mb250LmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLG05UkFBbTlSOztBQUU5L1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQztBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7OztBQzFPNUIsWUFBWTtBQUNaLCtCQUErQjtBQUMvQjtBQUNBLG9DQUFvQyxjQUFjO0FBQ2xEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixrQkFBa0I7O0FBRXJDLG1CQUFtQixrQkFBa0I7O0FBRXJDLHNCQUFzQixrQkFBa0I7O0FBRXhDLDRCQUE0QixrQkFBa0I7O0FBRTlDLHFCQUFxQixrQkFBa0I7O0FBRXZDLG1CQUFtQixrQkFBa0I7O0FBRXJDLG1CQUFtQixrQkFBa0I7O0FBRXJDLCtCQUErQixrQkFBa0I7O0FBRWpELDBCQUEwQixrQkFBa0I7O0FBRTVDLHNCQUFzQixrQkFBa0I7O0FBRXhDLG1CQUFtQixrQkFBa0I7O0FBRXJDLHdCQUF3QixrQkFBa0I7O0FBRTFDLGtDQUFrQyxrQkFBa0I7O0FBRXBELDJCQUEyQixrQkFBa0I7O0FBRTdDLHlCQUF5QixrQkFBa0I7O0FBRTNDLDBCQUEwQixrQkFBa0I7O0FBRTVDLG1CQUFtQixrQkFBa0I7O0FBRXJDLHNCQUFzQixrQkFBa0I7O0FBRXhDLHFCQUFxQixrQkFBa0I7O0FBRXZDLG9CQUFvQixrQkFBa0I7O0FBRXRDLG9CQUFvQixrQkFBa0IiLCJmaWxlIjoiYmVzdC1lZGl0b3IuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLmJlc3QtZWRpdG9yLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IH1cbiAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lci5mdWxsLXNjcmVlbiB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHotaW5kZXg6IDk5OTk7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7XG4gICAgaGVpZ2h0OiAxMDAlICFpbXBvcnRhbnQ7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZDlkOTsgfVxuICAgIC5iZXN0LWVkaXRvci1jb250YWluZXIuZnVsbC1zY3JlZW4gLmJlc3QtZWRpdG9yIHtcbiAgICAgIHdpZHRoOiA2MCU7XG4gICAgICBtYXJnaW46IDAgYXV0bztcbiAgICAgIGJveC1zaGFkb3c6IDAgMCAyMHB4IHJnYmEoMCwgMCwgMCwgMC4xKTtcbiAgICAgIG1hcmdpbi10b3A6IDM1cHg7XG4gICAgICBtYXJnaW4tYm90dG9tOiAyMHB4OyB9XG4gIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yLXRvb2xiYXIge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNkOWQ5ZDk7XG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNjY2M7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDsgfVxuICAgIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yLXRvb2xiYXIgdWwge1xuICAgICAgem9vbTogMTtcbiAgICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gICAgICB3b3JkLWJyZWFrOiBicmVhay1hbGw7IH1cbiAgICAgIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yLXRvb2xiYXIgdWwgbGkge1xuICAgICAgICBsaXN0LXN0eWxlOiBub25lO1xuICAgICAgICBmbG9hdDogbGVmdDsgfVxuICAgICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvci10b29sYmFyIHVsIGxpIGEge1xuICAgICAgICAgIGhlaWdodDogMzlweDtcbiAgICAgICAgICBsaW5lLWhlaWdodDogMzlweDtcbiAgICAgICAgICBjb2xvcjogIzU5NTk1OTtcbiAgICAgICAgICBwYWRkaW5nOiAwIDE0cHg7XG4gICAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgICAgICBmb250LXdlaWdodDogYm9sZDtcbiAgICAgICAgICBjdXJzb3I6IHBvaW50ZXI7IH1cbiAgICAgICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvci10b29sYmFyIHVsIGxpIGE6aG92ZXIge1xuICAgICAgICAgICAgY29sb3I6ICNmMmYyZjI7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjNTk1OTU5OyB9XG4gICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvci10b29sYmFyIHVsOmFmdGVyIHtcbiAgICAgICAgY29udGVudDogXCIuXCI7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBoZWlnaHQ6IDA7XG4gICAgICAgIGNsZWFyOiBib3RoO1xuICAgICAgICB2aXNpYmlsaXR5OiBoaWRkZW47IH1cbiAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3Ige1xuICAgIGZsZXg6IDE7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBwYWRkaW5nOiAzMHB4O1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgcGFkZGluZy10b3A6IDE1cHg7XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICBiYWNrZ3JvdW5kOiAjZmZmOyB9XG4gICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgcCB7XG4gICAgICBtYXJnaW46IDE1cHggMDtcbiAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7IH1cbiAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvciBoMSwgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgaDIsIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yIGgzLCAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvciBoNCwgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgaDUsIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yIGg2IHtcbiAgICAgIG1hcmdpbjogMTVweCAwOyB9XG4gICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgYSB7XG4gICAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgICBjb2xvcjogIzMxOTRkMDsgfVxuICAgIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yIGJsb2NrcXVvdGUge1xuICAgICAgcGFkZGluZzogMjBweDtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmMmYyZjI7XG4gICAgICBib3JkZXItbGVmdDogNnB4IHNvbGlkICNiM2IzYjM7XG4gICAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xuICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAzMHB4O1xuICAgICAgbWFyZ2luOiAwIDAgMjBweDsgfVxuICAgIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yIGlmcmFtZSB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIG1hcmdpbjogMCBhdXRvOyB9XG4gICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgdWwsIC5iZXN0LWVkaXRvci1jb250YWluZXIgLmJlc3QtZWRpdG9yIG9sIHtcbiAgICAgIGxpc3Qtc3R5bGUtcG9zaXRpb246IGluc2lkZTtcbiAgICAgIG1hcmdpbjogMTVweCAwOyB9XG4gICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgLmltYWdlLWJveCB7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBmb250LXNpemU6IDA7XG4gICAgICBtYXJnaW46IDE1cHggMDsgfVxuICAgICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgLmltYWdlLWJveCA+IGltZyB7XG4gICAgICAgIG1heC13aWR0aDogMTAwJTtcbiAgICAgICAgd2lkdGg6IGF1dG87XG4gICAgICAgIGhlaWdodDogYXV0bztcbiAgICAgICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgICAgICAgYm9yZGVyOiAwOyB9XG4gICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvciAuaW1hZ2UtYm94IC5pbWFnZS11cGxvYWQge1xuICAgICAgICB3aWR0aDogNDQzcHg7XG4gICAgICAgIHBhZGRpbmc6IDVweCAxNnB4IDVweCA1cHg7XG4gICAgICAgIG1hcmdpbjogMCBhdXRvO1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCAjZDlkOWQ5O1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICAgIC13ZWJraXQtYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDsgfVxuICAgICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvciAuaW1hZ2UtYm94IC5pbWFnZS11cGxvYWQgLnByZXZpZXctaW1hZ2Uge1xuICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICAgIGZsb2F0OiBsZWZ0O1xuICAgICAgICAgIHdpZHRoOiA5MHB4O1xuICAgICAgICAgIGhlaWdodDogOTBweDtcbiAgICAgICAgICBvYmplY3QtZml0OiBjb3ZlcjtcbiAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDIwcHg7IH1cbiAgICAgICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgLmltYWdlLWJveCAuaW1hZ2UtdXBsb2FkIC5zdGF0dXMtYmFyIHtcbiAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICBmbG9hdDogcmlnaHQ7XG4gICAgICAgICAgd2lkdGg6IDMwNXB4OyB9XG4gICAgICAgICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgLmltYWdlLWJveCAuaW1hZ2UtdXBsb2FkIC5zdGF0dXMtYmFyIC51cGxvYWQtZXJyb3ItbXNnIHtcbiAgICAgICAgICAgIGNvbG9yOiAjZjUwOyB9XG4gICAgICAgICAgLmJlc3QtZWRpdG9yLWNvbnRhaW5lciAuYmVzdC1lZGl0b3IgLmltYWdlLWJveCAuaW1hZ2UtdXBsb2FkIC5zdGF0dXMtYmFyIC5zdGF0dXMtYXJlYSBhIHtcbiAgICAgICAgICAgIGZsb2F0OiByaWdodDtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAyMHB4O1xuICAgICAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgICAgICAgY29sb3I6ICM5OTk7IH1cbiAgICAgICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvciAuaW1hZ2UtYm94IC5pbWFnZS11cGxvYWQgLnN0YXR1cy1iYXIgLnN0YXR1cy1hcmVhIC51cGxvYWQtYnRuLXJldHJ5IHtcbiAgICAgICAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAgICAgICAuYmVzdC1lZGl0b3ItY29udGFpbmVyIC5iZXN0LWVkaXRvciAuaW1hZ2UtYm94IC5pbWFnZS11cGxvYWQgLnN0YXR1cy1iYXIgLnVwbG9hZGluZy1pY29uIHtcbiAgICAgICAgICAgIGhlaWdodDogM3B4O1xuICAgICAgICAgICAgd2lkdGg6IDMwNXB4O1xuICAgICAgICAgICAgbWluLWhlaWdodDogM3B4O1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICBtYXJnaW46IDI1cHggMCAyMHB4O1xuICAgICAgICAgICAgYmFja2dyb3VuZDogdXJsKGRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaE1nRURBTVFmQUNWNzlEYUgrYXZIOGJESzlyREo3YWpJOHF2STdxM0s4YS9NOTJPYzdpaDc3Ni9LOUtyTDlLYkg4S2JLOGpWLzdpOSs3eGh3OGJqVCtJQ3c4cExGK3NIVzlhM0g4YWpIOGF6SjhMUEw5cTNMOXJQTDd6Qi84U1Y4OXpTSC9mLy8veUgvQzA1RlZGTkRRVkJGTWk0d0F3RUFBQUFoL3d0WVRWQWdSR0YwWVZoTlVEdy9lSEJoWTJ0bGRDQmlaV2RwYmowaTc3dS9JaUJwWkQwaVZ6Vk5NRTF3UTJWb2FVaDZjbVZUZWs1VVkzcHJZemxrSWo4K0lEeDRPbmh0Y0cxbGRHRWdlRzFzYm5NNmVEMGlZV1J2WW1VNmJuTTZiV1YwWVM4aUlIZzZlRzF3ZEdzOUlrRmtiMkpsSUZoTlVDQkRiM0psSURVdU5pMWpNVE15SURjNUxqRTFPVEk0TkN3Z01qQXhOaTh3TkM4eE9TMHhNem94TXpvME1DQWdJQ0FnSUNBZ0lqNGdQSEprWmpwU1JFWWdlRzFzYm5NNmNtUm1QU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh4T1RrNUx6QXlMekl5TFhKa1ppMXplVzUwWVhndGJuTWpJajRnUEhKa1pqcEVaWE5qY21sd2RHbHZiaUJ5WkdZNllXSnZkWFE5SWlJZ2VHMXNibk02ZUcxd1BTSm9kSFJ3T2k4dmJuTXVZV1J2WW1VdVkyOXRMM2hoY0M4eExqQXZJaUI0Yld4dWN6cDRiWEJOVFQwaWFIUjBjRG92TDI1ekxtRmtiMkpsTG1OdmJTOTRZWEF2TVM0d0wyMXRMeUlnZUcxc2JuTTZjM1JTWldZOUltaDBkSEE2THk5dWN5NWhaRzlpWlM1amIyMHZlR0Z3THpFdU1DOXpWSGx3WlM5U1pYTnZkWEpqWlZKbFppTWlJSGh0Y0RwRGNtVmhkRzl5Vkc5dmJEMGlRV1J2WW1VZ1VHaHZkRzl6YUc5d0lFTkRJREl3TVRVdU5TQW9UV0ZqYVc1MGIzTm9LU0lnZUcxd1RVMDZTVzV6ZEdGdVkyVkpSRDBpZUcxd0xtbHBaRG8yUVRkRlF6STNPVVV5TVVReE1VVTJPRVZHTVVWRlJUWTBOelkxTlVKRU15SWdlRzF3VFUwNlJHOWpkVzFsYm5SSlJEMGllRzF3TG1ScFpEbzJRVGRGUXpJM1FVVXlNVVF4TVVVMk9FVkdNVVZGUlRZME56WTFOVUpFTXlJK0lEeDRiWEJOVFRwRVpYSnBkbVZrUm5KdmJTQnpkRkpsWmpwcGJuTjBZVzVqWlVsRVBTSjRiWEF1YVdsa09qWkJOMFZETWpjM1JUSXhSREV4UlRZNFJVWXhSVVZGTmpRM05qVTFRa1F6SWlCemRGSmxaanBrYjJOMWJXVnVkRWxFUFNKNGJYQXVaR2xrT2paQk4wVkRNamM0UlRJeFJERXhSVFk0UlVZeFJVVkZOalEzTmpVMVFrUXpJaTgrSUR3dmNtUm1Pa1JsYzJOeWFYQjBhVzl1UGlBOEwzSmtaanBTUkVZK0lEd3ZlRHA0YlhCdFpYUmhQaUE4UDNod1lXTnJaWFFnWlc1a1BTSnlJajgrQWYvKy9mejcrdm40OS9iMTlQUHk4ZkR2N3UzczYrcnA2T2ZtNWVUajR1SGczOTdkM052YTJkalgxdFhVMDlMUjBNL096Y3pMeXNuSXg4YkZ4TVBDd2NDL3ZyMjh1N3E1dUxlMnRiU3pzckd3cjY2dHJLdXFxYWlucHFXa282S2hvSitlblp5Ym1wbVlsNWFWbEpPU2taQ1BqbzJNaTRxSmlJZUdoWVNEZ29HQWYzNTlmSHQ2ZVhoM2RuVjBjM0p4Y0c5dWJXeHJhbWxvWjJabFpHTmlZV0JmWGwxY1cxcFpXRmRXVlZSVFVsRlFUMDVOVEV0S1NVaEhSa1ZFUTBKQlFEOCtQVHc3T2prNE56WTFORE15TVRBdkxpMHNLeW9wS0NjbUpTUWpJaUVnSHg0ZEhCc2FHUmdYRmhVVUV4SVJFQThPRFF3TENna0lCd1lGQkFNQ0FRQUFJZmtFQlFNQUh3QXNBQUFBQURJQkF3QUFCWjZnSll5alpaNW9xcTVzNjc2d0tseDBiWk96cmU5ODcvL0FvTkJYS0JZYVNLU3htR3dzajhuTHN6bU5McHRPWTY2R3UrRzJsNitYWktEaEdvTUJZbzNJdU4zcHVEd2pyOXZ2K0x4K2o2ZHIvb0NCZ29PRWhZYUhpSW1LaTRGc0NJS09qNENSa0k2TmxwZHJsWkdjblo2Zm5IK09CUVNscHFlb3FhcXJySzJ1cjdBWXNyTzB0YmEzdUxtNnU3eTl2ci9Bd2NBSHdzSUh4QmlsQndzTklRQWgrUVFGQXdBZkFDd0dBQUFBQlFBQ0FBQUZCcUFnaWtoWmhnQWgrUVFGQXdBZkFDd0FBQUFBQXdBREFBQUZCK0FrZmVJZ2JpRUFJZmtFQlFNQUh3QXNBQUFBQUNzQkF3QUFCVUZnMXdIQUdDVVpZWHhzNjc2dElNOXdiZDk0cnU5ODcvL0FvSEJJTExJRWdXVEFFNENnTm9RZ1lvb3dXcS9ZckhiTDdlNGdqekQ0OGZTYXoraTBlcDBPQVFBaCtRUUZBd0FmQUN3RUFBQUFuZ0FEQUFBRk91RDNBVjFwbWxFaUNXenJpbkFzejNSdDMzaXU3N3p0Q2lLUGNFZ0VUQ29MalhMSlpQYWUwS2gwK3VSOElOaHNscU5JVktqZ3NIZ01EZ0VBSWZrRUJRTUFId0FzQkFBQUFCOEFBd0FBQlNiZzkzVmlhWFpvcW5iUlUyeG00Sm4wNTkxNDduWEJsNVdMUjgwRUtScVBFSTdpSVlDVlFnQWgrUVFGQXdBZkFDd0VBQUFBS0FBREFBQUZKR0FIQUYxcG5taXFvbEdRRVlFbnozUnQzM2VYWkJuSFFjQ2djRWdzRGptS3dHWVRBZ0FoK1FRRkF3QWZBQ3dCQUFBQU9RQURBQUFGSjJEWEFTUWdubWlxcm14N1JvbGtCVjV0MzNpdTc3emVKWlVNWkVnc0dvL0lwQkxKZ1ZVSUlRQWgrUVFGQXdBZkFDd0dBQUFBMVFBREFBQUZSMkQzaldScG5taXFqbDNydnJEU1ZLc3AzSFd1a3plKy84Qmc4RUs4Q0M3Q1pNM0RiRHFmajlsaXQ2aHFsTmlzZHF0RGVMbGNqbmhNSm5laXRPQmhkV2l2d2ZDNG5CUUNBQ0g1QkFVREFCOEFMQWtBQUFCU0FBTUFBQVV2NENlT1pHbWVhS3FXWGV1K3NOSklSVjJzZUs2clh1Ly93TWRNUS94d2RpTE9FY2tzS1ovUUtBY2dsQnl1bUJBQUlma0VCUU1BSHdBc1V3QUFBQk1BQXdBQUJSVmdKNDVrQ1VCTjVxMXM2M3BCSTNGMGJkL0FJNGNBSWZrRUJRTUFId0FzQmdBQUFOTUFBd0FBQlVJZ0lJcGZhWjduQ0tCczY3NXdMSDlkYmQ5NDlCRGE3UC9Bb1BBa0tBNU5nYU55MmZJNG4xQm9KN0ZCTUsvWUxBb1NoSEMxNEJsblRDNmJBWTlxZU0yR2hRQUFJZmtFQlFNQUh3QXNIUUFBQU8wQUF3QUFCVVlnOEkxa2FaNW9xcTVzYTNad0xNOVJVbDJYcSsrOG0vZStqMkFvK0FHUHlLVFM1R2s2bjlET3BMS3NXcTlZRm1mTHlYcVYzTENZVzZOK3o2aUQrb0Qrck5YSDl5RUVBQ0g1QkFVREFCOEFMQndBQUFEU0FBTUFBQVUrNENlT1pHbWVhS3F1Ykp0MmNDekwwZE5rYnE3di9IcDV2YUJ3dVBNWWowaGtKMUNRRUovUXFIUktWWEd1MkN3V0FuZ1lOdFVuWm96cEhjNW5WUWdBSWZrRUJRTUFId0FzQUFBQUFNa0FBd0FBQlVYZ1ZnVFIxM1ZmcXE1c3F3S3dLODkwYmQ5NFBwOTg3d01LaXVSeTBSbGJHVVFBZFd3Nm45QW96a090V3ErUGhrU3F5MndjQVFCM1RDNmJVNXkwZXMwR1pMZG5XZ2dBSWZrRUJRTUFId0FzQUFBQUFQSUFBd0FBQlcrZ0pZcEVFVVJmcXE1c0M2aHZLNjlBWGM5NHJ1OTg3N2Vkb0hBNGpEd01pRit1d1d3b2Y0TFZZRHJJWkJDSnp2TVQyTFlDNEs1M1RDN3ZQT2kwT3QwSkdDVG16K0pBWDhSbm1vVitRZWozTnhRbll4Q0VFSGVIaUlrN0hJeU5qbzRBUnhsM0l4WmJHSmlZT1F5Y0RDRUFJZmtFQlFNQUh3QXNCQUFBQUNzQkF3QUFCWFhnSjFna0tVMFI4SzFzNjdiZEs4OTBiZDk0cnU5NTUvOUFZQ1FoTVRRYU5HVHJ3cnk0bXBmQ3NzbXJXcStyd1NERDVaNDQyTEFuVEM2YnE1NjBlcjN1SkNxYnd5STNuMm0xNTd6ZVJTQnNObjRWRXdvN0hJWmdlNG1LaXppSGpvK0dReFVmSkRRV05BZVpCeSthblpxTU9KNVduU0VBSWZrRUJRTUFId0FzQndBQUFOMEFBd0FBQlhEZ0ozNVdhVXBKOUFFc01MNmlDODgwM041MS9yWjY3Ly9Bb0hEVUtScVB4c2pqY3hnMW50Q29kQXA5WmE2WlFRWWxDd1JlbnFGNFRDNmJ6MEdQZXMxZWR3S0h6R3RCcjl2dmVEcUI4Q0ZzL29Bb0tqa1FoUkJvaUltS2kyUWNqbytRandBUEJoczFHSmdZTTVtYUl4Z2hBQ0g1QkFVREFCOEFMQWNBQUFBb0FRTUFBQVZRNENlT3BHVWFhRFZGWk91K2NDelBkRzNmZUs2N1hlLy9Qc0RqZzlnWmo4aGI1cE5wYmc0YmxTSkpyVnF2V0oxbnkrMTJIdzFKZGp6ZW1EZXU4MW5hSWJ2ZjhIaUxRNi9iNndxd1dNNnZtVU1BSWZrRUJRTUFId0FzRkFBQUFCMEJBd0FBQlhDZ0pZNWpSbjJmb3FCczY3NHNBQU15YktQMWw5OTg3Ly9Bb0ZEWUtScVB4c2pEZ0JnNmY0Vm85UG5LV0s5WHlZa1RDRkMvNExCNFRBNTZ6dWowdVJNNFNEUmxxbVorY0daUXpkZG16OWVteGhDQmdvSlVnM0dIaUlrZkhJeU5qbzBBRHdRYkh4aUtUcFpDbVI4SGRRY2hBQ0g1QkFVREFCOEFMQjBBQUFBUUFRTUFBQVZ5b0NXT2xqUkZnS0lxM3dlOEx0ek9kRzNmZUs3dmZPLy93R0N3UXl3YWk1R0VCSE1wMEp5emdsUmFFMWl0dEt0QWFETllNK0J3cGpKaEJjNDdqNXJMYnJ2ZjhEaFBUYS9YTzBxRXZxYnBheEE5QzNJNEdodUdoeHNtRVRvY2pSeURrSkdTazNHT2xwY2NTUklIbkhDY25aSWhBQ0g1QkFVREFCOEFMQ1FBQUFEdkFBTUFBQVZqb0NVS1JXRklVL1N0d09xK2NDelBkRzNmZUs3dmZMOTN3S0F3cUtCSVpxV2tjbG5JT0JIUURBcmlxMXF2Mkt4MlcvTjR2K0R2b3lFNXVEVG90SHF0M3JnM0JEZEs0WUxZNzNldWZzL3YrejhjZ1lLRGdRb1BSaXNIWmk0WUdEQ05qaThoQUNINUJBVURBQjhBTENjQUFBRGlBQU1BQUFWVDRDZU1nbVdlMHFSOGJPdStzQXNBY2MzT2RxN3ZmTy8vd0tDdlF5d2FpWkZFNVROb05qUFFxSVR5NEFpdjJLeDJ5KzM2UE9Dd0dBeVlWQTZmRFd2RGJtK21INFhWUzYvYjczZ2ZaOC92ODVNVkdDRUFJZmtFQlFNQUh3QXNKd0FBQUFnQkF3QUFCV0dnSllwZmFZNm80Q1NSNmI0dVVBSXlETk56YmU4ZjdmTStIRzlJTEJxUHlLVHkxV2s2bjgxSVFuSll3akNZakZZTDIzb0hqSW5DU2k2YnoraTBtdXhwdTkvdHpoU3hIbTd1K1B1cWhZVDRJWDEvZFlPRWhZWkVISW1LaTRrS1Uyc2hBQ0g1QkFVREFCOEFMRGtBQUFEeUFBTUFBQVZhb0NXT1l6VkZRS3FtWCt1K3NOdkZkTjEyT0c3dmZPLy93S0J3K01zWmo1SEF4bUlUWko1UXFHbEdyRnF2Mkt4MmkvVjR2MkJ2SnlISjFCQ0x6MmJOWHBzQWtMZzh6ZzFDNnZpOGZ0K0NQQjRRSElLRGdoRmtCRHNoQUNINUJBVURBQjhBTEVJQUFBRHJBQU1BQUFWU29DV09ZNVZFWC9vQkxLQ21MZnZPZEEyM2RxN3ZmTy8vd0tCUTJDa2FqOFZJb3ZMSk9KL1B5cVF6ckZxdjJLeDJ5L1Y0djJCdlp6blltTTluS1NvRmFidGY3alozVHEvYjc1dzh4NmJ2KzVWTUlRQWgrUVFGQXdBZkFDeExBQUFBNXdBREFBQUZRcUFsanFORWRkR25ybXpydm5Bc3ozUnQzM2l1NzN2bi83NUlaa2drVmlpZkRtL0piRHFmME9qU1E2MVNPNXVzVm52a0tGNEJqblJNTHB2UE9ZNTZyWTZFQUFBaCtRUUZBd0FmQUN4VUFBQUFlUUFEQUFBRk5hQWxqdVJHZGRHbnJtenJBbTRzejNSdDN5dWc3MW52L3hMSHA0TXJHby9JNUNyQURIdzIwS2kwNGdnb09Fb1ZaSnZ0ZW9zaEFDSDVCQVVEQUI4QUxBRUFBQUNKQUFNQUFBVSs0Q2QrMW1pZWFLcXViT3UrVml6UFZ0WThFYUR2L1B0MVFHQm1PUFFaajhpa2lzaGtTaGlCanJLMXFWYW4yS3oyWSsxMkpaaUhBa0l1bXlHdmN3Z0FJZmtFQlFNQUh3QXNBUUFBQUJFQkF3QUFCVmVnSUlwZmFaNW9xcTVzNjZJaitiWldiZHZDZFdYWEU1bUFvSEJJTEFabnlLUnl5V3kraE02b2RJYW9JcWFmakhhN0hWUWxta0FIU3k2YnoxaUNtb0J1dTFtYnVId2VseHdlQ2hOa3orZWorb0FRYjRPRVppRUFJZmtFQlFNQUh3QXNBZ0FBQUpJQUF3QUFCVFpnSVg1a2FaNW9xcTVzNjc2d2FjMTBiVnVaRUVUdzRNZkFvSkNGR0w0eXlLUnltWkVnRWh5amRFcXREamZZckhiN1VFUmJqeEFBSWZrRUJRTUFId0FzQVFBQUFCSUJBd0FBQlV2Z0ozNkZNSjVvcXE1czY2cEZYTHgwM1ZwNHJ1L1ZGTm5BRDJCSURCcVB5QlpnQkJpTW5NbW9WS1daV2pQWXJIYmJlMWhYZ1hEZ1N5NmJ6K2kwY2NOdXU5czloWHBPVDBMdWtCQUFJZmtFQlFNQUh3QXNrUUFBQUNRQUF3QUFCU09nSlk1a2FVbEpCS3hmNjc1dkpzOTBuVlVKRU94dzN3YWJvSEJJM09BaXZtUXJCQUFoK1FRRkF3QWZBQ3cyQUFBQWZ3QURBQUFGTzZBZ0NsOXBubWlxcnVrb3NyQkx3alJzM1hpZUMwVWhKUkdFc0VZc29vUkRvMm5BWkNxVm1haDBTaFZXSm9xbmRzdnQxamJnc0hnTXZpcENBQ0g1QkFVREFCOEFMRFVBQUFDVUFBTUFBQVUzb1BDTlpHbWVhS3FPeGVxK2NBeGJkRzNmdURRcGN1K1BnK0RnUnl6R01zaWtjcm1zVEI0ZmozRktyVnBYbTZ4Mnk5VTZGWkJQQ0FBaCtRUUZBd0FmQUN3QUFBQUFKZ0VEQUFBRlk2QUNLWlAwbldpcXJtenJwa1ZjdkhSTnkvWXF6M252L3lxTGNFZ3NEak9DQUFESWJPWUFVR2dnOENobG5OZ1VBclhOQWdlSWNQY25IbnZQdm94NnpXNnZKWWdFQjAwSFRxY2Z5S05xcXZ2L2dCOEVnNEdGS0J1SWlZcUxpdzhLaHBBc0lRQWgrUVFGQXdBZkFDd0FBQUFBSWdFREFBQUZkU0NrZkVwcG5taDZCczcydlhBc3p5L3pDblN1QzN6di96MmRjRWdzR285SW82REFiRHFmVGNra2txeFdPNitBZHN2dGVybVBoTTBLR3h3MEdySU13VzY3MzI2MWZFNmZJejd3dkxzeUdkWC9IeDRQTHcrRmhvZUlpUThjaFFsM2N3Y0hCSUNVUnk2Vm1KUWJtNXlkbnB0OGZwbHFJUUFoK1FRRkF3QWZBQ3daQUFBQUNRRURBQUFGZE9BbkttUnBubWdaQmRUeFdXSXN6M1JjM0hpdTYzWHYvOENnY0Vnc0duV09wSEtwckV3aUg0QlJCS2hhcjFoUllNdnRlcjlkVHNBaEdXU21NZ1I2elc2NzMyNkVmRTZ2ejUwZE9QQWhldmovZ0lHQ2Z3b1BBeHQ2YUFjTExtc0xqNG1Sa213YmxaYVhtSlpPVUdzUW5wK2dvQjhoQUNINUJBVURBQjhBTERRQUFBRGNBQU1BQUFWYm9BS01aR21lcEVKSmd2QzljQ3pQcjB2ZmVLN3ZmTy8vd0oxalNDd2FoeHJESXhMNGVKNmVBSFJLclQ1V2c2QjJ5KzE2djE2RWVFd3VpeVdFUU9mQmdYRGE3N2g4TGxjOEdoS3dmcy92KzJjYmdZS0RoSUVTR3c4QUlRQWgrUVFGQXdBZkFDdzFBQUFBNndBREFBQUZaNkFpaWw5cG51Z0pyR3pydm11VVNNSm5wWGl1NzN6dm00Smc4TGNyRUk5SWxHUEpiRG9kZ3Nxa0ZLZ0draCtQZHN2dGVyV2NpU1NUd1pyUDU0RjZnRzY3ZFlpNGZFNUhaQ3FVem1PL1QzTCtnSUdDZzM5NllodHZpWXFMakl5SUc1Q1JrcE40Q2lFQUlma0VCUU1BSHdBc1l3QUFBTTRBQXdBQUJWbmdCNHhrYVo1QUZEVGI5eFZ3TE05dWJkOTRydTk4Ny8vQW9CQTNLeFlSaGtmazQyazZuOUNvaDVQUVNGeUlySGJMSFhxLzRMQjQvRUVjdU9pdGhCRDRjTjd3dUh6K1ZpUXlMYkoreisvM040Q0Jnb01iYXc4QUlRQWgrUVFGQXdBZkFDeDZBQUFBdUFBREFBQUZReUFnam1ScEF0RlVmV3pydm5EOENqUXQzM2l1NzN6dnk0VUNyZUVwR28vSXBLZWordjBHVUtoelNxMWFlNGdzb3NEcGVyL2dNQWZRdkpyUDZMUjZzeUZzR2lFQUlma0VCUU1BSHdBc2tBQUFBQmNBQXdBQUJSWWdJSTVrV1VhSjVLMXM2N3JjSkhGMGJkODI5TWdoQUNINUJBVURBQjhBTERvQUFBQ0JBQU1BQUFVMDRDZU9aR21lYUtxdWJPdCtRQ3pQOUJ3bEV2SHVmTy8vSDQ5d1NDd1NPYmdNWkxrRW5waE5weFRJcVZxdjJHdm5nZnVFQUFBaCtRUUZBd0FmQUN3QUFBQUErQUFEQUFBRlNlRDBBVjlwbm1pcXJtenJ2bkFzejNUTkFuaXU3M21VU0lLZ2NFZ2MybEtVaCtmSWJEcWYwS2pOUTYxYXJ3RXE0SWZvZXI5U1ZlUERDWnZQNkxTWncyNjczMjdGVDkzS2hBQUFJZmtFQlFNQUh3QXNBQUFBQUJjQkF3QUFCVitnSUk1a2FaWlZFbjFzNjc1d0xNOTBiZDk0cnUvOEIvekFvUEFYbVVnK2pxUnl5WFQwbnF5QmRMcW9WcWRTNndJclRRR2c0TEI0VEM2N1BPaTBlbzErR0RQbU9HRk9yOXZ2OXRRcXp1Lzcvem9jZ29PRWhSd0Fia2RqRzN3WklRQWgrUVFGQXdBZkFDd1pBQUFBL2dBREFBQUZZK0FuakdScG51aUlMVlFRS1Y4c3ozUnQzM2l1NzN6di8wQVpZRWdzR2lPQno2RlhDT0lXVU9oZ09vaEtxVlVyMXByUkJEcEpwM2hNTHB2UEg0OTZ6VzZEUHhJMGtFQ3YyKy80ZkgzVEFzai9nSUdDT2h5RmhvZUlIQUJoT1JtT0dYSWJJUUFoK1FRRkF3QWZBQ3c0QUFBQTN3QURBQUFGWGFBZ2ptUnBubWJCVEVyN3ZYQXN6M1J0MzNpdTczei9BY0NnY0tpWVNBUSszR0xBWkM2ZXkrWUErcFJPb1ZMTjZoRUlKTC9nc0hpODg1alA2UFREbUNISENQQzRmRTZ2enc4SXl1UERjZnYvZ0lFdkhJU0Zob2RyRW44TElRQWgrUVFGQXdBZkFDeGFBQUFBeEFBREFBQUZZYUJRakdOak5tU3FycWtnVGRHbktGOXQzM2l1NzN6di84QmdFRUFzR291UmhBUWoxR21lR29aMFNxMWFyNi9PSnhCb2VyL2dzSGpuS1p2UFpvaFNqQ0FjM20rTWZFNnYyK3VFRndEQ0gvdi9nSUFjZzRTRmhBb0pGVDRaTlJ1TU9DRUFJZmtFQlFNQUh3QXNlZ0FBQUxJQUF3QUFCVmRnSVk1a2FaN0Y0UVNSb254d0xNOTBiZDk0cnU4NzRQOUFYeVFoWWRnYU9TU013V3c2bjlCb1p0WDVCSGpZckhiTG5YbSs0UEQzUWV6R0RwaTBlczF1dXpFYlJnRHdnWmp2K0R5UHcrLzcrUW9KRlRFYlhTRUFJZmtFQlFNQUh3QXNaUUFBQUx3QUF3QUFCV3ZnSjQ1a2FaNW9XaFpYNDE1RkxNLzB2RkZCcE81ODcvOUFFV0JJTEFJaUNZbEl3OVNVbXM1blU4cWtWa2xRaG5iTDdYcTNFa2VnRXl5YnoyYVBlczMyUUNhVnoyRStMOUhyby92QlR1ZjNTWGNZZ29PRWhZYURHd2dCQUdpTmpvOGpISktUbEJ3S0NYRWZJUUFoK1FRRkF3QWZBQ3hxQUFBQXdnQURBQUFGZEdBamZtUXBqaVY1cHQ5MVh1elpzSFFxMDJ1aDYvSytuNzROcFJOUktHcklwSExKYkNvQjBHaFVBWmxJQ3M2c0ZxbnBkbGxlRGRqTEtKdkQ1ckpYUWlFRkF0dTRmRTd6Mk8vM3dJTlNPWHdRZElGSUI0U0VMSVYrS1lnSEdJMFlpNDZOaFd3ZlZCQ0NtSmxJSEp5ZG5SQjdGU1VoQUNINUJBVURBQjhBTEZrQUFBRFpBQU1BQUFWVzRDZU9aR21lYUtxdWJPdVN4ZFhNZEczUGh4TkViKy8vSjRCd0tJd0VOZ0tnY3Nsc2tqUlFoblJLclRJUWlFVEh5WFY2dnVCdko3RlpiRGJkdExwN1lCd1c4TGg4ZnRnd0FvcTF2dlhnK1A5K0FBa2ZCQ0VBSWZrRUJRTUFId0FzeHdBQUFHc0FBd0FBQlQzZ0o0NWtPVFpvcXE0Q3NWRlBaTTUwYmQvNEIreHlUakxBb0hDNDJHd2NBWTV2eVd5S1BKNUE1N0JZTHE3WXJIWnhjRkVDQ3FmWXFaeHh6cEVRQUNINUJBVURBQjhBTE9nQUFBQStBQU1BQUFVcFlDT09aSGtKR2RWRlgrdStjQ3pQTUdQZk9LN3RFaFhRd0tCd1FTd2FqWWRrTDZBUU9wK2ZSd2dBSWZrRUJRTUFId0FzQVFBQUFDVUJBd0FBQlV6Z0o0NWthWjVvcXE1czY3NXdMTTkwL1RaNHJ1dkZSbkVSbXduUklncHRSbGhTaEdnZW45QW9paUdOTWE3WXJHYXJZV2drbEUrblNpNURDUVN6ZXMydUxkN3crR0ZPQndjVVVVNElBQ0g1QkFVREFCOEFMQVVCQUFBUUFBTUFBQVVZWUNHS1RkbU1ncFJFU050cXNPWWlWZElkZUs3bmRSUUNBQ0g1QkFVREFCOEFMQkVCQUFBT0FBTUFBQVVYWUZFMFpIT0pCU1lsRVlKb01PeTZhM2ZjZUU1VWJBZ0FJZmtFQlFNQUh3QXNHd0VBQUEwQUF3QUFCUlpnY1RWa1U1d1M5YTFhMnlKd1JYSGZZZCszckNnaEFDSDVCQVVEQUI4QUxDUUJBQUFMQUFNQUFBVVdZRkUwSkxsUjNZY2dXcXN4a3ZOMVIyMFRWZk1wSVFBaCtRUUZBd0FmQUN3R0FBQUFMQUVEQUFBRk9lQW5qbVJwbm1pcXJtenJ2bkFzejNSdDMvQlY3TVYxTllOZ0VFY3N1alFJbzNMSmJEcGxEQ1JpT2kwOHI5aXNkc3Z0SHI3ZnplWVNBZ0E3KSA1MCUgbm8tcmVwZWF0OyB9XG5cbi5iZXN0LWVkaXRvci1kaWFsb2cge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgcmlnaHQ6IDA7XG4gIGJvdHRvbTogMDtcbiAgei1pbmRleDogOTk5OTk5OTk5OTk5OTtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjcpOyB9XG4gIC5iZXN0LWVkaXRvci1kaWFsb2cgLndyYXAge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDUwJTtcbiAgICBsZWZ0OiA1MCU7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgd2lkdGg6IDQxMnB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgIC13ZWJraXQtYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4yKTtcbiAgICBib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLCAwLCAwLCAwLjIpO1xuICAgIHBhZGRpbmc6IDE2cHg7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDsgfVxuICAgIC5iZXN0LWVkaXRvci1kaWFsb2cgLndyYXAgLmhlYWQgLmNsb3NlIHtcbiAgICAgIHRleHQtYWxpZ246IHJpZ2h0OyB9XG4gICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5oZWFkIC5jbG9zZSBhIHtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgICBmb250LXNpemU6IDI0cHg7XG4gICAgICAgIGNvbG9yOiAjOTk5O1xuICAgICAgICB0cmFuc2l0aW9uOiBjb2xvciAuM3MgZWFzZTsgfVxuICAgICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5oZWFkIC5jbG9zZSBhOmhvdmVyIHtcbiAgICAgICAgICBjb2xvcjogIzRkNGQ0ZDsgfVxuICAgIC5iZXN0LWVkaXRvci1kaWFsb2cgLndyYXAgLmhlYWQgaDMge1xuICAgICAgZm9udC1zaXplOiAyMnB4O1xuICAgICAgcGFkZGluZy1ib3R0b206IDI2cHg7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7IH1cbiAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IHtcbiAgICAgIHBhZGRpbmc6IDE1cHggMzBweCAzMHB4OyB9XG4gICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC51cGxvYWQtYnRuIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBoZWlnaHQ6IDQycHg7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDIwcHg7XG4gICAgICAgIGJhY2tncm91bmQ6ICM1NTU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDQycHg7XG4gICAgICAgIGNvbG9yOiAjZmZmO1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjsgfVxuICAgICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC51cGxvYWQtYnRuIGlucHV0IHtcbiAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgdG9wOiAtMTIwMDBweDtcbiAgICAgICAgICByaWdodDogMDtcbiAgICAgICAgICBsZWZ0OiAwOyB9XG4gICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC5pbnB1dC1ib3gge1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAyMHB4OyB9XG4gICAgICAgIC5iZXN0LWVkaXRvci1kaWFsb2cgLndyYXAgLmJvZHkgLmlucHV0LWJveCA+IGRpdiB7XG4gICAgICAgICAgaGVpZ2h0OiA0MnB4O1xuICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XG4gICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgICBsaW5lLWhlaWdodDogNDJweDsgfVxuICAgICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC5pbnB1dC1ib3ggLmljb24tYm94IHtcbiAgICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2VlZTtcbiAgICAgICAgICB3aWR0aDogMzhweDtcbiAgICAgICAgICBjb2xvcjogIzU5NTk1OTsgfVxuICAgICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC5pbnB1dC1ib3ggLmlucHV0IHtcbiAgICAgICAgICBib3JkZXItbGVmdDogMDtcbiAgICAgICAgICBmbGV4OiAxOyB9XG4gICAgICAgICAgLmJlc3QtZWRpdG9yLWRpYWxvZyAud3JhcCAuYm9keSAuaW5wdXQtYm94IC5pbnB1dCBpbnB1dCB7XG4gICAgICAgICAgICBib3JkZXI6IDA7XG4gICAgICAgICAgICBvdXRsaW5lOiBub25lO1xuICAgICAgICAgICAgd2lkdGg6IDk5JTtcbiAgICAgICAgICAgIGJvcmRlci1sZWZ0OiAwO1xuICAgICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgICAgIHBhZGRpbmc6IDAgMTBweDtcbiAgICAgICAgICAgIGNvbG9yOiAjNTk1OTU5OyB9XG4gICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC5zd2l0Y2gtYm94IHtcbiAgICAgICAgY29sb3I6ICM4ODg7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcbiAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyOyB9XG4gICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC53YXJpbmctdHh0IHtcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICBsaW5lLWhlaWdodDogMjBweDtcbiAgICAgICAgY29sb3I6ICNiYzYzNTE7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogNXB4OyB9XG4gICAgICAuYmVzdC1lZGl0b3ItZGlhbG9nIC53cmFwIC5ib2R5IC5idG4tYm94IHtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICB0ZXh0LWFsaWduOiByaWdodDtcbiAgICAgICAgaGVpZ2h0OiAzMHB4O1xuICAgICAgICBsaW5lLWhlaWdodDogMjBweDtcbiAgICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgICAgIGNvbG9yOiAjNTk1OTU5OyB9XG4gICAgICAgIC5iZXN0LWVkaXRvci1kaWFsb2cgLndyYXAgLmJvZHkgLmJ0bi1ib3ggPiBzcGFuIHtcbiAgICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICAgICAgdHJhbnNpdGlvbjogY29sb3IgLjNzIGVhc2U7XG4gICAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgICAgIHBhZGRpbmc6IDRweCAxMnB4O1xuICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgICBmb250LXdlaWdodDogNTAwOyB9XG4gICAgICAgIC5iZXN0LWVkaXRvci1kaWFsb2cgLndyYXAgLmJvZHkgLmJ0bi1ib3ggLmNhbmNlbDpob3ZlciB7XG4gICAgICAgICAgY29sb3I6ICMwMDA7IH1cbiAgICAgICAgLmJlc3QtZWRpdG9yLWRpYWxvZyAud3JhcCAuYm9keSAuYnRuLWJveCAuY29uZmlybSB7XG4gICAgICAgICAgY29sb3I6ICM0MmMwMmU7XG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbiAgICAgICAgICBib3JkZXI6IDFweCBzb2xpZCAjNDJjMDJlO1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDE1cHg7XG4gICAgICAgICAgbWFyZ2luLWxlZnQ6IDE1cHg7IH1cbiIsIlxyXG5AZm9udC1mYWNlIHtmb250LWZhbWlseTogXCJpY29uZm9udFwiO1xyXG4gIHNyYzogdXJsKGZvbnRzL2ljb25mb250LmVvdCk7IC8qIElFOSovXHJcbiAgc3JjOiB1cmwoZm9udHMvaWNvbmZvbnQuZW90I2llZml4KSBmb3JtYXQoJ2VtYmVkZGVkLW9wZW50eXBlJyksIFxyXG4gIHVybCgnZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtd29mZjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxkMDlHUmdBQkFBQUFBQTZVQUFzQUFBQUFGZ2dBQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQkhVMVZDQUFBQkNBQUFBRE1BQUFCQ3NQNno3VTlUTHpJQUFBRThBQUFBUkFBQUFGWThqazdvWTIxaGNBQUFBWUFBQUFEL0FBQUMrSk5aaG8xbmJIbG1BQUFDZ0FBQUNVRUFBQTAwdGlHYWtHaGxZV1FBQUF2RUFBQUFNUUFBQURZU1lLZ09hR2hsWVFBQUMvZ0FBQUFnQUFBQUpBZmZBNUJvYlhSNEFBQU1HQUFBQUJzQUFBQllXQVAvOTJ4dlkyRUFBQXcwQUFBQUxnQUFBQzRucUNTT2JXRjRjQUFBREdRQUFBQWZBQUFBSUFFbUFJTnVZVzFsQUFBTWhBQUFBVVVBQUFKdFBsVCtmWEJ2YzNRQUFBM01BQUFBeFFBQUFRN3Q3VUFxZUp4allHUmdZT0Jpa0dQUVlXQjBjZk1KWWVCZ1lHR0FBSkFNWTA1bWVpSlFETW9EeXJHQWFRNGdab09JQWdDS0l3TlBBSGljWTJCa1lXQ2N3TURLd01IVXlYU0dnWUdoSDBJenZtWXdZdVJnWUdCaVlHVm13QW9DMGx4VEdCeWVTYno1eHR6d3Y0RWhocm1Cb1FFb3pBaVNBd0R4MXd6M2VKemxrazFLQTBFUWhWOVB4dmczL293NjRGSk1zaEd2a0lNa2tFVk1jb1RrY081eW1UY0RHY2d1Mi9ocW5naUM2QUdzNGh2b3BwaXVycThCbkFEb2lWZVJBNmxGUWdTMW03cjlIaTY2L1J6dldqOHBWY2RIRGpqaWxET3V1T0dXK3pxcnE2WnNocnR4ZXpnZXZ5b21xcGh6L1ZQRnI1RzZreUtmbFMvcTQzdEd4Um5PY1lrQ1Y3akdEVzVSNGc0Wkt2WDdvSHZkbzQ5VGRSKzM2djl4Mm4rSUlqNnArRnhWWWNpRVp3Nk1aZ3FPaktZTFRvem1ERTVOL0lrem85bURjeU1MNEp1UkQzQmhaQVpjR2prQ1YwYTJ3TFdSTjNCanV0NjJKdDRlOTBaV1VXY20zbTFkR1psR1V4bzVSek0wc28vZDJNUWJidzhHK1FkbmJXYXBBSGljalZkOWJCeEhGWiszYzdkN2QzdGY2OXVQKzc3ZFc5K3U3Mnp2bmUremNYTzJreERYYnBMbWc0U1FwbW9EYlExQ1RVQVFWMjFSaWhVRk5XMGlKVzBFb29IeUIwSGhqeVpWSXdGRkNOZHRDaFdJU0pWQVFrb2pwTFlVVUZ1Q0dsUzFGZmpXdkxsejBzUTBFdlo2M3B2ZjI1bDlNL1BlNzQwSlI4alNSWHFjMmtRaGFVSzhwbFVHUStBRk0yKzFvTm1xcVJxb1BOUnN5K1lGT3Z0UWxOL3AvbkViSC8xYU1PeUJxaEQ1ZW9TSDJ6eGh0Ky8zVTMwaE1XeEIrSzIzd2lBSGFTWU1FRnA4UzFUZ3dmbktnTlZQOElmaXQvNUQ3MFdoa21GeUx5RUZ0Vlp0MUczSFkrWUZXVlh3ajljb1ltTmNvKzV3UFpBOUNyVEcyRE1PS0JwUjIrSEszQmpVcXZocWxpcHltQXBaWUFLZE52TVJnSjhYakY4cElkTW9Gekw5WVMvd25CQlJqR0o3SkptcGpocUpBWS9YL1FmNEp2c29EeFNBRTdtK2xEakFqZnhycmVpSTV0b3hKeDNWU3Jua3BobHpkTXQyUi8yODJyaHYvMVQwSjZzTU5TdjVPRy95SzhsOHR1QUVZTllUMGtkTFpqMGJGaEwzSjhLTmtDYTY2OHBjME1kSC9GRWg3alhnUGNVamVNQlRBcjgzbENtTldjbkJUQ1lhbE83ZFVOMWNNOFBVeXhPQ3o5SmxEOUFZOFJHSkdLUkVSc250aExSa1BtL1ZtMVcxY1ZYQkJmS21rYmZhVUcvV0RPemZ6Q0N0NkYrYTJEMXg3YUVGVWVoTSt3SUJIL2VDSUM1ZStqVDBlbjMzY0hmZ1I4N0V4RjBURSs3YmUzMmk2R01OSnpwZGkvdlhmV3dFYXlCenpZcG52YlMwOUR0Y1Y0dEVTSlhjUXdoVTFReGM1MW5Cc3EwR3lxcW1zbDlGamtBWkVEUHpQSjU1RnhScUNHTXNkbi9OZk5lTVkyMXJIQm90TlFlcWx1VXdXQUJEeUtML1pDNHY5ck1XdUdnby9mUjMwdXVzY1o3M1VhSGlTMmRyNjlkdTJ2and3SzJHK3RoN25uZ29wUmFIUzg3a212SVczZThCL0JuMSswSWVLbGNuaTRXZGRVZUd1WUN2d09iQ3BpQW5icWwvNlNrUm85R1p6SXNSemdNNzlQcTZhbW1US2FhaW9STnFkbUtWbnBhVDZVQXdwUGtGcjA4WVMwbXFrdUJrUlJjOVJpbWVYVzlYU2xIY0FwWUUzQkxua2dyR2ZqZWlXN0ZtcStHQTNkSXdsc2VCRjhJZzhCRUlRd1Q0REM0UWRiU3lUUkVnRUIvUmZBRnVkWVZYeWxwZ3owaGx3TjVNK1dRajRmTUlmVU55VkhRY0VIUmxTS25WakxXNnd3ZEZNUmtDOWMzUlVJQnlkUytsWGszMWhmeUtNcmpuNVQzVFZjWHY1eE54RG53QUFtVytMWDFJejlNQTVpYUpaVUZyT2RCQS82cDRESVlrb0JOaFRMNnRreHNhYmJwd2JQS1I4cU93OVZENzFOMExMa3pObkIzZlVUNjQ4ZGdDclNPODdkRFlldkM2aEN6UCtVcHZUbHlUWUV1R2pYbUxzMk5IdzlrZDRNamRwOXFIWU51M3lvOU1IbHZ3UUx1eDRiWXRPSndHWVAzWUlmZTVSOHQxL043R2crVWQ0MmRuRmx6aXdUbC9TMzlCYnlGZUltTEdhSmdyTmFVbUdURlRNU1FUYW8xYXc0ZzFUTWxvVE0wZmNGK2RuNGZSQS9Ed2dYbjMxUU1IWVBUYjJNVWVqQzRlbjBlWW9hUTc1MS9vTXpUenlad3hOb0ZKdTdOQmQyYXFzTTljbkFYcjNPenNPZmQxN3BWellNMmVPemNMQWZmMVdYam0zR3lualVhdWJ4YnhYbDdQWWZ4L0UxbDFGWmttbnlNejVFRkNOTXlBdk4zQ3cyNDI2b0xOSW1CRVVNeEdUVUVLaXlrbXBzUVlyZU41QzNhWDRKRFZPS0hXOEs1TWZqYWtaZkk0UTAxWmFWeEpBSytQTzZzdFBXMUk4ZFdSV0ZnV1crMkZWc2FFMTJqU3NsSlNPQ21QaEp0R2FaVmR0bUdhZnVGR2ZsaG9BM2pqeFR2YTlJczNvNGpzY01PcUpxVm92MGRQeERRUnNqdHJhNFJCdUgyM0xHWXFtVVFpSFRIeUdiMWNURmVTdVlqNXdqV09nSCt2V3ZWVVFCbWMvdnVmZXhUaUM5eElJZDE2OFJKOW1hN0JVNUZKdXhkREdEemR3S0U5OXBQNUdJSmhEdk1GMlI5M0Q3TUtxd2Z1WUJpV0FTd1N5SkVjTEhTODNzN0NpNng5U1U0bUI1TEp2ZjVVM2gvMGNoNCtoVHNUbC91aUFTT1p6Y1JTRVRXL1pyRFl6dE0xVjBlOHVORHAzSjhxSnBQRkZBekdrcm8vSlBKeVZvN0Z6VlFzR3BXRG1xNVBhS0gwTGYzWlJpN0IwaHg5UDA5L1RDZHhGVmo4V2diR2tLRkVRSks3WnkrVm9kSHJNcmR0ekRWRTdxTGppeS9EekthK2V4NjRiMWZmRmtodGxINXdkdmZqZGpZaGJSYlcwME5OUHVvKzh0VTk5KytIaDJKQ3N5bkUzQVBmUDFJZU11LzhMQnlNOHQxdjRxYTl4SjNIQ0M3amJwa3NmNXQxQzFOWGtIRGZhcXg2T2xENEZNekdkK25FSFBmQXRsUi9mK3J3enloTU4rZWEwd0RUYm1BbDBzVFg0T0RXdlZ5aDJRK2VueDVlSXEwcGdLbldYSFBxL1A5QzNOYTl6QzFQMTdjSEtlQlphc1JrL3NYWUNiSUF4VDBRdXEzUlJidzMwYy9nSG12Y0NkYnVZNDA3M1FVS3JPM3MvVVJmeGs4WXc3bytiT3pMT1liaDVDN3BUaTduNkpjTUpveGV6bjlBajlMZ2RmNFlXU3hRZ3VGZzNtai9oMzZXTzQwZmluZDJ4N0dGWDhmMVhNSmR6WFR1TkdzN2Q2N0FhUkQwaWc2c2VSTnlJNmpscXJtVkdxZFhjc3Y3aGR6NUkrVE9QcExGQ3ZvWnJCaDVqSk5XczlidnJXcFpMQk9Dd1dPRlVGRmlYV3kySUc4eXI1aFo3ZG56Sm5TOUxiSWE0aUI5MTFwVm9Gb3M2dWZGRVJnR1IrbUxpcnc0NkY3NEx2eW1IUFRuamM3YW9WQkF6OE9aSng3UEdFWWFZaUFIVkYvRXo0ZUtSNCtBa3RLTnBMdm9kZ0t5UCt3UHB1VVBqbHdVQTBhZkJjQkVBZTlTSTJCbGl3Qm1kZ2pjNXlFN2tzUGl3cVBONU55ejJNMWkxeXNhK1JoY1hlTlIrZ0hkMzQzWGNUS0JhK1JabWErUGc0V1ZqNWV4eGxmWnBjL0dHcGhuWlZGck5hc0k0bVZCYlk1RHN3NmFXc1Y3YWgwSDVRVWNvTUYycGFuc2tlVXJ4VjNtbVlHQjQ2VUhTbWNNVVlQSHJtcFhycmQzdHNlakExR0lSaUpNdXU5SElySXM3OEUzcm1paWNRWkhIQjhZT0dQdUtzSUx5OHFWRzh6dUhmRklCS0k0RktYN1BzcnVtdjdtSVRTSjk1NGNHY0I3THNGRDBDUk1Od3dhVzhKMEt4akx1V2RnUjNMQUc0WWVsMUZEQkp1ZXhNT0RyTFo0b1NkcGZmSEM0Q2hlVUFacHZTczcwMUNaR2htWnFyeEk3MzduM1ZQY3U1RFRPaWMxM09tY3hzMmdyTURvVU9ma0VIdDNpSnNaR24ydFVLbE1WeXFkaitGRDkrbnZMWFBURXYwbDBpdXJUVjFXUlhjd0U1R1hrQmxNVnZlUnBMQitXR2JYVitRc05ESmZyeGtaYVpqMHk0ZWZveUFGWVhOUWtvSWYwZjBiNjB6cHZJMXdEd1cwZmtpL3NhbldVeW1oeng5MmQ0VWtLUVIzSUhUcnBsbDg4ZGFRZEJPWVhaYytYbnJUNDZNNS9QOGtqcjQ2b0xOTGtzYXpHTmViV0VEdHBnV1NsLzR3ZmRuOTArVjBld2hncUoyK0RLVmx2VE1QTFJyd0JZTyt4QnRQUHZsRzRwcldPUTEvZUtkM0o2T0VtME1lSUtBSk5wWlV2STIxTkc3SHN6dWV2ZnJBM0hXZC93S0ZVVzlUQUFBQWVKeGpZR1JnWUFEaXhPN2dpbmgrbTY4TTNDd01JSEI5d1NadUdQMy94LzhHRmc3bWFpQ1hnNEVKSkFvQVBqWUwyZ0FBQUhpY1kyQmtZR0J1K04vQUVNUEMrUC9IL3g4c0hBeEFFUlFnQmdDZ1B3WjJlSnhqWVdCZ1lFSEdqUC8vSTlob2NrVGgvejlBTkFDbDhRUlFBQUFBQUFBQU5nREFBU3dCdGdJRUFpNENXQUtDQXF3RFRnT3NBK1lFTkFSOEJNd0ZQZ1dvQmZvR1VBYUFCcG9BQUhpY1kyQmtZR0FRWXlobllHTUFBU1lnNWdKQ0JvYi9ZRDREQUJiRkFhb0FlSnhsajAxT3d6QVFoVi82QjZRU3FxaGdoK1FGWWdFby9SR3JibGhVYXZkZGROK21UcHNxaVNQSHJkUURjQjZPd0FrNEF0eUFPL0JJSjVzMmxzZmZ2SGxqVHdEYzRBY2VqdDh0OTVFOVhESTdjZzBYdUJldVUzOFFicEJmaEp0bzQxVzRSZjFOMk1jenBzSnRkR0Y1ZzllNFl2YUVkMkVQSFh3STEzQ05UK0U2OVMvaEJ2bGJ1SWs3L0FxMzBQSHF3ajdtWGxlNGpVY3Y5c2RXTDV4ZXFlVkJ4YUhKSXBNNXY0S1pYdStTaGEzUzZweHJXOFFtVTRPZ1gwbFRuV2xiM1ZQczEwUG5JaFZaazZvSnF6cEpqTXF0MmVyUUJSdm44bEd2RjRrZWhDYmxXR1ArdHNZQ2puRUZoU1VPakRGQ0dHU0l5dWpvTzFWbTlLK3hROEplZTFZOXplZDBXeFRVLzNPRkFRTDB6MXhUdXJMU2VUcFBnVDFmRzFKMWRDdHV5NTZVTkpGZXpVa1Nza0plMXJaVVF1b0JObVZYamhGNlhOR0pQeWhuU1A4QUNWcHV5QUFBQUhpY2JZekJVc0pBRUVTM2NaTkFBb0tnK0JVNVdCNzhIQXMyazJSa2FoZDJaeTM1ZTFPVml3ZmZxYnVydTgzQ3pOVG1mNDVZNEFFV0JVcFVXR0tGR2czVzJPQVJXK3p3aEQwT2VNWUxqbmcxdGc5ZTdUbElWd2tuYmJOc2trYStrSTR4NUdFc1dVL0N6a2JxZ3MyK0M3cytpN1RKUlNMZjBnOXI4eWVZUDRMWWtlUzZtdW9VaFQwZFB0N2V6M3p5WDN6anp6djdlL0REZXJvZGZPdklLOFY2TmtLOU5yT01QSXhxcC9HbHVyTFRIS204NWFDVWltL3VLQlJPUWlKamZnSCt4RVlSQUFBQScpIGZvcm1hdCgnd29mZicpLFxyXG4gIHVybChmb250cy9pY29uZm9udC50dGYpIGZvcm1hdCgndHJ1ZXR5cGUnKVxyXG59XHJcblxyXG4uaWNvbmZvbnQge1xyXG4gIGZvbnQtZmFtaWx5OlwiaWNvbmZvbnRcIiAhaW1wb3J0YW50O1xyXG4gIGZvbnQtc3R5bGU6bm9ybWFsO1xyXG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xyXG4gIC1tb3otb3N4LWZvbnQtc21vb3RoaW5nOiBncmF5c2NhbGU7XHJcbn1cclxuXHJcbi5pY29uLWZvbnQ6YmVmb3JlIHsgY29udGVudDogXCJcXEU2MThcIjsgfVxyXG5cclxuLmljb24tYm9sZDpiZWZvcmUgeyBjb250ZW50OiBcIlxcRTY3NVwiOyB9XHJcblxyXG4uaWNvbi1saXN0LXVsOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFQjNEXCI7IH1cclxuXHJcbi5pY29uLXN0cmlrZXRocm91Z2g6YmVmb3JlIHsgY29udGVudDogXCJcXEVDRjZcIjsgfVxyXG5cclxuLmljb24taXRhbGljOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNzAyXCI7IH1cclxuXHJcbi5pY29uLXJlZG86YmVmb3JlIHsgY29udGVudDogXCJcXEU4MTFcIjsgfVxyXG5cclxuLmljb24tdW5kbzpiZWZvcmUgeyBjb250ZW50OiBcIlxcRTgyNFwiOyB9XHJcblxyXG4uaWNvbi1mdWxsLXNjcmVlbi1leGl0OmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNjIzXCI7IH1cclxuXHJcbi5pY29uLWZ1bGwtc2NyZWVuOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNjI1XCI7IH1cclxuXHJcbi5pY29uLWxpc3Qtb2w6YmVmb3JlIHsgY29udGVudDogXCJcXEU2QzFcIjsgfVxyXG5cclxuLmljb24taGVscDpiZWZvcmUgeyBjb250ZW50OiBcIlxcRTY1OVwiOyB9XHJcblxyXG4uaWNvbi11bmRlcmxpbmU6YmVmb3JlIHsgY29udGVudDogXCJcXEU2NUFcIjsgfVxyXG5cclxuLmljb24tNzEzYmlhbmppcWlfeWlueW9uZzpiZWZvcmUgeyBjb250ZW50OiBcIlxcRTY1RFwiOyB9XHJcblxyXG4uaWNvbi1hbGlnbi1jZW50ZXI6YmVmb3JlIHsgY29udGVudDogXCJcXEU2NjFcIjsgfVxyXG5cclxuLmljb24tYWxpZ24tbGVmdDpiZWZvcmUgeyBjb250ZW50OiBcIlxcRTY2MlwiOyB9XHJcblxyXG4uaWNvbi1hbGlnbi1yaWdodDpiZWZvcmUgeyBjb250ZW50OiBcIlxcRTY2M1wiOyB9XHJcblxyXG4uaWNvbi1saW5rOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNjY0XCI7IH1cclxuXHJcbi5pY29uLXBpY3R1cmU6YmVmb3JlIHsgY29udGVudDogXCJcXEU2NjVcIjsgfVxyXG5cclxuLmljb24tcXVvdGVzOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNzE1XCI7IH1cclxuXHJcbi5pY29uLXZpZGVvOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNkVGXCI7IH1cclxuXHJcbi5pY29uLWNsb3NlOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxFNjc2XCI7IH1cclxuXHJcbiJdLCJzb3VyY2VSb290IjoiIn0=*/
--------------------------------------------------------------------------------
/dist/best-editor.min.css:
--------------------------------------------------------------------------------
1 | .best-editor-container {
2 | display: flex;
3 | flex-direction: column; }
4 | .best-editor-container.full-screen {
5 | position: fixed;
6 | z-index: 9999;
7 | top: 0;
8 | left: 0;
9 | right: 0;
10 | bottom: 0;
11 | width: 100% !important;
12 | height: 100% !important;
13 | background-color: #d9d9d9; }
14 | .best-editor-container.full-screen .best-editor {
15 | width: 60%;
16 | margin: 0 auto;
17 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
18 | margin-top: 35px;
19 | margin-bottom: 20px; }
20 | .best-editor-container .best-editor-toolbar {
21 | background-color: #d9d9d9;
22 | border-bottom: 1px solid #ccc;
23 | user-select: none;
24 | box-sizing: border-box; }
25 | .best-editor-container .best-editor-toolbar ul {
26 | zoom: 1;
27 | list-style: none;
28 | word-break: break-all; }
29 | .best-editor-container .best-editor-toolbar ul li {
30 | list-style: none;
31 | float: left; }
32 | .best-editor-container .best-editor-toolbar ul li a {
33 | height: 39px;
34 | line-height: 39px;
35 | color: #595959;
36 | padding: 0 14px;
37 | display: inline-block;
38 | font-size: 16px;
39 | font-weight: bold;
40 | cursor: pointer; }
41 | .best-editor-container .best-editor-toolbar ul li a:hover {
42 | color: #f2f2f2;
43 | background-color: #595959; }
44 | .best-editor-container .best-editor-toolbar ul:after {
45 | content: ".";
46 | display: block;
47 | height: 0;
48 | clear: both;
49 | visibility: hidden; }
50 | .best-editor-container .best-editor {
51 | flex: 1;
52 | outline: none;
53 | padding: 30px;
54 | box-sizing: border-box;
55 | padding-top: 15px;
56 | overflow-y: auto;
57 | background: #fff; }
58 | .best-editor-container .best-editor p {
59 | margin: 15px 0;
60 | word-break: break-word; }
61 | .best-editor-container .best-editor h1, .best-editor-container .best-editor h2, .best-editor-container .best-editor h3, .best-editor-container .best-editor h4, .best-editor-container .best-editor h5, .best-editor-container .best-editor h6 {
62 | margin: 15px 0; }
63 | .best-editor-container .best-editor a {
64 | text-decoration: none;
65 | color: #3194d0; }
66 | .best-editor-container .best-editor blockquote {
67 | padding: 20px;
68 | background-color: #f2f2f2;
69 | border-left: 6px solid #b3b3b3;
70 | word-break: break-word;
71 | font-size: 16px;
72 | font-weight: 400;
73 | line-height: 30px;
74 | margin: 0 0 20px; }
75 | .best-editor-container .best-editor iframe {
76 | display: block;
77 | margin: 0 auto; }
78 | .best-editor-container .best-editor ul, .best-editor-container .best-editor ol {
79 | list-style-position: inside;
80 | margin: 15px 0; }
81 | .best-editor-container .best-editor .image-box {
82 | text-align: center;
83 | font-size: 0;
84 | margin: 15px 0; }
85 | .best-editor-container .best-editor .image-box > img {
86 | max-width: 100%;
87 | width: auto;
88 | height: auto;
89 | vertical-align: middle;
90 | border: 0; }
91 | .best-editor-container .best-editor .image-box .image-upload {
92 | width: 443px;
93 | padding: 5px 16px 5px 5px;
94 | margin: 0 auto;
95 | border: 1px solid #d9d9d9;
96 | overflow: hidden;
97 | font-size: 14px;
98 | -webkit-box-sizing: border-box;
99 | box-sizing: border-box; }
100 | .best-editor-container .best-editor .image-box .image-upload .preview-image {
101 | display: block;
102 | float: left;
103 | width: 90px;
104 | height: 90px;
105 | object-fit: cover;
106 | margin-right: 20px; }
107 | .best-editor-container .best-editor .image-box .image-upload .status-bar {
108 | display: block;
109 | float: right;
110 | width: 305px; }
111 | .best-editor-container .best-editor .image-box .image-upload .status-bar .upload-error-msg {
112 | color: #f50; }
113 | .best-editor-container .best-editor .image-box .image-upload .status-bar .status-area a {
114 | float: right;
115 | margin-left: 20px;
116 | cursor: pointer;
117 | color: #999; }
118 | .best-editor-container .best-editor .image-box .image-upload .status-bar .status-area .upload-btn-retry {
119 | display: none; }
120 | .best-editor-container .best-editor .image-box .image-upload .status-bar .uploading-icon {
121 | height: 3px;
122 | width: 305px;
123 | min-height: 3px;
124 | display: block;
125 | margin: 25px 0 20px;
126 | background: url(data:image/gif;base64,R0lGODlhMgEDAMQfACV79DaH+avH8bDK9rDJ7ajI8qvI7q3K8a/M92Oc7ih776/K9KrL9KbH8KbK8jV/7i9+7xhw8bjT+ICw8pLF+sHW9a3H8ajH8azJ8LPL9q3L9rPL7zB/8SV89zSH/f///yH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2QTdFQzI3OUUyMUQxMUU2OEVGMUVFRTY0NzY1NUJEMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2QTdFQzI3QUUyMUQxMUU2OEVGMUVFRTY0NzY1NUJEMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZBN0VDMjc3RTIxRDExRTY4RUYxRUVFNjQ3NjU1QkQzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjZBN0VDMjc4RTIxRDExRTY4RUYxRUVFNjQ3NjU1QkQzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwv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) 50% no-repeat; }
127 |
128 | .best-editor-dialog {
129 | position: fixed;
130 | top: 0;
131 | left: 0;
132 | right: 0;
133 | bottom: 0;
134 | z-index: 9999999999999;
135 | background-color: rgba(255, 255, 255, 0.7); }
136 | .best-editor-dialog .wrap {
137 | position: absolute;
138 | top: 50%;
139 | left: 50%;
140 | transform: translate(-50%, -50%);
141 | width: 412px;
142 | background-color: #fff;
143 | border-radius: 6px;
144 | -webkit-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
145 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
146 | padding: 16px;
147 | box-sizing: border-box; }
148 | .best-editor-dialog .wrap .head .close {
149 | text-align: right; }
150 | .best-editor-dialog .wrap .head .close a {
151 | cursor: pointer;
152 | font-size: 24px;
153 | color: #999;
154 | transition: color .3s ease; }
155 | .best-editor-dialog .wrap .head .close a:hover {
156 | color: #4d4d4d; }
157 | .best-editor-dialog .wrap .head h3 {
158 | font-size: 22px;
159 | padding-bottom: 26px;
160 | text-align: center; }
161 | .best-editor-dialog .wrap .body {
162 | padding: 15px 30px 30px; }
163 | .best-editor-dialog .wrap .body .upload-btn {
164 | position: relative;
165 | height: 42px;
166 | margin-bottom: 20px;
167 | background: #555;
168 | overflow: hidden;
169 | text-align: center;
170 | line-height: 42px;
171 | color: #fff;
172 | font-size: 14px;
173 | cursor: pointer; }
174 | .best-editor-dialog .wrap .body .upload-btn input {
175 | position: absolute;
176 | top: -12000px;
177 | right: 0;
178 | left: 0; }
179 | .best-editor-dialog .wrap .body .input-box {
180 | display: flex;
181 | margin-bottom: 20px; }
182 | .best-editor-dialog .wrap .body .input-box > div {
183 | height: 42px;
184 | border: 1px solid #ccc;
185 | box-sizing: border-box;
186 | line-height: 42px; }
187 | .best-editor-dialog .wrap .body .input-box .icon-box {
188 | text-align: center;
189 | background-color: #eee;
190 | width: 38px;
191 | color: #595959; }
192 | .best-editor-dialog .wrap .body .input-box .input {
193 | border-left: 0;
194 | flex: 1; }
195 | .best-editor-dialog .wrap .body .input-box .input input {
196 | border: 0;
197 | outline: none;
198 | width: 99%;
199 | border-left: 0;
200 | box-sizing: border-box;
201 | padding: 0 10px;
202 | color: #595959; }
203 | .best-editor-dialog .wrap .body .switch-box {
204 | color: #888;
205 | cursor: pointer;
206 | font-size: 14px;
207 | padding-bottom: 10px;
208 | text-align: center; }
209 | .best-editor-dialog .wrap .body .waring-txt {
210 | height: 20px;
211 | line-height: 20px;
212 | color: #bc6351;
213 | font-size: 14px;
214 | margin-bottom: 5px; }
215 | .best-editor-dialog .wrap .body .btn-box {
216 | font-size: 14px;
217 | text-align: right;
218 | height: 30px;
219 | line-height: 20px;
220 | user-select: none;
221 | color: #595959; }
222 | .best-editor-dialog .wrap .body .btn-box > span {
223 | display: inline-block;
224 | transition: color .3s ease;
225 | cursor: pointer;
226 | padding: 4px 12px;
227 | font-size: 14px;
228 | font-weight: 500; }
229 | .best-editor-dialog .wrap .body .btn-box .cancel:hover {
230 | color: #000; }
231 | .best-editor-dialog .wrap .body .btn-box .confirm {
232 | color: #42c02e;
233 | background-color: #fff;
234 | border: 1px solid #42c02e;
235 | border-radius: 15px;
236 | margin-left: 15px; }
237 |
238 |
239 | @font-face {font-family: "iconfont";
240 | src: url(fonts/iconfont.eot); /* IE9*/
241 | src: url(fonts/iconfont.eot#iefix) format('embedded-opentype'),
242 | url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
243 | url(fonts/iconfont.ttf) format('truetype')
244 | }
245 |
246 | .iconfont {
247 | font-family:"iconfont" !important;
248 | font-style:normal;
249 | -webkit-font-smoothing: antialiased;
250 | -moz-osx-font-smoothing: grayscale;
251 | }
252 |
253 | .icon-font:before { content: "\E618"; }
254 |
255 | .icon-bold:before { content: "\E675"; }
256 |
257 | .icon-list-ul:before { content: "\EB3D"; }
258 |
259 | .icon-strikethrough:before { content: "\ECF6"; }
260 |
261 | .icon-italic:before { content: "\E702"; }
262 |
263 | .icon-redo:before { content: "\E811"; }
264 |
265 | .icon-undo:before { content: "\E824"; }
266 |
267 | .icon-full-screen-exit:before { content: "\E623"; }
268 |
269 | .icon-full-screen:before { content: "\E625"; }
270 |
271 | .icon-list-ol:before { content: "\E6C1"; }
272 |
273 | .icon-help:before { content: "\E659"; }
274 |
275 | .icon-underline:before { content: "\E65A"; }
276 |
277 | .icon-713bianjiqi_yinyong:before { content: "\E65D"; }
278 |
279 | .icon-align-center:before { content: "\E661"; }
280 |
281 | .icon-align-left:before { content: "\E662"; }
282 |
283 | .icon-align-right:before { content: "\E663"; }
284 |
285 | .icon-link:before { content: "\E664"; }
286 |
287 | .icon-picture:before { content: "\E665"; }
288 |
289 | .icon-quotes:before { content: "\E715"; }
290 |
291 | .icon-video:before { content: "\E6EF"; }
292 |
293 | .icon-close:before { content: "\E676"; }
294 |
295 |
296 |
--------------------------------------------------------------------------------
/dist/fonts/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/dist/fonts/iconfont.eot
--------------------------------------------------------------------------------
/dist/fonts/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/dist/fonts/iconfont.ttf
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "best-editor",
3 | "version": "0.0.4",
4 | "description": "best-editor 一款简洁实用的web富文本编辑器",
5 | "homepage": "https://github.com/zc9/best-editor",
6 | "author": {
7 | "name": "zc9",
8 | "url": "https://github.com/zc9"
9 | },
10 | "keywords": [
11 | "best-editor",
12 | "bestEditor",
13 | "editor",
14 | "编辑器",
15 | "web富文本编辑器"
16 | ],
17 | "main": "dist/best-editor.js",
18 | "maintainers": [
19 | {
20 | "name": "zc9",
21 | "web": "https://github.com/zc9",
22 | "mail": "zouchao911@163.com"
23 | }
24 | ],
25 | "repositories": [
26 | {
27 | "type": "git",
28 | "url": "https://github.com/zc9/best-editor"
29 | }
30 | ],
31 | "scripts": {
32 | "build": "webpack --mode=production",
33 | "dev": "webpack --mode=development --progress --colors --watch",
34 | "test": "echo \"Error: no test specified\" && exit 1"
35 | },
36 | "license": "MIT",
37 | "devDependencies": {
38 | "babel-core": "^6.26.3",
39 | "babel-loader": "^7.1.5",
40 | "babel-preset-env": "^1.7.0",
41 | "css-loader": "^1.0.0",
42 | "file-loader": "^1.1.11",
43 | "html-loader": "^0.5.5",
44 | "mini-css-extract-plugin": "^0.4.1",
45 | "node-sass": "^4.9.2",
46 | "sass-loader": "^7.1.0",
47 | "style-loader": "^0.21.0",
48 | "uglifyjs-webpack-plugin": "^1.2.7",
49 | "webpack": "^4.16.4",
50 | "webpack-cli": "^3.1.0"
51 | },
52 | "dependencies": {
53 | "babel-polyfill": "^6.26.0",
54 | "mito": "^1.0.5"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/assets/iconfont.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face {font-family: "iconfont";
3 | src: url('iconfont.eot?t=1534759179951'); /* IE9*/
4 | src: url('iconfont.eot?t=1534759179951#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
6 | url('iconfont.ttf?t=1534759179951') format('truetype')
7 | }
8 |
9 | .iconfont {
10 | font-family:"iconfont" !important;
11 | font-style:normal;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | .icon-font:before { content: "\e618"; }
17 |
18 | .icon-bold:before { content: "\e675"; }
19 |
20 | .icon-list-ul:before { content: "\eb3d"; }
21 |
22 | .icon-strikethrough:before { content: "\ecf6"; }
23 |
24 | .icon-italic:before { content: "\e702"; }
25 |
26 | .icon-redo:before { content: "\e811"; }
27 |
28 | .icon-undo:before { content: "\e824"; }
29 |
30 | .icon-full-screen-exit:before { content: "\e623"; }
31 |
32 | .icon-full-screen:before { content: "\e625"; }
33 |
34 | .icon-list-ol:before { content: "\e6c1"; }
35 |
36 | .icon-help:before { content: "\e659"; }
37 |
38 | .icon-underline:before { content: "\e65a"; }
39 |
40 | .icon-713bianjiqi_yinyong:before { content: "\e65d"; }
41 |
42 | .icon-align-center:before { content: "\e661"; }
43 |
44 | .icon-align-left:before { content: "\e662"; }
45 |
46 | .icon-align-right:before { content: "\e663"; }
47 |
48 | .icon-link:before { content: "\e664"; }
49 |
50 | .icon-picture:before { content: "\e665"; }
51 |
52 | .icon-quotes:before { content: "\e715"; }
53 |
54 | .icon-video:before { content: "\e6ef"; }
55 |
56 | .icon-close:before { content: "\e676"; }
57 |
58 |
--------------------------------------------------------------------------------
/src/assets/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/src/assets/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/iconfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
90 |
--------------------------------------------------------------------------------
/src/assets/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/src/assets/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zc9/best-editor/a9c2a6c5df297f5691da65e4b71e5a03ba93b809/src/assets/iconfont.woff
--------------------------------------------------------------------------------
/src/core/best-editor.js:
--------------------------------------------------------------------------------
1 | import $ from '../core/dom';
2 | import Toolbar from '../core/toolbar';
3 | import Handler from '../core/handler';
4 | import Selection from '../core/selection';
5 | import Request from '../core/request';
6 |
7 | class BestEditor {
8 | constructor (container, opts = {}) {
9 | this.config = {};
10 | this.selection = new Selection();
11 | var $container = $(container);
12 | this.toolbar = new Toolbar(opts.toolbar);
13 | var $toolbar = this.toolbar.$elem;
14 | this.$toolbar = $toolbar;
15 | $container.append($toolbar);
16 | $container.addClass('best-editor-container');
17 | this.$container = $container;
18 | if (opts.imageUpload) {
19 | this.config.imageUpload = opts.imageUpload;
20 | }
21 | if (opts.imageLinkUpload) {
22 | this.config.imageLinkUpload = opts.imageLinkUpload;
23 | }
24 | //create editor
25 | var $editor = $(document.createElement('div'));
26 | $editor.attr('contenteditable', true);
27 | $editor.addClass('best-editor');
28 | $container.append($editor);
29 | $editor.append('
');
30 | this.$editor = $editor;
31 |
32 | this.handler = new Handler(this);
33 |
34 | this._saveSelectionRealTime();
35 |
36 | this._handleKeyDownEvent();
37 |
38 | this._handleKeyUpEvent();
39 |
40 | this._handleTabEvent();
41 |
42 | this._handlePasteEvent();
43 |
44 | this._handleCmd();
45 |
46 |
47 | console.log('BestEditor Created');
48 | }
49 |
50 | //handle toolbar cmd
51 | _handleCmd () {
52 | var _sel = window.getSelection();
53 | var _this = this;
54 |
55 | this.toolbar.$elem.find('[data-cmd]').bind('mousedown', function (event) {
56 | _this.selection.save();
57 | var cmd = $(this).attr('data-cmd');
58 | var cmdValue = $(this).attr('data-cmd-value');
59 |
60 | console.log('command:', cmd, cmdValue);
61 | var cmdHandle = _this.handler.getHandle(cmd);
62 | if (cmdHandle) {
63 | cmdHandle(event);
64 | } else {
65 | _this.handler.execCommand(cmd, cmdValue);
66 | }
67 | event.preventDefault();
68 | })
69 | }
70 |
71 | addHandle (cmd, handle) {
72 | if (cmd && handle) {
73 | this.handler.addHandle(cmd, handle);
74 | }
75 | }
76 | getHTML() {
77 | return this.$editor.html();
78 | }
79 | //save the editor selection in real time
80 | _saveSelectionRealTime () {
81 | var _this = this;
82 | function _saveSelection() {
83 | _this.selection.save();
84 | }
85 | this.$editor.bind('keyup', _saveSelection)
86 | this.$editor.bind('mousedown', function (event) {
87 | _this.$editor.bind('mouseleave', _saveSelection)
88 | })
89 | this.$editor.bind('mouseup', function (event) {
90 | _saveSelection();
91 | _this.$editor.unbind('mouseleave', _saveSelection);
92 | })
93 |
94 | }
95 |
96 | //handle the editor keyup event
97 | _handleKeyUpEvent () {
98 | var _this = this;
99 | this.$editor.bind('keyup', function (event) {
100 |
101 | //handle the editor enter key event
102 | if(event.keyCode === 13) {
103 | var selectionElem = _this.selection.getContainerElement();
104 | var $parentElem = $(selectionElem).parent();
105 | if (!$parentElem.equal(_this.$editor)) {
106 | return;
107 | }
108 |
109 | var tagName = selectionElem.tagName.toUpperCase();
110 | if (tagName === 'P') {
111 | return;
112 | } else {
113 | var text = selectionElem.innerHTML.replace(/<.*?>/g, () => '');
114 | var $p = $('
');
115 | $p.insertBefore(selectionElem);
116 | $p.html(text);
117 | _this.selection.createRangeByElement($p[0]);
118 | _this.selection.restore();
119 | $(selectionElem).remove();
120 | }
121 | }
122 | if (event.keyCode === 8) {
123 | var txtHtml = _this.$editor.html().toLowerCase().trim();
124 | if (!txtHtml || txtHtml === '
') {
125 | var $p = $('
')
126 | _this.$editor.html('');
127 | _this.$editor.append($p);
128 | _this.selection.createRangeByElement($p[0], false, true);
129 | _this.selection.restore()
130 | }
131 | }
132 | })
133 | }
134 | //handle the editor keydown event
135 | _handleKeyDownEvent () {
136 | var _this = this;
137 | this.$editor.bind('keydown', function (event) {
138 |
139 | //handle the editor backspace key event
140 | if (event.keyCode === 8) {
141 | if ($(this).html().trim() == '
') {
142 | event.preventDefault();
143 | }
144 | }
145 | if (event.keyCode !== 13) {
146 | var selectionElem = _this.selection.getContainerElement();
147 | var $selectionElem = $(selectionElem);
148 | if ($selectionElem.hasClass('image-box')) {
149 | event.preventDefault();
150 | if (event.keyCode === 8) {
151 | _this.selection.createRangeByElement(selectionElem);
152 | _this.selection.delete();
153 | }
154 | }
155 | }
156 |
157 | });
158 | }
159 | //handle the editor tab key event
160 | _handleTabEvent () {
161 | var _this = this;
162 | this.$editor.bind('keydown', function (event) {
163 | if (event.keyCode !== 9) {
164 | return;
165 | }
166 | var selectionElem = _this.selection.getContainerElement();
167 | if (!selectionElem) {
168 | return;
169 | }
170 | _this.handler.insertHTML(' ');
171 | event.preventDefault();
172 |
173 | });
174 | }
175 | //handle the editor paste event
176 | _handlePasteEvent () {
177 | this.$editor.bind('paste', (e) => {
178 | e.preventDefault();
179 | this.handler.getHandle('paste')(e);
180 | });
181 | }
182 |
183 | }
184 | export default BestEditor;
--------------------------------------------------------------------------------
/src/core/dom.js:
--------------------------------------------------------------------------------
1 | class D {
2 | constructor (selector) {
3 | this.length = 0;
4 | this.selector = null;
5 | if (typeof selector === 'string') {
6 | if (/^ this[i] = d);
17 | this.length = doms.length;
18 | }
19 | this.selector = selector || '';
20 |
21 | } else if (selector && typeof selector === 'object') {
22 | if (selector instanceof D) {
23 | for (var i = 0; i < selector.length; i++) {
24 | this[i] = selector[i];
25 | this.length++;
26 | }
27 | } else if (selector && selector.length) {
28 | var doms = selector;
29 | doms.forEach((d, i) => this[i] = d);
30 | this.length = doms.length;
31 | } else {
32 | this[0] = selector;
33 | this.length++;
34 | }
35 | this.selector = selector;
36 | }
37 | }
38 |
39 | attr (prop, value = null) {
40 | if (!value) {
41 | return this.length ? this[0].getAttribute(prop) : '';
42 | } else {
43 | for (var i = 0; i < this.length; i++) {
44 | this[i].setAttribute(prop, value);
45 | }
46 | }
47 |
48 | }
49 |
50 | val (val) {
51 | if (val) {
52 | for (var i = 0; i < this.length; i++) {
53 | this[i].value = val;
54 | }
55 | } else {
56 | return this.length ? this[0].value : '';
57 | }
58 | }
59 |
60 | focus () {
61 | for (var i = 0; i < this.length; i++) {
62 | this[i].focus();
63 | }
64 | }
65 |
66 | html (htmlStr = null) {
67 | if (!htmlStr) {
68 | return this.length ? this[0].innerHTML : '';
69 | } else {
70 | for (var i = 0; i < this.length; i++) {
71 | this[i].innerHTML = htmlStr;
72 | }
73 | }
74 | }
75 | text (text = null) {
76 | if (!text) {
77 | return this.length ? this[0].innerText : '';
78 | } else {
79 | for (var i = 0; i < this.length; i++) {
80 | this[i].innerText = text;
81 | }
82 | }
83 | }
84 | height (height = null) {
85 | if (!height) {
86 | return this.length ? this[0].getBoundingClientRect().height : null;
87 | } else {
88 | for (var i = 0; i < this.length; i++) {
89 | this[i].style.height = height + 'px';
90 | }
91 | }
92 | }
93 |
94 | width (width = null) {
95 | if (!width) {
96 | return this.length ? this[0].getBoundingClientRect().width : null;
97 | } else {
98 | for (var i = 0; i < this.length; i++) {
99 | this[i].style.width = height + 'px';
100 | }
101 | }
102 | }
103 |
104 | find (selector) {
105 | for (var i = 0; i < this.length; i++) {
106 | var slice = Array.prototype.slice;
107 | var doms = slice.apply(this[i].querySelectorAll(selector));
108 | if (doms.length) {
109 | return new D(doms);
110 | }
111 | }
112 | return new D(null);
113 | }
114 |
115 | append (dom) {
116 | if (typeof dom === 'string') {
117 | for (var i = 0; i < this.length; i++) {
118 | this[i].insertAdjacentHTML('beforeend', dom);
119 | }
120 | } else if (dom instanceof D) {
121 | for (var i = 0; i < this.length; i++) {
122 | for (var j = 0; j < dom.length; j++) {
123 | this[i].appendChild(dom[j]);
124 | }
125 | }
126 | } else {
127 | for (var i = 0; i < this.length; i++) {
128 | this[i].appendChild(dom);
129 | }
130 | }
131 | }
132 |
133 | hide () {
134 | for (var i = 0; i < this.length; i++) {
135 | this[i].style.display = 'none';
136 | }
137 | }
138 |
139 | show () {
140 | for (var i = 0; i < this.length; i++) {
141 | this[i].style.display = 'block';
142 | }
143 | }
144 |
145 | parent () {
146 | return this.length ? new D(this[0].parentNode) : new D(null);
147 | }
148 |
149 | insertBefore (selector) {
150 | var $beforeElem = new D(selector);
151 | if ($beforeElem.length) {
152 | var beforeElem = $beforeElem[0];
153 | var parent = beforeElem.parentNode;
154 | for (var i = 0; i < this.length; i++) {
155 | parent.insertBefore(this[i], beforeElem);
156 | }
157 | }
158 | }
159 |
160 | insertAfter (selector) {
161 | var $afterElem = new D(selector);
162 | if ($afterElem.length) {
163 | var afterElem = $afterElem[0];
164 | var parent = afterElem.parentNode;
165 | for (var i = 0; i < this.length; i++) {
166 | if (parent.lastChild === afterElem) {
167 | parent.appendChild(this[i]);
168 | } else {
169 | parent.insertBefore(this[i], afterElem.nextSibling);
170 | }
171 | }
172 | }
173 | }
174 |
175 | equal ($elem) {
176 | if (!this.length) {
177 | return false;
178 | }
179 | if ($elem.nodeType === 1) {
180 | return this[0] === $elem;
181 | } else {
182 | return this[0] === $elem[0];
183 | }
184 | }
185 |
186 | remove () {
187 | for (var i = 0; i < this.length; i++) {
188 | var elem = this[i];
189 | if (elem.remove) {
190 | elem.remove();
191 | } else {
192 | var parent = elem.parentElement;
193 | parent && parent.removeChild(elem);
194 | }
195 | }
196 |
197 | }
198 |
199 | bind (event, handler) {
200 | for (var i = 0; i < this.length; i++) {
201 | this[i].addEventListener(event, function (evt) {
202 | handler.call(evt.currentTarget, evt);
203 | });
204 | }
205 | }
206 | unbind (event, handler) {
207 | for (var i = 0; i < this.length; i++) {
208 | this[i].removeEventListener(event, handler);
209 | }
210 | }
211 | addClass (className) {
212 | for (var i = 0; i < this.length; i++) {
213 | var classArr = [];
214 | var elem = this[i];
215 | if (elem.className) {
216 | classArr = elem.className.split(' ');
217 | }
218 | var classArr1 = className.split(' ');
219 | classArr.push.apply(classArr, classArr1);
220 | elem.className = classArr.join(' ');
221 | }
222 | }
223 |
224 | removeClass (className) {
225 | for (var i = 0; i < this.length; i++) {
226 | var elem = this[i];
227 | var classArr = [];
228 | if (elem.className) {
229 | classArr = elem.className.split(' ');
230 | }
231 | classArr = classArr.filter(item => {
232 | item = item.trim();
233 | if (!item || item === className) {
234 | return false;
235 | }
236 | return true;
237 | });
238 | elem.className = classArr.join(' ');
239 | }
240 | }
241 |
242 | hasClass (className) {
243 | for (var i = 0; i < this.length; i++) {
244 | var elem = this[i];
245 | var classArr = [];
246 | if (elem.className) {
247 | classArr = elem.className.split(' ');
248 | }
249 | if (classArr.indexOf(className) !== -1) {
250 | return true;
251 | }
252 | }
253 | return false;
254 | }
255 | }
256 |
257 | export default function (selector) {
258 | return new D(selector);
259 | };
--------------------------------------------------------------------------------
/src/core/handle/image-handle.js:
--------------------------------------------------------------------------------
1 | import $ from '../dom';
2 | import imageDialogTpl from '../../ui/image-dialog.html';
3 | import imageUploadTpl from '../../ui/image-upload.html';
4 | import mito from 'mito';
5 | import Request from '../../core/request';
6 | class ImageHandle {
7 | constructor (context) {
8 | this.context = context;
9 | }
10 | do () {
11 | this.type = 1;
12 | this._create();
13 | this._bindEvent();
14 | }
15 | _create () {
16 | this.$elem = $(imageDialogTpl);
17 | $('body').append(this.$elem);
18 | }
19 | _bindEvent () {
20 | var _this = this;
21 | var $uploadBtn = this.$elem.find('.upload-btn');
22 | var $inputBox = this.$elem.find('.input-box');
23 | var $confirm = this.$elem.find('.confirm');
24 |
25 | this.$elem.find('.close').bind('click', function (event) {
26 | _this._destroy();
27 | })
28 | this.$elem.find('.cancel').bind('click', function (event) {
29 | _this._destroy();
30 | })
31 |
32 | this.$elem.find('.switch-box').bind('click', function (event) {
33 |
34 | if (_this.type === 1) {
35 | $(this).text('或上传本地图片');
36 | $inputBox[0].style.display = 'flex';
37 | $uploadBtn.hide();
38 | $confirm[0].style.display = 'inline-block';
39 | _this.type = 2;
40 | } else {
41 | $inputBox.hide();
42 | $uploadBtn.show();
43 | $(this).text('或选择网络图片');
44 | $confirm.hide();
45 | _this.type = 1;
46 | }
47 | });
48 | var $linkInput = this.$elem.find('#linkInput');
49 |
50 | var $waringTxt = this.$elem.find('.waring-txt');
51 |
52 | $confirm.bind('click', function (event) {
53 | var link = $linkInput.val();
54 | if (!link.length) {
55 | $waringTxt.text('链接不能为空');
56 | } else {
57 | _this._destroy();
58 | _this._insertImage(2, [link], null);
59 | }
60 | });
61 | var fileInput = this.$elem.find('input')[0];
62 |
63 | this.$elem.find('.upload-btn').bind('click', (event) => {
64 | var fileInput = this.$elem.find('input')[0];
65 | fileInput.click();
66 | fileInput.onchange = (evt) => {
67 | fileInput.val = '';
68 | var files = evt.target.files;
69 | var i = 0;
70 | var images = [];
71 | var _this = this;
72 | function loadFile () {
73 | if (i >= files.length) {
74 | _this._destroy();
75 | _this._insertImage(1, images, files);
76 | return;
77 | }
78 |
79 | var file = files[i++];
80 | var reader = new FileReader();
81 |
82 | reader.readAsDataURL(file);
83 | reader.onload = () => {
84 | var data = reader.result;
85 | images.push(data);
86 | loadFile();
87 | }
88 | }
89 | loadFile();
90 |
91 | }
92 | });
93 |
94 | }
95 |
96 | _uploadImage (type, $imageBox, image) {
97 | var config = this.context.bestEditor.config;
98 | var $uploadErrorMsg = $imageBox.find('.upload-error-msg');
99 | var request = new Request();
100 | var _this = this;
101 | function _upload() {
102 | if (type === 1) {
103 | if (config.imageUpload) {
104 | var formData = new FormData();
105 | formData.append('file', image);
106 | request.post(config.imageUpload, formData)
107 | .then(function (data) {
108 | if (data.code == 0) {
109 | $imageBox.find('.image-upload').remove();
110 | $imageBox.append(`
`);
111 | }
112 |
113 | })
114 | .catch (function (status, msg) {
115 | $uploadErrorMsg.text('网络异常!');
116 | })
117 | }
118 | } else if (type === 2) {
119 | if (config.imageLinkUpload) {
120 | request.get(config.imageLinkUpload + '?imageUrl=' + image)
121 | .then(function (data) {
122 | if (data.code == 0) {
123 | $imageBox.find('.image-upload').remove();
124 | $imageBox.append(`
`);
125 | }
126 |
127 | })
128 | .catch (function (status, msg) {
129 | $uploadErrorMsg.text('网络异常!');
130 | })
131 | }
132 | }
133 | }
134 |
135 | _upload();
136 | //cancel upload
137 | $imageBox.find('.upload-btn-cancel').bind('click', function (event) {
138 | console.log('cancel upload!');
139 | $imageBox.remove();
140 | request.abort();
141 | })
142 |
143 | //retry upload
144 | $imageBox.find('.upload-btn-retry').bind('click', function (event) {
145 | $uploadErrorMsg.text('正在上传');
146 | _upload();
147 | })
148 | }
149 |
150 | //upload images
151 | _uploadImages (type, $imageBoxArr, images) {
152 | for (var i = 0; i < $imageBoxArr.length; i++) {
153 | var $imageBox = $imageBoxArr[i];
154 | var image;
155 | if (!images && type === 2) {
156 | image = $imageBox.find('.image-upload img')[0].src;
157 | } else {
158 | image = images[i];
159 | }
160 | this._uploadImage(type, $imageBox, image);
161 | }
162 | }
163 |
164 | //insert image tag to editor
165 | _insertImage (type, images, files) {
166 |
167 | var selectionElem = this.context.bestEditor.selection.getContainerElement();
168 | var config = this.context.bestEditor.config;
169 | if (/^p$/i.test(selectionElem.tagName)) {
170 |
171 | var curRange = this.context.bestEditor.selection.getCurrentRange();
172 |
173 | var text = selectionElem.innerText.trim();
174 | var text1 = text.substring(0, curRange.startOffset);
175 | var text2 = text.substr(curRange.startOffset);
176 | if (text1.length > 0) {
177 | selectionElem.innerText = text1;
178 | }
179 |
180 | var afterElem = selectionElem;
181 | var $imageBoxArr = [];
182 | var $imageBox;
183 | for (var image of images) {
184 | if (type === 2 && !config.imageLinkUpload) {
185 | $imageBox = $(``);
186 | $imageBox.insertAfter(afterElem);
187 | afterElem = $imageBox[0];
188 | this.context.bestEditor.selection.createRangeByElement($imageBox[0], false, true);
189 | this.context.bestEditor.selection.restore();
190 | } else {
191 | var imageUpload = mito(imageUploadTpl)({imageUrl: image});
192 | $imageBox = $(``);
193 | $imageBox.append(imageUpload);
194 | $imageBox.insertAfter(afterElem);
195 | afterElem = $imageBox[0];
196 | $imageBoxArr.push($imageBox);
197 | }
198 | }
199 | if (text.length === 0) {
200 | $(selectionElem).remove();
201 | }
202 | if (text2.length > 0) {
203 | var $p = $(`${text2}
`)
204 | $p.insertAfter($imageBox);
205 | this.context.bestEditor.selection.createRangeByElement($p[0], false);
206 | this.context.bestEditor.selection.restore();
207 | } else {
208 | var $p = $('
');
209 | $p.insertAfter($imageBox);
210 | this.context.bestEditor.selection.createRangeByElement($p[0], false);
211 | this.context.bestEditor.selection.restore();
212 | }
213 | if (type === 1 || config.imageLinkUpload) {
214 | this._uploadImages(type, $imageBoxArr, type === 1 ? files : images);
215 | }
216 | } else {
217 | // var $imageBoxArr = [];
218 | // for (var image of images) {
219 | // var imageUpload = mito(imageUploadTpl)({imageUrl: image});
220 | // var $imageBox = $(``);
221 | // $imageBox.append(imageUpload);
222 | // var range = this.context.bestEditor.selection.getCurrentRange();
223 | // range.insertNode($imageBox[0]);
224 | // //this.context.insertHTML($imageBox[0].outerHTML);
225 | // $imageBoxArr.push($imageBox);
226 | // // console.log($imageBox.parent().remove());
227 | // }
228 | // this._uploadImages(type, $imageBoxArr, type === 1 ? files : images);
229 | }
230 | console.log('insertImage')
231 | }
232 |
233 | _destroy () {
234 | this.$elem.remove();
235 | this.context.bestEditor.selection.restore();
236 | }
237 |
238 | }
239 | export default ImageHandle;
--------------------------------------------------------------------------------
/src/core/handle/link-handle.js:
--------------------------------------------------------------------------------
1 | import $ from '../dom';
2 | import linkDialogTpl from '../../ui/link-dialog.html';
3 |
4 | class LinkHandle {
5 | constructor (context) {
6 | this.context = context;
7 | }
8 | do () {
9 |
10 | this._create();
11 | this.bindEvent();
12 | }
13 | _create () {
14 | this.$elem = $(linkDialogTpl);
15 | $('body').append(this.$elem);
16 | this.selectionElem = null;
17 | }
18 | bindEvent () {
19 | var _this = this;
20 |
21 | var $confirm = this.$elem.find('.confirm');
22 |
23 | this.$elem.find('.close').bind('click', function (event) {
24 | _this._destroy();
25 | })
26 | this.$elem.find('.cancel').bind('click', function (event) {
27 | _this._destroy();
28 | })
29 |
30 |
31 | var $linkInput = this.$elem.find('#linkInput');
32 | var $linkText = this.$elem.find('#linkText');
33 | var $waringTxt = this.$elem.find('.waring-txt');
34 |
35 | var selectionElem = this.context.bestEditor.selection.getContainerElement();
36 |
37 | if (selectionElem) {
38 | if (/^a$/i.test(selectionElem.tagName)) {
39 | this.selectionElem = selectionElem;
40 | $linkText.val(selectionElem.innerText);
41 | $linkInput.val(selectionElem.href);
42 | } else {
43 | $linkText.val(this.context.bestEditor.selection.getText());
44 | }
45 | }
46 |
47 | $confirm.bind('click', function (event) {
48 |
49 | var link = $linkInput.val();
50 | var linkText = $linkText.val();
51 | if (!link.length) {
52 | $waringTxt.text('链接地址不能为空');
53 | } else if (!linkText.length) {
54 | $waringTxt.text('链接文本不能为空');
55 | } else {
56 | _this._destroy();
57 | _this._insertLink(link, linkText);
58 | }
59 | })
60 | }
61 |
62 | _insertLink (link, linkText) {
63 |
64 | if (this.selectionElem) {
65 | this.context.bestEditor.selection.createRangeByElement(this.selectionElem);
66 | this.context.bestEditor.selection.delete();
67 | }
68 | this.context.bestEditor.selection.restore();
69 | this.context.insertHTML(`${linkText}`)
70 |
71 | }
72 |
73 | _destroy () {
74 | this.$elem.remove();
75 | this.context.bestEditor.selection.restore();
76 | }
77 |
78 | }
79 | export default LinkHandle;
--------------------------------------------------------------------------------
/src/core/handle/list-handle.js:
--------------------------------------------------------------------------------
1 | import $ from '../dom';
2 | class ListHandle {
3 | constructor (context) {
4 | this.context = context;
5 | }
6 | handleUnOrderList () {
7 | this._handleList('unorder');
8 | }
9 |
10 | handleOrderList () {
11 | this._handleList('order');
12 | }
13 |
14 | _handleList (flag) {
15 | if (flag === 'unorder') {
16 | this.context.execCommand('insertUnorderedList');
17 | } else {
18 | this.context.execCommand('insertOrderedList');
19 | }
20 | this.context.bestEditor.selection.save();
21 |
22 | var bestEditor = this.context.bestEditor;
23 |
24 | //fix ul wrapper
25 | var selectionElem = bestEditor.selection.getContainerElement();
26 | console.log(selectionElem)
27 | var $selectionElem = $(selectionElem);
28 | if (/^li$/i.test(selectionElem.tagName)) {
29 | $selectionElem = $selectionElem.parent();
30 | }
31 | if (!/^ol|ul$/i.test($selectionElem[0].tagName)) {
32 | return;
33 | }
34 | var $parent = $selectionElem.parent()
35 | if ($parent.equal(bestEditor.$editor)) {
36 | return;
37 | }
38 | $selectionElem.insertAfter($parent);
39 | $parent.remove();
40 |
41 | }
42 | }
43 | export default ListHandle;
--------------------------------------------------------------------------------
/src/core/handle/paste-handle.js:
--------------------------------------------------------------------------------
1 | import imageUploadTpl from '../../ui/image-upload.html';
2 | import mito from 'mito';
3 | import $ from '../dom';
4 | import ImageHandle from './image-handle';
5 |
6 | class PasteHandle {
7 | constructor (context) {
8 | this.inlineTags = ['label', 'i', 'em', 'span', 'strike', 'u', 'a', 'input', 'font', 'br', 'strong', 'select', 'textarea', 'b'];
9 | this.context = context;
10 | this.imageHandle = new ImageHandle(context);
11 | }
12 | getPasteText (e) {
13 | var clipboardData = e.clipboardData || (e.originalEvent && e.originalEvent.clipboardData);
14 | var pasteText;
15 | if (clipboardData == null) {
16 | pasteText = window.clipboardData && window.clipboardData.getData('text');
17 | } else {
18 | pasteText = clipboardData.getData('text/plain');
19 | }
20 | return pasteText;
21 | }
22 |
23 | getPasteHTML (e, filterStyle, ignoreImg) {
24 | var clipboardData = e.clipboardData || (e.originalEvent && e.originalEvent.clipboardData);
25 | var pasteHTML, pasteText;
26 | if (clipboardData == null) {
27 | pasteText = window.clipboardData && window.clipboardData.getData('text');
28 | } else {
29 | pasteHTML = clipboardData.getData('text/html');
30 | pasteText = clipboardData.getData('text/plain')
31 | }
32 |
33 | if (!pasteHTML && pasteText) {
34 | this.contentType = 1;
35 | pasteHTML = '' + this._replaceHtmlSymbol(pasteText) + '
';
36 | return pasteHTML;
37 | }
38 | if (!pasteHTML) {
39 | return;
40 | }
41 |
42 | pasteHTML = pasteHTML.replace(/<(meta|script|link).+?>/igm, '');
43 | pasteHTML = pasteHTML.replace(//mg, '')
44 | pasteHTML = pasteHTML.replace(/\s?data-.+?=('|").+?('|")/igm, '');
45 | pasteHTML = pasteHTML.replace(/<\/?(body|html)>/igm, '');
46 |
47 |
48 | if (ignoreImg) {
49 | pasteHTML = pasteHTML.replace(//igm, '');
50 | }
51 | if (filterStyle) {
52 | pasteHTML = pasteHTML.replace(/\s?(class|style)=('|").*?('|")/igm, '');
53 | } else {
54 | pasteHTML = pasteHTML.replace(/\s?class=('|").*?('|")/igm, '');
55 | }
56 | pasteHTML = this._optimizeHTML(pasteHTML);
57 | return pasteHTML;
58 | }
59 | do (e) {
60 |
61 | var selectionElem = this.context.bestEditor.selection.getContainerElement();
62 | var text = selectionElem.innerText.trim();
63 | var html = this.getPasteHTML(e, true, false);
64 |
65 | if (this.contentType === 1) {
66 | this.context.insertHTML(html);
67 | return;
68 | }
69 | if (text.length === 0) {
70 | $(selectionElem).remove();
71 | }
72 | this.context.insertHTML(html);
73 |
74 | if (this.context.bestEditor.config.imageLinkUpload) {
75 | var $imageBoxs = this.context.bestEditor.$editor.find('.image-box');
76 | var $imageBoxsArr = [];
77 | if ($imageBoxs.elems.length > 0) {
78 | for (var imageBox of $imageBoxs.elems) {
79 | $imageBoxsArr.push($(imageBox));
80 | }
81 | }
82 | if ($imageBoxsArr.length > 0) {
83 | this.imageHandle._uploadImages(2, $imageBoxsArr);
84 | }
85 | }
86 |
87 | }
88 | _hasBlockTag (elem) {
89 | for (var i = 0; i < elem.children.length; i++) {
90 | var child = elem.children[i];
91 | var nodeName = child.nodeName.toLowerCase();
92 | if (this.inlineTags.indexOf(nodeName) === -1) {
93 | return true;
94 | }
95 | }
96 | return false;
97 | }
98 | _getElementStr (elem) {
99 | var strArr = [];
100 | for (var i = 0; i < elem.childNodes.length; i++) {
101 | var node = elem.childNodes[i];
102 | if (node.nodeType === 3) {
103 | var text = node.nodeValue.trim();
104 | if (text.length > 0) {
105 | strArr.push(text);
106 | }
107 |
108 | } else if (node.nodeType === 1) {
109 | var nodeName = node.nodeName.toLowerCase();
110 | if (this.inlineTags.indexOf(nodeName) !== -1 && !this._hasBlockTag(node)) {
111 | if (node.innerText.length > 0) {
112 | strArr.push(node.outerHTML);
113 | }
114 | }
115 | }
116 | }
117 | if (strArr.length > 0) {
118 | var nodeName = elem.nodeName.toLowerCase();
119 | if (nodeName === 'div') {
120 | nodeName = 'p';
121 | }
122 | return '<' + nodeName + '>' + strArr.join('') + '' + nodeName + '>';
123 | }
124 | return '';
125 | }
126 |
127 | _optimizeDom (elem) {
128 | var strArr = [];
129 | var str = this._getElementStr(elem);
130 | if (str.length > 0) {
131 | strArr.push(str);
132 | }
133 | for (var i = 0; i < elem.children.length; i++) {
134 | var child = elem.children[i];
135 | var nodeName = child.nodeName.toLowerCase();
136 | if (this.inlineTags.indexOf(nodeName) === -1 || this._hasBlockTag(child)) {
137 | if (nodeName === 'img') {
138 | if (!this.context.bestEditor.config.imageLinkUpload) {
139 | strArr.push(``);
140 | } else {
141 | var imageUpload = mito(imageUploadTpl)({imageUrl: child.src});
142 | strArr.push(`${imageUpload}
`);
143 | }
144 | } else {
145 | str = this._optimizeDom(child);
146 | if (str.length > 0) {
147 | strArr.push(str);
148 | }
149 | }
150 | }
151 | }
152 | return strArr.join('');
153 | }
154 |
155 |
156 | _optimizeHTML (html) {
157 | var divElem = document.createElement('div');
158 | divElem.innerHTML = html;
159 | return this._optimizeDom(divElem);
160 | }
161 |
162 | _replaceHtmlSymbol (html) {
163 | return html.replace(//gm, '>')
165 | .replace(/"/gm, '"')
166 | .replace(/(\r\n|\r|\n)/g, '
');
167 | }
168 | }
169 | export default PasteHandle;
--------------------------------------------------------------------------------
/src/core/handle/video-handle.js:
--------------------------------------------------------------------------------
1 | import $ from '../dom';
2 | import videoDialogTpl from '../../ui/video-dialog.html';
3 |
4 | class ImageHandle {
5 | constructor (context) {
6 | this.context = context;
7 | }
8 | do () {
9 | this.type = 1;
10 | this._create();
11 | this.bindEvent();
12 | }
13 | _create () {
14 | this.$elem = $(videoDialogTpl);
15 | $('body').append(this.$elem);
16 | }
17 | bindEvent () {
18 | var _this = this;
19 | var $uploadBtn = this.$elem.find('.upload-btn');
20 | var $inputBox = this.$elem.find('.input-box');
21 | var $confirm = this.$elem.find('.confirm');
22 |
23 | this.$elem.find('.close').bind('click', function (event) {
24 | _this._destroy();
25 | })
26 | this.$elem.find('.cancel').bind('click', function (event) {
27 | _this._destroy();
28 | })
29 |
30 |
31 | var $linkInput = this.$elem.find('#linkInput');
32 |
33 | var $waringTxt = this.$elem.find('.waring-txt');
34 |
35 | $confirm.bind('click', function (event) {
36 | var link = $linkInput.val();
37 | if (!link.length) {
38 | $waringTxt.text('视频链接不能为空');
39 | } else {
40 | _this._destroy();
41 | _this._insertVideo(link);
42 | }
43 | })
44 |
45 | }
46 |
47 | _insertVideo (link) {
48 | console.log('_insertVideo');
49 | this.context.execCommand('insertHTML', link);
50 | }
51 |
52 | _destroy () {
53 | this.$elem.remove();
54 | this.context.bestEditor.selection.restore();
55 | }
56 |
57 | }
58 | export default ImageHandle;
--------------------------------------------------------------------------------
/src/core/handler.js:
--------------------------------------------------------------------------------
1 | import $ from '../core/dom';
2 | import ListHandle from './handle/list-handle';
3 | import ImageHandle from './handle/image-handle';
4 | import LinkHandle from './handle/link-handle';
5 | import VideoHandle from './handle/video-handle';
6 | import PasteHandle from './handle/paste-handle';
7 |
8 | class Handler {
9 | constructor (bestEditor) {
10 | this.bestEditor = bestEditor;
11 | var listHandle = new ListHandle(this);
12 | var imageHandle = new ImageHandle(this);
13 | var linkHandle = new LinkHandle(this);
14 | var videoHandle = new VideoHandle(this);
15 | var pasteHandle = new PasteHandle(this);
16 | this.handleMap = {
17 | 'insertUnorderedList': listHandle.handleUnOrderList.bind(listHandle),
18 | 'insertOrderedList': listHandle.handleOrderList.bind(listHandle),
19 | 'image': imageHandle.do.bind(imageHandle),
20 | 'link': linkHandle.do.bind(linkHandle),
21 | 'video': videoHandle.do.bind(videoHandle),
22 | 'paste': pasteHandle.do.bind(pasteHandle),
23 | 'fullscreen': this.handleFullScreen.bind(this),
24 | }
25 |
26 | }
27 |
28 | addHandle (cmd, handle) {
29 | this.handleMap[cmd] = handle;
30 | }
31 |
32 | //handle full screen
33 | handleFullScreen (event) {
34 | var $elem = $(event.currentTarget);
35 | var $i = $elem.find('i');
36 | if (this.bestEditor.$container.hasClass('full-screen')) {
37 | this.bestEditor.$container.removeClass('full-screen');
38 | $i.addClass('icon-full-screen');
39 | $elem.attr('title', '全屏');
40 | $i.removeClass('icon-full-screen-exit');
41 | } else {
42 | this.bestEditor.$container.addClass('full-screen');
43 | $i.removeClass('icon-full-screen');
44 | $i.addClass('icon-full-screen-exit');
45 | $elem.attr('title', '退出全屏');
46 | }
47 | this.bestEditor.$editor[0].focus();
48 | this.bestEditor.selection.restore();
49 | }
50 |
51 | getHandle (cmd) {
52 | return this.handleMap[cmd];
53 | }
54 |
55 | execCommand (cmd, value = null) {
56 | if (value) {
57 | document.execCommand(cmd, false, value);
58 | } else {
59 | document.execCommand(cmd, false, null);
60 | }
61 | }
62 |
63 | queryCommandSupported (name) {
64 | return document.queryCommandSupported(name)
65 | }
66 |
67 | insertHTML (html) {
68 | var sel, range;
69 | if (window.getSelection) {
70 | // IE9 and non-IE
71 | sel = window.getSelection();
72 | if (sel.getRangeAt && sel.rangeCount) {
73 | range = sel.getRangeAt(0);
74 | range.deleteContents();
75 |
76 | // Range.createContextualFragment() would be useful here but is
77 | // only relatively recently standardized and is not supported in
78 | // some browsers (IE9, for one)
79 | var el = document.createElement('div');
80 | el.innerHTML = html;
81 | var frag = document.createDocumentFragment(), node, lastNode;
82 | while ( (node = el.firstChild) ) {
83 | lastNode = frag.appendChild(node);
84 | }
85 | range.insertNode(frag);
86 | // Preserve the selection
87 | if (lastNode) {
88 | range = range.cloneRange();
89 | range.setStartAfter(lastNode);
90 | range.collapse(true);
91 | sel.removeAllRanges();
92 | sel.addRange(range);
93 | }
94 | }
95 | } else if (document.selection && document.selection.type != 'Control') {
96 | // IE < 9
97 | document.selection.createRange().pasteHTML(html);
98 | }
99 | }
100 | }
101 | export default Handler;
--------------------------------------------------------------------------------
/src/core/request.js:
--------------------------------------------------------------------------------
1 | class Request {
2 |
3 | constructor () {
4 | this.xmlHttp = null;
5 | }
6 |
7 | _getXMLHttpRequest () {
8 | return new XMLHttpRequest();
9 | }
10 |
11 | get (url) {
12 | return new Promise((resolve, reject) => {
13 | var xmlHttp = this._getXMLHttpRequest();
14 | this.xmlHttp = xmlHttp;
15 | xmlHttp.open('get', url, true);
16 | xmlHttp.send();
17 | xmlHttp.onreadystatechange = function () {
18 | if (xmlHttp.readyState === 4) {
19 | if (xmlHttp.status === 200) {
20 | resolve(JSON.parse(xmlHttp.responseText));
21 | } else {
22 | reject(xmlHttp.status, xmlHttp.statusText);
23 | }
24 | }
25 | }
26 | });
27 | }
28 |
29 | post (url, data) {
30 | return new Promise((resolve, reject) => {
31 | var xmlHttp = this._getXMLHttpRequest();
32 | this.xmlHttp = xmlHttp;
33 | xmlHttp.open('post', url, true);
34 | xmlHttp.send(data);
35 | xmlHttp.onreadystatechange = function () {
36 | if (xmlHttp.readyState === 4) {
37 | if (xmlHttp.status === 200) {
38 | resolve(JSON.parse(xmlHttp.responseText));
39 | } else {
40 | reject(xmlHttp.status, xmlHttp.statusText);
41 | }
42 | }
43 | }
44 | });
45 | }
46 |
47 | abort () {
48 | if (this.xmlHttp) {
49 | this.xmlHttp.abort();
50 | }
51 | }
52 | }
53 | export default Request;
--------------------------------------------------------------------------------
/src/core/selection.js:
--------------------------------------------------------------------------------
1 | class Selection {
2 | constructor () {
3 | this._curRange = null;
4 | this._context = window.getSelection();
5 | console.log(this._context)
6 | }
7 |
8 | save (range) {
9 |
10 | if (range) {
11 | this._curRange = range;
12 | return;
13 | }
14 |
15 | var selection = this._context;
16 | if (selection.rangeCount === 0) {
17 | return;
18 | }
19 |
20 | range = selection.getRangeAt(0);
21 | this._curRange = range;
22 | }
23 |
24 | getCurrentRange () {
25 | return this._curRange;
26 | }
27 |
28 | restore () {
29 | var selection = this._context;
30 | selection.removeAllRanges();
31 | selection.addRange(this._curRange);
32 | }
33 |
34 | getText () {
35 | var range = this._curRange;
36 | if (range) {
37 | return this._curRange.toString();
38 | } else {
39 | return '';
40 | }
41 | }
42 |
43 | getContainerElement (range) {
44 | range = range || this._curRange;
45 | if (range) {
46 | var elem = range.commonAncestorContainer;
47 | return elem.nodeType === 1 ? elem : elem.parentNode;
48 | }
49 | return null;
50 | }
51 | getStartElement (range) {
52 | range = range || this._curRange;
53 | if (range) {
54 | var elem = range.startContainer;
55 | return elem.nodeType === 1 ? elem : elem.parentNode;
56 | }
57 | return null;
58 | }
59 | getEndElement (range) {
60 | range = range || this._curRange;
61 | if (range) {
62 | var elem = range.endContainer;
63 | return elem.nodeType === 1 ? elem : elem.parentNode;
64 | }
65 | return null;
66 | }
67 |
68 | createRangeByElement (elem, toStart = null, isContent = false) {
69 | var range = document.createRange();
70 | if (isContent) {
71 | range.selectNodeContents(elem);
72 | } else {
73 | range.selectNode(elem);
74 | }
75 | if (typeof toStart === 'boolean') {
76 | range.collapse(toStart);
77 | }
78 | this.save(range);
79 | }
80 |
81 | delete () {
82 | var range = this._curRange;
83 | if (range) {
84 | range.deleteContents();
85 | this.save();
86 | }
87 | }
88 |
89 | selectRange (range) {
90 | this._context.removeAllRanges();
91 | this._context.addRange(range);
92 | }
93 |
94 | }
95 | export default Selection;
--------------------------------------------------------------------------------
/src/core/toolbar.js:
--------------------------------------------------------------------------------
1 | import toolbarTpl from '../ui/toolbar.html';
2 | import $ from '../core/dom';
3 | import mito from 'mito';
4 | const DEFAULT_TOOLS = {
5 | bold: {
6 | cmd: 'bold',
7 | title: '粗体',
8 | icon: ''
9 | },
10 | italic: {
11 | cmd: 'italic',
12 | title: '斜体',
13 | icon: ''
14 | },
15 | underline: {
16 | cmd: 'underline',
17 | title: '下划线',
18 | icon: ''
19 | },
20 | strikethrough: {
21 | cmd: 'strikethrough',
22 | title: '删除线',
23 | icon: ''
24 | },
25 |
26 | link: {
27 | cmd: 'link',
28 | title: '插入链接',
29 | icon: ''
30 | },
31 | image: {
32 | cmd: 'image',
33 | title: '插入图片',
34 | icon: ''
35 | },
36 | video: {
37 | cmd: 'video',
38 | title: '插入视频',
39 | icon: ''
40 | },
41 | unorderlist: {
42 | cmd: 'insertUnorderedList',
43 | title: '无序列表',
44 | icon: ''
45 | },
46 | orderlist: {
47 | cmd: 'insertOrderedList',
48 | title: '有序列表',
49 | icon: ''
50 | },
51 | h1: {
52 | cmd: 'formatBlock',
53 | value: '',
54 | title: '标题1',
55 | icon: 'H1'
56 | },
57 | h2: {
58 | cmd: 'formatBlock',
59 | value: '',
60 | title: '标题2',
61 | icon: 'H2'
62 | },
63 | h3: {
64 | cmd: 'formatBlock',
65 | value: '',
66 | title: '标题3',
67 | icon: 'H3'
68 | },
69 | h4: {
70 | cmd: 'formatBlock',
71 | value: '',
72 | title: '标题4',
73 | icon: 'H4'
74 | },
75 | alignLeft: {
76 | cmd: 'justifyLeft',
77 | title: '左对齐',
78 | icon: ''
79 | },
80 | alignCenter: {
81 | cmd: 'justifyCenter',
82 | title: '居中对齐',
83 | icon: ''
84 | },
85 | alignRight: {
86 | cmd: 'justifyRight',
87 | title: '右对齐',
88 | icon: ''
89 | },
90 | undo: {
91 | cmd: 'undo',
92 | title: '撤销',
93 | icon: ''
94 | },
95 | redo: {
96 | cmd: 'redo',
97 | title: '重做',
98 | icon: ''
99 | },
100 | full: {
101 | cmd: 'fullscreen',
102 | title: '全屏',
103 | icon: ''
104 | }
105 | }
106 | class Toolbar {
107 | constructor (tools = null) {
108 | var toolbarStr = null;
109 | if (tools) {
110 | if (typeof tools === 'string') {
111 | toolbarStr = tools;
112 | } else if (tools instanceof Array) {
113 | var customTools = {};
114 | for (var tool of tools) {
115 | if (typeof tool === 'string') {
116 | customTools[tool] = DEFAULT_TOOLS[tool];
117 | } else if (typeof tool === 'object') {
118 | for (var k in tool) {
119 | customTools[tool] = tool[k];
120 | }
121 | }
122 | }
123 | toolbarStr = mito(toolbarTpl)({tools: customTools});
124 | } else if (typeof tools === 'object') {
125 | toolbarStr = mito(toolbarTpl)({tools: tools});
126 | }
127 | } else {
128 | toolbarStr = mito(toolbarTpl)({tools: DEFAULT_TOOLS});
129 | }
130 | this.$elem = $(toolbarStr);
131 | }
132 | }
133 | export default Toolbar;
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import './scss/main.scss';
2 | import 'babel-polyfill';
3 | import BestEditor from './core/best-editor';
4 | import './assets/iconfont.css';
5 | module.exports = BestEditor;
--------------------------------------------------------------------------------
/src/scss/main.scss:
--------------------------------------------------------------------------------
1 | .best-editor-container {
2 | display: flex;
3 | flex-direction: column;
4 | &.full-screen {
5 | position: fixed;
6 | z-index: 9999;
7 | top: 0;
8 | left: 0;
9 | right: 0;
10 | bottom: 0;
11 | width: 100% !important;
12 | height: 100% !important;
13 | background-color: #d9d9d9;
14 | .best-editor {
15 | width: 60%;
16 | margin: 0 auto;
17 | box-shadow: 0 0 20px rgba(0, 0, 0, .1);
18 | margin-top: 35px;
19 | margin-bottom: 20px;
20 | }
21 | }
22 | .best-editor-toolbar {
23 | background-color: #d9d9d9;
24 | border-bottom: 1px solid #ccc;
25 | user-select: none;
26 | box-sizing: border-box;
27 | ul {
28 | zoom:1;
29 | list-style: none;
30 | word-break: break-all;
31 | li {
32 | list-style: none;
33 | float: left;
34 | a {
35 | height: 39px;
36 | line-height: 39px;
37 | color: #595959;
38 | padding: 0 14px;
39 | display: inline-block;
40 | font-size: 16px;
41 | font-weight: bold;
42 | cursor: pointer;
43 | &:hover {
44 | color:#f2f2f2;
45 | background-color:#595959
46 | }
47 | }
48 | }
49 | &:after{
50 | content: ".";
51 | display: block;
52 | height: 0;
53 | clear: both;
54 | visibility: hidden;
55 | }
56 | }
57 | }
58 | .best-editor {
59 | flex: 1;
60 | outline: none;
61 | padding: 30px;
62 | box-sizing: border-box;
63 | padding-top: 15px;
64 | overflow-y: auto;
65 | background: #fff;
66 | p {
67 | margin: 15px 0;
68 | word-break: break-word;
69 | }
70 | h1, h2, h3, h4, h5, h6 {
71 | margin: 15px 0;
72 | }
73 | a {
74 | text-decoration: none;
75 | color: #3194d0;
76 | }
77 | blockquote {
78 | padding: 20px;
79 | background-color: #f2f2f2;
80 | border-left: 6px solid #b3b3b3;
81 | word-break: break-word;
82 | font-size: 16px;
83 | font-weight: 400;
84 | line-height: 30px;
85 | margin: 0 0 20px;
86 | }
87 | iframe {
88 | display: block;
89 | margin: 0 auto;
90 | }
91 | ul, ol {
92 | list-style-position: inside;
93 | margin: 15px 0;
94 | }
95 |
96 | .image-box {
97 | text-align: center;
98 | font-size: 0;
99 | margin: 15px 0;
100 | > img {
101 | max-width: 100%;
102 | width: auto;
103 | height: auto;
104 | vertical-align: middle;
105 | border: 0;
106 | }
107 | .image-upload {
108 | width: 443px;
109 | padding: 5px 16px 5px 5px;
110 | margin: 0 auto;
111 | border: 1px solid #d9d9d9;
112 | overflow: hidden;
113 | font-size: 14px;
114 | -webkit-box-sizing: border-box;
115 | box-sizing: border-box;
116 | .preview-image {
117 | display: block;
118 | float: left;
119 | width: 90px;
120 | height: 90px;
121 | object-fit: cover;
122 | margin-right: 20px;
123 | }
124 | .status-bar {
125 | display: block;
126 | float: right;
127 | width: 305px;
128 | .upload-error-msg {
129 | color: #f50;
130 | }
131 | .status-area {
132 | a {
133 | float: right;
134 | margin-left: 20px;
135 | cursor: pointer;
136 | color: #999;
137 | }
138 | .upload-btn-retry {
139 | display: none;
140 | }
141 | }
142 | .uploading-icon {
143 | height: 3px;
144 | width: 305px;
145 | min-height: 3px;
146 | display: block;
147 | margin: 25px 0 20px;
148 | background: url(data:image/gif;base64,R0lGODlhMgEDAMQfACV79DaH+avH8bDK9rDJ7ajI8qvI7q3K8a/M92Oc7ih776/K9KrL9KbH8KbK8jV/7i9+7xhw8bjT+ICw8pLF+sHW9a3H8ajH8azJ8LPL9q3L9rPL7zB/8SV89zSH/f///yH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2QTdFQzI3OUUyMUQxMUU2OEVGMUVFRTY0NzY1NUJEMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2QTdFQzI3QUUyMUQxMUU2OEVGMUVFRTY0NzY1NUJEMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZBN0VDMjc3RTIxRDExRTY4RUYxRUVFNjQ3NjU1QkQzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjZBN0VDMjc4RTIxRDExRTY4RUYxRUVFNjQ3NjU1QkQzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwv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) 50% no-repeat;
149 | }
150 | }
151 |
152 | }
153 | }
154 | }
155 | }
156 | .best-editor-dialog {
157 | position: fixed;
158 | top: 0;
159 | left: 0;
160 | right: 0;
161 | bottom: 0;
162 | z-index: 9999999999999;
163 | background-color: hsla(0, 0%, 100%, .7);
164 | .wrap {
165 | position: absolute;
166 | top: 50%;
167 | left: 50%;
168 | transform: translate(-50%, -50%);
169 | width: 412px;
170 | background-color: #fff;
171 | border-radius: 6px;
172 | -webkit-box-shadow: 0 2px 8px rgba(0,0,0,.2);
173 | box-shadow: 0 2px 8px rgba(0,0,0,.2);
174 | padding: 16px;
175 | box-sizing: border-box;
176 | .head {
177 | .close {
178 | text-align: right;
179 | a {
180 | cursor: pointer;
181 | font-size: 24px;
182 | color: #999;
183 | transition: color .3s ease;
184 | &:hover {
185 | color: #4d4d4d;
186 | }
187 | }
188 | }
189 | h3 {
190 | font-size: 22px;
191 | padding-bottom: 26px;
192 | text-align: center;
193 | }
194 | }
195 |
196 | .body {
197 | padding: 15px 30px 30px;
198 | .upload-btn {
199 | position: relative;
200 | height: 42px;
201 | margin-bottom: 20px;
202 | background: #555;
203 | overflow: hidden;
204 | text-align: center;
205 | line-height: 42px;
206 | color: #fff;
207 | font-size: 14px;
208 | cursor: pointer;
209 | input {
210 | position: absolute;
211 | top: -12000px;
212 | right: 0;
213 | left: 0;
214 | }
215 | }
216 | .input-box {
217 | display: flex;
218 | margin-bottom: 20px;
219 | > div {
220 | height: 42px;
221 | border: 1px solid #ccc;
222 | box-sizing: border-box;
223 | line-height: 42px;
224 | }
225 | .icon-box {
226 | text-align: center;
227 | background-color: #eee;
228 | width: 38px;
229 | color: #595959;
230 | }
231 | .input {
232 | border-left: 0;
233 | flex: 1;
234 | input {
235 | border: 0;
236 | outline: none;
237 | width: 99%;
238 | border-left: 0;
239 | box-sizing: border-box;
240 | padding: 0 10px;
241 | color: #595959;
242 | }
243 | }
244 | }
245 | .switch-box {
246 |
247 | color: #888;
248 | cursor: pointer;
249 | font-size: 14px;
250 | padding-bottom: 10px;
251 | text-align: center;
252 | }
253 | .waring-txt {
254 | height: 20px;
255 | line-height: 20px;
256 | color: #bc6351;
257 | font-size: 14px;
258 | margin-bottom: 5px;
259 | }
260 | .btn-box {
261 | font-size: 14px;
262 | text-align: right;
263 | height: 30px;
264 | line-height: 20px;
265 | user-select: none;
266 | color: #595959;
267 | > span {
268 | display: inline-block;
269 | transition: color .3s ease;
270 | cursor: pointer;
271 |
272 | padding: 4px 12px;
273 | font-size: 14px;
274 | font-weight: 500;
275 | }
276 | .cancel {
277 | &:hover {
278 | color: #000;
279 | }
280 | }
281 | .confirm {
282 | color: #42c02e;
283 | background-color: #fff;
284 | border: 1px solid #42c02e;
285 | border-radius: 15px;
286 | margin-left: 15px;
287 | }
288 |
289 | }
290 | }
291 |
292 |
293 | }
294 | }
--------------------------------------------------------------------------------
/src/ui/image-dialog.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
点击上传(可多张)
11 |
15 |
或选择网络图片
16 |
17 |
18 | 取 消
19 | 确 认
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/ui/image-upload.html:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 |
6 |
正在上传...
7 |
取消
8 |
重新上传
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/ui/link-dialog.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
18 |
19 |
20 | 取 消
21 | 确 认
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/ui/toolbar.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/ui/video-dialog.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
16 | 取 消
17 | 确 认
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4 | module.exports = (env, argv) => {
5 | var DEV = argv.mode === 'development';
6 | var config = {
7 | entry: './src/main.js',
8 | devtool: DEV ? 'inline-source-map' : '',
9 | output: {
10 | filename: DEV ? 'best-editor-dev.js' : 'best-editor.js',
11 | path: path.resolve(__dirname, 'dist'),
12 | library: 'BestEditor',
13 | libraryTarget: 'umd',
14 | umdNamedDefine: true
15 | },
16 | module: {
17 | rules: [{
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel-loader'
21 | }, {
22 | test: /\.css$/,
23 | use: [MiniCssExtractPlugin.loader, 'css-loader']
24 | }, {
25 | test: /\.scss$/,
26 | use: [{
27 | loader: MiniCssExtractPlugin.loader
28 | }, {
29 | loader: 'css-loader'
30 | }, {
31 | loader: 'sass-loader'
32 | }]
33 | }, {
34 | test: /\.html$/,
35 | use: [{
36 | loader: 'html-loader',
37 | options: {
38 | minimize: true,
39 | removeComments: false,
40 | collapseWhitespace: false
41 | }
42 | }],
43 | }, {
44 | test: /\.(ttf|eot|woff|woff2)$/,
45 | use: {
46 | loader: 'file-loader',
47 | options: {
48 | name: 'fonts/[name].[ext]',
49 | },
50 | }
51 | }]
52 | },
53 | plugins: [
54 | new MiniCssExtractPlugin({
55 | filename: DEV ? 'best-editor.css' : 'best-editor.min.css'
56 | })
57 | ]
58 | };
59 | return config;
60 | };
61 |
62 |
--------------------------------------------------------------------------------