@opentiny/fluent-editor 4.0.0-alpha.2 → 4.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/fluent-editor.es.js +2 -0
- package/es/fluent-editor.es.js.map +1 -1
- package/es/modules/ai/index.es.js +238 -0
- package/es/modules/ai/index.es.js.map +1 -0
- package/es/modules/emoji.es.js.map +1 -1
- package/es/themes/snow.es.js +2 -0
- package/es/themes/snow.es.js.map +1 -1
- package/es/ui/icons.config.es.js +15 -0
- package/es/ui/icons.config.es.js.map +1 -1
- package/es/ui/icons.es.js +2 -1
- package/es/ui/icons.es.js.map +1 -1
- package/lib/fluent-editor.cjs.js +4 -2
- package/lib/fluent-editor.cjs.js.map +1 -1
- package/lib/modules/ai/index.cjs.js +238 -0
- package/lib/modules/ai/index.cjs.js.map +1 -0
- package/lib/modules/emoji.cjs.js.map +1 -1
- package/lib/themes/snow.cjs.js +2 -0
- package/lib/themes/snow.cjs.js.map +1 -1
- package/lib/ui/icons.cjs.js +1 -0
- package/lib/ui/icons.cjs.js.map +1 -1
- package/lib/ui/icons.config.cjs.js +15 -0
- package/lib/ui/icons.config.cjs.js.map +1 -1
- package/package.json +1 -1
- package/style.css +90 -0
- package/types/modules/ai/index.d.ts +39 -0
- package/types/ui/icons.config.d.ts +1 -0
package/es/fluent-editor.es.js
CHANGED
|
@@ -3,6 +3,7 @@ import { EN_US } from "./config/i18n/en-us.es.js";
|
|
|
3
3
|
import { ZH_CN } from "./config/i18n/zh-cn.es.js";
|
|
4
4
|
import FluentEditor from "./core/fluent-editor.es.js";
|
|
5
5
|
import "./formats/index.es.js";
|
|
6
|
+
import { AI } from "./modules/ai/index.es.js";
|
|
6
7
|
import Counter from "./modules/counter.es.js";
|
|
7
8
|
import { CustomClipboard } from "./modules/custom-clipboard.es.js";
|
|
8
9
|
import "./modules/custom-image/index.es.js";
|
|
@@ -63,6 +64,7 @@ FluentEditor.register(
|
|
|
63
64
|
"modules/i18n": I18N,
|
|
64
65
|
"modules/image": BlotFormatter,
|
|
65
66
|
"modules/mathlive": MathliveModule,
|
|
67
|
+
"modules/ai": AI,
|
|
66
68
|
"modules/mention": Mention,
|
|
67
69
|
"modules/syntax": CustomSyntax,
|
|
68
70
|
"modules/toolbar": BetterToolbar,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluent-editor.es.js","sources":["../../src/fluent-editor.ts"],"sourcesContent":["import { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'\r\nimport { EN_US } from './config/i18n/en-us'\r\nimport { ZH_CN } from './config/i18n/zh-cn'\r\nimport FluentEditor from './core/fluent-editor'\r\nimport { EmojiBlot, SoftBreak, StrikeBlot, Video } from './formats'\r\nimport Counter from './modules/counter' // 字符统计\r\nimport { CustomClipboard } from './modules/custom-clipboard' // 粘贴板\r\nimport { BlotFormatter } from './modules/custom-image' // 图片\r\nimport { FileUploader } from './modules/custom-uploader' // 上传\r\nimport { DividerBlot } from './modules/divider' // 分割线\r\nimport { EmojiModule } from './modules/emoji'\r\nimport { FileModule } from './modules/file' // 文件\r\nimport I18N from './modules/i18n'\r\nimport { LinkBlot } from './modules/link' // 超链接\r\nimport { MathliveModule } from './modules/mathlive' // latex公式\r\nimport { Mention } from './modules/mention' // @提醒\r\nimport { ShortCutKey } from './modules/shortcut-key'\r\nimport Syntax from './modules/syntax' // 代码块高亮\r\nimport { BetterToolbar } from './modules/toolbar' // 工具栏\r\nimport { ColorPicker, Picker } from './modules/toolbar/better-picker'\r\nimport SnowTheme from './themes/snow'\r\nimport Icons from './ui/icons'\r\n\r\nI18N.register(\r\n {\r\n 'en-US': EN_US,\r\n 'zh-CN': ZH_CN,\r\n },\r\n true,\r\n)\r\nFluentEditor.register(\r\n {\r\n 'attributors/style/font': FontStyle,\r\n 'attributors/style/size': SizeStyle,\r\n 'attributors/style/line-height': LineHeightStyle,\r\n\r\n 'formats/font': FontStyle,\r\n 'formats/line-height': LineHeightStyle,\r\n 'formats/size': SizeStyle,\r\n 'formats/emoji': EmojiBlot,\r\n 'formats/softBreak': SoftBreak,\r\n 'formats/strike': StrikeBlot,\r\n 'formats/text-indent': TextIndentStyle,\r\n 'formats/video': Video,\r\n 'formats/divider': DividerBlot,\r\n 'formats/link': LinkBlot,\r\n\r\n 'modules/clipboard': CustomClipboard,\r\n 'modules/counter': Counter,\r\n 'modules/emoji': EmojiModule,\r\n 'modules/file': FileModule,\r\n 'modules/i18n': I18N,\r\n 'modules/image': BlotFormatter,\r\n 'modules/mathlive': MathliveModule,\r\n 'modules/mention': Mention,\r\n 'modules/syntax': Syntax,\r\n 'modules/toolbar': BetterToolbar,\r\n 'modules/uploader': FileUploader,\r\n 'modules/shortcut-key': ShortCutKey,\r\n\r\n 'themes/snow': SnowTheme,\r\n\r\n 'ui/icons': Icons,\r\n 'ui/picker': Picker,\r\n 'ui/color-picker': ColorPicker,\r\n },\r\n true, // 覆盖内部模块\r\n)\r\n\r\nexport default FluentEditor\r\n"],"names":["Syntax"],"mappings":"
|
|
1
|
+
{"version":3,"file":"fluent-editor.es.js","sources":["../../src/fluent-editor.ts"],"sourcesContent":["import { FontStyle, LineHeightStyle, SizeStyle, TextIndentStyle } from './attributors'\r\nimport { EN_US } from './config/i18n/en-us'\r\nimport { ZH_CN } from './config/i18n/zh-cn'\r\nimport FluentEditor from './core/fluent-editor'\r\nimport { EmojiBlot, SoftBreak, StrikeBlot, Video } from './formats'\r\nimport { AI } from './modules/ai' // AI\r\nimport Counter from './modules/counter' // 字符统计\r\nimport { CustomClipboard } from './modules/custom-clipboard' // 粘贴板\r\nimport { BlotFormatter } from './modules/custom-image' // 图片\r\nimport { FileUploader } from './modules/custom-uploader' // 上传\r\nimport { DividerBlot } from './modules/divider' // 分割线\r\nimport { EmojiModule } from './modules/emoji'\r\nimport { FileModule } from './modules/file' // 文件\r\nimport I18N from './modules/i18n'\r\nimport { LinkBlot } from './modules/link' // 超链接\r\nimport { MathliveModule } from './modules/mathlive' // latex公式\r\nimport { Mention } from './modules/mention' // @提醒\r\nimport { ShortCutKey } from './modules/shortcut-key'\r\nimport Syntax from './modules/syntax' // 代码块高亮\r\nimport { BetterToolbar } from './modules/toolbar' // 工具栏\r\nimport { ColorPicker, Picker } from './modules/toolbar/better-picker'\r\nimport SnowTheme from './themes/snow'\r\nimport Icons from './ui/icons'\r\n\r\nI18N.register(\r\n {\r\n 'en-US': EN_US,\r\n 'zh-CN': ZH_CN,\r\n },\r\n true,\r\n)\r\nFluentEditor.register(\r\n {\r\n 'attributors/style/font': FontStyle,\r\n 'attributors/style/size': SizeStyle,\r\n 'attributors/style/line-height': LineHeightStyle,\r\n\r\n 'formats/font': FontStyle,\r\n 'formats/line-height': LineHeightStyle,\r\n 'formats/size': SizeStyle,\r\n 'formats/emoji': EmojiBlot,\r\n 'formats/softBreak': SoftBreak,\r\n 'formats/strike': StrikeBlot,\r\n 'formats/text-indent': TextIndentStyle,\r\n 'formats/video': Video,\r\n 'formats/divider': DividerBlot,\r\n 'formats/link': LinkBlot,\r\n\r\n 'modules/clipboard': CustomClipboard,\r\n 'modules/counter': Counter,\r\n 'modules/emoji': EmojiModule,\r\n 'modules/file': FileModule,\r\n 'modules/i18n': I18N,\r\n 'modules/image': BlotFormatter,\r\n 'modules/mathlive': MathliveModule,\r\n 'modules/ai': AI,\r\n 'modules/mention': Mention,\r\n 'modules/syntax': Syntax,\r\n 'modules/toolbar': BetterToolbar,\r\n 'modules/uploader': FileUploader,\r\n 'modules/shortcut-key': ShortCutKey,\r\n\r\n 'themes/snow': SnowTheme,\r\n\r\n 'ui/icons': Icons,\r\n 'ui/picker': Picker,\r\n 'ui/color-picker': ColorPicker,\r\n },\r\n true, // 覆盖内部模块\r\n)\r\n\r\nexport default FluentEditor\r\n"],"names":["Syntax"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,KAAK;AAAA,EACH;AAAA,IACE,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAAA,EACA;AACF;AACA,aAAa;AAAA,EACX;AAAA,IACE,0BAA0B;AAAA,IAC1B,0BAA0B;AAAA,IAC1B,iCAAiC;AAAA,IAEjC,gBAAgB;AAAA,IAChB,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,uBAAuB;AAAA,IACvB,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAEhB,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,kBAAkBA;AAAAA,IAClB,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IAExB,eAAe;AAAA,IAEf,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,mBAAmB;AAAA,EACrB;AAAA,EACA;AAAA;AACF;"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { AI_ICON } from "../../ui/icons.config.es.js";
|
|
5
|
+
class AI {
|
|
6
|
+
constructor(quill, options) {
|
|
7
|
+
__publicField(this, "toolbar");
|
|
8
|
+
__publicField(this, "host");
|
|
9
|
+
__publicField(this, "apiKey");
|
|
10
|
+
__publicField(this, "model");
|
|
11
|
+
__publicField(this, "message");
|
|
12
|
+
__publicField(this, "isBreak", false);
|
|
13
|
+
// 打断标记
|
|
14
|
+
__publicField(this, "inputValue", "");
|
|
15
|
+
// 存储输入框的值
|
|
16
|
+
__publicField(this, "SEND", "发送");
|
|
17
|
+
// 发送按钮文字
|
|
18
|
+
__publicField(this, "BREAK", "停止");
|
|
19
|
+
// 取消按钮文字
|
|
20
|
+
__publicField(this, "DONE", "完成");
|
|
21
|
+
__publicField(this, "REGENERATE", "重新生成");
|
|
22
|
+
__publicField(this, "CLOSE", "关闭");
|
|
23
|
+
__publicField(this, "dialogContainerEl", null);
|
|
24
|
+
__publicField(this, "wrapContainerEl", null);
|
|
25
|
+
__publicField(this, "aiPreTextEl", null);
|
|
26
|
+
__publicField(this, "inputContainerEl", null);
|
|
27
|
+
__publicField(this, "inputEl", null);
|
|
28
|
+
__publicField(this, "sendButtonEl", null);
|
|
29
|
+
__publicField(this, "resultPopupEl", null);
|
|
30
|
+
__publicField(this, "actionMenuEl", null);
|
|
31
|
+
this.quill = quill;
|
|
32
|
+
this.options = options;
|
|
33
|
+
this.quill = quill;
|
|
34
|
+
this.toolbar = quill.getModule("toolbar");
|
|
35
|
+
if (typeof this.toolbar !== "undefined") {
|
|
36
|
+
this.toolbar.addHandler("ai", this.showAIInput.bind(this));
|
|
37
|
+
}
|
|
38
|
+
this.host = options.host;
|
|
39
|
+
this.apiKey = options.apiKey;
|
|
40
|
+
this.model = options.model;
|
|
41
|
+
}
|
|
42
|
+
positionElements() {
|
|
43
|
+
if (!this.dialogContainerEl) return;
|
|
44
|
+
const range = this.quill.getSelection();
|
|
45
|
+
if (range) {
|
|
46
|
+
const bounds = this.quill.getBounds(range.index);
|
|
47
|
+
this.dialogContainerEl.style.position = "absolute";
|
|
48
|
+
this.dialogContainerEl.style.top = `${bounds.top + bounds.height}px`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 创建AI提示语元素
|
|
52
|
+
createAiPreTextEl() {
|
|
53
|
+
if (!this.aiPreTextEl) {
|
|
54
|
+
this.aiPreTextEl = document.createElement("span");
|
|
55
|
+
this.aiPreTextEl.className = "ql-ai-tip";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 创建弹出框
|
|
59
|
+
createElements() {
|
|
60
|
+
if (!this.dialogContainerEl) {
|
|
61
|
+
this.dialogContainerEl = document.createElement("div");
|
|
62
|
+
this.dialogContainerEl.className = "ql-ai-dialog";
|
|
63
|
+
this.wrapContainerEl = document.createElement("div");
|
|
64
|
+
this.wrapContainerEl.className = "ql-ai-wrapper";
|
|
65
|
+
this.wrapContainerEl.style.width = `${this.quill.container.clientWidth * 0.9}px`;
|
|
66
|
+
this.inputContainerEl = document.createElement("div");
|
|
67
|
+
this.inputContainerEl.className = "ql-ai-input";
|
|
68
|
+
const aiIcon = document.createElement("div");
|
|
69
|
+
aiIcon.className = "ql-ai-icon";
|
|
70
|
+
aiIcon.innerHTML = AI_ICON;
|
|
71
|
+
this.createAiPreTextEl();
|
|
72
|
+
this.inputEl = document.createElement("input");
|
|
73
|
+
this.inputEl.type = "text";
|
|
74
|
+
this.inputEl.placeholder = "请输入内容";
|
|
75
|
+
this.sendButtonEl = document.createElement("div");
|
|
76
|
+
this.sendButtonEl.className = "ql-ai-send";
|
|
77
|
+
this.resultPopupEl = document.createElement("div");
|
|
78
|
+
this.resultPopupEl.className = "ql-ai-result";
|
|
79
|
+
this.wrapContainerEl.appendChild(this.resultPopupEl);
|
|
80
|
+
this.inputContainerEl.appendChild(aiIcon);
|
|
81
|
+
this.inputContainerEl.appendChild(this.aiPreTextEl);
|
|
82
|
+
this.inputContainerEl.appendChild(this.inputEl);
|
|
83
|
+
this.inputContainerEl.appendChild(this.sendButtonEl);
|
|
84
|
+
this.wrapContainerEl.appendChild(this.inputContainerEl);
|
|
85
|
+
this.dialogContainerEl.appendChild(this.wrapContainerEl);
|
|
86
|
+
}
|
|
87
|
+
this.aiPreTextEl.textContent = `${this.model}帮你写:`;
|
|
88
|
+
this.sendButtonEl.textContent = this.SEND;
|
|
89
|
+
this.sendButtonEl.style.display = "block";
|
|
90
|
+
this.resultPopupEl.style.display = "none";
|
|
91
|
+
this.quill.container.appendChild(this.dialogContainerEl);
|
|
92
|
+
}
|
|
93
|
+
showAIInput() {
|
|
94
|
+
this.createElements();
|
|
95
|
+
this.positionElements();
|
|
96
|
+
this.inputEl.addEventListener("keydown", async (e) => {
|
|
97
|
+
if (e.key === "Enter") {
|
|
98
|
+
await this.queryAI();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
this.sendButtonEl.addEventListener("click", async (e) => {
|
|
102
|
+
if (e.target instanceof HTMLElement && e.target.textContent === this.BREAK) {
|
|
103
|
+
this.isBreak = true;
|
|
104
|
+
} else {
|
|
105
|
+
await this.queryAI();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const handleKeyDown = (e) => {
|
|
109
|
+
if (e.key === "Escape") {
|
|
110
|
+
this.closeAIPanel();
|
|
111
|
+
this.quill.container.removeEventListener("keydown", handleKeyDown);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
this.quill.container.addEventListener("keydown", handleKeyDown);
|
|
115
|
+
}
|
|
116
|
+
// AI查询
|
|
117
|
+
async queryAI(question) {
|
|
118
|
+
this.inputValue = question || this.inputEl.value;
|
|
119
|
+
this.inputEl.value = "";
|
|
120
|
+
if (this.inputValue.trim() === "") {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.isBreak = false;
|
|
124
|
+
this.sendButtonEl.textContent = this.BREAK;
|
|
125
|
+
this.sendButtonEl.style.display = "block";
|
|
126
|
+
this.aiPreTextEl.textContent = "按ESC退出 | 正在编写...";
|
|
127
|
+
try {
|
|
128
|
+
const response = await fetch(`${this.host}/api/generate`, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: {
|
|
131
|
+
"Content-Type": "application/json",
|
|
132
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
model: this.model,
|
|
136
|
+
prompt: this.inputValue,
|
|
137
|
+
stream: true
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
142
|
+
}
|
|
143
|
+
const reader = response.body.getReader();
|
|
144
|
+
const decoder = new TextDecoder();
|
|
145
|
+
let content = "";
|
|
146
|
+
while (true) {
|
|
147
|
+
if (this.isBreak) {
|
|
148
|
+
this.isBreak = false;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
const { done, value } = await reader.read();
|
|
152
|
+
if (done) break;
|
|
153
|
+
const chunk = decoder.decode(value);
|
|
154
|
+
const lines = chunk.split("\n").filter((line) => line.trim() !== "");
|
|
155
|
+
for (const line of lines) {
|
|
156
|
+
try {
|
|
157
|
+
const data = JSON.parse(line);
|
|
158
|
+
content += data.response || "";
|
|
159
|
+
this.showAIResponse(content);
|
|
160
|
+
} catch (e) {
|
|
161
|
+
console.error("解析错误:", e);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
this.createActionMenu();
|
|
166
|
+
if (content) {
|
|
167
|
+
this.aiPreTextEl.textContent = "";
|
|
168
|
+
this.sendButtonEl.textContent = this.SEND;
|
|
169
|
+
this.sendButtonEl.style.display = "none";
|
|
170
|
+
}
|
|
171
|
+
return content;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.error("AI查询失败:", error);
|
|
174
|
+
return "AI查询失败,请重试";
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
showAIResponse(response) {
|
|
178
|
+
if (!this.resultPopupEl) return;
|
|
179
|
+
this.resultPopupEl.innerHTML = response;
|
|
180
|
+
this.resultPopupEl.style.display = "block";
|
|
181
|
+
}
|
|
182
|
+
createActionMenu() {
|
|
183
|
+
if (!this.actionMenuEl) {
|
|
184
|
+
this.actionMenuEl = document.createElement("div");
|
|
185
|
+
this.actionMenuEl.className = "ql-ai-actions";
|
|
186
|
+
const actions = [this.DONE, this.REGENERATE, this.CLOSE];
|
|
187
|
+
actions.forEach((action) => {
|
|
188
|
+
const menuItem = document.createElement("div");
|
|
189
|
+
menuItem.className = "ql-ai-action-item";
|
|
190
|
+
menuItem.textContent = action;
|
|
191
|
+
menuItem.addEventListener("click", () => this.handleAction(action));
|
|
192
|
+
this.actionMenuEl.appendChild(menuItem);
|
|
193
|
+
});
|
|
194
|
+
this.wrapContainerEl.appendChild(this.actionMenuEl);
|
|
195
|
+
}
|
|
196
|
+
this.actionMenuEl.style.display = "block";
|
|
197
|
+
}
|
|
198
|
+
handleAction(action) {
|
|
199
|
+
switch (action) {
|
|
200
|
+
case this.DONE:
|
|
201
|
+
this.insertAIResponse();
|
|
202
|
+
break;
|
|
203
|
+
case this.REGENERATE:
|
|
204
|
+
this.regenerateResponse();
|
|
205
|
+
break;
|
|
206
|
+
case this.CLOSE:
|
|
207
|
+
this.closeAIPanel();
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
insertAIResponse() {
|
|
212
|
+
if (!this.resultPopupEl) return;
|
|
213
|
+
const range = this.quill.getSelection(true);
|
|
214
|
+
if (range) {
|
|
215
|
+
this.quill.clipboard.dangerouslyPasteHTML(
|
|
216
|
+
range.index,
|
|
217
|
+
this.resultPopupEl.innerHTML
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
this.closeAIPanel();
|
|
221
|
+
}
|
|
222
|
+
async regenerateResponse() {
|
|
223
|
+
this.actionMenuEl.style.display = "none";
|
|
224
|
+
await this.queryAI(this.inputValue);
|
|
225
|
+
}
|
|
226
|
+
closeAIPanel() {
|
|
227
|
+
this.isBreak = true;
|
|
228
|
+
if (this.dialogContainerEl) {
|
|
229
|
+
this.quill.container.removeChild(this.dialogContainerEl);
|
|
230
|
+
}
|
|
231
|
+
this.dialogContainerEl = null;
|
|
232
|
+
this.actionMenuEl = null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
export {
|
|
236
|
+
AI
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../../../../src/modules/ai/index.ts"],"sourcesContent":["import type TypeToolbar from 'quill/modules/toolbar'\r\nimport type FluentEditor from '../../core/fluent-editor'\r\nimport { AI_ICON } from '../../ui/icons.config'\r\n\r\nexport class AI {\r\n toolbar: TypeToolbar\r\n host: string\r\n apiKey: string\r\n model: string\r\n message: string\r\n isBreak: boolean = false // 打断标记\r\n inputValue: string = '' // 存储输入框的值\r\n SEND: string = '发送' // 发送按钮文字\r\n BREAK: string = '停止' // 取消按钮文字\r\n DONE: string = '完成'\r\n REGENERATE: string = '重新生成'\r\n CLOSE: string = '关闭'\r\n private dialogContainerEl: HTMLDivElement | null = null\r\n private wrapContainerEl: HTMLDivElement | null = null\r\n private aiPreTextEl: HTMLSpanElement | null = null\r\n private inputContainerEl: HTMLDivElement | null = null\r\n private inputEl: HTMLInputElement | null = null\r\n private sendButtonEl: HTMLDivElement | null = null\r\n private resultPopupEl: HTMLDivElement | null = null\r\n private actionMenuEl: HTMLDivElement | null = null\r\n\r\n constructor(public quill: FluentEditor, public options: any) {\r\n this.quill = quill\r\n this.toolbar = quill.getModule('toolbar') as TypeToolbar\r\n // 添加AI按钮到工具栏\r\n if (typeof this.toolbar !== 'undefined') {\r\n this.toolbar.addHandler('ai', this.showAIInput.bind(this))\r\n }\r\n\r\n this.host = options.host\r\n this.apiKey = options.apiKey\r\n this.model = options.model\r\n }\r\n\r\n positionElements() {\r\n if (!this.dialogContainerEl) return\r\n const range = this.quill.getSelection()\r\n if (range) {\r\n const bounds = this.quill.getBounds(range.index)\r\n this.dialogContainerEl.style.position = 'absolute'\r\n this.dialogContainerEl.style.top = `${bounds.top + bounds.height}px`\r\n }\r\n }\r\n\r\n // 创建AI提示语元素\r\n private createAiPreTextEl() {\r\n if (!this.aiPreTextEl) {\r\n this.aiPreTextEl = document.createElement('span')\r\n this.aiPreTextEl.className = 'ql-ai-tip'\r\n }\r\n }\r\n\r\n // 创建弹出框\r\n private createElements() {\r\n if (!this.dialogContainerEl) {\r\n this.dialogContainerEl = document.createElement('div')\r\n this.dialogContainerEl.className = 'ql-ai-dialog'\r\n this.wrapContainerEl = document.createElement('div')\r\n this.wrapContainerEl.className = 'ql-ai-wrapper'\r\n this.wrapContainerEl.style.width = `${this.quill.container.clientWidth * 0.9}px`\r\n\r\n // 创建输入框\r\n this.inputContainerEl = document.createElement('div')\r\n this.inputContainerEl.className = 'ql-ai-input'\r\n\r\n // 添加AI图标\r\n const aiIcon = document.createElement('div')\r\n aiIcon.className = 'ql-ai-icon'\r\n aiIcon.innerHTML = AI_ICON\r\n // 添加AI提示语\r\n this.createAiPreTextEl()\r\n\r\n // 增加输入框\r\n this.inputEl = document.createElement('input')\r\n this.inputEl.type = 'text'\r\n this.inputEl.placeholder = '请输入内容'\r\n // 添加发送按钮\r\n this.sendButtonEl = document.createElement('div')\r\n this.sendButtonEl.className = 'ql-ai-send'\r\n\r\n // 创建结果弹窗\r\n this.resultPopupEl = document.createElement('div')\r\n this.resultPopupEl.className = 'ql-ai-result'\r\n\r\n // 添加到编辑器\r\n this.wrapContainerEl.appendChild(this.resultPopupEl)\r\n this.inputContainerEl.appendChild(aiIcon)\r\n this.inputContainerEl.appendChild(this.aiPreTextEl)\r\n this.inputContainerEl.appendChild(this.inputEl)\r\n this.inputContainerEl.appendChild(this.sendButtonEl) // 添加发送按钮\r\n this.wrapContainerEl.appendChild(this.inputContainerEl)\r\n this.dialogContainerEl.appendChild(this.wrapContainerEl)\r\n }\r\n\r\n this.aiPreTextEl.textContent = `${this.model}帮你写:`\r\n this.sendButtonEl.textContent = this.SEND\r\n this.sendButtonEl.style.display = 'block' // 显示发送按钮\r\n this.resultPopupEl.style.display = 'none'\r\n this.quill.container.appendChild(this.dialogContainerEl)\r\n }\r\n\r\n showAIInput() {\r\n // 创建输入框和结果弹窗\r\n this.createElements()\r\n\r\n // 定位到编辑器焦点位置\r\n this.positionElements()\r\n\r\n // 监听发送事件\r\n this.inputEl.addEventListener('keydown', async (e) => {\r\n if (e.key === 'Enter') {\r\n await this.queryAI()\r\n }\r\n })\r\n this.sendButtonEl.addEventListener('click', async (e) => {\r\n if (e.target instanceof HTMLElement && e.target.textContent === this.BREAK) {\r\n this.isBreak = true\r\n }\r\n else {\r\n await this.queryAI()\r\n }\r\n })\r\n\r\n // 添加ESC键监听\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n this.closeAIPanel()\r\n this.quill.container.removeEventListener('keydown', handleKeyDown)\r\n }\r\n }\r\n this.quill.container.addEventListener('keydown', handleKeyDown)\r\n }\r\n\r\n // AI查询\r\n private async queryAI(question?: string): Promise<string> {\r\n this.inputValue = question || this.inputEl.value\r\n this.inputEl.value = '' // 清空输入框\r\n if (this.inputValue.trim() === '') {\r\n return\r\n }\r\n\r\n // 有信息\r\n this.isBreak = false // 重置打断标记,防止重复打断ai\r\n this.sendButtonEl.textContent = this.BREAK\r\n this.sendButtonEl.style.display = 'block'\r\n this.aiPreTextEl.textContent = '按ESC退出 | 正在编写...' // 显示提示语\r\n // 这里实现实际的AI查询逻辑\r\n try {\r\n const response = await fetch(`${this.host}/api/generate`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n prompt: this.inputValue,\r\n stream: true,\r\n }),\r\n })\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`)\r\n }\r\n\r\n const reader = response.body.getReader()\r\n const decoder = new TextDecoder()\r\n let content = ''\r\n\r\n while (true) {\r\n if (this.isBreak) {\r\n this.isBreak = false\r\n break\r\n }\r\n\r\n const { done, value } = await reader.read()\r\n if (done) break\r\n\r\n const chunk = decoder.decode(value)\r\n const lines = chunk.split('\\n').filter(line => line.trim() !== '')\r\n\r\n for (const line of lines) {\r\n try {\r\n const data = JSON.parse(line)\r\n content += data.response || ''\r\n this.showAIResponse(content)\r\n }\r\n catch (e) {\r\n console.error('解析错误:', e)\r\n }\r\n }\r\n }\r\n\r\n // 创建操作菜单\r\n this.createActionMenu()\r\n if (content) {\r\n this.aiPreTextEl.textContent = '' // 清空提示语\r\n // 隐藏发送按钮\r\n this.sendButtonEl.textContent = this.SEND\r\n this.sendButtonEl.style.display = 'none'\r\n }\r\n return content\r\n }\r\n catch (error) {\r\n console.error('AI查询失败:', error)\r\n return 'AI查询失败,请重试'\r\n }\r\n }\r\n\r\n private showAIResponse(response: string) {\r\n if (!this.resultPopupEl) return\r\n\r\n // 显示结果\r\n this.resultPopupEl.innerHTML = response\r\n this.resultPopupEl.style.display = 'block'\r\n }\r\n\r\n private createActionMenu() {\r\n if (!this.actionMenuEl) {\r\n this.actionMenuEl = document.createElement('div')\r\n this.actionMenuEl.className = 'ql-ai-actions'\r\n\r\n const actions = [this.DONE, this.REGENERATE, this.CLOSE]\r\n actions.forEach((action) => {\r\n const menuItem = document.createElement('div')\r\n menuItem.className = 'ql-ai-action-item'\r\n menuItem.textContent = action\r\n menuItem.addEventListener('click', () => this.handleAction(action))\r\n this.actionMenuEl.appendChild(menuItem)\r\n })\r\n\r\n this.wrapContainerEl.appendChild(this.actionMenuEl)\r\n }\r\n // 展示下拉菜单\r\n this.actionMenuEl.style.display = 'block'\r\n }\r\n\r\n private handleAction(action: string) {\r\n switch (action) {\r\n case this.DONE:\r\n this.insertAIResponse()\r\n break\r\n case this.REGENERATE:\r\n this.regenerateResponse()\r\n break\r\n case this.CLOSE:\r\n this.closeAIPanel()\r\n break\r\n }\r\n }\r\n\r\n private insertAIResponse() {\r\n if (!this.resultPopupEl) return\r\n const range = this.quill.getSelection(true)\r\n if (range) {\r\n // 使用HTML方式插入可以保留格式\r\n this.quill.clipboard.dangerouslyPasteHTML(\r\n range.index,\r\n this.resultPopupEl.innerHTML,\r\n )\r\n }\r\n this.closeAIPanel()\r\n }\r\n\r\n private async regenerateResponse() {\r\n this.actionMenuEl.style.display = 'none'\r\n await this.queryAI(this.inputValue)\r\n }\r\n\r\n private closeAIPanel() {\r\n this.isBreak = true // 停止查询\r\n if (this.dialogContainerEl) {\r\n this.quill.container.removeChild(this.dialogContainerEl)\r\n }\r\n this.dialogContainerEl = null\r\n this.actionMenuEl = null\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emoji.es.js","sources":["../../../src/modules/emoji.ts"],"sourcesContent":["import type { Delta } from 'quill'\r\nimport type TypeToolbar from 'quill/modules/toolbar'\r\nimport type FluentEditor from '../fluent-editor'\r\nimport data from '@emoji-mart/data'\r\nimport { computePosition } from '@floating-ui/dom'\r\nimport { Picker } from 'emoji-mart'\r\nimport { debounce } from 'lodash-es'\r\n\r\nexport interface EmojiModuleOptions {\r\n theme?: string\r\n locale?: string\r\n set?: string\r\n skinTonePosition?: string\r\n previewPosition?: string\r\n searchPosition?: string\r\n categories?: string[]\r\n maxFrequentRows?: number\r\n perLine?: number\r\n navPosition?: string\r\n noCountryFlags?: boolean\r\n dynamicWidth?: boolean\r\n}\r\n\r\nconst DEFAULT_OPTIONS:
|
|
1
|
+
{"version":3,"file":"emoji.es.js","sources":["../../../src/modules/emoji.ts"],"sourcesContent":["import type { Delta } from 'quill'\r\nimport type TypeToolbar from 'quill/modules/toolbar'\r\nimport type FluentEditor from '../fluent-editor'\r\nimport data from '@emoji-mart/data'\r\nimport { computePosition } from '@floating-ui/dom'\r\nimport { Picker } from 'emoji-mart'\r\nimport { debounce } from 'lodash-es'\r\n\r\nexport interface EmojiModuleOptions {\r\n theme?: string\r\n locale?: string\r\n set?: string\r\n skinTonePosition?: string\r\n previewPosition?: string\r\n searchPosition?: string\r\n categories?: string[]\r\n maxFrequentRows?: number\r\n perLine?: number\r\n navPosition?: string\r\n noCountryFlags?: boolean\r\n dynamicWidth?: boolean\r\n}\r\n\r\nconst DEFAULT_OPTIONS: EmojiModuleOptions = {\r\n theme: 'light',\r\n set: 'native',\r\n skinTonePosition: 'none',\r\n previewPosition: 'bottom',\r\n searchPosition: 'sticky',\r\n categories: ['frequent', 'people', 'nature', 'foods', 'activity', 'places', 'objects', 'symbols', 'flags'],\r\n maxFrequentRows: 2,\r\n perLine: 8,\r\n navPosition: 'top',\r\n noCountryFlags: false,\r\n dynamicWidth: false,\r\n}\r\n\r\nconst PICKER_DOM_ID = 'emoji-picker'\r\n\r\nconst LOCALE_MAP = {\r\n 'zh-CN': 'zh',\r\n 'en-US': 'en',\r\n} as const\r\n\r\nclass EmojiModule {\r\n private readonly quill: FluentEditor\r\n private readonly options: EmojiModuleOptions\r\n private picker: HTMLElement | null = null\r\n private isPickerVisible = false\r\n private cleanupResizeObserver: (() => void) | null = null\r\n\r\n constructor(quill: FluentEditor, options: EmojiModuleOptions = {}) {\r\n this.quill = quill\r\n\r\n this.options = options\r\n\r\n const toolbar = this.quill.getModule('toolbar') as TypeToolbar\r\n\r\n if (toolbar) {\r\n toolbar.addHandler('emoji', () => {\r\n if (this.isPickerVisible) {\r\n this.closeDialog()\r\n }\r\n else {\r\n this.openDialog()\r\n }\r\n })\r\n }\r\n }\r\n\r\n private getEmojiButton() {\r\n return document.querySelector('.ql-emoji') as HTMLElement | null\r\n }\r\n\r\n private async updatePickerPosition() {\r\n const button = this.getEmojiButton()\r\n const pickerElement = document.getElementById(PICKER_DOM_ID)\r\n\r\n if (!button || !this.picker || !pickerElement) {\r\n return\r\n }\r\n\r\n try {\r\n const { x, y } = await computePosition(button, pickerElement)\r\n this.picker.style.top = `${y}px`\r\n this.picker.style.left = `${x}px`\r\n }\r\n catch (error) {\r\n console.warn('Failed to compute picker position:', error)\r\n }\r\n }\r\n\r\n // 监听容器大小变化,更新表情选择弹窗位置\r\n private setupContainerResizeObserver() {\r\n const container = this.quill.root.parentElement\r\n if (!container) {\r\n return null\r\n }\r\n\r\n const debouncedUpdate = debounce(() => {\r\n this.updatePickerPosition()\r\n }, 100)\r\n\r\n const resizeObserver = new ResizeObserver(() => {\r\n debouncedUpdate()\r\n })\r\n\r\n resizeObserver.observe(container)\r\n\r\n return () => {\r\n resizeObserver.disconnect()\r\n debouncedUpdate.cancel()\r\n }\r\n }\r\n\r\n // 创建表情选择弹窗\r\n private createPicker() {\r\n const pickerConfig = {\r\n ...DEFAULT_OPTIONS,\r\n // emoji-mart 与 tiny-editor 国际化的的 locale 不一致使用 LOCALE_MAP 转换\r\n locale: LOCALE_MAP[this.quill.lang] ?? 'en',\r\n ...this.options,\r\n data,\r\n onEmojiSelect: this.handleEmojiSelect.bind(this),\r\n onClickOutside: this.handleClickOutside.bind(this),\r\n }\r\n\r\n const picker = new Picker(pickerConfig) as unknown as HTMLElement\r\n\r\n // 设置样式和属性\r\n picker.id = PICKER_DOM_ID\r\n picker.style.position = 'absolute'\r\n picker.style.zIndex = '1000'\r\n\r\n return picker\r\n }\r\n\r\n // 打开表情弹窗\r\n public openDialog() {\r\n if (this.picker) {\r\n return\r\n }\r\n\r\n try {\r\n this.picker = this.createPicker()\r\n document.body.appendChild(this.picker)\r\n\r\n this.updatePickerPosition()\r\n this.cleanupResizeObserver = this.setupContainerResizeObserver()\r\n this.isPickerVisible = true\r\n }\r\n catch (error) {\r\n console.error('Failed to open emoji picker:', error)\r\n this.closeDialog()\r\n }\r\n }\r\n\r\n // 关闭表情弹窗\r\n public closeDialog() {\r\n if (!this.picker) {\r\n return\r\n }\r\n\r\n this.isPickerVisible = false\r\n this.picker.remove()\r\n this.picker = null\r\n\r\n this.cleanupResizeObserver?.()\r\n this.cleanupResizeObserver = null\r\n }\r\n\r\n // 处理表情选择事件\r\n private handleEmojiSelect(emoji: { native: string }) {\r\n const selection = this.quill.getSelection(true)\r\n if (!selection) {\r\n console.warn('No selection available for emoji insertion')\r\n return\r\n }\r\n\r\n try {\r\n const emojiDelta = this.quill.insertText(selection.index, emoji.native, 'user')\r\n\r\n this.closeDialog()\r\n\r\n // 异步设置光标位置,确保插入完成后再设置\r\n this.setSelectionAfterEmoji(emojiDelta)\r\n }\r\n catch (error) {\r\n console.error('Failed to insert emoji:', error)\r\n }\r\n }\r\n\r\n // 设置表情插入后的光标位置\r\n private setSelectionAfterEmoji(emojiDelta: Delta) {\r\n setTimeout(() => {\r\n try {\r\n const newSelection = this.quill.getSelection(true)\r\n if (newSelection && emojiDelta) {\r\n this.quill.setSelection(newSelection.index + emojiDelta.length())\r\n }\r\n }\r\n catch (error) {\r\n console.warn('Failed to set selection after emoji insertion:', error)\r\n }\r\n }, 0)\r\n }\r\n\r\n // 处理外部点击事件\r\n private handleClickOutside(event: MouseEvent) {\r\n const button = this.getEmojiButton()\r\n\r\n const target = event.target\r\n\r\n const isClickOnButton = target === button || (target instanceof Element && button?.contains(target))\r\n\r\n // 如果点击的是表情符号按钮或其子元素,则不关闭选择器\r\n if (isClickOnButton) {\r\n return\r\n }\r\n\r\n this.closeDialog()\r\n }\r\n\r\n // 销毁模块,清理资源\r\n public destroy() {\r\n this.cleanupResizeObserver?.()\r\n this.cleanupResizeObserver = null\r\n this.closeDialog()\r\n }\r\n}\r\n\r\nexport { EmojiModule }\r\n"],"names":["Picker"],"mappings":"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"}
|
package/es/themes/snow.es.js
CHANGED
package/es/themes/snow.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snow.es.js","sources":["../../../src/themes/snow.ts"],"sourcesContent":["import type { ThemeOptions } from 'quill/core/theme'\r\nimport type TypeToolbar from 'quill/modules/toolbar'\r\nimport type TypeIconPicker from 'quill/ui/icon-picker'\r\nimport { CHANGE_LANGUAGE_EVENT, inputFile, isNullOrUndefined } from '../config'\r\nimport FluentEditor from '../core/fluent-editor'\r\nimport { CustomImageSpec } from '../modules/custom-image/specs/custom-image-spec'\r\nimport { LinkTooltip } from '../modules/link'\r\nimport { shortKey } from '../modules/shortcut-key'\r\nimport { ColorPicker, Picker } from '../modules/toolbar/better-picker'\r\nimport { FormatPainter } from '../tools/format-painter'\r\nimport { fullscreenHandler } from '../tools/fullscreen'\r\nimport { Screenshot } from '../tools/screenshot'\r\n\r\nconst OriginSnowTheme = FluentEditor.import('themes/snow') as any\r\nconst IconPicker = FluentEditor.import('ui/icon-picker') as typeof TypeIconPicker\r\n\r\nOriginSnowTheme.DEFAULTS = {\r\n modules: {\r\n 'i18n': true,\r\n 'keyboard': {\r\n bindings: {\r\n ...shortKey,\r\n },\r\n },\r\n 'toolbar': {\r\n handlers: {\r\n ...(OriginSnowTheme.DEFAULTS as Record<string, any>).modules.toolbar.handlers,\r\n 'formula': function () {\r\n if (!this.quill.isEnabled()) return\r\n const mathlive = this.quill.getModule('mathlive')\r\n if (!mathlive) {\r\n this.quill.theme.tooltip.edit('formula')\r\n }\r\n else {\r\n mathlive.createDialog()\r\n }\r\n },\r\n 'undo': function () {\r\n this.quill.history.undo()\r\n },\r\n 'redo': function () {\r\n this.quill.history.redo()\r\n },\r\n 'file': function () {\r\n const accept = this.quill.uploader.options.mimetypes\r\n inputFile.call(this, 'file', accept)\r\n },\r\n 'image': function () {\r\n const accept = (this.quill as FluentEditor).uploader.options.mimetypes.filter((type) => {\r\n if (type === '*') return 'image/*'\r\n return type.startsWith('image/')\r\n })\r\n inputFile.call(this, 'image', accept)\r\n },\r\n 'video': function () {\r\n const accept = (this.quill as FluentEditor).uploader.options.mimetypes.filter((type) => {\r\n if (type === '*') return 'video/*'\r\n return type.startsWith('video/')\r\n })\r\n inputFile.call(this, 'video', accept)\r\n },\r\n 'emoji': function () {},\r\n 'fullscreen': fullscreenHandler,\r\n [FormatPainter.toolName]: FormatPainter,\r\n [Screenshot.toolName]: Screenshot,\r\n 'line-height': function (value) {\r\n this.quill.format('line-height', value)\r\n },\r\n 'divider': function () {\r\n const range = this.quill.getSelection(true)\r\n this.quill.insertText(range.index, '\\n', FluentEditor.sources.USER)\r\n this.quill.insertEmbed(range.index + 1, 'divider', true, FluentEditor.sources.USER)\r\n this.quill.setSelection(range.index + 2, FluentEditor.sources.SILENT)\r\n },\r\n },\r\n },\r\n 'image': {\r\n specs: [CustomImageSpec],\r\n overlay: {\r\n style: {\r\n border: '1px dashed rgb(68, 68, 68)',\r\n },\r\n },\r\n },\r\n 'shortcut-key': true,\r\n 'file': true,\r\n },\r\n}\r\n\r\nconst ALIGNS = [false, 'center', 'right']\r\nconst COLORS = [\r\n '',\r\n 'rgb(255, 255, 255)',\r\n 'rgb(0, 0, 0)',\r\n 'rgb(72, 83, 104)',\r\n 'rgb(41, 114, 244)',\r\n 'rgb(0, 163, 245)',\r\n 'rgb(49, 155, 98)',\r\n 'rgb(222, 60, 54)',\r\n 'rgb(248, 136, 37)',\r\n 'rgb(245, 196, 0)',\r\n 'rgb(153, 56, 215)',\r\n\r\n 'rgb(242, 242, 242)',\r\n 'rgb(127, 127, 127)',\r\n 'rgb(243, 245, 247)',\r\n 'rgb(229, 239, 255)',\r\n 'rgb(229, 246, 255)',\r\n 'rgb(234, 250, 241)',\r\n 'rgb(254, 233, 232)',\r\n 'rgb(254, 243, 235)',\r\n 'rgb(254, 249, 227)',\r\n 'rgb(253, 235, 255)',\r\n\r\n 'rgb(216, 216, 216)',\r\n 'rgb(89, 89, 89)',\r\n 'rgb(197, 202, 211)',\r\n 'rgb(199, 220, 255)',\r\n 'rgb(199, 236, 255)',\r\n 'rgb(195, 234, 213)',\r\n 'rgb(255, 201, 199)',\r\n 'rgb(255, 220, 196)',\r\n 'rgb(255, 238, 173)',\r\n 'rgb(242, 199, 255)',\r\n\r\n 'rgb(191, 191, 191)',\r\n 'rgb(63, 63, 63)',\r\n 'rgb(128, 139, 158)',\r\n 'rgb(153, 190, 255)',\r\n 'rgb(153, 221, 255)',\r\n 'rgb(152, 215, 182)',\r\n 'rgb(255, 156, 153)',\r\n 'rgb(255, 186, 132)',\r\n 'rgb(255, 226, 112)',\r\n 'rgb(213, 142, 255)',\r\n\r\n 'rgb(165, 165, 165)',\r\n 'rgb(38, 38, 38)',\r\n 'rgb(53, 59, 69)',\r\n 'rgb(20, 80, 184)',\r\n 'rgb(18, 116, 165)',\r\n 'rgb(39, 124, 79)',\r\n 'rgb(158, 30, 26)',\r\n 'rgb(184, 96, 20)',\r\n 'rgb(163, 130, 0)',\r\n 'rgb(94, 34, 129)',\r\n\r\n 'rgb(147, 147, 147)',\r\n 'rgb(13, 13, 13)',\r\n 'rgb(36, 39, 46)',\r\n 'rgb(12, 48, 110)',\r\n 'rgb(10, 65, 92)',\r\n 'rgb(24, 78, 50)',\r\n 'rgb(88, 17, 14)',\r\n 'rgb(92, 48, 10)',\r\n 'rgb(102, 82, 0)',\r\n 'rgb(59, 21, 81)',\r\n\r\n 'custom',\r\n]\r\nconst FONTS = [false, 'serif', 'monospace']\r\nconst HEADERS = ['1', '2', '3', false]\r\nconst SIZES = ['small', false, 'large', 'huge']\r\nconst LINEHEIGHT = [false, '1.2', '1.5', '2']\r\n\r\nclass SnowTheme extends OriginSnowTheme {\r\n constructor(public quill: FluentEditor, options: ThemeOptions) {\r\n super(quill, options)\r\n\r\n this.quill.emitter.on(CHANGE_LANGUAGE_EVENT, () => {\r\n this.i18nTextToolbar()\r\n })\r\n }\r\n\r\n i18nTextToolbar() {\r\n const toolbar = this.quill.getModule('toolbar') as TypeToolbar\r\n ColorPicker.clearText = this.quill.getLangText('clear-color')\r\n ColorPicker.customText = this.quill.getLangText('custom-color')\r\n if (!toolbar || !this.pickers) return\r\n this.pickers.forEach((picker) => {\r\n if (picker instanceof ColorPicker) {\r\n // EasyColorPicker have not dts. abd origin quill ColorPicker dts not complete. use any to resovle ts type error\r\n const colorPicker = picker as any\r\n colorPicker.options.remove()\r\n Array.from(colorPicker.select.options).forEach((option: any) => {\r\n if (option.hasAttribute('custom')) {\r\n option.remove()\r\n }\r\n })\r\n colorPicker.buildOptions()\r\n colorPicker.createUsedColor()\r\n }\r\n })\r\n }\r\n\r\n buildPickers(selects: NodeListOf<HTMLSelectElement>, icons: Record<string, string | Record<string, string>>) {\r\n this.pickers = Array.from(selects).map((select) => {\r\n if (select.classList.contains('ql-align')) {\r\n if (isNullOrUndefined(select.querySelector('option'))) {\r\n fillSelect(select, ALIGNS)\r\n }\r\n return new IconPicker(select, icons.align as Record<string, string>)\r\n }\r\n if (select.classList.contains('ql-background') || select.classList.contains('ql-color')) {\r\n const format = select.classList.contains('ql-background') ? 'background' : 'color'\r\n if (isNullOrUndefined(select.querySelector('option'))) {\r\n fillColorSelect(select, COLORS, format, format === 'background' ? '#ffffff' : '#000000')\r\n }\r\n return new ColorPicker(select, icons[format] as string, {\r\n expandIcon: '<i class=\"icon\" />',\r\n closeAfterChange: false,\r\n })\r\n }\r\n if (isNullOrUndefined(select.querySelector('option'))) {\r\n if (select.classList.contains('ql-font')) {\r\n fillSelect(select, FONTS)\r\n }\r\n else if (select.classList.contains('ql-header')) {\r\n fillSelect(select, HEADERS)\r\n }\r\n else if (select.classList.contains('ql-size')) {\r\n fillSelect(select, SIZES)\r\n }\r\n else if (select.classList.contains('ql-line-height')) {\r\n fillSelect(select, LINEHEIGHT)\r\n }\r\n }\r\n return new Picker(select)\r\n })\r\n const update = () => {\r\n this.pickers.forEach((picker) => {\r\n if (picker instanceof ColorPicker) return\r\n picker.update()\r\n })\r\n }\r\n this.quill.on(FluentEditor.events.EDITOR_CHANGE, update)\r\n }\r\n\r\n extendToolbar(toolbar) {\r\n const icons = FluentEditor.import('ui/icons') as Record<string, any>\r\n toolbar.container.classList.add('ql-snow')\r\n this.buildButtons(toolbar.container.querySelectorAll('button'), icons)\r\n this.buildPickers(toolbar.container.querySelectorAll('select'), icons)\r\n this.tooltip = new LinkTooltip(this.quill, this.options.bounds)\r\n }\r\n}\r\n\r\nfunction fillSelect(select, values, defaultValue = false) {\r\n values.forEach((value) => {\r\n const option = document.createElement('option')\r\n if (value === defaultValue) {\r\n option.setAttribute('selected', 'selected')\r\n }\r\n else {\r\n option.setAttribute('value', value)\r\n }\r\n select.appendChild(option)\r\n })\r\n}\r\nfunction fillColorSelect(\r\n select: HTMLSelectElement,\r\n values: Array<string | boolean>,\r\n format: string,\r\n defaultValue: unknown = false,\r\n) {\r\n const colorGetter = document.createElement('span') as HTMLElement\r\n for (const value of values) {\r\n const option = document.createElement('option')\r\n if (value === defaultValue) {\r\n option.setAttribute('selected', 'selected')\r\n }\r\n else {\r\n if (value !== 'custom') {\r\n colorGetter.style[format] = String(value)\r\n option.setAttribute('value', colorGetter.style[format])\r\n }\r\n else {\r\n option.setAttribute('value', value)\r\n }\r\n }\r\n select.appendChild(option)\r\n }\r\n}\r\n\r\nexport default SnowTheme\r\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snow.es.js","sources":["../../../src/themes/snow.ts"],"sourcesContent":["import type { ThemeOptions } from 'quill/core/theme'\r\nimport type TypeToolbar from 'quill/modules/toolbar'\r\nimport type TypeIconPicker from 'quill/ui/icon-picker'\r\nimport { CHANGE_LANGUAGE_EVENT, inputFile, isNullOrUndefined } from '../config'\r\nimport FluentEditor from '../core/fluent-editor'\r\nimport { CustomImageSpec } from '../modules/custom-image/specs/custom-image-spec'\r\nimport { LinkTooltip } from '../modules/link'\r\nimport { shortKey } from '../modules/shortcut-key'\r\nimport { ColorPicker, Picker } from '../modules/toolbar/better-picker'\r\nimport { FormatPainter } from '../tools/format-painter'\r\nimport { fullscreenHandler } from '../tools/fullscreen'\r\nimport { Screenshot } from '../tools/screenshot'\r\n\r\nconst OriginSnowTheme = FluentEditor.import('themes/snow') as any\r\nconst IconPicker = FluentEditor.import('ui/icon-picker') as typeof TypeIconPicker\r\n\r\nOriginSnowTheme.DEFAULTS = {\r\n modules: {\r\n 'i18n': true,\r\n 'keyboard': {\r\n bindings: {\r\n ...shortKey,\r\n },\r\n },\r\n 'toolbar': {\r\n handlers: {\r\n ...(OriginSnowTheme.DEFAULTS as Record<string, any>).modules.toolbar.handlers,\r\n 'formula': function () {\r\n if (!this.quill.isEnabled()) return\r\n const mathlive = this.quill.getModule('mathlive')\r\n if (!mathlive) {\r\n this.quill.theme.tooltip.edit('formula')\r\n }\r\n else {\r\n mathlive.createDialog()\r\n }\r\n },\r\n 'undo': function () {\r\n this.quill.history.undo()\r\n },\r\n 'redo': function () {\r\n this.quill.history.redo()\r\n },\r\n 'file': function () {\r\n const accept = this.quill.uploader.options.mimetypes\r\n inputFile.call(this, 'file', accept)\r\n },\r\n 'image': function () {\r\n const accept = (this.quill as FluentEditor).uploader.options.mimetypes.filter((type) => {\r\n if (type === '*') return 'image/*'\r\n return type.startsWith('image/')\r\n })\r\n inputFile.call(this, 'image', accept)\r\n },\r\n 'video': function () {\r\n const accept = (this.quill as FluentEditor).uploader.options.mimetypes.filter((type) => {\r\n if (type === '*') return 'video/*'\r\n return type.startsWith('video/')\r\n })\r\n inputFile.call(this, 'video', accept)\r\n },\r\n 'ai': function () {},\r\n 'emoji': function () {},\r\n 'fullscreen': fullscreenHandler,\r\n [FormatPainter.toolName]: FormatPainter,\r\n [Screenshot.toolName]: Screenshot,\r\n 'line-height': function (value) {\r\n this.quill.format('line-height', value)\r\n },\r\n 'divider': function () {\r\n const range = this.quill.getSelection(true)\r\n this.quill.insertText(range.index, '\\n', FluentEditor.sources.USER)\r\n this.quill.insertEmbed(range.index + 1, 'divider', true, FluentEditor.sources.USER)\r\n this.quill.setSelection(range.index + 2, FluentEditor.sources.SILENT)\r\n },\r\n },\r\n },\r\n 'image': {\r\n specs: [CustomImageSpec],\r\n overlay: {\r\n style: {\r\n border: '1px dashed rgb(68, 68, 68)',\r\n },\r\n },\r\n },\r\n 'shortcut-key': true,\r\n 'file': true,\r\n },\r\n}\r\n\r\nconst ALIGNS = [false, 'center', 'right']\r\nconst COLORS = [\r\n '',\r\n 'rgb(255, 255, 255)',\r\n 'rgb(0, 0, 0)',\r\n 'rgb(72, 83, 104)',\r\n 'rgb(41, 114, 244)',\r\n 'rgb(0, 163, 245)',\r\n 'rgb(49, 155, 98)',\r\n 'rgb(222, 60, 54)',\r\n 'rgb(248, 136, 37)',\r\n 'rgb(245, 196, 0)',\r\n 'rgb(153, 56, 215)',\r\n\r\n 'rgb(242, 242, 242)',\r\n 'rgb(127, 127, 127)',\r\n 'rgb(243, 245, 247)',\r\n 'rgb(229, 239, 255)',\r\n 'rgb(229, 246, 255)',\r\n 'rgb(234, 250, 241)',\r\n 'rgb(254, 233, 232)',\r\n 'rgb(254, 243, 235)',\r\n 'rgb(254, 249, 227)',\r\n 'rgb(253, 235, 255)',\r\n\r\n 'rgb(216, 216, 216)',\r\n 'rgb(89, 89, 89)',\r\n 'rgb(197, 202, 211)',\r\n 'rgb(199, 220, 255)',\r\n 'rgb(199, 236, 255)',\r\n 'rgb(195, 234, 213)',\r\n 'rgb(255, 201, 199)',\r\n 'rgb(255, 220, 196)',\r\n 'rgb(255, 238, 173)',\r\n 'rgb(242, 199, 255)',\r\n\r\n 'rgb(191, 191, 191)',\r\n 'rgb(63, 63, 63)',\r\n 'rgb(128, 139, 158)',\r\n 'rgb(153, 190, 255)',\r\n 'rgb(153, 221, 255)',\r\n 'rgb(152, 215, 182)',\r\n 'rgb(255, 156, 153)',\r\n 'rgb(255, 186, 132)',\r\n 'rgb(255, 226, 112)',\r\n 'rgb(213, 142, 255)',\r\n\r\n 'rgb(165, 165, 165)',\r\n 'rgb(38, 38, 38)',\r\n 'rgb(53, 59, 69)',\r\n 'rgb(20, 80, 184)',\r\n 'rgb(18, 116, 165)',\r\n 'rgb(39, 124, 79)',\r\n 'rgb(158, 30, 26)',\r\n 'rgb(184, 96, 20)',\r\n 'rgb(163, 130, 0)',\r\n 'rgb(94, 34, 129)',\r\n\r\n 'rgb(147, 147, 147)',\r\n 'rgb(13, 13, 13)',\r\n 'rgb(36, 39, 46)',\r\n 'rgb(12, 48, 110)',\r\n 'rgb(10, 65, 92)',\r\n 'rgb(24, 78, 50)',\r\n 'rgb(88, 17, 14)',\r\n 'rgb(92, 48, 10)',\r\n 'rgb(102, 82, 0)',\r\n 'rgb(59, 21, 81)',\r\n\r\n 'custom',\r\n]\r\nconst FONTS = [false, 'serif', 'monospace']\r\nconst HEADERS = ['1', '2', '3', false]\r\nconst SIZES = ['small', false, 'large', 'huge']\r\nconst LINEHEIGHT = [false, '1.2', '1.5', '2']\r\n\r\nclass SnowTheme extends OriginSnowTheme {\r\n constructor(public quill: FluentEditor, options: ThemeOptions) {\r\n super(quill, options)\r\n\r\n this.quill.emitter.on(CHANGE_LANGUAGE_EVENT, () => {\r\n this.i18nTextToolbar()\r\n })\r\n }\r\n\r\n i18nTextToolbar() {\r\n const toolbar = this.quill.getModule('toolbar') as TypeToolbar\r\n ColorPicker.clearText = this.quill.getLangText('clear-color')\r\n ColorPicker.customText = this.quill.getLangText('custom-color')\r\n if (!toolbar || !this.pickers) return\r\n this.pickers.forEach((picker) => {\r\n if (picker instanceof ColorPicker) {\r\n // EasyColorPicker have not dts. abd origin quill ColorPicker dts not complete. use any to resovle ts type error\r\n const colorPicker = picker as any\r\n colorPicker.options.remove()\r\n Array.from(colorPicker.select.options).forEach((option: any) => {\r\n if (option.hasAttribute('custom')) {\r\n option.remove()\r\n }\r\n })\r\n colorPicker.buildOptions()\r\n colorPicker.createUsedColor()\r\n }\r\n })\r\n }\r\n\r\n buildPickers(selects: NodeListOf<HTMLSelectElement>, icons: Record<string, string | Record<string, string>>) {\r\n this.pickers = Array.from(selects).map((select) => {\r\n if (select.classList.contains('ql-align')) {\r\n if (isNullOrUndefined(select.querySelector('option'))) {\r\n fillSelect(select, ALIGNS)\r\n }\r\n return new IconPicker(select, icons.align as Record<string, string>)\r\n }\r\n if (select.classList.contains('ql-background') || select.classList.contains('ql-color')) {\r\n const format = select.classList.contains('ql-background') ? 'background' : 'color'\r\n if (isNullOrUndefined(select.querySelector('option'))) {\r\n fillColorSelect(select, COLORS, format, format === 'background' ? '#ffffff' : '#000000')\r\n }\r\n return new ColorPicker(select, icons[format] as string, {\r\n expandIcon: '<i class=\"icon\" />',\r\n closeAfterChange: false,\r\n })\r\n }\r\n if (isNullOrUndefined(select.querySelector('option'))) {\r\n if (select.classList.contains('ql-font')) {\r\n fillSelect(select, FONTS)\r\n }\r\n else if (select.classList.contains('ql-header')) {\r\n fillSelect(select, HEADERS)\r\n }\r\n else if (select.classList.contains('ql-size')) {\r\n fillSelect(select, SIZES)\r\n }\r\n else if (select.classList.contains('ql-line-height')) {\r\n fillSelect(select, LINEHEIGHT)\r\n }\r\n }\r\n return new Picker(select)\r\n })\r\n const update = () => {\r\n this.pickers.forEach((picker) => {\r\n if (picker instanceof ColorPicker) return\r\n picker.update()\r\n })\r\n }\r\n this.quill.on(FluentEditor.events.EDITOR_CHANGE, update)\r\n }\r\n\r\n extendToolbar(toolbar) {\r\n const icons = FluentEditor.import('ui/icons') as Record<string, any>\r\n toolbar.container.classList.add('ql-snow')\r\n this.buildButtons(toolbar.container.querySelectorAll('button'), icons)\r\n this.buildPickers(toolbar.container.querySelectorAll('select'), icons)\r\n this.tooltip = new LinkTooltip(this.quill, this.options.bounds)\r\n }\r\n}\r\n\r\nfunction fillSelect(select, values, defaultValue = false) {\r\n values.forEach((value) => {\r\n const option = document.createElement('option')\r\n if (value === defaultValue) {\r\n option.setAttribute('selected', 'selected')\r\n }\r\n else {\r\n option.setAttribute('value', value)\r\n }\r\n select.appendChild(option)\r\n })\r\n}\r\nfunction fillColorSelect(\r\n select: HTMLSelectElement,\r\n values: Array<string | boolean>,\r\n format: string,\r\n defaultValue: unknown = false,\r\n) {\r\n const colorGetter = document.createElement('span') as HTMLElement\r\n for (const value of values) {\r\n const option = document.createElement('option')\r\n if (value === defaultValue) {\r\n option.setAttribute('selected', 'selected')\r\n }\r\n else {\r\n if (value !== 'custom') {\r\n colorGetter.style[format] = String(value)\r\n option.setAttribute('value', colorGetter.style[format])\r\n }\r\n else {\r\n option.setAttribute('value', value)\r\n }\r\n }\r\n select.appendChild(option)\r\n }\r\n}\r\n\r\nexport default SnowTheme\r\n"],"names":[],"mappings":"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"}
|
package/es/ui/icons.config.es.js
CHANGED
|
@@ -278,7 +278,22 @@ const FULLSCREEN_EXIT_ICON = `
|
|
|
278
278
|
const TRIANGLE_DOWN_ICON = `<i class="icon-triangle-down"></i>`;
|
|
279
279
|
const FORMAT_PAINTER_ICON = `<svg viewBox="0 0 32 32"><path fill="currentColor" d="M28.83 23.17L23 17.33V13a1 1 0 0 0-.29-.71l-10-10a1 1 0 0 0-1.42 0l-9 9a1 1 0 0 0 0 1.42l10 10A1 1 0 0 0 13 23h4.34l5.83 5.84a4 4 0 0 0 5.66-5.66ZM6 10.41l2.29 2.3l1.42-1.42L7.41 9L9 7.41l4.29 4.3l1.42-1.42L10.41 6L12 4.41L18.59 11L11 18.59L4.41 12Zm21.41 17a2 2 0 0 1-2.82 0l-6.13-6.12a1.8 1.8 0 0 0-.71-.29h-4.34l-1-1L20 12.41l1 1v4.34a1 1 0 0 0 .29.7l6.12 6.14a2 2 0 0 1 0 2.82"/></svg>`;
|
|
280
280
|
const DIVIDER_ICON = `<svg viewBox="0 0 18 18"><line x1="0" y1="9" x2="18" y2="9" stroke="currentColor" stroke-width="2"/></svg>`;
|
|
281
|
+
const AI_ICON = `<svg viewBox="0 0 24 24.0023" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24.0022736" fill="none" customFrame="#000000">
|
|
282
|
+
<defs>
|
|
283
|
+
<linearGradient id="paint_linear_1" x1="2.50000095" x2="12.0000048" y1="0" y2="23.9999962" gradientUnits="userSpaceOnUse">
|
|
284
|
+
<stop stop-color="rgb(250,100,1)" offset="0.263296664" stop-opacity="1" />
|
|
285
|
+
<stop stop-color="rgb(249.9,102.687,1)" offset="0.349490285" stop-opacity="1" />
|
|
286
|
+
<stop stop-color="rgb(247,181,1)" offset="0.494946986" stop-opacity="1" />
|
|
287
|
+
<stop stop-color="rgb(11,184,178)" offset="0.690560162" stop-opacity="1" />
|
|
288
|
+
<stop stop-color="rgb(1,145,255)" offset="0.858591199" stop-opacity="1" />
|
|
289
|
+
<stop stop-color="rgb(182,32,224)" offset="1" stop-opacity="1" />
|
|
290
|
+
</linearGradient>
|
|
291
|
+
</defs>
|
|
292
|
+
<path id="矢量 54" d="M12.9196 5.92509L6.52253 12.3221C6.30963 12.5349 6.14215 12.7787 6.01959 13.0536C5.89703 13.3284 5.8277 13.6161 5.81207 13.9166L5.71637 15.7208C5.63971 17.1667 6.83308 18.3601 8.27938 18.2835L10.0831 18.188C10.3839 18.1721 10.6715 18.1029 10.9464 17.9804C11.2213 17.8579 11.465 17.6903 11.6779 17.4775L18.9079 10.2475C19.3942 10.9692 19.7898 11.7495 20.0944 12.5884C20.2961 13.1437 20.448 13.7009 20.5495 14.2597C20.6428 14.7731 20.6897 15.2605 20.6897 15.7225C20.6897 16.4805 20.4992 17.1292 20.1179 17.6686C19.7619 18.1717 19.2678 18.5486 18.6359 18.7997C17.9894 19.0561 17.2853 19.1496 16.5231 19.0801C15.7233 19.0073 14.9669 18.763 14.2545 18.3471C14.1144 18.2653 13.9557 18.2223 13.7941 18.2223C13.2819 18.2223 12.8663 18.6465 12.8663 19.1698C12.8663 19.2533 12.8771 19.3354 12.8981 19.416C12.9196 19.4967 12.9508 19.5731 12.9918 19.6453C13.0328 19.7176 13.0822 19.7831 13.1403 19.842C13.1793 19.8813 13.2208 19.9168 13.2653 19.9483L13.3336 19.9924C13.8068 20.2686 14.3029 20.4897 14.8229 20.6555C15.3239 20.8158 15.8356 20.9198 16.3586 20.9676C16.8722 21.0144 17.3776 21.0043 17.8747 20.9373C18.3771 20.8694 18.8552 20.7456 19.3078 20.5658C19.7761 20.3802 20.2024 20.1407 20.5871 19.8474C20.9904 19.5403 21.3352 19.1839 21.6223 18.7779C21.9216 18.3542 22.1496 17.8888 22.3054 17.3818C22.4656 16.8605 22.5456 16.3074 22.5456 15.7225C22.5456 15.1442 22.4885 14.5412 22.3743 13.9136C22.2532 13.2479 22.073 12.5866 21.8347 11.9295C21.5764 11.218 21.2575 10.5358 20.8786 9.88306C20.6838 9.54703 20.4743 9.22121 20.2502 8.90559L23.2864 5.86926C24.238 4.91748 24.238 3.37431 23.2864 2.42253L21.5779 0.713837C20.6257 -0.237946 19.0827 -0.237946 18.1306 0.713837L14.4083 4.43634C12.5861 3.74113 10.5411 3.39346 8.27499 3.39346C7.76229 3.39346 7.34724 3.81766 7.34724 4.34097C7.34724 4.86429 7.76229 5.28848 8.27499 5.28848C9.97178 5.28865 11.5196 5.50081 12.9196 5.92509ZM7.91903 14.0282C7.92244 13.9442 7.95418 13.8728 8.01473 13.8142L17.3937 4.43512L19.6228 6.54848L19.5256 6.64574L10.1856 15.9854C10.1271 16.0456 10.0558 16.0774 9.97178 16.0808L8.16756 16.1763C8.07039 16.1815 7.98739 16.1496 7.91903 16.0809C7.85018 16.0122 7.81844 15.9294 7.82381 15.8324L7.91903 14.0282ZM21.7942 4.37717L20.8239 5.34731L18.653 3.1759L19.6228 2.20593C19.6867 2.14209 19.7639 2.11012 19.8542 2.11012C19.8991 2.10941 19.9406 2.1169 19.9792 2.1326L20.0857 2.20593L21.7942 3.91463C21.8581 3.97856 21.8899 4.05559 21.8899 4.14589C21.8913 4.2368 21.8596 4.31389 21.7942 4.37717ZM0.381352 6.34212C-0.126954 6.2448 -0.126954 5.50148 0.381352 5.40408L0.451665 5.39062C0.521978 5.37715 0.591315 5.36131 0.660651 5.34309C0.744636 5.32089 0.827645 5.29515 0.910165 5.26588C1.06007 5.21257 1.20509 5.14813 1.34523 5.07259C1.48537 4.99702 1.61916 4.91119 1.74709 4.81508C1.87453 4.71898 1.99465 4.61366 2.10647 4.49916C2.21877 4.38464 2.3218 4.26222 2.41604 4.1319C2.4468 4.08905 2.47659 4.0455 2.50588 4.00127L2.54495 3.93964L2.57473 3.89056C2.60745 3.83527 2.6387 3.77893 2.668 3.72156C2.74222 3.57832 2.8052 3.43025 2.85745 3.27734C2.9097 3.12442 2.95023 2.96838 2.97952 2.80922L2.98733 2.76753C3.07913 2.26801 3.78226 2.27577 3.86381 2.7771C3.88969 2.93764 3.92729 3.09518 3.97709 3.24979C4.0269 3.40439 4.08793 3.5542 4.1602 3.69925C4.23198 3.84428 4.31499 3.98286 4.40776 4.11496C4.50102 4.24706 4.60307 4.37114 4.71489 4.4872C4.82671 4.60326 4.94634 4.70993 5.07378 4.80724C5.20171 4.90453 5.33599 4.99132 5.47662 5.06758C5.61724 5.14384 5.76324 5.20869 5.91363 5.26215C6.06403 5.31558 6.21784 5.35699 6.37458 5.38635L6.47516 5.4053C6.98396 5.50072 6.98396 6.24556 6.47516 6.34097L6.37458 6.35992C6.21784 6.3893 6.06403 6.43069 5.91363 6.48413C5.76324 6.53758 5.61724 6.60243 5.47662 6.6787C5.33599 6.75494 5.20171 6.84174 5.07378 6.93903C4.94634 7.03632 4.82671 7.14301 4.71489 7.25905C4.60307 7.37511 4.50102 7.49918 4.40776 7.63127C4.37749 7.67439 4.34819 7.71822 4.32036 7.76273C4.26225 7.85454 4.20903 7.94928 4.1602 8.04697C4.08793 8.19202 4.0269 8.34183 3.97709 8.49641C3.92729 8.651 3.88969 8.80856 3.86381 8.96909C3.78226 9.4706 3.07913 9.47827 2.98733 8.97874L2.97952 8.93706C2.95023 8.77789 2.9097 8.62186 2.85745 8.46895C2.8052 8.31604 2.74222 8.16797 2.668 8.02473C2.62893 7.94897 2.58694 7.87502 2.54251 7.80286C2.50247 7.7386 2.46047 7.67578 2.41604 7.6144C2.3218 7.48405 2.21877 7.36163 2.10647 7.24713C1.99465 7.13263 1.87453 7.02731 1.74709 6.9312C1.61916 6.8351 1.48537 6.74925 1.34523 6.67371C1.20509 6.59814 1.06007 6.53371 0.910165 6.48041C0.760262 6.42711 0.607428 6.38551 0.451665 6.35567L0.381352 6.34212ZM2.26418 14.218C2.62259 15.5594 3.22367 16.7893 4.06694 17.9076C4.9063 19.0207 5.92242 19.9394 7.11531 20.6639C8.34188 21.409 9.66807 21.8938 11.0953 22.1182C11.1495 22.1268 11.2028 22.1401 11.2545 22.1583C11.3068 22.1765 11.3566 22.1992 11.4049 22.2265C11.4528 22.2537 11.4982 22.2851 11.5406 22.3206C11.5836 22.3561 11.6227 22.3951 11.6583 22.4377C11.6945 22.4803 11.7262 22.5258 11.754 22.5742C11.7819 22.6226 11.8053 22.6731 11.8243 22.7258C11.8434 22.7784 11.858 22.8324 11.8678 22.8876C11.8771 22.9429 11.882 22.9986 11.882 23.0547C11.882 23.5781 11.4669 24.0023 10.9542 24.0023C10.9068 24.0023 10.86 23.9986 10.8107 23.9909C9.14804 23.7294 7.59969 23.1631 6.16608 22.2925C4.77056 21.4447 3.5806 20.3685 2.59671 19.0638C1.60402 17.7478 0.896493 16.2987 0.474126 14.7167C0.03418 13.0693 -0.0654303 11.39 0.176271 9.67772L0.192873 9.58968L0.214358 9.51338L0.254885 9.41016L0.280276 9.35857C0.306644 9.30896 0.337406 9.26216 0.372074 9.21817C0.406742 9.17416 0.445317 9.13367 0.486821 9.09666C0.528814 9.05966 0.573736 9.02673 0.6211 8.99791L0.734871 8.93944L0.770516 8.92503C0.822274 8.90529 0.875497 8.89041 0.929697 8.88037C0.984385 8.87035 1.03907 8.86533 1.09474 8.86533C1.60695 8.86533 2.02248 9.28952 2.02248 9.81284C2.02248 9.85803 2.01955 9.90323 2.0132 9.94795C1.80812 11.4 1.89211 12.8234 2.26418 14.218Z" fill="url(#paint_linear_1)" fill-rule="evenodd" />
|
|
293
|
+
</svg>
|
|
294
|
+
`;
|
|
281
295
|
export {
|
|
296
|
+
AI_ICON,
|
|
282
297
|
ALIGN_CENTER_ICON,
|
|
283
298
|
ALIGN_JUSTIFY_ICON,
|
|
284
299
|
ALIGN_LEFT_ICON,
|